Commit 9b08f832 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-updates-for-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
 "Core GPIOLIB:
   - provide and add users for a macro allowing to iterate over accepted
     GPIO property names of consumer device nodes
   - remove legacy definitions that are no longer used
   - put legacy GPIO devres helpers together with the rest of the
     deprecated code
   - implement and use swnode_gpio_get_reference(): a wrapper
     simplifying the underlying calls to
     fwnode_property_get_reference_args()
   - use IS_ERR_OR_NULL() where it makes sense
   - replace of_find_property() with of_property_present()
   - simplify code with the scoped variant of OF-node children iterator

  Documentation:
   - update GPIO kerneldocs with Return sections
   - fix "Excess struct member description" warnings now being triggered
     with W=1

  New drivers:
   - add support for Analog Devices ADP5585

  Driver improvements:
   - add support for wake-on-GPIO to gpio-mpc8xxx
   - use GPIO_LOOKUP_IDX() in gpio-virtuser
   - use devm_clk_get_[optional_]enabled() where applicable in several
     drivers
   - replace OF-specific functions with provider-agnostic alternatives
     where possible
   - drop support for legacy platform data from gpio-ath79 and
     gpio-davinci
   - refactor gpio-stmpe
   - improve error reporting in gpio-pca953x
   - add support for reading the direction of pins for some models to
     gpio-vf610

  DT bindings:
   - convert the bindings for nxp,lpc3220 to YAML
   - add gpio-reserved-ranges to gpio-davinci
   - simplify the GPIO hog schema
   - fix a GPIO hog issue in bindings for fcs,fxl6408

  Other:
   - fix format specifiers in user-space tools
   - remove leftover files on make clean in tools/gpio/"

* tag 'gpio-updates-for-v6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (54 commits)
  gpio: mpc8xxx: switch to using DEFINE_RUNTIME_DEV_PM_OPS()
  gpio: xilinx: Use helper function devm_clk_get_optional_enabled()
  gpio: mb86s7x: Use helper function devm_clk_get_optional_enabled()
  gpio: lpc18xx: Use helper function devm_clk_get_enabled()
  gpio: cadence: Use helper function devm_clk_get_enabled()
  gpio: sama5d2-piobu: convert comma to semicolon
  gpio: mpc8xxx: order headers alphabetically
  gpio: davinci: use devm_clk_get_enabled()
  gpio: davinci: drop platform data support
  gpio: stmpe: Sort headers
  gpio: stmpe: Make use of device properties
  gpio: stmpe: Utilise temporary variable for struct device
  gpio: stmpe: Remove unused 'dev' member of struct stmpe_gpio
  gpio: stmpe: Fix IRQ related error messages
  gpio: pch: kerneldoc fixes for excess members
  gpio: zynq: Simplify using devm_clk_get_enabled()
  gpio: mpc8xxx: Add wake on GPIO support
  gpio: syscon: fix excess struct member build warning
  gpio: stp-xway: Simplify using devm_clk_get_enabled()
  gpiolib: legacy: Consolidate devm_gpio_*() with other legacy APIs
  ...
parents cc52dc2f 6b5e97c0
...@@ -36,19 +36,8 @@ properties: ...@@ -36,19 +36,8 @@ properties:
patternProperties: patternProperties:
"^(hog-[0-9]+|.+-hog(-[0-9]+)?)$": "^(hog-[0-9]+|.+-hog(-[0-9]+)?)$":
type: object type: object
properties:
gpio-hog: true
gpios: true
output-high: true
output-low: true
line-name: true
required: required:
- gpio-hog - gpio-hog
- gpios
additionalProperties: false
required: required:
- compatible - compatible
......
...@@ -28,6 +28,7 @@ properties: ...@@ -28,6 +28,7 @@ properties:
patternProperties: patternProperties:
"^(hog-[0-9]+|.+-hog(-[0-9]+)?)$": "^(hog-[0-9]+|.+-hog(-[0-9]+)?)$":
type: object
required: required:
- gpio-hog - gpio-hog
......
...@@ -85,19 +85,8 @@ properties: ...@@ -85,19 +85,8 @@ properties:
patternProperties: patternProperties:
"^(hog-[0-9]+|.+-hog(-[0-9]+)?)$": "^(hog-[0-9]+|.+-hog(-[0-9]+)?)$":
type: object type: object
properties:
gpio-hog: true
gpios: true
input: true
output-high: true
output-low: true
line-name: true
required: required:
- gpio-hog - gpio-hog
- gpios
additionalProperties: false
required: required:
- compatible - compatible
......
...@@ -32,6 +32,8 @@ properties: ...@@ -32,6 +32,8 @@ properties:
gpio-ranges: true gpio-ranges: true
gpio-reserved-ranges: true
gpio-line-names: gpio-line-names:
description: strings describing the names of each gpio line. description: strings describing the names of each gpio line.
minItems: 1 minItems: 1
......
...@@ -107,19 +107,8 @@ properties: ...@@ -107,19 +107,8 @@ properties:
patternProperties: patternProperties:
"^(hog-[0-9]+|.+-hog(-[0-9]+)?)$": "^(hog-[0-9]+|.+-hog(-[0-9]+)?)$":
type: object type: object
properties:
gpio-hog: true
gpios: true
input: true
output-high: true
output-low: true
line-name: true
required: required:
- gpio-hog - gpio-hog
- gpios
additionalProperties: false
required: required:
- compatible - compatible
......
NXP LPC32xx SoC GPIO controller
Required properties:
- compatible: must be "nxp,lpc3220-gpio"
- reg: Physical base address and length of the controller's registers.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be 3:
1) bank:
0: GPIO P0
1: GPIO P1
2: GPIO P2
3: GPIO P3
4: GPI P3
5: GPO P3
2) pin number
3) optional parameters:
- bit 0 specifies polarity (0 for normal, 1 for inverted)
- reg: Index of the GPIO group
Example:
gpio: gpio@40028000 {
compatible = "nxp,lpc3220-gpio";
reg = <0x40028000 0x1000>;
gpio-controller;
#gpio-cells = <3>; /* bank, pin, flags */
};
leds {
compatible = "gpio-leds";
led0 {
gpios = <&gpio 5 1 1>; /* GPO_P3 1, active low */
linux,default-trigger = "heartbeat";
default-state = "off";
};
led1 {
gpios = <&gpio 5 14 1>; /* GPO_P3 14, active low */
linux,default-trigger = "timer";
default-state = "off";
};
};
...@@ -49,20 +49,8 @@ properties: ...@@ -49,20 +49,8 @@ properties:
patternProperties: patternProperties:
"^.+-hog(-[0-9]+)?$": "^.+-hog(-[0-9]+)?$":
type: object type: object
additionalProperties: false
properties:
gpio-hog: true
gpios: true
input: true
output-high: true
output-low: true
line-name: true
required: required:
- gpio-hog - gpio-hog
- gpios
allOf: allOf:
- if: - if:
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/nxp,lpc3220-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP LPC3220 SoC GPIO controller
maintainers:
- Animesh Agarwal <animeshagarwal28@gmail.com>
properties:
compatible:
const: nxp,lpc3220-gpio
reg:
maxItems: 1
gpio-controller: true
'#gpio-cells':
const: 3
description: |
1) bank:
0: GPIO P0
1: GPIO P1
2: GPIO P2
3: GPIO P3
4: GPI P3
5: GPO P3
2) pin number
3) flags:
- bit 0 specifies polarity (0 for normal, 1 for inverted)
required:
- compatible
- reg
- gpio-controller
- '#gpio-cells'
additionalProperties: false
examples:
- |
gpio@40028000 {
compatible = "nxp,lpc3220-gpio";
reg = <0x40028000 0x1000>;
gpio-controller;
#gpio-cells = <3>; /* bank, pin, flags */
};
...@@ -55,19 +55,8 @@ properties: ...@@ -55,19 +55,8 @@ properties:
patternProperties: patternProperties:
"^.+-hog(-[0-9]+)?$": "^.+-hog(-[0-9]+)?$":
type: object type: object
properties:
gpio-hog: true
gpios: true
input: true
output-high: true
output-low: true
line-name: true
required: required:
- gpio-hog - gpio-hog
- gpios
additionalProperties: false
required: required:
- compatible - compatible
......
...@@ -76,8 +76,7 @@ static int vision_lcd_setup(struct platform_device *pdev) ...@@ -76,8 +76,7 @@ static int vision_lcd_setup(struct platform_device *pdev)
{ {
int err; int err;
err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_INIT_HIGH, err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_OUT_INIT_HIGH, dev_name(&pdev->dev));
dev_name(&pdev->dev));
if (err) if (err)
return err; return err;
...@@ -293,8 +292,7 @@ static void __init vision_init_machine(void) ...@@ -293,8 +292,7 @@ static void __init vision_init_machine(void)
* Request the gpio expander's interrupt gpio line now to prevent * Request the gpio expander's interrupt gpio line now to prevent
* the kernel from doing a WARN in gpiolib:gpio_ensure_requested(). * the kernel from doing a WARN in gpiolib:gpio_ensure_requested().
*/ */
if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_DIR_IN, if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_IN, "pca9539:74"))
"pca9539:74"))
pr_warn("cannot request interrupt gpio for pca9539:74\n"); pr_warn("cannot request interrupt gpio for pca9539:74\n");
vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7)); vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
......
...@@ -42,7 +42,7 @@ static struct board_info __initdata board_cvg834g = { ...@@ -42,7 +42,7 @@ static struct board_info __initdata board_cvg834g = {
.expected_cpu_id = 0x3368, .expected_cpu_id = 0x3368,
.ephy_reset_gpio = 36, .ephy_reset_gpio = 36,
.ephy_reset_gpio_flags = GPIOF_INIT_HIGH, .ephy_reset_gpio_flags = GPIOF_OUT_INIT_HIGH,
.has_pci = 1, .has_pci = 1,
.has_uart0 = 1, .has_uart0 = 1,
.has_uart1 = 1, .has_uart1 = 1,
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*/ */
#include <linux/device.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/platform_data/gpio-ath79.h>
#include <linux/of.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#define AR71XX_GPIO_REG_OE 0x00 #define AR71XX_GPIO_REG_OE 0x00
#define AR71XX_GPIO_REG_IN 0x04 #define AR71XX_GPIO_REG_IN 0x04
...@@ -224,9 +224,7 @@ MODULE_DEVICE_TABLE(of, ath79_gpio_of_match); ...@@ -224,9 +224,7 @@ MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
static int ath79_gpio_probe(struct platform_device *pdev) static int ath79_gpio_probe(struct platform_device *pdev)
{ {
struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct ath79_gpio_ctrl *ctrl; struct ath79_gpio_ctrl *ctrl;
struct gpio_irq_chip *girq; struct gpio_irq_chip *girq;
u32 ath79_gpio_count; u32 ath79_gpio_count;
...@@ -237,21 +235,14 @@ static int ath79_gpio_probe(struct platform_device *pdev) ...@@ -237,21 +235,14 @@ static int ath79_gpio_probe(struct platform_device *pdev)
if (!ctrl) if (!ctrl)
return -ENOMEM; return -ENOMEM;
if (np) { err = device_property_read_u32(dev, "ngpios", &ath79_gpio_count);
err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); if (err) {
if (err) { dev_err(dev, "ngpios property is not valid\n");
dev_err(dev, "ngpios property is not valid\n"); return err;
return err;
}
oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
} else if (pdata) {
ath79_gpio_count = pdata->ngpios;
oe_inverted = pdata->oe_inverted;
} else {
dev_err(dev, "No DT node or platform data found\n");
return -EINVAL;
} }
oe_inverted = device_is_compatible(dev, "qca,ar9340-gpio");
if (ath79_gpio_count >= 32) { if (ath79_gpio_count >= 32) {
dev_err(dev, "ngpios must be less than 32\n"); dev_err(dev, "ngpios must be less than 32\n");
return -EINVAL; return -EINVAL;
...@@ -275,7 +266,7 @@ static int ath79_gpio_probe(struct platform_device *pdev) ...@@ -275,7 +266,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
} }
/* Optional interrupt setup */ /* Optional interrupt setup */
if (!np || of_property_read_bool(np, "interrupt-controller")) { if (device_property_read_bool(dev, "interrupt-controller")) {
girq = &ctrl->gc.irq; girq = &ctrl->gc.irq;
gpio_irq_chip_set_chip(girq, &ath79_gpio_irqchip); gpio_irq_chip_set_chip(girq, &ath79_gpio_irqchip);
girq->parent_handler = ath79_gpio_irq_handler; girq->parent_handler = ath79_gpio_irq_handler;
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
struct cdns_gpio_chip { struct cdns_gpio_chip {
struct gpio_chip gc; struct gpio_chip gc;
struct clk *pclk;
void __iomem *regs; void __iomem *regs;
u32 bypass_orig; u32 bypass_orig;
}; };
...@@ -155,6 +154,7 @@ static int cdns_gpio_probe(struct platform_device *pdev) ...@@ -155,6 +154,7 @@ static int cdns_gpio_probe(struct platform_device *pdev)
int ret, irq; int ret, irq;
u32 dir_prev; u32 dir_prev;
u32 num_gpios = 32; u32 num_gpios = 32;
struct clk *clk;
cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL); cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL);
if (!cgpio) if (!cgpio)
...@@ -203,21 +203,14 @@ static int cdns_gpio_probe(struct platform_device *pdev) ...@@ -203,21 +203,14 @@ static int cdns_gpio_probe(struct platform_device *pdev)
cgpio->gc.request = cdns_gpio_request; cgpio->gc.request = cdns_gpio_request;
cgpio->gc.free = cdns_gpio_free; cgpio->gc.free = cdns_gpio_free;
cgpio->pclk = devm_clk_get(&pdev->dev, NULL); clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(cgpio->pclk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(cgpio->pclk); ret = PTR_ERR(clk);
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Failed to retrieve peripheral clock, %d\n", ret); "Failed to retrieve peripheral clock, %d\n", ret);
goto err_revert_dir; goto err_revert_dir;
} }
ret = clk_prepare_enable(cgpio->pclk);
if (ret) {
dev_err(&pdev->dev,
"Failed to enable the peripheral clock, %d\n", ret);
goto err_revert_dir;
}
/* /*
* Optional irq_chip support * Optional irq_chip support
*/ */
...@@ -234,7 +227,7 @@ static int cdns_gpio_probe(struct platform_device *pdev) ...@@ -234,7 +227,7 @@ static int cdns_gpio_probe(struct platform_device *pdev)
GFP_KERNEL); GFP_KERNEL);
if (!girq->parents) { if (!girq->parents) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_disable_clk; goto err_revert_dir;
} }
girq->parents[0] = irq; girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE; girq->default_type = IRQ_TYPE_NONE;
...@@ -244,7 +237,7 @@ static int cdns_gpio_probe(struct platform_device *pdev) ...@@ -244,7 +237,7 @@ static int cdns_gpio_probe(struct platform_device *pdev)
ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio); ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
goto err_disable_clk; goto err_revert_dir;
} }
cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE); cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE);
...@@ -259,9 +252,6 @@ static int cdns_gpio_probe(struct platform_device *pdev) ...@@ -259,9 +252,6 @@ static int cdns_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cgpio); platform_set_drvdata(pdev, cgpio);
return 0; return 0;
err_disable_clk:
clk_disable_unprepare(cgpio->pclk);
err_revert_dir: err_revert_dir:
iowrite32(dir_prev, cgpio->regs + CDNS_GPIO_DIRECTION_MODE); iowrite32(dir_prev, cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
...@@ -273,7 +263,6 @@ static void cdns_gpio_remove(struct platform_device *pdev) ...@@ -273,7 +263,6 @@ static void cdns_gpio_remove(struct platform_device *pdev)
struct cdns_gpio_chip *cgpio = platform_get_drvdata(pdev); struct cdns_gpio_chip *cgpio = platform_get_drvdata(pdev);
iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE); iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE);
clk_disable_unprepare(cgpio->pclk);
} }
static const struct of_device_id cdns_of_ids[] = { static const struct of_device_id cdns_of_ids[] = {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -154,74 +153,37 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ...@@ -154,74 +153,37 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
value ? &g->set_data : &g->clr_data); value ? &g->set_data : &g->clr_data);
} }
static struct davinci_gpio_platform_data *
davinci_gpio_get_pdata(struct platform_device *pdev)
{
struct device_node *dn = pdev->dev.of_node;
struct davinci_gpio_platform_data *pdata;
int ret;
u32 val;
if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
return dev_get_platdata(&pdev->dev);
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
ret = of_property_read_u32(dn, "ti,ngpio", &val);
if (ret)
goto of_err;
pdata->ngpio = val;
ret = of_property_read_u32(dn, "ti,davinci-gpio-unbanked", &val);
if (ret)
goto of_err;
pdata->gpio_unbanked = val;
return pdata;
of_err:
dev_err(&pdev->dev, "Populating pdata from DT failed: err %d\n", ret);
return NULL;
}
static int davinci_gpio_probe(struct platform_device *pdev) static int davinci_gpio_probe(struct platform_device *pdev)
{ {
int bank, i, ret = 0; int bank, i, ret = 0;
unsigned int ngpio, nbank, nirq; unsigned int ngpio, nbank, nirq, gpio_unbanked;
struct davinci_gpio_controller *chips; struct davinci_gpio_controller *chips;
struct davinci_gpio_platform_data *pdata;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *dn = dev_of_node(dev);
pdata = davinci_gpio_get_pdata(pdev);
if (!pdata) {
dev_err(dev, "No platform data found\n");
return -EINVAL;
}
dev->platform_data = pdata;
/* /*
* The gpio banks conceptually expose a segmented bitmap, * The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based * and "ngpio" is one more than the largest zero-based
* bit index that's valid. * bit index that's valid.
*/ */
ngpio = pdata->ngpio; ret = of_property_read_u32(dn, "ti,ngpio", &ngpio);
if (ngpio == 0) { if (ret)
dev_err(dev, "How many GPIOs?\n"); return dev_err_probe(dev, ret, "Failed to get the number of GPIOs\n");
return -EINVAL; if (ngpio == 0)
} return dev_err_probe(dev, -EINVAL, "How many GPIOs?\n");
/* /*
* If there are unbanked interrupts then the number of * If there are unbanked interrupts then the number of
* interrupts is equal to number of gpios else all are banked so * interrupts is equal to number of gpios else all are banked so
* number of interrupts is equal to number of banks(each with 16 gpios) * number of interrupts is equal to number of banks(each with 16 gpios)
*/ */
if (pdata->gpio_unbanked) ret = of_property_read_u32(dn, "ti,davinci-gpio-unbanked",
nirq = pdata->gpio_unbanked; &gpio_unbanked);
if (ret)
return dev_err_probe(dev, ret, "Failed to get the unbanked GPIOs property\n");
if (gpio_unbanked)
nirq = gpio_unbanked;
else else
nirq = DIV_ROUND_UP(ngpio, 16); nirq = DIV_ROUND_UP(ngpio, 16);
...@@ -252,7 +214,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) ...@@ -252,7 +214,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
chips->chip.set = davinci_gpio_set; chips->chip.set = davinci_gpio_set;
chips->chip.ngpio = ngpio; chips->chip.ngpio = ngpio;
chips->chip.base = pdata->no_auto_base ? pdata->base : -1; chips->chip.base = -1;
#ifdef CONFIG_OF_GPIO #ifdef CONFIG_OF_GPIO
chips->chip.parent = dev; chips->chip.parent = dev;
...@@ -261,6 +223,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) ...@@ -261,6 +223,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
#endif #endif
spin_lock_init(&chips->lock); spin_lock_init(&chips->lock);
chips->gpio_unbanked = gpio_unbanked;
nbank = DIV_ROUND_UP(ngpio, 32); nbank = DIV_ROUND_UP(ngpio, 32);
for (bank = 0; bank < nbank; bank++) for (bank = 0; bank < nbank; bank++)
chips->regs[bank] = gpio_base + offset_array[bank]; chips->regs[bank] = gpio_base + offset_array[bank];
...@@ -482,13 +446,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -482,13 +446,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
{ {
unsigned gpio, bank; unsigned gpio, bank;
int irq; int irq;
int ret;
struct clk *clk; struct clk *clk;
u32 binten = 0; u32 binten = 0;
unsigned ngpio; unsigned ngpio;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct davinci_gpio_controller *chips = platform_get_drvdata(pdev); struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
struct davinci_gpio_platform_data *pdata = dev->platform_data;
struct davinci_gpio_regs __iomem *g; struct davinci_gpio_regs __iomem *g;
struct irq_domain *irq_domain = NULL; struct irq_domain *irq_domain = NULL;
struct irq_chip *irq_chip; struct irq_chip *irq_chip;
...@@ -502,23 +464,18 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -502,23 +464,18 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
if (dev->of_node) if (dev->of_node)
gpio_get_irq_chip = (gpio_get_irq_chip_cb_t)device_get_match_data(dev); gpio_get_irq_chip = (gpio_get_irq_chip_cb_t)device_get_match_data(dev);
ngpio = pdata->ngpio; ngpio = chips->chip.ngpio;
clk = devm_clk_get(dev, "gpio"); clk = devm_clk_get_enabled(dev, "gpio");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
dev_err(dev, "Error %ld getting gpio clock\n", PTR_ERR(clk)); dev_err(dev, "Error %ld getting gpio clock\n", PTR_ERR(clk));
return PTR_ERR(clk); return PTR_ERR(clk);
} }
ret = clk_prepare_enable(clk); if (chips->gpio_unbanked) {
if (ret)
return ret;
if (!pdata->gpio_unbanked) {
irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0);
if (irq < 0) { if (irq < 0) {
dev_err(dev, "Couldn't allocate IRQ numbers\n"); dev_err(dev, "Couldn't allocate IRQ numbers\n");
clk_disable_unprepare(clk);
return irq; return irq;
} }
...@@ -527,7 +484,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -527,7 +484,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
chips); chips);
if (!irq_domain) { if (!irq_domain) {
dev_err(dev, "Couldn't register an IRQ domain\n"); dev_err(dev, "Couldn't register an IRQ domain\n");
clk_disable_unprepare(clk);
return -ENODEV; return -ENODEV;
} }
} }
...@@ -546,11 +502,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -546,11 +502,11 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
* controller only handling trigger modes. We currently assume no * controller only handling trigger modes. We currently assume no
* IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
*/ */
if (pdata->gpio_unbanked) { if (chips->gpio_unbanked) {
/* pass "bank 0" GPIO IRQs to AINTC */ /* pass "bank 0" GPIO IRQs to AINTC */
chips->chip.to_irq = gpio_to_irq_unbanked; chips->chip.to_irq = gpio_to_irq_unbanked;
chips->gpio_unbanked = pdata->gpio_unbanked;
binten = GENMASK(pdata->gpio_unbanked / 16, 0); binten = GENMASK(chips->gpio_unbanked / 16, 0);
/* AINTC handles mask/unmask; GPIO handles triggering */ /* AINTC handles mask/unmask; GPIO handles triggering */
irq = chips->irqs[0]; irq = chips->irqs[0];
...@@ -564,7 +520,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -564,7 +520,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
writel_relaxed(~0, &g->set_rising); writel_relaxed(~0, &g->set_rising);
/* set the direct IRQs up to use that irqchip */ /* set the direct IRQs up to use that irqchip */
for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++) { for (gpio = 0; gpio < chips->gpio_unbanked; gpio++) {
irq_set_chip(chips->irqs[gpio], irq_chip); irq_set_chip(chips->irqs[gpio], irq_chip);
irq_set_handler_data(chips->irqs[gpio], chips); irq_set_handler_data(chips->irqs[gpio], chips);
irq_set_status_flags(chips->irqs[gpio], irq_set_status_flags(chips->irqs[gpio],
...@@ -596,10 +552,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -596,10 +552,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
sizeof(struct sizeof(struct
davinci_gpio_irq_data), davinci_gpio_irq_data),
GFP_KERNEL); GFP_KERNEL);
if (!irqdata) { if (!irqdata)
clk_disable_unprepare(clk);
return -ENOMEM; return -ENOMEM;
}
irqdata->regs = g; irqdata->regs = g;
irqdata->bank_num = bank; irqdata->bank_num = bank;
...@@ -675,8 +629,7 @@ static void davinci_gpio_restore_context(struct davinci_gpio_controller *chips, ...@@ -675,8 +629,7 @@ static void davinci_gpio_restore_context(struct davinci_gpio_controller *chips,
static int davinci_gpio_suspend(struct device *dev) static int davinci_gpio_suspend(struct device *dev)
{ {
struct davinci_gpio_controller *chips = dev_get_drvdata(dev); struct davinci_gpio_controller *chips = dev_get_drvdata(dev);
struct davinci_gpio_platform_data *pdata = dev_get_platdata(dev); u32 nbank = DIV_ROUND_UP(chips->chip.ngpio, 32);
u32 nbank = DIV_ROUND_UP(pdata->ngpio, 32);
davinci_gpio_save_context(chips, nbank); davinci_gpio_save_context(chips, nbank);
...@@ -686,8 +639,7 @@ static int davinci_gpio_suspend(struct device *dev) ...@@ -686,8 +639,7 @@ static int davinci_gpio_suspend(struct device *dev)
static int davinci_gpio_resume(struct device *dev) static int davinci_gpio_resume(struct device *dev)
{ {
struct davinci_gpio_controller *chips = dev_get_drvdata(dev); struct davinci_gpio_controller *chips = dev_get_drvdata(dev);
struct davinci_gpio_platform_data *pdata = dev_get_platdata(dev); u32 nbank = DIV_ROUND_UP(chips->chip.ngpio, 32);
u32 nbank = DIV_ROUND_UP(pdata->ngpio, 32);
davinci_gpio_restore_context(chips, nbank); davinci_gpio_restore_context(chips, nbank);
......
...@@ -138,7 +138,7 @@ static const __maybe_unused struct of_device_id fxl6408_dt_ids[] = { ...@@ -138,7 +138,7 @@ static const __maybe_unused struct of_device_id fxl6408_dt_ids[] = {
MODULE_DEVICE_TABLE(of, fxl6408_dt_ids); MODULE_DEVICE_TABLE(of, fxl6408_dt_ids);
static const struct i2c_device_id fxl6408_id[] = { static const struct i2c_device_id fxl6408_id[] = {
{ "fxl6408", 0 }, { "fxl6408" },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, fxl6408_id); MODULE_DEVICE_TABLE(i2c, fxl6408_id);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// based on previous work and know-how from: // based on previous work and know-how from:
// Deepak Saxena <dsaxena@plexity.net> // Deepak Saxena <dsaxena@plexity.net>
#include <linux/bitops.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/bitops.h> #include <linux/property.h>
#define IXP4XX_REG_GPOUT 0x00 #define IXP4XX_REG_GPOUT 0x00
#define IXP4XX_REG_GPOE 0x04 #define IXP4XX_REG_GPOE 0x04
...@@ -53,16 +54,14 @@ ...@@ -53,16 +54,14 @@
/** /**
* struct ixp4xx_gpio - IXP4 GPIO state container * struct ixp4xx_gpio - IXP4 GPIO state container
* @dev: containing device for this instance * @dev: containing device for this instance
* @fwnode: the fwnode for this GPIO chip
* @gc: gpiochip for this instance * @gc: gpiochip for this instance
* @base: remapped I/O-memory base * @base: remapped I/O-memory base
* @irq_edge: Each bit represents an IRQ: 1: edge-triggered, * @irq_edge: Each bit represents an IRQ: 1: edge-triggered,
* 0: level triggered * 0: level triggered
*/ */
struct ixp4xx_gpio { struct ixp4xx_gpio {
struct device *dev;
struct fwnode_handle *fwnode;
struct gpio_chip gc; struct gpio_chip gc;
struct device *dev;
void __iomem *base; void __iomem *base;
unsigned long long irq_edge; unsigned long long irq_edge;
}; };
...@@ -237,7 +236,6 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev) ...@@ -237,7 +236,6 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
dev_err(dev, "no IRQ parent domain\n"); dev_err(dev, "no IRQ parent domain\n");
return -ENODEV; return -ENODEV;
} }
g->fwnode = of_node_to_fwnode(np);
/* /*
* If either clock output is enabled explicitly in the device tree * If either clock output is enabled explicitly in the device tree
...@@ -322,7 +320,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev) ...@@ -322,7 +320,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
girq = &g->gc.irq; girq = &g->gc.irq;
gpio_irq_chip_set_chip(girq, &ixp4xx_gpio_irqchip); gpio_irq_chip_set_chip(girq, &ixp4xx_gpio_irqchip);
girq->fwnode = g->fwnode; girq->fwnode = dev_fwnode(dev);
girq->parent_domain = parent; girq->parent_domain = parent;
girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq; girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq;
girq->handler = handle_bad_irq; girq->handler = handle_bad_irq;
......
...@@ -47,7 +47,6 @@ struct lpc18xx_gpio_pin_ic { ...@@ -47,7 +47,6 @@ struct lpc18xx_gpio_pin_ic {
struct lpc18xx_gpio_chip { struct lpc18xx_gpio_chip {
struct gpio_chip gpio; struct gpio_chip gpio;
void __iomem *base; void __iomem *base;
struct clk *clk;
struct lpc18xx_gpio_pin_ic *pin_ic; struct lpc18xx_gpio_pin_ic *pin_ic;
spinlock_t lock; spinlock_t lock;
}; };
...@@ -328,6 +327,7 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev) ...@@ -328,6 +327,7 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct lpc18xx_gpio_chip *gc; struct lpc18xx_gpio_chip *gc;
int index, ret; int index, ret;
struct clk *clk;
gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
if (!gc) if (!gc)
...@@ -352,16 +352,10 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev) ...@@ -352,16 +352,10 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev)
if (IS_ERR(gc->base)) if (IS_ERR(gc->base))
return PTR_ERR(gc->base); return PTR_ERR(gc->base);
gc->clk = devm_clk_get(dev, NULL); clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(gc->clk)) { if (IS_ERR(clk)) {
dev_err(dev, "input clock not found\n"); dev_err(dev, "input clock not found\n");
return PTR_ERR(gc->clk); return PTR_ERR(clk);
}
ret = clk_prepare_enable(gc->clk);
if (ret) {
dev_err(dev, "unable to enable clock\n");
return ret;
} }
spin_lock_init(&gc->lock); spin_lock_init(&gc->lock);
...@@ -369,11 +363,8 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev) ...@@ -369,11 +363,8 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev)
gc->gpio.parent = dev; gc->gpio.parent = dev;
ret = devm_gpiochip_add_data(dev, &gc->gpio, gc); ret = devm_gpiochip_add_data(dev, &gc->gpio, gc);
if (ret) { if (ret)
dev_err(dev, "failed to add gpio chip\n"); return dev_err_probe(dev, ret, "failed to add gpio chip\n");
clk_disable_unprepare(gc->clk);
return ret;
}
/* On error GPIO pin interrupt controller just won't be registered */ /* On error GPIO pin interrupt controller just won't be registered */
lpc18xx_gpio_pin_ic_probe(gc); lpc18xx_gpio_pin_ic_probe(gc);
...@@ -387,8 +378,6 @@ static void lpc18xx_gpio_remove(struct platform_device *pdev) ...@@ -387,8 +378,6 @@ static void lpc18xx_gpio_remove(struct platform_device *pdev)
if (gc->pin_ic) if (gc->pin_ic)
irq_domain_remove(gc->pin_ic->domain); irq_domain_remove(gc->pin_ic->domain);
clk_disable_unprepare(gc->clk);
} }
static const struct of_device_id lpc18xx_gpio_match[] = { static const struct of_device_id lpc18xx_gpio_match[] = {
......
...@@ -53,7 +53,7 @@ static void max7300_remove(struct i2c_client *client) ...@@ -53,7 +53,7 @@ static void max7300_remove(struct i2c_client *client)
} }
static const struct i2c_device_id max7300_id[] = { static const struct i2c_device_id max7300_id[] = {
{ "max7300", 0 }, { "max7300" },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, max7300_id); MODULE_DEVICE_TABLE(i2c, max7300_id);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
struct mb86s70_gpio_chip { struct mb86s70_gpio_chip {
struct gpio_chip gc; struct gpio_chip gc;
void __iomem *base; void __iomem *base;
struct clk *clk;
spinlock_t lock; spinlock_t lock;
}; };
...@@ -157,6 +156,7 @@ static int mb86s70_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) ...@@ -157,6 +156,7 @@ static int mb86s70_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
static int mb86s70_gpio_probe(struct platform_device *pdev) static int mb86s70_gpio_probe(struct platform_device *pdev)
{ {
struct mb86s70_gpio_chip *gchip; struct mb86s70_gpio_chip *gchip;
struct clk *clk;
int ret; int ret;
gchip = devm_kzalloc(&pdev->dev, sizeof(*gchip), GFP_KERNEL); gchip = devm_kzalloc(&pdev->dev, sizeof(*gchip), GFP_KERNEL);
...@@ -169,13 +169,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev) ...@@ -169,13 +169,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
if (IS_ERR(gchip->base)) if (IS_ERR(gchip->base))
return PTR_ERR(gchip->base); return PTR_ERR(gchip->base);
gchip->clk = devm_clk_get_optional(&pdev->dev, NULL); clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR(gchip->clk)) if (IS_ERR(clk))
return PTR_ERR(gchip->clk); return PTR_ERR(clk);
ret = clk_prepare_enable(gchip->clk);
if (ret)
return ret;
spin_lock_init(&gchip->lock); spin_lock_init(&gchip->lock);
...@@ -193,11 +189,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev) ...@@ -193,11 +189,9 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
gchip->gc.base = -1; gchip->gc.base = -1;
ret = gpiochip_add_data(&gchip->gc, gchip); ret = gpiochip_add_data(&gchip->gc, gchip);
if (ret) { if (ret)
dev_err(&pdev->dev, "couldn't register gpio driver\n"); return dev_err_probe(&pdev->dev, ret,
clk_disable_unprepare(gchip->clk); "couldn't register gpio driver\n");
return ret;
}
acpi_gpiochip_request_interrupts(&gchip->gc); acpi_gpiochip_request_interrupts(&gchip->gc);
...@@ -210,7 +204,6 @@ static void mb86s70_gpio_remove(struct platform_device *pdev) ...@@ -210,7 +204,6 @@ static void mb86s70_gpio_remove(struct platform_device *pdev)
acpi_gpiochip_free_interrupts(&gchip->gc); acpi_gpiochip_free_interrupts(&gchip->gc);
gpiochip_remove(&gchip->gc); gpiochip_remove(&gchip->gc);
clk_disable_unprepare(gchip->clk);
} }
static const struct of_device_id mb86s70_gpio_dt_ids[] = { static const struct of_device_id mb86s70_gpio_dt_ids[] = {
......
...@@ -7,19 +7,21 @@ ...@@ -7,19 +7,21 @@
*/ */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/kernel.h> #include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/irq.h> #include <linux/spinlock.h>
#include <linux/gpio/driver.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#define MPC8XXX_GPIO_PINS 32 #define MPC8XXX_GPIO_PINS 32
...@@ -413,6 +415,8 @@ static int mpc8xxx_probe(struct platform_device *pdev) ...@@ -413,6 +415,8 @@ static int mpc8xxx_probe(struct platform_device *pdev)
goto err; goto err;
} }
device_init_wakeup(&pdev->dev, true);
return 0; return 0;
err: err:
irq_domain_remove(mpc8xxx_gc->irq); irq_domain_remove(mpc8xxx_gc->irq);
...@@ -429,6 +433,29 @@ static void mpc8xxx_remove(struct platform_device *pdev) ...@@ -429,6 +433,29 @@ static void mpc8xxx_remove(struct platform_device *pdev)
} }
} }
static int mpc8xxx_suspend(struct device *dev)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = dev_get_drvdata(dev);
if (mpc8xxx_gc->irqn && device_may_wakeup(dev))
enable_irq_wake(mpc8xxx_gc->irqn);
return 0;
}
static int mpc8xxx_resume(struct device *dev)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = dev_get_drvdata(dev);
if (mpc8xxx_gc->irqn && device_may_wakeup(dev))
disable_irq_wake(mpc8xxx_gc->irqn);
return 0;
}
static DEFINE_RUNTIME_DEV_PM_OPS(mpc8xx_pm_ops,
mpc8xxx_suspend, mpc8xxx_resume, NULL);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static const struct acpi_device_id gpio_acpi_ids[] = { static const struct acpi_device_id gpio_acpi_ids[] = {
{"NXP0031",}, {"NXP0031",},
...@@ -444,6 +471,7 @@ static struct platform_driver mpc8xxx_plat_driver = { ...@@ -444,6 +471,7 @@ static struct platform_driver mpc8xxx_plat_driver = {
.name = "gpio-mpc8xxx", .name = "gpio-mpc8xxx",
.of_match_table = mpc8xxx_gpio_ids, .of_match_table = mpc8xxx_gpio_ids,
.acpi_match_table = ACPI_PTR(gpio_acpi_ids), .acpi_match_table = ACPI_PTR(gpio_acpi_ids),
.pm = pm_ptr(&mpc8xx_pm_ops),
}, },
}; };
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/types.h>
#include <dt-bindings/gpio/msc313-gpio.h> #include <dt-bindings/gpio/msc313-gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/arm-gic.h>
...@@ -662,7 +663,7 @@ static int msc313_gpio_probe(struct platform_device *pdev) ...@@ -662,7 +663,7 @@ static int msc313_gpio_probe(struct platform_device *pdev)
gpioirqchip = &gpiochip->irq; gpioirqchip = &gpiochip->irq;
gpio_irq_chip_set_chip(gpioirqchip, &msc313_gpio_irqchip); gpio_irq_chip_set_chip(gpioirqchip, &msc313_gpio_irqchip);
gpioirqchip->fwnode = of_node_to_fwnode(dev->of_node); gpioirqchip->fwnode = dev_fwnode(dev);
gpioirqchip->parent_domain = parent_domain; gpioirqchip->parent_domain = parent_domain;
gpioirqchip->child_to_parent_hwirq = msc313e_gpio_child_to_parent_hwirq; gpioirqchip->child_to_parent_hwirq = msc313e_gpio_child_to_parent_hwirq;
gpioirqchip->populate_parent_alloc_arg = msc313_gpio_populate_parent_fwspec; gpioirqchip->populate_parent_alloc_arg = msc313_gpio_populate_parent_fwspec;
......
...@@ -498,7 +498,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long ...@@ -498,7 +498,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long
ret = regmap_bulk_write(chip->regmap, regaddr, value, NBANK(chip)); ret = regmap_bulk_write(chip->regmap, regaddr, value, NBANK(chip));
if (ret < 0) { if (ret < 0) {
dev_err(&chip->client->dev, "failed writing register\n"); dev_err(&chip->client->dev, "failed writing register: %d\n", ret);
return ret; return ret;
} }
...@@ -513,7 +513,7 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long * ...@@ -513,7 +513,7 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *
ret = regmap_bulk_read(chip->regmap, regaddr, value, NBANK(chip)); ret = regmap_bulk_read(chip->regmap, regaddr, value, NBANK(chip));
if (ret < 0) { if (ret < 0) {
dev_err(&chip->client->dev, "failed reading register\n"); dev_err(&chip->client->dev, "failed reading register: %d\n", ret);
return ret; return ret;
} }
......
...@@ -84,7 +84,6 @@ struct pch_gpio_reg_data { ...@@ -84,7 +84,6 @@ struct pch_gpio_reg_data {
* @gpio: Data for GPIO infrastructure. * @gpio: Data for GPIO infrastructure.
* @pch_gpio_reg: Memory mapped Register data is saved here * @pch_gpio_reg: Memory mapped Register data is saved here
* when suspend. * when suspend.
* @lock: Used for register access protection
* @irq_base: Save base of IRQ number for interrupt * @irq_base: Save base of IRQ number for interrupt
* @ioh: IOH ID * @ioh: IOH ID
* @spinlock: Used for register access protection * @spinlock: Used for register access protection
......
...@@ -191,15 +191,15 @@ static int sama5d2_piobu_probe(struct platform_device *pdev) ...@@ -191,15 +191,15 @@ static int sama5d2_piobu_probe(struct platform_device *pdev)
piobu->chip.label = pdev->name; piobu->chip.label = pdev->name;
piobu->chip.parent = &pdev->dev; piobu->chip.parent = &pdev->dev;
piobu->chip.owner = THIS_MODULE, piobu->chip.owner = THIS_MODULE;
piobu->chip.get_direction = sama5d2_piobu_get_direction, piobu->chip.get_direction = sama5d2_piobu_get_direction;
piobu->chip.direction_input = sama5d2_piobu_direction_input, piobu->chip.direction_input = sama5d2_piobu_direction_input;
piobu->chip.direction_output = sama5d2_piobu_direction_output, piobu->chip.direction_output = sama5d2_piobu_direction_output;
piobu->chip.get = sama5d2_piobu_get, piobu->chip.get = sama5d2_piobu_get;
piobu->chip.set = sama5d2_piobu_set, piobu->chip.set = sama5d2_piobu_set;
piobu->chip.base = -1, piobu->chip.base = -1;
piobu->chip.ngpio = PIOBU_NUM, piobu->chip.ngpio = PIOBU_NUM;
piobu->chip.can_sleep = 0, piobu->chip.can_sleep = 0;
piobu->regmap = syscon_node_to_regmap(pdev->dev.of_node); piobu->regmap = syscon_node_to_regmap(pdev->dev.of_node);
if (IS_ERR(piobu->regmap)) { if (IS_ERR(piobu->regmap)) {
......
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
*/ */
#include <linux/bitops.h>
#include <linux/cleanup.h> #include <linux/cleanup.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/mfd/stmpe.h> #include <linux/mfd/stmpe.h>
#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/bitops.h> #include <linux/slab.h>
/* /*
* These registers are modified under the irq bus lock and cached to avoid * These registers are modified under the irq bus lock and cached to avoid
...@@ -31,7 +31,6 @@ enum { LSB, CSB, MSB }; ...@@ -31,7 +31,6 @@ enum { LSB, CSB, MSB };
struct stmpe_gpio { struct stmpe_gpio {
struct gpio_chip chip; struct gpio_chip chip;
struct stmpe *stmpe; struct stmpe *stmpe;
struct device *dev;
struct mutex irq_lock; struct mutex irq_lock;
u32 norequest_mask; u32 norequest_mask;
/* Caches of interrupt control registers for bus_lock */ /* Caches of interrupt control registers for bus_lock */
...@@ -464,59 +463,49 @@ static void stmpe_gpio_disable(void *stmpe) ...@@ -464,59 +463,49 @@ static void stmpe_gpio_disable(void *stmpe)
static int stmpe_gpio_probe(struct platform_device *pdev) static int stmpe_gpio_probe(struct platform_device *pdev)
{ {
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node; struct stmpe *stmpe = dev_get_drvdata(dev->parent);
struct stmpe_gpio *stmpe_gpio; struct stmpe_gpio *stmpe_gpio;
int ret, irq; int ret, irq;
if (stmpe->num_gpios > MAX_GPIOS) { if (stmpe->num_gpios > MAX_GPIOS) {
dev_err(&pdev->dev, "Need to increase maximum GPIO number\n"); dev_err(dev, "Need to increase maximum GPIO number\n");
return -EINVAL; return -EINVAL;
} }
stmpe_gpio = devm_kzalloc(&pdev->dev, sizeof(*stmpe_gpio), GFP_KERNEL); stmpe_gpio = devm_kzalloc(dev, sizeof(*stmpe_gpio), GFP_KERNEL);
if (!stmpe_gpio) if (!stmpe_gpio)
return -ENOMEM; return -ENOMEM;
mutex_init(&stmpe_gpio->irq_lock); mutex_init(&stmpe_gpio->irq_lock);
stmpe_gpio->dev = &pdev->dev;
stmpe_gpio->stmpe = stmpe; stmpe_gpio->stmpe = stmpe;
stmpe_gpio->chip = template_chip; stmpe_gpio->chip = template_chip;
stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.ngpio = stmpe->num_gpios;
stmpe_gpio->chip.parent = &pdev->dev; stmpe_gpio->chip.parent = dev;
stmpe_gpio->chip.base = -1; stmpe_gpio->chip.base = -1;
if (IS_ENABLED(CONFIG_DEBUG_FS)) if (IS_ENABLED(CONFIG_DEBUG_FS))
stmpe_gpio->chip.dbg_show = stmpe_dbg_show; stmpe_gpio->chip.dbg_show = stmpe_dbg_show;
of_property_read_u32(np, "st,norequest-mask", device_property_read_u32(dev, "st,norequest-mask", &stmpe_gpio->norequest_mask);
&stmpe_gpio->norequest_mask);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
dev_info(&pdev->dev,
"device configured in no-irq mode: "
"irqs are not available\n");
ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
if (ret) if (ret)
return ret; return ret;
ret = devm_add_action_or_reset(&pdev->dev, stmpe_gpio_disable, stmpe); ret = devm_add_action_or_reset(dev, stmpe_gpio_disable, stmpe);
if (ret) if (ret)
return ret; return ret;
irq = platform_get_irq(pdev, 0);
if (irq > 0) { if (irq > 0) {
struct gpio_irq_chip *girq; struct gpio_irq_chip *girq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, ret = devm_request_threaded_irq(dev, irq, NULL, stmpe_gpio_irq,
stmpe_gpio_irq, IRQF_ONESHOT, IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
"stmpe-gpio", stmpe_gpio); if (ret)
if (ret) { return dev_err_probe(dev, ret, "unable to register IRQ handler\n");
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
return ret;
}
girq = &stmpe_gpio->chip.irq; girq = &stmpe_gpio->chip.irq;
gpio_irq_chip_set_chip(girq, &stmpe_gpio_irq_chip); gpio_irq_chip_set_chip(girq, &stmpe_gpio_irq_chip);
...@@ -530,7 +519,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) ...@@ -530,7 +519,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
girq->init_valid_mask = stmpe_init_irq_valid_mask; girq->init_valid_mask = stmpe_init_irq_valid_mask;
} }
return devm_gpiochip_add_data(&pdev->dev, &stmpe_gpio->chip, stmpe_gpio); return devm_gpiochip_add_data(dev, &stmpe_gpio->chip, stmpe_gpio);
} }
static struct platform_driver stmpe_gpio_driver = { static struct platform_driver stmpe_gpio_driver = {
......
...@@ -296,23 +296,17 @@ static int xway_stp_probe(struct platform_device *pdev) ...@@ -296,23 +296,17 @@ static int xway_stp_probe(struct platform_device *pdev)
if (!of_property_read_bool(pdev->dev.of_node, "lantiq,rising")) if (!of_property_read_bool(pdev->dev.of_node, "lantiq,rising"))
chip->edge = XWAY_STP_FALLING; chip->edge = XWAY_STP_FALLING;
clk = devm_clk_get(&pdev->dev, NULL); clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
dev_err(&pdev->dev, "Failed to get clock\n"); dev_err(&pdev->dev, "Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
ret = clk_prepare_enable(clk);
if (ret)
return ret;
xway_stp_hw_init(chip); xway_stp_hw_init(chip);
ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
if (ret) { if (ret)
clk_disable_unprepare(clk);
return ret; return ret;
}
dev_info(&pdev->dev, "Init done\n"); dev_info(&pdev->dev, "Init done\n");
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
/** /**
* struct syscon_gpio_data - Configuration for the device. * struct syscon_gpio_data - Configuration for the device.
* @compatible: SYSCON driver compatible string.
* @flags: Set of GPIO_SYSCON_FEAT_ flags: * @flags: Set of GPIO_SYSCON_FEAT_ flags:
* GPIO_SYSCON_FEAT_IN: GPIOs supports input, * GPIO_SYSCON_FEAT_IN: GPIOs supports input,
* GPIO_SYSCON_FEAT_OUT: GPIOs supports output, * GPIO_SYSCON_FEAT_OUT: GPIOs supports output,
......
...@@ -18,11 +18,12 @@ ...@@ -18,11 +18,12 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/property.h>
#include <linux/seq_file.h>
#define GPIO_BANK(x) ((x) >> 5) #define GPIO_BANK(x) ((x) >> 5)
#define GPIO_PORT(x) (((x) >> 3) & 0x3) #define GPIO_PORT(x) (((x) >> 3) & 0x3)
...@@ -755,7 +756,7 @@ static int tegra_gpio_probe(struct platform_device *pdev) ...@@ -755,7 +756,7 @@ static int tegra_gpio_probe(struct platform_device *pdev)
} }
irq = &tgi->gc.irq; irq = &tgi->gc.irq;
irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); irq->fwnode = dev_fwnode(&pdev->dev);
irq->child_to_parent_hwirq = tegra_gpio_child_to_parent_hwirq; irq->child_to_parent_hwirq = tegra_gpio_child_to_parent_hwirq;
irq->populate_parent_alloc_arg = tegra_gpio_populate_parent_fwspec; irq->populate_parent_alloc_arg = tegra_gpio_populate_parent_fwspec;
irq->handler = handle_simple_irq; irq->handler = handle_simple_irq;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <dt-bindings/gpio/tegra186-gpio.h> #include <dt-bindings/gpio/tegra186-gpio.h>
...@@ -928,7 +929,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) ...@@ -928,7 +929,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
irq = &gpio->gpio.irq; irq = &gpio->gpio.irq;
gpio_irq_chip_set_chip(irq, &tegra186_gpio_irq_chip); gpio_irq_chip_set_chip(irq, &tegra186_gpio_irq_chip);
irq->fwnode = of_node_to_fwnode(pdev->dev.of_node); irq->fwnode = dev_fwnode(&pdev->dev);
irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq; irq->child_to_parent_hwirq = tegra186_gpio_child_to_parent_hwirq;
irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec; irq->populate_parent_alloc_arg = tegra186_gpio_populate_parent_fwspec;
irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq; irq->child_offset_to_irq = tegra186_gpio_child_offset_to_irq;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/property.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#define GPIO_RX_DAT 0x0 #define GPIO_RX_DAT 0x0
...@@ -533,7 +534,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev, ...@@ -533,7 +534,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
chip->set_config = thunderx_gpio_set_config; chip->set_config = thunderx_gpio_set_config;
girq = &chip->irq; girq = &chip->irq;
gpio_irq_chip_set_chip(girq, &thunderx_gpio_irq_chip); gpio_irq_chip_set_chip(girq, &thunderx_gpio_irq_chip);
girq->fwnode = of_node_to_fwnode(dev->of_node); girq->fwnode = dev_fwnode(dev);
girq->parent_domain = girq->parent_domain =
irq_get_irq_data(txgpio->msix_entries[0].vector)->domain; irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq; girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq;
...@@ -549,7 +550,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev, ...@@ -549,7 +550,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
for (i = 0; i < ngpio; i++) { for (i = 0; i < ngpio; i++) {
struct irq_fwspec fwspec; struct irq_fwspec fwspec;
fwspec.fwnode = of_node_to_fwnode(dev->of_node); fwspec.fwnode = dev_fwnode(dev);
fwspec.param_count = 2; fwspec.param_count = 2;
fwspec.param[0] = i; fwspec.param[0] = i;
fwspec.param[1] = IRQ_TYPE_NONE; fwspec.param[1] = IRQ_TYPE_NONE;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <dt-bindings/gpio/uniphier-gpio.h> #include <dt-bindings/gpio/uniphier-gpio.h>
...@@ -164,7 +165,7 @@ static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) ...@@ -164,7 +165,7 @@ static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
if (offset < UNIPHIER_GPIO_IRQ_OFFSET) if (offset < UNIPHIER_GPIO_IRQ_OFFSET)
return -ENXIO; return -ENXIO;
fwspec.fwnode = of_node_to_fwnode(chip->parent->of_node); fwspec.fwnode = dev_fwnode(chip->parent);
fwspec.param_count = 2; fwspec.param_count = 2;
fwspec.param[0] = offset - UNIPHIER_GPIO_IRQ_OFFSET; fwspec.param[0] = offset - UNIPHIER_GPIO_IRQ_OFFSET;
/* /*
...@@ -404,7 +405,7 @@ static int uniphier_gpio_probe(struct platform_device *pdev) ...@@ -404,7 +405,7 @@ static int uniphier_gpio_probe(struct platform_device *pdev)
priv->domain = irq_domain_create_hierarchy( priv->domain = irq_domain_create_hierarchy(
parent_domain, 0, parent_domain, 0,
UNIPHIER_GPIO_IRQ_MAX_NUM, UNIPHIER_GPIO_IRQ_MAX_NUM,
of_node_to_fwnode(dev->of_node), dev_fwnode(dev),
&uniphier_gpio_irq_domain_ops, priv); &uniphier_gpio_irq_domain_ops, priv);
if (!priv->domain) if (!priv->domain)
return -ENOMEM; return -ENOMEM;
......
...@@ -97,7 +97,7 @@ static inline u32 vf610_gpio_readl(void __iomem *reg) ...@@ -97,7 +97,7 @@ static inline u32 vf610_gpio_readl(void __iomem *reg)
static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio) static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(gc); struct vf610_gpio_port *port = gpiochip_get_data(gc);
unsigned long mask = BIT(gpio); u32 mask = BIT(gpio);
unsigned long offset = GPIO_PDIR; unsigned long offset = GPIO_PDIR;
if (port->sdata->have_paddr) { if (port->sdata->have_paddr) {
...@@ -112,16 +112,16 @@ static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio) ...@@ -112,16 +112,16 @@ static int vf610_gpio_get(struct gpio_chip *gc, unsigned int gpio)
static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static void vf610_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(gc); struct vf610_gpio_port *port = gpiochip_get_data(gc);
unsigned long mask = BIT(gpio); u32 mask = BIT(gpio);
unsigned long offset = val ? GPIO_PSOR : GPIO_PCOR; unsigned long offset = val ? GPIO_PSOR : GPIO_PCOR;
vf610_gpio_writel(mask, port->gpio_base + offset); vf610_gpio_writel(mask, port->gpio_base + offset);
} }
static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(chip); struct vf610_gpio_port *port = gpiochip_get_data(chip);
unsigned long mask = BIT(gpio); u32 mask = BIT(gpio);
u32 val; u32 val;
if (port->sdata->have_paddr) { if (port->sdata->have_paddr) {
...@@ -133,11 +133,11 @@ static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) ...@@ -133,11 +133,11 @@ static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
return pinctrl_gpio_direction_input(chip, gpio); return pinctrl_gpio_direction_input(chip, gpio);
} }
static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
int value) int value)
{ {
struct vf610_gpio_port *port = gpiochip_get_data(chip); struct vf610_gpio_port *port = gpiochip_get_data(chip);
unsigned long mask = BIT(gpio); u32 mask = BIT(gpio);
u32 val; u32 val;
vf610_gpio_set(chip, gpio, value); vf610_gpio_set(chip, gpio, value);
...@@ -151,6 +151,19 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, ...@@ -151,6 +151,19 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
return pinctrl_gpio_direction_output(chip, gpio); return pinctrl_gpio_direction_output(chip, gpio);
} }
static int vf610_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
{
struct vf610_gpio_port *port = gpiochip_get_data(gc);
u32 mask = BIT(gpio);
mask &= vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
if (mask)
return GPIO_LINE_DIRECTION_OUT;
return GPIO_LINE_DIRECTION_IN;
}
static void vf610_gpio_irq_handler(struct irq_desc *desc) static void vf610_gpio_irq_handler(struct irq_desc *desc)
{ {
struct vf610_gpio_port *port = struct vf610_gpio_port *port =
...@@ -362,6 +375,12 @@ static int vf610_gpio_probe(struct platform_device *pdev) ...@@ -362,6 +375,12 @@ static int vf610_gpio_probe(struct platform_device *pdev)
gc->get = vf610_gpio_get; gc->get = vf610_gpio_get;
gc->direction_output = vf610_gpio_direction_output; gc->direction_output = vf610_gpio_direction_output;
gc->set = vf610_gpio_set; gc->set = vf610_gpio_set;
/*
* only IP has Port Data Direction Register(PDDR) can
* support get direction
*/
if (port->sdata->have_paddr)
gc->get_direction = vf610_gpio_get_direction;
/* Mask all GPIO interrupts */ /* Mask all GPIO interrupts */
for (i = 0; i < gc->ngpio; i++) for (i = 0; i < gc->ngpio; i++)
......
...@@ -1410,7 +1410,6 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) ...@@ -1410,7 +1410,6 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev)
size_t num_entries = gpio_virtuser_get_lookup_count(dev); size_t num_entries = gpio_virtuser_get_lookup_count(dev);
struct gpio_virtuser_lookup_entry *entry; struct gpio_virtuser_lookup_entry *entry;
struct gpio_virtuser_lookup *lookup; struct gpio_virtuser_lookup *lookup;
struct gpiod_lookup *curr;
unsigned int i = 0; unsigned int i = 0;
lockdep_assert_held(&dev->lock); lockdep_assert_held(&dev->lock);
...@@ -1426,14 +1425,10 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) ...@@ -1426,14 +1425,10 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev)
list_for_each_entry(lookup, &dev->lookup_list, siblings) { list_for_each_entry(lookup, &dev->lookup_list, siblings) {
list_for_each_entry(entry, &lookup->entry_list, siblings) { list_for_each_entry(entry, &lookup->entry_list, siblings) {
curr = &table->table[i]; table->table[i] =
GPIO_LOOKUP_IDX(entry->key,
curr->con_id = lookup->con_id; entry->offset < 0 ? U16_MAX : entry->offset,
curr->idx = i; lookup->con_id, i, entry->flags);
curr->key = entry->key;
curr->chip_hwnum = entry->offset < 0 ?
U16_MAX : entry->offset;
curr->flags = entry->flags;
i++; i++;
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*/ */
#include <linux/bitops.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -15,8 +16,8 @@ ...@@ -15,8 +16,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/bitops.h>
/* register offset */ /* register offset */
#define GPIO_DIR 0x00 #define GPIO_DIR 0x00
...@@ -202,7 +203,7 @@ static int visconti_gpio_probe(struct platform_device *pdev) ...@@ -202,7 +203,7 @@ static int visconti_gpio_probe(struct platform_device *pdev)
girq = &priv->gpio_chip.irq; girq = &priv->gpio_chip.irq;
gpio_irq_chip_set_chip(girq, &visconti_gpio_irq_chip); gpio_irq_chip_set_chip(girq, &visconti_gpio_irq_chip);
girq->fwnode = of_node_to_fwnode(dev->of_node); girq->fwnode = dev_fwnode(dev);
girq->parent_domain = parent; girq->parent_domain = parent;
girq->child_to_parent_hwirq = visconti_gpio_child_to_parent_hwirq; girq->child_to_parent_hwirq = visconti_gpio_child_to_parent_hwirq;
girq->populate_parent_alloc_arg = visconti_gpio_populate_parent_fwspec; girq->populate_parent_alloc_arg = visconti_gpio_populate_parent_fwspec;
......
...@@ -333,12 +333,9 @@ static int __maybe_unused xgpio_suspend(struct device *dev) ...@@ -333,12 +333,9 @@ static int __maybe_unused xgpio_suspend(struct device *dev)
*/ */
static void xgpio_remove(struct platform_device *pdev) static void xgpio_remove(struct platform_device *pdev)
{ {
struct xgpio_instance *gpio = platform_get_drvdata(pdev);
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(gpio->clk);
} }
/** /**
...@@ -644,15 +641,10 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -644,15 +641,10 @@ static int xgpio_probe(struct platform_device *pdev)
return PTR_ERR(chip->regs); return PTR_ERR(chip->regs);
} }
chip->clk = devm_clk_get_optional(&pdev->dev, NULL); chip->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR(chip->clk)) if (IS_ERR(chip->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(chip->clk), "input clock not found.\n"); return dev_err_probe(&pdev->dev, PTR_ERR(chip->clk), "input clock not found.\n");
status = clk_prepare_enable(chip->clk);
if (status < 0) {
dev_err(&pdev->dev, "Failed to prepare clk\n");
return status;
}
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
...@@ -699,7 +691,6 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -699,7 +691,6 @@ static int xgpio_probe(struct platform_device *pdev)
err_pm_put: err_pm_put:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
clk_disable_unprepare(chip->clk);
return status; return status;
} }
......
...@@ -940,16 +940,10 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -940,16 +940,10 @@ static int zynq_gpio_probe(struct platform_device *pdev)
chip->ngpio = gpio->p_data->ngpio; chip->ngpio = gpio->p_data->ngpio;
/* Retrieve GPIO clock */ /* Retrieve GPIO clock */
gpio->clk = devm_clk_get(&pdev->dev, NULL); gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(gpio->clk)) if (IS_ERR(gpio->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(gpio->clk), "input clock not found.\n"); return dev_err_probe(&pdev->dev, PTR_ERR(gpio->clk), "input clock not found.\n");
ret = clk_prepare_enable(gpio->clk);
if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n");
return ret;
}
spin_lock_init(&gpio->dirlock); spin_lock_init(&gpio->dirlock);
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
...@@ -999,7 +993,6 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -999,7 +993,6 @@ static int zynq_gpio_probe(struct platform_device *pdev)
pm_runtime_put(&pdev->dev); pm_runtime_put(&pdev->dev);
err_pm_dis: err_pm_dis:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(gpio->clk);
return ret; return ret;
} }
...@@ -1019,7 +1012,6 @@ static void zynq_gpio_remove(struct platform_device *pdev) ...@@ -1019,7 +1012,6 @@ static void zynq_gpio_remove(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n");
gpiochip_remove(&gpio->chip); gpiochip_remove(&gpio->chip);
clk_disable_unprepare(gpio->clk);
device_set_wakeup_capable(&pdev->dev, 0); device_set_wakeup_capable(&pdev->dev, 0);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
} }
......
...@@ -153,8 +153,12 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) ...@@ -153,8 +153,12 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data)
* @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
* @pin: ACPI GPIO pin number (0-based, controller-relative) * @pin: ACPI GPIO pin number (0-based, controller-relative)
* *
* Return: GPIO descriptor to use with Linux generic GPIO API, or ERR_PTR * Returns:
* error value. Specifically returns %-EPROBE_DEFER if the referenced GPIO * GPIO descriptor to use with Linux generic GPIO API.
* If the GPIO cannot be translated or there is an error an ERR_PTR is
* returned.
*
* Specifically returns %-EPROBE_DEFER if the referenced GPIO
* controller does not have GPIO chip registered at the moment. This is to * controller does not have GPIO chip registered at the moment. This is to
* support probe deferral. * support probe deferral.
*/ */
...@@ -224,6 +228,9 @@ EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource); ...@@ -224,6 +228,9 @@ EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);
* I/O resource or return False if not. * I/O resource or return False if not.
* @ares: Pointer to the ACPI resource to fetch * @ares: Pointer to the ACPI resource to fetch
* @agpio: Pointer to a &struct acpi_resource_gpio to store the output pointer * @agpio: Pointer to a &struct acpi_resource_gpio to store the output pointer
*
* Returns:
* %true if GpioIo resource is found, %false otherwise.
*/ */
bool acpi_gpio_get_io_resource(struct acpi_resource *ares, bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio) struct acpi_resource_gpio **agpio)
...@@ -876,7 +883,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, ...@@ -876,7 +883,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
* that case @index is used to select the GPIO entry in the property value * that case @index is used to select the GPIO entry in the property value
* (in case of multiple). * (in case of multiple).
* *
* If the GPIO cannot be translated or there is an error, an ERR_PTR is * Returns:
* GPIO descriptor to use with Linux generic GPIO API.
* If the GPIO cannot be translated or there is an error an ERR_PTR is
* returned. * returned.
* *
* Note: if the GPIO resource has multiple entries in the pin list, this * Note: if the GPIO resource has multiple entries in the pin list, this
...@@ -924,6 +933,8 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, ...@@ -924,6 +933,8 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
* resource with the relevant information from a data-only ACPI firmware node * resource with the relevant information from a data-only ACPI firmware node
* and uses that to obtain the GPIO descriptor to return. * and uses that to obtain the GPIO descriptor to return.
* *
* Returns:
* GPIO descriptor to use with Linux generic GPIO API.
* If the GPIO cannot be translated or there is an error an ERR_PTR is * If the GPIO cannot be translated or there is an error an ERR_PTR is
* returned. * returned.
*/ */
...@@ -973,18 +984,9 @@ __acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int ...@@ -973,18 +984,9 @@ __acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int
struct acpi_device *adev = to_acpi_device_node(fwnode); struct acpi_device *adev = to_acpi_device_node(fwnode);
struct gpio_desc *desc; struct gpio_desc *desc;
char propname[32]; char propname[32];
int i;
/* Try first from _DSD */ /* Try first from _DSD */
for (i = 0; i < gpio_suffix_count; i++) { for_each_gpio_property_name(propname, con_id) {
if (con_id) {
snprintf(propname, sizeof(propname), "%s-%s",
con_id, gpio_suffixes[i]);
} else {
snprintf(propname, sizeof(propname), "%s",
gpio_suffixes[i]);
}
if (adev) if (adev)
desc = acpi_get_gpiod_by_index(adev, desc = acpi_get_gpiod_by_index(adev,
propname, idx, info); propname, idx, info);
...@@ -1051,7 +1053,8 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, ...@@ -1051,7 +1053,8 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
* The GPIO is considered wake capable if the GpioInt resource specifies * The GPIO is considered wake capable if the GpioInt resource specifies
* SharedAndWake or ExclusiveAndWake. * SharedAndWake or ExclusiveAndWake.
* *
* Return: Linux IRQ number (> %0) on success, negative errno on failure. * Returns:
* Linux IRQ number (> 0) on success, negative errno on failure.
*/ */
int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *con_id, int index, int acpi_dev_gpio_irq_wake_get_by(struct acpi_device *adev, const char *con_id, int index,
bool *wake_capable) bool *wake_capable)
...@@ -1438,7 +1441,7 @@ static int acpi_find_gpio_count(struct acpi_resource *ares, void *data) ...@@ -1438,7 +1441,7 @@ static int acpi_find_gpio_count(struct acpi_resource *ares, void *data)
* @fwnode: firmware node of the GPIO consumer * @fwnode: firmware node of the GPIO consumer
* @con_id: function within the GPIO consumer * @con_id: function within the GPIO consumer
* *
* Return: * Returns:
* The number of GPIOs associated with a firmware node / function or %-ENOENT, * The number of GPIOs associated with a firmware node / function or %-ENOENT,
* if no GPIO has been assigned to the requested function. * if no GPIO has been assigned to the requested function.
*/ */
...@@ -1450,17 +1453,9 @@ int acpi_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) ...@@ -1450,17 +1453,9 @@ int acpi_gpio_count(const struct fwnode_handle *fwnode, const char *con_id)
int count = -ENOENT; int count = -ENOENT;
int ret; int ret;
char propname[32]; char propname[32];
unsigned int i;
/* Try first from _DSD */ /* Try first from _DSD */
for (i = 0; i < gpio_suffix_count; i++) { for_each_gpio_property_name(propname, con_id) {
if (con_id)
snprintf(propname, sizeof(propname), "%s-%s",
con_id, gpio_suffixes[i]);
else
snprintf(propname, sizeof(propname), "%s",
gpio_suffixes[i]);
ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, &obj); ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, &obj);
if (ret == 0) { if (ret == 0) {
if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) if (obj->type == ACPI_TYPE_LOCAL_REFERENCE)
......
...@@ -2748,7 +2748,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf, ...@@ -2748,7 +2748,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
* gpio_chrdev_open() - open the chardev for ioctl operations * gpio_chrdev_open() - open the chardev for ioctl operations
* @inode: inode for this chardev * @inode: inode for this chardev
* @file: file struct for storing private data * @file: file struct for storing private data
* Returns 0 on success *
* Returns:
* 0 on success, or negative errno on failure.
*/ */
static int gpio_chrdev_open(struct inode *inode, struct file *file) static int gpio_chrdev_open(struct inode *inode, struct file *file)
{ {
...@@ -2814,7 +2816,9 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) ...@@ -2814,7 +2816,9 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
* gpio_chrdev_release() - close chardev after ioctl operations * gpio_chrdev_release() - close chardev after ioctl operations
* @inode: inode for this chardev * @inode: inode for this chardev
* @file: file struct for storing private data * @file: file struct for storing private data
* Returns 0 on success *
* Returns:
* 0 on success, or negative errno on failure.
*/ */
static int gpio_chrdev_release(struct inode *inode, struct file *file) static int gpio_chrdev_release(struct inode *inode, struct file *file)
{ {
......
...@@ -6,15 +6,19 @@ ...@@ -6,15 +6,19 @@
* Copyright (c) 2011 John Crispin <john@phrozen.org> * Copyright (c) 2011 John Crispin <john@phrozen.org>
*/ */
#include <linux/module.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/types.h>
#include <linux/gpio/consumer.h>
#include "gpiolib.h" #include "gpiolib.h"
struct fwnode_handle;
struct lock_class_key;
static void devm_gpiod_release(struct device *dev, void *res) static void devm_gpiod_release(struct device *dev, void *res)
{ {
struct gpio_desc **desc = res; struct gpio_desc **desc = res;
...@@ -52,6 +56,11 @@ static int devm_gpiod_match_array(struct device *dev, void *res, void *data) ...@@ -52,6 +56,11 @@ static int devm_gpiod_match_array(struct device *dev, void *res, void *data)
* Managed gpiod_get(). GPIO descriptors returned from this function are * Managed gpiod_get(). GPIO descriptors returned from this function are
* automatically disposed on driver detach. See gpiod_get() for detailed * automatically disposed on driver detach. See gpiod_get() for detailed
* information about behavior and return values. * information about behavior and return values.
*
* Returns:
* The GPIO descriptor corresponding to the function @con_id of device
* dev, %-ENOENT if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/ */
struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
const char *con_id, const char *con_id,
...@@ -70,6 +79,11 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get); ...@@ -70,6 +79,11 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get);
* Managed gpiod_get_optional(). GPIO descriptors returned from this function * Managed gpiod_get_optional(). GPIO descriptors returned from this function
* are automatically disposed on driver detach. See gpiod_get_optional() for * are automatically disposed on driver detach. See gpiod_get_optional() for
* detailed information about behavior and return values. * detailed information about behavior and return values.
*
* Returns:
* The GPIO descriptor corresponding to the function @con_id of device
* dev, NULL if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/ */
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev, struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id, const char *con_id,
...@@ -89,6 +103,11 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_optional); ...@@ -89,6 +103,11 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_optional);
* Managed gpiod_get_index(). GPIO descriptors returned from this function are * Managed gpiod_get_index(). GPIO descriptors returned from this function are
* automatically disposed on driver detach. See gpiod_get_index() for detailed * automatically disposed on driver detach. See gpiod_get_index() for detailed
* information about behavior and return values. * information about behavior and return values.
*
* Returns:
* The GPIO descriptor corresponding to the function @con_id of device
* dev, %-ENOENT if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/ */
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
const char *con_id, const char *con_id,
...@@ -141,8 +160,10 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_index); ...@@ -141,8 +160,10 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_index);
* GPIO descriptors returned from this function are automatically disposed on * GPIO descriptors returned from this function are automatically disposed on
* driver detach. * driver detach.
* *
* On successful request the GPIO pin is configured in accordance with * Returns:
* provided @flags. * The GPIO descriptor corresponding to the function @con_id of device
* dev, %-ENOENT if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/ */
struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev, struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev,
struct fwnode_handle *fwnode, struct fwnode_handle *fwnode,
...@@ -182,6 +203,11 @@ EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index); ...@@ -182,6 +203,11 @@ EXPORT_SYMBOL_GPL(devm_fwnode_gpiod_get_index);
* function are automatically disposed on driver detach. See * function are automatically disposed on driver detach. See
* gpiod_get_index_optional() for detailed information about behavior and * gpiod_get_index_optional() for detailed information about behavior and
* return values. * return values.
*
* Returns:
* The GPIO descriptor corresponding to the function @con_id of device
* dev, %NULL if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/ */
struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev, struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
const char *con_id, const char *con_id,
...@@ -207,6 +233,12 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional); ...@@ -207,6 +233,12 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional);
* Managed gpiod_get_array(). GPIO descriptors returned from this function are * Managed gpiod_get_array(). GPIO descriptors returned from this function are
* automatically disposed on driver detach. See gpiod_get_array() for detailed * automatically disposed on driver detach. See gpiod_get_array() for detailed
* information about behavior and return values. * information about behavior and return values.
*
* Returns:
* The GPIO descriptors corresponding to the function @con_id of device
* dev, %-ENOENT if no GPIO has been assigned to the requested function,
* or another IS_ERR() code if an error occurred while trying to acquire
* the GPIOs.
*/ */
struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
const char *con_id, const char *con_id,
...@@ -243,6 +275,12 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_array); ...@@ -243,6 +275,12 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_array);
* function are automatically disposed on driver detach. * function are automatically disposed on driver detach.
* See gpiod_get_array_optional() for detailed information about behavior and * See gpiod_get_array_optional() for detailed information about behavior and
* return values. * return values.
*
* Returns:
* The GPIO descriptors corresponding to the function @con_id of device
* dev, %NULL if no GPIO has been assigned to the requested function,
* or another IS_ERR() code if an error occurred while trying to acquire
* the GPIOs.
*/ */
struct gpio_descs *__must_check struct gpio_descs *__must_check
devm_gpiod_get_array_optional(struct device *dev, const char *con_id, devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
...@@ -320,76 +358,6 @@ void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs) ...@@ -320,76 +358,6 @@ void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
} }
EXPORT_SYMBOL_GPL(devm_gpiod_put_array); EXPORT_SYMBOL_GPL(devm_gpiod_put_array);
static void devm_gpio_release(struct device *dev, void *res)
{
unsigned *gpio = res;
gpio_free(*gpio);
}
/**
* devm_gpio_request - request a GPIO for a managed device
* @dev: device to request the GPIO for
* @gpio: GPIO to allocate
* @label: the name of the requested GPIO
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as
* gpio_request(). GPIOs requested with this function will be
* automatically freed on driver detach.
*/
int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
{
unsigned *dr;
int rc;
dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
if (!dr)
return -ENOMEM;
rc = gpio_request(gpio, label);
if (rc) {
devres_free(dr);
return rc;
}
*dr = gpio;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_gpio_request);
/**
* devm_gpio_request_one - request a single GPIO with initial setup
* @dev: device to request for
* @gpio: the GPIO number
* @flags: GPIO configuration as specified by GPIOF_*
* @label: a literal description string of this GPIO
*/
int devm_gpio_request_one(struct device *dev, unsigned gpio,
unsigned long flags, const char *label)
{
unsigned *dr;
int rc;
dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
if (!dr)
return -ENOMEM;
rc = gpio_request_one(gpio, flags, label);
if (rc) {
devres_free(dr);
return rc;
}
*dr = gpio;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_gpio_request_one);
static void devm_gpio_chip_release(void *data) static void devm_gpio_chip_release(void *data)
{ {
struct gpio_chip *gc = data; struct gpio_chip *gc = data;
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
...@@ -22,6 +28,9 @@ EXPORT_SYMBOL_GPL(gpio_free); ...@@ -22,6 +28,9 @@ EXPORT_SYMBOL_GPL(gpio_free);
* @label: a literal description string of this GPIO * @label: a literal description string of this GPIO
* *
* **DEPRECATED** This function is deprecated and must not be used in new code. * **DEPRECATED** This function is deprecated and must not be used in new code.
*
* Returns:
* 0 on success, or negative errno on failure.
*/ */
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
{ {
...@@ -40,11 +49,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) ...@@ -40,11 +49,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
if (flags & GPIOF_ACTIVE_LOW) if (flags & GPIOF_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags); set_bit(FLAG_ACTIVE_LOW, &desc->flags);
if (flags & GPIOF_DIR_IN) if (flags & GPIOF_IN)
err = gpiod_direction_input(desc); err = gpiod_direction_input(desc);
else else
err = gpiod_direction_output_raw(desc, err = gpiod_direction_output_raw(desc, !!(flags & GPIOF_OUT_INIT_HIGH));
(flags & GPIOF_INIT_HIGH) ? 1 : 0);
if (err) if (err)
goto free_gpio; goto free_gpio;
...@@ -72,3 +80,83 @@ int gpio_request(unsigned gpio, const char *label) ...@@ -72,3 +80,83 @@ int gpio_request(unsigned gpio, const char *label)
return gpiod_request(desc, label); return gpiod_request(desc, label);
} }
EXPORT_SYMBOL_GPL(gpio_request); EXPORT_SYMBOL_GPL(gpio_request);
static void devm_gpio_release(struct device *dev, void *res)
{
unsigned *gpio = res;
gpio_free(*gpio);
}
/**
* devm_gpio_request - request a GPIO for a managed device
* @dev: device to request the GPIO for
* @gpio: GPIO to allocate
* @label: the name of the requested GPIO
*
* Except for the extra @dev argument, this function takes the
* same arguments and performs the same function as gpio_request().
* GPIOs requested with this function will be automatically freed
* on driver detach.
*
* **DEPRECATED** This function is deprecated and must not be used in new code.
*
* Returns:
* 0 on success, or negative errno on failure.
*/
int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
{
unsigned *dr;
int rc;
dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
if (!dr)
return -ENOMEM;
rc = gpio_request(gpio, label);
if (rc) {
devres_free(dr);
return rc;
}
*dr = gpio;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_gpio_request);
/**
* devm_gpio_request_one - request a single GPIO with initial setup
* @dev: device to request for
* @gpio: the GPIO number
* @flags: GPIO configuration as specified by GPIOF_*
* @label: a literal description string of this GPIO
*
* **DEPRECATED** This function is deprecated and must not be used in new code.
*
* Returns:
* 0 on success, or negative errno on failure.
*/
int devm_gpio_request_one(struct device *dev, unsigned gpio,
unsigned long flags, const char *label)
{
unsigned *dr;
int rc;
dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
if (!dr)
return -ENOMEM;
rc = gpio_request_one(gpio, flags, label);
if (rc) {
devres_free(dr);
return rc;
}
*dr = gpio;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_gpio_request_one);
...@@ -46,16 +46,19 @@ enum of_gpio_flags { ...@@ -46,16 +46,19 @@ enum of_gpio_flags {
* @propname: property name containing gpio specifier(s) * @propname: property name containing gpio specifier(s)
* *
* The function returns the count of GPIOs specified for a node. * The function returns the count of GPIOs specified for a node.
* Note that the empty GPIO specifiers count too. Returns either * NOTE: The empty GPIO specifiers count too.
* Number of gpios defined in property,
* -EINVAL for an incorrectly formed gpios property, or
* -ENOENT for a missing gpios property
* *
* Example: * Returns:
* gpios = <0 * Either number of GPIOs defined in the property, or
* &gpio1 1 2 * * %-EINVAL for an incorrectly formed "gpios" property, or
* 0 * * %-ENOENT for a missing "gpios" property.
* &gpio2 3 4>; *
* Example::
*
* gpios = <0
* &gpio1 1 2
* 0
* &gpio2 3 4>;
* *
* The above example defines four GPIOs, two of which are not specified. * The above example defines four GPIOs, two of which are not specified.
* This function will return '4' * This function will return '4'
...@@ -77,6 +80,11 @@ static int of_gpio_named_count(const struct device_node *np, ...@@ -77,6 +80,11 @@ static int of_gpio_named_count(const struct device_node *np,
* "gpios" for the chip select lines. If we detect this, we redirect * "gpios" for the chip select lines. If we detect this, we redirect
* the counting of "cs-gpios" to count "gpios" transparent to the * the counting of "cs-gpios" to count "gpios" transparent to the
* driver. * driver.
*
* Returns:
* Either number of GPIOs defined in the property, or
* * %-EINVAL for an incorrectly formed "gpios" property, or
* * %-ENOENT for a missing "gpios" property.
*/ */
static int of_gpio_spi_cs_get_count(const struct device_node *np, static int of_gpio_spi_cs_get_count(const struct device_node *np,
const char *con_id) const char *con_id)
...@@ -97,20 +105,12 @@ int of_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) ...@@ -97,20 +105,12 @@ int of_gpio_count(const struct fwnode_handle *fwnode, const char *con_id)
const struct device_node *np = to_of_node(fwnode); const struct device_node *np = to_of_node(fwnode);
int ret; int ret;
char propname[32]; char propname[32];
unsigned int i;
ret = of_gpio_spi_cs_get_count(np, con_id); ret = of_gpio_spi_cs_get_count(np, con_id);
if (ret > 0) if (ret > 0)
return ret; return ret;
for (i = 0; i < gpio_suffix_count; i++) { for_each_gpio_property_name(propname, con_id) {
if (con_id)
snprintf(propname, sizeof(propname), "%s-%s",
con_id, gpio_suffixes[i]);
else
snprintf(propname, sizeof(propname), "%s",
gpio_suffixes[i]);
ret = of_gpio_named_count(np, propname); ret = of_gpio_named_count(np, propname);
if (ret > 0) if (ret > 0)
break; break;
...@@ -338,11 +338,10 @@ static void of_gpio_flags_quirks(const struct device_node *np, ...@@ -338,11 +338,10 @@ static void of_gpio_flags_quirks(const struct device_node *np,
*/ */
if (IS_ENABLED(CONFIG_SPI_MASTER) && !strcmp(propname, "cs-gpios") && if (IS_ENABLED(CONFIG_SPI_MASTER) && !strcmp(propname, "cs-gpios") &&
of_property_read_bool(np, "cs-gpios")) { of_property_read_bool(np, "cs-gpios")) {
struct device_node *child;
u32 cs; u32 cs;
int ret; int ret;
for_each_child_of_node(np, child) { for_each_child_of_node_scoped(np, child) {
ret = of_property_read_u32(child, "reg", &cs); ret = of_property_read_u32(child, "reg", &cs);
if (ret) if (ret)
continue; continue;
...@@ -363,7 +362,6 @@ static void of_gpio_flags_quirks(const struct device_node *np, ...@@ -363,7 +362,6 @@ static void of_gpio_flags_quirks(const struct device_node *np,
"spi-cs-high"); "spi-cs-high");
of_gpio_quirk_polarity(child, active_high, of_gpio_quirk_polarity(child, active_high,
flags); flags);
of_node_put(child);
break; break;
} }
} }
...@@ -383,7 +381,8 @@ static void of_gpio_flags_quirks(const struct device_node *np, ...@@ -383,7 +381,8 @@ static void of_gpio_flags_quirks(const struct device_node *np,
* @index: index of the GPIO * @index: index of the GPIO
* @flags: a flags pointer to fill in * @flags: a flags pointer to fill in
* *
* Returns GPIO descriptor to use with Linux GPIO API, or one of the errno * Returns:
* GPIO descriptor to use with Linux GPIO API, or one of the errno
* value on the error condition. If @flags is not NULL the function also fills * value on the error condition. If @flags is not NULL the function also fills
* in flags for the GPIO. * in flags for the GPIO.
*/ */
...@@ -435,7 +434,8 @@ static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np, ...@@ -435,7 +434,8 @@ static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np,
* *
* **DEPRECATED** This function is deprecated and must not be used in new code. * **DEPRECATED** This function is deprecated and must not be used in new code.
* *
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno * Returns:
* GPIO number to use with Linux generic GPIO API, or one of the errno
* value on the error condition. * value on the error condition.
*/ */
int of_get_named_gpio(const struct device_node *np, const char *propname, int of_get_named_gpio(const struct device_node *np, const char *propname,
...@@ -687,23 +687,14 @@ static const of_find_gpio_quirk of_find_gpio_quirks[] = { ...@@ -687,23 +687,14 @@ static const of_find_gpio_quirk of_find_gpio_quirks[] = {
struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id,
unsigned int idx, unsigned long *flags) unsigned int idx, unsigned long *flags)
{ {
char prop_name[32]; /* 32 is max size of property name */ char propname[32]; /* 32 is max size of property name */
enum of_gpio_flags of_flags; enum of_gpio_flags of_flags;
const of_find_gpio_quirk *q; const of_find_gpio_quirk *q;
struct gpio_desc *desc; struct gpio_desc *desc;
unsigned int i;
/* Try GPIO property "foo-gpios" and "foo-gpio" */ /* Try GPIO property "foo-gpios" and "foo-gpio" */
for (i = 0; i < gpio_suffix_count; i++) { for_each_gpio_property_name(propname, con_id) {
if (con_id) desc = of_get_named_gpiod_flags(np, propname, idx, &of_flags);
snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
gpio_suffixes[i]);
else
snprintf(prop_name, sizeof(prop_name), "%s",
gpio_suffixes[i]);
desc = of_get_named_gpiod_flags(np, prop_name, idx, &of_flags);
if (!gpiod_not_found(desc)) if (!gpiod_not_found(desc))
break; break;
} }
...@@ -730,7 +721,8 @@ struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, ...@@ -730,7 +721,8 @@ struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id,
* of_find_gpio() or of_parse_own_gpio() * of_find_gpio() or of_parse_own_gpio()
* @dflags: gpiod_flags - optional GPIO initialization flags * @dflags: gpiod_flags - optional GPIO initialization flags
* *
* Returns GPIO descriptor to use with Linux GPIO API, or one of the errno * Returns:
* GPIO descriptor to use with Linux GPIO API, or one of the errno
* value on the error condition. * value on the error condition.
*/ */
static struct gpio_desc *of_parse_own_gpio(struct device_node *np, static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
...@@ -798,7 +790,8 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, ...@@ -798,7 +790,8 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
* @chip: gpio chip to act on * @chip: gpio chip to act on
* @hog: device node describing the hogs * @hog: device node describing the hogs
* *
* Returns error if it fails otherwise 0 on success. * Returns:
* 0 on success, or negative errno on failure.
*/ */
static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog) static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog)
{ {
...@@ -832,22 +825,21 @@ static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog) ...@@ -832,22 +825,21 @@ static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog)
* *
* This is only used by of_gpiochip_add to request/set GPIO initial * This is only used by of_gpiochip_add to request/set GPIO initial
* configuration. * configuration.
* It returns error if it fails otherwise 0 on success. *
* Returns:
* 0 on success, or negative errno on failure.
*/ */
static int of_gpiochip_scan_gpios(struct gpio_chip *chip) static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
{ {
struct device_node *np;
int ret; int ret;
for_each_available_child_of_node(dev_of_node(&chip->gpiodev->dev), np) { for_each_available_child_of_node_scoped(dev_of_node(&chip->gpiodev->dev), np) {
if (!of_property_read_bool(np, "gpio-hog")) if (!of_property_read_bool(np, "gpio-hog"))
continue; continue;
ret = of_gpiochip_add_hog(chip, np); ret = of_gpiochip_add_hog(chip, np);
if (ret < 0) { if (ret < 0)
of_node_put(np);
return ret; return ret;
}
of_node_set_flag(np, OF_POPULATED); of_node_set_flag(np, OF_POPULATED);
} }
...@@ -945,6 +937,9 @@ struct notifier_block gpio_of_notifier = { ...@@ -945,6 +937,9 @@ struct notifier_block gpio_of_notifier = {
* This is simple translation function, suitable for the most 1:1 mapped * This is simple translation function, suitable for the most 1:1 mapped
* GPIO chips. This function performs only one sanity check: whether GPIO * GPIO chips. This function performs only one sanity check: whether GPIO
* is less than ngpios (that is specified in the gpio_chip). * is less than ngpios (that is specified in the gpio_chip).
*
* Returns:
* GPIO number (>= 0) on success, negative errno on failure.
*/ */
static int of_gpio_simple_xlate(struct gpio_chip *gc, static int of_gpio_simple_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, const struct of_phandle_args *gpiospec,
...@@ -994,6 +989,9 @@ static int of_gpio_simple_xlate(struct gpio_chip *gc, ...@@ -994,6 +989,9 @@ static int of_gpio_simple_xlate(struct gpio_chip *gc,
* If succeeded, this function will map bank's memory and will * If succeeded, this function will map bank's memory and will
* do all necessary work for you. Then you'll able to use .regs * do all necessary work for you. Then you'll able to use .regs
* to manage GPIOs from the callbacks. * to manage GPIOs from the callbacks.
*
* Returns:
* 0 on success, or negative errno on failure.
*/ */
int of_mm_gpiochip_add_data(struct device_node *np, int of_mm_gpiochip_add_data(struct device_node *np,
struct of_mm_gpio_chip *mm_gc, struct of_mm_gpio_chip *mm_gc,
...@@ -1058,13 +1056,13 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -1058,13 +1056,13 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
int index = 0, ret, trim; int index = 0, ret, trim;
const char *name; const char *name;
static const char group_names_propname[] = "gpio-ranges-group-names"; static const char group_names_propname[] = "gpio-ranges-group-names";
struct property *group_names; bool has_group_names;
np = dev_of_node(&chip->gpiodev->dev); np = dev_of_node(&chip->gpiodev->dev);
if (!np) if (!np)
return 0; return 0;
group_names = of_find_property(np, group_names_propname, NULL); has_group_names = of_property_present(np, group_names_propname);
for (;; index++) { for (;; index++) {
ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
...@@ -1085,7 +1083,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -1085,7 +1083,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
if (pinspec.args[2]) { if (pinspec.args[2]) {
/* npins != 0: linear range */ /* npins != 0: linear range */
if (group_names) { if (has_group_names) {
of_property_read_string_index(np, of_property_read_string_index(np,
group_names_propname, group_names_propname,
index, &name); index, &name);
...@@ -1123,7 +1121,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -1123,7 +1121,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
break; break;
} }
if (!group_names) { if (!has_group_names) {
pr_err("%pOF: GPIO group range requested but no %s property.\n", pr_err("%pOF: GPIO group range requested but no %s property.\n",
np, group_names_propname); np, group_names_propname);
break; break;
......
...@@ -24,20 +24,6 @@ ...@@ -24,20 +24,6 @@
#define GPIOLIB_SWNODE_UNDEFINED_NAME "swnode-gpio-undefined" #define GPIOLIB_SWNODE_UNDEFINED_NAME "swnode-gpio-undefined"
static void swnode_format_propname(const char *con_id, char *propname,
size_t max_size)
{
/*
* Note we do not need to try both -gpios and -gpio suffixes,
* as, unlike OF and ACPI, we can fix software nodes to conform
* to the proper binding.
*/
if (con_id)
snprintf(propname, max_size, "%s-gpios", con_id);
else
strscpy(propname, "gpios", max_size);
}
static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode)
{ {
const struct software_node *gdev_node; const struct software_node *gdev_node;
...@@ -59,6 +45,17 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) ...@@ -59,6 +45,17 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode)
return gdev ?: ERR_PTR(-EPROBE_DEFER); return gdev ?: ERR_PTR(-EPROBE_DEFER);
} }
static int swnode_gpio_get_reference(const struct fwnode_handle *fwnode,
const char *propname, unsigned int idx,
struct fwnode_reference_args *args)
{
/*
* We expect all swnode-described GPIOs have GPIO number and
* polarity arguments, hence nargs is set to 2.
*/
return fwnode_property_get_reference_args(fwnode, propname, NULL, 2, idx, args);
}
struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
const char *con_id, unsigned int idx, const char *con_id, unsigned int idx,
unsigned long *flags) unsigned long *flags)
...@@ -67,23 +64,21 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, ...@@ -67,23 +64,21 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
struct fwnode_reference_args args; struct fwnode_reference_args args;
struct gpio_desc *desc; struct gpio_desc *desc;
char propname[32]; /* 32 is max size of property name */ char propname[32]; /* 32 is max size of property name */
int error; int ret;
swnode = to_software_node(fwnode); swnode = to_software_node(fwnode);
if (!swnode) if (!swnode)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
swnode_format_propname(con_id, propname, sizeof(propname)); for_each_gpio_property_name(propname, con_id) {
ret = swnode_gpio_get_reference(fwnode, propname, idx, &args);
/* if (ret == 0)
* We expect all swnode-described GPIOs have GPIO number and break;
* polarity arguments, hence nargs is set to 2. }
*/ if (ret) {
error = fwnode_property_get_reference_args(fwnode, propname, NULL, 2, idx, &args);
if (error) {
pr_debug("%s: can't parse '%s' property of node '%pfwP[%d]'\n", pr_debug("%s: can't parse '%s' property of node '%pfwP[%d]'\n",
__func__, propname, fwnode, idx); __func__, propname, fwnode, idx);
return ERR_PTR(error); return ERR_PTR(ret);
} }
struct gpio_device *gdev __free(gpio_device_put) = struct gpio_device *gdev __free(gpio_device_put) =
...@@ -111,7 +106,7 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, ...@@ -111,7 +106,7 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
* system-global GPIOs * system-global GPIOs
* @con_id: function within the GPIO consumer * @con_id: function within the GPIO consumer
* *
* Return: * Returns:
* The number of GPIOs associated with a device / function or %-ENOENT, * The number of GPIOs associated with a device / function or %-ENOENT,
* if no GPIO has been assigned to the requested function. * if no GPIO has been assigned to the requested function.
*/ */
...@@ -121,20 +116,21 @@ int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) ...@@ -121,20 +116,21 @@ int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id)
char propname[32]; char propname[32];
int count; int count;
swnode_format_propname(con_id, propname, sizeof(propname));
/* /*
* This is not very efficient, but GPIO lists usually have only * This is not very efficient, but GPIO lists usually have only
* 1 or 2 entries. * 1 or 2 entries.
*/ */
count = 0; for_each_gpio_property_name(propname, con_id) {
while (fwnode_property_get_reference_args(fwnode, propname, NULL, 0, count = 0;
count, &args) == 0) { while (swnode_gpio_get_reference(fwnode, propname, count, &args) == 0) {
fwnode_handle_put(args.fwnode); fwnode_handle_put(args.fwnode);
count++; count++;
}
if (count)
return count;
} }
return count ?: -ENOENT; return -ENOENT;
} }
#if IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED) #if IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED)
......
...@@ -568,7 +568,8 @@ static struct class gpio_class = { ...@@ -568,7 +568,8 @@ static struct class gpio_class = {
* will see "direction" sysfs attribute which may be used to change * will see "direction" sysfs attribute which may be used to change
* the gpio's direction. A "value" attribute will always be provided. * the gpio's direction. A "value" attribute will always be provided.
* *
* Returns zero on success, else an error. * Returns:
* 0 on success, or negative errno on failure.
*/ */
int gpiod_export(struct gpio_desc *desc, bool direction_may_change) int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
{ {
...@@ -667,7 +668,8 @@ static int match_export(struct device *dev, const void *desc) ...@@ -667,7 +668,8 @@ static int match_export(struct device *dev, const void *desc)
* Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
* node. Caller is responsible for unlinking. * node. Caller is responsible for unlinking.
* *
* Returns zero on success, else an error. * Returns:
* 0 on success, or negative errno on failure.
*/ */
int gpiod_export_link(struct device *dev, const char *name, int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc) struct gpio_desc *desc)
......
This diff is collapsed.
...@@ -89,9 +89,21 @@ static inline struct gpio_device *to_gpio_device(struct device *dev) ...@@ -89,9 +89,21 @@ static inline struct gpio_device *to_gpio_device(struct device *dev)
return container_of(dev, struct gpio_device, dev); return container_of(dev, struct gpio_device, dev);
} }
/* gpio suffixes used for ACPI and device tree lookup */ /* GPIO suffixes used for ACPI and device tree lookup */
extern const char *const gpio_suffixes[]; extern const char *const gpio_suffixes[];
extern const size_t gpio_suffix_count;
#define for_each_gpio_property_name(propname, con_id) \
for (const char * const *__suffixes = gpio_suffixes; \
*__suffixes && ({ \
const char *__gs = *__suffixes; \
\
if (con_id) \
snprintf(propname, sizeof(propname), "%s-%s", con_id, __gs); \
else \
snprintf(propname, sizeof(propname), "%s", __gs); \
1; \
}); \
__suffixes++)
/** /**
* struct gpio_array - Opaque descriptor for a structure of GPIO array attributes * struct gpio_array - Opaque descriptor for a structure of GPIO array attributes
......
...@@ -17,15 +17,9 @@ ...@@ -17,15 +17,9 @@
struct device; struct device;
/* make these flag values available regardless of GPIO kconfig options */ /* make these flag values available regardless of GPIO kconfig options */
#define GPIOF_DIR_OUT (0 << 0) #define GPIOF_IN ((1 << 0))
#define GPIOF_DIR_IN (1 << 0) #define GPIOF_OUT_INIT_LOW ((0 << 0) | (0 << 1))
#define GPIOF_OUT_INIT_HIGH ((0 << 0) | (1 << 1))
#define GPIOF_INIT_LOW (0 << 1)
#define GPIOF_INIT_HIGH (1 << 1)
#define GPIOF_IN (GPIOF_DIR_IN)
#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
/* Gpio pin is active-low */ /* Gpio pin is active-low */
#define GPIOF_ACTIVE_LOW (1 << 2) #define GPIOF_ACTIVE_LOW (1 << 2)
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Atheros AR7XXX/AR9XXX GPIO controller platform data
*
* Copyright (C) 2015 Alban Bedel <albeu@free.fr>
*/
#ifndef __LINUX_PLATFORM_DATA_GPIO_ATH79_H
#define __LINUX_PLATFORM_DATA_GPIO_ATH79_H
struct ath79_gpio_platform_data {
unsigned ngpios;
bool oe_inverted;
};
#endif
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* DaVinci GPIO Platform Related Defines
*
* Copyright (C) 2013 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef __DAVINCI_GPIO_PLATFORM_H
#define __DAVINCI_GPIO_PLATFORM_H
struct davinci_gpio_platform_data {
bool no_auto_base;
u32 base;
u32 ngpio;
u32 gpio_unbanked;
};
/* Convert GPIO signal to GPIO pin number */
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
#endif
...@@ -78,7 +78,7 @@ $(OUTPUT)gpio-watch: $(GPIO_WATCH_IN) ...@@ -78,7 +78,7 @@ $(OUTPUT)gpio-watch: $(GPIO_WATCH_IN)
clean: clean:
rm -f $(ALL_PROGRAMS) rm -f $(ALL_PROGRAMS)
rm -f $(OUTPUT)include/linux/gpio.h rm -f $(OUTPUT)include/linux/gpio.h
find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete -o -name '\.*.cmd' -delete
install: $(ALL_PROGRAMS) install: $(ALL_PROGRAMS)
install -d -m 755 $(DESTDIR)$(bindir); \ install -d -m 755 $(DESTDIR)$(bindir); \
......
...@@ -54,7 +54,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int num_lines, ...@@ -54,7 +54,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int num_lines,
fprintf(stdout, "Hammer lines ["); fprintf(stdout, "Hammer lines [");
for (i = 0; i < num_lines; i++) { for (i = 0; i < num_lines; i++) {
fprintf(stdout, "%d", lines[i]); fprintf(stdout, "%u", lines[i]);
if (i != (num_lines - 1)) if (i != (num_lines - 1))
fprintf(stdout, ", "); fprintf(stdout, ", ");
} }
...@@ -89,7 +89,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int num_lines, ...@@ -89,7 +89,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int num_lines,
fprintf(stdout, "["); fprintf(stdout, "[");
for (i = 0; i < num_lines; i++) { for (i = 0; i < num_lines; i++) {
fprintf(stdout, "%d: %d", lines[i], fprintf(stdout, "%u: %d", lines[i],
gpiotools_test_bit(values.bits, i)); gpiotools_test_bit(values.bits, i));
if (i != (num_lines - 1)) if (i != (num_lines - 1))
fprintf(stdout, ", "); fprintf(stdout, ", ");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment