From 66ad66293edeb2bcc27a329f35018b18601da452 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 11 Jul 2019 10:29:36 +0200 Subject: gpio: em: use a helper variable for &pdev->dev Instead of always dereferencing &pdev->dev, just assign a helper local variable of type struct device * and use it where applicable. Signed-off-by: Bartosz Golaszewski Reviewed-by: Geert Uytterhoeven --- drivers/gpio/gpio-em.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index a87951293aaa..620f25b7efb4 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -272,11 +272,12 @@ static int em_gio_probe(struct platform_device *pdev) struct resource *io[2], *irq[2]; struct gpio_chip *gpio_chip; struct irq_chip *irq_chip; - const char *name = dev_name(&pdev->dev); + struct device *dev = &pdev->dev; + const char *name = dev_name(dev); unsigned int ngpios; int ret; - p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); + p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; @@ -290,27 +291,27 @@ static int em_gio_probe(struct platform_device *pdev) irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1); if (!io[0] || !io[1] || !irq[0] || !irq[1]) { - dev_err(&pdev->dev, "missing IRQ or IOMEM\n"); + dev_err(dev, "missing IRQ or IOMEM\n"); return -EINVAL; } - p->base0 = devm_ioremap_nocache(&pdev->dev, io[0]->start, + p->base0 = devm_ioremap_nocache(dev, io[0]->start, resource_size(io[0])); if (!p->base0) return -ENOMEM; - p->base1 = devm_ioremap_nocache(&pdev->dev, io[1]->start, + p->base1 = devm_ioremap_nocache(dev, io[1]->start, resource_size(io[1])); if (!p->base1) return -ENOMEM; - if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) { - dev_err(&pdev->dev, "Missing ngpios OF property\n"); + if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) { + dev_err(dev, "Missing ngpios OF property\n"); return -EINVAL; } gpio_chip = &p->gpio_chip; - gpio_chip->of_node = pdev->dev.of_node; + gpio_chip->of_node = dev->of_node; gpio_chip->direction_input = em_gio_direction_input; gpio_chip->get = em_gio_get; gpio_chip->direction_output = em_gio_direction_output; @@ -319,7 +320,7 @@ static int em_gio_probe(struct platform_device *pdev) gpio_chip->request = em_gio_request; gpio_chip->free = em_gio_free; gpio_chip->label = name; - gpio_chip->parent = &pdev->dev; + gpio_chip->parent = dev; gpio_chip->owner = THIS_MODULE; gpio_chip->base = -1; gpio_chip->ngpio = ngpios; @@ -333,33 +334,33 @@ static int em_gio_probe(struct platform_device *pdev) irq_chip->irq_release_resources = em_gio_irq_relres; irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; - p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, ngpios, 0, + p->irq_domain = irq_domain_add_simple(dev->of_node, ngpios, 0, &em_gio_irq_domain_ops, p); if (!p->irq_domain) { - dev_err(&pdev->dev, "cannot initialize irq domain\n"); + dev_err(dev, "cannot initialize irq domain\n"); return -ENXIO; } - ret = devm_add_action_or_reset(&pdev->dev, em_gio_irq_domain_remove, + ret = devm_add_action_or_reset(dev, em_gio_irq_domain_remove, p->irq_domain); if (ret) return ret; - if (devm_request_irq(&pdev->dev, irq[0]->start, + if (devm_request_irq(dev, irq[0]->start, em_gio_irq_handler, 0, name, p)) { - dev_err(&pdev->dev, "failed to request low IRQ\n"); + dev_err(dev, "failed to request low IRQ\n"); return -ENOENT; } - if (devm_request_irq(&pdev->dev, irq[1]->start, + if (devm_request_irq(dev, irq[1]->start, em_gio_irq_handler, 0, name, p)) { - dev_err(&pdev->dev, "failed to request high IRQ\n"); + dev_err(dev, "failed to request high IRQ\n"); return -ENOENT; } - ret = devm_gpiochip_add_data(&pdev->dev, gpio_chip, p); + ret = devm_gpiochip_add_data(dev, gpio_chip, p); if (ret) { - dev_err(&pdev->dev, "failed to add GPIO controller\n"); + dev_err(dev, "failed to add GPIO controller\n"); return ret; } -- cgit v1.2.3 From 61059b7048ee1d635673f3014ea9f7e3e4b1532f Mon Sep 17 00:00:00 2001 From: Ding Xiang Date: Wed, 31 Jul 2019 17:47:54 +0800 Subject: gpio: ixp4xx: remove redundant dev_err message devm_ioremap_resource already contains error message, so remove the redundant dev_err message Signed-off-by: Ding Xiang Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-ixp4xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c index 670c2a85a35b..2b2b89b6cd18 100644 --- a/drivers/gpio/gpio-ixp4xx.c +++ b/drivers/gpio/gpio-ixp4xx.c @@ -321,10 +321,8 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); g->base = devm_ioremap_resource(dev, res); - if (IS_ERR(g->base)) { - dev_err(dev, "ioremap error\n"); + if (IS_ERR(g->base)) return PTR_ERR(g->base); - } /* * Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on -- cgit v1.2.3 From 7beb620f805dcb6757b5e7870bebd75e3e9b37e0 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 1 Aug 2019 16:44:39 +0800 Subject: gpio: mxc: Use devm_clk_get_optional instead of devm_clk_get i.MX SoC's GPIO clock is optional, so it is better to use devm_clk_get_optional instead of devm_clk_get. Signed-off-by: Anson Huang Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mxc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index b2813580c582..7907a8755866 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -435,12 +435,9 @@ static int mxc_gpio_probe(struct platform_device *pdev) return port->irq; /* the controller clock is optional */ - port->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(port->clk)) { - if (PTR_ERR(port->clk) == -EPROBE_DEFER) - return -EPROBE_DEFER; - port->clk = NULL; - } + port->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(port->clk)) + return PTR_ERR(port->clk); err = clk_prepare_enable(port->clk); if (err) { -- cgit v1.2.3 From 8eeb467d3b4f8a5f05e49dd88e7674a2d6c0f346 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 1 Aug 2019 20:39:35 +0300 Subject: gpio: pca953x: Switch to use device_get_match_data() Instead of open coded variants, switch to direct use of device_get_match_data(). Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 378b206d2dc9..54cf01901320 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -949,19 +949,15 @@ static int pca953x_probe(struct i2c_client *client, if (i2c_id) { chip->driver_data = i2c_id->driver_data; } else { - const struct acpi_device_id *acpi_id; - struct device *dev = &client->dev; - - chip->driver_data = (uintptr_t)of_device_get_match_data(dev); - if (!chip->driver_data) { - acpi_id = acpi_match_device(pca953x_acpi_ids, dev); - if (!acpi_id) { - ret = -ENODEV; - goto err_exit; - } - - chip->driver_data = acpi_id->driver_data; + const void *match; + + match = device_get_match_data(&client->dev); + if (!match) { + ret = -ENODEV; + goto err_exit; } + + chip->driver_data = (uintptr_t)match; } i2c_set_clientdata(client, chip); -- cgit v1.2.3 From 63b484c2a69a4a98a22e072ea2ad1317a85e3abf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 1 Aug 2019 20:39:36 +0300 Subject: gpio: pca953x: Use GENMASK() consistently Use GENMASK() macro for all definitions where it's appropriate. No functional change intended. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 54cf01901320..aaba0b394d2f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -28,9 +29,9 @@ #define PCA953X_INVERT 0x02 #define PCA953X_DIRECTION 0x03 -#define REG_ADDR_MASK 0x3f -#define REG_ADDR_EXT 0x40 -#define REG_ADDR_AI 0x80 +#define REG_ADDR_MASK GENMASK(5, 0) +#define REG_ADDR_EXT BIT(6) +#define REG_ADDR_AI BIT(7) #define PCA957X_IN 0x00 #define PCA957X_INVRT 0x01 @@ -55,17 +56,17 @@ #define PCAL6524_OUT_INDCONF 0x2c #define PCAL6524_DEBOUNCE 0x2d -#define PCA_GPIO_MASK 0x00FF +#define PCA_GPIO_MASK GENMASK(7, 0) -#define PCAL_GPIO_MASK 0x1f -#define PCAL_PINCTRL_MASK 0x60 +#define PCAL_GPIO_MASK GENMASK(4, 0) +#define PCAL_PINCTRL_MASK GENMASK(6, 5) -#define PCA_INT 0x0100 -#define PCA_PCAL 0x0200 +#define PCA_INT BIT(8) +#define PCA_PCAL BIT(9) #define PCA_LATCH_INT (PCA_PCAL | PCA_INT) -#define PCA953X_TYPE 0x1000 -#define PCA957X_TYPE 0x2000 -#define PCA_TYPE_MASK 0xF000 +#define PCA953X_TYPE BIT(12) +#define PCA957X_TYPE BIT(13) +#define PCA_TYPE_MASK GENMASK(15, 12) #define PCA_CHIP_TYPE(x) ((x) & PCA_TYPE_MASK) @@ -565,7 +566,7 @@ static void pca953x_irq_mask(struct irq_data *d) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ)); + chip->irq_mask[d->hwirq / BANK_SZ] &= ~BIT(d->hwirq % BANK_SZ); } static void pca953x_irq_unmask(struct irq_data *d) @@ -573,7 +574,7 @@ static void pca953x_irq_unmask(struct irq_data *d) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); + chip->irq_mask[d->hwirq / BANK_SZ] |= BIT(d->hwirq % BANK_SZ); } static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on) @@ -641,7 +642,7 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); int bank_nb = d->hwirq / BANK_SZ; - u8 mask = 1 << (d->hwirq % BANK_SZ); + u8 mask = BIT(d->hwirq % BANK_SZ); if (!(type & IRQ_TYPE_EDGE_BOTH)) { dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", @@ -666,7 +667,7 @@ static void pca953x_irq_shutdown(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 mask = 1 << (d->hwirq % BANK_SZ); + u8 mask = BIT(d->hwirq % BANK_SZ); chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask; chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask; -- cgit v1.2.3 From 6dd6a2d27e5a0d192b542389f4c9a035d1b77b8e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 1 Aug 2019 20:39:37 +0300 Subject: gpio: pca953x: Remove explicit comparison with 0 There is no need to explicitly compare return code with 0. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index aaba0b394d2f..454bbe2fb41f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -850,12 +850,12 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert) ret = regcache_sync_region(chip->regmap, chip->regs->output, chip->regs->output + NBANK(chip)); - if (ret != 0) + if (ret) goto out; ret = regcache_sync_region(chip->regmap, chip->regs->direction, chip->regs->direction + NBANK(chip)); - if (ret != 0) + if (ret) goto out; /* set platform specific polarity inversion */ @@ -1061,14 +1061,14 @@ static int pca953x_regcache_sync(struct device *dev) */ ret = regcache_sync_region(chip->regmap, chip->regs->direction, chip->regs->direction + NBANK(chip)); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret); return ret; } ret = regcache_sync_region(chip->regmap, chip->regs->output, chip->regs->output + NBANK(chip)); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret); return ret; } @@ -1077,7 +1077,7 @@ static int pca953x_regcache_sync(struct device *dev) if (chip->driver_data & PCA_PCAL) { ret = regcache_sync_region(chip->regmap, PCAL953X_IN_LATCH, PCAL953X_IN_LATCH + NBANK(chip)); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to sync INT latch registers: %d\n", ret); return ret; @@ -1085,7 +1085,7 @@ static int pca953x_regcache_sync(struct device *dev) ret = regcache_sync_region(chip->regmap, PCAL953X_INT_MASK, PCAL953X_INT_MASK + NBANK(chip)); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to sync INT mask registers: %d\n", ret); return ret; @@ -1117,7 +1117,7 @@ static int pca953x_resume(struct device *dev) if (!atomic_read(&chip->wakeup_path)) { ret = regulator_enable(chip->regulator); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to enable regulator: %d\n", ret); return 0; } @@ -1130,7 +1130,7 @@ static int pca953x_resume(struct device *dev) return ret; ret = regcache_sync(chip->regmap); - if (ret != 0) { + if (ret) { dev_err(dev, "Failed to restore register map: %d\n", ret); return ret; } -- cgit v1.2.3 From f4160faac98c36556231621b03b44b646508b08e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 1 Aug 2019 20:39:38 +0300 Subject: gpio: pca953x: Drop %s for constant string literals There is no need to use %s for constant string literals w/o special characters inside. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 454bbe2fb41f..64d02ca60f53 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -1038,8 +1038,7 @@ static int pca953x_remove(struct i2c_client *client) ret = pdata->teardown(client, chip->gpio_chip.base, chip->gpio_chip.ngpio, pdata->context); if (ret < 0) - dev_err(&client->dev, "%s failed, %d\n", - "teardown", ret); + dev_err(&client->dev, "teardown failed, %d\n", ret); } else { ret = 0; } -- cgit v1.2.3 From f2ee73147a3f23cc4b032a76b5677b4b8441ba74 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 9 Aug 2019 16:40:31 +0200 Subject: gpio: lpc32xx: allow building on non-lpc32xx targets The driver uses hardwire MMIO addresses instead of the data that is passed in device tree. Change it over to only hardcode the register offset values and allow compile-testing. Acked-by: Sylvain Lemieux Tested-by: Sylvain Lemieux Signed-off-by: Arnd Bergmann Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 7 +++ drivers/gpio/Makefile | 2 +- drivers/gpio/gpio-lpc32xx.c | 118 +++++++++++++++++++++++++------------------- 3 files changed, 76 insertions(+), 51 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index bb13c266c329..8b40a578963c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -311,6 +311,13 @@ config GPIO_LPC18XX Select this option to enable GPIO driver for NXP LPC18XX/43XX devices. +config GPIO_LPC32XX + tristate "NXP LPC32XX GPIO support" + depends on OF_GPIO && (ARCH_LPC32XX || COMPILE_TEST) + help + Select this option to enable GPIO driver for + NXP LPC32XX devices. + config GPIO_LYNXPOINT tristate "Intel Lynxpoint GPIO support" depends on ACPI && X86 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index a4e91175c708..87d659ae95eb 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -74,7 +74,7 @@ obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o -obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o +obj-$(CONFIG_GPIO_LPC32XX) += gpio-lpc32xx.o obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 24885b3db3d5..4e626c4235c2 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -16,36 +16,33 @@ #include #include -#include -#include - -#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) -#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) -#define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) -#define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) -#define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) -#define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) -#define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) -#define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) -#define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) -#define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) -#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) -#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) -#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) -#define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) -#define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) -#define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) -#define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) -#define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) -#define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) -#define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) -#define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) -#define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) -#define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) -#define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) -#define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) -#define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) -#define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) +#define LPC32XX_GPIO_P3_INP_STATE (0x000) +#define LPC32XX_GPIO_P3_OUTP_SET (0x004) +#define LPC32XX_GPIO_P3_OUTP_CLR (0x008) +#define LPC32XX_GPIO_P3_OUTP_STATE (0x00C) +#define LPC32XX_GPIO_P2_DIR_SET (0x010) +#define LPC32XX_GPIO_P2_DIR_CLR (0x014) +#define LPC32XX_GPIO_P2_DIR_STATE (0x018) +#define LPC32XX_GPIO_P2_INP_STATE (0x01C) +#define LPC32XX_GPIO_P2_OUTP_SET (0x020) +#define LPC32XX_GPIO_P2_OUTP_CLR (0x024) +#define LPC32XX_GPIO_P2_MUX_SET (0x028) +#define LPC32XX_GPIO_P2_MUX_CLR (0x02C) +#define LPC32XX_GPIO_P2_MUX_STATE (0x030) +#define LPC32XX_GPIO_P0_INP_STATE (0x040) +#define LPC32XX_GPIO_P0_OUTP_SET (0x044) +#define LPC32XX_GPIO_P0_OUTP_CLR (0x048) +#define LPC32XX_GPIO_P0_OUTP_STATE (0x04C) +#define LPC32XX_GPIO_P0_DIR_SET (0x050) +#define LPC32XX_GPIO_P0_DIR_CLR (0x054) +#define LPC32XX_GPIO_P0_DIR_STATE (0x058) +#define LPC32XX_GPIO_P1_INP_STATE (0x060) +#define LPC32XX_GPIO_P1_OUTP_SET (0x064) +#define LPC32XX_GPIO_P1_OUTP_CLR (0x068) +#define LPC32XX_GPIO_P1_OUTP_STATE (0x06C) +#define LPC32XX_GPIO_P1_DIR_SET (0x070) +#define LPC32XX_GPIO_P1_DIR_CLR (0x074) +#define LPC32XX_GPIO_P1_DIR_STATE (0x078) #define GPIO012_PIN_TO_BIT(x) (1 << (x)) #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) @@ -72,12 +69,12 @@ #define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX) struct gpio_regs { - void __iomem *inp_state; - void __iomem *outp_state; - void __iomem *outp_set; - void __iomem *outp_clr; - void __iomem *dir_set; - void __iomem *dir_clr; + unsigned long inp_state; + unsigned long outp_state; + unsigned long outp_set; + unsigned long outp_clr; + unsigned long dir_set; + unsigned long dir_clr; }; /* @@ -165,16 +162,27 @@ static struct gpio_regs gpio_grp_regs_p3 = { struct lpc32xx_gpio_chip { struct gpio_chip chip; struct gpio_regs *gpio_grp; + void __iomem *reg_base; }; +static inline u32 gpreg_read(struct lpc32xx_gpio_chip *group, unsigned long offset) +{ + return __raw_readl(group->reg_base + offset); +} + +static inline void gpreg_write(struct lpc32xx_gpio_chip *group, u32 val, unsigned long offset) +{ + __raw_writel(val, group->reg_base + offset); +} + static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, unsigned pin, int input) { if (input) - __raw_writel(GPIO012_PIN_TO_BIT(pin), + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), group->gpio_grp->dir_clr); else - __raw_writel(GPIO012_PIN_TO_BIT(pin), + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), group->gpio_grp->dir_set); } @@ -184,19 +192,19 @@ static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group, u32 u = GPIO3_PIN_TO_BIT(pin); if (input) - __raw_writel(u, group->gpio_grp->dir_clr); + gpreg_write(group, u, group->gpio_grp->dir_clr); else - __raw_writel(u, group->gpio_grp->dir_set); + gpreg_write(group, u, group->gpio_grp->dir_set); } static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, unsigned pin, int high) { if (high) - __raw_writel(GPIO012_PIN_TO_BIT(pin), + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), group->gpio_grp->outp_set); else - __raw_writel(GPIO012_PIN_TO_BIT(pin), + gpreg_write(group, GPIO012_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); } @@ -206,31 +214,31 @@ static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group, u32 u = GPIO3_PIN_TO_BIT(pin); if (high) - __raw_writel(u, group->gpio_grp->outp_set); + gpreg_write(group, u, group->gpio_grp->outp_set); else - __raw_writel(u, group->gpio_grp->outp_clr); + gpreg_write(group, u, group->gpio_grp->outp_clr); } static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, unsigned pin, int high) { if (high) - __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); + gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); else - __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); + gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); } static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, unsigned pin) { - return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), + return GPIO012_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state), pin); } static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, unsigned pin) { - int state = __raw_readl(group->gpio_grp->inp_state); + int state = gpreg_read(group, group->gpio_grp->inp_state); /* * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped @@ -242,13 +250,13 @@ static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, unsigned pin) { - return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); + return GPI3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state), pin); } static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group, unsigned pin) { - return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin); + return GPO3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->outp_state), pin); } /* @@ -497,12 +505,18 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc, static int lpc32xx_gpio_probe(struct platform_device *pdev) { int i; + void __iomem *reg_base; + + reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(reg_base)) + return PTR_ERR(reg_base); for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { if (pdev->dev.of_node) { lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; + lpc32xx_gpiochip[i].reg_base = reg_base; } devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, &lpc32xx_gpiochip[i]); @@ -527,3 +541,7 @@ static struct platform_driver lpc32xx_gpio_driver = { }; module_platform_driver(lpc32xx_gpio_driver); + +MODULE_AUTHOR("Kevin Wells "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("GPIO driver for LPC32xx SoC"); -- cgit v1.2.3