diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-cadence.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-crystalcove.c | 10 | ||||
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-tegra186.c | 11 | ||||
-rw-r--r-- | drivers/gpio/gpio-wcd934x.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-wcove.c | 39 | ||||
-rw-r--r-- | drivers/gpio/gpio-xilinx.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 61 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-cdev.c | 1 |
10 files changed, 84 insertions, 49 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1dd0ec6727fd..63b84ba161dc 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1367,7 +1367,7 @@ config GPIO_TPS65912 config GPIO_TPS68470 bool "TPS68470 GPIO" - depends on MFD_TPS68470 + depends on INTEL_SKL_INT3472 help Select this option to enable GPIO driver for the TPS68470 chip family. @@ -1383,6 +1383,7 @@ config GPIO_TPS68470 config GPIO_TQMX86 tristate "TQ-Systems QTMX86 GPIO" depends on MFD_TQMX86 || COMPILE_TEST + depends on HAS_IOPORT_MAP select GPIOLIB_IRQCHIP help This driver supports GPIO on the TQMX86 IO controller. @@ -1450,6 +1451,7 @@ menu "PCI GPIO expanders" config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" depends on X86 || COMPILE_TEST + depends on HAS_IOPORT_MAP help The AMD 8111 south bridge contains 32 GPIO pins which can be used. diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c index a4d3239d2594..4ab3fcd9b9ba 100644 --- a/drivers/gpio/gpio-cadence.c +++ b/drivers/gpio/gpio-cadence.c @@ -278,6 +278,7 @@ static const struct of_device_id cdns_of_ids[] = { { .compatible = "cdns,gpio-r1p02" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, cdns_of_ids); static struct platform_driver cdns_gpio_driver = { .driver = { diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 2ba225720086..5a909f3c79e8 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -339,8 +339,6 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) if (!cg) return -ENOMEM; - platform_set_drvdata(pdev, cg); - mutex_init(&cg->buslock); cg->chip.label = KBUILD_MODNAME; cg->chip.direction_input = crystalcove_gpio_dir_in; @@ -372,13 +370,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) return retval; } - retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); - if (retval) { - dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval); - return retval; - } - - return 0; + return devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); } static struct platform_driver crystalcove_gpio_driver = { diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 157106e1e438..b9fdf05d7669 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -334,7 +334,7 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_set_irq_type; ct->chip.irq_set_wake = gpio_set_wake_irq; - ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND; + ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND; ct->regs.ack = GPIO_ISR; ct->regs.mask = GPIO_IMR; diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 1bd9e44df718..05974b760796 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -444,16 +444,6 @@ static int tegra186_irq_set_wake(struct irq_data *data, unsigned int on) return 0; } -static int tegra186_irq_set_affinity(struct irq_data *data, - const struct cpumask *dest, - bool force) -{ - if (data->parent_data) - return irq_chip_set_affinity_parent(data, dest, force); - - return -EINVAL; -} - static void tegra186_gpio_irq(struct irq_desc *desc) { struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); @@ -700,7 +690,6 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->intc.irq_unmask = tegra186_irq_unmask; gpio->intc.irq_set_type = tegra186_irq_set_type; gpio->intc.irq_set_wake = tegra186_irq_set_wake; - gpio->intc.irq_set_affinity = tegra186_irq_set_affinity; irq = &gpio->gpio.irq; irq->chip = &gpio->intc; diff --git a/drivers/gpio/gpio-wcd934x.c b/drivers/gpio/gpio-wcd934x.c index 1cbce5990855..97e6caedf1f3 100644 --- a/drivers/gpio/gpio-wcd934x.c +++ b/drivers/gpio/gpio-wcd934x.c @@ -7,7 +7,7 @@ #include <linux/slab.h> #include <linux/of_device.h> -#define WCD_PIN_MASK(p) BIT(p - 1) +#define WCD_PIN_MASK(p) BIT(p) #define WCD_REG_DIR_CTL_OFFSET 0x42 #define WCD_REG_VAL_CTL_OFFSET 0x43 #define WCD934X_NPINS 5 diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index a19eeef6cf1e..16a0fae1e32e 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -99,19 +99,14 @@ struct wcove_gpio { bool set_irq_mask; }; -static inline int to_reg(int gpio, enum ctrl_register reg_type) +static inline int to_reg(int gpio, enum ctrl_register type) { - unsigned int reg; + unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE; if (gpio >= WCOVE_GPIO_NUM) return -EOPNOTSUPP; - if (reg_type == CTRL_IN) - reg = GPIO_IN_CTRL_BASE + gpio; - else - reg = GPIO_OUT_CTRL_BASE + gpio; - - return reg; + return reg + gpio; } static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) @@ -129,7 +124,7 @@ static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) return reg; } -static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) +static void wcove_update_irq_mask(struct wcove_gpio *wg, irq_hw_number_t gpio) { unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask); @@ -139,13 +134,10 @@ static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) regmap_clear_bits(wg->regmap, reg, mask); } -static void wcove_update_irq_ctrl(struct wcove_gpio *wg, int gpio) +static void wcove_update_irq_ctrl(struct wcove_gpio *wg, irq_hw_number_t gpio) { int reg = to_reg(gpio, CTRL_IN); - if (reg < 0) - return; - regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt); } @@ -248,8 +240,9 @@ static int wcove_irq_type(struct irq_data *data, unsigned int type) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct wcove_gpio *wg = gpiochip_get_data(chip); + irq_hw_number_t gpio = irqd_to_hwirq(data); - if (data->hwirq >= WCOVE_GPIO_NUM) + if (gpio >= WCOVE_GPIO_NUM) return 0; switch (type) { @@ -286,7 +279,7 @@ static void wcove_bus_sync_unlock(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct wcove_gpio *wg = gpiochip_get_data(chip); - int gpio = data->hwirq; + irq_hw_number_t gpio = irqd_to_hwirq(data); if (wg->update & UPDATE_IRQ_TYPE) wcove_update_irq_ctrl(wg, gpio); @@ -301,8 +294,9 @@ static void wcove_irq_unmask(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct wcove_gpio *wg = gpiochip_get_data(chip); + irq_hw_number_t gpio = irqd_to_hwirq(data); - if (data->hwirq >= WCOVE_GPIO_NUM) + if (gpio >= WCOVE_GPIO_NUM) return; wg->set_irq_mask = false; @@ -313,8 +307,9 @@ static void wcove_irq_mask(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct wcove_gpio *wg = gpiochip_get_data(chip); + irq_hw_number_t gpio = irqd_to_hwirq(data); - if (data->hwirq >= WCOVE_GPIO_NUM) + if (gpio >= WCOVE_GPIO_NUM) return; wg->set_irq_mask = true; @@ -369,8 +364,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static void wcove_gpio_dbg_show(struct seq_file *s, - struct gpio_chip *chip) +static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { unsigned int ctlo, ctli, irq_mask, irq_status; struct wcove_gpio *wg = gpiochip_get_data(chip); @@ -379,10 +373,15 @@ static void wcove_gpio_dbg_show(struct seq_file *s, for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) { ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); + if (ret) { + dev_err(wg->dev, "Failed to read registers: CTRL out/in\n"); + break; + } + ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); if (ret) { - pr_err("Failed to read registers: ctrl out/in or irq status/mask\n"); + dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n"); break; } diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index b411d3156e0b..136557e7dd3c 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -542,7 +542,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) } /** - * xgpio_of_probe - Probe method for the GPIO device. + * xgpio_probe - Probe method for the GPIO device. * @pdev: pointer to the platform device * * Return: diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 3ef22a3c104d..411525ac4cc4 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) return gpiochip_get_desc(chip, pin); } +/** + * acpi_get_and_request_gpiod - Translate ACPI GPIO pin to GPIO descriptor and + * hold a refcount to the GPIO device. + * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") + * @pin: ACPI GPIO pin number (0-based, controller-relative) + * @label: Label to pass to gpiod_request() + * + * This function is a simple pass-through to acpi_get_gpiod(), except that + * as it is intended for use outside of the GPIO layer (in a similar fashion to + * gpiod_get_index() for example) it also holds a reference to the GPIO device. + */ +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label) +{ + struct gpio_desc *gpio; + int ret; + + gpio = acpi_get_gpiod(path, pin); + if (IS_ERR(gpio)) + return gpio; + + ret = gpiod_request(gpio, label); + if (ret) + return ERR_PTR(ret); + + return gpio; +} +EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod); + static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) { struct acpi_gpio_event *event = data; @@ -168,6 +196,29 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, } EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource); +/** + * acpi_gpio_get_io_resource - Fetch details of an ACPI resource if it is a GPIO + * I/O resource or return False if not. + * @ares: Pointer to the ACPI resource to fetch + * @agpio: Pointer to a &struct acpi_resource_gpio to store the output pointer + */ +bool acpi_gpio_get_io_resource(struct acpi_resource *ares, + struct acpi_resource_gpio **agpio) +{ + struct acpi_resource_gpio *gpio; + + if (ares->type != ACPI_RESOURCE_TYPE_GPIO) + return false; + + gpio = &ares->data.gpio; + if (gpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_IO) + return false; + + *agpio = gpio; + return true; +} +EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource); + static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, struct acpi_gpio_event *event) { @@ -1233,14 +1284,14 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip) void acpi_gpiochip_add(struct gpio_chip *chip) { struct acpi_gpio_chip *acpi_gpio; - acpi_handle handle; + struct acpi_device *adev; acpi_status status; if (!chip || !chip->parent) return; - handle = ACPI_HANDLE(chip->parent); - if (!handle) + adev = ACPI_COMPANION(chip->parent); + if (!adev) return; acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL); @@ -1254,7 +1305,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) INIT_LIST_HEAD(&acpi_gpio->events); INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry); - status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio); + status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio); if (ACPI_FAILURE(status)) { dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n"); kfree(acpi_gpio); @@ -1263,7 +1314,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) acpi_gpiochip_request_regions(acpi_gpio); acpi_gpiochip_scan_gpios(acpi_gpio); - acpi_walk_dep_device_list(handle); + acpi_dev_clear_dependencies(adev); } void acpi_gpiochip_remove(struct gpio_chip *chip) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 1631727bf0da..c7b5446d01fd 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1880,6 +1880,7 @@ static void gpio_v2_line_info_changed_to_v1( struct gpio_v2_line_info_changed *lic_v2, struct gpioline_info_changed *lic_v1) { + memset(lic_v1, 0, sizeof(*lic_v1)); gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); lic_v1->timestamp = lic_v2->timestamp_ns; lic_v1->event_type = lic_v2->event_type; |