+ default y
I'm not sure we have to have this always y. Perhaps
default SERIAL_8250_PCI
+obj-$(CONFIG_MFD_FINTEK_F81504_CORE) += f81504-core.o
I think '_' is better than '-'. What I saw and usually do is '_' for
regular source modules and '-' for the resulting objects when they have
more than one file.
+#define F81504_DEV_DESC "Fintek F81504/508/512 PCIE-
to-UART core"
Do you need this definition? Is it used more than once?
+static int f81504_port_init(struct pci_dev *dev)
+{
+ size_t i, j;
+ u32 max_port, iobase, gpio_addr;
+ u32 bar_data[3];
+ u16 tmp;
+ u8 config_base, gpio_en, f0h_data, f3h_data;
+ bool is_gpio;
+ struct f81504_pci_private *priv = pci_get_drvdata(dev);
I would suggest to rearrange definition block here (and in the rest of
the functions in entire series) to somehow follow the following pattern
1) assignments go first, especially container_of() based ones;
2) group variables by meaning and put longer lines upper;
3) return value variable, if exists, goes last.
Besides that choose types carefully. If there is known limit for
counters, no need to define wider type than needed. Use proper types
for corresponding values.
+
+ /* Init GPIO IO Address */
+ pci_read_config_dword(dev, 0x18, &gpio_addr);
+ gpio_addr &= 0xffffffe0;
+ pci_write_config_byte(dev, F81504_GPIO_IO_LSB_REG, gpio_addr
& 0xff);
+ pci_write_config_byte(dev, F81504_GPIO_IO_MSB_REG,
(gpio_addr >> 8) &
+ 0xff);
Could it be written at once as a word?
+ if (priv) {
+ /* Reinit from resume(), read the previous value
from priv */
+ gpio_en = priv->gpio_en;
I would suggest to move this line down to follow same pattern in else
branch.
+
+ /* re-save GPIO IO addr for called by resume() */
re-save -> Re-save
addr -> address
+ priv->gpio_ioaddr = gpio_addr;
+ } else {
+ /* Driver first init */
+ pci_read_config_byte(dev, F81504_GPIO_ENABLE_REG,
&f0h_data);
+ pci_read_config_byte(dev, F81504_GPIO_MODE_REG,
&f3h_data);
+
+ /* find the max set of GPIOs */
Use one pattern for all comments, like "Capital letter first, and full
words avoiding abbreviations".
+ case FINTEK_F81504: /* 4 ports */
+ /* F81504 max 2 sets of GPIO, others are max 6
sets*/
Space before * is needed.
+ for (i = 0; i < max_port; ++i) {
i++, since it's more usual pattern.
+ /* find every port to check is multi-function port?
*/
+ for (j = 0; j < ARRAY_SIZE(fintek_gpio_mapping);
++j) {
+ if (fintek_gpio_mapping[j] != i || !(gpio_en
& BIT(j)))
+ continue;
+
+ /*
+ * This port is multi-function and enabled
as gpio
+ * mode. So we'll not configure it as serial
port.
+ */
+ is_gpio = true;
+ break;
+ }
Looks like a separate function.
func()
{
for () {
if ()
return X;
}
return Y;
}
+ /* Select 128-byte FIFO and 8x FIFO threshold */
+ pci_write_config_byte(dev, config_base + 0x01,
0x33);
+
+ /* LSB UART */
+ pci_write_config_byte(dev, config_base + 0x04,
+ (u8)(iobase & 0xff));
Redundant explicit casting.
+
+ /* MSB UART */
+ pci_write_config_byte(dev, config_base + 0x05,
+ (u8)((iobase & 0xff00) >> 8));
Ditto.
And similar question, can it be written as a word?
+
+ pci_write_config_byte(dev, config_base + 0x06, dev-
irq);+
+ /*
+ * Force init to RS232 / Share Mode, recovery
previous mode
+ * will done in F81504 8250 platform driver resume()
Period at the end of sentences in multi-line comments.
+ for (i = 0; i < max_port; ++i) {
+ /* Check UART is enabled */
+ pci_read_config_byte(dev, F81504_UART_START_ADDR + i
*
+ F81504_UART_OFFSET, &tmp);
+ if (!tmp)
+ continue;
So, this is the same as below, right?
+
+ /* Get UART IO Address */
+ pci_read_config_word(dev, F81504_UART_START_ADDR + i
*
+ F81504_UART_OFFSET + 4, &iobase);
âwhy not to check here?
+ f81504_serial_cell.pdata_size = sizeof(i);
This is static, can be part of definition.
+ f81504_serial_cell.platform_data = &i;
+
+ status = mfd_add_devices(&dev->dev,
PLATFORM_DEVID_AUTO,
+ &f81504_serial_cell, 1,
NULL, dev->irq,
+ NULL);
+ if (status) {
+ dev_warn(&dev->dev, "%s: add device failed:
%d\n",
+ __func__, status);
Indent _ under &.
+ f81504_gpio_cell.pdata_size = sizeof(i);
Static. The problem here is badly chosen type of i. Like I mentioned at
the top of reviewâ
+static int f81504_probe(struct pci_dev *dev, const struct
pci_device_id
+ *dev_id)
Usually drivers are using pdev, id pair in parameters. Shorter; known
pattern.
+{
+ int status;
+ u8 tmp;
+ struct f81504_pci_private *priv;
+
+ status = pci_enable_device(dev);
Please, pcim_, see comment below.
+ if (status)
+ return status;
+
+ /* Init PCI Configuration Space */
+ status = f81504_port_init(dev);
+ if (status)
Device left enabled if not managed.
+ return status;
+
+ priv = devm_kzalloc(&dev->dev, sizeof(struct
f81504_pci_private),
+ GFP_KERNEL);
+ if (!priv)
Ditto.
+ return -ENOMEM;
+
+ /* Save the GPIO_ENABLE_REG after f81504_port_init() for
future use */
+ pci_read_config_byte(dev, F81504_GPIO_ENABLE_REG, &priv-
gpio_en);+
+ /* Save GPIO IO Addr to private data */
+ pci_read_config_byte(dev, F81504_GPIO_IO_MSB_REG, &tmp);
+ priv->gpio_ioaddr = tmp << 8;
+ pci_read_config_byte(dev, F81504_GPIO_IO_LSB_REG, &tmp);
+ priv->gpio_ioaddr |= tmp;
One read as word?
+ mfd_remove_devices(&dev->dev);
mfd_add_devices takes care.
+ pci_disable_device(dev);
pcim_ takes case.
+ return status;
+}
+
+static void f81504_remove(struct pci_dev *dev)
+{
+ mfd_remove_devices(&dev->dev);
+ pci_disable_device(dev);
Ditto.
+static int f81504_resume(struct device *dev)
+{
+ int status;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ status = pci_enable_device(pdev);
+ if (status)
+ return status;
It's done by PCI core I believe.
+static const struct pci_device_id f81504_dev_table[] = {
+ /* Fintek PCI serial cards */
+ {PCI_DEVICE(FINTEK_VID, FINTEK_F81504), .driver_data = 4},
+ {PCI_DEVICE(FINTEK_VID, FINTEK_F81508), .driver_data = 8},
+ {PCI_DEVICE(FINTEK_VID, FINTEK_F81512), .driver_data = 12},
+ {}
So, if you have default y for this and 8250_pci, which one will be
loaded?
+static struct pci_driver f81504_driver = {
+ .name = F81504_DRIVER_NAME,
+ .probe = f81504_probe,
+ .remove = f81504_remove,
+ .driver = {
+ .pm = &f81504_pm_ops,
+ .owner = THIS_MODULE,
kbuild already complained about.
diff --git a/include/linux/mfd/f81504.h b/include/linux/mfd/f81504.h
new file mode 100644
index 0000000..13bd0ae
--- /dev/null
+++ b/include/linux/mfd/f81504.h
@@ -0,0 +1,52 @@
+#ifndef __F81504_H__
__MFD_Fâ