diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-74x164.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-74xx-mmio.c | 7 | ||||
-rw-r--r-- | drivers/gpio/gpio-max7301.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-mc33880.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-mcp23s08.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-palmas.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-syscon.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 105 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 153 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 5 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.h | 10 |
13 files changed, 189 insertions, 108 deletions
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index e3d968f751f1..60172f835d15 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -183,7 +183,6 @@ MODULE_DEVICE_TABLE(of, gen_74x164_dt_ids); static struct spi_driver gen_74x164_driver = { .driver = { .name = "74x164", - .owner = THIS_MODULE, .of_match_table = gen_74x164_dt_ids, }, .probe = gen_74x164_probe, diff --git a/drivers/gpio/gpio-74xx-mmio.c b/drivers/gpio/gpio-74xx-mmio.c index 6ed7c0fb3378..6b186829087c 100644 --- a/drivers/gpio/gpio-74xx-mmio.c +++ b/drivers/gpio/gpio-74xx-mmio.c @@ -113,13 +113,16 @@ static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static int mmio_74xx_gpio_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(mmio_74xx_gpio_ids, &pdev->dev); + const struct of_device_id *of_id; struct mmio_74xx_gpio_priv *priv; struct resource *res; void __iomem *dat; int err; + of_id = of_match_device(mmio_74xx_gpio_ids, &pdev->dev); + if (!of_id) + return -ENODEV; + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index 6e1c984a75d4..05813fbf3daf 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c @@ -87,7 +87,6 @@ MODULE_DEVICE_TABLE(spi, max7301_id); static struct spi_driver max7301_driver = { .driver = { .name = "max7301", - .owner = THIS_MODULE, }, .probe = max7301_probe, .remove = max7301_remove, diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index a431604c9e67..2853731db5bc 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -163,7 +163,6 @@ static int mc33880_remove(struct spi_device *spi) static struct spi_driver mc33880_driver = { .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, }, .probe = mc33880_probe, .remove = mc33880_remove, diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 73db7ecd7ffd..4a41694919da 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -848,7 +848,6 @@ MODULE_DEVICE_TABLE(i2c, mcp230xx_id); static struct i2c_driver mcp230xx_driver = { .driver = { .name = "mcp230xx", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mcp23s08_i2c_of_match), }, .probe = mcp230xx_probe, @@ -1021,7 +1020,6 @@ static struct spi_driver mcp23s08_driver = { .id_table = mcp23s08_ids, .driver = { .name = "mcp23s08", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mcp23s08_spi_of_match), }, }; diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index b8dd847443c5..6ea8df6c7397 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -33,7 +33,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/module.h> -#include <asm-generic/bug.h> +#include <linux/bug.h> enum mxc_gpio_hwtype { IMX1_GPIO, /* runs on i.mx1 */ diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 56d2d026e62e..f7fbb46d5d79 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1122,8 +1122,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) /* MPUIO is a bit different, reading IRQ status clears it */ if (bank->is_mpuio) { irqc->irq_ack = dummy_irq_chip.irq_ack; - irqc->irq_mask = irq_gc_mask_set_bit; - irqc->irq_unmask = irq_gc_mask_clr_bit; if (!bank->regs->wkup_en) irqc->irq_set_wake = NULL; } diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index 171a6389f9ce..52b447c071cb 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c @@ -167,6 +167,8 @@ static int palmas_gpio_probe(struct platform_device *pdev) const struct palmas_device_data *dev_data; match = of_match_device(of_palmas_gpio_match, &pdev->dev); + if (!match) + return -ENODEV; dev_data = match->data; if (!dev_data) dev_data = &palmas_dev_data; diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c index 045a952576c7..7b25fdf64802 100644 --- a/drivers/gpio/gpio-syscon.c +++ b/drivers/gpio/gpio-syscon.c @@ -187,11 +187,15 @@ MODULE_DEVICE_TABLE(of, syscon_gpio_ids); static int syscon_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - const struct of_device_id *of_id = of_match_device(syscon_gpio_ids, dev); + const struct of_device_id *of_id; struct syscon_gpio_priv *priv; struct device_node *np = dev->of_node; int ret; + of_id = of_match_device(syscon_gpio_ids, dev); + if (!of_id) + return -ENODEV; + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 027e5f47dd28..896bf29776b0 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -375,6 +375,60 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) } #endif +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static int dbg_gpio_show(struct seq_file *s, void *unused) +{ + int i; + int j; + + for (i = 0; i < tegra_gpio_bank_count; i++) { + for (j = 0; j < 4; j++) { + int gpio = tegra_gpio_compose(i, j, 0); + seq_printf(s, + "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", + i, j, + tegra_gpio_readl(GPIO_CNF(gpio)), + tegra_gpio_readl(GPIO_OE(gpio)), + tegra_gpio_readl(GPIO_OUT(gpio)), + tegra_gpio_readl(GPIO_IN(gpio)), + tegra_gpio_readl(GPIO_INT_STA(gpio)), + tegra_gpio_readl(GPIO_INT_ENB(gpio)), + tegra_gpio_readl(GPIO_INT_LVL(gpio))); + } + } + return 0; +} + +static int dbg_gpio_open(struct inode *inode, struct file *file) +{ + return single_open(file, dbg_gpio_show, &inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = dbg_gpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void tegra_gpio_debuginit(void) +{ + (void) debugfs_create_file("tegra_gpio", S_IRUGO, + NULL, NULL, &debug_fops); +} + +#else + +static inline void tegra_gpio_debuginit(void) +{ +} + +#endif + static struct irq_chip tegra_gpio_irq_chip = { .name = "GPIO", .irq_ack = tegra_gpio_irq_ack, @@ -519,6 +573,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) spin_lock_init(&bank->lvl_lock[j]); } + tegra_gpio_debuginit(); + return 0; } @@ -536,52 +592,3 @@ static int __init tegra_gpio_init(void) return platform_driver_register(&tegra_gpio_driver); } postcore_initcall(tegra_gpio_init); - -#ifdef CONFIG_DEBUG_FS - -#include <linux/debugfs.h> -#include <linux/seq_file.h> - -static int dbg_gpio_show(struct seq_file *s, void *unused) -{ - int i; - int j; - - for (i = 0; i < tegra_gpio_bank_count; i++) { - for (j = 0; j < 4; j++) { - int gpio = tegra_gpio_compose(i, j, 0); - seq_printf(s, - "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", - i, j, - tegra_gpio_readl(GPIO_CNF(gpio)), - tegra_gpio_readl(GPIO_OE(gpio)), - tegra_gpio_readl(GPIO_OUT(gpio)), - tegra_gpio_readl(GPIO_IN(gpio)), - tegra_gpio_readl(GPIO_INT_STA(gpio)), - tegra_gpio_readl(GPIO_INT_ENB(gpio)), - tegra_gpio_readl(GPIO_INT_LVL(gpio))); - } - } - return 0; -} - -static int dbg_gpio_open(struct inode *inode, struct file *file) -{ - return single_open(file, dbg_gpio_show, &inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = dbg_gpio_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init tegra_gpio_debuginit(void) -{ - (void) debugfs_create_file("tegra_gpio", S_IRUGO, - NULL, NULL, &debug_fops); - return 0; -} -late_initcall(tegra_gpio_debuginit); -#endif diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index bbcac3af2a7a..16a7b6816744 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -388,6 +388,8 @@ struct acpi_gpio_lookup { struct acpi_gpio_info info; int index; int pin_index; + bool active_low; + struct acpi_device *adev; struct gpio_desc *desc; int n; }; @@ -424,6 +426,65 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data) return 1; } +static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, + struct acpi_gpio_info *info) +{ + struct list_head res_list; + int ret; + + INIT_LIST_HEAD(&res_list); + + ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio, + lookup); + if (ret < 0) + return ret; + + acpi_dev_free_resource_list(&res_list); + + if (!lookup->desc) + return -ENOENT; + + if (info) { + *info = lookup->info; + if (lookup->active_low) + info->active_low = lookup->active_low; + } + return 0; +} + +static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, + const char *propname, int index, + struct acpi_gpio_lookup *lookup) +{ + struct acpi_reference_args args; + int ret; + + memset(&args, 0, sizeof(args)); + ret = acpi_node_get_property_reference(fwnode, propname, index, &args); + if (ret) { + struct acpi_device *adev = to_acpi_device_node(fwnode); + + if (!adev) + return ret; + + if (!acpi_get_driver_gpio_data(adev, propname, index, &args)) + return ret; + } + /* + * The property was found and resolved, so need to lookup the GPIO based + * on returned args. + */ + lookup->adev = args.adev; + if (args.nargs >= 2) { + lookup->index = args.args[0]; + lookup->pin_index = args.args[1]; + /* 3rd argument, if present is used to specify active_low. */ + if (args.nargs >= 3) + lookup->active_low = !!args.args[2]; + } + return 0; +} + /** * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources * @adev: pointer to a ACPI device to get GPIO from @@ -451,8 +512,6 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, struct acpi_gpio_info *info) { struct acpi_gpio_lookup lookup; - struct list_head resource_list; - bool active_low = false; int ret; if (!adev) @@ -462,58 +521,64 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, lookup.index = index; if (propname) { - struct acpi_reference_args args; - dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); - memset(&args, 0, sizeof(args)); - ret = acpi_dev_get_property_reference(adev, propname, - index, &args); - if (ret) { - bool found = acpi_get_driver_gpio_data(adev, propname, - index, &args); - if (!found) - return ERR_PTR(ret); - } + ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), + propname, index, &lookup); + if (ret) + return ERR_PTR(ret); - /* - * The property was found and resolved so need to - * lookup the GPIO based on returned args instead. - */ - adev = args.adev; - if (args.nargs >= 2) { - lookup.index = args.args[0]; - lookup.pin_index = args.args[1]; - /* - * 3rd argument, if present is used to - * specify active_low. - */ - if (args.nargs >= 3) - active_low = !!args.args[2]; - } - - dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n", - dev_name(&adev->dev), args.nargs, - args.args[0], args.args[1], args.args[2]); + dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n", + dev_name(&lookup.adev->dev), lookup.index, + lookup.pin_index, lookup.active_low); } else { dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); + lookup.adev = adev; } - INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio, - &lookup); - if (ret < 0) - return ERR_PTR(ret); + ret = acpi_gpio_resource_lookup(&lookup, info); + return ret ? ERR_PTR(ret) : lookup.desc; +} + +/** + * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources + * @fwnode: pointer to an ACPI firmware node to get the GPIO information from + * @propname: Property name of the GPIO + * @index: index of GpioIo/GpioInt resource (starting from %0) + * @info: info pointer to fill in (optional) + * + * If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it. + * Otherwise (ie. it is a data-only non-device object), use the property-based + * GPIO lookup to get to the GPIO resource with the relevant information and use + * that to obtain the GPIO descriptor to return. + */ +struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, + const char *propname, int index, + struct acpi_gpio_info *info) +{ + struct acpi_gpio_lookup lookup; + struct acpi_device *adev; + int ret; - acpi_dev_free_resource_list(&resource_list); + adev = to_acpi_device_node(fwnode); + if (adev) + return acpi_get_gpiod_by_index(adev, propname, index, info); - if (lookup.desc && info) { - *info = lookup.info; - if (active_low) - info->active_low = active_low; - } + if (!is_acpi_data_node(fwnode)) + return ERR_PTR(-ENODEV); + + if (!propname) + return ERR_PTR(-EINVAL); + + memset(&lookup, 0, sizeof(lookup)); + lookup.index = index; + + ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); + if (ret) + return ERR_PTR(ret); - return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT); + ret = acpi_gpio_resource_lookup(&lookup, info); + return ret ? ERR_PTR(ret) : lookup.desc; } /** diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6798355c61c6..2a91f3287e3b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -233,7 +233,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name) for (i = 0; i != chip->ngpio; ++i) { struct gpio_desc *gpio = &chip->desc[i]; - if (!gpio->name) + if (!gpio->name || !name) continue; if (!strcmp(gpio->name, name)) { @@ -2209,8 +2209,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; - desc = acpi_get_gpiod_by_index(to_acpi_node(fwnode), propname, 0, - &info); + desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); if (!IS_ERR(desc)) active_low = info.active_low; } diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 78e634d1c719..98ab08c0aa2d 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -42,6 +42,9 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, int index, struct acpi_gpio_info *info); +struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, + const char *propname, int index, + struct acpi_gpio_info *info); int acpi_gpio_count(struct device *dev, const char *con_id); #else @@ -60,7 +63,12 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, { return ERR_PTR(-ENOSYS); } - +static inline struct gpio_desc * +acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, + int index, struct acpi_gpio_info *info) +{ + return ERR_PTR(-ENXIO); +} static inline int acpi_gpio_count(struct device *dev, const char *con_id) { return -ENODEV; |