Module: xenomai-3
Branch: wip/drivers
Commit: b4afc3ed63caaac49881c2be4a9f150ca182e735
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b4afc3ed63caaac49881c2be4a9f150ca182e735

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

Reply via email to