summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib-acpi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-04 12:05:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-04 12:05:32 -0700
commit2bd80401743568ced7d303b008ae5298ce77e695 (patch)
treed70278682fca619f7d842faa7c5a5bdce5016cfa /drivers/gpio/gpiolib-acpi.c
parent99a7583de5ffd5cd82c407aad32bcbdeea09155b (diff)
parentb86c86aa9805b25ee70071d084e618b2c40641b5 (diff)
Merge tag 'gpio-v4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO updates from Linus Walleij: "This is the bulk of GPIO changes for the v4.12 kernel cycle. Core changes: - Return NULL from gpiod_get_optional() when GPIOLIB is disabled. This was a much discussed change. It affects use cases where people write drivers that might or might not be using GPIO resources. I have decided that this is the lesser evil right now. - Make gpiod_count() behave consistently across different hardware descriptions. - Fix the syntax around open drain/open source to not infer active high/low semantics. New drivers: - A new single-register fixed-direction framework driver for hardware that have lines controlled by a single register that just work in one direction (out or in), including IRQ support. - Support the Fintek F71889A GPIO SuperIO controller. - Support the National NI 169445 MMIO GPIO. - Support for the X-Gene derivative of the DWC GPIO controller - Support for the Rohm BD9571MWV-M PMIC GPIO controller. - Refactor the Gemini GPIO driver to a generic Faraday FTGPIO driver and replace both the Gemini and the Moxa ART custom drivers with this driver. Driver improvements: - A whole slew of drivers have their spinlocks chaned to raw spinlocks as they provide irqchips, and thus we are progressing on realtime compliance. - Use devm_irq_alloc_descs() in a slew of drivers, getting managed resources. - Support for the embedded PWM controller inside the MVEBU driver. - Debounce, open source and open drain support for the Aspeed driver. - Misc smaller fixes like spelling and syntax and whatnot" * tag 'gpio-v4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (77 commits) gpio: f7188x: Add a missing break gpio: omap: return error if requested debounce time is not possible gpio: Add ROHM BD9571MWV-M PMIC GPIO driver gpio: gpio-wcove: fix GPIO IRQ status mask gpio: DT bindings, move tca9554 from pcf857x to pca953x gpio: move tca9554 from pcf857x to pca953x gpio: arizona: Correct check whether the pin is an input gpio: Add XRA1403 DTS binding documentation dt-bindings: add exar to vendor prefixes list gpio: gpio-wcove: fix irq pending status bit width gpio: dwapb: use dwapb_read instead of readl_relaxed gpio: aspeed: Add open-source and open-drain support gpio: aspeed: Add debounce support gpio: aspeed: dt: Add optional clocks property gpio: aspeed: dt: Fix description alignment in bindings document gpio: mvebu: Add limited PWM support gpio: Use unsigned int for interrupt numbers gpio: f7188x: Add F71889A GPIO support. gpio: core: Decouple open drain/source flag with active low/high gpio: arizona: Correct handling for reading input GPIOs ...
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r--drivers/gpio/gpiolib-acpi.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 2bd683e2be02..2185232da823 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -368,6 +368,37 @@ int acpi_dev_add_driver_gpios(struct acpi_device *adev,
}
EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
+static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res)
+{
+ acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev));
+}
+
+int devm_acpi_dev_add_driver_gpios(struct device *dev,
+ const struct acpi_gpio_mapping *gpios)
+{
+ void *res;
+ int ret;
+
+ res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+
+ ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios);
+ if (ret) {
+ devres_free(res);
+ return ret;
+ }
+ devres_add(dev, res);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios);
+
+void devm_acpi_dev_remove_driver_gpios(struct device *dev)
+{
+ WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL));
+}
+EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios);
+
static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
const char *name, int index,
struct acpi_reference_args *args)
@@ -661,20 +692,24 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
{
int idx, i;
unsigned int irq_flags;
- int ret = -ENOENT;
for (i = 0, idx = 0; idx <= index; i++) {
struct acpi_gpio_info info;
struct gpio_desc *desc;
desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
- if (IS_ERR(desc)) {
- ret = PTR_ERR(desc);
- break;
- }
+
+ /* Ignore -EPROBE_DEFER, it only matters if idx matches */
+ if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
+ return PTR_ERR(desc);
+
if (info.gpioint && idx++ == index) {
- int irq = gpiod_to_irq(desc);
+ int irq;
+ if (IS_ERR(desc))
+ return PTR_ERR(desc);
+
+ irq = gpiod_to_irq(desc);
if (irq < 0)
return irq;
@@ -690,7 +725,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
}
}
- return ret;
+ return -ENOENT;
}
EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
@@ -1075,7 +1110,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
break;
}
}
- if (count >= 0)
+ if (count > 0)
break;
}
@@ -1091,7 +1126,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
if (crs_count > 0)
count = crs_count;
}
- return count;
+ return count ? count : -ENOENT;
}
struct acpi_crs_lookup {