From 9d7ae8127ff9eea84375dd8d962ce776a3734119 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Thu, 19 Jan 2017 10:05:37 -0500 Subject: gpio: 104-idio-16: Add set_multiple callback function support The ACCES 104-IDIO-16 series provides registers where 8 lines of GPIO may be set at a time. This patch add support for the set_multiple callback function, thus allowing multiple GPIO output lines to be set more efficiently in groups. Signed-off-by: William Breathitt Gray Signed-off-by: Linus Walleij --- drivers/gpio/gpio-104-idio-16.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpio/gpio-104-idio-16.c') diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 6787b8fcf0d8..a57900fd0dc7 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -116,6 +116,25 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value) spin_unlock_irqrestore(&idio16gpio->lock, flags); } +static void idio_16_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); + unsigned long flags; + + spin_lock_irqsave(&idio16gpio->lock, flags); + + idio16gpio->out_state &= ~*mask; + idio16gpio->out_state |= *mask & *bits; + + if (*mask & 0xFF) + outb(idio16gpio->out_state, idio16gpio->base); + if ((*mask >> 8) & 0xFF) + outb(idio16gpio->out_state >> 8, idio16gpio->base + 4); + + spin_unlock_irqrestore(&idio16gpio->lock, flags); +} + static void idio_16_irq_ack(struct irq_data *data) { } @@ -219,6 +238,7 @@ static int idio_16_probe(struct device *dev, unsigned int id) idio16gpio->chip.direction_output = idio_16_gpio_direction_output; idio16gpio->chip.get = idio_16_gpio_get; idio16gpio->chip.set = idio_16_gpio_set; + idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; idio16gpio->base = base[id]; idio16gpio->irq = irq[id]; idio16gpio->out_state = 0xFFFF; -- cgit v1.2.3 From 837143d356fd066ed6fb0a3a91700d66a7916841 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Tue, 24 Jan 2017 15:00:54 -0500 Subject: gpio: 104-idio-16: Utilize devm_ functions in driver probe callback The devm_ resource manager functions allow memory to be automatically released when a device is unbound. This patch takes advantage of the resource manager functions and replaces the gpiochip_add_data call and request_irq call with the devm_gpiochip_add_data call and devm_request_irq call respectively. In addition, the idio_16_remove function has been removed as no longer necessary due to the use of the relevant devm_ resource manager functions. Signed-off-by: William Breathitt Gray Signed-off-by: Linus Walleij --- drivers/gpio/gpio-104-idio-16.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'drivers/gpio/gpio-104-idio-16.c') diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index a57900fd0dc7..01a091e17614 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -46,7 +46,6 @@ MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers"); * @lock: synchronization lock to prevent I/O race conditions * @irq_mask: I/O bits affected by interrupts * @base: base port address of the GPIO device - * @irq: Interrupt line number * @out_state: output bits state */ struct idio_16_gpio { @@ -54,7 +53,6 @@ struct idio_16_gpio { spinlock_t lock; unsigned long irq_mask; unsigned base; - unsigned irq; unsigned out_state; }; @@ -240,14 +238,13 @@ static int idio_16_probe(struct device *dev, unsigned int id) idio16gpio->chip.set = idio_16_gpio_set; idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; idio16gpio->base = base[id]; - idio16gpio->irq = irq[id]; idio16gpio->out_state = 0xFFFF; spin_lock_init(&idio16gpio->lock); dev_set_drvdata(dev, idio16gpio); - err = gpiochip_add_data(&idio16gpio->chip, idio16gpio); + err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); return err; @@ -261,29 +258,16 @@ static int idio_16_probe(struct device *dev, unsigned int id) handle_edge_irq, IRQ_TYPE_NONE); if (err) { dev_err(dev, "Could not add irqchip (%d)\n", err); - goto err_gpiochip_remove; + return err; } - err = request_irq(irq[id], idio_16_irq_handler, 0, name, idio16gpio); + err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name, + idio16gpio); if (err) { dev_err(dev, "IRQ handler registering failed (%d)\n", err); - goto err_gpiochip_remove; + return err; } - return 0; - -err_gpiochip_remove: - gpiochip_remove(&idio16gpio->chip); - return err; -} - -static int idio_16_remove(struct device *dev, unsigned int id) -{ - struct idio_16_gpio *const idio16gpio = dev_get_drvdata(dev); - - free_irq(idio16gpio->irq, idio16gpio); - gpiochip_remove(&idio16gpio->chip); - return 0; } @@ -292,7 +276,6 @@ static struct isa_driver idio_16_driver = { .driver = { .name = "104-idio-16" }, - .remove = idio_16_remove }; module_isa_driver(idio_16_driver, num_idio_16); -- cgit v1.2.3 From c74f04d4b5b5049d6bd94bdc85a9da7b5896ca4b Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Mon, 30 Jan 2017 09:39:57 -0500 Subject: gpio: 104-idio-16: Remove unnecessary driver_data set Setting driver_data was necessary to access private data in the idio_16_remove function. Now that the idio_16_remove function is gone, driver_data is no longer used. This patch removes the relevant code. Signed-off-by: William Breathitt Gray Signed-off-by: Linus Walleij --- drivers/gpio/gpio-104-idio-16.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpio/gpio-104-idio-16.c') diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 01a091e17614..67068b61b90b 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -242,8 +242,6 @@ static int idio_16_probe(struct device *dev, unsigned int id) spin_lock_init(&idio16gpio->lock); - dev_set_drvdata(dev, idio16gpio); - err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); -- cgit v1.2.3 From e0af4b5e248bcfbdb056691c9b12ee697b07c213 Mon Sep 17 00:00:00 2001 From: William Breathitt Gray Date: Mon, 30 Jan 2017 13:33:21 -0500 Subject: gpio: 104-idio-16: Add support for GPIO names This patch sets the gpio_chip names option with an array of GPIO line names that match the manual documentation for the ACCES 104-IDIO-16. This should make it easier for users to identify which GPIO line corresponds to a respective GPIO pin on the device. Signed-off-by: William Breathitt Gray Signed-off-by: Linus Walleij --- drivers/gpio/gpio-104-idio-16.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/gpio/gpio-104-idio-16.c') diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index 67068b61b90b..7053cf736648 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -210,6 +210,14 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +#define IDIO_16_NGPIO 32 +static const char *idio_16_names[IDIO_16_NGPIO] = { + "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7", + "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15", + "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7", + "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15" +}; + static int idio_16_probe(struct device *dev, unsigned int id) { struct idio_16_gpio *idio16gpio; @@ -230,7 +238,8 @@ static int idio_16_probe(struct device *dev, unsigned int id) idio16gpio->chip.parent = dev; idio16gpio->chip.owner = THIS_MODULE; idio16gpio->chip.base = -1; - idio16gpio->chip.ngpio = 32; + idio16gpio->chip.ngpio = IDIO_16_NGPIO; + idio16gpio->chip.names = idio_16_names; idio16gpio->chip.get_direction = idio_16_gpio_get_direction; idio16gpio->chip.direction_input = idio_16_gpio_direction_input; idio16gpio->chip.direction_output = idio_16_gpio_direction_output; -- cgit v1.2.3