diff options
-rw-r--r-- | Documentation/gpio.txt | 3 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 13 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-bt8xx.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-langwell.c | 51 | ||||
-rw-r--r-- | drivers/gpio/gpio-ml-ioh.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-pch.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-sodaville.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-of.c (renamed from drivers/of/gpio.c) | 0 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 12 | ||||
-rw-r--r-- | drivers/of/Kconfig | 6 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | include/linux/gpio.h | 19 |
13 files changed, 86 insertions, 68 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 620a07844e8..e08a883de36 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -322,6 +322,9 @@ where 'flags' is currently defined to specify the following properties: * GPIOF_OPEN_DRAIN - gpio pin is open drain type. * GPIOF_OPEN_SOURCE - gpio pin is open source type. + * GPIOF_EXPORT_DIR_FIXED - export gpio to sysfs, keep direction + * GPIOF_EXPORT_DIR_CHANGEABLE - also export, allow changing direction + since GPIOF_INIT_* are only valid when configured as output, so group valid combinations as: diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e03653d6935..7875c3f9366 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -37,6 +37,10 @@ menuconfig GPIOLIB if GPIOLIB +config OF_GPIO + def_bool y + depends on OF && !SPARC + config DEBUG_GPIO bool "Debug GPIO calls" depends on DEBUG_KERNEL @@ -243,7 +247,7 @@ config GPIO_MC9S08DZ60 Select this to enable the MC9S08DZ60 GPIO driver config GPIO_PCA953X - tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" + tristate "PCA953x, PCA955x, PCA957x, TCA64xx, and MAX7310 I/O ports" depends on I2C help Say yes here to provide access to several register-oriented @@ -252,10 +256,11 @@ config GPIO_PCA953X 4 bits: pca9536, pca9537 - 8 bits: max7310, pca9534, pca9538, pca9554, pca9557, - tca6408 + 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554, + pca9556, pca9557, pca9574, tca6408 - 16 bits: pca9535, pca9539, pca9555, tca6416 + 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575, + tca6416 config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 007f54bd008..1c2f6c0a835 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -3,6 +3,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o +obj-$(CONFIG_OF_GPIO) += gpiolib-of.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/gpio-bt8xx.c index 5ca4098ba09..e4cc7eb69bb 100644 --- a/drivers/gpio/gpio-bt8xx.c +++ b/drivers/gpio/gpio-bt8xx.c @@ -328,17 +328,7 @@ static struct pci_driver bt8xxgpio_pci_driver = { .resume = bt8xxgpio_resume, }; -static int __init bt8xxgpio_init(void) -{ - return pci_register_driver(&bt8xxgpio_pci_driver); -} -module_init(bt8xxgpio_init) - -static void __exit bt8xxgpio_exit(void) -{ - pci_unregister_driver(&bt8xxgpio_pci_driver); -} -module_exit(bt8xxgpio_exit) +module_pci_driver(bt8xxgpio_pci_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Buesch"); diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index 00692e89ef8..52f00d3cf66 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -263,6 +263,24 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) chip->irq_eoi(data); } +static void lnw_irq_init_hw(struct lnw_gpio *lnw) +{ + void __iomem *reg; + unsigned base; + + for (base = 0; base < lnw->chip.ngpio; base += 32) { + /* Clear the rising-edge detect register */ + reg = gpio_reg(&lnw->chip, base, GRER); + writel(0, reg); + /* Clear the falling-edge detect register */ + reg = gpio_reg(&lnw->chip, base, GFER); + writel(0, reg); + /* Clear the edge detect status register */ + reg = gpio_reg(&lnw->chip, base, GEDR); + writel(~0, reg); + } +} + #ifdef CONFIG_PM static int lnw_gpio_runtime_resume(struct device *dev) { @@ -306,10 +324,11 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, u32 irq_base; u32 gpio_base; int retval = 0; + int ngpio = id->driver_data; retval = pci_enable_device(pdev); if (retval) - goto done; + return retval; retval = pci_request_regions(pdev, "langwell_gpio"); if (retval) { @@ -331,21 +350,28 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, /* get the register base from bar0 */ start = pci_resource_start(pdev, 0); len = pci_resource_len(pdev, 0); - base = ioremap_nocache(start, len); + base = devm_ioremap_nocache(&pdev->dev, start, len); if (!base) { dev_err(&pdev->dev, "error mapping bar0\n"); retval = -EFAULT; goto err3; } - lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL); + lnw = devm_kzalloc(&pdev->dev, sizeof(struct lnw_gpio), GFP_KERNEL); if (!lnw) { dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n"); retval = -ENOMEM; - goto err4; + goto err3; } + + retval = irq_alloc_descs(-1, irq_base, ngpio, 0); + if (retval < 0) { + dev_err(&pdev->dev, "can't allocate IRQ descs\n"); + goto err3; + } + lnw->irq_base = retval; + lnw->reg_base = base; - lnw->irq_base = irq_base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; lnw->chip.direction_input = lnw_gpio_direction_input; @@ -354,15 +380,18 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.set = lnw_gpio_set; lnw->chip.to_irq = lnw_gpio_to_irq; lnw->chip.base = gpio_base; - lnw->chip.ngpio = id->driver_data; + lnw->chip.ngpio = ngpio; lnw->chip.can_sleep = 0; lnw->pdev = pdev; pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); - goto err5; + goto err4; } + + lnw_irq_init_hw(lnw); + irq_set_handler_data(pdev->irq, lnw); irq_set_chained_handler(pdev->irq, lnw_irq_handler); for (i = 0; i < lnw->chip.ngpio; i++) { @@ -376,16 +405,14 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); - goto done; -err5: - kfree(lnw); + return 0; + err4: - iounmap(base); + irq_free_descs(lnw->irq_base, ngpio); err3: pci_release_regions(pdev); err2: pci_disable_device(pdev); -done: return retval; } diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index f0febe5b822..db01f151d41 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -611,17 +611,7 @@ static struct pci_driver ioh_gpio_driver = { .resume = ioh_gpio_resume }; -static int __init ioh_gpio_pci_init(void) -{ - return pci_register_driver(&ioh_gpio_driver); -} -module_init(ioh_gpio_pci_init); - -static void __exit ioh_gpio_pci_exit(void) -{ - pci_unregister_driver(&ioh_gpio_driver); -} -module_exit(ioh_gpio_pci_exit); +module_pci_driver(ioh_gpio_driver); MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e8729cc2ba2..a05fdb6c464 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -539,17 +539,7 @@ static struct pci_driver pch_gpio_driver = { .resume = pch_gpio_resume }; -static int __init pch_gpio_pci_init(void) -{ - return pci_register_driver(&pch_gpio_driver); -} -module_init(pch_gpio_pci_init); - -static void __exit pch_gpio_pci_exit(void) -{ - pci_unregister_driver(&pch_gpio_driver); -} -module_exit(pch_gpio_pci_exit); +module_pci_driver(pch_gpio_driver); MODULE_DESCRIPTION("PCH GPIO PCI Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c index 031e5d24837..820209c420e 100644 --- a/drivers/gpio/gpio-sodaville.c +++ b/drivers/gpio/gpio-sodaville.c @@ -282,17 +282,7 @@ static struct pci_driver sdv_gpio_driver = { .remove = sdv_gpio_remove, }; -static int __init sdv_gpio_init(void) -{ - return pci_register_driver(&sdv_gpio_driver); -} -module_init(sdv_gpio_init); - -static void __exit sdv_gpio_exit(void) -{ - pci_unregister_driver(&sdv_gpio_driver); -} -module_exit(sdv_gpio_exit); +module_pci_driver(sdv_gpio_driver); MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>"); MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs"); diff --git a/drivers/of/gpio.c b/drivers/gpio/gpiolib-of.c index bf984b6dc47..bf984b6dc47 100644 --- a/drivers/of/gpio.c +++ b/drivers/gpio/gpiolib-of.c diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5a75510d66b..566d0122d83 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1302,8 +1302,18 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) (flags & GPIOF_INIT_HIGH) ? 1 : 0); if (err) - gpio_free(gpio); + goto free_gpio; + + if (flags & GPIOF_EXPORT) { + err = gpio_export(gpio, flags & GPIOF_EXPORT_CHANGEABLE); + if (err) + goto free_gpio; + } + + return 0; + free_gpio: + gpio_free(gpio); return err; } EXPORT_SYMBOL_GPL(gpio_request_one); diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 8e84ce9765a..ce00d11144d 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -51,12 +51,6 @@ config OF_IRQ config OF_DEVICE def_bool y -config OF_GPIO - def_bool y - depends on GPIOLIB && !SPARC - help - OpenFirmware GPIO accessors - config OF_I2C def_tristate I2C depends on I2C && !SPARC diff --git a/drivers/of/Makefile b/drivers/of/Makefile index aa90e602c8a..aff2c623039 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o -obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 6155ecf192b..d1890d46b6c 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -20,6 +20,11 @@ /* Gpio pin is open source */ #define GPIOF_OPEN_SOURCE (1 << 3) +#define GPIOF_EXPORT (1 << 2) +#define GPIOF_EXPORT_CHANGEABLE (1 << 3) +#define GPIOF_EXPORT_DIR_FIXED (GPIOF_EXPORT) +#define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE) + /** * struct gpio - a structure describing a GPIO with configuration * @gpio: the GPIO number @@ -55,6 +60,12 @@ static inline int gpio_request(unsigned gpio, const char *label) return -ENOSYS; } +static inline int devm_gpio_request(struct device *dev, unsigned gpio, + const char *label) +{ + return -ENOSYS; +} + static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) { @@ -74,6 +85,14 @@ static inline void gpio_free(unsigned gpio) WARN_ON(1); } +static inline void devm_gpio_free(struct device *dev, unsigned gpio) +{ + might_sleep(); + + /* GPIO can never have been requested */ + WARN_ON(1); +} + static inline void gpio_free_array(const struct gpio *array, size_t num) { might_sleep(); |