aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2024-04-29 15:56:02 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2024-04-29 15:56:02 +1000
commitf91c947295b916e5499d57090d2339f5f83649ca (patch)
tree078046349f0946eebb5229b09f846d80055b408c
parentf000ca6ed61d20f73c17ee3c5f5803e6499e4fcc (diff)
parent5539287ca65686f478e058a1e939294cb5682426 (diff)
downloadlinux-next-f91c947295b916e5499d57090d2339f5f83649ca.tar.gz
Merge branch 'gpio/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
-rw-r--r--Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml3
-rw-r--r--Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml17
-rw-r--r--Documentation/driver-api/gpio/driver.rst28
-rw-r--r--Documentation/driver-api/gpio/legacy.rst16
-rw-r--r--Documentation/translations/zh_CN/driver-api/gpio/legacy.rst16
-rw-r--r--Documentation/translations/zh_TW/gpio.txt17
-rw-r--r--Documentation/userspace-api/gpio/gpio-v2-get-line-ioctl.rst2
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c22
-rw-r--r--arch/arm/mach-sa1100/h3600.c47
-rw-r--r--drivers/gpio/gpio-brcmstb.c21
-rw-r--r--drivers/gpio/gpio-cros-ec.c8
-rw-r--r--drivers/gpio/gpio-pcie-idio-24.c2
-rw-r--r--drivers/gpio/gpio-regmap.c4
-rw-r--r--drivers/gpio/gpiolib-legacy.c49
-rw-r--r--drivers/gpio/gpiolib-of.c23
-rw-r--r--drivers/gpio/gpiolib-sysfs.c2
-rw-r--r--drivers/gpio/gpiolib.c26
-rw-r--r--drivers/gpio/gpiolib.h2
-rw-r--r--include/linux/gpio.h21
19 files changed, 149 insertions, 177 deletions
diff --git a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
index a1e71c974e79ce..f096f286da19cd 100644
--- a/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
@@ -62,6 +62,8 @@ properties:
interrupt-controller: true
+ gpio-ranges: true
+
wakeup-source:
type: boolean
description: >
@@ -88,6 +90,7 @@ examples:
interrupt-parent = <&irq0_intc>;
interrupts = <0x6>;
brcm,gpio-bank-widths = <32 32 32 24>;
+ gpio-ranges = <&pinctrl 0 0 120>;
};
upg_gio_aon: gpio@f04172c0 {
diff --git a/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml b/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml
index d481e78958a74a..d61569b3f15b2a 100644
--- a/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml
@@ -14,6 +14,7 @@ properties:
items:
- enum:
- microchip,mpfs-gpio
+ - microchip,coregpio-rtl-v3
reg:
maxItems: 1
@@ -43,6 +44,7 @@ properties:
default: 32
gpio-controller: true
+ gpio-line-names: true
patternProperties:
"^.+-hog(-[0-9]+)?$":
@@ -62,12 +64,21 @@ patternProperties:
- gpio-hog
- gpios
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: microchip,mpfs-gpio
+ then:
+ required:
+ - interrupts
+ - "#interrupt-cells"
+ - interrupt-controller
+
required:
- compatible
- reg
- - interrupts
- - "#interrupt-cells"
- - interrupt-controller
- "#gpio-cells"
- gpio-controller
- clocks
diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst
index bf6319cc531b7a..e541bd2e898b51 100644
--- a/Documentation/driver-api/gpio/driver.rst
+++ b/Documentation/driver-api/gpio/driver.rst
@@ -7,7 +7,7 @@ This document serves as a guide for writers of GPIO chip drivers.
Each GPIO controller driver needs to include the following header, which defines
the structures used to define a GPIO driver::
- #include <linux/gpio/driver.h>
+ #include <linux/gpio/driver.h>
Internal Representation of GPIOs
@@ -144,7 +144,7 @@ is not open, it will present a high-impedance (tristate) to the external rail::
in ----|| |/
||--+ in ----|
| |\
- GND GND
+ GND GND
This configuration is normally used as a way to achieve one of two things:
@@ -550,10 +550,10 @@ the interrupt separately and go with it:
struct my_gpio *g;
struct gpio_irq_chip *girq;
- ret = devm_request_threaded_irq(dev, irq, NULL,
- irq_thread_fn, IRQF_ONESHOT, "my-chip", g);
+ ret = devm_request_threaded_irq(dev, irq, NULL, irq_thread_fn,
+ IRQF_ONESHOT, "my-chip", g);
if (ret < 0)
- return ret;
+ return ret;
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
@@ -681,12 +681,12 @@ certain operations and keep track of usage inside of the gpiolib subsystem.
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
to mark the GPIO as being used as an IRQ::
- int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
+ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
is released::
- void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
+ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
When implementing an irqchip inside a GPIO driver, these two functions should
typically be called in the .startup() and .shutdown() callbacks from the
@@ -708,12 +708,12 @@ When a GPIO is used as an IRQ signal, then gpiolib also needs to know if
the IRQ is enabled or disabled. In order to inform gpiolib about this,
the irqchip driver should call::
- void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset)
+ void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset)
This allows drivers to drive the GPIO as an output while the IRQ is
disabled. When the IRQ is enabled again, a driver should call::
- void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset)
+ void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset)
When implementing an irqchip inside a GPIO driver, these two functions should
typically be called in the .irq_disable() and .irq_enable() callbacks from the
@@ -763,12 +763,12 @@ Sometimes it is useful to allow a GPIO chip driver to request its own GPIO
descriptors through the gpiolib API. A GPIO driver can use the following
functions to request and free descriptors::
- struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
- u16 hwnum,
- const char *label,
- enum gpiod_flags flags)
+ struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
+ u16 hwnum,
+ const char *label,
+ enum gpiod_flags flags)
- void gpiochip_free_own_desc(struct gpio_desc *desc)
+ void gpiochip_free_own_desc(struct gpio_desc *desc)
Descriptors requested with gpiochip_request_own_desc() must be released with
gpiochip_free_own_desc().
diff --git a/Documentation/driver-api/gpio/legacy.rst b/Documentation/driver-api/gpio/legacy.rst
index b6505914791c7d..534dfe95d128b8 100644
--- a/Documentation/driver-api/gpio/legacy.rst
+++ b/Documentation/driver-api/gpio/legacy.rst
@@ -225,8 +225,6 @@ setup or driver probe/teardown code, so this is an easy constraint.)::
gpio_request()
## gpio_request_one()
- ## gpio_request_array()
- ## gpio_free_array()
gpio_free()
@@ -295,14 +293,6 @@ are claimed, three additional calls are defined::
*/
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
- /* request multiple GPIOs in a single call
- */
- int gpio_request_array(struct gpio *array, size_t num);
-
- /* release multiple GPIOs in a single call
- */
- void gpio_free_array(struct gpio *array, size_t num);
-
where 'flags' is currently defined to specify the following properties:
* GPIOF_DIR_IN - to configure direction as input
@@ -341,12 +331,6 @@ A typical example of usage::
if (err)
...
- err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
- if (err)
- ...
-
- gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
-
GPIOs mapped to IRQs
--------------------
diff --git a/Documentation/translations/zh_CN/driver-api/gpio/legacy.rst b/Documentation/translations/zh_CN/driver-api/gpio/legacy.rst
index aeccff77717090..0faf042001d241 100644
--- a/Documentation/translations/zh_CN/driver-api/gpio/legacy.rst
+++ b/Documentation/translations/zh_CN/driver-api/gpio/legacy.rst
@@ -208,8 +208,6 @@ GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其
gpio_request()
## gpio_request_one()
- ## gpio_request_array()
- ## gpio_free_array()
gpio_free()
@@ -272,14 +270,6 @@ gpio_request()前将这类细节配置好,例如使用引脚控制子系统的
*/
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
- /* 在单个函数中申请多个 GPIO
- */
- int gpio_request_array(struct gpio *array, size_t num);
-
- /* 在单个函数中释放多个 GPIO
- */
- void gpio_free_array(struct gpio *array, size_t num);
-
这里 'flags' 当前定义可指定以下属性:
* GPIOF_DIR_IN - 配置方向为输入
@@ -317,12 +307,6 @@ gpio_request()前将这类细节配置好,例如使用引脚控制子系统的
if (err)
...
- err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
- if (err)
- ...
-
- gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
-
GPIO 映射到 IRQ
----------------
diff --git a/Documentation/translations/zh_TW/gpio.txt b/Documentation/translations/zh_TW/gpio.txt
index b9b48012c62e59..77d69d38131637 100644
--- a/Documentation/translations/zh_TW/gpio.txt
+++ b/Documentation/translations/zh_TW/gpio.txt
@@ -215,13 +215,10 @@ GPIO 值的命令需要等待其信息排到隊首才發送命令,再獲得其
gpio_request()
## gpio_request_one()
-## gpio_request_array()
-## gpio_free_array()
gpio_free()
-
聲明和釋放 GPIO
----------------------------
爲了有助於捕獲系統配置錯誤,定義了兩個函數。
@@ -278,14 +275,6 @@ gpio_request()前將這類細節配置好,例如使用 pinctrl 子系統的映
*/
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
- /* 在單個函數中申請多個 GPIO
- */
- int gpio_request_array(struct gpio *array, size_t num);
-
- /* 在單個函數中釋放多個 GPIO
- */
- void gpio_free_array(struct gpio *array, size_t num);
-
這裡 'flags' 當前定義可指定以下屬性:
* GPIOF_DIR_IN - 配置方向爲輸入
@@ -323,12 +312,6 @@ gpio_request()前將這類細節配置好,例如使用 pinctrl 子系統的映
if (err)
...
- err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
- if (err)
- ...
-
- gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
-
GPIO 映射到 IRQ
--------------------
diff --git a/Documentation/userspace-api/gpio/gpio-v2-get-line-ioctl.rst b/Documentation/userspace-api/gpio/gpio-v2-get-line-ioctl.rst
index 56b975801b6af0..6615d6ced755ba 100644
--- a/Documentation/userspace-api/gpio/gpio-v2-get-line-ioctl.rst
+++ b/Documentation/userspace-api/gpio/gpio-v2-get-line-ioctl.rst
@@ -81,7 +81,7 @@ Only one event clock flag, ``GPIO_V2_LINE_FLAG_EVENT_CLOCK_xxx``, may be set.
If none are set then the event clock defaults to ``CLOCK_MONOTONIC``.
The ``GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE`` flag requires supporting hardware
and a kernel with ``CONFIG_HTE`` set. Requesting HTE from a device that
-doesn't support it is an error (**EOPNOTSUP**).
+doesn't support it is an error (**EOPNOTSUPP**).
The :c:type:`debounce_period_us<gpio_v2_line_attribute>` attribute may only
be applied to lines with ``GPIO_V2_LINE_FLAG_INPUT`` set. When set, debounce
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 8bc4ea51a0c164..03b4b347f11a07 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -35,18 +35,20 @@
static int spitz_last_ac_status;
-static struct gpio spitz_charger_gpios[] = {
- { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" },
- { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" },
- { SPITZ_GPIO_AC_IN, GPIOF_IN, "Charger Detection" },
- { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
- { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" },
- { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
-};
-
static void spitz_charger_init(void)
{
- gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
+ gpio_request(SPITZ_GPIO_KEY_INT, "Keyboard Interrupt");
+ gpio_direction_input(SPITZ_GPIO_KEY_INT);
+ gpio_request(SPITZ_GPIO_SYNC, "Sync");
+ gpio_direction_input(SPITZ_GPIO_SYNC);
+ gpio_request(SPITZ_GPIO_AC_IN, "Charger Detection");
+ gpio_direction_input(SPITZ_GPIO_AC_IN);
+ gpio_request(SPITZ_GPIO_ADC_TEMP_ON, "ADC Temp On");
+ gpio_direction_output(SPITZ_GPIO_ADC_TEMP_ON, 0);
+ gpio_request(SPITZ_GPIO_JK_B, "JK B");
+ gpio_direction_output(SPITZ_GPIO_JK_B, 0);
+ gpio_request(SPITZ_GPIO_CHRG_ON, "Charger On");
+ gpio_direction_output(SPITZ_GPIO_CHRG_ON, 0);
}
static void spitz_measure_temp(int on)
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 5e25dfa752e908..1cfc0b1fa41ca4 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -20,16 +20,6 @@
#include "generic.h"
-/*
- * helper for sa1100fb
- */
-static struct gpio h3600_lcd_gpio[] = {
- { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD power" },
- { H3600_EGPIO_LCD_PCI, GPIOF_OUT_INIT_LOW, "LCD control" },
- { H3600_EGPIO_LCD_5V_ON, GPIOF_OUT_INIT_LOW, "LCD 5v" },
- { H3600_EGPIO_LVDD_ON, GPIOF_OUT_INIT_LOW, "LCD 9v/-6.5v" },
-};
-
static bool h3600_lcd_request(void)
{
static bool h3600_lcd_ok;
@@ -38,7 +28,42 @@ static bool h3600_lcd_request(void)
if (h3600_lcd_ok)
return true;
- rc = gpio_request_array(h3600_lcd_gpio, ARRAY_SIZE(h3600_lcd_gpio));
+ rc = gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power");
+ if (rc)
+ goto out;
+ rc = gpio_direction_output(H3XXX_EGPIO_LCD_ON, 0);
+ if (rc)
+ goto out_free_on;
+ rc = gpio_request(H3600_EGPIO_LCD_PCI, "LCD control");
+ if (rc)
+ goto out_free_on;
+ rc = gpio_direction_output(H3600_EGPIO_LCD_PCI, 0);
+ if (rc)
+ goto out_free_pci;
+ rc = gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v");
+ if (rc)
+ goto out_free_pci;
+ rc = gpio_direction_output(H3600_EGPIO_LCD_5V_ON, 0);
+ if (rc)
+ goto out_free_5v_on;
+ rc = gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v");
+ if (rc)
+ goto out_free_5v_on;
+ rc = gpio_direction_output(H3600_EGPIO_LVDD_ON, 0);
+ if (rc)
+ goto out_free_lvdd_on;
+
+ goto out;
+
+out_free_lvdd_on:
+ gpio_free(H3600_EGPIO_LVDD_ON);
+out_free_5v_on:
+ gpio_free(H3600_EGPIO_LCD_5V_ON);
+out_free_pci:
+ gpio_free(H3600_EGPIO_LCD_PCI);
+out_free_on:
+ gpio_free(H3XXX_EGPIO_LCD_ON);
+out:
if (rc)
pr_err("%s: can't request GPIOs\n", __func__);
else
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index a789af4a5c85f2..8dce78ea71395d 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -50,7 +50,6 @@ struct brcmstb_gpio_priv {
struct irq_domain *irq_domain;
struct irq_chip irq_chip;
int parent_irq;
- int gpio_base;
int num_gpios;
int parent_wake_irq;
};
@@ -92,7 +91,7 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
static int brcmstb_gpio_hwirq_to_offset(irq_hw_number_t hwirq,
struct brcmstb_gpio_bank *bank)
{
- return hwirq - (bank->gc.base - bank->parent_priv->gpio_base);
+ return hwirq - bank->gc.offset;
}
static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
@@ -118,7 +117,7 @@ static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
/* gc_offset is relative to this gpio_chip; want real offset */
- int hwirq = offset + (gc->base - priv->gpio_base);
+ int hwirq = offset + gc->offset;
if (hwirq >= priv->num_gpios)
return -ENXIO;
@@ -263,7 +262,7 @@ static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank)
{
struct brcmstb_gpio_priv *priv = bank->parent_priv;
struct irq_domain *domain = priv->irq_domain;
- int hwbase = bank->gc.base - priv->gpio_base;
+ int hwbase = bank->gc.offset;
unsigned long status;
while ((status = brcmstb_gpio_get_active_irqs(bank))) {
@@ -412,7 +411,7 @@ static int brcmstb_gpio_of_xlate(struct gpio_chip *gc,
if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
- offset = gpiospec->args[0] - (gc->base - priv->gpio_base);
+ offset = gpiospec->args[0] - bank->gc.offset;
if (offset >= gc->ngpio || offset < 0)
return -EINVAL;
@@ -596,8 +595,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
const __be32 *p;
u32 bank_width;
int num_banks = 0;
+ int num_gpios = 0;
int err;
- static int gpio_base;
unsigned long flags = 0;
bool need_wakeup_event = false;
@@ -611,7 +610,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
if (IS_ERR(reg_base))
return PTR_ERR(reg_base);
- priv->gpio_base = gpio_base;
priv->reg_base = reg_base;
priv->pdev = pdev;
@@ -651,7 +649,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
dev_dbg(dev, "Width 0 found: Empty bank @ %d\n",
num_banks);
num_banks++;
- gpio_base += MAX_GPIO_PER_BANK;
+ num_gpios += MAX_GPIO_PER_BANK;
continue;
}
@@ -691,12 +689,13 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
err = -ENOMEM;
goto fail;
}
- gc->base = gpio_base;
gc->of_gpio_n_cells = 2;
gc->of_xlate = brcmstb_gpio_of_xlate;
/* not all ngpio lines are valid, will use bank width later */
gc->ngpio = MAX_GPIO_PER_BANK;
gc->offset = bank->id * MAX_GPIO_PER_BANK;
+ gc->request = gpiochip_generic_request;
+ gc->free = gpiochip_generic_free;
if (priv->parent_irq > 0)
gc->to_irq = brcmstb_gpio_to_irq;
@@ -713,7 +712,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
bank->id);
goto fail;
}
- gpio_base += gc->ngpio;
+ num_gpios += gc->ngpio;
dev_dbg(dev, "bank=%d, base=%d, ngpio=%d, width=%d\n", bank->id,
gc->base, gc->ngpio, bank->width);
@@ -724,7 +723,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
num_banks++;
}
- priv->num_gpios = gpio_base - priv->gpio_base;
+ priv->num_gpios = num_gpios;
if (priv->parent_irq > 0) {
err = brcmstb_gpio_irq_setup(pdev, priv);
if (err)
diff --git a/drivers/gpio/gpio-cros-ec.c b/drivers/gpio/gpio-cros-ec.c
index 842e1c06041442..0c09bb54dc0c9e 100644
--- a/drivers/gpio/gpio-cros-ec.c
+++ b/drivers/gpio/gpio-cros-ec.c
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
@@ -197,11 +198,18 @@ static int cros_ec_gpio_probe(struct platform_device *pdev)
return devm_gpiochip_add_data(dev, gc, cros_ec);
}
+static const struct platform_device_id cros_ec_gpio_id[] = {
+ { "cros-ec-gpio", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, cros_ec_gpio_id);
+
static struct platform_driver cros_ec_gpio_driver = {
.probe = cros_ec_gpio_probe,
.driver = {
.name = "cros-ec-gpio",
},
+ .id_table = cros_ec_gpio_id,
};
module_platform_driver(cros_ec_gpio_driver);
diff --git a/drivers/gpio/gpio-pcie-idio-24.c b/drivers/gpio/gpio-pcie-idio-24.c
index 2efd1b1a0805f2..7f7f95ad4343d9 100644
--- a/drivers/gpio/gpio-pcie-idio-24.c
+++ b/drivers/gpio/gpio-pcie-idio-24.c
@@ -267,7 +267,7 @@ static int idio_24_reg_mask_xlate(struct gpio_regmap *const gpio, const unsigned
case IDIO_24_CONTROL_REG:
/* We can only set direction for TTL/CMOS lines */
if (offset < 48)
- return -EOPNOTSUPP;
+ return -ENOTSUPP;
*reg = IDIO_24_CONTROL_REG;
*mask = CONTROL_REG_OUT_MODE;
diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c
index c08c8e528867ee..71684dee2ca5d2 100644
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -129,7 +129,7 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip,
base = gpio_regmap_addr(gpio->reg_dir_in_base);
invert = 1;
} else {
- return -EOPNOTSUPP;
+ return -ENOTSUPP;
}
ret = gpio->reg_mask_xlate(gpio, base, offset, &reg, &mask);
@@ -160,7 +160,7 @@ static int gpio_regmap_set_direction(struct gpio_chip *chip,
base = gpio_regmap_addr(gpio->reg_dir_in_base);
invert = 1;
} else {
- return -EOPNOTSUPP;
+ return -ENOTSUPP;
}
ret = gpio->reg_mask_xlate(gpio, base, offset, &reg, &mask);
diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c
index b138682fec3d68..5a9911ae912509 100644
--- a/drivers/gpio/gpiolib-legacy.c
+++ b/drivers/gpio/gpiolib-legacy.c
@@ -28,10 +28,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
struct gpio_desc *desc;
int err;
- desc = gpio_to_desc(gpio);
-
/* Compatibility: assume unavailable "valid" GPIOs will appear later */
- if (!desc && gpio_is_valid(gpio))
+ desc = gpio_to_desc(gpio);
+ if (!desc)
return -EPROBE_DEFER;
err = gpiod_request(desc, label);
@@ -63,51 +62,13 @@ EXPORT_SYMBOL_GPL(gpio_request_one);
*/
int gpio_request(unsigned gpio, const char *label)
{
- struct gpio_desc *desc = gpio_to_desc(gpio);
+ struct gpio_desc *desc;
/* Compatibility: assume unavailable "valid" GPIOs will appear later */
- if (!desc && gpio_is_valid(gpio))
+ desc = gpio_to_desc(gpio);
+ if (!desc)
return -EPROBE_DEFER;
return gpiod_request(desc, label);
}
EXPORT_SYMBOL_GPL(gpio_request);
-
-/**
- * gpio_request_array - request multiple GPIOs in a single call
- * @array: array of the 'struct gpio'
- * @num: how many GPIOs in the array
- *
- * **DEPRECATED** This function is deprecated and must not be used in new code.
- */
-int gpio_request_array(const struct gpio *array, size_t num)
-{
- int i, err;
-
- for (i = 0; i < num; i++, array++) {
- err = gpio_request_one(array->gpio, array->flags, array->label);
- if (err)
- goto err_free;
- }
- return 0;
-
-err_free:
- while (i--)
- gpio_free((--array)->gpio);
- return err;
-}
-EXPORT_SYMBOL_GPL(gpio_request_array);
-
-/**
- * gpio_free_array - release multiple GPIOs in a single call
- * @array: array of the 'struct gpio'
- * @num: how many GPIOs in the array
- *
- * **DEPRECATED** This function is deprecated and must not be used in new code.
- */
-void gpio_free_array(const struct gpio *array, size_t num)
-{
- while (num--)
- gpio_free((array++)->gpio);
-}
-EXPORT_SYMBOL_GPL(gpio_free_array);
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index cb0cefaec37e8d..d75f6ee370282e 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -1037,7 +1037,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
struct of_phandle_args pinspec;
struct pinctrl_dev *pctldev;
struct device_node *np;
- int index = 0, ret;
+ int index = 0, ret, trim;
const char *name;
static const char group_names_propname[] = "gpio-ranges-group-names";
struct property *group_names;
@@ -1059,7 +1059,14 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
if (!pctldev)
return -EPROBE_DEFER;
+ /* Ignore ranges outside of this GPIO chip */
+ if (pinspec.args[0] >= (chip->offset + chip->ngpio))
+ continue;
+ if (pinspec.args[0] + pinspec.args[2] <= chip->offset)
+ continue;
+
if (pinspec.args[2]) {
+ /* npins != 0: linear range */
if (group_names) {
of_property_read_string_index(np,
group_names_propname,
@@ -1070,7 +1077,19 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
break;
}
}
- /* npins != 0: linear range */
+
+ /* Trim the range to fit this GPIO chip */
+ if (chip->offset > pinspec.args[0]) {
+ trim = chip->offset - pinspec.args[0];
+ pinspec.args[2] -= trim;
+ pinspec.args[1] += trim;
+ pinspec.args[0] = 0;
+ } else {
+ pinspec.args[0] -= chip->offset;
+ }
+ if ((pinspec.args[0] + pinspec.args[2]) > chip->ngpio)
+ pinspec.args[2] = chip->ngpio - pinspec.args[0];
+
ret = gpiochip_add_pin_range(chip,
pinctrl_dev_get_devname(pctldev),
pinspec.args[0],
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 6853ecd98bcb8c..26202586fd39de 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -412,7 +412,7 @@ static ssize_t base_show(struct device *dev,
{
const struct gpio_device *gdev = dev_get_drvdata(dev);
- return sysfs_emit(buf, "%d\n", gdev->base);
+ return sysfs_emit(buf, "%u\n", gdev->base);
}
static DEVICE_ATTR_RO(base);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 94903fc1c1459f..468a19e5a7ac6a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -150,9 +150,6 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
}
}
- if (!gpio_is_valid(gpio))
- pr_warn("invalid GPIO %d\n", gpio);
-
return NULL;
}
EXPORT_SYMBOL_GPL(gpio_to_desc);
@@ -297,10 +294,10 @@ struct gpio_chip *gpio_device_get_chip(struct gpio_device *gdev)
EXPORT_SYMBOL_GPL(gpio_device_get_chip);
/* dynamic allocation of GPIOs, e.g. on a hotplugged device */
-static int gpiochip_find_base_unlocked(int ngpio)
+static int gpiochip_find_base_unlocked(u16 ngpio)
{
+ unsigned int base = GPIO_DYNAMIC_BASE;
struct gpio_device *gdev;
- int base = GPIO_DYNAMIC_BASE;
list_for_each_entry_srcu(gdev, &gpio_devices, list,
lockdep_is_held(&gpio_devices_lock)) {
@@ -311,9 +308,11 @@ static int gpiochip_find_base_unlocked(int ngpio)
base = gdev->base + gdev->ngpio;
if (base < GPIO_DYNAMIC_BASE)
base = GPIO_DYNAMIC_BASE;
+ if (base > GPIO_DYNAMIC_MAX - ngpio)
+ break;
}
- if (gpio_is_valid(base)) {
+ if (base <= GPIO_DYNAMIC_MAX - ngpio) {
pr_debug("%s: found new base at %d\n", __func__, base);
return base;
} else {
@@ -365,7 +364,10 @@ int gpiod_get_direction(struct gpio_desc *desc)
if (ret < 0)
return ret;
- /* GPIOF_DIR_IN or other positive, otherwise GPIOF_DIR_OUT */
+ /*
+ * GPIO_LINE_DIRECTION_IN or other positive,
+ * otherwise GPIO_LINE_DIRECTION_OUT.
+ */
if (ret > 0)
ret = 1;
@@ -746,7 +748,7 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
if (ret)
goto err_remove_device;
- dev_dbg(&gdev->dev, "registered GPIOs %d to %d on %s\n", gdev->base,
+ dev_dbg(&gdev->dev, "registered GPIOs %u to %u on %s\n", gdev->base,
gdev->base + gdev->ngpio - 1, gdev->label);
return 0;
@@ -4240,7 +4242,7 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
if (ret < 0) {
gpiod_put(desc);
- dev_dbg(consumer, "setup of GPIO %s failed\n", name);
+ dev_err(consumer, "setup of GPIO %s failed: %d\n", name, ret);
return ERR_PTR(ret);
}
@@ -4788,14 +4790,14 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
value = gpio_chip_get_value(gc, desc);
is_irq = test_bit(FLAG_USED_AS_IRQ, &desc->flags);
active_low = test_bit(FLAG_ACTIVE_LOW, &desc->flags);
- seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s\n",
+ seq_printf(s, " gpio-%-3u (%-20.20s|%-20.20s) %s %s %s%s\n",
gpio, desc->name ?: "", gpiod_get_label(desc),
is_out ? "out" : "in ",
value >= 0 ? (value ? "hi" : "lo") : "? ",
is_irq ? "IRQ " : "",
active_low ? "ACTIVE LOW" : "");
} else if (desc->name) {
- seq_printf(s, " gpio-%-3d (%-20.20s)\n", gpio, desc->name);
+ seq_printf(s, " gpio-%-3u (%-20.20s)\n", gpio, desc->name);
}
gpio++;
@@ -4867,7 +4869,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v)
return 0;
}
- seq_printf(s, "%s%s: GPIOs %d-%d", priv->newline ? "\n" : "",
+ seq_printf(s, "%s%s: GPIOs %u-%u", priv->newline ? "\n" : "",
dev_name(&gdev->dev),
gdev->base, gdev->base + gdev->ngpio - 1);
parent = gc->parent;
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index f67d5991ab1c7a..7f94580efdbca2 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -61,7 +61,7 @@ struct gpio_device {
struct module *owner;
struct gpio_chip __rcu *chip;
struct gpio_desc *descs;
- int base;
+ unsigned int base;
u16 ngpio;
bool can_sleep;
const char *label;
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 7ecc25c543cef3..56ac7e7a288903 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -74,6 +74,12 @@ static inline bool gpio_is_valid(int number)
* Until they are all fixed, leave 0-512 space for them.
*/
#define GPIO_DYNAMIC_BASE 512
+/*
+ * Define the maximum of the possible GPIO in the global numberspace.
+ * While the GPIO base and numbers are positive, we limit it with signed
+ * maximum as a lot of code is using negative values for special cases.
+ */
+#define GPIO_DYNAMIC_MAX INT_MAX
/* Always use the library code for GPIO management calls,
* or when sleeping may be involved.
@@ -114,8 +120,6 @@ static inline int gpio_to_irq(unsigned gpio)
}
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
-int gpio_request_array(const struct gpio *array, size_t num);
-void gpio_free_array(const struct gpio *array, size_t num);
/* CONFIG_GPIOLIB: bindings for managed devices that want to request gpios */
@@ -146,11 +150,6 @@ static inline int gpio_request_one(unsigned gpio,
return -ENOSYS;
}
-static inline int gpio_request_array(const struct gpio *array, size_t num)
-{
- return -ENOSYS;
-}
-
static inline void gpio_free(unsigned gpio)
{
might_sleep();
@@ -159,14 +158,6 @@ static inline void gpio_free(unsigned gpio)
WARN_ON(1);
}
-static inline void gpio_free_array(const struct gpio *array, size_t num)
-{
- might_sleep();
-
- /* GPIO can never have been requested */
- WARN_ON(1);
-}
-
static inline int gpio_direction_input(unsigned gpio)
{
return -ENOSYS;