Re: [PATCH v6 07/13] gpio: add support for the sl28cpld GPIO controller
On Sun, Jul 26, 2020 at 01:18:28AM +0200, Michael Walle wrote: > Add support for the GPIO controller of the sl28 board management > controller. This driver is part of a multi-function device. > > A controller has 8 lines. There are three different flavors: > full-featured GPIO with interrupt support, input-only and output-only. FWIW, Reviewed-by: Andy Shevchenko > Signed-off-by: Michael Walle > Reviewed-by: Linus Walleij > --- > Changes since v5: > - added "select REGMAP_IRQ" > > Changes since v4: > - update copyright year > - remove #include , suggested by Andy. > - use device_get_match_data(), suggested by Andy. > - drop the irq_support variable, instead call _init_irq() directly, >suggested by Andy. > - also move the irq code a bit around to make it look nicer > - drop "struct sl28cpld_gpio". We don't need to actually store the >irq_chip and irq_chip_data, everything is device resource managed. > - use 100 chars line limit, suggested by Andy. > - remove the platform device table > - don't use KBUID_MODNAME > > Changes since v3: > - see cover letter > > drivers/gpio/Kconfig | 12 +++ > drivers/gpio/Makefile| 1 + > drivers/gpio/gpio-sl28cpld.c | 161 +++ > 3 files changed, 174 insertions(+) > create mode 100644 drivers/gpio/gpio-sl28cpld.c > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 8030fd91a3cc..f6a547b76432 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -1223,6 +1223,18 @@ config GPIO_RC5T583 > This driver provides the support for driving/reading the gpio pins > of RC5T583 device through standard gpio library. > > +config GPIO_SL28CPLD > + tristate "Kontron sl28cpld GPIO support" > + select MFD_SIMPLE_MFD_I2C > + select GPIO_REGMAP > + select GPIOLIB_IRQCHIP > + select REGMAP_IRQ > + help > + This enables support for the GPIOs found on the Kontron sl28 CPLD. > + > + This driver can also be built as a module. If so, the module will be > + called gpio-sl28cpld. > + > config GPIO_STMPE > bool "STMPE GPIOs" > depends on MFD_STMPE > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index 4f9abff4f2dc..c3a4e7c94a91 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -132,6 +132,7 @@ obj-$(CONFIG_GPIO_SCH311X)+= > gpio-sch311x.o > obj-$(CONFIG_GPIO_SCH) += gpio-sch.o > obj-$(CONFIG_GPIO_SIFIVE)+= gpio-sifive.o > obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o > +obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o > obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o > obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o > obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o > diff --git a/drivers/gpio/gpio-sl28cpld.c b/drivers/gpio/gpio-sl28cpld.c > new file mode 100644 > index ..889b8f5622c2 > --- /dev/null > +++ b/drivers/gpio/gpio-sl28cpld.c > @@ -0,0 +1,161 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * sl28cpld GPIO driver > + * > + * Copyright 2020 Michael Walle > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* GPIO flavor */ > +#define GPIO_REG_DIR 0x00 > +#define GPIO_REG_OUT 0x01 > +#define GPIO_REG_IN 0x02 > +#define GPIO_REG_IE 0x03 > +#define GPIO_REG_IP 0x04 > + > +/* input-only flavor */ > +#define GPI_REG_IN 0x00 > + > +/* output-only flavor */ > +#define GPO_REG_OUT 0x00 > + > +enum sl28cpld_gpio_type { > + SL28CPLD_GPIO = 1, > + SL28CPLD_GPI, > + SL28CPLD_GPO, > +}; > + > +static const struct regmap_irq sl28cpld_gpio_irqs[] = { > + REGMAP_IRQ_REG_LINE(0, 8), > + REGMAP_IRQ_REG_LINE(1, 8), > + REGMAP_IRQ_REG_LINE(2, 8), > + REGMAP_IRQ_REG_LINE(3, 8), > + REGMAP_IRQ_REG_LINE(4, 8), > + REGMAP_IRQ_REG_LINE(5, 8), > + REGMAP_IRQ_REG_LINE(6, 8), > + REGMAP_IRQ_REG_LINE(7, 8), > +}; > + > +static int sl28cpld_gpio_irq_init(struct platform_device *pdev, > + unsigned int base, > + struct gpio_regmap_config *config) > +{ > + struct regmap_irq_chip_data *irq_data; > + struct regmap_irq_chip *irq_chip; > + struct device *dev = >dev; > + int irq, ret; > + > + if (!device_property_read_bool(dev, "interrupt-controller")) > + return 0; > + > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) > + return irq; > + > + irq_chip = devm_kzalloc(dev, sizeof(*irq_chip), GFP_KERNEL); > + if (!irq_chip) > + return -ENOMEM; > + > + irq_chip->name = "sl28cpld-gpio-irq", > + irq_chip->irqs = sl28cpld_gpio_irqs; > + irq_chip->num_irqs = ARRAY_SIZE(sl28cpld_gpio_irqs); > + irq_chip->num_regs = 1; > + irq_chip->status_base = base + GPIO_REG_IP; > + irq_chip->mask_base = base +
[PATCH v6 07/13] gpio: add support for the sl28cpld GPIO controller
Add support for the GPIO controller of the sl28 board management controller. This driver is part of a multi-function device. A controller has 8 lines. There are three different flavors: full-featured GPIO with interrupt support, input-only and output-only. Signed-off-by: Michael Walle Reviewed-by: Linus Walleij --- Changes since v5: - added "select REGMAP_IRQ" Changes since v4: - update copyright year - remove #include , suggested by Andy. - use device_get_match_data(), suggested by Andy. - drop the irq_support variable, instead call _init_irq() directly, suggested by Andy. - also move the irq code a bit around to make it look nicer - drop "struct sl28cpld_gpio". We don't need to actually store the irq_chip and irq_chip_data, everything is device resource managed. - use 100 chars line limit, suggested by Andy. - remove the platform device table - don't use KBUID_MODNAME Changes since v3: - see cover letter drivers/gpio/Kconfig | 12 +++ drivers/gpio/Makefile| 1 + drivers/gpio/gpio-sl28cpld.c | 161 +++ 3 files changed, 174 insertions(+) create mode 100644 drivers/gpio/gpio-sl28cpld.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8030fd91a3cc..f6a547b76432 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1223,6 +1223,18 @@ config GPIO_RC5T583 This driver provides the support for driving/reading the gpio pins of RC5T583 device through standard gpio library. +config GPIO_SL28CPLD + tristate "Kontron sl28cpld GPIO support" + select MFD_SIMPLE_MFD_I2C + select GPIO_REGMAP + select GPIOLIB_IRQCHIP + select REGMAP_IRQ + help + This enables support for the GPIOs found on the Kontron sl28 CPLD. + + This driver can also be built as a module. If so, the module will be + called gpio-sl28cpld. + config GPIO_STMPE bool "STMPE GPIOs" depends on MFD_STMPE diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4f9abff4f2dc..c3a4e7c94a91 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -132,6 +132,7 @@ obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o obj-$(CONFIG_GPIO_SIOX)+= gpio-siox.o +obj-$(CONFIG_GPIO_SL28CPLD)+= gpio-sl28cpld.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o obj-$(CONFIG_GPIO_SPRD)+= gpio-sprd.o diff --git a/drivers/gpio/gpio-sl28cpld.c b/drivers/gpio/gpio-sl28cpld.c new file mode 100644 index ..889b8f5622c2 --- /dev/null +++ b/drivers/gpio/gpio-sl28cpld.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * sl28cpld GPIO driver + * + * Copyright 2020 Michael Walle + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* GPIO flavor */ +#define GPIO_REG_DIR 0x00 +#define GPIO_REG_OUT 0x01 +#define GPIO_REG_IN0x02 +#define GPIO_REG_IE0x03 +#define GPIO_REG_IP0x04 + +/* input-only flavor */ +#define GPI_REG_IN 0x00 + +/* output-only flavor */ +#define GPO_REG_OUT0x00 + +enum sl28cpld_gpio_type { + SL28CPLD_GPIO = 1, + SL28CPLD_GPI, + SL28CPLD_GPO, +}; + +static const struct regmap_irq sl28cpld_gpio_irqs[] = { + REGMAP_IRQ_REG_LINE(0, 8), + REGMAP_IRQ_REG_LINE(1, 8), + REGMAP_IRQ_REG_LINE(2, 8), + REGMAP_IRQ_REG_LINE(3, 8), + REGMAP_IRQ_REG_LINE(4, 8), + REGMAP_IRQ_REG_LINE(5, 8), + REGMAP_IRQ_REG_LINE(6, 8), + REGMAP_IRQ_REG_LINE(7, 8), +}; + +static int sl28cpld_gpio_irq_init(struct platform_device *pdev, + unsigned int base, + struct gpio_regmap_config *config) +{ + struct regmap_irq_chip_data *irq_data; + struct regmap_irq_chip *irq_chip; + struct device *dev = >dev; + int irq, ret; + + if (!device_property_read_bool(dev, "interrupt-controller")) + return 0; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + irq_chip = devm_kzalloc(dev, sizeof(*irq_chip), GFP_KERNEL); + if (!irq_chip) + return -ENOMEM; + + irq_chip->name = "sl28cpld-gpio-irq", + irq_chip->irqs = sl28cpld_gpio_irqs; + irq_chip->num_irqs = ARRAY_SIZE(sl28cpld_gpio_irqs); + irq_chip->num_regs = 1; + irq_chip->status_base = base + GPIO_REG_IP; + irq_chip->mask_base = base + GPIO_REG_IE; + irq_chip->mask_invert = true, + irq_chip->ack_base = base + GPIO_REG_IP; + + ret = devm_regmap_add_irq_chip_fwnode(dev, dev_fwnode(dev), + config->regmap, irq, + IRQF_SHARED |