Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: 104-idio-16: Utilize the ISA bus driver

The ACCES 104-IDIO-16 series communicates via the ISA bus. As such, it
is more appropriate to use the ISA bus driver over the platform driver
to control the ACCES 104-IDIO-16 GPIO driver.

This patch also adds support for multiple devices via the base and irq
module array parameters. Each element of the base array corresponds to a
discrete device; each element of the irq array corresponds to the
respective device addressed in the respective base array element.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

William Breathitt Gray and committed by
Greg Kroah-Hartman
86ea8a95 72bf7443

+34 -61
+6 -4
drivers/gpio/Kconfig
··· 527 527 528 528 config GPIO_104_IDIO_16 529 529 tristate "ACCES 104-IDIO-16 GPIO support" 530 + depends on ISA 530 531 select GPIOLIB_IRQCHIP 531 532 help 532 - Enables GPIO support for the ACCES 104-IDIO-16 family. The base port 533 - address for the device may be set via the idio_16_base module 534 - parameter. The interrupt line number for the device may be set via the 535 - idio_16_irq module parameter. 533 + Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16, 534 + 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, 104-IDO-8). The 535 + base port addresses for the devices may be configured via the base 536 + module parameter. The interrupt line numbers for the devices may be 537 + configured via the irq module parameter. 536 538 537 539 config GPIO_104_IDI_48 538 540 tristate "ACCES 104-IDI-48 GPIO support"
+28 -57
drivers/gpio/gpio-104-idio-16.c
··· 10 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 12 * General Public License for more details. 13 + * 14 + * This driver supports the following ACCES devices: 104-IDIO-16, 15 + * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8. 13 16 */ 14 17 #include <linux/bitops.h> 15 18 #include <linux/device.h> ··· 22 19 #include <linux/ioport.h> 23 20 #include <linux/interrupt.h> 24 21 #include <linux/irqdesc.h> 22 + #include <linux/isa.h> 25 23 #include <linux/kernel.h> 26 24 #include <linux/module.h> 27 25 #include <linux/moduleparam.h> 28 - #include <linux/platform_device.h> 29 26 #include <linux/spinlock.h> 30 27 31 - static unsigned idio_16_base; 32 - module_param(idio_16_base, uint, 0); 33 - MODULE_PARM_DESC(idio_16_base, "ACCES 104-IDIO-16 base address"); 34 - static unsigned idio_16_irq; 35 - module_param(idio_16_irq, uint, 0); 36 - MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number"); 28 + #define IDIO_16_EXTENT 8 29 + #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT) 30 + 31 + static unsigned int base[MAX_NUM_IDIO_16]; 32 + static unsigned int num_idio_16; 33 + module_param_array(base, uint, &num_idio_16, 0); 34 + MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses"); 35 + 36 + static unsigned int irq[MAX_NUM_IDIO_16]; 37 + module_param_array(irq, uint, NULL, 0); 38 + MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers"); 37 39 38 40 /** 39 41 * struct idio_16_gpio - GPIO device private data structure ··· 193 185 return IRQ_HANDLED; 194 186 } 195 187 196 - static int __init idio_16_probe(struct platform_device *pdev) 188 + static int idio_16_probe(struct device *dev, unsigned int id) 197 189 { 198 - struct device *dev = &pdev->dev; 199 190 struct idio_16_gpio *idio16gpio; 200 - const unsigned base = idio_16_base; 201 - const unsigned extent = 8; 202 191 const char *const name = dev_name(dev); 203 192 int err; 204 - const unsigned irq = idio_16_irq; 205 193 206 194 idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); 207 195 if (!idio16gpio) 208 196 return -ENOMEM; 209 197 210 - if (!devm_request_region(dev, base, extent, name)) { 198 + if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) { 211 199 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 212 - base, base + extent); 200 + base[id], base[id] + IDIO_16_EXTENT); 213 201 return -EBUSY; 214 202 } 215 203 ··· 219 215 idio16gpio->chip.direction_output = idio_16_gpio_direction_output; 220 216 idio16gpio->chip.get = idio_16_gpio_get; 221 217 idio16gpio->chip.set = idio_16_gpio_set; 222 - idio16gpio->base = base; 223 - idio16gpio->irq = irq; 218 + idio16gpio->base = base[id]; 219 + idio16gpio->irq = irq[id]; 224 220 idio16gpio->out_state = 0xFFFF; 225 221 226 222 spin_lock_init(&idio16gpio->lock); ··· 234 230 } 235 231 236 232 /* Disable IRQ by default */ 237 - outb(0, base + 2); 238 - outb(0, base + 1); 233 + outb(0, base[id] + 2); 234 + outb(0, base[id] + 1); 239 235 240 236 err = gpiochip_irqchip_add(&idio16gpio->chip, &idio_16_irqchip, 0, 241 237 handle_edge_irq, IRQ_TYPE_NONE); ··· 244 240 goto err_gpiochip_remove; 245 241 } 246 242 247 - err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio); 243 + err = request_irq(irq[id], idio_16_irq_handler, 0, name, idio16gpio); 248 244 if (err) { 249 245 dev_err(dev, "IRQ handler registering failed (%d)\n", err); 250 246 goto err_gpiochip_remove; ··· 257 253 return err; 258 254 } 259 255 260 - static int idio_16_remove(struct platform_device *pdev) 256 + static int idio_16_remove(struct device *dev, unsigned int id) 261 257 { 262 - struct idio_16_gpio *const idio16gpio = platform_get_drvdata(pdev); 258 + struct idio_16_gpio *const idio16gpio = dev_get_drvdata(dev); 263 259 264 260 free_irq(idio16gpio->irq, idio16gpio); 265 261 gpiochip_remove(&idio16gpio->chip); ··· 267 263 return 0; 268 264 } 269 265 270 - static struct platform_device *idio_16_device; 271 - 272 - static struct platform_driver idio_16_driver = { 266 + static struct isa_driver idio_16_driver = { 267 + .probe = idio_16_probe, 273 268 .driver = { 274 269 .name = "104-idio-16" 275 270 }, 276 271 .remove = idio_16_remove 277 272 }; 278 273 279 - static void __exit idio_16_exit(void) 280 - { 281 - platform_device_unregister(idio_16_device); 282 - platform_driver_unregister(&idio_16_driver); 283 - } 284 - 285 - static int __init idio_16_init(void) 286 - { 287 - int err; 288 - 289 - idio_16_device = platform_device_alloc(idio_16_driver.driver.name, -1); 290 - if (!idio_16_device) 291 - return -ENOMEM; 292 - 293 - err = platform_device_add(idio_16_device); 294 - if (err) 295 - goto err_platform_device; 296 - 297 - err = platform_driver_probe(&idio_16_driver, idio_16_probe); 298 - if (err) 299 - goto err_platform_driver; 300 - 301 - return 0; 302 - 303 - err_platform_driver: 304 - platform_device_del(idio_16_device); 305 - err_platform_device: 306 - platform_device_put(idio_16_device); 307 - return err; 308 - } 309 - 310 - module_init(idio_16_init); 311 - module_exit(idio_16_exit); 274 + module_isa_driver(idio_16_driver, num_idio_16); 312 275 313 276 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 314 277 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");