From patchwork Thu Apr 7 14:47:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 607417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3qglq36yKZz9t3t for ; Fri, 8 Apr 2016 00:49:19 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=Fxpvem0q; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756526AbcDGOsw (ORCPT ); Thu, 7 Apr 2016 10:48:52 -0400 Received: from mail-io0-f195.google.com ([209.85.223.195]:32886 "EHLO mail-io0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756017AbcDGOsr (ORCPT ); Thu, 7 Apr 2016 10:48:47 -0400 Received: by mail-io0-f195.google.com with SMTP id g185so12500667ioa.0; Thu, 07 Apr 2016 07:48:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=dgvK1VpKQhoUFsSk2ITRAJwo378PGidfWKYQUAe5YDk=; b=Fxpvem0q1ci6BOV8OM5vxmRJ/iDRDtnF8pYRVRe136atyWV/PCXs/F2+3r/b3C+5QY eGTrLWtaBQUZ3TB3vnMHFkvkAouowl6wU//HPRg3fVXsnsxFUsWk0KEqQztcU0v5h5oh Yuy+4meX9dz4jcAgLVSbY8F6NXlEP3nDalnVQdG0r6z50yoBAk6ATKBfRvl+gzoWO4jJ BeRCMxqnQE7z6/sRAwZwHF66h3gPZT6GVfl6TEGO6D4AuxmjIonE2mXdbP1WlDu/tCRf RXeVcRscC2ZrZQAYHK8pntR09mC4WzUdp2pFJvxJwHfRdUqKKnAJ7OseCaNPlK7enggC 3HuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=dgvK1VpKQhoUFsSk2ITRAJwo378PGidfWKYQUAe5YDk=; b=bvSDzrYtQRzgxENFXkKxJg8wNkp089+kg/JZDFDukD8FA41UsivW/VzBJONvcWHxfO 9fT1Pn7T31hTf4zTw9HowAeyGf+Mq7z0rOHwZTv4MxMnELG08R6JPEC/bjIDsLmbY01/ LDT13nb3UgQt9zi/9yPx6frUrDWBepsBeo1Z7IWS8SnfufQ/rTo6P1zIBnzw1y1gHUjd pRkBurUfRd7fvvhLa3rTXAQetjNL7YGv8RVUZ7wZbw2hR8RtxI11n1ipOavMxssGUxXe fBsxJtTDsXw78diZaOgVsCm1SRAz6cdDGDMx6CNjMaciw9/OvU1VdeH3mWccQOJ12azl 6JCw== X-Gm-Message-State: AD7BkJJUXc2c6g/o9w+YAL3jz5OJd8NA50S5HcyUqa5gMdz+B79/YRyuNiooDXEV+3ltaQ== X-Received: by 10.107.34.139 with SMTP id i133mr3637864ioi.108.1460040526647; Thu, 07 Apr 2016 07:48:46 -0700 (PDT) Received: from localhost (71-47-58-73.res.bhn.net. [71.47.58.73]) by smtp.gmail.com with ESMTPSA id h90sm3733871iod.41.2016.04.07.07.48.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Apr 2016 07:48:46 -0700 (PDT) From: William Breathitt Gray To: gregkh@linuxfoundation.org, tglx@linutronix.de, jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, wim@iguana.be, linux@roeck-us.net, linus.walleij@linaro.org, gnurou@gmail.com Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-watchdog@vger.kernel.org, linux-gpio@vger.kernel.org, William Breathitt Gray Subject: [PATCH 07/10] gpio: 104-dio-48e: Utilize the ISA bus driver Date: Thu, 7 Apr 2016 10:47:28 -0400 Message-Id: X-Mailer: git-send-email 2.7.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The ACCES 104-DIO-48E 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-DIO-48E 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. Signed-off-by: William Breathitt Gray --- drivers/gpio/Kconfig | 9 ++-- drivers/gpio/gpio-104-dio-48e.c | 106 ++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 72 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5f3429f..4ce3f8d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -517,12 +517,13 @@ menu "Port-mapped I/O GPIO drivers" config GPIO_104_DIO_48E tristate "ACCES 104-DIO-48E GPIO support" + depends on ISA_BUS select GPIOLIB_IRQCHIP help - Enables GPIO support for the ACCES 104-DIO-48E family. The base port - address for the device may be configured via the dio_48e_base module - parameter. The interrupt line number for the device may be configured - via the dio_48e_irq module parameter. + Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E, + 104-DIO-24E). The base port addresses for the devices may be + configured via the base module parameter. The interrupt line numbers + for the devices may be configured via the irq module parameter. config GPIO_104_IDIO_16 tristate "ACCES 104-IDIO-16 GPIO support" diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 448a903..1a647c0 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -1,5 +1,5 @@ /* - * GPIO driver for the ACCES 104-DIO-48E + * GPIO driver for the ACCES 104-DIO-48E series * Copyright (C) 2016 William Breathitt Gray * * This program is free software; you can redistribute it and/or modify @@ -10,6 +10,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. + * + * This driver supports the following ACCES devices: 104-DIO-48E and + * 104-DIO-24E. */ #include #include @@ -19,18 +22,23 @@ #include #include #include +#include #include #include #include -#include #include -static unsigned dio_48e_base; -module_param(dio_48e_base, uint, 0); -MODULE_PARM_DESC(dio_48e_base, "ACCES 104-DIO-48E base address"); -static unsigned dio_48e_irq; -module_param(dio_48e_irq, uint, 0); -MODULE_PARM_DESC(dio_48e_irq, "ACCES 104-DIO-48E interrupt line number"); +#define DIO48E_EXTENT 16 +#define MAX_NUM_DIO48E max_num_isa_dev(DIO48E_EXTENT) + +static unsigned int base[MAX_NUM_DIO48E]; +static unsigned int num_dio48e; +module_param_array(base, uint, &num_dio48e, 0); +MODULE_PARM_DESC(base, "ACCES 104-DIO-48E base addresses"); + +static unsigned int irq[MAX_NUM_DIO48E]; +module_param_array(irq, uint, NULL, 0); +MODULE_PARM_DESC(irq, "ACCES 104-DIO-48E interrupt line numbers"); /** * struct dio48e_gpio - GPIO device private data structure @@ -294,23 +302,19 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int __init dio48e_probe(struct platform_device *pdev) +static int dio48e_probe(struct device *dev, unsigned int id) { - struct device *dev = &pdev->dev; struct dio48e_gpio *dio48egpio; - const unsigned base = dio_48e_base; - const unsigned extent = 16; const char *const name = dev_name(dev); int err; - const unsigned irq = dio_48e_irq; dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL); if (!dio48egpio) return -ENOMEM; - if (!devm_request_region(dev, base, extent, name)) { + if (!devm_request_region(dev, base[id], DIO48E_EXTENT, name)) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", - base, base + extent); + base[id], base[id] + DIO48E_EXTENT); return -EBUSY; } @@ -324,8 +328,8 @@ static int __init dio48e_probe(struct platform_device *pdev) dio48egpio->chip.direction_output = dio48e_gpio_direction_output; dio48egpio->chip.get = dio48e_gpio_get; dio48egpio->chip.set = dio48e_gpio_set; - dio48egpio->base = base; - dio48egpio->irq = irq; + dio48egpio->base = base[id]; + dio48egpio->irq = irq[id]; spin_lock_init(&dio48egpio->lock); @@ -338,19 +342,19 @@ static int __init dio48e_probe(struct platform_device *pdev) } /* initialize all GPIO as output */ - outb(0x80, base + 3); - outb(0x00, base); - outb(0x00, base + 1); - outb(0x00, base + 2); - outb(0x00, base + 3); - outb(0x80, base + 7); - outb(0x00, base + 4); - outb(0x00, base + 5); - outb(0x00, base + 6); - outb(0x00, base + 7); + outb(0x80, base[id] + 3); + outb(0x00, base[id]); + outb(0x00, base[id] + 1); + outb(0x00, base[id] + 2); + outb(0x00, base[id] + 3); + outb(0x80, base[id] + 7); + outb(0x00, base[id] + 4); + outb(0x00, base[id] + 5); + outb(0x00, base[id] + 6); + outb(0x00, base[id] + 7); /* disable IRQ by default */ - inb(base + 0xB); + inb(base[id] + 0xB); err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0, handle_edge_irq, IRQ_TYPE_NONE); @@ -359,7 +363,7 @@ static int __init dio48e_probe(struct platform_device *pdev) goto err_gpiochip_remove; } - err = request_irq(irq, dio48e_irq_handler, 0, name, dio48egpio); + err = request_irq(irq[id], dio48e_irq_handler, 0, name, dio48egpio); if (err) { dev_err(dev, "IRQ handler registering failed (%d)\n", err); goto err_gpiochip_remove; @@ -372,9 +376,9 @@ err_gpiochip_remove: return err; } -static int dio48e_remove(struct platform_device *pdev) +static int dio48e_remove(struct device *dev, unsigned int id) { - struct dio48e_gpio *const dio48egpio = platform_get_drvdata(pdev); + struct dio48e_gpio *const dio48egpio = dev_get_drvdata(dev); free_irq(dio48egpio->irq, dio48egpio); gpiochip_remove(&dio48egpio->chip); @@ -382,48 +386,14 @@ static int dio48e_remove(struct platform_device *pdev) return 0; } -static struct platform_device *dio48e_device; - -static struct platform_driver dio48e_driver = { +static struct isa_driver dio48e_driver = { + .probe = dio48e_probe, .driver = { .name = "104-dio-48e" }, .remove = dio48e_remove }; - -static void __exit dio48e_exit(void) -{ - platform_device_unregister(dio48e_device); - platform_driver_unregister(&dio48e_driver); -} - -static int __init dio48e_init(void) -{ - int err; - - dio48e_device = platform_device_alloc(dio48e_driver.driver.name, -1); - if (!dio48e_device) - return -ENOMEM; - - err = platform_device_add(dio48e_device); - if (err) - goto err_platform_device; - - err = platform_driver_probe(&dio48e_driver, dio48e_probe); - if (err) - goto err_platform_driver; - - return 0; - -err_platform_driver: - platform_device_del(dio48e_device); -err_platform_device: - platform_device_put(dio48e_device); - return err; -} - -module_init(dio48e_init); -module_exit(dio48e_exit); +module_isa_driver(dio48e_driver, num_dio48e); MODULE_AUTHOR("William Breathitt Gray "); MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");