Module: xenomai-3 Branch: wip/drivers Commit: bb9c92b86ac166f12d5661950fe53187af3247cf URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=bb9c92b86ac166f12d5661950fe53187af3247cf
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Sep 29 15:22:24 2016 +0200 drivers/gpio: fix enumeration/detection of controllers --- kernel/drivers/gpio/Kconfig | 18 +++++---- kernel/drivers/gpio/gpio-bcm2835.c | 12 +++--- kernel/drivers/gpio/gpio-core.c | 71 +++++++++++++++++++++++++++++++----- kernel/drivers/gpio/gpio-core.h | 10 ++++- kernel/drivers/gpio/gpio-mxc.c | 39 ++------------------ 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/kernel/drivers/gpio/Kconfig b/kernel/drivers/gpio/Kconfig index 850127f..74c56d4 100644 --- a/kernel/drivers/gpio/Kconfig +++ b/kernel/drivers/gpio/Kconfig @@ -1,13 +1,17 @@ menu "Real-time GPIO drivers" config XENO_DRIVERS_GPIO - tristate + tristate "GPIO controller" depends on GPIOLIB + help + + Real-time capable GPIO module. + +if XENO_DRIVERS_GPIO config XENO_DRIVERS_GPIO_BCM2835 depends on MACH_BCM2708 - select XENO_DRIVERS_GPIO - tristate "Support for BCM2835 GPIOs" + bool "Support for BCM2835 GPIOs" help Enables support for the GPIO controller available from @@ -15,15 +19,15 @@ config XENO_DRIVERS_GPIO_BCM2835 config XENO_DRIVERS_GPIO_MXC depends on GPIO_MXC - select XENO_DRIVERS_GPIO - tristate "Support for MXC GPIOs" + bool "Support for MXC GPIOs" help Suitable for the GPIO controller available from Freescale/NXP's MXC architecture. config XENO_DRIVERS_GPIO_DEBUG - depends on XENO_DRIVERS_GPIO bool "Enable GPIO core debugging features" - + +endif + endmenu diff --git a/kernel/drivers/gpio/gpio-bcm2835.c b/kernel/drivers/gpio/gpio-bcm2835.c index f277262..6328955 100644 --- a/kernel/drivers/gpio/gpio-bcm2835.c +++ b/kernel/drivers/gpio/gpio-bcm2835.c @@ -20,20 +20,18 @@ #define RTDM_SUBCLASS_BCM2835 1 -static struct rtdm_gpio_chip bcm2835_gpio_chip; - static int __init bcm2835_gpio_init(void) { - return rtdm_gpiochip_add_by_name(&bcm2835_gpio_chip, "bcm2708_gpio", - RTDM_SUBCLASS_BCM2835); + return rtdm_gpiochip_scan_of(NULL, "brcm,bcm2835-gpio", + RTDM_SUBCLASS_BCM2835); } +module_init(bcm2835_gpio_init); static void __exit bcm2835_gpio_exit(void) { - rtdm_gpiochip_remove(&bcm2835_gpio_chip); + rtdm_gpiochip_remove_of(RTDM_SUBCLASS_BCM2835); } - -module_init(bcm2835_gpio_init); module_exit(bcm2835_gpio_exit); MODULE_LICENSE("GPL"); + diff --git a/kernel/drivers/gpio/gpio-core.c b/kernel/drivers/gpio/gpio-core.c index f18d571..5c08355 100644 --- a/kernel/drivers/gpio/gpio-core.c +++ b/kernel/drivers/gpio/gpio-core.c @@ -203,22 +203,23 @@ static void delete_pin_devices(struct rtdm_gpio_chip *rgc) { struct rtdm_gpio_pin *pin, *n; struct rtdm_device *dev; + rtdm_lockctx_t s; - rtdm_lock_get(&rgc->lock); + rtdm_lock_get_irqsave(&rgc->lock, s); list_for_each_entry_safe(pin, n, &rgc->pins, next) { list_del(&pin->next); - rtdm_lock_put(&rgc->lock); + rtdm_lock_put_irqrestore(&rgc->lock, s); dev = &pin->dev; rtdm_dev_unregister(dev); rtdm_event_destroy(&pin->event); kfree(dev->label); kfree(pin->name); kfree(pin); - rtdm_lock_get(&rgc->lock); + rtdm_lock_get_irqsave(&rgc->lock, s); } - rtdm_lock_put(&rgc->lock); + rtdm_lock_put_irqrestore(&rgc->lock, s); } static int create_pin_devices(struct rtdm_gpio_chip *rgc) @@ -226,6 +227,7 @@ static int create_pin_devices(struct rtdm_gpio_chip *rgc) struct gpio_chip *gc = rgc->gc; struct rtdm_gpio_pin *pin; struct rtdm_device *dev; + rtdm_lockctx_t s; int n, ret; for (n = gc->base; n < gc->base + gc->ngpio - 1; n++) { @@ -252,9 +254,9 @@ static int create_pin_devices(struct rtdm_gpio_chip *rgc) if (ret) goto fail_register; rtdm_event_init(&pin->event, 0); - rtdm_lock_get(&rgc->lock); + rtdm_lock_get_irqsave(&rgc->lock, s); list_add_tail(&pin->next, &rgc->pins); - rtdm_lock_put(&rgc->lock); + rtdm_lock_put_irqrestore(&rgc->lock, s); } return 0; @@ -362,8 +364,41 @@ EXPORT_SYMBOL_GPL(rtdm_gpiochip_add_by_name); #include <linux/of_platform.h> +LIST_HEAD(rtdm_gpio_chips); + +static DEFINE_MUTEX(chip_lock); + +static int match_gpio_chip(struct gpio_chip *gc, void *data) +{ + struct device *dev = data; + + return gc->dev == dev; +} + +static int add_gpio_chip(struct gpio_chip *gc, int type) +{ + struct rtdm_gpio_chip *rgc; + int ret; + + rgc = kzalloc(sizeof(*rgc), GFP_KERNEL); + if (rgc == NULL) + return -ENOMEM; + + ret = rtdm_gpiochip_add(rgc, gc, type); + if (ret) { + kfree(rgc); + return ret; + } + + mutex_lock(&chip_lock); + list_add(&rgc->next, &rtdm_gpio_chips); + mutex_unlock(&chip_lock); + + return 0; +} + int rtdm_gpiochip_scan_of(struct device_node *from, const char *compat, - int (*match)(struct gpio_chip *gc)) + int type) { struct device_node *np = from; struct platform_device *pdev; @@ -378,11 +413,11 @@ int rtdm_gpiochip_scan_of(struct device_node *from, const char *compat, of_node_put(np); if (pdev == NULL) break; - gc = find_chip_by_name(dev_name(&pdev->dev)); + gc = gpiochip_find(&pdev->dev, match_gpio_chip); if (gc) { - ret = match(gc); + ret = add_gpio_chip(gc, type); if (ret) - break; + return ret; } } @@ -390,4 +425,20 @@ int rtdm_gpiochip_scan_of(struct device_node *from, const char *compat, } EXPORT_SYMBOL_GPL(rtdm_gpiochip_scan_of); +void rtdm_gpiochip_remove_of(int type) +{ + struct rtdm_gpio_chip *rgc, *n; + + list_for_each_entry_safe(rgc, n, &rtdm_gpio_chips, next) { + if (rgc->driver.profile_info.subclass_id == type) { + mutex_lock(&chip_lock); + list_del(&rgc->next); + mutex_unlock(&chip_lock); + rtdm_gpiochip_remove(rgc); + kfree(rgc); + } + } +} +EXPORT_SYMBOL_GPL(rtdm_gpiochip_remove_of); + #endif /* CONFIG_OF */ diff --git a/kernel/drivers/gpio/gpio-core.h b/kernel/drivers/gpio/gpio-core.h index c0eac32..11249e8 100644 --- a/kernel/drivers/gpio/gpio-core.h +++ b/kernel/drivers/gpio/gpio-core.h @@ -44,8 +44,14 @@ int rtdm_gpiochip_add_by_name(struct rtdm_gpio_chip *rgc, const char *label, int gpio_subclass); #ifdef CONFIG_OF -int rtdm_gpiochip_scan_of(struct device_node *from, const char *compat, - int (*match)(struct gpio_chip *gc)); + +int rtdm_gpiochip_scan_of(struct device_node *from, + const char *compat, int type); + +void rtdm_gpiochip_remove_of(int type); + +extern struct list_head rtdm_gpio_chips; + #endif #endif /* !_RTDM_GPIO_CORE_H */ diff --git a/kernel/drivers/gpio/gpio-mxc.c b/kernel/drivers/gpio/gpio-mxc.c index 808cd54..520838d 100644 --- a/kernel/drivers/gpio/gpio-mxc.c +++ b/kernel/drivers/gpio/gpio-mxc.c @@ -16,52 +16,21 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <linux/module.h> -#include <linux/list.h> -#include <linux/gpio.h> -#include <linux/slab.h> #include "gpio-core.h" #define RTDM_SUBCLASS_MXC 2 -static LIST_HEAD(mxc_gpio_chips); - -static int match_gpio_chip(struct gpio_chip *gc) -{ - struct rtdm_gpio_chip *rgc; - int ret; - - rgc = kzalloc(sizeof(*rgc), GFP_KERNEL); - if (rgc == NULL) - return -ENOMEM; - - ret = rtdm_gpiochip_add(rgc, gc, RTDM_SUBCLASS_MXC); - if (ret) { - kfree(rgc); - return ret; - } - - list_add(&rgc->next, &mxc_gpio_chips); - - return 0; -} - static int __init mxc_gpio_init(void) { - return rtdm_gpiochip_scan_of(NULL, "fsl,imx6q-gpio", match_gpio_chip); + return rtdm_gpiochip_scan_of(NULL, "fsl,imx6q-gpio", + RTDM_SUBCLASS_MXC); } +module_init(mxc_gpio_init); static void __exit mxc_gpio_exit(void) { - struct rtdm_gpio_chip *rgc, *n; - - list_for_each_entry_safe(rgc, n, &mxc_gpio_chips, next) { - list_del(&rgc->next); - rtdm_gpiochip_remove(rgc); - kfree(rgc); - } + rtdm_gpiochip_remove_of(RTDM_SUBCLASS_MXC); } - -module_init(mxc_gpio_init); module_exit(mxc_gpio_exit); MODULE_LICENSE("GPL"); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git