Hi Bartosz Golaszewski and Linux Walleij, Thanks for your reply.I have modified it according to your suggestions.And our device is silmilar as AMD South Bridge(amd8111), then i just take gpio-amd8111.c in kernel driver source as reference. It says that we can't use plain pci_driver mechanism, as the device is really a multiple function device,main driver that binds to the pci_device is a bus driver.It seems reasonable then i follow it. Signed-off-by: Richard Hsu <saraon640529@xxxxxxxxx> --- patch | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/patch b/patch index a713f91..220a8cf 100644 --- a/patch +++ b/patch @@ -1,7 +1,7 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpio/gpio-asm28xx-18xx.c linux-5.7.0-rc6-patch/drivers/gpio/gpio-asm28xx-18xx.c --- linux-5.7.0-rc6/drivers/gpio/gpio-asm28xx-18xx.c 1970-01-01 08:00:00.000000000 +0800 -+++ linux-5.7.0-rc6-patch/drivers/gpio/gpio-asm28xx-18xx.c 2020-05-22 11:55:13.736272177 +0800 -@@ -0,0 +1,282 @@ ++++ linux-5.7.0-rc6-patch/drivers/gpio/gpio-asm28xx-18xx.c 2020-05-26 10:41:11.401349769 +0800 +@@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Asmedia 28xx/18xx GPIO driver @@ -17,6 +17,7 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi +#include <linux/pci.h> +#include <linux/spinlock.h> +#include <linux/pm_runtime.h> ++#include <linux/bits.h> + + +/* GPIO registers offsets */ @@ -63,7 +64,6 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi +}; +MODULE_DEVICE_TABLE(pci, pci_tbl); + -+ +struct asm28xx_gpio { + struct gpio_chip chip; + struct pci_dev *pdev; @@ -104,20 +104,12 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi + +static int asm28xx_gpio_request(struct gpio_chip *chip, unsigned offset) +{ -+ -+ dev_dbg(chip->parent, "ASMEDIA-28xx/18xx gpio %d request\n", offset); -+ + if (offset == ASM_GPIO_PIN5) + return -ENODEV; + + return 0; +} + -+static void asm28xx_gpio_free(struct gpio_chip *chip, unsigned offset) -+{ -+ dev_dbg(chip->parent, "ASMEDIA-28xx/18xx gpio %d free\n", offset); -+} -+ +static void asm28xx_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct asm28xx_gpio *agp = gpiochip_get_data(chip); @@ -196,7 +188,6 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi + .owner = THIS_MODULE, + .ngpio = 8, + .request = asm28xx_gpio_request, -+ .free = asm28xx_gpio_free, + .set = asm28xx_gpio_set, + .get = asm28xx_gpio_get, + .direction_output = asm28xx_gpio_dirout, @@ -213,6 +204,16 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi + unsigned long flags; + int type; + ++ /* We look for our device - Asmedia 28XX and 18XX Bridge ++ * I don't know about a system with two such bridges, ++ * so we can assume that there is max. one device. ++ * ++ * We can't use plain pci_driver mechanism, ++ * as the device is really a multiple function device, ++ * main driver that binds to the pci_device is an bus ++ * driver and have to find & bind to the device this way. ++ */ ++ + for_each_pci_dev(pdev) { + ent = pci_match_id(pci_tbl, pdev); + if (ent) { @@ -282,11 +283,9 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Richard Hsu <Richard_Hsu@xxxxxxxxxxxxxx>"); +MODULE_DESCRIPTION("Asmedia 28xx 18xx GPIO Driver"); -+ -+ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpio/Kconfig linux-5.7.0-rc6-patch/drivers/gpio/Kconfig --- linux-5.7.0-rc6/drivers/gpio/Kconfig 2020-05-22 11:54:00.862644198 +0800 -+++ linux-5.7.0-rc6-patch/drivers/gpio/Kconfig 2020-05-22 11:55:13.680270929 +0800 ++++ linux-5.7.0-rc6-patch/drivers/gpio/Kconfig 2020-05-26 09:42:21.777312685 +0800 @@ -113,6 +113,14 @@ config GPIO_AMDPT driver for GPIO functionality on Promontory IOHub Require ACPI ASL code to enumerate as a platform device. @@ -296,7 +295,7 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi + depends on PCI + select GPIO_GENERIC + help -+ driver for GPIO functionality on Asmedia 28XX and 18XX PCI-E Bridge. ++ Driver for GPIO functionality on Asmedia 28XX and 18XX PCI-E Bridge. + + config GPIO_ASPEED @@ -304,9 +303,12 @@ diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpi depends on (ARCH_ASPEED || COMPILE_TEST) && OF_GPIO diff -uprN -X linux-5.7.0-rc6/Documentation/dontdiff linux-5.7.0-rc6/drivers/gpio/Makefile linux-5.7.0-rc6-patch/drivers/gpio/Makefile --- linux-5.7.0-rc6/drivers/gpio/Makefile 2020-05-22 11:54:00.862644198 +0800 -+++ linux-5.7.0-rc6-patch/drivers/gpio/Makefile 2020-05-22 11:55:13.680270929 +0800 -@@ -176,3 +176,4 @@ obj-$(CONFIG_GPIO_XTENSA) += gpio-xtens - obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o - obj-$(CONFIG_GPIO_ZX) += gpio-zx.o - obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o ++++ linux-5.7.0-rc6-patch/drivers/gpio/Makefile 2020-05-26 09:45:42.092095882 +0800 +@@ -31,6 +31,7 @@ obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8 + obj-$(CONFIG_GPIO_AMD_FCH) += gpio-amd-fch.o + obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o + obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o +obj-$(CONFIG_GPIO_ASM28XX) += gpio-asm28xx-18xx.o + obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o + obj-$(CONFIG_GPIO_ASPEED_SGPIO) += gpio-aspeed-sgpio.o + obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o -- 2.17.1