diff options
Diffstat (limited to 'drivers/gpio/gpio-ts5500.c')
| -rw-r--r-- | drivers/gpio/gpio-ts5500.c | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c index cc53cab8df2a..3c7f2efe10fd 100644 --- a/drivers/gpio/gpio-ts5500.c +++ b/drivers/gpio/gpio-ts5500.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Digital I/O driver for Technologic Systems TS-5500 * @@ -10,23 +11,18 @@ * Actually, the following platforms have DIO support: * * TS-5500: - * Documentation: http://wiki.embeddedarm.com/wiki/TS-5500 + * Documentation: https://docs.embeddedts.com/TS-5500 * Blocks: DIO1, DIO2 and LCD port. * * TS-5600: - * Documentation: http://wiki.embeddedarm.com/wiki/TS-5600 + * Documentation: https://docs.embeddedts.com/TS-5600 * Blocks: LCD port (identical to TS-5500 LCD). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/bitops.h> -#include <linux/gpio.h> +#include <linux/gpio/driver.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/platform_data/gpio-ts5500.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -185,11 +181,6 @@ static const struct ts5500_dio ts5500_lcd[] = { TS5500_DIO_IN_IRQ(0x73, 7, 1), }; -static inline struct ts5500_priv *ts5500_gc_to_priv(struct gpio_chip *chip) -{ - return container_of(chip, struct ts5500_priv, gpio_chip); -} - static inline void ts5500_set_mask(u8 mask, u8 addr) { u8 val = inb(addr); @@ -206,7 +197,7 @@ static inline void ts5500_clear_mask(u8 mask, u8 addr) static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset) { - struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + struct ts5500_priv *priv = gpiochip_get_data(chip); const struct ts5500_dio line = priv->pinout[offset]; unsigned long flags; @@ -225,7 +216,7 @@ static int ts5500_gpio_input(struct gpio_chip *chip, unsigned offset) static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset) { - struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + struct ts5500_priv *priv = gpiochip_get_data(chip); const struct ts5500_dio line = priv->pinout[offset]; return !!(inb(line.value_addr) & line.value_mask); @@ -233,7 +224,7 @@ static int ts5500_gpio_get(struct gpio_chip *chip, unsigned offset) static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val) { - struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + struct ts5500_priv *priv = gpiochip_get_data(chip); const struct ts5500_dio line = priv->pinout[offset]; unsigned long flags; @@ -253,9 +244,9 @@ static int ts5500_gpio_output(struct gpio_chip *chip, unsigned offset, int val) return 0; } -static void ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) +static int ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) { - struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + struct ts5500_priv *priv = gpiochip_get_data(chip); const struct ts5500_dio line = priv->pinout[offset]; unsigned long flags; @@ -265,11 +256,13 @@ static void ts5500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) else ts5500_clear_mask(line.value_mask, line.value_addr); spin_unlock_irqrestore(&priv->lock, flags); + + return 0; } static int ts5500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - struct ts5500_priv *priv = ts5500_gc_to_priv(chip); + struct ts5500_priv *priv = gpiochip_get_data(chip); const struct ts5500_dio *block = priv->pinout; const struct ts5500_dio line = block[offset]; @@ -315,48 +308,41 @@ static void ts5500_disable_irq(struct ts5500_priv *priv) else if (priv->hwirq == 1) ts5500_clear_mask(BIT(6), 0x7d); /* LCD_RS on IRQ1 */ else - dev_err(priv->gpio_chip.dev, "invalid hwirq %d\n", priv->hwirq); + dev_err(priv->gpio_chip.parent, "invalid hwirq %d\n", + priv->hwirq); spin_unlock_irqrestore(&priv->lock, flags); } static int ts5500_dio_probe(struct platform_device *pdev) { enum ts5500_blocks block = platform_get_device_id(pdev)->driver_data; - struct ts5500_dio_platform_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; const char *name = dev_name(dev); struct ts5500_priv *priv; - struct resource *res; unsigned long flags; int ret; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "missing IRQ resource\n"); - return -EINVAL; - } + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL); if (!priv) return -ENOMEM; platform_set_drvdata(pdev, priv); - priv->hwirq = res->start; + priv->hwirq = ret; spin_lock_init(&priv->lock); priv->gpio_chip.owner = THIS_MODULE; priv->gpio_chip.label = name; - priv->gpio_chip.dev = dev; + priv->gpio_chip.parent = dev; priv->gpio_chip.direction_input = ts5500_gpio_input; priv->gpio_chip.direction_output = ts5500_gpio_output; priv->gpio_chip.get = ts5500_gpio_get; priv->gpio_chip.set = ts5500_gpio_set; priv->gpio_chip.to_irq = ts5500_gpio_to_irq; priv->gpio_chip.base = -1; - if (pdata) { - priv->gpio_chip.base = pdata->base; - priv->strap = pdata->strap; - } switch (block) { case TS5500_DIO1: @@ -413,7 +399,7 @@ static int ts5500_dio_probe(struct platform_device *pdev) break; } - ret = gpiochip_add(&priv->gpio_chip); + ret = devm_gpiochip_add_data(dev, &priv->gpio_chip, priv); if (ret) { dev_err(dev, "failed to register the gpio chip\n"); return ret; @@ -422,25 +408,20 @@ static int ts5500_dio_probe(struct platform_device *pdev) ret = ts5500_enable_irq(priv); if (ret) { dev_err(dev, "invalid interrupt %d\n", priv->hwirq); - goto cleanup; + return ret; } return 0; -cleanup: - if (gpiochip_remove(&priv->gpio_chip)) - dev_err(dev, "failed to remove gpio chip\n"); - return ret; } -static int ts5500_dio_remove(struct platform_device *pdev) +static void ts5500_dio_remove(struct platform_device *pdev) { struct ts5500_priv *priv = platform_get_drvdata(pdev); ts5500_disable_irq(priv); - return gpiochip_remove(&priv->gpio_chip); } -static struct platform_device_id ts5500_dio_ids[] = { +static const struct platform_device_id ts5500_dio_ids[] = { { "ts5500-dio1", TS5500_DIO1 }, { "ts5500-dio2", TS5500_DIO2 }, { "ts5500-dio-lcd", TS5500_LCD }, @@ -452,7 +433,6 @@ MODULE_DEVICE_TABLE(platform, ts5500_dio_ids); static struct platform_driver ts5500_dio_driver = { .driver = { .name = "ts5500-dio", - .owner = THIS_MODULE, }, .probe = ts5500_dio_probe, .remove = ts5500_dio_remove, |
