Commit 17bbc46f authored by Linus Torvalds's avatar Linus Torvalds

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

Pull gpio updates from Bartosz Golaszewski:
 "A rather small update, there are no new drivers, just improvements and
  refactoring in existing ones.

  Thanks to migrating of several drivers to using generalized APIs and
  dropping of OF interfaces in favor of using software nodes we're
  actually removing more code than we're adding.

  Core GPIOLIB:
   - drop several OF interfaces after moving a significant part of the
     code to using software nodes
   - remove more interfaces referring to the global GPIO numberspace
     that we're getting rid of
   - improvements in the gpio-regmap library
   - add helper for GPIO device reference counting
   - remove unused APIs
   - minor tweaks like sorting headers alphabetically

  Extended support in existing drivers:
   - add support for Tegra 234 PMC to gpio-tegra186

  Driver improvements:
   - migrate the 104-dio/idi family of drivers to using the regmap-irq
     API
   - migrate gpio-i8255 and gpio-mm to the GPIO regmap API
   - clean-ups in gpio-pca953x
   - remove duplicate assignments of of_gpio_n_cells in gpio-davinci,
     gpio-ge, gpio-xilinx, gpio-zevio and gpio-wcd934x
   - improvements to gpio-pcf857x: implement get/set_multiple callbacks,
     use generic device properties instead of OF + minor tweaks
   - fix OF-related header includes and Kconfig dependencies in
     gpio-zevio
   - dynamically allocate the GPIO base in gpio-omap
   - use a dedicated printf specifier for printing fwnode info in
     gpio-sim
   - use dev_name() for the GPIO chip label in gpio-vf610
   - other minor tweaks and fixes

  Documentation:
   - remove mentions of legacy API from comments in various places
   - convert the DT binding documents to YAML schema for Fujitsu
     MB86S7x, Unisoc GPIO and Unisoc EIC
   - document the Unisoc UMS512 controller in DT bindings"

* tag 'gpio-updates-for-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (54 commits)
  gpio: sim: Use %pfwP specifier instead of calling fwnode API directly
  gpio: tegra186: remove unneeded loop in tegra186_gpio_init_route_mapping()
  gpiolib: of: Move enum of_gpio_flags to its only user
  gpio: mvebu: Use IS_REACHABLE instead of IS_ENABLED for CONFIG_PWM
  gpio: zevio: Add missing header
  gpio: Get rid of gpio_to_chip()
  gpio: pcf857x: Drop unneeded explicit casting
  gpio: pcf857x: Make use of device properties
  gpio: pcf857x: Get rid of legacy platform data
  gpio: rockchip: Do not mention legacy API in the code
  gpio: wcd934x: Remove duplicate assignment of of_gpio_n_cells
  gpio: zevio: Use proper headers and drop OF_GPIO dependency
  gpio: zevio: Remove duplicate assignment of of_gpio_n_cells
  gpio: xilinx: Remove duplicate assignment of of_gpio_n_cells
  dt-bindings: gpio: Add compatible string for Unisoc UMS512
  dt-bindings: gpio: Convert Unisoc EIC controller binding to yaml
  dt-bindings: gpio: Convert Unisoc GPIO controller binding to yaml
  gpio: ge: Remove duplicate assignment of of_gpio_n_cells
  gpio: davinci: Remove duplicate assignment of of_gpio_n_cells
  gpio: omap: use dynamic allocation of base
  ...
parents 13e574b4 4827aae0
Fujitsu MB86S7x GPIO Controller
-------------------------------
Required properties:
- compatible: Should be "fujitsu,mb86s70-gpio"
- reg: Base address and length of register space
- clocks: Specify the clock
- gpio-controller: Marks the device node as a gpio controller.
- #gpio-cells: Should be <2>. The first cell is the pin number and the
second cell is used to specify optional parameters:
- bit 0 specifies polarity (0 for normal, 1 for inverted).
Examples:
gpio0: gpio@31000000 {
compatible = "fujitsu,mb86s70-gpio";
reg = <0 0x31000000 0x10000>;
gpio-controller;
#gpio-cells = <2>;
clocks = <&clk 0 2 1>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/fujitsu,mb86s70-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Fujitsu MB86S7x GPIO Controller
maintainers:
- Jassi Brar <jaswinder.singh@linaro.org>
properties:
compatible:
oneOf:
- items:
- const: socionext,synquacer-gpio
- const: fujitsu,mb86s70-gpio
- const: fujitsu,mb86s70-gpio
reg:
maxItems: 1
'#gpio-cells':
const: 2
gpio-controller: true
gpio-line-names: true
clocks:
maxItems: 1
required:
- compatible
- reg
- '#gpio-cells'
- gpio-controller
- clocks
additionalProperties: false
examples:
- |
gpio@31000000 {
compatible = "fujitsu,mb86s70-gpio";
reg = <0x31000000 0x10000>;
gpio-controller;
#gpio-cells = <2>;
clocks = <&clk 0 2 1>;
};
...
Spreadtrum EIC controller bindings
The EIC is the abbreviation of external interrupt controller, which can
be used only in input mode. The Spreadtrum platform has 2 EIC controllers,
one is in digital chip, and another one is in PMIC. The digital chip EIC
controller contains 4 sub-modules: EIC-debounce, EIC-latch, EIC-async and
EIC-sync. But the PMIC EIC controller contains only one EIC-debounce sub-
module.
The EIC-debounce sub-module provides up to 8 source input signal
connections. A debounce mechanism is used to capture the input signals'
stable status (millisecond resolution) and a single-trigger mechanism
is introduced into this sub-module to enhance the input event detection
reliability. In addition, this sub-module's clock can be shut off
automatically to reduce power dissipation. Moreover the debounce range
is from 1ms to 4s with a step size of 1ms. The input signal will be
ignored if it is asserted for less than 1 ms.
The EIC-latch sub-module is used to latch some special power down signals
and generate interrupts, since the EIC-latch does not depend on the APB
clock to capture signals.
The EIC-async sub-module uses a 32kHz clock to capture the short signals
(microsecond resolution) to generate interrupts by level or edge trigger.
The EIC-sync is similar with GPIO's input function, which is a synchronized
signal input register. It can generate interrupts by level or edge trigger
when detecting input signals.
Required properties:
- compatible: Should be one of the following:
"sprd,sc9860-eic-debounce",
"sprd,sc9860-eic-latch",
"sprd,sc9860-eic-async",
"sprd,sc9860-eic-sync",
"sprd,sc2731-eic".
- reg: Define the base and range of the I/O address space containing
the GPIO controller registers.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be <2>. The first cell is the gpio number and
the second cell is used to specify optional parameters.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Should be <2>. Specifies the number of cells needed
to encode interrupt source.
- interrupts: Should be the port interrupt shared by all the gpios.
Example:
eic_debounce: gpio@40210000 {
compatible = "sprd,sc9860-eic-debounce";
reg = <0 0x40210000 0 0x80>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
};
eic_latch: gpio@40210080 {
compatible = "sprd,sc9860-eic-latch";
reg = <0 0x40210080 0 0x20>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
};
eic_async: gpio@402100a0 {
compatible = "sprd,sc9860-eic-async";
reg = <0 0x402100a0 0 0x20>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
};
eic_sync: gpio@402100c0 {
compatible = "sprd,sc9860-eic-sync";
reg = <0 0x402100c0 0 0x20>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
};
pmic_eic: gpio@300 {
compatible = "sprd,sc2731-eic";
reg = <0x300>;
interrupt-parent = <&sc2731_pmic>;
interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
Spreadtrum GPIO controller bindings
The controller's registers are organized as sets of sixteen 16-bit
registers with each set controlling a bank of up to 16 pins. A single
interrupt is shared for all of the banks handled by the controller.
Required properties:
- compatible: Should be "sprd,sc9860-gpio".
- reg: Define the base and range of the I/O address space containing
the GPIO controller registers.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be <2>. The first cell is the gpio number and
the second cell is used to specify optional parameters.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Should be <2>. Specifies the number of cells needed
to encode interrupt source.
- interrupts: Should be the port interrupt shared by all the gpios.
Example:
ap_gpio: gpio@40280000 {
compatible = "sprd,sc9860-gpio";
reg = <0 0x40280000 0 0x1000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright 2022 Unisoc Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/sprd,gpio-eic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Unisoc EIC controller
maintainers:
- Orson Zhai <orsonzhai@gmail.com>
- Baolin Wang <baolin.wang7@gmail.com>
- Chunyan Zhang <zhang.lyra@gmail.com>
description: |
The EIC is the abbreviation of external interrupt controller, which can
be used only in input mode. The Spreadtrum platform has 2 EIC controllers,
one is in digital chip, and another one is in PMIC. The digital chip EIC
controller contains 4 sub-modules, i.e. EIC-debounce, EIC-latch, EIC-async and
EIC-sync. But the PMIC EIC controller contains only one EIC-debounce sub-
module.
The EIC-debounce sub-module provides up to 8 source input signal
connections. A debounce mechanism is used to capture the input signals'
stable status (millisecond resolution) and a single-trigger mechanism
is introduced into this sub-module to enhance the input event detection
reliability. In addition, this sub-module's clock can be shut off
automatically to reduce power dissipation. Moreover the debounce range
is from 1ms to 4s with a step size of 1ms. The input signal will be
ignored if it is asserted for less than 1 ms.
The EIC-latch sub-module is used to latch some special power down signals
and generate interrupts, since the EIC-latch does not depend on the APB
clock to capture signals.
The EIC-async sub-module uses a 32kHz clock to capture the short signals
(microsecond resolution) to generate interrupts by level or edge trigger.
The EIC-sync is similar with GPIO's input function, which is a synchronized
signal input register. It can generate interrupts by level or edge trigger
when detecting input signals.
properties:
compatible:
oneOf:
- enum:
- sprd,sc9860-eic-debounce
- sprd,sc9860-eic-latch
- sprd,sc9860-eic-async
- sprd,sc9860-eic-sync
- sprd,sc2731-eic
- items:
- enum:
- sprd,ums512-eic-debounce
- const: sprd,sc9860-eic-debounce
- items:
- enum:
- sprd,ums512-eic-latch
- const: sprd,sc9860-eic-latch
- items:
- enum:
- sprd,ums512-eic-async
- const: sprd,sc9860-eic-async
- items:
- enum:
- sprd,ums512-eic-sync
- const: sprd,sc9860-eic-sync
- items:
- enum:
- sprd,sc2730-eic
- const: sprd,sc2731-eic
reg:
minItems: 1
maxItems: 3
description:
EIC controller can support maximum 3 banks which has its own
address base.
gpio-controller: true
"#gpio-cells":
const: 2
interrupt-controller: true
"#interrupt-cells":
const: 2
interrupts:
maxItems: 1
description:
The interrupt shared by all GPIO lines for this controller.
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
- interrupt-controller
- "#interrupt-cells"
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
eic_debounce: gpio@40210000 {
compatible = "sprd,sc9860-eic-debounce";
reg = <0 0x40210000 0 0x80>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
};
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright 2022 Unisoc Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/sprd,gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Unisoc GPIO controller
maintainers:
- Orson Zhai <orsonzhai@gmail.com>
- Baolin Wang <baolin.wang7@gmail.com>
- Chunyan Zhang <zhang.lyra@gmail.com>
description: |
The controller's registers are organized as sets of sixteen 16-bit
registers with each set controlling a bank of up to 16 pins. A single
interrupt is shared for all of the banks handled by the controller.
properties:
compatible:
oneOf:
- const: sprd,sc9860-gpio
- items:
- enum:
- sprd,ums512-gpio
- const: sprd,sc9860-gpio
reg:
maxItems: 1
gpio-controller: true
"#gpio-cells":
const: 2
interrupt-controller: true
"#interrupt-cells":
const: 2
interrupts:
maxItems: 1
description: The interrupt shared by all GPIO lines for this controller.
required:
- compatible
- reg
- gpio-controller
- "#gpio-cells"
- interrupt-controller
- "#interrupt-cells"
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
ap_gpio: gpio@40280000 {
compatible = "sprd,sc9860-gpio";
reg = <0 0x40280000 0 0x1000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
};
};
...
...@@ -387,9 +387,6 @@ map between them using calls like:: ...@@ -387,9 +387,6 @@ map between them using calls like::
/* map GPIO numbers to IRQ numbers */ /* map GPIO numbers to IRQ numbers */
int gpio_to_irq(unsigned gpio); int gpio_to_irq(unsigned gpio);
/* map IRQ numbers to GPIO numbers (avoid using this) */
int irq_to_gpio(unsigned irq);
Those return either the corresponding number in the other namespace, or Those return either the corresponding number in the other namespace, or
else a negative errno code if the mapping can't be done. (For example, else a negative errno code if the mapping can't be done. (For example,
some GPIOs can't be used as IRQs.) It is an unchecked error to use a GPIO some GPIOs can't be used as IRQs.) It is an unchecked error to use a GPIO
...@@ -405,11 +402,6 @@ devices, by the board-specific initialization code. Note that IRQ trigger ...@@ -405,11 +402,6 @@ devices, by the board-specific initialization code. Note that IRQ trigger
options are part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are options are part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are
system wakeup capabilities. system wakeup capabilities.
Non-error values returned from irq_to_gpio() would most commonly be used
with gpio_get_value(), for example to initialize or update driver state
when the IRQ is edge-triggered. Note that some platforms don't support
this reverse mapping, so you should avoid using it.
Emulating Open Drain Signals Emulating Open Drain Signals
---------------------------- ----------------------------
...@@ -735,10 +727,6 @@ requested using gpio_request():: ...@@ -735,10 +727,6 @@ requested using gpio_request()::
/* reverse gpio_export() */ /* reverse gpio_export() */
void gpio_unexport(); void gpio_unexport();
/* create a sysfs link to an exported GPIO node */
int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
After a kernel driver requests a GPIO, it may only be made available in After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpio_export(). The driver can control whether the the sysfs interface by gpio_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code signal direction may change. This helps drivers prevent userspace code
...@@ -748,11 +736,6 @@ This explicit exporting can help with debugging (by making some kinds ...@@ -748,11 +736,6 @@ This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface that's of experiments easier), or can provide an always-there interface that's
suitable for documenting as part of a board support package. suitable for documenting as part of a board support package.
After the GPIO has been exported, gpio_export_link() allows creating
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
use this to provide the interface under their own device in sysfs with
a descriptive name.
API Reference API Reference
============= =============
......
...@@ -358,9 +358,6 @@ GPIO 编号是无符号整数;IRQ 编号也是。这些构成了两个逻辑上 ...@@ -358,9 +358,6 @@ GPIO 编号是无符号整数;IRQ 编号也是。这些构成了两个逻辑上
/* 映射 GPIO 编号到 IRQ 编号 */ /* 映射 GPIO 编号到 IRQ 编号 */
int gpio_to_irq(unsigned gpio); int gpio_to_irq(unsigned gpio);
/* 映射 IRQ 编号到 GPIO 编号 (尽量避免使用) */
int irq_to_gpio(unsigned irq);
它们的返回值为对应命名空间的相关编号,或是负的错误代码(如果无法映射)。 它们的返回值为对应命名空间的相关编号,或是负的错误代码(如果无法映射)。
(例如,某些 GPIO 无法做为 IRQ 使用。)以下的编号错误是未经检测的:使用一个 (例如,某些 GPIO 无法做为 IRQ 使用。)以下的编号错误是未经检测的:使用一个
未通过 gpio_direction_input()配置为输入的 GPIO 编号,或者使用一个 未通过 gpio_direction_input()配置为输入的 GPIO 编号,或者使用一个
...@@ -373,10 +370,6 @@ gpio_to_irq()返回的非错误值可以传递给 request_irq()或者 free_irq() ...@@ -373,10 +370,6 @@ gpio_to_irq()返回的非错误值可以传递给 request_irq()或者 free_irq()
触发选项是 IRQ 接口的一部分,如 IRQF_TRIGGER_FALLING,系统唤醒能力 触发选项是 IRQ 接口的一部分,如 IRQF_TRIGGER_FALLING,系统唤醒能力
也是如此。 也是如此。
irq_to_gpio()返回的非错误值大多数通常可以被 gpio_get_value()所使用,
比如在 IRQ 是沿触发时初始化或更新驱动状态。注意某些平台不支持反映射,所以
你应该尽量避免使用它。
模拟开漏信号 模拟开漏信号
------------ ------------
...@@ -672,10 +665,6 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO ...@@ -672,10 +665,6 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO
/* gpio_export()的逆操作 */ /* gpio_export()的逆操作 */
void gpio_unexport(); void gpio_unexport();
/* 创建一个 sysfs 连接到已导出的 GPIO 节点 */
int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
在一个内核驱动申请一个 GPIO 之后,它可以通过 gpio_export()使其在 sysfs 在一个内核驱动申请一个 GPIO 之后,它可以通过 gpio_export()使其在 sysfs
接口中可见。该驱动可以控制信号方向是否可修改。这有助于防止用户空间代码无意间 接口中可见。该驱动可以控制信号方向是否可修改。这有助于防止用户空间代码无意间
破坏重要的系统状态。 破坏重要的系统状态。
...@@ -683,10 +672,6 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO ...@@ -683,10 +672,6 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO
这个明确的导出有助于(通过使某些实验更容易来)调试,也可以提供一个始终存在的接口, 这个明确的导出有助于(通过使某些实验更容易来)调试,也可以提供一个始终存在的接口,
与文档配合作为板级支持包的一部分。 与文档配合作为板级支持包的一部分。
在 GPIO 被导出之后,gpio_export_link()允许在 sysfs 文件系统的任何地方
创建一个到这个 GPIO sysfs 节点的符号链接。这样驱动就可以通过一个描述性的
名字,在 sysfs 中他们所拥有的设备下提供一个(到这个 GPIO sysfs 节点的)接口。
API参考 API参考
======= =======
......
...@@ -363,9 +363,6 @@ GPIO 編號是無符號整數;IRQ 編號也是。這些構成了兩個邏輯上 ...@@ -363,9 +363,6 @@ GPIO 編號是無符號整數;IRQ 編號也是。這些構成了兩個邏輯上
/* 映射 GPIO 編號到 IRQ 編號 */ /* 映射 GPIO 編號到 IRQ 編號 */
int gpio_to_irq(unsigned gpio); int gpio_to_irq(unsigned gpio);
/* 映射 IRQ 編號到 GPIO 編號 (儘量避免使用) */
int irq_to_gpio(unsigned irq);
它們的返回值爲對應命名空間的相關編號,或是負的錯誤代碼(如果無法映射)。 它們的返回值爲對應命名空間的相關編號,或是負的錯誤代碼(如果無法映射)。
(例如,某些 GPIO 無法做爲 IRQ 使用。)以下的編號錯誤是未經檢測的:使用一個 (例如,某些 GPIO 無法做爲 IRQ 使用。)以下的編號錯誤是未經檢測的:使用一個
未通過 gpio_direction_input()配置爲輸入的 GPIO 編號,或者使用一個 未通過 gpio_direction_input()配置爲輸入的 GPIO 編號,或者使用一個
...@@ -378,10 +375,6 @@ gpio_to_irq()返回的非錯誤值可以傳遞給 request_irq()或者 free_irq() ...@@ -378,10 +375,6 @@ gpio_to_irq()返回的非錯誤值可以傳遞給 request_irq()或者 free_irq()
觸發選項是 IRQ 接口的一部分,如 IRQF_TRIGGER_FALLING,系統喚醒能力 觸發選項是 IRQ 接口的一部分,如 IRQF_TRIGGER_FALLING,系統喚醒能力
也是如此。 也是如此。
irq_to_gpio()返回的非錯誤值大多數通常可以被 gpio_get_value()所使用,
比如在 IRQ 是沿觸發時初始化或更新驅動狀態。注意某些平台不支持反映射,所以
你應該儘量避免使用它。
模擬開漏信號 模擬開漏信號
---------------------------- ----------------------------
...@@ -634,18 +627,9 @@ GPIO 控制器的路徑類似 /sys/class/gpio/gpiochip42/ (對於從#42 GPIO ...@@ -634,18 +627,9 @@ GPIO 控制器的路徑類似 /sys/class/gpio/gpiochip42/ (對於從#42 GPIO
/* gpio_export()的逆操作 */ /* gpio_export()的逆操作 */
void gpio_unexport(); void gpio_unexport();
/* 創建一個 sysfs 連接到已導出的 GPIO 節點 */
int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
在一個內核驅動申請一個 GPIO 之後,它可以通過 gpio_export()使其在 sysfs 在一個內核驅動申請一個 GPIO 之後,它可以通過 gpio_export()使其在 sysfs
接口中可見。該驅動可以控制信號方向是否可修改。這有助於防止用戶空間代碼無意間 接口中可見。該驅動可以控制信號方向是否可修改。這有助於防止用戶空間代碼無意間
破壞重要的系統狀態。 破壞重要的系統狀態。
這個明確的導出有助於(通過使某些實驗更容易來)調試,也可以提供一個始終存在的接口, 這個明確的導出有助於(通過使某些實驗更容易來)調試,也可以提供一個始終存在的接口,
與文檔配合作爲板級支持包的一部分。 與文檔配合作爲板級支持包的一部分。
在 GPIO 被導出之後,gpio_export_link()允許在 sysfs 文件系統的任何地方
創建一個到這個 GPIO sysfs 節點的符號連結。這樣驅動就可以通過一個描述性的
名字,在 sysfs 中他們所擁有的設備下提供一個(到這個 GPIO sysfs 節點的)接口。
...@@ -66,13 +66,6 @@ static inline int gpio_to_irq(unsigned gpio) ...@@ -66,13 +66,6 @@ static inline int gpio_to_irq(unsigned gpio)
return __gpio_to_irq(gpio); return __gpio_to_irq(gpio);
} }
static inline int irq_to_gpio(unsigned irq)
{
return (irq >= MCFGPIO_IRQ_VECBASE &&
irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
}
static inline int gpio_cansleep(unsigned gpio) static inline int gpio_cansleep(unsigned gpio)
{ {
return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
......
...@@ -40,11 +40,6 @@ static inline int gpio_to_irq(unsigned gpio) ...@@ -40,11 +40,6 @@ static inline int gpio_to_irq(unsigned gpio)
return __gpio_to_irq(gpio); return __gpio_to_irq(gpio);
} }
static inline int irq_to_gpio(unsigned int irq)
{
return -ENOSYS;
}
#endif /* CONFIG_GPIOLIB */ #endif /* CONFIG_GPIOLIB */
#endif /* __ASM_SH_GPIO_H */ #endif /* __ASM_SH_GPIO_H */
...@@ -752,7 +752,7 @@ config GPIO_XTENSA ...@@ -752,7 +752,7 @@ config GPIO_XTENSA
config GPIO_ZEVIO config GPIO_ZEVIO
bool "LSI ZEVIO SoC memory mapped GPIOs" bool "LSI ZEVIO SoC memory mapped GPIOs"
depends on ARM && OF_GPIO depends on ARM
help help
Say yes here to support the GPIO controller in LSI ZEVIO SoCs. Say yes here to support the GPIO controller in LSI ZEVIO SoCs.
...@@ -821,6 +821,7 @@ menu "Port-mapped I/O GPIO drivers" ...@@ -821,6 +821,7 @@ menu "Port-mapped I/O GPIO drivers"
config GPIO_I8255 config GPIO_I8255
tristate tristate
select GPIO_REGMAP
help help
Enables support for the i8255 interface library functions. The i8255 Enables support for the i8255 interface library functions. The i8255
interface library provides functions to facilitate communication with interface library provides functions to facilitate communication with
...@@ -835,6 +836,8 @@ config GPIO_104_DIO_48E ...@@ -835,6 +836,8 @@ config GPIO_104_DIO_48E
tristate "ACCES 104-DIO-48E GPIO support" tristate "ACCES 104-DIO-48E GPIO support"
depends on PC104 depends on PC104
select ISA_BUS_API select ISA_BUS_API
select REGMAP_MMIO
select REGMAP_IRQ
select GPIOLIB_IRQCHIP select GPIOLIB_IRQCHIP
select GPIO_I8255 select GPIO_I8255
help help
...@@ -860,8 +863,10 @@ config GPIO_104_IDI_48 ...@@ -860,8 +863,10 @@ config GPIO_104_IDI_48
tristate "ACCES 104-IDI-48 GPIO support" tristate "ACCES 104-IDI-48 GPIO support"
depends on PC104 depends on PC104
select ISA_BUS_API select ISA_BUS_API
select REGMAP_MMIO
select REGMAP_IRQ
select GPIOLIB_IRQCHIP select GPIOLIB_IRQCHIP
select GPIO_I8255 select GPIO_REGMAP
help help
Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A, Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A,
104-IDI-48AC, 104-IDI-48B, 104-IDI-48BC). The base port addresses for 104-IDI-48AC, 104-IDI-48B, 104-IDI-48BC). The base port addresses for
...@@ -883,6 +888,7 @@ config GPIO_GPIO_MM ...@@ -883,6 +888,7 @@ config GPIO_GPIO_MM
tristate "Diamond Systems GPIO-MM GPIO support" tristate "Diamond Systems GPIO-MM GPIO support"
depends on PC104 depends on PC104
select ISA_BUS_API select ISA_BUS_API
select REGMAP_MMIO
select GPIO_I8255 select GPIO_I8255
help help
Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12. Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12.
......
...@@ -61,8 +61,8 @@ Work items: ...@@ -61,8 +61,8 @@ Work items:
- Get rid of struct of_mm_gpio_chip altogether: use the generic MMIO - Get rid of struct of_mm_gpio_chip altogether: use the generic MMIO
GPIO for all current users (see below). Delete struct of_mm_gpio_chip, GPIO for all current users (see below). Delete struct of_mm_gpio_chip,
to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_add() to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_remove()
of_mm_gpiochip_remove() from the kernel. from the kernel.
- Change all consumer drivers that #include <linux/of_gpio.h> to - Change all consumer drivers that #include <linux/of_gpio.h> to
#include <linux/gpio/consumer.h> and stop doing custom parsing of the #include <linux/gpio/consumer.h> and stop doing custom parsing of the
......
This diff is collapsed.
This diff is collapsed.
...@@ -252,7 +252,6 @@ static int davinci_gpio_probe(struct platform_device *pdev) ...@@ -252,7 +252,6 @@ static int davinci_gpio_probe(struct platform_device *pdev)
chips->chip.base = pdata->no_auto_base ? pdata->base : -1; chips->chip.base = pdata->no_auto_base ? pdata->base : -1;
#ifdef CONFIG_OF_GPIO #ifdef CONFIG_OF_GPIO
chips->chip.of_gpio_n_cells = 2;
chips->chip.parent = dev; chips->chip.parent = dev;
chips->chip.request = gpiochip_generic_request; chips->chip.request = gpiochip_generic_request;
chips->chip.free = gpiochip_generic_free; chips->chip.free = gpiochip_generic_free;
...@@ -534,7 +533,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) ...@@ -534,7 +533,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
} }
/* /*
* Arrange gpio_to_irq() support, handling either direct IRQs or * Arrange gpiod_to_irq() support, handling either direct IRQs or
* banked IRQs. Having GPIOs in the first GPIO bank use direct * banked IRQs. Having GPIOs in the first GPIO bank use direct
* IRQs, while the others use banked IRQs, would need some setup * IRQs, while the others use banked IRQs, would need some setup
* tweaks to recognize hardware which can do that. * tweaks to recognize hardware which can do that.
......
...@@ -81,7 +81,6 @@ static int __init gef_gpio_probe(struct platform_device *pdev) ...@@ -81,7 +81,6 @@ static int __init gef_gpio_probe(struct platform_device *pdev)
gc->base = -1; gc->base = -1;
gc->ngpio = (u16)(uintptr_t)of_device_get_match_data(&pdev->dev); gc->ngpio = (u16)(uintptr_t)of_device_get_match_data(&pdev->dev);
gc->of_gpio_n_cells = 2;
/* This function adds a memory mapped GPIO chip */ /* This function adds a memory mapped GPIO chip */
ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL); ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL);
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/isa.h> #include <linux/isa.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include "gpio-i8255.h" #include "gpio-i8255.h"
...@@ -30,83 +30,22 @@ MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses"); ...@@ -30,83 +30,22 @@ MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses");
#define GPIOMM_NUM_PPI 2 #define GPIOMM_NUM_PPI 2
/** static const struct regmap_range gpiomm_volatile_ranges[] = {
* struct gpiomm_gpio - GPIO device private data structure i8255_volatile_regmap_range(0x0), i8255_volatile_regmap_range(0x4),
* @chip: instance of the gpio_chip };
* @ppi_state: Programmable Peripheral Interface group states static const struct regmap_access_table gpiomm_volatile_table = {
* @ppi: Programmable Peripheral Interface groups .yes_ranges = gpiomm_volatile_ranges,
*/ .n_yes_ranges = ARRAY_SIZE(gpiomm_volatile_ranges),
struct gpiomm_gpio { };
struct gpio_chip chip; static const struct regmap_config gpiomm_regmap_config = {
struct i8255_state ppi_state[GPIOMM_NUM_PPI]; .reg_bits = 8,
struct i8255 __iomem *ppi; .reg_stride = 1,
.val_bits = 8,
.io_port = true,
.max_register = 0x7,
.volatile_table = &gpiomm_volatile_table,
.cache_type = REGCACHE_FLAT,
}; };
static int gpiomm_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
if (i8255_get_direction(gpiommgpio->ppi_state, offset))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
i8255_direction_input(gpiommgpio->ppi, gpiommgpio->ppi_state, offset);
return 0;
}
static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
i8255_direction_output(gpiommgpio->ppi, gpiommgpio->ppi_state, offset,
value);
return 0;
}
static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
return i8255_get(gpiommgpio->ppi, offset);
}
static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
i8255_get_multiple(gpiommgpio->ppi, mask, bits, chip->ngpio);
return 0;
}
static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
i8255_set(gpiommgpio->ppi, gpiommgpio->ppi_state, offset, value);
}
static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
unsigned long *mask, unsigned long *bits)
{
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
i8255_set_multiple(gpiommgpio->ppi, gpiommgpio->ppi_state, mask, bits,
chip->ngpio);
}
#define GPIOMM_NGPIO 48 #define GPIOMM_NGPIO 48
static const char *gpiomm_names[GPIOMM_NGPIO] = { static const char *gpiomm_names[GPIOMM_NGPIO] = {
...@@ -120,30 +59,11 @@ static const char *gpiomm_names[GPIOMM_NGPIO] = { ...@@ -120,30 +59,11 @@ static const char *gpiomm_names[GPIOMM_NGPIO] = {
"Port 2C2", "Port 2C3", "Port 2C4", "Port 2C5", "Port 2C6", "Port 2C7", "Port 2C2", "Port 2C3", "Port 2C4", "Port 2C5", "Port 2C6", "Port 2C7",
}; };
static void gpiomm_init_dio(struct i8255 __iomem *const ppi,
struct i8255_state *const ppi_state)
{
const unsigned long ngpio = 24;
const unsigned long mask = GENMASK(ngpio - 1, 0);
const unsigned long bits = 0;
unsigned long i;
/* Initialize all GPIO to output 0 */
for (i = 0; i < GPIOMM_NUM_PPI; i++) {
i8255_mode0_output(&ppi[i]);
i8255_set_multiple(&ppi[i], &ppi_state[i], &mask, &bits, ngpio);
}
}
static int gpiomm_probe(struct device *dev, unsigned int id) static int gpiomm_probe(struct device *dev, unsigned int id)
{ {
struct gpiomm_gpio *gpiommgpio;
const char *const name = dev_name(dev); const char *const name = dev_name(dev);
int err; struct i8255_regmap_config config = {};
void __iomem *regs;
gpiommgpio = devm_kzalloc(dev, sizeof(*gpiommgpio), GFP_KERNEL);
if (!gpiommgpio)
return -ENOMEM;
if (!devm_request_region(dev, base[id], GPIOMM_EXTENT, name)) { if (!devm_request_region(dev, base[id], GPIOMM_EXTENT, name)) {
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
...@@ -151,34 +71,20 @@ static int gpiomm_probe(struct device *dev, unsigned int id) ...@@ -151,34 +71,20 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
return -EBUSY; return -EBUSY;
} }
gpiommgpio->ppi = devm_ioport_map(dev, base[id], GPIOMM_EXTENT); regs = devm_ioport_map(dev, base[id], GPIOMM_EXTENT);
if (!gpiommgpio->ppi) if (!regs)
return -ENOMEM; return -ENOMEM;
gpiommgpio->chip.label = name; config.map = devm_regmap_init_mmio(dev, regs, &gpiomm_regmap_config);
gpiommgpio->chip.parent = dev; if (IS_ERR(config.map))
gpiommgpio->chip.owner = THIS_MODULE; return dev_err_probe(dev, PTR_ERR(config.map),
gpiommgpio->chip.base = -1; "Unable to initialize register map\n");
gpiommgpio->chip.ngpio = GPIOMM_NGPIO;
gpiommgpio->chip.names = gpiomm_names; config.parent = dev;
gpiommgpio->chip.get_direction = gpiomm_gpio_get_direction; config.num_ppi = GPIOMM_NUM_PPI;
gpiommgpio->chip.direction_input = gpiomm_gpio_direction_input; config.names = gpiomm_names;
gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output;
gpiommgpio->chip.get = gpiomm_gpio_get;
gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;
gpiommgpio->chip.set = gpiomm_gpio_set;
gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple;
i8255_state_init(gpiommgpio->ppi_state, GPIOMM_NUM_PPI);
gpiomm_init_dio(gpiommgpio->ppi, gpiommgpio->ppi_state);
err = devm_gpiochip_add_data(dev, &gpiommgpio->chip, gpiommgpio);
if (err) {
dev_err(dev, "GPIO registering failed (%d)\n", err);
return err;
}
return 0; return devm_i8255_regmap_register(dev, &config);
} }
static struct isa_driver gpiomm_driver = { static struct isa_driver gpiomm_driver = {
......
This diff is collapsed.
...@@ -3,44 +3,32 @@ ...@@ -3,44 +3,32 @@
#ifndef _I8255_H_ #ifndef _I8255_H_
#define _I8255_H_ #define _I8255_H_
#include <linux/spinlock.h> struct device;
#include <linux/types.h> struct irq_domain;
struct regmap;
/** #define i8255_volatile_regmap_range(_base) regmap_reg_range(_base, _base + 0x2)
* struct i8255 - Intel 8255 register structure
* @port: Port A, B, and C
* @control: Control register
*/
struct i8255 {
u8 port[3];
u8 control;
};
/** /**
* struct i8255_state - Intel 8255 state structure * struct i8255_regmap_config - Configuration for the register map of an i8255
* @lock: synchronization lock for accessing device state * @parent: parent device
* @control_state: Control register state * @map: regmap for the i8255
* @num_ppi: number of i8255 Programmable Peripheral Interface
* @names: (optional) array of names for gpios
* @domain: (optional) IRQ domain if the controller is interrupt-capable
*
* Note: The regmap is expected to have cache enabled and i8255 control
* registers not marked as volatile.
*/ */
struct i8255_state { struct i8255_regmap_config {
spinlock_t lock; struct device *parent;
u8 control_state; struct regmap *map;
int num_ppi;
const char *const *names;
struct irq_domain *domain;
}; };
void i8255_direction_input(struct i8255 __iomem *ppi, struct i8255_state *state, int devm_i8255_regmap_register(struct device *dev,
unsigned long offset); const struct i8255_regmap_config *config);
void i8255_direction_output(struct i8255 __iomem *ppi,
struct i8255_state *state, unsigned long offset,
unsigned long value);
int i8255_get(struct i8255 __iomem *ppi, unsigned long offset);
int i8255_get_direction(const struct i8255_state *state, unsigned long offset);
void i8255_get_multiple(struct i8255 __iomem *ppi, const unsigned long *mask,
unsigned long *bits, unsigned long ngpio);
void i8255_mode0_output(struct i8255 __iomem *const ppi);
void i8255_set(struct i8255 __iomem *ppi, struct i8255_state *state,
unsigned long offset, unsigned long value);
void i8255_set_multiple(struct i8255 __iomem *ppi, struct i8255_state *state,
const unsigned long *mask, const unsigned long *bits,
unsigned long ngpio);
void i8255_state_init(struct i8255_state *const state, unsigned long nbanks);
#endif /* _I8255_H_ */ #endif /* _I8255_H_ */
...@@ -655,11 +655,6 @@ static int msc313_gpio_probe(struct platform_device *pdev) ...@@ -655,11 +655,6 @@ static int msc313_gpio_probe(struct platform_device *pdev)
return devm_gpiochip_add_data(dev, gpiochip, gpio); return devm_gpiochip_add_data(dev, gpiochip, gpio);
} }
static int msc313_gpio_remove(struct platform_device *pdev)
{
return 0;
}
static const struct of_device_id msc313_gpio_of_match[] = { static const struct of_device_id msc313_gpio_of_match[] = {
#ifdef CONFIG_MACH_INFINITY #ifdef CONFIG_MACH_INFINITY
{ {
...@@ -710,6 +705,5 @@ static struct platform_driver msc313_gpio_driver = { ...@@ -710,6 +705,5 @@ static struct platform_driver msc313_gpio_driver = {
.pm = &msc313_gpio_ops, .pm = &msc313_gpio_ops,
}, },
.probe = msc313_gpio_probe, .probe = msc313_gpio_probe,
.remove = msc313_gpio_remove,
}; };
builtin_platform_driver(msc313_gpio_driver); builtin_platform_driver(msc313_gpio_driver);
...@@ -1002,7 +1002,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state) ...@@ -1002,7 +1002,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
BUG(); BUG();
} }
if (IS_ENABLED(CONFIG_PWM)) if (IS_REACHABLE(CONFIG_PWM))
mvebu_pwm_suspend(mvchip); mvebu_pwm_suspend(mvchip);
return 0; return 0;
...@@ -1054,7 +1054,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev) ...@@ -1054,7 +1054,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
BUG(); BUG();
} }
if (IS_ENABLED(CONFIG_PWM)) if (IS_REACHABLE(CONFIG_PWM))
mvebu_pwm_resume(mvchip); mvebu_pwm_resume(mvchip);
return 0; return 0;
...@@ -1228,7 +1228,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1228,7 +1228,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip);
/* Some MVEBU SoCs have simple PWM support for GPIO lines */ /* Some MVEBU SoCs have simple PWM support for GPIO lines */
if (IS_ENABLED(CONFIG_PWM)) { if (IS_REACHABLE(CONFIG_PWM)) {
err = mvebu_pwm_probe(pdev, mvchip, id); err = mvebu_pwm_probe(pdev, mvchip, id);
if (err) if (err)
return err; return err;
......
...@@ -1020,7 +1020,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc, ...@@ -1020,7 +1020,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc,
if (!label) if (!label)
return -ENOMEM; return -ENOMEM;
bank->chip.label = label; bank->chip.label = label;
bank->chip.base = gpio; bank->chip.base = -1;
} }
bank->chip.ngpio = bank->width; bank->chip.ngpio = bank->width;
......
...@@ -306,34 +306,31 @@ static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg, ...@@ -306,34 +306,31 @@ static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg,
static bool pcal6534_check_register(struct pca953x_chip *chip, unsigned int reg, static bool pcal6534_check_register(struct pca953x_chip *chip, unsigned int reg,
u32 checkbank) u32 checkbank)
{ {
int bank_shift;
int bank; int bank;
int offset; int offset;
if (reg >= 0x30) { if (reg >= 0x54) {
/*
* Reserved block between 14h and 2Fh does not align on
* expected bank boundaries like other devices.
*/
int temp = reg - 0x30;
bank = temp / NBANK(chip);
offset = temp - (bank * NBANK(chip));
bank += 8;
} else if (reg >= 0x54) {
/* /*
* Handle lack of reserved registers after output port * Handle lack of reserved registers after output port
* configuration register to form a bank. * configuration register to form a bank.
*/ */
int temp = reg - 0x54; reg -= 0x54;
bank_shift = 16;
bank = temp / NBANK(chip); } else if (reg >= 0x30) {
offset = temp - (bank * NBANK(chip)); /*
bank += 16; * Reserved block between 14h and 2Fh does not align on
* expected bank boundaries like other devices.
*/
reg -= 0x30;
bank_shift = 8;
} else { } else {
bank = reg / NBANK(chip); bank_shift = 0;
offset = reg - (bank * NBANK(chip));
} }
bank = bank_shift + reg / NBANK(chip);
offset = reg % NBANK(chip);
/* Register is not in the matching bank. */ /* Register is not in the matching bank. */
if (!(BIT(bank) & checkbank)) if (!(BIT(bank) & checkbank))
return false; return false;
...@@ -464,7 +461,6 @@ static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off) ...@@ -464,7 +461,6 @@ static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off)
case PCAL953X_PULL_SEL: case PCAL953X_PULL_SEL:
case PCAL953X_INT_MASK: case PCAL953X_INT_MASK:
case PCAL953X_INT_STAT: case PCAL953X_INT_STAT:
case PCAL953X_OUT_CONF:
pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x20; pinctrl = ((reg & PCAL_PINCTRL_MASK) >> 1) + 0x20;
break; break;
case PCAL6524_INT_EDGE: case PCAL6524_INT_EDGE:
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
#define SLG7XL45106_GPO_REG 0xDB #define SLG7XL45106_GPO_REG 0xDB
/** /**
* struct pca9570_platform_data - GPIO platformdata * struct pca9570_chip_data - GPIO platformdata
* @ngpio: no of gpios * @ngpio: no of gpios
* @command: Command to be sent * @command: Command to be sent
*/ */
struct pca9570_platform_data { struct pca9570_chip_data {
u16 ngpio; u16 ngpio;
u32 command; u32 command;
}; };
...@@ -36,7 +36,7 @@ struct pca9570_platform_data { ...@@ -36,7 +36,7 @@ struct pca9570_platform_data {
*/ */
struct pca9570 { struct pca9570 {
struct gpio_chip chip; struct gpio_chip chip;
const struct pca9570_platform_data *p_data; const struct pca9570_chip_data *chip_data;
struct mutex lock; struct mutex lock;
u8 out; u8 out;
}; };
...@@ -46,8 +46,8 @@ static int pca9570_read(struct pca9570 *gpio, u8 *value) ...@@ -46,8 +46,8 @@ static int pca9570_read(struct pca9570 *gpio, u8 *value)
struct i2c_client *client = to_i2c_client(gpio->chip.parent); struct i2c_client *client = to_i2c_client(gpio->chip.parent);
int ret; int ret;
if (gpio->p_data->command != 0) if (gpio->chip_data->command != 0)
ret = i2c_smbus_read_byte_data(client, gpio->p_data->command); ret = i2c_smbus_read_byte_data(client, gpio->chip_data->command);
else else
ret = i2c_smbus_read_byte(client); ret = i2c_smbus_read_byte(client);
...@@ -62,8 +62,8 @@ static int pca9570_write(struct pca9570 *gpio, u8 value) ...@@ -62,8 +62,8 @@ static int pca9570_write(struct pca9570 *gpio, u8 value)
{ {
struct i2c_client *client = to_i2c_client(gpio->chip.parent); struct i2c_client *client = to_i2c_client(gpio->chip.parent);
if (gpio->p_data->command != 0) if (gpio->chip_data->command != 0)
return i2c_smbus_write_byte_data(client, gpio->p_data->command, value); return i2c_smbus_write_byte_data(client, gpio->chip_data->command, value);
return i2c_smbus_write_byte(client, value); return i2c_smbus_write_byte(client, value);
} }
...@@ -127,8 +127,8 @@ static int pca9570_probe(struct i2c_client *client) ...@@ -127,8 +127,8 @@ static int pca9570_probe(struct i2c_client *client)
gpio->chip.get = pca9570_get; gpio->chip.get = pca9570_get;
gpio->chip.set = pca9570_set; gpio->chip.set = pca9570_set;
gpio->chip.base = -1; gpio->chip.base = -1;
gpio->p_data = device_get_match_data(&client->dev); gpio->chip_data = device_get_match_data(&client->dev);
gpio->chip.ngpio = gpio->p_data->ngpio; gpio->chip.ngpio = gpio->chip_data->ngpio;
gpio->chip.can_sleep = true; gpio->chip.can_sleep = true;
mutex_init(&gpio->lock); mutex_init(&gpio->lock);
...@@ -141,15 +141,15 @@ static int pca9570_probe(struct i2c_client *client) ...@@ -141,15 +141,15 @@ static int pca9570_probe(struct i2c_client *client)
return devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); return devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio);
} }
static const struct pca9570_platform_data pca9570_gpio = { static const struct pca9570_chip_data pca9570_gpio = {
.ngpio = 4, .ngpio = 4,
}; };
static const struct pca9570_platform_data pca9571_gpio = { static const struct pca9570_chip_data pca9571_gpio = {
.ngpio = 8, .ngpio = 8,
}; };
static const struct pca9570_platform_data slg7xl45106_gpio = { static const struct pca9570_chip_data slg7xl45106_gpio = {
.ngpio = 8, .ngpio = 8,
.command = SLG7XL45106_GPO_REG, .command = SLG7XL45106_GPO_REG,
}; };
......
...@@ -7,18 +7,16 @@ ...@@ -7,18 +7,16 @@
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/property.h>
#include <linux/of_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
static const struct i2c_device_id pcf857x_id[] = { static const struct i2c_device_id pcf857x_id[] = {
{ "pcf8574", 8 }, { "pcf8574", 8 },
{ "pcf8574a", 8 }, { "pcf8574a", 8 },
...@@ -37,7 +35,6 @@ static const struct i2c_device_id pcf857x_id[] = { ...@@ -37,7 +35,6 @@ static const struct i2c_device_id pcf857x_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, pcf857x_id); MODULE_DEVICE_TABLE(i2c, pcf857x_id);
#ifdef CONFIG_OF
static const struct of_device_id pcf857x_of_table[] = { static const struct of_device_id pcf857x_of_table[] = {
{ .compatible = "nxp,pcf8574" }, { .compatible = "nxp,pcf8574" },
{ .compatible = "nxp,pcf8574a" }, { .compatible = "nxp,pcf8574a" },
...@@ -55,7 +52,6 @@ static const struct of_device_id pcf857x_of_table[] = { ...@@ -55,7 +52,6 @@ static const struct of_device_id pcf857x_of_table[] = {
{ } { }
}; };
MODULE_DEVICE_TABLE(of, pcf857x_of_table); MODULE_DEVICE_TABLE(of, pcf857x_of_table);
#endif
/* /*
* The pcf857x, pca857x, and pca967x chips only expose one read and one * The pcf857x, pca857x, and pca967x chips only expose one read and one
...@@ -73,11 +69,11 @@ struct pcf857x { ...@@ -73,11 +69,11 @@ struct pcf857x {
struct gpio_chip chip; struct gpio_chip chip;
struct i2c_client *client; struct i2c_client *client;
struct mutex lock; /* protect 'out' */ struct mutex lock; /* protect 'out' */
unsigned out; /* software latch */ unsigned int out; /* software latch */
unsigned status; /* current status */ unsigned int status; /* current status */
unsigned irq_enabled; /* enabled irqs */ unsigned int irq_enabled; /* enabled irqs */
int (*write)(struct i2c_client *client, unsigned data); int (*write)(struct i2c_client *client, unsigned int data);
int (*read)(struct i2c_client *client); int (*read)(struct i2c_client *client);
}; };
...@@ -85,19 +81,19 @@ struct pcf857x { ...@@ -85,19 +81,19 @@ struct pcf857x {
/* Talk to 8-bit I/O expander */ /* Talk to 8-bit I/O expander */
static int i2c_write_le8(struct i2c_client *client, unsigned data) static int i2c_write_le8(struct i2c_client *client, unsigned int data)
{ {
return i2c_smbus_write_byte(client, data); return i2c_smbus_write_byte(client, data);
} }
static int i2c_read_le8(struct i2c_client *client) static int i2c_read_le8(struct i2c_client *client)
{ {
return (int)i2c_smbus_read_byte(client); return i2c_smbus_read_byte(client);
} }
/* Talk to 16-bit I/O expander */ /* Talk to 16-bit I/O expander */
static int i2c_write_le16(struct i2c_client *client, unsigned word) static int i2c_write_le16(struct i2c_client *client, unsigned int word)
{ {
u8 buf[2] = { word & 0xff, word >> 8, }; u8 buf[2] = { word & 0xff, word >> 8, };
int status; int status;
...@@ -119,7 +115,7 @@ static int i2c_read_le16(struct i2c_client *client) ...@@ -119,7 +115,7 @@ static int i2c_read_le16(struct i2c_client *client)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static int pcf857x_input(struct gpio_chip *chip, unsigned offset) static int pcf857x_input(struct gpio_chip *chip, unsigned int offset)
{ {
struct pcf857x *gpio = gpiochip_get_data(chip); struct pcf857x *gpio = gpiochip_get_data(chip);
int status; int status;
...@@ -132,7 +128,7 @@ static int pcf857x_input(struct gpio_chip *chip, unsigned offset) ...@@ -132,7 +128,7 @@ static int pcf857x_input(struct gpio_chip *chip, unsigned offset)
return status; return status;
} }
static int pcf857x_get(struct gpio_chip *chip, unsigned offset) static int pcf857x_get(struct gpio_chip *chip, unsigned int offset)
{ {
struct pcf857x *gpio = gpiochip_get_data(chip); struct pcf857x *gpio = gpiochip_get_data(chip);
int value; int value;
...@@ -141,10 +137,25 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned offset) ...@@ -141,10 +137,25 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned offset)
return (value < 0) ? value : !!(value & (1 << offset)); return (value < 0) ? value : !!(value & (1 << offset));
} }
static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) static int pcf857x_get_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits)
{ {
struct pcf857x *gpio = gpiochip_get_data(chip); struct pcf857x *gpio = gpiochip_get_data(chip);
unsigned bit = 1 << offset; int value = gpio->read(gpio->client);
if (value < 0)
return value;
*bits &= ~*mask;
*bits |= value & *mask;
return 0;
}
static int pcf857x_output(struct gpio_chip *chip, unsigned int offset, int value)
{
struct pcf857x *gpio = gpiochip_get_data(chip);
unsigned int bit = 1 << offset;
int status; int status;
mutex_lock(&gpio->lock); mutex_lock(&gpio->lock);
...@@ -158,11 +169,23 @@ static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) ...@@ -158,11 +169,23 @@ static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value)
return status; return status;
} }
static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) static void pcf857x_set(struct gpio_chip *chip, unsigned int offset, int value)
{ {
pcf857x_output(chip, offset, value); pcf857x_output(chip, offset, value);
} }
static void pcf857x_set_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long *bits)
{
struct pcf857x *gpio = gpiochip_get_data(chip);
mutex_lock(&gpio->lock);
gpio->out &= ~*mask;
gpio->out |= *bits & *mask;
gpio->write(gpio->client, gpio->out);
mutex_unlock(&gpio->lock);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static irqreturn_t pcf857x_irq(int irq, void *data) static irqreturn_t pcf857x_irq(int irq, void *data)
...@@ -250,18 +273,11 @@ static const struct irq_chip pcf857x_irq_chip = { ...@@ -250,18 +273,11 @@ static const struct irq_chip pcf857x_irq_chip = {
static int pcf857x_probe(struct i2c_client *client) static int pcf857x_probe(struct i2c_client *client)
{ {
const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = client->dev.of_node;
struct pcf857x *gpio; struct pcf857x *gpio;
unsigned int n_latch = 0; unsigned int n_latch = 0;
int status; int status;
if (IS_ENABLED(CONFIG_OF) && np) device_property_read_u32(&client->dev, "lines-initial-states", &n_latch);
of_property_read_u32(np, "lines-initial-states", &n_latch);
else if (pdata)
n_latch = pdata->n_latch;
else
dev_dbg(&client->dev, "no platform data\n");
/* Allocate, initialize, and register this gpio_chip. */ /* Allocate, initialize, and register this gpio_chip. */
gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL); gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
...@@ -270,12 +286,14 @@ static int pcf857x_probe(struct i2c_client *client) ...@@ -270,12 +286,14 @@ static int pcf857x_probe(struct i2c_client *client)
mutex_init(&gpio->lock); mutex_init(&gpio->lock);
gpio->chip.base = pdata ? pdata->gpio_base : -1; gpio->chip.base = -1;
gpio->chip.can_sleep = true; gpio->chip.can_sleep = true;
gpio->chip.parent = &client->dev; gpio->chip.parent = &client->dev;
gpio->chip.owner = THIS_MODULE; gpio->chip.owner = THIS_MODULE;
gpio->chip.get = pcf857x_get; gpio->chip.get = pcf857x_get;
gpio->chip.get_multiple = pcf857x_get_multiple;
gpio->chip.set = pcf857x_set; gpio->chip.set = pcf857x_set;
gpio->chip.set_multiple = pcf857x_set_multiple;
gpio->chip.direction_input = pcf857x_input; gpio->chip.direction_input = pcf857x_input;
gpio->chip.direction_output = pcf857x_output; gpio->chip.direction_output = pcf857x_output;
gpio->chip.ngpio = id->driver_data; gpio->chip.ngpio = id->driver_data;
...@@ -377,17 +395,6 @@ static int pcf857x_probe(struct i2c_client *client) ...@@ -377,17 +395,6 @@ static int pcf857x_probe(struct i2c_client *client)
if (status < 0) if (status < 0)
goto fail; goto fail;
/* Let platform code set up the GPIOs and their users.
* Now is the first time anyone could use them.
*/
if (pdata && pdata->setup) {
status = pdata->setup(client,
gpio->chip.base, gpio->chip.ngpio,
pdata->context);
if (status < 0)
dev_warn(&client->dev, "setup --> %d\n", status);
}
dev_info(&client->dev, "probed\n"); dev_info(&client->dev, "probed\n");
return 0; return 0;
...@@ -399,16 +406,6 @@ static int pcf857x_probe(struct i2c_client *client) ...@@ -399,16 +406,6 @@ static int pcf857x_probe(struct i2c_client *client)
return status; return status;
} }
static void pcf857x_remove(struct i2c_client *client)
{
struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pcf857x *gpio = i2c_get_clientdata(client);
if (pdata && pdata->teardown)
pdata->teardown(client, gpio->chip.base, gpio->chip.ngpio,
pdata->context);
}
static void pcf857x_shutdown(struct i2c_client *client) static void pcf857x_shutdown(struct i2c_client *client)
{ {
struct pcf857x *gpio = i2c_get_clientdata(client); struct pcf857x *gpio = i2c_get_clientdata(client);
...@@ -420,10 +417,9 @@ static void pcf857x_shutdown(struct i2c_client *client) ...@@ -420,10 +417,9 @@ static void pcf857x_shutdown(struct i2c_client *client)
static struct i2c_driver pcf857x_driver = { static struct i2c_driver pcf857x_driver = {
.driver = { .driver = {
.name = "pcf857x", .name = "pcf857x",
.of_match_table = of_match_ptr(pcf857x_of_table), .of_match_table = pcf857x_of_table,
}, },
.probe_new = pcf857x_probe, .probe_new = pcf857x_probe,
.remove = pcf857x_remove,
.shutdown = pcf857x_shutdown, .shutdown = pcf857x_shutdown,
.id_table = pcf857x_id, .id_table = pcf857x_id,
}; };
......
...@@ -111,6 +111,11 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, ...@@ -111,6 +111,11 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip,
unsigned int base, val, reg, mask; unsigned int base, val, reg, mask;
int invert, ret; int invert, ret;
if (gpio->reg_dat_base && !gpio->reg_set_base)
return GPIO_LINE_DIRECTION_IN;
if (gpio->reg_set_base && !gpio->reg_dat_base)
return GPIO_LINE_DIRECTION_OUT;
if (gpio->reg_dir_out_base) { if (gpio->reg_dir_out_base) {
base = gpio_regmap_addr(gpio->reg_dir_out_base); base = gpio_regmap_addr(gpio->reg_dir_out_base);
invert = 0; invert = 0;
...@@ -249,15 +254,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config ...@@ -249,15 +254,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
chip->ngpio = config->ngpio; chip->ngpio = config->ngpio;
chip->names = config->names; chip->names = config->names;
chip->label = config->label ?: dev_name(config->parent); chip->label = config->label ?: dev_name(config->parent);
chip->can_sleep = regmap_might_sleep(config->regmap);
/*
* If our regmap is fast_io we should probably set can_sleep to false.
* Right now, the regmap doesn't save this property, nor is there any
* access function for it.
* The only regmap type which uses fast_io is regmap-mmio. For now,
* assume a safe default of true here.
*/
chip->can_sleep = true;
chip->get = gpio_regmap_get; chip->get = gpio_regmap_get;
if (gpio->reg_set_base && gpio->reg_clr_base) if (gpio->reg_set_base && gpio->reg_clr_base)
...@@ -265,8 +262,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config ...@@ -265,8 +262,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
else if (gpio->reg_set_base) else if (gpio->reg_set_base)
chip->set = gpio_regmap_set; chip->set = gpio_regmap_set;
if (gpio->reg_dir_in_base || gpio->reg_dir_out_base) {
chip->get_direction = gpio_regmap_get_direction; chip->get_direction = gpio_regmap_get_direction;
if (gpio->reg_dir_in_base || gpio->reg_dir_out_base) {
chip->direction_input = gpio_regmap_direction_input; chip->direction_input = gpio_regmap_direction_input;
chip->direction_output = gpio_regmap_direction_output; chip->direction_output = gpio_regmap_direction_output;
} }
......
...@@ -299,7 +299,7 @@ static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset, ...@@ -299,7 +299,7 @@ static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
} }
/* /*
* gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin
* and a virtual IRQ, if not already present. * and a virtual IRQ, if not already present.
*/ */
static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
......
...@@ -377,8 +377,8 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) ...@@ -377,8 +377,8 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev)
ret = fwnode_property_read_string(swnode, "gpio-sim,label", &label); ret = fwnode_property_read_string(swnode, "gpio-sim,label", &label);
if (ret) { if (ret) {
label = devm_kasprintf(dev, GFP_KERNEL, "%s-%s", label = devm_kasprintf(dev, GFP_KERNEL, "%s-%pfwP",
dev_name(dev), fwnode_get_name(swnode)); dev_name(dev), swnode);
if (!label) if (!label)
return -ENOMEM; return -ENOMEM;
} }
...@@ -784,10 +784,9 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev) ...@@ -784,10 +784,9 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev)
GFP_KERNEL); GFP_KERNEL);
else else
hog->chip_label = kasprintf(GFP_KERNEL, hog->chip_label = kasprintf(GFP_KERNEL,
"gpio-sim.%u-%s", "gpio-sim.%u-%pfwP",
dev->id, dev->id,
fwnode_get_name( bank->swnode);
bank->swnode));
if (!hog->chip_label) { if (!hog->chip_label) {
gpio_sim_remove_hogs(dev); gpio_sim_remove_hogs(dev);
return -ENOMEM; return -ENOMEM;
......
...@@ -670,13 +670,14 @@ static unsigned int tegra186_gpio_child_offset_to_irq(struct gpio_chip *chip, ...@@ -670,13 +670,14 @@ static unsigned int tegra186_gpio_child_offset_to_irq(struct gpio_chip *chip,
static const struct of_device_id tegra186_pmc_of_match[] = { static const struct of_device_id tegra186_pmc_of_match[] = {
{ .compatible = "nvidia,tegra186-pmc" }, { .compatible = "nvidia,tegra186-pmc" },
{ .compatible = "nvidia,tegra194-pmc" }, { .compatible = "nvidia,tegra194-pmc" },
{ .compatible = "nvidia,tegra234-pmc" },
{ /* sentinel */ } { /* sentinel */ }
}; };
static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio)
{ {
struct device *dev = gpio->gpio.parent; struct device *dev = gpio->gpio.parent;
unsigned int i, j; unsigned int i;
u32 value; u32 value;
for (i = 0; i < gpio->soc->num_ports; i++) { for (i = 0; i < gpio->soc->num_ports; i++) {
...@@ -698,11 +699,10 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) ...@@ -698,11 +699,10 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio)
* On Tegra194 and later, each pin can be routed to one or more * On Tegra194 and later, each pin can be routed to one or more
* interrupts. * interrupts.
*/ */
for (j = 0; j < gpio->num_irqs_per_bank; j++) {
dev_dbg(dev, "programming default interrupt routing for port %s\n", dev_dbg(dev, "programming default interrupt routing for port %s\n",
port->name); port->name);
offset = TEGRA186_GPIO_INT_ROUTE_MAPPING(p, j); offset = TEGRA186_GPIO_INT_ROUTE_MAPPING(p, 0);
/* /*
* By default we only want to route GPIO pins to IRQ 0. This works * By default we only want to route GPIO pins to IRQ 0. This works
...@@ -713,14 +713,11 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) ...@@ -713,14 +713,11 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio)
* to configure the interrupt routing and pass only the valid * to configure the interrupt routing and pass only the valid
* interrupts via device tree. * interrupts via device tree.
*/ */
if (j == 0) {
value = readl(base + offset); value = readl(base + offset);
value = BIT(port->pins) - 1; value = BIT(port->pins) - 1;
writel(value, base + offset); writel(value, base + offset);
} }
} }
}
}
} }
static unsigned int tegra186_gpio_irqs_per_bank(struct tegra_gpio *gpio) static unsigned int tegra186_gpio_irqs_per_bank(struct tegra_gpio *gpio)
......
...@@ -317,7 +317,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) ...@@ -317,7 +317,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
gc = &port->gc; gc = &port->gc;
gc->parent = dev; gc->parent = dev;
gc->label = "vf610-gpio"; gc->label = dev_name(dev);
gc->ngpio = VF610_GPIO_PER_PORT; gc->ngpio = VF610_GPIO_PER_PORT;
gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT;
......
...@@ -98,7 +98,6 @@ static int wcd_gpio_probe(struct platform_device *pdev) ...@@ -98,7 +98,6 @@ static int wcd_gpio_probe(struct platform_device *pdev)
chip->base = -1; chip->base = -1;
chip->ngpio = WCD934X_NPINS; chip->ngpio = WCD934X_NPINS;
chip->label = dev_name(dev); chip->label = dev_name(dev);
chip->of_gpio_n_cells = 2;
chip->can_sleep = false; chip->can_sleep = false;
return devm_gpiochip_add_data(dev, chip, data); return devm_gpiochip_add_data(dev, chip, data);
......
...@@ -558,7 +558,6 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -558,7 +558,6 @@ static int xgpio_probe(struct platform_device *pdev)
int status = 0; int status = 0;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 is_dual = 0; u32 is_dual = 0;
u32 cells = 2;
u32 width[2]; u32 width[2];
u32 state[2]; u32 state[2];
u32 dir[2]; u32 dir[2];
...@@ -591,15 +590,6 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -591,15 +590,6 @@ static int xgpio_probe(struct platform_device *pdev)
bitmap_from_arr32(chip->dir, dir, 64); bitmap_from_arr32(chip->dir, dir, 64);
/* Update cells with gpio-cells value */
if (of_property_read_u32(np, "#gpio-cells", &cells))
dev_dbg(&pdev->dev, "Missing gpio-cells property\n");
if (cells != 2) {
dev_err(&pdev->dev, "#gpio-cells mismatch\n");
return -EINVAL;
}
/* /*
* Check device node and parent device node for device width * Check device node and parent device node for device width
* and assume default width of 32 * and assume default width of 32
...@@ -630,7 +620,6 @@ static int xgpio_probe(struct platform_device *pdev) ...@@ -630,7 +620,6 @@ static int xgpio_probe(struct platform_device *pdev)
chip->gc.parent = &pdev->dev; chip->gc.parent = &pdev->dev;
chip->gc.direction_input = xgpio_dir_in; chip->gc.direction_input = xgpio_dir_in;
chip->gc.direction_output = xgpio_dir_out; chip->gc.direction_output = xgpio_dir_out;
chip->gc.of_gpio_n_cells = cells;
chip->gc.get = xgpio_get; chip->gc.get = xgpio_get;
chip->gc.set = xgpio_set; chip->gc.set = xgpio_set;
chip->gc.request = xgpio_request; chip->gc.request = xgpio_request;
......
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
* Author: Fabian Vogt <fabian@ritter-vogt.de> * Author: Fabian Vogt <fabian@ritter-vogt.de>
*/ */
#include <linux/spinlock.h> #include <linux/bitops.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitops.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_device.h> #include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
/* /*
...@@ -162,7 +164,6 @@ static const struct gpio_chip zevio_gpio_chip = { ...@@ -162,7 +164,6 @@ static const struct gpio_chip zevio_gpio_chip = {
.base = 0, .base = 0,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.ngpio = 32, .ngpio = 32,
.of_gpio_n_cells = 2,
}; };
/* Initialization */ /* Initialization */
......
...@@ -1388,16 +1388,6 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) ...@@ -1388,16 +1388,6 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
kfree(acpi_gpio); kfree(acpi_gpio);
} }
void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev)
{
/* Set default fwnode to parent's one if present */
if (gc->parent)
ACPI_COMPANION_SET(&gdev->dev, ACPI_COMPANION(gc->parent));
if (gc->fwnode)
device_set_node(&gdev->dev, gc->fwnode);
}
static int acpi_gpio_package_count(const union acpi_object *obj) static int acpi_gpio_package_count(const union acpi_object *obj)
{ {
const union acpi_object *element = obj->package.elements; const union acpi_object *element = obj->package.elements;
......
...@@ -25,8 +25,6 @@ struct gpio_device; ...@@ -25,8 +25,6 @@ struct gpio_device;
void acpi_gpiochip_add(struct gpio_chip *chip); void acpi_gpiochip_add(struct gpio_chip *chip);
void acpi_gpiochip_remove(struct gpio_chip *chip); void acpi_gpiochip_remove(struct gpio_chip *chip);
void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev);
void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
...@@ -41,8 +39,6 @@ int acpi_gpio_count(struct device *dev, const char *con_id); ...@@ -41,8 +39,6 @@ int acpi_gpio_count(struct device *dev, const char *con_id);
static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
static inline void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) { }
static inline void static inline void
acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
......
...@@ -321,7 +321,7 @@ static void linehandle_free(struct linehandle_state *lh) ...@@ -321,7 +321,7 @@ static void linehandle_free(struct linehandle_state *lh)
if (lh->descs[i]) if (lh->descs[i])
gpiod_free(lh->descs[i]); gpiod_free(lh->descs[i]);
kfree(lh->label); kfree(lh->label);
put_device(&lh->gdev->dev); gpio_device_put(lh->gdev);
kfree(lh); kfree(lh);
} }
...@@ -363,8 +363,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -363,8 +363,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
lh = kzalloc(sizeof(*lh), GFP_KERNEL); lh = kzalloc(sizeof(*lh), GFP_KERNEL);
if (!lh) if (!lh)
return -ENOMEM; return -ENOMEM;
lh->gdev = gdev; lh->gdev = gpio_device_get(gdev);
get_device(&gdev->dev);
if (handlereq.consumer_label[0] != '\0') { if (handlereq.consumer_label[0] != '\0') {
/* label is only initialized if consumer_label is set */ /* label is only initialized if consumer_label is set */
...@@ -1576,7 +1575,7 @@ static void linereq_free(struct linereq *lr) ...@@ -1576,7 +1575,7 @@ static void linereq_free(struct linereq *lr)
} }
kfifo_free(&lr->events); kfifo_free(&lr->events);
kfree(lr->label); kfree(lr->label);
put_device(&lr->gdev->dev); gpio_device_put(lr->gdev);
kfree(lr); kfree(lr);
} }
...@@ -1646,8 +1645,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip) ...@@ -1646,8 +1645,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
if (!lr) if (!lr)
return -ENOMEM; return -ENOMEM;
lr->gdev = gdev; lr->gdev = gpio_device_get(gdev);
get_device(&gdev->dev);
for (i = 0; i < ulr.num_lines; i++) { for (i = 0; i < ulr.num_lines; i++) {
lr->lines[i].req = lr; lr->lines[i].req = lr;
...@@ -1916,7 +1914,7 @@ static void lineevent_free(struct lineevent_state *le) ...@@ -1916,7 +1914,7 @@ static void lineevent_free(struct lineevent_state *le)
if (le->desc) if (le->desc)
gpiod_free(le->desc); gpiod_free(le->desc);
kfree(le->label); kfree(le->label);
put_device(&le->gdev->dev); gpio_device_put(le->gdev);
kfree(le); kfree(le);
} }
...@@ -2094,8 +2092,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) ...@@ -2094,8 +2092,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
le = kzalloc(sizeof(*le), GFP_KERNEL); le = kzalloc(sizeof(*le), GFP_KERNEL);
if (!le) if (!le)
return -ENOMEM; return -ENOMEM;
le->gdev = gdev; le->gdev = gpio_device_get(gdev);
get_device(&gdev->dev);
if (eventreq.consumer_label[0] != '\0') { if (eventreq.consumer_label[0] != '\0') {
/* label is only initialized if consumer_label is set */ /* label is only initialized if consumer_label is set */
...@@ -2671,7 +2668,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) ...@@ -2671,7 +2668,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
init_waitqueue_head(&cdev->wait); init_waitqueue_head(&cdev->wait);
INIT_KFIFO(cdev->events); INIT_KFIFO(cdev->events);
cdev->gdev = gdev; cdev->gdev = gpio_device_get(gdev);
cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify;
ret = blocking_notifier_chain_register(&gdev->notifier, ret = blocking_notifier_chain_register(&gdev->notifier,
...@@ -2679,7 +2676,6 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) ...@@ -2679,7 +2676,6 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
if (ret) if (ret)
goto out_free_bitmap; goto out_free_bitmap;
get_device(&gdev->dev);
file->private_data = cdev; file->private_data = cdev;
ret = nonseekable_open(inode, file); ret = nonseekable_open(inode, file);
...@@ -2694,6 +2690,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file) ...@@ -2694,6 +2690,7 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
blocking_notifier_chain_unregister(&gdev->notifier, blocking_notifier_chain_unregister(&gdev->notifier,
&cdev->lineinfo_changed_nb); &cdev->lineinfo_changed_nb);
out_free_bitmap: out_free_bitmap:
gpio_device_put(gdev);
bitmap_free(cdev->watched_lines); bitmap_free(cdev->watched_lines);
out_free_cdev: out_free_cdev:
kfree(cdev); kfree(cdev);
...@@ -2716,7 +2713,7 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file) ...@@ -2716,7 +2713,7 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file)
bitmap_free(cdev->watched_lines); bitmap_free(cdev->watched_lines);
blocking_notifier_chain_unregister(&gdev->notifier, blocking_notifier_chain_unregister(&gdev->notifier,
&cdev->lineinfo_changed_nb); &cdev->lineinfo_changed_nb);
put_device(&gdev->dev); gpio_device_put(gdev);
kfree(cdev); kfree(cdev);
return 0; return 0;
......
...@@ -129,61 +129,6 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, ...@@ -129,61 +129,6 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
} }
EXPORT_SYMBOL_GPL(devm_gpiod_get_index); EXPORT_SYMBOL_GPL(devm_gpiod_get_index);
/**
* devm_gpiod_get_from_of_node() - obtain a GPIO from an OF node
* @dev: device for lifecycle management
* @node: handle of the OF node
* @propname: name of the DT property representing the GPIO
* @index: index of the GPIO to obtain for the consumer
* @dflags: GPIO initialization flags
* @label: label to attach to the requested GPIO
*
* Returns:
* On successful request the GPIO pin is configured in accordance with
* provided @dflags.
*
* In case of error an ERR_PTR() is returned.
*/
struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label)
{
struct gpio_desc **dr;
struct gpio_desc *desc;
desc = gpiod_get_from_of_node(node, propname, index, dflags, label);
if (IS_ERR(desc))
return desc;
/*
* For non-exclusive GPIO descriptors, check if this descriptor is
* already under resource management by this device.
*/
if (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
struct devres *dres;
dres = devres_find(dev, devm_gpiod_release,
devm_gpiod_match, &desc);
if (dres)
return desc;
}
dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
GFP_KERNEL);
if (!dr) {
gpiod_put(desc);
return ERR_PTR(-ENOMEM);
}
*dr = desc;
devres_add(dev, dr);
return desc;
}
EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node);
/** /**
* devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node * devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node
* @dev: GPIO consumer * @dev: GPIO consumer
......
...@@ -23,6 +23,47 @@ ...@@ -23,6 +23,47 @@
#include "gpiolib.h" #include "gpiolib.h"
#include "gpiolib-of.h" #include "gpiolib-of.h"
/*
* This is Linux-specific flags. By default controllers' and Linux' mapping
* match, but GPIO controllers are free to translate their own flags to
* Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended.
*/
enum of_gpio_flags {
OF_GPIO_ACTIVE_LOW = 0x1,
OF_GPIO_SINGLE_ENDED = 0x2,
OF_GPIO_OPEN_DRAIN = 0x4,
OF_GPIO_TRANSITORY = 0x8,
OF_GPIO_PULL_UP = 0x10,
OF_GPIO_PULL_DOWN = 0x20,
OF_GPIO_PULL_DISABLE = 0x40,
};
/**
* of_gpio_named_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
* @propname: property name containing gpio specifier(s)
*
* The function returns the count of GPIOs specified for a node.
* Note that the empty GPIO specifiers count too. Returns either
* Number of gpios defined in property,
* -EINVAL for an incorrectly formed gpios property, or
* -ENOENT for a missing gpios property
*
* Example:
* gpios = <0
* &gpio1 1 2
* 0
* &gpio2 3 4>;
*
* The above example defines four GPIOs, two of which are not specified.
* This function will return '4'
*/
static int of_gpio_named_count(const struct device_node *np,
const char *propname)
{
return of_count_phandle_with_args(np, propname, "#gpio-cells");
}
/** /**
* of_gpio_spi_cs_get_count() - special GPIO counting for SPI * of_gpio_spi_cs_get_count() - special GPIO counting for SPI
* @dev: Consuming device * @dev: Consuming device
...@@ -50,12 +91,6 @@ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) ...@@ -50,12 +91,6 @@ static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id)
return of_gpio_named_count(np, "gpios"); return of_gpio_named_count(np, "gpios");
} }
/*
* This is used by external users of of_gpio_count() from <linux/of_gpio.h>
*
* FIXME: get rid of those external users by converting them to GPIO
* descriptors and let them all use gpiod_count()
*/
int of_gpio_get_count(struct device *dev, const char *con_id) int of_gpio_get_count(struct device *dev, const char *con_id)
{ {
int ret; int ret;
...@@ -345,19 +380,28 @@ static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np, ...@@ -345,19 +380,28 @@ static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np,
return desc; return desc;
} }
int of_get_named_gpio_flags(const struct device_node *np, const char *list_name, /**
int index, enum of_gpio_flags *flags) * of_get_named_gpio() - Get a GPIO number to use with GPIO API
* @np: device node to get GPIO from
* @propname: Name of property containing gpio specifier(s)
* @index: index of the GPIO
*
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
* value on the error condition.
*/
int of_get_named_gpio(const struct device_node *np, const char *propname,
int index)
{ {
struct gpio_desc *desc; struct gpio_desc *desc;
desc = of_get_named_gpiod_flags(np, list_name, index, flags); desc = of_get_named_gpiod_flags(np, propname, index, NULL);
if (IS_ERR(desc)) if (IS_ERR(desc))
return PTR_ERR(desc); return PTR_ERR(desc);
else else
return desc_to_gpio(desc); return desc_to_gpio(desc);
} }
EXPORT_SYMBOL_GPL(of_get_named_gpio_flags); EXPORT_SYMBOL_GPL(of_get_named_gpio);
/* Converts gpio_lookup_flags into bitmask of GPIO_* values */ /* Converts gpio_lookup_flags into bitmask of GPIO_* values */
static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags) static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags)
...@@ -389,52 +433,6 @@ static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags) ...@@ -389,52 +433,6 @@ static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags)
return lflags; return lflags;
} }
/**
* gpiod_get_from_of_node() - obtain a GPIO from an OF node
* @node: handle of the OF node
* @propname: name of the DT property representing the GPIO
* @index: index of the GPIO to obtain for the consumer
* @dflags: GPIO initialization flags
* @label: label to attach to the requested GPIO
*
* Returns:
* On successful request the GPIO pin is configured in accordance with
* provided @dflags.
*
* In case of error an ERR_PTR() is returned.
*/
struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label)
{
unsigned long lflags;
struct gpio_desc *desc;
enum of_gpio_flags of_flags;
int ret;
desc = of_get_named_gpiod_flags(node, propname, index, &of_flags);
if (!desc || IS_ERR(desc))
return desc;
ret = gpiod_request(desc, label);
if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
return desc;
if (ret)
return ERR_PTR(ret);
lflags = of_convert_gpio_flags(of_flags);
ret = gpiod_configure_flags(desc, propname, lflags, dflags);
if (ret < 0) {
gpiod_put(desc);
return ERR_PTR(ret);
}
return desc;
}
EXPORT_SYMBOL_GPL(gpiod_get_from_of_node);
static struct gpio_desc *of_find_gpio_rename(struct device_node *np, static struct gpio_desc *of_find_gpio_rename(struct device_node *np,
const char *con_id, const char *con_id,
unsigned int idx, unsigned int idx,
...@@ -668,7 +666,7 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, ...@@ -668,7 +666,7 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
u32 tmp; u32 tmp;
int ret; int ret;
chip_np = chip->of_node; chip_np = dev_of_node(&chip->gpiodev->dev);
if (!chip_np) if (!chip_np)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -760,7 +758,7 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip) ...@@ -760,7 +758,7 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
struct device_node *np; struct device_node *np;
int ret; int ret;
for_each_available_child_of_node(chip->of_node, np) { for_each_available_child_of_node(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;
...@@ -970,14 +968,15 @@ EXPORT_SYMBOL_GPL(of_mm_gpiochip_remove); ...@@ -970,14 +968,15 @@ EXPORT_SYMBOL_GPL(of_mm_gpiochip_remove);
#ifdef CONFIG_PINCTRL #ifdef CONFIG_PINCTRL
static int of_gpiochip_add_pin_range(struct gpio_chip *chip) static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
{ {
struct device_node *np = chip->of_node;
struct of_phandle_args pinspec; struct of_phandle_args pinspec;
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
struct device_node *np;
int index = 0, ret; int index = 0, ret;
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; struct property *group_names;
np = dev_of_node(&chip->gpiodev->dev);
if (!np) if (!np)
return 0; return 0;
...@@ -1063,7 +1062,7 @@ int of_gpiochip_add(struct gpio_chip *chip) ...@@ -1063,7 +1062,7 @@ int of_gpiochip_add(struct gpio_chip *chip)
struct device_node *np; struct device_node *np;
int ret; int ret;
np = to_of_node(dev_fwnode(&chip->gpiodev->dev)); np = dev_of_node(&chip->gpiodev->dev);
if (!np) if (!np)
return 0; return 0;
...@@ -1092,19 +1091,3 @@ void of_gpiochip_remove(struct gpio_chip *chip) ...@@ -1092,19 +1091,3 @@ void of_gpiochip_remove(struct gpio_chip *chip)
{ {
fwnode_handle_put(chip->fwnode); fwnode_handle_put(chip->fwnode);
} }
void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev)
{
/* Set default OF node to parent's one if present */
if (gc->parent)
gdev->dev.of_node = gc->parent->of_node;
if (gc->fwnode)
gc->of_node = to_of_node(gc->fwnode);
/* If the gpiochip has an assigned OF node this takes precedence */
if (gc->of_node)
gdev->dev.of_node = gc->of_node;
else
gc->of_node = gdev->dev.of_node;
}
...@@ -23,7 +23,6 @@ struct gpio_desc *of_find_gpio(struct device_node *np, ...@@ -23,7 +23,6 @@ struct gpio_desc *of_find_gpio(struct device_node *np,
int of_gpiochip_add(struct gpio_chip *gc); int of_gpiochip_add(struct gpio_chip *gc);
void of_gpiochip_remove(struct gpio_chip *gc); void of_gpiochip_remove(struct gpio_chip *gc);
int of_gpio_get_count(struct device *dev, const char *con_id); int of_gpio_get_count(struct device *dev, const char *con_id);
void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev);
#else #else
static inline struct gpio_desc *of_find_gpio(struct device_node *np, static inline struct gpio_desc *of_find_gpio(struct device_node *np,
const char *con_id, const char *con_id,
...@@ -38,10 +37,6 @@ static inline int of_gpio_get_count(struct device *dev, const char *con_id) ...@@ -38,10 +37,6 @@ static inline int of_gpio_get_count(struct device *dev, const char *con_id)
{ {
return 0; return 0;
} }
static inline void of_gpio_dev_init(struct gpio_chip *gc,
struct gpio_device *gdev)
{
}
#endif /* CONFIG_OF_GPIO */ #endif /* CONFIG_OF_GPIO */
extern struct notifier_block gpio_of_notifier; extern struct notifier_block gpio_of_notifier;
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/acpi.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <linux/kernel.h> #include <linux/compat.h>
#include <linux/module.h> #include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/debugfs.h> #include <linux/file.h>
#include <linux/seq_file.h> #include <linux/fs.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/fs.h> #include <linux/seq_file.h>
#include <linux/compat.h> #include <linux/slab.h>
#include <linux/file.h> #include <linux/spinlock.h>
#include <uapi/linux/gpio.h> #include <uapi/linux/gpio.h>
#include "gpiolib.h"
#include "gpiolib-of.h"
#include "gpiolib-acpi.h" #include "gpiolib-acpi.h"
#include "gpiolib-swnode.h"
#include "gpiolib-cdev.h" #include "gpiolib-cdev.h"
#include "gpiolib-of.h"
#include "gpiolib-swnode.h"
#include "gpiolib-sysfs.h" #include "gpiolib-sysfs.h"
#include "gpiolib.h"
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/gpio.h> #include <trace/events/gpio.h>
...@@ -659,10 +660,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -659,10 +660,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
int base = 0; int base = 0;
int ret = 0; int ret = 0;
/* If the calling driver did not initialize firmware node, do it here */
if (gc->fwnode) if (gc->fwnode)
fwnode = gc->fwnode; fwnode = gc->fwnode;
else if (gc->parent) else if (gc->parent)
fwnode = dev_fwnode(gc->parent); fwnode = dev_fwnode(gc->parent);
gc->fwnode = fwnode;
/* /*
* First: allocate and populate the internal stat container, and * First: allocate and populate the internal stat container, and
...@@ -676,14 +679,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -676,14 +679,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gdev->chip = gc; gdev->chip = gc;
gc->gpiodev = gdev; gc->gpiodev = gdev;
of_gpio_dev_init(gc, gdev); device_set_node(&gdev->dev, gc->fwnode);
acpi_gpio_dev_init(gc, gdev);
/*
* Assign fwnode depending on the result of the previous calls,
* if none of them succeed, assign it to the parent's one.
*/
gc->fwnode = gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode;
gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL); gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
if (gdev->id < 0) { if (gdev->id < 0) {
...@@ -882,7 +878,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, ...@@ -882,7 +878,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gpiochip_free_valid_mask(gc); gpiochip_free_valid_mask(gc);
if (gdev->dev.release) { if (gdev->dev.release) {
/* release() has been registered by gpiochip_setup_dev() */ /* release() has been registered by gpiochip_setup_dev() */
put_device(&gdev->dev); gpio_device_put(gdev);
goto err_print_message; goto err_print_message;
} }
err_remove_from_list: err_remove_from_list:
...@@ -972,7 +968,7 @@ void gpiochip_remove(struct gpio_chip *gc) ...@@ -972,7 +968,7 @@ void gpiochip_remove(struct gpio_chip *gc)
*/ */
gcdev_unregister(gdev); gcdev_unregister(gdev);
up_write(&gdev->sem); up_write(&gdev->sem);
put_device(&gdev->dev); gpio_device_put(gdev);
} }
EXPORT_SYMBOL_GPL(gpiochip_remove); EXPORT_SYMBOL_GPL(gpiochip_remove);
...@@ -1126,14 +1122,8 @@ static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc, ...@@ -1126,14 +1122,8 @@ static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc,
/* Just pick something */ /* Just pick something */
fwspec.param[1] = IRQ_TYPE_EDGE_RISING; fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
fwspec.param_count = 2; fwspec.param_count = 2;
ret = __irq_domain_alloc_irqs(gc->irq.domain, ret = irq_domain_alloc_irqs(gc->irq.domain, 1,
/* just pick something */ NUMA_NO_NODE, &fwspec);
-1,
1,
NUMA_NO_NODE,
&fwspec,
false,
NULL);
if (ret < 0) { if (ret < 0) {
chip_err(gc, chip_err(gc,
"can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n", "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
...@@ -2063,17 +2053,15 @@ static int validate_desc(const struct gpio_desc *desc, const char *func) ...@@ -2063,17 +2053,15 @@ static int validate_desc(const struct gpio_desc *desc, const char *func)
int gpiod_request(struct gpio_desc *desc, const char *label) int gpiod_request(struct gpio_desc *desc, const char *label)
{ {
int ret = -EPROBE_DEFER; int ret = -EPROBE_DEFER;
struct gpio_device *gdev;
VALIDATE_DESC(desc); VALIDATE_DESC(desc);
gdev = desc->gdev;
if (try_module_get(gdev->owner)) { if (try_module_get(desc->gdev->owner)) {
ret = gpiod_request_commit(desc, label); ret = gpiod_request_commit(desc, label);
if (ret) if (ret)
module_put(gdev->owner); module_put(desc->gdev->owner);
else else
get_device(&gdev->dev); gpio_device_get(desc->gdev);
} }
if (ret) if (ret)
...@@ -2134,7 +2122,7 @@ void gpiod_free(struct gpio_desc *desc) ...@@ -2134,7 +2122,7 @@ void gpiod_free(struct gpio_desc *desc)
{ {
if (desc && desc->gdev && gpiod_free_commit(desc)) { if (desc && desc->gdev && gpiod_free_commit(desc)) {
module_put(desc->gdev->owner); module_put(desc->gdev->owner);
put_device(&desc->gdev->dev); gpio_device_put(desc->gdev);
} else { } else {
WARN_ON(extra_checks); WARN_ON(extra_checks);
} }
......
...@@ -82,6 +82,16 @@ static inline struct gpio_device *to_gpio_device(struct device *dev) ...@@ -82,6 +82,16 @@ 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);
} }
static inline struct gpio_device *gpio_device_get(struct gpio_device *gdev)
{
return to_gpio_device(get_device(&gdev->dev));
}
static inline void gpio_device_put(struct gpio_device *gdev)
{
put_device(&gdev->dev);
}
/* gpio suffixes used for ACPI and device tree lookup */ /* gpio suffixes used for ACPI and device tree lookup */
static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" };
......
...@@ -325,7 +325,12 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio) ...@@ -325,7 +325,12 @@ static bool pinctrl_ready_for_gpio_range(unsigned gpio)
{ {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range = NULL; struct pinctrl_gpio_range *range = NULL;
struct gpio_chip *chip = gpio_to_chip(gpio); /*
* FIXME: "gpio" here is a number in the global GPIO numberspace.
* get rid of this from the ranges eventually and get the GPIO
* descriptor from the gpio_chip.
*/
struct gpio_chip *chip = gpiod_to_chip(gpio_to_desc(gpio));
if (WARN(!chip, "no gpio_chip for gpio%i?", gpio)) if (WARN(!chip, "no gpio_chip for gpio%i?", gpio))
return false; return false;
...@@ -1657,7 +1662,12 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) ...@@ -1657,7 +1662,12 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
} }
} }
if (gpio_num >= 0) if (gpio_num >= 0)
chip = gpio_to_chip(gpio_num); /*
* FIXME: gpio_num comes from the global GPIO numberspace.
* we need to get rid of the range->base eventually and
* get the descriptor directly from the gpio_chip.
*/
chip = gpiod_to_chip(gpio_to_desc(gpio_num));
else else
chip = NULL; chip = NULL;
if (chip) if (chip)
......
...@@ -31,12 +31,6 @@ struct module; ...@@ -31,12 +31,6 @@ struct module;
struct device_node; struct device_node;
struct gpio_desc; struct gpio_desc;
/* caller holds gpio_lock *OR* gpio is marked as requested */
static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
{
return gpiod_to_chip(gpio_to_desc(gpio));
}
/* Always use the library code for GPIO management calls, /* Always use the library code for GPIO management calls,
* or when sleeping may be involved. * or when sleeping may be involved.
*/ */
...@@ -103,12 +97,6 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change) ...@@ -103,12 +97,6 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
return gpiod_export(gpio_to_desc(gpio), direction_may_change); return gpiod_export(gpio_to_desc(gpio), direction_may_change);
} }
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
return gpiod_export_link(dev, name, gpio_to_desc(gpio));
}
static inline void gpio_unexport(unsigned gpio) static inline void gpio_unexport(unsigned gpio)
{ {
gpiod_unexport(gpio_to_desc(gpio)); gpiod_unexport(gpio_to_desc(gpio));
......
...@@ -81,11 +81,6 @@ static inline int gpio_to_irq(unsigned int gpio) ...@@ -81,11 +81,6 @@ static inline int gpio_to_irq(unsigned int gpio)
return __gpio_to_irq(gpio); return __gpio_to_irq(gpio);
} }
static inline int irq_to_gpio(unsigned int irq)
{
return -EINVAL;
}
#endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */ #endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */
/* CONFIG_GPIOLIB: bindings for managed devices that want to request gpios */ /* CONFIG_GPIOLIB: bindings for managed devices that want to request gpios */
...@@ -197,14 +192,6 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change) ...@@ -197,14 +192,6 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
return -EINVAL; return -EINVAL;
} }
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
/* GPIO can never have been exported */
WARN_ON(1);
return -EINVAL;
}
static inline void gpio_unexport(unsigned gpio) static inline void gpio_unexport(unsigned gpio)
{ {
/* GPIO can never have been exported */ /* GPIO can never have been exported */
...@@ -218,13 +205,6 @@ static inline int gpio_to_irq(unsigned gpio) ...@@ -218,13 +205,6 @@ static inline int gpio_to_irq(unsigned gpio)
return -EINVAL; return -EINVAL;
} }
static inline int irq_to_gpio(unsigned irq)
{
/* irq can never have been returned from gpio_to_irq() */
WARN_ON(1);
return -EINVAL;
}
static inline int devm_gpio_request(struct device *dev, unsigned gpio, static inline int devm_gpio_request(struct device *dev, unsigned gpio,
const char *label) const char *label)
{ {
......
...@@ -581,54 +581,6 @@ struct gpio_desc *devm_fwnode_gpiod_get(struct device *dev, ...@@ -581,54 +581,6 @@ struct gpio_desc *devm_fwnode_gpiod_get(struct device *dev,
flags, label); flags, label);
} }
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_OF_GPIO)
struct device_node;
struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label);
#else /* CONFIG_GPIOLIB && CONFIG_OF_GPIO */
struct device_node;
static inline
struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label)
{
return ERR_PTR(-ENOSYS);
}
#endif /* CONFIG_GPIOLIB && CONFIG_OF_GPIO */
#ifdef CONFIG_GPIOLIB
struct device_node;
struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label);
#else /* CONFIG_GPIOLIB */
struct device_node;
static inline
struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
const struct device_node *node,
const char *propname, int index,
enum gpiod_flags dflags,
const char *label)
{
return ERR_PTR(-ENOSYS);
}
#endif /* CONFIG_GPIOLIB */
struct acpi_gpio_params { struct acpi_gpio_params {
unsigned int crs_entry_index; unsigned int crs_entry_index;
unsigned int line_index; unsigned int line_index;
......
...@@ -336,7 +336,7 @@ struct gpio_irq_chip { ...@@ -336,7 +336,7 @@ struct gpio_irq_chip {
* @set_multiple: assigns output values for multiple signals defined by "mask" * @set_multiple: assigns output values for multiple signals defined by "mask"
* @set_config: optional hook for all kinds of settings. Uses the same * @set_config: optional hook for all kinds of settings. Uses the same
* packed config format as generic pinconf. * packed config format as generic pinconf.
* @to_irq: optional hook supporting non-static gpio_to_irq() mappings; * @to_irq: optional hook supporting non-static gpiod_to_irq() mappings;
* implementation may not sleep * implementation may not sleep
* @dbg_show: optional routine to show contents in debugfs; default code * @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra * will be used when this is omitted, but custom code can show extra
...@@ -503,13 +503,6 @@ struct gpio_chip { ...@@ -503,13 +503,6 @@ struct gpio_chip {
* the device tree automatically may have an OF translation * the device tree automatically may have an OF translation
*/ */
/**
* @of_node:
*
* Pointer to a device tree node representing this GPIO controller.
*/
struct device_node *of_node;
/** /**
* @of_gpio_n_cells: * @of_gpio_n_cells:
* *
......
...@@ -17,21 +17,6 @@ ...@@ -17,21 +17,6 @@
struct device_node; struct device_node;
/*
* This is Linux-specific flags. By default controllers' and Linux' mapping
* match, but GPIO controllers are free to translate their own flags to
* Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended.
*/
enum of_gpio_flags {
OF_GPIO_ACTIVE_LOW = 0x1,
OF_GPIO_SINGLE_ENDED = 0x2,
OF_GPIO_OPEN_DRAIN = 0x4,
OF_GPIO_TRANSITORY = 0x8,
OF_GPIO_PULL_UP = 0x10,
OF_GPIO_PULL_DOWN = 0x20,
OF_GPIO_PULL_DISABLE = 0x40,
};
#ifdef CONFIG_OF_GPIO #ifdef CONFIG_OF_GPIO
#include <linux/container_of.h> #include <linux/container_of.h>
...@@ -50,17 +35,12 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc) ...@@ -50,17 +35,12 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
return container_of(gc, struct of_mm_gpio_chip, gc); return container_of(gc, struct of_mm_gpio_chip, gc);
} }
extern int of_get_named_gpio_flags(const struct device_node *np, extern int of_get_named_gpio(const struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags); const char *list_name, int index);
extern int of_mm_gpiochip_add_data(struct device_node *np, extern int of_mm_gpiochip_add_data(struct device_node *np,
struct of_mm_gpio_chip *mm_gc, struct of_mm_gpio_chip *mm_gc,
void *data); void *data);
static inline int of_mm_gpiochip_add(struct device_node *np,
struct of_mm_gpio_chip *mm_gc)
{
return of_mm_gpiochip_add_data(np, mm_gc, NULL);
}
extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc); extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc);
#else /* CONFIG_OF_GPIO */ #else /* CONFIG_OF_GPIO */
...@@ -68,86 +48,12 @@ extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc); ...@@ -68,86 +48,12 @@ extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc);
#include <linux/errno.h> #include <linux/errno.h>
/* Drivers may not strictly depend on the GPIO support, so let them link. */ /* Drivers may not strictly depend on the GPIO support, so let them link. */
static inline int of_get_named_gpio_flags(const struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags)
{
if (flags)
*flags = 0;
return -ENOSYS;
}
#endif /* CONFIG_OF_GPIO */
/**
* of_gpio_named_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
* @propname: property name containing gpio specifier(s)
*
* The function returns the count of GPIOs specified for a node.
* Note that the empty GPIO specifiers count too. Returns either
* Number of gpios defined in property,
* -EINVAL for an incorrectly formed gpios property, or
* -ENOENT for a missing gpios property
*
* Example:
* gpios = <0
* &gpio1 1 2
* 0
* &gpio2 3 4>;
*
* The above example defines four GPIOs, two of which are not specified.
* This function will return '4'
*/
static inline int of_gpio_named_count(const struct device_node *np,
const char *propname)
{
return of_count_phandle_with_args(np, propname, "#gpio-cells");
}
/**
* of_gpio_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
*
* Same as of_gpio_named_count, but hard coded to use the 'gpios' property
*/
static inline int of_gpio_count(const struct device_node *np)
{
return of_gpio_named_count(np, "gpios");
}
static inline int of_get_gpio_flags(const struct device_node *np, int index,
enum of_gpio_flags *flags)
{
return of_get_named_gpio_flags(np, "gpios", index, flags);
}
/**
* of_get_named_gpio() - Get a GPIO number to use with GPIO API
* @np: device node to get GPIO from
* @propname: Name of property containing gpio specifier(s)
* @index: index of the GPIO
*
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
* value on the error condition.
*/
static inline int of_get_named_gpio(const struct device_node *np, static inline int of_get_named_gpio(const struct device_node *np,
const char *propname, int index) const char *propname, int index)
{ {
return of_get_named_gpio_flags(np, propname, index, NULL); return -ENOSYS;
} }
/** #endif /* CONFIG_OF_GPIO */
* of_get_gpio() - Get a GPIO number to use with GPIO API
* @np: device node to get GPIO from
* @index: index of the GPIO
*
* Returns GPIO number to use with Linux generic GPIO API, or one of the errno
* value on the error condition.
*/
static inline int of_get_gpio(const struct device_node *np, int index)
{
return of_get_gpio_flags(np, index, NULL);
}
#endif /* __LINUX_OF_GPIO_H */ #endif /* __LINUX_OF_GPIO_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_PCF857X_H
#define __LINUX_PCF857X_H
/**
* struct pcf857x_platform_data - data to set up pcf857x driver
* @gpio_base: number of the chip's first GPIO
* @n_latch: optional bit-inverse of initial register value; if
* you leave this initialized to zero the driver will act
* like the chip was just reset
* @setup: optional callback issued once the GPIOs are valid
* @teardown: optional callback issued before the GPIOs are invalidated
* @context: optional parameter passed to setup() and teardown()
*
* In addition to the I2C_BOARD_INFO() state appropriate to each chip,
* the i2c_board_info used with the pcf875x driver must provide its
* platform_data (pointer to one of these structures) with at least
* the gpio_base value initialized.
*
* The @setup callback may be used with the kind of board-specific glue
* which hands the (now-valid) GPIOs to other drivers, or which puts
* devices in their initial states using these GPIOs.
*
* These GPIO chips are only "quasi-bidirectional"; read the chip specs
* to understand the behavior. They don't have separate registers to
* record which pins are used for input or output, record which output
* values are driven, or provide access to input values. That must be
* inferred by reading the chip's value and knowing the last value written
* to it. If you leave n_latch initialized to zero, that last written
* value is presumed to be all ones (as if the chip were just reset).
*/
struct pcf857x_platform_data {
unsigned gpio_base;
unsigned n_latch;
int (*setup)(struct i2c_client *client,
int gpio, unsigned ngpio,
void *context);
void (*teardown)(struct i2c_client *client,
int gpio, unsigned ngpio,
void *context);
void *context;
};
#endif /* __LINUX_PCF857X_H */
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