mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
This is the bulk of GPIO changes for kernel v4.6:
Core changes: - The gpio_chip is now a *real device*. Until now the gpio chips were just piggybacking the parent device or (gasp) floating in space outside of the device model. We now finally make GPIO chips devices. The gpio_chip will create a gpio_device which contains a struct device, and this gpio_device struct is kept private. Anything that needs to be kept private from the rest of the kernel will gradually be moved over to the gpio_device. - As a result of making the gpio_device a real device, we have added resource management, so devm_gpiochip_add_data() will cut down on overhead and reduce code lines. A huge slew of patches convert almost all drivers in the subsystem to use this. - Building on making the GPIO a real device, we add the first step of a new userspace ABI: the GPIO character device. We take small steps here, so we first add a pure *information* ABI and the tool "lsgpio" that will list all GPIO devices on the system and all lines on these devices. We can now discover GPIOs properly from userspace. We still have not come up with a way to actually *use* GPIOs from userspace. - To encourage people to use the character device for the future, we have it always-enabled when using GPIO. The old sysfs ABI is still opt-in (and can be used in parallel), but is marked as deprecated. We will keep it around for the foreseeable future, but it will not be extended to cover ever more use cases. Cleanup: - Bjorn Helgaas removed a whole slew of per-architecture <asm/gpio.h> includes. This dates back to when GPIO was an opt-in feature and no shared library even existed: just a header file with proper prototypes was provided and all semantics were up to the arch to implement. These patches make the GPIO chip even more a proper device and cleans out leftovers of the old in-kernel API here and there. Still some cruft is left but it's very little now. - There is still some clamping of return values for .get() going on, but we now return sane values in the vast majority of drivers and the errorpath is sanitized. Some patches for powerpc, blackfin and unicore still drop in. - We continue to switch the ARM, MIPS, blackfin, m68k local GPIO implementations to use gpiochip_add_data() and cut down on code lines. - MPC8xxx is converted to use the generic GPIO helpers. - ATH79 is converted to use the generic GPIO helpers. New drivers: - WinSystems WS16C48 - Acces 104-DIO-48E - F81866 (a F7188x variant) - Qoric (a MPC8xxx variant) - TS-4800 - SPI serializers (pisosr): simple 74xx shift registers connected to SPI to obtain a dirt-cheap output-only GPIO expander. - Texas Instruments TPIC2810 - Texas Instruments TPS65218 - Texas Instruments TPS65912 - X-Gene (ARM64) standby GPIO controller -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW6m24AAoJEEEQszewGV1zUasP/RpTrjRcNI5QFHjudd2oioDx R/IljC06Q072ZqVy/MR7QxwhoU8jUnCgKgv4rgMa1OcfHblxC2R1+YBKOUSij831 E+SYmYDYmoMhN7j5Aslr66MXg1rLdFSdCZWemuyNruAK8bx6cTE1AWS8AELQzzTn Re/CPpCDbujLy0ZK2wJHgr9ZkdcBGICtDRCrOR3Kyjpwk/DSZcruK1PDN+VQMI3k bJlwgtGenOHINgCq/16edpwj/hzmoJXhTOZXJHI5XVR6czTwb3SvCYACvCkauI/a /N7b3quG88b5y0OPQPVxp5+VVl9GyVcv5oGzIfTNat/g5QinShZIT4kVV9r0xu6/ TQHh1HlXleh+QI3yX0oRv9ztHreMf+vdpw1dhIwLqHqfJ7AWdOGk7BbKjwCrsOoq t/qUVFnyvooLpyr53Z5JY8+LqyynHF68G+jUQyHLgTZ0GCE+z+1jqNl1T501n3kv 3CSlNYxSN/YUBN3cnroAIU/ZWcV4YRdxmOtEWP+7xgcdzTE6s/JHb2fuEfVHzWPf mHWtJGy8U0IR4VSSEln5RtjhRr0PAjTHeTOGAmivUnaIGDziTowyUVF+X5hwC77E DGTuLVx/Kniv173DK7xNAsUZNAETBa3fQZTgu+RfOpMiM1FZc7tI1rd7K7PjbyCc d2M0gcq+d11ITJTxC7OM =9AJ4 -----END PGP SIGNATURE----- Merge tag 'gpio-v4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio Pull GPIO updates from Linus Walleij: "This is the bulk of GPIO changes for kernel v4.6. There is quite a lot of interesting stuff going on. The patches to other subsystems and arch-wide are ACKed as far as possible, though I consider things like per-arch <asm/gpio.h> as essentially a part of the GPIO subsystem so it should not be needed. Core changes: - The gpio_chip is now a *real device*. Until now the gpio chips were just piggybacking the parent device or (gasp) floating in space outside of the device model. We now finally make GPIO chips devices. The gpio_chip will create a gpio_device which contains a struct device, and this gpio_device struct is kept private. Anything that needs to be kept private from the rest of the kernel will gradually be moved over to the gpio_device. - As a result of making the gpio_device a real device, we have added resource management, so devm_gpiochip_add_data() will cut down on overhead and reduce code lines. A huge slew of patches convert almost all drivers in the subsystem to use this. - Building on making the GPIO a real device, we add the first step of a new userspace ABI: the GPIO character device. We take small steps here, so we first add a pure *information* ABI and the tool "lsgpio" that will list all GPIO devices on the system and all lines on these devices. We can now discover GPIOs properly from userspace. We still have not come up with a way to actually *use* GPIOs from userspace. - To encourage people to use the character device for the future, we have it always-enabled when using GPIO. The old sysfs ABI is still opt-in (and can be used in parallel), but is marked as deprecated. We will keep it around for the foreseeable future, but it will not be extended to cover ever more use cases. Cleanup: - Bjorn Helgaas removed a whole slew of per-architecture <asm/gpio.h> includes. This dates back to when GPIO was an opt-in feature and no shared library even existed: just a header file with proper prototypes was provided and all semantics were up to the arch to implement. These patches make the GPIO chip even more a proper device and cleans out leftovers of the old in-kernel API here and there. Still some cruft is left but it's very little now. - There is still some clamping of return values for .get() going on, but we now return sane values in the vast majority of drivers and the errorpath is sanitized. Some patches for powerpc, blackfin and unicore still drop in. - We continue to switch the ARM, MIPS, blackfin, m68k local GPIO implementations to use gpiochip_add_data() and cut down on code lines. - MPC8xxx is converted to use the generic GPIO helpers. - ATH79 is converted to use the generic GPIO helpers. New drivers: - WinSystems WS16C48 - Acces 104-DIO-48E - F81866 (a F7188x variant) - Qoric (a MPC8xxx variant) - TS-4800 - SPI serializers (pisosr): simple 74xx shift registers connected to SPI to obtain a dirt-cheap output-only GPIO expander. - Texas Instruments TPIC2810 - Texas Instruments TPS65218 - Texas Instruments TPS65912 - X-Gene (ARM64) standby GPIO controller" * tag 'gpio-v4.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (194 commits) Revert "Share upstreaming patches" gpio: mcp23s08: Fix clearing of interrupt. gpiolib: Fix comment referring to gpio_*() in gpiod_*() gpio: pca953x: Fix pca953x_gpio_set_multiple() on 64-bit gpio: xgene: Fix kconfig for standby GIPO contoller gpio: Add generic serializer DT binding gpio: uapi: use 0xB4 as ioctl() major gpio: tps65912: fix bad merge Revert "gpio: lp3943: Drop pin_used and lp3943_gpio_request/lp3943_gpio_free" gpio: omap: drop dev field from gpio_bank structure gpio: mpc8xxx: Slightly update the code for better readability gpio: mpc8xxx: Remove *read_reg and *write_reg from struct mpc8xxx_gpio_chip gpio: mpc8xxx: Fixup setting gpio direction output gpio: mcp23s08: Add support for mcp23s18 dt-bindings: gpio: altera: Fix altr,interrupt-type property gpio: add driver for MEN 16Z127 GPIO controller gpio: lp3943: Drop pin_used and lp3943_gpio_request/lp3943_gpio_free gpio: timberdale: Switch to devm_ioremap_resource() gpio: ts4800: Add IMX51 dependency gpiolib: rewrite gpiodev_add_to_list ...
This commit is contained in:
commit
1a46712aa9
@ -1,7 +1,7 @@
|
||||
What: /sys/class/gpio/
|
||||
Date: July 2008
|
||||
KernelVersion: 2.6.27
|
||||
Contact: David Brownell <dbrownell@users.sourceforge.net>
|
||||
Contact: Linus Walleij <linusw@kernel.org>
|
||||
Description:
|
||||
|
||||
As a Kconfig option, individual GPIO signals may be accessed from
|
||||
@ -26,3 +26,5 @@ Description:
|
||||
/label ... (r/o) descriptive, not necessarily unique
|
||||
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
|
||||
|
||||
This ABI is deprecated and will be removed after 2020. It is
|
||||
replaced with the GPIO character device.
|
26
Documentation/ABI/testing/gpio-cdev
Normal file
26
Documentation/ABI/testing/gpio-cdev
Normal file
@ -0,0 +1,26 @@
|
||||
What: /dev/gpiochip[0-9]+
|
||||
Date: November 2015
|
||||
KernelVersion: 4.4
|
||||
Contact: linux-gpio@vger.kernel.org
|
||||
Description:
|
||||
The character device files /dev/gpiochip* are the interface
|
||||
between GPIO chips and userspace.
|
||||
|
||||
The ioctl(2)-based ABI is defined and documented in
|
||||
[include/uapi]<linux/gpio.h>.
|
||||
|
||||
The following file operations are supported:
|
||||
|
||||
open(2)
|
||||
Currently the only useful flags are O_RDWR.
|
||||
|
||||
ioctl(2)
|
||||
Initiate various actions.
|
||||
See the inline documentation in [include/uapi]<linux/gpio.h>
|
||||
for descriptions of all ioctls.
|
||||
|
||||
close(2)
|
||||
Stops and free up the I/O contexts that was associated
|
||||
with the file descriptor.
|
||||
|
||||
Users: TBD
|
@ -12,7 +12,7 @@ Required properties:
|
||||
- #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware.
|
||||
- The first cell is the GPIO offset number within the GPIO controller.
|
||||
- interrupts: Specify the interrupt.
|
||||
- altr,interrupt-trigger: Specifies the interrupt trigger type the GPIO
|
||||
- altr,interrupt-type: Specifies the interrupt trigger type the GPIO
|
||||
hardware is synthesized. This field is required if the Altera GPIO controller
|
||||
used has IRQ enabled as the interrupt type is not software controlled,
|
||||
but hardware synthesized. Required if GPIO is used as an interrupt
|
||||
@ -35,7 +35,7 @@ gpio_altr: gpio@0xff200000 {
|
||||
reg = <0xff200000 0x10>;
|
||||
interrupts = <0 45 4>;
|
||||
altr,ngpio = <32>;
|
||||
altr,interrupt-trigger = <IRQ_TYPE_EDGE_RISING>;
|
||||
altr,interrupt-type = <IRQ_TYPE_EDGE_RISING>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
@ -10,6 +10,7 @@ Required properties:
|
||||
|
||||
- "microchip,mcp23s08" for 8 GPIO SPI version
|
||||
- "microchip,mcp23s17" for 16 GPIO SPI version
|
||||
- "microchip,mcp23s18" for 16 GPIO SPI version
|
||||
- "microchip,mcp23008" for 8 GPIO I2C version or
|
||||
- "microchip,mcp23017" for 16 GPIO I2C version of the chip
|
||||
NOTE: Do not use the old mcp prefix any more. It is deprecated and will be
|
||||
@ -43,9 +44,6 @@ Optional properties:
|
||||
- first cell is the pin number
|
||||
- second cell is used to specify flags.
|
||||
- interrupt-controller: Marks the device node as a interrupt controller.
|
||||
NOTE: The interrupt functionality is only supported for i2c versions of the
|
||||
chips. The spi chips can also do the interrupts, but this is not supported by
|
||||
the linux driver yet.
|
||||
|
||||
Optional device specific properties:
|
||||
- microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices
|
||||
|
34
Documentation/devicetree/bindings/gpio/gpio-pisosr.txt
Normal file
34
Documentation/devicetree/bindings/gpio/gpio-pisosr.txt
Normal file
@ -0,0 +1,34 @@
|
||||
Generic Parallel-in/Serial-out Shift Register GPIO Driver
|
||||
|
||||
This binding describes generic parallel-in/serial-out shift register
|
||||
devices that can be used for GPI (General Purpose Input). This includes
|
||||
SN74165 serial-out shift registers and the SN65HVS88x series of
|
||||
industrial serializers.
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "pisosr-gpio".
|
||||
- gpio-controller : Marks the device node as a GPIO controller.
|
||||
- #gpio-cells : Should be two. For consumer use see gpio.txt.
|
||||
|
||||
Optional properties:
|
||||
- ngpios : Number of used GPIO lines (0..n-1), default is 8.
|
||||
- load-gpios : GPIO pin specifier attached to load enable, this
|
||||
pin is pulsed before reading from the device to
|
||||
load input pin values into the the device.
|
||||
|
||||
For other required and optional properties of SPI slave
|
||||
nodes please refer to ../spi/spi-bus.txt.
|
||||
|
||||
Example:
|
||||
|
||||
gpio@0 {
|
||||
compatible = "ti,sn65hvs882", "pisosr-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
load-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
|
||||
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
spi-cpol;
|
||||
};
|
20
Documentation/devicetree/bindings/gpio/gpio-ts4800.txt
Normal file
20
Documentation/devicetree/bindings/gpio/gpio-ts4800.txt
Normal file
@ -0,0 +1,20 @@
|
||||
* TS-4800 FPGA's GPIO controller bindings
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "technologic,ts4800-gpio".
|
||||
- #gpio-cells: Should be two. The first cell is the pin number.
|
||||
- reg: Physical base address of the controller and length
|
||||
of memory mapped region.
|
||||
|
||||
Optional property:
|
||||
- ngpios: See "gpio.txt"
|
||||
|
||||
Example:
|
||||
|
||||
gpio1: gpio {
|
||||
compatible = "technologic,ts4800-gpio";
|
||||
reg = <0x10020 0x6>;
|
||||
ngpios = <8>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
@ -1,10 +1,20 @@
|
||||
APM X-Gene Standby GPIO controller bindings
|
||||
|
||||
This is a gpio controller in the standby domain.
|
||||
|
||||
There are 20 GPIO pins from 0..21. There is no GPIO_DS14 or GPIO_DS15,
|
||||
only GPIO_DS8..GPIO_DS13 support interrupts. The IRQ mapping
|
||||
is currently 1-to-1 on interrupts 0x28 thru 0x2d.
|
||||
This is a gpio controller in the standby domain. It also supports interrupt in
|
||||
some particular pins which are sourced to its parent interrupt controller
|
||||
as diagram below:
|
||||
+-----------------+
|
||||
| X-Gene standby |
|
||||
| GPIO controller +------ GPIO_0
|
||||
+------------+ | | ...
|
||||
| Parent IRQ | EXT_INT_0 | +------ GPIO_8/EXT_INT_0
|
||||
| controller | (SPI40) | | ...
|
||||
| (GICv2) +--------------+ +------ GPIO_[N+8]/EXT_INT_N
|
||||
| | ... | |
|
||||
| | EXT_INT_N | +------ GPIO_[N+9]
|
||||
| | (SPI[40 + N])| | ...
|
||||
| +--------------+ +------ GPIO_MAX
|
||||
+------------+ +-----------------+
|
||||
|
||||
Required properties:
|
||||
- compatible: "apm,xgene-gpio-sb" for the X-Gene Standby GPIO controller
|
||||
@ -15,10 +25,18 @@ Required properties:
|
||||
0 = active high
|
||||
1 = active low
|
||||
- gpio-controller: Marks the device node as a GPIO controller.
|
||||
- interrupts: Shall contain exactly 6 interrupts.
|
||||
- interrupts: The EXT_INT_0 parent interrupt resource must be listed first.
|
||||
- interrupt-parent: Phandle of the parent interrupt controller.
|
||||
- interrupt-cells: Should be two.
|
||||
- first cell is 0-N coresponding for EXT_INT_0 to EXT_INT_N.
|
||||
- second cell is used to specify flags.
|
||||
- interrupt-controller: Marks the device node as an interrupt controller.
|
||||
- apm,nr-gpios: Optional, specify number of gpios pin.
|
||||
- apm,nr-irqs: Optional, specify number of interrupt pins.
|
||||
- apm,irq-start: Optional, specify lowest gpio pin support interrupt.
|
||||
|
||||
Example:
|
||||
sbgpio: sbgpio@17001000 {
|
||||
sbgpio: gpio@17001000{
|
||||
compatible = "apm,xgene-gpio-sb";
|
||||
reg = <0x0 0x17001000 0x0 0x400>;
|
||||
#gpio-cells = <2>;
|
||||
@ -29,4 +47,19 @@ Example:
|
||||
<0x0 0x2b 0x1>,
|
||||
<0x0 0x2c 0x1>,
|
||||
<0x0 0x2d 0x1>;
|
||||
interrupt-parent = <&gic>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
apm,nr-gpios = <22>;
|
||||
apm,nr-irqs = <6>;
|
||||
apm,irq-start = <8>;
|
||||
};
|
||||
|
||||
testuser {
|
||||
compatible = "example,testuser";
|
||||
/* Use the GPIO_13/EXT_INT_5 line as an active high triggered
|
||||
* level interrupt
|
||||
*/
|
||||
interrupts = <5 4>;
|
||||
interrupt-parent = <&sbgpio>;
|
||||
};
|
||||
|
50
Documentation/devicetree/bindings/mfd/tps65912.txt
Normal file
50
Documentation/devicetree/bindings/mfd/tps65912.txt
Normal file
@ -0,0 +1,50 @@
|
||||
* TPS65912 Power Management Integrated Circuit bindings
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "ti,tps65912".
|
||||
- reg : Slave address or chip select number (I2C / SPI).
|
||||
- interrupt-parent : The parent interrupt controller.
|
||||
- interrupts : The interrupt line the device is connected to.
|
||||
- interrupt-controller : Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells : The number of cells to describe an IRQ, should be 2.
|
||||
The first cell is the IRQ number.
|
||||
The second cell is the flags, encoded as trigger
|
||||
masks from ../interrupt-controller/interrupts.txt.
|
||||
- gpio-controller : Marks the device node as a GPIO Controller.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify flags.
|
||||
See ../gpio/gpio.txt for more information.
|
||||
- regulators: : List of child nodes that specify the regulator
|
||||
initialization data. Child nodes must be named
|
||||
after their hardware counterparts: dcdc[1-4] and
|
||||
ldo[1-10]. Each child nodes is defined using the
|
||||
standard binding for regulators.
|
||||
|
||||
Example:
|
||||
|
||||
pmic: tps65912@2d {
|
||||
compatible = "ti,tps65912";
|
||||
reg = <0x2d>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
regulators {
|
||||
dcdc1 {
|
||||
regulator-name = "vdd_core";
|
||||
regulator-min-microvolt = <912000>;
|
||||
regulator-max-microvolt = <1144000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <1900000>;
|
||||
regulator-max-microvolt = <1900000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -252,6 +252,11 @@ GPIO
|
||||
devm_gpiod_get_index_optional()
|
||||
devm_gpiod_get_optional()
|
||||
devm_gpiod_put()
|
||||
devm_gpiochip_add_data()
|
||||
devm_gpiochip_remove()
|
||||
devm_gpio_request()
|
||||
devm_gpio_request_one()
|
||||
devm_gpio_free()
|
||||
|
||||
IIO
|
||||
devm_iio_device_alloc()
|
||||
|
@ -111,16 +111,13 @@ files that desire to do so need to include the following header:
|
||||
GPIOs are mapped by the means of tables of lookups, containing instances of the
|
||||
gpiod_lookup structure. Two macros are defined to help declaring such mappings:
|
||||
|
||||
GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
|
||||
GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
|
||||
GPIO_LOOKUP(chip_label, chip_hwnum, con_id, flags)
|
||||
GPIO_LOOKUP_IDX(chip_label, chip_hwnum, con_id, idx, flags)
|
||||
|
||||
where
|
||||
|
||||
- chip_label is the label of the gpiod_chip instance providing the GPIO
|
||||
- chip_hwnum is the hardware number of the GPIO within the chip
|
||||
- dev_id is the identifier of the device that will make use of this GPIO. It
|
||||
can be NULL, in which case it will be matched for calls to gpiod_get()
|
||||
with a NULL device.
|
||||
- con_id is the name of the GPIO function from the device point of view. It
|
||||
can be NULL, in which case it will match any function.
|
||||
- idx is the index of the GPIO within the function.
|
||||
@ -134,7 +131,9 @@ In the future, these flags might be extended to support more properties.
|
||||
Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
|
||||
|
||||
A lookup table can then be defined as follows, with an empty entry defining its
|
||||
end:
|
||||
end. The 'dev_id' field of the table is the identifier of the device that will
|
||||
make use of these GPIOs. It can be NULL, in which case it will be matched for
|
||||
calls to gpiod_get() with a NULL device.
|
||||
|
||||
struct gpiod_lookup_table gpios_table = {
|
||||
.dev_id = "foo.0",
|
||||
|
@ -319,6 +319,7 @@ Code Seq#(hex) Include File Comments
|
||||
<mailto:vgo@ratio.de>
|
||||
0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca>
|
||||
0xB3 00 linux/mmc/ioctl.h
|
||||
0xB4 00-0F linux/gpio.h <mailto:linux-gpio@vger.kernel.org>
|
||||
0xC0 00-0F linux/usb/iowarrior.h
|
||||
0xCA 00-0F uapi/misc/cxl.h
|
||||
0xCA 80-8F uapi/scsi/cxlflash_ioctl.h
|
||||
|
16
MAINTAINERS
16
MAINTAINERS
@ -238,6 +238,12 @@ L: lm-sensors@lm-sensors.org
|
||||
S: Maintained
|
||||
F: drivers/hwmon/abituguru3.c
|
||||
|
||||
ACCES 104-DIO-48E GPIO DRIVER
|
||||
M: William Breathitt Gray <vilhelm.gray@gmail.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-104-dio-48e.c
|
||||
|
||||
ACCES 104-IDI-48 GPIO DRIVER
|
||||
M: "William Breathitt Gray" <vilhelm.gray@gmail.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
@ -4827,10 +4833,14 @@ L: linux-gpio@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
|
||||
S: Maintained
|
||||
F: Documentation/gpio/
|
||||
F: Documentation/ABI/testing/gpio-cdev
|
||||
F: Documentation/ABI/obsolete/sysfs-gpio
|
||||
F: drivers/gpio/
|
||||
F: include/linux/gpio/
|
||||
F: include/linux/gpio.h
|
||||
F: include/asm-generic/gpio.h
|
||||
F: include/uapi/linux/gpio.h
|
||||
F: tools/gpio/
|
||||
|
||||
GRE DEMULTIPLEXER DRIVER
|
||||
M: Dmitry Kozlov <xeb@mail.ru>
|
||||
@ -11931,6 +11941,12 @@ M: David Härdeman <david@hardeman.nu>
|
||||
S: Maintained
|
||||
F: drivers/media/rc/winbond-cir.c
|
||||
|
||||
WINSYSTEMS WS16C48 GPIO DRIVER
|
||||
M: William Breathitt Gray <vilhelm.gray@gmail.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-ws16c48.c
|
||||
|
||||
WIMAX STACK
|
||||
M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
|
||||
M: linux-wimax@intel.com
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -69,7 +69,7 @@ static void __scoop_gpio_set(struct scoop_dev *sdev,
|
||||
|
||||
static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
|
||||
struct scoop_dev *sdev = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sdev->scoop_lock, flags);
|
||||
@ -81,7 +81,7 @@ static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
|
||||
static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
|
||||
struct scoop_dev *sdev = gpiochip_get_data(chip);
|
||||
|
||||
/* XXX: I'm unsure, but it seems so */
|
||||
return !!(ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1)));
|
||||
@ -90,7 +90,7 @@ static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
static int scoop_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
{
|
||||
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
|
||||
struct scoop_dev *sdev = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
unsigned short gpcr;
|
||||
|
||||
@ -108,7 +108,7 @@ static int scoop_gpio_direction_input(struct gpio_chip *chip,
|
||||
static int scoop_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
|
||||
struct scoop_dev *sdev = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
unsigned short gpcr;
|
||||
|
||||
@ -224,7 +224,7 @@ static int scoop_probe(struct platform_device *pdev)
|
||||
devptr->gpio.direction_input = scoop_gpio_direction_input;
|
||||
devptr->gpio.direction_output = scoop_gpio_direction_output;
|
||||
|
||||
ret = gpiochip_add(&devptr->gpio);
|
||||
ret = gpiochip_add_data(&devptr->gpio, devptr);
|
||||
if (ret)
|
||||
goto err_gpio;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
@ -227,5 +227,5 @@ void __init gemini_gpio_init(void)
|
||||
(void *)i);
|
||||
}
|
||||
|
||||
BUG_ON(gpiochip_add(&gemini_gpio_chip));
|
||||
BUG_ON(gpiochip_add_data(&gemini_gpio_chip, NULL));
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/gpio/driver.h>
|
||||
/* Needed for gpio_to_irq() */
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
@ -243,7 +245,7 @@ static void __init mx27ads_regulator_init(void)
|
||||
vchip->ngpio = 1;
|
||||
vchip->direction_output = vgpio_dir_out;
|
||||
vchip->set = vgpio_set;
|
||||
gpiochip_add(vchip);
|
||||
gpiochip_add_data(vchip, NULL);
|
||||
|
||||
platform_device_register_data(NULL, "reg-fixed-voltage",
|
||||
PLATFORM_DEVID_AUTO,
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sched_clock.h>
|
||||
@ -461,7 +461,7 @@ void __init ixp4xx_sys_init(void)
|
||||
|
||||
platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
|
||||
|
||||
gpiochip_add(&ixp4xx_gpio_chip);
|
||||
gpiochip_add_data(&ixp4xx_gpio_chip, NULL);
|
||||
|
||||
if (cpu_is_ixp46x()) {
|
||||
int region;
|
||||
|
@ -664,7 +664,7 @@ static void __init h1940_map_io(void)
|
||||
|
||||
/* Add latch gpio chip, set latch initial value */
|
||||
h1940_latch_control(0, 0);
|
||||
WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
|
||||
WARN_ON(gpiochip_add_data(&h1940_latch_gpiochip, NULL));
|
||||
}
|
||||
|
||||
static void __init h1940_init_time(void)
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/setup.h>
|
||||
@ -369,7 +369,7 @@ static int __init simpad_init(void)
|
||||
cs3_gpio.get = cs3_gpio_get;
|
||||
cs3_gpio.direction_input = cs3_gpio_direction_input;
|
||||
cs3_gpio.direction_output = cs3_gpio_direction_output;
|
||||
ret = gpiochip_add(&cs3_gpio);
|
||||
ret = gpiochip_add_data(&cs3_gpio, NULL);
|
||||
if (ret)
|
||||
printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
#define GPIO_IN (0x0C)
|
||||
#define GROUPINERV (0x10)
|
||||
#define GPIO_GPIO(Nb) (0x00000001 << (Nb))
|
||||
#define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip)
|
||||
|
||||
#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \
|
||||
{ \
|
||||
@ -53,7 +52,7 @@ struct nuc900_gpio_chip {
|
||||
|
||||
static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
|
||||
struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
|
||||
void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
|
||||
unsigned int regval;
|
||||
|
||||
@ -65,7 +64,7 @@ static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
{
|
||||
struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
|
||||
struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
|
||||
void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
|
||||
unsigned int regval;
|
||||
unsigned long flags;
|
||||
@ -86,7 +85,7 @@ static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
|
||||
static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
|
||||
struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
|
||||
void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
|
||||
unsigned int regval;
|
||||
unsigned long flags;
|
||||
@ -104,7 +103,7 @@ static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
|
||||
{
|
||||
struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
|
||||
struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
|
||||
void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
|
||||
void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
|
||||
unsigned int regval;
|
||||
@ -149,6 +148,6 @@ void __init nuc900_init_gpio(int nr_group)
|
||||
gpio_chip = &nuc900_gpio[i];
|
||||
spin_lock_init(&gpio_chip->gpio_lock);
|
||||
gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
|
||||
gpiochip_add(&gpio_chip->chip);
|
||||
gpiochip_add_data(&gpio_chip->chip, gpio_chip);
|
||||
}
|
||||
}
|
||||
|
@ -154,8 +154,7 @@ err_out:
|
||||
*/
|
||||
static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
|
||||
if (orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK) ||
|
||||
orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
|
||||
@ -166,8 +165,7 @@ static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
|
||||
|
||||
static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK))
|
||||
@ -182,8 +180,7 @@ static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
|
||||
|
||||
static int orion_gpio_get(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
int val;
|
||||
|
||||
if (readl(GPIO_IO_CONF(ochip)) & (1 << pin)) {
|
||||
@ -198,8 +195,7 @@ static int orion_gpio_get(struct gpio_chip *chip, unsigned pin)
|
||||
static int
|
||||
orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
|
||||
@ -216,8 +212,7 @@ orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value)
|
||||
|
||||
static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ochip->lock, flags);
|
||||
@ -227,8 +222,7 @@ static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
|
||||
|
||||
static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
|
||||
return irq_create_mapping(ochip->domain,
|
||||
ochip->secondary_irq_base + pin);
|
||||
@ -445,8 +439,8 @@ static void gpio_irq_handler(struct irq_desc *desc)
|
||||
|
||||
static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
{
|
||||
struct orion_gpio_chip *ochip =
|
||||
container_of(chip, struct orion_gpio_chip, chip);
|
||||
|
||||
struct orion_gpio_chip *ochip = gpiochip_get_data(chip);
|
||||
u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
|
||||
int i;
|
||||
|
||||
@ -567,7 +561,7 @@ void __init orion_gpio_init(struct device_node *np,
|
||||
ochip->mask_offset = mask_offset;
|
||||
ochip->secondary_irq_base = secondary_irq_base;
|
||||
|
||||
gpiochip_add(&ochip->chip);
|
||||
gpiochip_add_data(&ochip->chip, ochip);
|
||||
|
||||
/*
|
||||
* Mask and clear GPIO interrupts.
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#include <mach/at32ap700x.h>
|
||||
#include <mach/board.h>
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <mach/portmux.h>
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
/* FIXME: consumer API required for gpio_set_value() etc, get rid of this */
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
@ -1159,7 +1161,7 @@ static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio,
|
||||
|
||||
static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
return bfin_gpio_get_value(gpio);
|
||||
return !!bfin_gpio_get_value(gpio);
|
||||
}
|
||||
|
||||
static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
|
||||
@ -1197,7 +1199,7 @@ static struct gpio_chip bfin_chip = {
|
||||
|
||||
static int __init bfin_gpiolib_setup(void)
|
||||
{
|
||||
return gpiochip_add(&bfin_chip);
|
||||
return gpiochip_add_data(&bfin_chip, NULL);
|
||||
}
|
||||
arch_initcall(bfin_gpiolib_setup);
|
||||
#endif
|
||||
|
@ -11,9 +11,9 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c/bfin_twi.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/gptimers.h>
|
||||
#include <asm/bfin_can.h>
|
||||
#include <asm/bfin_dma.h>
|
||||
|
@ -15,9 +15,9 @@
|
||||
#include <linux/spi/flash.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/portmux.h>
|
||||
|
||||
#define DEFINE_REG(reg, off) \
|
||||
@ -116,9 +116,9 @@ static struct gpio_chip bf538_porte_chip = {
|
||||
|
||||
static int __init bf538_extgpio_setup(void)
|
||||
{
|
||||
return gpiochip_add(&bf538_portc_chip) |
|
||||
gpiochip_add(&bf538_portd_chip) |
|
||||
gpiochip_add(&bf538_porte_chip);
|
||||
return gpiochip_add_data(&bf538_portc_chip, NULL) |
|
||||
gpiochip_add_data(&bf538_portd_chip, NULL) |
|
||||
gpiochip_add_data(&bf538_porte_chip, NULL);
|
||||
}
|
||||
arch_initcall(bf538_extgpio_setup);
|
||||
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/usb/musb.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/bfin_sdh.h>
|
||||
|
@ -20,9 +20,9 @@
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/platform_data/pinctrl-adi2.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <asm/bfin_sport.h>
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/platform_data/pinctrl-adi2.h>
|
||||
#include <linux/spi/adi_spi3.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <asm/portmux.h>
|
||||
|
@ -17,13 +17,13 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/delay.h>
|
||||
#ifdef CONFIG_IPIPE
|
||||
#include <linux/ipipe.h>
|
||||
#endif
|
||||
#include <asm/traps.h>
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/irq_handler.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <asm/traps.h>
|
||||
|
@ -15,9 +15,9 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/cplb.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <asm/pm.h>
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -178,7 +178,7 @@ static struct gpio_chip mcfgpio_chip = {
|
||||
|
||||
static int __init mcfgpio_sysinit(void)
|
||||
{
|
||||
gpiochip_add(&mcfgpio_chip);
|
||||
gpiochip_add_data(&mcfgpio_chip, NULL);
|
||||
return subsys_system_register(&mcfgpio_subsys, NULL);
|
||||
}
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -160,14 +160,14 @@ static int __init alchemy_gpiochip_init(void)
|
||||
|
||||
switch (alchemy_get_cputype()) {
|
||||
case ALCHEMY_CPU_AU1000:
|
||||
ret = gpiochip_add(&alchemy_gpio_chip[0]);
|
||||
ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL);
|
||||
break;
|
||||
case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200:
|
||||
ret = gpiochip_add(&alchemy_gpio_chip[0]);
|
||||
ret |= gpiochip_add(&alchemy_gpio_chip[1]);
|
||||
ret = gpiochip_add_data(&alchemy_gpio_chip[0], NULL);
|
||||
ret |= gpiochip_add_data(&alchemy_gpio_chip[1], NULL);
|
||||
break;
|
||||
case ALCHEMY_CPU_AU1300:
|
||||
ret = gpiochip_add(&au1300_gpiochip);
|
||||
ret = gpiochip_add_data(&au1300_gpiochip, NULL);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
@ -33,8 +33,7 @@ struct ar7_gpio_chip {
|
||||
|
||||
static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
|
||||
|
||||
return !!(readl(gpio_in) & (1 << gpio));
|
||||
@ -42,8 +41,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
|
||||
static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
|
||||
void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
|
||||
|
||||
@ -53,8 +51,7 @@ static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
static void ar7_gpio_set_value(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
|
||||
unsigned tmp;
|
||||
|
||||
@ -67,8 +64,7 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
|
||||
static void titan_gpio_set_value(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
|
||||
void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
|
||||
unsigned tmp;
|
||||
@ -81,8 +77,7 @@ static void titan_gpio_set_value(struct gpio_chip *chip,
|
||||
|
||||
static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
|
||||
|
||||
writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
|
||||
@ -92,8 +87,7 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
|
||||
|
||||
static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
|
||||
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
|
||||
|
||||
@ -108,8 +102,7 @@ static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
|
||||
static int ar7_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
|
||||
|
||||
ar7_gpio_set_value(chip, gpio, value);
|
||||
@ -121,8 +114,7 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
|
||||
static int titan_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
{
|
||||
struct ar7_gpio_chip *gpch =
|
||||
container_of(chip, struct ar7_gpio_chip, chip);
|
||||
struct ar7_gpio_chip *gpch = gpiochip_get_data(chip);
|
||||
void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
|
||||
void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
|
||||
|
||||
@ -335,7 +327,7 @@ int __init ar7_gpio_init(void)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = gpiochip_add(&gpch->chip);
|
||||
ret = gpiochip_add_data(&gpch->chip, gpch);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: failed to add gpiochip\n",
|
||||
gpch->chip.label);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#include <bcm63xx_cpu.h>
|
||||
#include <bcm63xx_gpio.h>
|
||||
@ -147,5 +147,5 @@ int __init bcm63xx_gpio_init(void)
|
||||
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
|
||||
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
|
||||
|
||||
return gpiochip_add(&bcm63xx_gpio_chip);
|
||||
return gpiochip_add_data(&bcm63xx_gpio_chip, NULL);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
/* FIXME: needed for gpio_request(), try to remove consumer API from driver */
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -91,9 +93,9 @@ static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
|
||||
return &jz4740_gpio_chips[gpio >> 5];
|
||||
}
|
||||
|
||||
static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
|
||||
static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gc)
|
||||
{
|
||||
return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
|
||||
return gpiochip_get_data(gc);
|
||||
}
|
||||
|
||||
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
|
||||
@ -234,7 +236,7 @@ static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
|
||||
|
||||
static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct jz_gpio_chip *jz_gpio = gpio_chip_to_jz_gpio_chip(chip);
|
||||
struct jz_gpio_chip *jz_gpio = gpiochip_get_data(chip);
|
||||
|
||||
return jz_gpio->irq_base + gpio;
|
||||
}
|
||||
@ -449,7 +451,7 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
|
||||
IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
|
||||
|
||||
gpiochip_add(&chip->gpio_chip);
|
||||
gpiochip_add_data(&chip->gpio_chip, chip);
|
||||
}
|
||||
|
||||
static int __init jz4740_gpio_init(void)
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/txx9pio.h>
|
||||
@ -85,5 +85,5 @@ int __init txx9_gpio_init(unsigned long baseaddr,
|
||||
return -ENODEV;
|
||||
txx9_gpio_chip.base = base;
|
||||
txx9_gpio_chip.ngpio = num;
|
||||
return gpiochip_add(&txx9_gpio_chip);
|
||||
return gpiochip_add_data(&txx9_gpio_chip, NULL);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#include <asm/mach-rc32434/rb.h>
|
||||
#include <asm/mach-rc32434/gpio.h>
|
||||
@ -88,7 +88,7 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct rb532_gpio_chip *gpch;
|
||||
|
||||
gpch = container_of(chip, struct rb532_gpio_chip, chip);
|
||||
gpch = gpiochip_get_data(chip);
|
||||
return !!rb532_get_bit(offset, gpch->regbase + GPIOD);
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ static void rb532_gpio_set(struct gpio_chip *chip,
|
||||
{
|
||||
struct rb532_gpio_chip *gpch;
|
||||
|
||||
gpch = container_of(chip, struct rb532_gpio_chip, chip);
|
||||
gpch = gpiochip_get_data(chip);
|
||||
rb532_set_bit(value, offset, gpch->regbase + GPIOD);
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct rb532_gpio_chip *gpch;
|
||||
|
||||
gpch = container_of(chip, struct rb532_gpio_chip, chip);
|
||||
gpch = gpiochip_get_data(chip);
|
||||
|
||||
/* disable alternate function in case it's set */
|
||||
rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
|
||||
@ -128,7 +128,7 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip,
|
||||
{
|
||||
struct rb532_gpio_chip *gpch;
|
||||
|
||||
gpch = container_of(chip, struct rb532_gpio_chip, chip);
|
||||
gpch = gpiochip_get_data(chip);
|
||||
|
||||
/* disable alternate function in case it's set */
|
||||
rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
|
||||
@ -200,7 +200,7 @@ int __init rb532_gpio_init(void)
|
||||
}
|
||||
|
||||
/* Register our GPIO chip */
|
||||
gpiochip_add(&rb532_gpio_chip->chip);
|
||||
gpiochip_add_data(&rb532_gpio_chip->chip, rb532_gpio_chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
@ -687,16 +687,14 @@ struct txx9_iocled_data {
|
||||
|
||||
static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct txx9_iocled_data *data =
|
||||
container_of(chip, struct txx9_iocled_data, chip);
|
||||
struct txx9_iocled_data *data = gpiochip_get_data(chip);
|
||||
return !!(data->cur_val & (1 << offset));
|
||||
}
|
||||
|
||||
static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct txx9_iocled_data *data =
|
||||
container_of(chip, struct txx9_iocled_data, chip);
|
||||
struct txx9_iocled_data *data = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&txx9_iocled_lock, flags);
|
||||
if (value)
|
||||
@ -749,7 +747,7 @@ void __init txx9_iocled_init(unsigned long baseaddr,
|
||||
iocled->chip.label = "iocled";
|
||||
iocled->chip.base = basenum;
|
||||
iocled->chip.ngpio = num;
|
||||
if (gpiochip_add(&iocled->chip))
|
||||
if (gpiochip_add_data(&iocled->chip, iocled))
|
||||
goto out_unmap;
|
||||
if (basenum < 0)
|
||||
basenum = iocled->chip.base;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
@ -335,7 +336,7 @@ static void __init rbtx4938_mtd_init(void)
|
||||
|
||||
static void __init rbtx4938_arch_init(void)
|
||||
{
|
||||
gpiochip_add(&rbtx4938_spi_gpio_chip);
|
||||
gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL);
|
||||
rbtx4938_pci_setup();
|
||||
rbtx4938_spi_init();
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -78,7 +78,7 @@ static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
|
||||
|
||||
return in_be32(®s->ir) & GPIO_MASK(gpio);
|
||||
return !!(in_be32(®s->ir) & GPIO_MASK(gpio));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -46,7 +46,7 @@ static int u8_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
|
||||
return in_8(mm_gc->regs) & u8_pin2mask(gpio);
|
||||
return !!(in_8(mm_gc->regs) & u8_pin2mask(gpio));
|
||||
}
|
||||
|
||||
static void u8_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
|
@ -13,7 +13,7 @@
|
||||
#ifndef __ASM_SH_MAGICPANELR2_H
|
||||
#define __ASM_SH_MAGICPANELR2_H
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#define __IO_PREFIX mpr2
|
||||
#include <asm/io_generic.h>
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -52,7 +52,7 @@ device_initcall(puv3_gpio_leds_init);
|
||||
|
||||
static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return readl(GPIO_GPLR) & GPIO_GPIO(offset);
|
||||
return !!(readl(GPIO_GPLR) & GPIO_GPIO(offset));
|
||||
}
|
||||
|
||||
static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -1,4 +0,0 @@
|
||||
#ifndef __LINUX_GPIO_H
|
||||
#warning Include linux/gpio.h instead of asm/gpio.h
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
@ -30,8 +30,7 @@
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/platform_data/atmel.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#define DRV_NAME "pata_at91"
|
||||
#define DRV_VERSION "0.3"
|
||||
|
@ -36,8 +36,8 @@
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/portmux.h>
|
||||
|
||||
#define DRV_NAME "pata-bf54x"
|
||||
|
@ -126,6 +126,16 @@ config GPIO_AMDPT
|
||||
driver for GPIO functionality on Promontory IOHub
|
||||
Require ACPI ASL code to enumerate as a platform device.
|
||||
|
||||
config GPIO_ATH79
|
||||
tristate "Atheros AR71XX/AR724X/AR913X GPIO support"
|
||||
default y if ATH79
|
||||
depends on ATH79 || COMPILE_TEST
|
||||
select GPIO_GENERIC
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Select this option to enable GPIO driver for
|
||||
Atheros AR71XX/AR724X/AR913X SoC devices.
|
||||
|
||||
config GPIO_BCM_KONA
|
||||
bool "Broadcom Kona GPIO"
|
||||
depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
|
||||
@ -256,10 +266,17 @@ config GPIO_LYNXPOINT
|
||||
|
||||
config GPIO_MB86S7X
|
||||
bool "GPIO support for Fujitsu MB86S7x Platforms"
|
||||
depends on ARCH_MB86S7X
|
||||
depends on ARCH_MB86S7X || COMPILE_TEST
|
||||
help
|
||||
Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs.
|
||||
|
||||
config GPIO_MENZ127
|
||||
tristate "MEN 16Z127 GPIO support"
|
||||
depends on MCB
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
Say yes here to support the MEN 16Z127 GPIO Controller
|
||||
|
||||
config GPIO_MM_LANTIQ
|
||||
bool "Lantiq Memory mapped GPIOs"
|
||||
depends on LANTIQ && SOC_XWAY
|
||||
@ -270,7 +287,7 @@ config GPIO_MM_LANTIQ
|
||||
|
||||
config GPIO_MOXART
|
||||
bool "MOXART GPIO support"
|
||||
depends on ARCH_MOXART
|
||||
depends on ARCH_MOXART || COMPILE_TEST
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
Select this option to enable GPIO driver for
|
||||
@ -281,12 +298,14 @@ config GPIO_MPC5200
|
||||
depends on PPC_MPC52xx
|
||||
|
||||
config GPIO_MPC8XXX
|
||||
bool "MPC512x/MPC8xxx GPIO support"
|
||||
bool "MPC512x/MPC8xxx/QorIQ GPIO support"
|
||||
depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
|
||||
FSL_SOC_BOOKE || PPC_86xx
|
||||
FSL_SOC_BOOKE || PPC_86xx || ARCH_LAYERSCAPE || ARM || \
|
||||
COMPILE_TEST
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
MPC512x/831x/834x/837x/8572/8610 GPIOs.
|
||||
MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
|
||||
|
||||
config GPIO_MVEBU
|
||||
def_bool y
|
||||
@ -339,7 +358,7 @@ config GPIO_PXA
|
||||
|
||||
config GPIO_RCAR
|
||||
tristate "Renesas R-Car GPIO"
|
||||
depends on ARCH_SHMOBILE || COMPILE_TEST
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Say yes here to support GPIO on Renesas R-Car SoCs.
|
||||
@ -380,6 +399,14 @@ config GPIO_TB10X
|
||||
select GENERIC_IRQ_CHIP
|
||||
select OF_GPIO
|
||||
|
||||
config GPIO_TS4800
|
||||
tristate "TS-4800 DIO blocks and compatibles"
|
||||
depends on OF_GPIO
|
||||
depends on SOC_IMX51 || COMPILE_TEST
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
This driver support TS-4800 FPGA GPIO controllers.
|
||||
|
||||
config GPIO_TZ1090
|
||||
bool "Toumaz Xenif TZ1090 GPIO support"
|
||||
depends on SOC_TZ1090
|
||||
@ -433,6 +460,7 @@ config GPIO_XGENE_SB
|
||||
tristate "APM X-Gene GPIO standby controller support"
|
||||
depends on ARCH_XGENE && OF_GPIO
|
||||
select GPIO_GENERIC
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
This driver supports the GPIO block within the APM X-Gene
|
||||
Standby Domain. Say yes here to enable the GPIO functionality.
|
||||
@ -487,6 +515,15 @@ endmenu
|
||||
menu "Port-mapped I/O GPIO drivers"
|
||||
depends on X86 # Unconditional I/O space access
|
||||
|
||||
config GPIO_104_DIO_48E
|
||||
tristate "ACCES 104-DIO-48E GPIO support"
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Enables GPIO support for the ACCES 104-DIO-48E family. The base port
|
||||
address for the device may be configured via the dio_48e_base module
|
||||
parameter. The interrupt line number for the device may be configured
|
||||
via the dio_48e_irq module parameter.
|
||||
|
||||
config GPIO_104_IDIO_16
|
||||
tristate "ACCES 104-IDIO-16 GPIO support"
|
||||
select GPIOLIB_IRQCHIP
|
||||
@ -506,10 +543,10 @@ config GPIO_104_IDI_48
|
||||
via the idi_48_irq module parameter.
|
||||
|
||||
config GPIO_F7188X
|
||||
tristate "F71869, F71869A, F71882FG and F71889F GPIO support"
|
||||
tristate "F71869, F71869A, F71882FG, F71889F and F81866 GPIO support"
|
||||
help
|
||||
This option enables support for GPIOs found on Fintek Super-I/O
|
||||
chips F71869, F71869A, F71882FG and F71889F.
|
||||
chips F71869, F71869A, F71882FG, F71889F and F81866.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called f7188x-gpio.
|
||||
@ -570,6 +607,15 @@ config GPIO_TS5500
|
||||
blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
|
||||
LCD port.
|
||||
|
||||
config GPIO_WS16C48
|
||||
tristate "WinSystems WS16C48 GPIO support"
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Enables GPIO support for the WinSystems WS16C48. The base port address
|
||||
for the device may be configured via the ws16c48_base module
|
||||
parameter. The interrupt line number for the device may be configured
|
||||
via the ws16c48_irq module parameter.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "I2C GPIO expanders"
|
||||
@ -702,6 +748,14 @@ config GPIO_SX150X
|
||||
8 bits: sx1508q
|
||||
16 bits: sx1509q
|
||||
|
||||
config GPIO_TPIC2810
|
||||
tristate "TPIC2810 8-Bit I2C GPO expander"
|
||||
help
|
||||
Say yes here to enable the GPO driver for the TI TPIC2810 chip.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called gpio-tpic2810.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "MFD GPIO expanders"
|
||||
@ -844,6 +898,13 @@ config GPIO_TIMBERDALE
|
||||
---help---
|
||||
Add support for the GPIO IP in the timberdale FPGA.
|
||||
|
||||
config GPIO_TPS65218
|
||||
tristate "TPS65218 GPIO"
|
||||
depends on MFD_TPS65218
|
||||
help
|
||||
Select this option to enable GPIO driver for the TPS65218
|
||||
chip family.
|
||||
|
||||
config GPIO_TPS6586X
|
||||
bool "TPS6586X GPIO"
|
||||
depends on MFD_TPS6586X
|
||||
@ -860,7 +921,7 @@ config GPIO_TPS65910
|
||||
|
||||
config GPIO_TPS65912
|
||||
tristate "TI TPS65912 GPIO"
|
||||
depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
|
||||
depends on MFD_TPS65912
|
||||
help
|
||||
This driver supports TPS65912 gpio chip
|
||||
|
||||
@ -1011,6 +1072,12 @@ config GPIO_MC33880
|
||||
SPI driver for Freescale MC33880 high-side/low-side switch.
|
||||
This provides GPIO interface supporting inputs and outputs.
|
||||
|
||||
config GPIO_PISOSR
|
||||
tristate "Generic parallel-in/serial-out shift register"
|
||||
help
|
||||
GPIO driver for SPI compatible parallel-in/serial-out shift
|
||||
registers. These are input only devices.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "SPI or I2C GPIO expanders"
|
||||
|
@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
|
||||
# Device drivers. Generally keep list sorted alphabetically
|
||||
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
|
||||
|
||||
obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o
|
||||
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
|
||||
obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
|
||||
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
|
||||
@ -23,7 +24,7 @@ obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
|
||||
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
|
||||
obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
|
||||
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
|
||||
obj-$(CONFIG_ATH79) += gpio-ath79.o
|
||||
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
|
||||
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
|
||||
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
|
||||
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
|
||||
@ -58,6 +59,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
|
||||
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
|
||||
obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
|
||||
obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o
|
||||
obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o
|
||||
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
|
||||
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
|
||||
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
|
||||
@ -75,6 +77,7 @@ obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
|
||||
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
@ -95,9 +98,12 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
|
||||
obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
|
||||
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
|
||||
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
|
||||
obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
|
||||
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
|
||||
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
|
||||
obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o
|
||||
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
|
||||
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
|
||||
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
|
||||
@ -111,6 +117,7 @@ obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
|
||||
obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o
|
||||
obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o
|
||||
obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
|
||||
|
@ -155,7 +155,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
|
||||
suffixes[i]);
|
||||
|
||||
desc = fwnode_get_named_gpiod(child, prop_name);
|
||||
if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
|
||||
if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
|
||||
break;
|
||||
}
|
||||
if (IS_ERR(desc)) {
|
||||
|
430
drivers/gpio/gpio-104-dio-48e.c
Normal file
430
drivers/gpio/gpio-104-dio-48e.c
Normal file
@ -0,0 +1,430 @@
|
||||
/*
|
||||
* GPIO driver for the ACCES 104-DIO-48E
|
||||
* Copyright (C) 2016 William Breathitt Gray
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdesc.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
static unsigned dio_48e_base;
|
||||
module_param(dio_48e_base, uint, 0);
|
||||
MODULE_PARM_DESC(dio_48e_base, "ACCES 104-DIO-48E base address");
|
||||
static unsigned dio_48e_irq;
|
||||
module_param(dio_48e_irq, uint, 0);
|
||||
MODULE_PARM_DESC(dio_48e_irq, "ACCES 104-DIO-48E interrupt line number");
|
||||
|
||||
/**
|
||||
* struct dio48e_gpio - GPIO device private data structure
|
||||
* @chip: instance of the gpio_chip
|
||||
* @io_state: bit I/O state (whether bit is set to input or output)
|
||||
* @out_state: output bits state
|
||||
* @control: Control registers state
|
||||
* @lock: synchronization lock to prevent I/O race conditions
|
||||
* @base: base port address of the GPIO device
|
||||
* @irq: Interrupt line number
|
||||
* @irq_mask: I/O bits affected by interrupts
|
||||
*/
|
||||
struct dio48e_gpio {
|
||||
struct gpio_chip chip;
|
||||
unsigned char io_state[6];
|
||||
unsigned char out_state[6];
|
||||
unsigned char control[2];
|
||||
spinlock_t lock;
|
||||
unsigned base;
|
||||
unsigned irq;
|
||||
unsigned char irq_mask;
|
||||
};
|
||||
|
||||
static int dio48e_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned port = offset / 8;
|
||||
const unsigned mask = BIT(offset % 8);
|
||||
|
||||
return !!(dio48egpio->io_state[port] & mask);
|
||||
}
|
||||
|
||||
static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned io_port = offset / 8;
|
||||
const unsigned control_port = io_port / 2;
|
||||
const unsigned control_addr = dio48egpio->base + 3 + control_port*4;
|
||||
unsigned long flags;
|
||||
unsigned control;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
/* Check if configuring Port C */
|
||||
if (io_port == 2 || io_port == 5) {
|
||||
/* Port C can be configured by nibble */
|
||||
if (offset % 8 > 3) {
|
||||
dio48egpio->io_state[io_port] |= 0xF0;
|
||||
dio48egpio->control[control_port] |= BIT(3);
|
||||
} else {
|
||||
dio48egpio->io_state[io_port] |= 0x0F;
|
||||
dio48egpio->control[control_port] |= BIT(0);
|
||||
}
|
||||
} else {
|
||||
dio48egpio->io_state[io_port] |= 0xFF;
|
||||
if (io_port == 0 || io_port == 3)
|
||||
dio48egpio->control[control_port] |= BIT(4);
|
||||
else
|
||||
dio48egpio->control[control_port] |= BIT(1);
|
||||
}
|
||||
|
||||
control = BIT(7) | dio48egpio->control[control_port];
|
||||
outb(control, control_addr);
|
||||
control &= ~BIT(7);
|
||||
outb(control, control_addr);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned io_port = offset / 8;
|
||||
const unsigned control_port = io_port / 2;
|
||||
const unsigned mask = BIT(offset % 8);
|
||||
const unsigned control_addr = dio48egpio->base + 3 + control_port*4;
|
||||
const unsigned out_port = (io_port > 2) ? io_port + 1 : io_port;
|
||||
unsigned long flags;
|
||||
unsigned control;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
/* Check if configuring Port C */
|
||||
if (io_port == 2 || io_port == 5) {
|
||||
/* Port C can be configured by nibble */
|
||||
if (offset % 8 > 3) {
|
||||
dio48egpio->io_state[io_port] &= 0x0F;
|
||||
dio48egpio->control[control_port] &= ~BIT(3);
|
||||
} else {
|
||||
dio48egpio->io_state[io_port] &= 0xF0;
|
||||
dio48egpio->control[control_port] &= ~BIT(0);
|
||||
}
|
||||
} else {
|
||||
dio48egpio->io_state[io_port] &= 0x00;
|
||||
if (io_port == 0 || io_port == 3)
|
||||
dio48egpio->control[control_port] &= ~BIT(4);
|
||||
else
|
||||
dio48egpio->control[control_port] &= ~BIT(1);
|
||||
}
|
||||
|
||||
if (value)
|
||||
dio48egpio->out_state[io_port] |= mask;
|
||||
else
|
||||
dio48egpio->out_state[io_port] &= ~mask;
|
||||
|
||||
control = BIT(7) | dio48egpio->control[control_port];
|
||||
outb(control, control_addr);
|
||||
|
||||
outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port);
|
||||
|
||||
control &= ~BIT(7);
|
||||
outb(control, control_addr);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned port = offset / 8;
|
||||
const unsigned mask = BIT(offset % 8);
|
||||
const unsigned in_port = (port > 2) ? port + 1 : port;
|
||||
unsigned long flags;
|
||||
unsigned port_state;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
/* ensure that GPIO is set for input */
|
||||
if (!(dio48egpio->io_state[port] & mask)) {
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
port_state = inb(dio48egpio->base + in_port);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
|
||||
return !!(port_state & mask);
|
||||
}
|
||||
|
||||
static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned port = offset / 8;
|
||||
const unsigned mask = BIT(offset % 8);
|
||||
const unsigned out_port = (port > 2) ? port + 1 : port;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
if (value)
|
||||
dio48egpio->out_state[port] |= mask;
|
||||
else
|
||||
dio48egpio->out_state[port] &= ~mask;
|
||||
|
||||
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
}
|
||||
|
||||
static void dio48e_irq_ack(struct irq_data *data)
|
||||
{
|
||||
}
|
||||
|
||||
static void dio48e_irq_mask(struct irq_data *data)
|
||||
{
|
||||
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned long offset = irqd_to_hwirq(data);
|
||||
unsigned long flags;
|
||||
|
||||
/* only bit 3 on each respective Port C supports interrupts */
|
||||
if (offset != 19 && offset != 43)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
if (offset == 19)
|
||||
dio48egpio->irq_mask &= ~BIT(0);
|
||||
else
|
||||
dio48egpio->irq_mask &= ~BIT(1);
|
||||
|
||||
if (!dio48egpio->irq_mask)
|
||||
/* disable interrupts */
|
||||
inb(dio48egpio->base + 0xB);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
}
|
||||
|
||||
static void dio48e_irq_unmask(struct irq_data *data)
|
||||
{
|
||||
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
|
||||
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
|
||||
const unsigned long offset = irqd_to_hwirq(data);
|
||||
unsigned long flags;
|
||||
|
||||
/* only bit 3 on each respective Port C supports interrupts */
|
||||
if (offset != 19 && offset != 43)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
|
||||
if (!dio48egpio->irq_mask) {
|
||||
/* enable interrupts */
|
||||
outb(0x00, dio48egpio->base + 0xF);
|
||||
outb(0x00, dio48egpio->base + 0xB);
|
||||
}
|
||||
|
||||
if (offset == 19)
|
||||
dio48egpio->irq_mask |= BIT(0);
|
||||
else
|
||||
dio48egpio->irq_mask |= BIT(1);
|
||||
|
||||
spin_unlock_irqrestore(&dio48egpio->lock, flags);
|
||||
}
|
||||
|
||||
static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
|
||||
{
|
||||
const unsigned long offset = irqd_to_hwirq(data);
|
||||
|
||||
/* only bit 3 on each respective Port C supports interrupts */
|
||||
if (offset != 19 && offset != 43)
|
||||
return -EINVAL;
|
||||
|
||||
if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_RISING)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip dio48e_irqchip = {
|
||||
.name = "104-dio-48e",
|
||||
.irq_ack = dio48e_irq_ack,
|
||||
.irq_mask = dio48e_irq_mask,
|
||||
.irq_unmask = dio48e_irq_unmask,
|
||||
.irq_set_type = dio48e_irq_set_type
|
||||
};
|
||||
|
||||
static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = dev_id;
|
||||
struct gpio_chip *const chip = &dio48egpio->chip;
|
||||
const unsigned long irq_mask = dio48egpio->irq_mask;
|
||||
unsigned long gpio;
|
||||
|
||||
for_each_set_bit(gpio, &irq_mask, 2)
|
||||
generic_handle_irq(irq_find_mapping(chip->irqdomain,
|
||||
19 + gpio*24));
|
||||
|
||||
spin_lock(&dio48egpio->lock);
|
||||
|
||||
outb(0x00, dio48egpio->base + 0xF);
|
||||
|
||||
spin_unlock(&dio48egpio->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init dio48e_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct dio48e_gpio *dio48egpio;
|
||||
const unsigned base = dio_48e_base;
|
||||
const unsigned extent = 16;
|
||||
const char *const name = dev_name(dev);
|
||||
int err;
|
||||
const unsigned irq = dio_48e_irq;
|
||||
|
||||
dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
|
||||
if (!dio48egpio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!devm_request_region(dev, base, extent, name)) {
|
||||
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
|
||||
base, base + extent);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dio48egpio->chip.label = name;
|
||||
dio48egpio->chip.parent = dev;
|
||||
dio48egpio->chip.owner = THIS_MODULE;
|
||||
dio48egpio->chip.base = -1;
|
||||
dio48egpio->chip.ngpio = 48;
|
||||
dio48egpio->chip.get_direction = dio48e_gpio_get_direction;
|
||||
dio48egpio->chip.direction_input = dio48e_gpio_direction_input;
|
||||
dio48egpio->chip.direction_output = dio48e_gpio_direction_output;
|
||||
dio48egpio->chip.get = dio48e_gpio_get;
|
||||
dio48egpio->chip.set = dio48e_gpio_set;
|
||||
dio48egpio->base = base;
|
||||
dio48egpio->irq = irq;
|
||||
|
||||
spin_lock_init(&dio48egpio->lock);
|
||||
|
||||
dev_set_drvdata(dev, dio48egpio);
|
||||
|
||||
err = gpiochip_add_data(&dio48egpio->chip, dio48egpio);
|
||||
if (err) {
|
||||
dev_err(dev, "GPIO registering failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* initialize all GPIO as output */
|
||||
outb(0x80, base + 3);
|
||||
outb(0x00, base);
|
||||
outb(0x00, base + 1);
|
||||
outb(0x00, base + 2);
|
||||
outb(0x00, base + 3);
|
||||
outb(0x80, base + 7);
|
||||
outb(0x00, base + 4);
|
||||
outb(0x00, base + 5);
|
||||
outb(0x00, base + 6);
|
||||
outb(0x00, base + 7);
|
||||
|
||||
/* disable IRQ by default */
|
||||
inb(base + 0xB);
|
||||
|
||||
err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0,
|
||||
handle_edge_irq, IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(dev, "Could not add irqchip (%d)\n", err);
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
err = request_irq(irq, dio48e_irq_handler, 0, name, dio48egpio);
|
||||
if (err) {
|
||||
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_gpiochip_remove:
|
||||
gpiochip_remove(&dio48egpio->chip);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dio48e_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = platform_get_drvdata(pdev);
|
||||
|
||||
free_irq(dio48egpio->irq, dio48egpio);
|
||||
gpiochip_remove(&dio48egpio->chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device *dio48e_device;
|
||||
|
||||
static struct platform_driver dio48e_driver = {
|
||||
.driver = {
|
||||
.name = "104-dio-48e"
|
||||
},
|
||||
.remove = dio48e_remove
|
||||
};
|
||||
|
||||
static void __exit dio48e_exit(void)
|
||||
{
|
||||
platform_device_unregister(dio48e_device);
|
||||
platform_driver_unregister(&dio48e_driver);
|
||||
}
|
||||
|
||||
static int __init dio48e_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
dio48e_device = platform_device_alloc(dio48e_driver.driver.name, -1);
|
||||
if (!dio48e_device)
|
||||
return -ENOMEM;
|
||||
|
||||
err = platform_device_add(dio48e_device);
|
||||
if (err)
|
||||
goto err_platform_device;
|
||||
|
||||
err = platform_driver_probe(&dio48e_driver, dio48e_probe);
|
||||
if (err)
|
||||
goto err_platform_driver;
|
||||
|
||||
return 0;
|
||||
|
||||
err_platform_driver:
|
||||
platform_device_del(dio48e_device);
|
||||
err_platform_device:
|
||||
platform_device_put(dio48e_device);
|
||||
return err;
|
||||
}
|
||||
|
||||
module_init(dio48e_init);
|
||||
module_exit(dio48e_exit);
|
||||
|
||||
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
|
||||
MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -39,7 +39,6 @@ MODULE_PARM_DESC(idi_48_irq, "ACCES 104-IDI-48 interrupt line number");
|
||||
* @ack_lock: synchronization lock to prevent IRQ handler race conditions
|
||||
* @irq_mask: input bits affected by interrupts
|
||||
* @base: base port address of the GPIO device
|
||||
* @extent: extent of port address region of the GPIO device
|
||||
* @irq: Interrupt line number
|
||||
* @cos_enb: Change-Of-State IRQ enable boundaries mask
|
||||
*/
|
||||
@ -49,7 +48,6 @@ struct idi_48_gpio {
|
||||
spinlock_t ack_lock;
|
||||
unsigned char irq_mask[6];
|
||||
unsigned base;
|
||||
unsigned extent;
|
||||
unsigned irq;
|
||||
unsigned char cos_enb;
|
||||
};
|
||||
@ -227,11 +225,10 @@ static int __init idi_48_probe(struct platform_device *pdev)
|
||||
if (!idi48gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!request_region(base, extent, name)) {
|
||||
dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n",
|
||||
name, base, base + extent);
|
||||
err = -EBUSY;
|
||||
goto err_lock_io_port;
|
||||
if (!devm_request_region(dev, base, extent, name)) {
|
||||
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
|
||||
base, base + extent);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
idi48gpio->chip.label = name;
|
||||
@ -243,7 +240,6 @@ static int __init idi_48_probe(struct platform_device *pdev)
|
||||
idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
|
||||
idi48gpio->chip.get = idi_48_gpio_get;
|
||||
idi48gpio->base = base;
|
||||
idi48gpio->extent = extent;
|
||||
idi48gpio->irq = irq;
|
||||
|
||||
spin_lock_init(&idi48gpio->lock);
|
||||
@ -253,7 +249,7 @@ static int __init idi_48_probe(struct platform_device *pdev)
|
||||
err = gpiochip_add_data(&idi48gpio->chip, idi48gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "GPIO registering failed (%d)\n", err);
|
||||
goto err_gpio_register;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Disable IRQ by default */
|
||||
@ -264,23 +260,20 @@ static int __init idi_48_probe(struct platform_device *pdev)
|
||||
handle_edge_irq, IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(dev, "Could not add irqchip (%d)\n", err);
|
||||
goto err_gpiochip_irqchip_add;
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
err = request_irq(irq, idi_48_irq_handler, 0, name, idi48gpio);
|
||||
err = request_irq(irq, idi_48_irq_handler, IRQF_SHARED, name,
|
||||
idi48gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
|
||||
goto err_request_irq;
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
err_gpiochip_irqchip_add:
|
||||
err_gpiochip_remove:
|
||||
gpiochip_remove(&idi48gpio->chip);
|
||||
err_gpio_register:
|
||||
release_region(base, extent);
|
||||
err_lock_io_port:
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -290,7 +283,6 @@ static int idi_48_remove(struct platform_device *pdev)
|
||||
|
||||
free_irq(idi48gpio->irq, idi48gpio);
|
||||
gpiochip_remove(&idi48gpio->chip);
|
||||
release_region(idi48gpio->base, idi48gpio->extent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -340,4 +332,4 @@ module_exit(idi_48_exit);
|
||||
|
||||
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
|
||||
MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -38,7 +38,6 @@ MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number");
|
||||
* @lock: synchronization lock to prevent I/O race conditions
|
||||
* @irq_mask: I/O bits affected by interrupts
|
||||
* @base: base port address of the GPIO device
|
||||
* @extent: extent of port address region of the GPIO device
|
||||
* @irq: Interrupt line number
|
||||
* @out_state: output bits state
|
||||
*/
|
||||
@ -47,7 +46,6 @@ struct idio_16_gpio {
|
||||
spinlock_t lock;
|
||||
unsigned long irq_mask;
|
||||
unsigned base;
|
||||
unsigned extent;
|
||||
unsigned irq;
|
||||
unsigned out_state;
|
||||
};
|
||||
@ -201,11 +199,10 @@ static int __init idio_16_probe(struct platform_device *pdev)
|
||||
if (!idio16gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!request_region(base, extent, name)) {
|
||||
dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n",
|
||||
name, base, base + extent);
|
||||
err = -EBUSY;
|
||||
goto err_lock_io_port;
|
||||
if (!devm_request_region(dev, base, extent, name)) {
|
||||
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
|
||||
base, base + extent);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
idio16gpio->chip.label = name;
|
||||
@ -219,7 +216,6 @@ static int __init idio_16_probe(struct platform_device *pdev)
|
||||
idio16gpio->chip.get = idio_16_gpio_get;
|
||||
idio16gpio->chip.set = idio_16_gpio_set;
|
||||
idio16gpio->base = base;
|
||||
idio16gpio->extent = extent;
|
||||
idio16gpio->irq = irq;
|
||||
idio16gpio->out_state = 0xFFFF;
|
||||
|
||||
@ -230,7 +226,7 @@ static int __init idio_16_probe(struct platform_device *pdev)
|
||||
err = gpiochip_add_data(&idio16gpio->chip, idio16gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "GPIO registering failed (%d)\n", err);
|
||||
goto err_gpio_register;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Disable IRQ by default */
|
||||
@ -241,23 +237,19 @@ static int __init idio_16_probe(struct platform_device *pdev)
|
||||
handle_edge_irq, IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(dev, "Could not add irqchip (%d)\n", err);
|
||||
goto err_gpiochip_irqchip_add;
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
|
||||
goto err_request_irq;
|
||||
goto err_gpiochip_remove;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
err_gpiochip_irqchip_add:
|
||||
err_gpiochip_remove:
|
||||
gpiochip_remove(&idio16gpio->chip);
|
||||
err_gpio_register:
|
||||
release_region(base, extent);
|
||||
err_lock_io_port:
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -267,7 +259,6 @@ static int idio_16_remove(struct platform_device *pdev)
|
||||
|
||||
free_irq(idio16gpio->irq, idio16gpio);
|
||||
gpiochip_remove(&idio16gpio->chip);
|
||||
release_region(idio16gpio->base, idio16gpio->extent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -317,4 +308,4 @@ module_exit(idio_16_exit);
|
||||
|
||||
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
|
||||
MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -140,15 +140,7 @@ static int mmio_74xx_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return gpiochip_add_data(&priv->gc, priv);
|
||||
}
|
||||
|
||||
static int mmio_74xx_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mmio_74xx_gpio_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&priv->gc);
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv);
|
||||
}
|
||||
|
||||
static struct platform_driver mmio_74xx_gpio_driver = {
|
||||
@ -157,7 +149,6 @@ static struct platform_driver mmio_74xx_gpio_driver = {
|
||||
.of_match_table = mmio_74xx_gpio_ids,
|
||||
},
|
||||
.probe = mmio_74xx_gpio_probe,
|
||||
.remove = mmio_74xx_gpio_remove,
|
||||
};
|
||||
module_platform_driver(mmio_74xx_gpio_driver);
|
||||
|
||||
|
@ -265,7 +265,7 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
|
||||
chip->of_node = chip->parent->of_node;
|
||||
chip->owner = THIS_MODULE;
|
||||
|
||||
err = gpiochip_add_data(chip, adnp);
|
||||
err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -520,14 +520,6 @@ static int adnp_i2c_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adnp_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct adnp *adnp = i2c_get_clientdata(client);
|
||||
|
||||
gpiochip_remove(&adnp->gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id adnp_i2c_id[] = {
|
||||
{ "gpio-adnp" },
|
||||
{ },
|
||||
@ -546,7 +538,6 @@ static struct i2c_driver adnp_i2c_driver = {
|
||||
.of_match_table = adnp_of_match,
|
||||
},
|
||||
.probe = adnp_i2c_probe,
|
||||
.remove = adnp_i2c_remove,
|
||||
.id_table = adnp_i2c_id,
|
||||
};
|
||||
module_i2c_driver(adnp_i2c_driver);
|
||||
|
@ -153,7 +153,7 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(&dev->gpio_chip, dev);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &dev->gpio_chip, dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -164,22 +164,11 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adp5520_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct adp5520_gpio *dev;
|
||||
|
||||
dev = platform_get_drvdata(pdev);
|
||||
gpiochip_remove(&dev->gpio_chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver adp5520_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "adp5520-gpio",
|
||||
},
|
||||
.probe = adp5520_gpio_probe,
|
||||
.remove = adp5520_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(adp5520_gpio_driver);
|
||||
|
@ -414,7 +414,7 @@ static int adp5588_gpio_probe(struct i2c_client *client,
|
||||
}
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(&dev->gpio_chip, dev);
|
||||
ret = devm_gpiochip_add_data(&client->dev, &dev->gpio_chip, dev);
|
||||
if (ret)
|
||||
goto err_irq;
|
||||
|
||||
@ -457,8 +457,6 @@ static int adp5588_gpio_remove(struct i2c_client *client)
|
||||
if (dev->irq_base)
|
||||
free_irq(dev->client->irq, dev);
|
||||
|
||||
gpiochip_remove(&dev->gpio_chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gpio.h>
|
||||
@ -204,7 +205,8 @@ found:
|
||||
gp.pmbase &= 0x0000FF00;
|
||||
if (gp.pmbase == 0)
|
||||
goto out;
|
||||
if (!request_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE, "AMD GPIO")) {
|
||||
if (!devm_request_region(&pdev->dev, gp.pmbase + PMBASE_OFFSET,
|
||||
PMBASE_SIZE, "AMD GPIO")) {
|
||||
dev_err(&pdev->dev, "AMD GPIO region 0x%x already in use!\n",
|
||||
gp.pmbase + PMBASE_OFFSET);
|
||||
err = -EBUSY;
|
||||
@ -213,7 +215,6 @@ found:
|
||||
gp.pm = ioport_map(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
if (!gp.pm) {
|
||||
dev_err(&pdev->dev, "Couldn't map io port into io memory\n");
|
||||
release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -228,7 +229,6 @@ found:
|
||||
printk(KERN_ERR "GPIO registering failed (%d)\n",
|
||||
err);
|
||||
ioport_unmap(gp.pm);
|
||||
release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
@ -239,7 +239,6 @@ static void __exit amd_gpio_exit(void)
|
||||
{
|
||||
gpiochip_remove(&gp.chip);
|
||||
ioport_unmap(gp.pm);
|
||||
release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
|
||||
}
|
||||
|
||||
module_init(amd_gpio_init);
|
||||
|
@ -132,7 +132,8 @@ static int arizona_gpio_probe(struct platform_device *pdev)
|
||||
else
|
||||
arizona_gpio->gpio_chip.base = -1;
|
||||
|
||||
ret = gpiochip_add_data(&arizona_gpio->gpio_chip, arizona_gpio);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &arizona_gpio->gpio_chip,
|
||||
arizona_gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
|
||||
ret);
|
||||
@ -147,18 +148,9 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&arizona_gpio->gpio_chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver arizona_gpio_driver = {
|
||||
.driver.name = "arizona-gpio",
|
||||
.probe = arizona_gpio_probe,
|
||||
.remove = arizona_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(arizona_gpio_driver);
|
||||
|
@ -1,12 +1,11 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X GPIO API support
|
||||
*
|
||||
* Copyright (C) 2015 Alban Bedel <albeu@free.fr>
|
||||
* Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
@ -15,119 +14,205 @@
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/platform_data/gpio-ath79.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mach-ath79/ar71xx_regs.h>
|
||||
#define AR71XX_GPIO_REG_OE 0x00
|
||||
#define AR71XX_GPIO_REG_IN 0x04
|
||||
#define AR71XX_GPIO_REG_SET 0x0c
|
||||
#define AR71XX_GPIO_REG_CLEAR 0x10
|
||||
|
||||
#define AR71XX_GPIO_REG_INT_ENABLE 0x14
|
||||
#define AR71XX_GPIO_REG_INT_TYPE 0x18
|
||||
#define AR71XX_GPIO_REG_INT_POLARITY 0x1c
|
||||
#define AR71XX_GPIO_REG_INT_PENDING 0x20
|
||||
#define AR71XX_GPIO_REG_INT_MASK 0x24
|
||||
|
||||
struct ath79_gpio_ctrl {
|
||||
struct gpio_chip chip;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *base;
|
||||
spinlock_t lock;
|
||||
unsigned long both_edges;
|
||||
};
|
||||
|
||||
static void ath79_gpio_set_value(struct gpio_chip *chip,
|
||||
unsigned gpio, int value)
|
||||
static struct ath79_gpio_ctrl *irq_data_to_ath79_gpio(struct irq_data *data)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
|
||||
|
||||
if (value)
|
||||
__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET);
|
||||
else
|
||||
__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR);
|
||||
return container_of(gc, struct ath79_gpio_ctrl, gc);
|
||||
}
|
||||
|
||||
static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
||||
static u32 ath79_gpio_read(struct ath79_gpio_ctrl *ctrl, unsigned reg)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
|
||||
return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
|
||||
return readl(ctrl->base + reg);
|
||||
}
|
||||
|
||||
static int ath79_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned offset)
|
||||
static void ath79_gpio_write(struct ath79_gpio_ctrl *ctrl,
|
||||
unsigned reg, u32 val)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
return writel(val, ctrl->base + reg);
|
||||
}
|
||||
|
||||
static bool ath79_gpio_update_bits(
|
||||
struct ath79_gpio_ctrl *ctrl, unsigned reg, u32 mask, u32 bits)
|
||||
{
|
||||
u32 old_val, new_val;
|
||||
|
||||
old_val = ath79_gpio_read(ctrl, reg);
|
||||
new_val = (old_val & ~mask) | (bits & mask);
|
||||
|
||||
if (new_val != old_val)
|
||||
ath79_gpio_write(ctrl, reg, new_val);
|
||||
|
||||
return new_val != old_val;
|
||||
}
|
||||
|
||||
static void ath79_gpio_irq_unmask(struct irq_data *data)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
|
||||
u32 mask = BIT(irqd_to_hwirq(data));
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
}
|
||||
|
||||
__raw_writel(
|
||||
__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
|
||||
ctrl->base + AR71XX_GPIO_REG_OE);
|
||||
static void ath79_gpio_irq_mask(struct irq_data *data)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
|
||||
u32 mask = BIT(irqd_to_hwirq(data));
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
}
|
||||
|
||||
static void ath79_gpio_irq_enable(struct irq_data *data)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
|
||||
u32 mask = BIT(irqd_to_hwirq(data));
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
}
|
||||
|
||||
static void ath79_gpio_irq_disable(struct irq_data *data)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
|
||||
u32 mask = BIT(irqd_to_hwirq(data));
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
}
|
||||
|
||||
static int ath79_gpio_irq_set_type(struct irq_data *data,
|
||||
unsigned int flow_type)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
|
||||
u32 mask = BIT(irqd_to_hwirq(data));
|
||||
u32 type = 0, polarity = 0;
|
||||
unsigned long flags;
|
||||
bool disabled;
|
||||
|
||||
switch (flow_type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
polarity |= mask;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
polarity |= mask;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
type |= mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
|
||||
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
|
||||
ctrl->both_edges |= mask;
|
||||
polarity = ~ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
|
||||
} else {
|
||||
ctrl->both_edges &= ~mask;
|
||||
}
|
||||
|
||||
/* As the IRQ configuration can't be loaded atomically we
|
||||
* have to disable the interrupt while the configuration state
|
||||
* is invalid.
|
||||
*/
|
||||
disabled = ath79_gpio_update_bits(
|
||||
ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
|
||||
|
||||
ath79_gpio_update_bits(
|
||||
ctrl, AR71XX_GPIO_REG_INT_TYPE, mask, type);
|
||||
ath79_gpio_update_bits(
|
||||
ctrl, AR71XX_GPIO_REG_INT_POLARITY, mask, polarity);
|
||||
|
||||
if (disabled)
|
||||
ath79_gpio_update_bits(
|
||||
ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
|
||||
if (value)
|
||||
__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
|
||||
else
|
||||
__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
|
||||
|
||||
__raw_writel(
|
||||
__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
|
||||
ctrl->base + AR71XX_GPIO_REG_OE);
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
|
||||
__raw_writel(
|
||||
__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
|
||||
ctrl->base + AR71XX_GPIO_REG_OE);
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
int value)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
|
||||
if (value)
|
||||
__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
|
||||
else
|
||||
__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
|
||||
|
||||
__raw_writel(
|
||||
__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
|
||||
ctrl->base + AR71XX_GPIO_REG_OE);
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct gpio_chip ath79_gpio_chip = {
|
||||
.label = "ath79",
|
||||
.get = ath79_gpio_get_value,
|
||||
.set = ath79_gpio_set_value,
|
||||
.direction_input = ath79_gpio_direction_input,
|
||||
.direction_output = ath79_gpio_direction_output,
|
||||
.base = 0,
|
||||
static struct irq_chip ath79_gpio_irqchip = {
|
||||
.name = "gpio-ath79",
|
||||
.irq_enable = ath79_gpio_irq_enable,
|
||||
.irq_disable = ath79_gpio_irq_disable,
|
||||
.irq_mask = ath79_gpio_irq_mask,
|
||||
.irq_unmask = ath79_gpio_irq_unmask,
|
||||
.irq_set_type = ath79_gpio_irq_set_type,
|
||||
};
|
||||
|
||||
static void ath79_gpio_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
||||
struct ath79_gpio_ctrl *ctrl =
|
||||
container_of(gc, struct ath79_gpio_ctrl, gc);
|
||||
unsigned long flags, pending;
|
||||
u32 both_edges, state;
|
||||
int irq;
|
||||
|
||||
chained_irq_enter(irqchip, desc);
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
|
||||
pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING);
|
||||
|
||||
/* Update the polarity of the both edges irqs */
|
||||
both_edges = ctrl->both_edges & pending;
|
||||
if (both_edges) {
|
||||
state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
|
||||
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY,
|
||||
both_edges, ~state);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
if (pending) {
|
||||
for_each_set_bit(irq, &pending, gc->ngpio)
|
||||
generic_handle_irq(
|
||||
irq_linear_revmap(gc->irqdomain, irq));
|
||||
}
|
||||
|
||||
chained_irq_exit(irqchip, desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id ath79_gpio_of_match[] = {
|
||||
{ .compatible = "qca,ar7100-gpio" },
|
||||
{ .compatible = "qca,ar9340-gpio" },
|
||||
@ -147,6 +232,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
|
||||
if (!ctrl)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, ctrl);
|
||||
|
||||
if (np) {
|
||||
err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
|
||||
@ -154,10 +240,6 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev, "ngpios property is not valid\n");
|
||||
return err;
|
||||
}
|
||||
if (ath79_gpio_count >= 32) {
|
||||
dev_err(&pdev->dev, "ngpios must be less than 32\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
|
||||
} else if (pdata) {
|
||||
ath79_gpio_count = pdata->ngpios;
|
||||
@ -167,6 +249,11 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ath79_gpio_count >= 32) {
|
||||
dev_err(&pdev->dev, "ngpios must be less than 32\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ctrl->base = devm_ioremap_nocache(
|
||||
&pdev->dev, res->start, resource_size(res));
|
||||
@ -174,21 +261,53 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&ctrl->lock);
|
||||
memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip));
|
||||
ctrl->chip.parent = &pdev->dev;
|
||||
ctrl->chip.ngpio = ath79_gpio_count;
|
||||
if (oe_inverted) {
|
||||
ctrl->chip.direction_input = ar934x_gpio_direction_input;
|
||||
ctrl->chip.direction_output = ar934x_gpio_direction_output;
|
||||
err = bgpio_init(&ctrl->gc, &pdev->dev, 4,
|
||||
ctrl->base + AR71XX_GPIO_REG_IN,
|
||||
ctrl->base + AR71XX_GPIO_REG_SET,
|
||||
ctrl->base + AR71XX_GPIO_REG_CLEAR,
|
||||
oe_inverted ? NULL : ctrl->base + AR71XX_GPIO_REG_OE,
|
||||
oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL,
|
||||
0);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "bgpio_init failed\n");
|
||||
return err;
|
||||
}
|
||||
/* Use base 0 to stay compatible with legacy platforms */
|
||||
ctrl->gc.base = 0;
|
||||
|
||||
err = gpiochip_add_data(&ctrl->chip, ctrl);
|
||||
err = gpiochip_add_data(&ctrl->gc, ctrl);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"cannot add AR71xx GPIO chip, error=%d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (np && !of_property_read_bool(np, "interrupt-controller"))
|
||||
return 0;
|
||||
|
||||
err = gpiochip_irqchip_add(&ctrl->gc, &ath79_gpio_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
|
||||
goto gpiochip_remove;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&ctrl->gc, &ath79_gpio_irqchip,
|
||||
platform_get_irq(pdev, 0),
|
||||
ath79_gpio_irq_handler);
|
||||
|
||||
return 0;
|
||||
|
||||
gpiochip_remove:
|
||||
gpiochip_remove(&ctrl->gc);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ath79_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&ctrl->gc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -198,6 +317,7 @@ static struct platform_driver ath79_gpio_driver = {
|
||||
.of_match_table = ath79_gpio_of_match,
|
||||
},
|
||||
.probe = ath79_gpio_probe,
|
||||
.remove = ath79_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ath79_gpio_driver);
|
||||
|
@ -630,7 +630,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
bcm_kona_gpio_reset(kona_gpio);
|
||||
|
||||
ret = gpiochip_add_data(chip, kona_gpio);
|
||||
ret = devm_gpiochip_add_data(dev, chip, kona_gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret);
|
||||
goto err_irq_domain;
|
||||
|
@ -233,17 +233,14 @@ static void brcmstb_gpio_irq_handler(struct irq_desc *desc)
|
||||
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
struct brcmstb_gpio_priv *priv = brcmstb_gpio_gc_to_priv(gc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct list_head *pos;
|
||||
struct brcmstb_gpio_bank *bank;
|
||||
|
||||
/* Interrupts weren't properly cleared during probe */
|
||||
BUG_ON(!priv || !chip);
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
list_for_each(pos, &priv->bank_list) {
|
||||
struct brcmstb_gpio_bank *bank =
|
||||
list_entry(pos, struct brcmstb_gpio_bank, node);
|
||||
list_for_each_entry(bank, &priv->bank_list, node)
|
||||
brcmstb_gpio_irq_bank_handler(bank);
|
||||
}
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
@ -280,7 +277,6 @@ static int brcmstb_gpio_sanity_check_banks(struct device *dev,
|
||||
static int brcmstb_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct brcmstb_gpio_priv *priv = platform_get_drvdata(pdev);
|
||||
struct list_head *pos;
|
||||
struct brcmstb_gpio_bank *bank;
|
||||
int ret = 0;
|
||||
|
||||
@ -293,10 +289,9 @@ static int brcmstb_gpio_remove(struct platform_device *pdev)
|
||||
* You can lose return values below, but we report all errors, and it's
|
||||
* more important to actually perform all of the steps.
|
||||
*/
|
||||
list_for_each(pos, &priv->bank_list) {
|
||||
bank = list_entry(pos, struct brcmstb_gpio_bank, node);
|
||||
list_for_each_entry(bank, &priv->bank_list, node)
|
||||
gpiochip_remove(&bank->gc);
|
||||
}
|
||||
|
||||
if (priv->reboot_notifier.notifier_call) {
|
||||
ret = unregister_reboot_notifier(&priv->reboot_notifier);
|
||||
if (ret)
|
||||
|
@ -67,15 +67,7 @@ static int clps711x_gpio_probe(struct platform_device *pdev)
|
||||
gc->owner = THIS_MODULE;
|
||||
platform_set_drvdata(pdev, gc);
|
||||
|
||||
return gpiochip_add_data(gc, NULL);
|
||||
}
|
||||
|
||||
static int clps711x_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_chip *gc = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(gc);
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&pdev->dev, gc, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = {
|
||||
@ -90,7 +82,6 @@ static struct platform_driver clps711x_gpio_driver = {
|
||||
.of_match_table = of_match_ptr(clps711x_gpio_ids),
|
||||
},
|
||||
.probe = clps711x_gpio_probe,
|
||||
.remove = clps711x_gpio_remove,
|
||||
};
|
||||
module_platform_driver(clps711x_gpio_driver);
|
||||
|
||||
|
@ -345,7 +345,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
|
||||
cg->chip.dbg_show = crystalcove_gpio_dbg_show;
|
||||
cg->regmap = pmic->regmap;
|
||||
|
||||
retval = gpiochip_add_data(&cg->chip, cg);
|
||||
retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg);
|
||||
if (retval) {
|
||||
dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval);
|
||||
return retval;
|
||||
@ -359,14 +359,10 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
if (retval) {
|
||||
dev_warn(&pdev->dev, "request irq failed: %d\n", retval);
|
||||
goto out_remove_gpio;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_remove_gpio:
|
||||
gpiochip_remove(&cg->chip);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int crystalcove_gpio_remove(struct platform_device *pdev)
|
||||
@ -374,7 +370,6 @@ static int crystalcove_gpio_remove(struct platform_device *pdev)
|
||||
struct crystalcove_gpio *cg = platform_get_drvdata(pdev);
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
gpiochip_remove(&cg->chip);
|
||||
if (irq >= 0)
|
||||
free_irq(irq, cg);
|
||||
return 0;
|
||||
|
@ -320,13 +320,13 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "can't fetch device resource info\n");
|
||||
goto done;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
|
||||
pdev->name)) {
|
||||
dev_err(&pdev->dev, "can't request region\n");
|
||||
goto done;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* set up the driver-specific struct */
|
||||
@ -348,19 +348,10 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
|
||||
mask_orig, mask);
|
||||
|
||||
/* finally, register with the generic GPIO API */
|
||||
err = gpiochip_add_data(&cs5535_gpio_chip.chip, &cs5535_gpio_chip);
|
||||
err = devm_gpiochip_add_data(&pdev->dev, &cs5535_gpio_chip.chip,
|
||||
&cs5535_gpio_chip);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
return 0;
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cs5535_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
gpiochip_remove(&cs5535_gpio_chip.chip);
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -370,7 +361,6 @@ static struct platform_driver cs5535_gpio_driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
.probe = cs5535_gpio_probe,
|
||||
.remove = cs5535_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cs5535_gpio_driver);
|
||||
|
@ -214,7 +214,7 @@ static int da9052_gpio_probe(struct platform_device *pdev)
|
||||
if (pdata && pdata->gpio_base)
|
||||
gpio->gp.base = pdata->gpio_base;
|
||||
|
||||
ret = gpiochip_add_data(&gpio->gp, gpio);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
|
||||
return ret;
|
||||
@ -225,17 +225,8 @@ static int da9052_gpio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9052_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct da9052_gpio *gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&gpio->gp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver da9052_gpio_driver = {
|
||||
.probe = da9052_gpio_probe,
|
||||
.remove = da9052_gpio_remove,
|
||||
.driver = {
|
||||
.name = "da9052-gpio",
|
||||
},
|
||||
|
@ -151,31 +151,19 @@ static int da9055_gpio_probe(struct platform_device *pdev)
|
||||
if (pdata && pdata->gpio_base)
|
||||
gpio->gp.base = pdata->gpio_base;
|
||||
|
||||
ret = gpiochip_add_data(&gpio->gp, gpio);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
|
||||
goto err_mem;
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, gpio);
|
||||
|
||||
return 0;
|
||||
|
||||
err_mem:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9055_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct da9055_gpio *gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&gpio->gp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver da9055_gpio_driver = {
|
||||
.probe = da9055_gpio_probe,
|
||||
.remove = da9055_gpio_remove,
|
||||
.driver = {
|
||||
.name = "da9055-gpio",
|
||||
},
|
||||
|
@ -258,6 +258,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&chips[i].lock);
|
||||
|
||||
regs = gpio2regs(base);
|
||||
if (!regs)
|
||||
return -ENXIO;
|
||||
chips[i].regs = regs;
|
||||
chips[i].set_data = ®s->set_data;
|
||||
chips[i].clr_data = ®s->clr_data;
|
||||
@ -433,8 +435,7 @@ static struct irq_chip *davinci_gpio_get_irq_chip(unsigned int irq)
|
||||
{
|
||||
static struct irq_chip_type gpio_unbanked;
|
||||
|
||||
gpio_unbanked = *container_of(irq_get_chip(irq),
|
||||
struct irq_chip_type, chip);
|
||||
gpio_unbanked = *irq_data_get_chip_type(irq_get_irq_data(irq));
|
||||
|
||||
return &gpio_unbanked.chip;
|
||||
};
|
||||
|
@ -479,40 +479,32 @@ static int dln2_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, dln2);
|
||||
|
||||
ret = gpiochip_add_data(&dln2->gpio, dln2);
|
||||
ret = devm_gpiochip_add_data(dev, &dln2->gpio, dln2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to add gpio chip: %d\n", ret);
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpiochip_irqchip_add(&dln2->gpio, &dln2_gpio_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to add irq chip: %d\n", ret);
|
||||
goto out_gpiochip_remove;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV,
|
||||
dln2_gpio_event);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register event cb: %d\n", ret);
|
||||
goto out_gpiochip_remove;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_gpiochip_remove:
|
||||
gpiochip_remove(&dln2->gpio);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dln2_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dln2_gpio *dln2 = platform_get_drvdata(pdev);
|
||||
|
||||
dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);
|
||||
gpiochip_remove(&dln2->gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
|
||||
gc->to_irq = ep93xx_gpio_to_irq;
|
||||
}
|
||||
|
||||
return gpiochip_add_data(gc, NULL);
|
||||
return devm_gpiochip_add_data(dev, gc, NULL);
|
||||
}
|
||||
|
||||
static int ep93xx_gpio_probe(struct platform_device *pdev)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* GPIO driver for Fintek Super-I/O F71869, F71869A, F71882 and F71889
|
||||
* GPIO driver for Fintek Super-I/O F71869, F71869A, F71882, F71889 and F81866
|
||||
*
|
||||
* Copyright (C) 2010-2013 LaCie
|
||||
*
|
||||
@ -36,14 +36,16 @@
|
||||
#define SIO_F71869A_ID 0x1007 /* F71869A chipset ID */
|
||||
#define SIO_F71882_ID 0x0541 /* F71882 chipset ID */
|
||||
#define SIO_F71889_ID 0x0909 /* F71889 chipset ID */
|
||||
#define SIO_F81866_ID 0x1010 /* F81866 chipset ID */
|
||||
|
||||
enum chips { f71869, f71869a, f71882fg, f71889f };
|
||||
enum chips { f71869, f71869a, f71882fg, f71889f, f81866 };
|
||||
|
||||
static const char * const f7188x_names[] = {
|
||||
"f71869",
|
||||
"f71869a",
|
||||
"f71882fg",
|
||||
"f71889f",
|
||||
"f81866",
|
||||
};
|
||||
|
||||
struct f7188x_sio {
|
||||
@ -190,6 +192,18 @@ static struct f7188x_gpio_bank f71889_gpio_bank[] = {
|
||||
F7188X_GPIO_BANK(70, 8, 0x80),
|
||||
};
|
||||
|
||||
static struct f7188x_gpio_bank f81866_gpio_bank[] = {
|
||||
F7188X_GPIO_BANK(0, 8, 0xF0),
|
||||
F7188X_GPIO_BANK(10, 8, 0xE0),
|
||||
F7188X_GPIO_BANK(20, 8, 0xD0),
|
||||
F7188X_GPIO_BANK(30, 8, 0xC0),
|
||||
F7188X_GPIO_BANK(40, 8, 0xB0),
|
||||
F7188X_GPIO_BANK(50, 8, 0xA0),
|
||||
F7188X_GPIO_BANK(60, 8, 0x90),
|
||||
F7188X_GPIO_BANK(70, 8, 0x80),
|
||||
F7188X_GPIO_BANK(80, 8, 0x88),
|
||||
};
|
||||
|
||||
static int f7188x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
int err;
|
||||
@ -318,6 +332,10 @@ static int f7188x_gpio_probe(struct platform_device *pdev)
|
||||
data->nr_bank = ARRAY_SIZE(f71889_gpio_bank);
|
||||
data->bank = f71889_gpio_bank;
|
||||
break;
|
||||
case f81866:
|
||||
data->nr_bank = ARRAY_SIZE(f81866_gpio_bank);
|
||||
data->bank = f81866_gpio_bank;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
@ -332,36 +350,15 @@ static int f7188x_gpio_probe(struct platform_device *pdev)
|
||||
bank->chip.parent = &pdev->dev;
|
||||
bank->data = data;
|
||||
|
||||
err = gpiochip_add_data(&bank->chip, bank);
|
||||
err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to register gpiochip %d: %d\n",
|
||||
i, err);
|
||||
goto err_gpiochip;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_gpiochip:
|
||||
for (i = i - 1; i >= 0; i--) {
|
||||
struct f7188x_gpio_bank *bank = &data->bank[i];
|
||||
gpiochip_remove(&bank->chip);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int f7188x_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
struct f7188x_gpio_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
for (i = 0; i < data->nr_bank; i++) {
|
||||
struct f7188x_gpio_bank *bank = &data->bank[i];
|
||||
gpiochip_remove(&bank->chip);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -395,6 +392,9 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio)
|
||||
case SIO_F71889_ID:
|
||||
sio->type = f71889f;
|
||||
break;
|
||||
case SIO_F81866_ID:
|
||||
sio->type = f81866;
|
||||
break;
|
||||
default:
|
||||
pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid);
|
||||
goto err;
|
||||
@ -455,7 +455,6 @@ static struct platform_driver f7188x_gpio_driver = {
|
||||
.name = DRVNAME,
|
||||
},
|
||||
.probe = f7188x_gpio_probe,
|
||||
.remove = f7188x_gpio_remove,
|
||||
};
|
||||
|
||||
static int __init f7188x_gpio_init(void)
|
||||
@ -485,6 +484,6 @@ static void __exit f7188x_gpio_exit(void)
|
||||
}
|
||||
module_exit(f7188x_gpio_exit);
|
||||
|
||||
MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG and F71889F");
|
||||
MODULE_DESCRIPTION("GPIO driver for Super-I/O chips F71869, F71869A, F71882FG, F71889F and F81866");
|
||||
MODULE_AUTHOR("Simon Guinot <simon.guinot@sequanux.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -89,7 +89,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev)
|
||||
gc->of_node = pdev->dev.of_node;
|
||||
|
||||
/* This function adds a memory mapped GPIO chip */
|
||||
ret = gpiochip_add_data(gc, NULL);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL);
|
||||
if (ret)
|
||||
goto err0;
|
||||
|
||||
|
@ -628,15 +628,7 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, gc);
|
||||
|
||||
return gpiochip_add_data(gc, NULL);
|
||||
}
|
||||
|
||||
static int bgpio_pdev_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_chip *gc = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(gc);
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&pdev->dev, gc, NULL);
|
||||
}
|
||||
|
||||
static const struct platform_device_id bgpio_id_table[] = {
|
||||
@ -657,7 +649,6 @@ static struct platform_driver bgpio_driver = {
|
||||
},
|
||||
.id_table = bgpio_id_table,
|
||||
.probe = bgpio_pdev_probe,
|
||||
.remove = bgpio_pdev_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bgpio_driver);
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/gpio.h>
|
||||
@ -384,8 +385,8 @@ static struct ichx_desc avoton_desc = {
|
||||
.use_outlvl_cache = true,
|
||||
};
|
||||
|
||||
static int ichx_gpio_request_regions(struct resource *res_base,
|
||||
const char *name, u8 use_gpio)
|
||||
static int ichx_gpio_request_regions(struct device *dev,
|
||||
struct resource *res_base, const char *name, u8 use_gpio)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -395,34 +396,12 @@ static int ichx_gpio_request_regions(struct resource *res_base,
|
||||
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
|
||||
if (!(use_gpio & (1 << i)))
|
||||
continue;
|
||||
if (!request_region(
|
||||
if (!devm_request_region(dev,
|
||||
res_base->start + ichx_priv.desc->regs[0][i],
|
||||
ichx_priv.desc->reglen[i], name))
|
||||
goto request_err;
|
||||
return -EBUSY;
|
||||
}
|
||||
return 0;
|
||||
|
||||
request_err:
|
||||
/* Clean up: release already requested regions, if any */
|
||||
for (i--; i >= 0; i--) {
|
||||
if (!(use_gpio & (1 << i)))
|
||||
continue;
|
||||
release_region(res_base->start + ichx_priv.desc->regs[0][i],
|
||||
ichx_priv.desc->reglen[i]);
|
||||
}
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
|
||||
if (!(use_gpio & (1 << i)))
|
||||
continue;
|
||||
release_region(res_base->start + ichx_priv.desc->regs[0][i],
|
||||
ichx_priv.desc->reglen[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int ichx_gpio_probe(struct platform_device *pdev)
|
||||
@ -468,7 +447,7 @@ static int ichx_gpio_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&ichx_priv.lock);
|
||||
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
|
||||
ichx_priv.use_gpio = ich_info->use_gpio;
|
||||
err = ichx_gpio_request_regions(res_base, pdev->name,
|
||||
err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name,
|
||||
ichx_priv.use_gpio);
|
||||
if (err)
|
||||
return err;
|
||||
@ -489,8 +468,8 @@ static int ichx_gpio_probe(struct platform_device *pdev)
|
||||
goto init;
|
||||
}
|
||||
|
||||
if (!request_region(res_pm->start, resource_size(res_pm),
|
||||
pdev->name)) {
|
||||
if (!devm_request_region(&pdev->dev, res_pm->start,
|
||||
resource_size(res_pm), pdev->name)) {
|
||||
pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
|
||||
goto init;
|
||||
}
|
||||
@ -502,31 +481,19 @@ init:
|
||||
err = gpiochip_add_data(&ichx_priv.chip, NULL);
|
||||
if (err) {
|
||||
pr_err("Failed to register GPIOs\n");
|
||||
goto add_err;
|
||||
return err;
|
||||
}
|
||||
|
||||
pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
|
||||
ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
|
||||
|
||||
return 0;
|
||||
|
||||
add_err:
|
||||
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
|
||||
if (ichx_priv.pm_base)
|
||||
release_region(ichx_priv.pm_base->start,
|
||||
resource_size(ichx_priv.pm_base));
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ichx_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
gpiochip_remove(&ichx_priv.chip);
|
||||
|
||||
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
|
||||
if (ichx_priv.pm_base)
|
||||
release_region(ichx_priv.pm_base->start,
|
||||
resource_size(ichx_priv.pm_base));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ static int iop3xx_gpio_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
return gpiochip_add_data(&iop3xx_chip, NULL);
|
||||
return devm_gpiochip_add_data(&pdev->dev, &iop3xx_chip, NULL);
|
||||
}
|
||||
|
||||
static struct platform_driver iop3xx_gpio_driver = {
|
||||
|
@ -182,7 +182,7 @@ static int ttl_probe(struct platform_device *pdev)
|
||||
gpio->base = -1;
|
||||
gpio->ngpio = 20;
|
||||
|
||||
ret = gpiochip_add_data(gpio, NULL);
|
||||
ret = devm_gpiochip_add_data(dev, gpio, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to add GPIO chip\n");
|
||||
return ret;
|
||||
@ -191,21 +191,11 @@ static int ttl_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ttl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ttl_module *mod = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&mod->gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ttl_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
.probe = ttl_probe,
|
||||
.remove = ttl_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ttl_driver);
|
||||
|
@ -178,7 +178,7 @@ static int kempld_gpio_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(chip, gpio);
|
||||
ret = devm_gpiochip_add_data(dev, chip, gpio);
|
||||
if (ret) {
|
||||
dev_err(dev, "Could not register GPIO chip\n");
|
||||
return ret;
|
||||
@ -190,20 +190,11 @@ static int kempld_gpio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kempld_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct kempld_gpio_data *gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&gpio->chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver kempld_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "kempld-gpio",
|
||||
},
|
||||
.probe = kempld_gpio_probe,
|
||||
.remove = kempld_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(kempld_gpio_driver);
|
||||
|
@ -205,18 +205,6 @@ static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin)
|
||||
return gpio_irq[pin];
|
||||
}
|
||||
|
||||
/*
|
||||
* Map IRQ number to GPIO line.
|
||||
*/
|
||||
int irq_to_gpio(unsigned int irq)
|
||||
{
|
||||
if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
|
||||
return -EINVAL;
|
||||
|
||||
return (irq - KS8695_IRQ_EXTERN0);
|
||||
}
|
||||
EXPORT_SYMBOL(irq_to_gpio);
|
||||
|
||||
/* GPIOLIB interface */
|
||||
|
||||
static struct gpio_chip ks8695_gpio_chip = {
|
||||
|
@ -204,15 +204,8 @@ static int lp3943_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, lp3943_gpio);
|
||||
|
||||
return gpiochip_add_data(&lp3943_gpio->chip, lp3943_gpio);
|
||||
}
|
||||
|
||||
static int lp3943_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct lp3943_gpio *lp3943_gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&lp3943_gpio->chip);
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&pdev->dev, &lp3943_gpio->chip,
|
||||
lp3943_gpio);
|
||||
}
|
||||
|
||||
static const struct of_device_id lp3943_gpio_of_match[] = {
|
||||
@ -223,7 +216,6 @@ MODULE_DEVICE_TABLE(of, lp3943_gpio_of_match);
|
||||
|
||||
static struct platform_driver lp3943_gpio_driver = {
|
||||
.probe = lp3943_gpio_probe,
|
||||
.remove = lp3943_gpio_remove,
|
||||
.driver = {
|
||||
.name = "lp3943-gpio",
|
||||
.of_match_table = lp3943_gpio_of_match,
|
||||
|
@ -547,7 +547,7 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev)
|
||||
lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3;
|
||||
lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node;
|
||||
}
|
||||
gpiochip_add_data(&lpc32xx_gpiochip[i].chip,
|
||||
devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip,
|
||||
&lpc32xx_gpiochip[i]);
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
|
||||
gc->can_sleep = false;
|
||||
gc->parent = dev;
|
||||
|
||||
ret = gpiochip_add_data(gc, lg);
|
||||
ret = devm_gpiochip_add_data(dev, gc, lg);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed adding lp-gpio chip\n");
|
||||
return ret;
|
||||
@ -439,9 +439,7 @@ MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
|
||||
|
||||
static int lp_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct lp_gpio *lg = platform_get_drvdata(pdev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
gpiochip_remove(&lg->chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -103,17 +103,7 @@ static int mc9s08dz60_probe(struct i2c_client *client,
|
||||
mc9s->client = client;
|
||||
i2c_set_clientdata(client, mc9s);
|
||||
|
||||
return gpiochip_add_data(&mc9s->chip, mc9s);
|
||||
}
|
||||
|
||||
static int mc9s08dz60_remove(struct i2c_client *client)
|
||||
{
|
||||
struct mc9s08dz60 *mc9s;
|
||||
|
||||
mc9s = i2c_get_clientdata(client);
|
||||
|
||||
gpiochip_remove(&mc9s->chip);
|
||||
return 0;
|
||||
return devm_gpiochip_add_data(&client->dev, &mc9s->chip, mc9s);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mc9s08dz60_id[] = {
|
||||
@ -128,7 +118,6 @@ static struct i2c_driver mc9s08dz60_i2c_driver = {
|
||||
.name = "mc9s08dz60",
|
||||
},
|
||||
.probe = mc9s08dz60_probe,
|
||||
.remove = mc9s08dz60_remove,
|
||||
.id_table = mc9s08dz60_id,
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#define MCP_TYPE_S17 1
|
||||
#define MCP_TYPE_008 2
|
||||
#define MCP_TYPE_017 3
|
||||
#define MCP_TYPE_S18 4
|
||||
|
||||
/* Registers are all 8 bits wide.
|
||||
*
|
||||
@ -48,6 +49,7 @@
|
||||
# define IOCON_HAEN (1 << 3)
|
||||
# define IOCON_ODR (1 << 2)
|
||||
# define IOCON_INTPOL (1 << 1)
|
||||
# define IOCON_INTCC (1)
|
||||
#define MCP_GPPU 0x06
|
||||
#define MCP_INTF 0x07
|
||||
#define MCP_INTCAP 0x08
|
||||
@ -617,6 +619,12 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
mcp->chip.ngpio = 16;
|
||||
mcp->chip.label = "mcp23s17";
|
||||
break;
|
||||
|
||||
case MCP_TYPE_S18:
|
||||
mcp->ops = &mcp23s17_ops;
|
||||
mcp->chip.ngpio = 16;
|
||||
mcp->chip.label = "mcp23s18";
|
||||
break;
|
||||
#endif /* CONFIG_SPI_MASTER */
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
@ -657,8 +665,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
of_property_read_bool(mcp->chip.parent->of_node,
|
||||
"microchip,irq-active-high");
|
||||
|
||||
if (type == MCP_TYPE_017)
|
||||
mirror = pdata->mirror;
|
||||
mirror = pdata->mirror;
|
||||
}
|
||||
|
||||
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror ||
|
||||
@ -674,6 +681,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
if (mirror)
|
||||
status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
|
||||
|
||||
if (type == MCP_TYPE_S18)
|
||||
status |= IOCON_INTCC | (IOCON_INTCC << 8);
|
||||
|
||||
status = mcp->ops->write(mcp, MCP_IOCON, status);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
@ -735,6 +745,10 @@ static const struct of_device_id mcp23s08_spi_of_match[] = {
|
||||
.compatible = "microchip,mcp23s17",
|
||||
.data = (void *) MCP_TYPE_S17,
|
||||
},
|
||||
{
|
||||
.compatible = "microchip,mcp23s18",
|
||||
.data = (void *) MCP_TYPE_S18,
|
||||
},
|
||||
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
|
||||
{
|
||||
.compatible = "mcp,mcp23s08",
|
||||
@ -803,6 +817,8 @@ static int mcp230xx_probe(struct i2c_client *client,
|
||||
pdata = devm_kzalloc(&client->dev,
|
||||
sizeof(struct mcp23s08_platform_data),
|
||||
GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
pdata->base = -1;
|
||||
}
|
||||
}
|
||||
@ -969,8 +985,8 @@ static int mcp23s08_probe(struct spi_device *spi)
|
||||
goto fail;
|
||||
|
||||
if (pdata->base != -1)
|
||||
pdata->base += (type == MCP_TYPE_S17) ? 16 : 8;
|
||||
ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
|
||||
pdata->base += data->mcp[addr]->chip.ngpio;
|
||||
ngpio += data->mcp[addr]->chip.ngpio;
|
||||
}
|
||||
data->ngpio = ngpio;
|
||||
|
||||
@ -1012,6 +1028,7 @@ static int mcp23s08_remove(struct spi_device *spi)
|
||||
static const struct spi_device_id mcp23s08_ids[] = {
|
||||
{ "mcp23s08", MCP_TYPE_S08 },
|
||||
{ "mcp23s17", MCP_TYPE_S17 },
|
||||
{ "mcp23s18", MCP_TYPE_S18 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
|
||||
|
200
drivers/gpio/gpio-menz127.c
Normal file
200
drivers/gpio/gpio-menz127.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* MEN 16Z127 GPIO driver
|
||||
*
|
||||
* Copyright (C) 2016 MEN Mikroelektronik GmbH (www.men.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mcb.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#define MEN_Z127_CTRL 0x00
|
||||
#define MEN_Z127_PSR 0x04
|
||||
#define MEN_Z127_IRQR 0x08
|
||||
#define MEN_Z127_GPIODR 0x0c
|
||||
#define MEN_Z127_IER1 0x10
|
||||
#define MEN_Z127_IER2 0x14
|
||||
#define MEN_Z127_DBER 0x18
|
||||
#define MEN_Z127_ODER 0x1C
|
||||
#define GPIO_TO_DBCNT_REG(gpio) ((gpio * 4) + 0x80)
|
||||
|
||||
#define MEN_Z127_DB_MIN_US 50
|
||||
/* 16 bit compare register. Each bit represents 50us */
|
||||
#define MEN_Z127_DB_MAX_US (0xffff * MEN_Z127_DB_MIN_US)
|
||||
#define MEN_Z127_DB_IN_RANGE(db) ((db >= MEN_Z127_DB_MIN_US) && \
|
||||
(db <= MEN_Z127_DB_MAX_US))
|
||||
|
||||
struct men_z127_gpio {
|
||||
struct gpio_chip gc;
|
||||
void __iomem *reg_base;
|
||||
struct mcb_device *mdev;
|
||||
struct resource *mem;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
|
||||
unsigned debounce)
|
||||
{
|
||||
struct men_z127_gpio *priv = gpiochip_get_data(gc);
|
||||
struct device *dev = &priv->mdev->dev;
|
||||
unsigned int rnd;
|
||||
u32 db_en, db_cnt;
|
||||
|
||||
if (!MEN_Z127_DB_IN_RANGE(debounce)) {
|
||||
dev_err(dev, "debounce value %u out of range", debounce);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (debounce > 0) {
|
||||
/* round up or down depending on MSB-1 */
|
||||
rnd = fls(debounce) - 1;
|
||||
|
||||
if (rnd && (debounce & BIT(rnd - 1)))
|
||||
debounce = round_up(debounce, MEN_Z127_DB_MIN_US);
|
||||
else
|
||||
debounce = round_down(debounce, MEN_Z127_DB_MIN_US);
|
||||
|
||||
if (debounce > MEN_Z127_DB_MAX_US)
|
||||
debounce = MEN_Z127_DB_MAX_US;
|
||||
|
||||
/* 50us per register unit */
|
||||
debounce /= 50;
|
||||
}
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
db_en = readl(priv->reg_base + MEN_Z127_DBER);
|
||||
|
||||
if (debounce == 0) {
|
||||
db_en &= ~BIT(gpio);
|
||||
db_cnt = 0;
|
||||
} else {
|
||||
db_en |= BIT(gpio);
|
||||
db_cnt = debounce;
|
||||
}
|
||||
|
||||
writel(db_en, priv->reg_base + MEN_Z127_DBER);
|
||||
writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
|
||||
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int men_z127_request(struct gpio_chip *gc, unsigned gpio_pin)
|
||||
{
|
||||
struct men_z127_gpio *priv = gpiochip_get_data(gc);
|
||||
u32 od_en;
|
||||
|
||||
if (gpio_pin >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&priv->lock);
|
||||
od_en = readl(priv->reg_base + MEN_Z127_ODER);
|
||||
|
||||
if (gpiochip_line_is_open_drain(gc, gpio_pin))
|
||||
od_en |= BIT(gpio_pin);
|
||||
else
|
||||
od_en &= ~BIT(gpio_pin);
|
||||
|
||||
writel(od_en, priv->reg_base + MEN_Z127_ODER);
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int men_z127_probe(struct mcb_device *mdev,
|
||||
const struct mcb_device_id *id)
|
||||
{
|
||||
struct men_z127_gpio *men_z127_gpio;
|
||||
struct device *dev = &mdev->dev;
|
||||
int ret;
|
||||
|
||||
men_z127_gpio = devm_kzalloc(dev, sizeof(struct men_z127_gpio),
|
||||
GFP_KERNEL);
|
||||
if (!men_z127_gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
men_z127_gpio->mem = mcb_request_mem(mdev, dev_name(dev));
|
||||
if (IS_ERR(men_z127_gpio->mem)) {
|
||||
dev_err(dev, "failed to request device memory");
|
||||
return PTR_ERR(men_z127_gpio->mem);
|
||||
}
|
||||
|
||||
men_z127_gpio->reg_base = ioremap(men_z127_gpio->mem->start,
|
||||
resource_size(men_z127_gpio->mem));
|
||||
if (men_z127_gpio->reg_base == NULL) {
|
||||
ret = -ENXIO;
|
||||
goto err_release;
|
||||
}
|
||||
|
||||
men_z127_gpio->mdev = mdev;
|
||||
mcb_set_drvdata(mdev, men_z127_gpio);
|
||||
|
||||
ret = bgpio_init(&men_z127_gpio->gc, &mdev->dev, 4,
|
||||
men_z127_gpio->reg_base + MEN_Z127_PSR,
|
||||
men_z127_gpio->reg_base + MEN_Z127_CTRL,
|
||||
NULL,
|
||||
men_z127_gpio->reg_base + MEN_Z127_GPIODR,
|
||||
NULL, 0);
|
||||
if (ret)
|
||||
goto err_unmap;
|
||||
|
||||
men_z127_gpio->gc.set_debounce = men_z127_debounce;
|
||||
men_z127_gpio->gc.request = men_z127_request;
|
||||
|
||||
ret = gpiochip_add_data(&men_z127_gpio->gc, men_z127_gpio);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register MEN 16Z127 GPIO controller");
|
||||
goto err_unmap;
|
||||
}
|
||||
|
||||
dev_info(dev, "MEN 16Z127 GPIO driver registered");
|
||||
|
||||
return 0;
|
||||
|
||||
err_unmap:
|
||||
iounmap(men_z127_gpio->reg_base);
|
||||
err_release:
|
||||
mcb_release_mem(men_z127_gpio->mem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void men_z127_remove(struct mcb_device *mdev)
|
||||
{
|
||||
struct men_z127_gpio *men_z127_gpio = mcb_get_drvdata(mdev);
|
||||
|
||||
gpiochip_remove(&men_z127_gpio->gc);
|
||||
iounmap(men_z127_gpio->reg_base);
|
||||
mcb_release_mem(men_z127_gpio->mem);
|
||||
}
|
||||
|
||||
static const struct mcb_device_id men_z127_ids[] = {
|
||||
{ .device = 0x7f },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(mcb, men_z127_ids);
|
||||
|
||||
static struct mcb_driver men_z127_driver = {
|
||||
.driver = {
|
||||
.name = "z127-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = men_z127_probe,
|
||||
.remove = men_z127_remove,
|
||||
.id_table = men_z127_ids,
|
||||
};
|
||||
module_mcb_driver(men_z127_driver);
|
||||
|
||||
MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>");
|
||||
MODULE_DESCRIPTION("MEN 16z127 GPIO Controller");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("mcb:16z127");
|
@ -57,13 +57,10 @@ static int moxart_gpio_probe(struct platform_device *pdev)
|
||||
gc->label = "moxart-gpio";
|
||||
gc->request = gpiochip_generic_request;
|
||||
gc->free = gpiochip_generic_free;
|
||||
gc->bgpio_data = gc->read_reg(gc->reg_set);
|
||||
gc->base = 0;
|
||||
gc->ngpio = 32;
|
||||
gc->parent = dev;
|
||||
gc->owner = THIS_MODULE;
|
||||
|
||||
ret = gpiochip_add_data(gc, NULL);
|
||||
ret = devm_gpiochip_add_data(dev, gc, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: gpiochip_add failed\n",
|
||||
dev->of_node->full_name);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
/*
|
||||
* GPIOs on MPC512x/8349/8572/8610 and compatible
|
||||
* GPIOs on MPC512x/8349/8572/8610/QorIQ and compatible
|
||||
*
|
||||
* Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
|
||||
* Copyright (C) 2016 Freescale Semiconductor Inc.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
@ -14,11 +15,12 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
#define MPC8XXX_GPIO_PINS 32
|
||||
|
||||
@ -31,32 +33,17 @@
|
||||
#define GPIO_ICR2 0x18
|
||||
|
||||
struct mpc8xxx_gpio_chip {
|
||||
struct of_mm_gpio_chip mm_gc;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *regs;
|
||||
raw_spinlock_t lock;
|
||||
|
||||
/*
|
||||
* shadowed data register to be able to clear/set output pins in
|
||||
* open drain mode safely
|
||||
*/
|
||||
u32 data;
|
||||
int (*direction_output)(struct gpio_chip *chip,
|
||||
unsigned offset, int value);
|
||||
|
||||
struct irq_domain *irq;
|
||||
unsigned int irqn;
|
||||
const void *of_dev_id_data;
|
||||
};
|
||||
|
||||
static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
|
||||
{
|
||||
return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc =
|
||||
container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
|
||||
|
||||
mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
|
||||
}
|
||||
|
||||
/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
|
||||
* defined as output cannot be determined by reading GPDAT register,
|
||||
* so we use shadow data register instead. The status of input pins
|
||||
@ -65,117 +52,36 @@ static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
|
||||
static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
u32 val;
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
u32 out_mask, out_shadow;
|
||||
|
||||
out_mask = in_be32(mm->regs + GPIO_DIR);
|
||||
out_mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_DIR);
|
||||
val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
|
||||
out_shadow = gc->bgpio_data & out_mask;
|
||||
|
||||
val = in_be32(mm->regs + GPIO_DAT) & ~out_mask;
|
||||
out_shadow = mpc8xxx_gc->data & out_mask;
|
||||
|
||||
return !!((val | out_shadow) & mpc8xxx_gpio2mask(gpio));
|
||||
return !!((val | out_shadow) & gc->pin2mask(gc, gpio));
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
|
||||
unsigned int gpio, int val)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
|
||||
return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
if (val)
|
||||
mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
|
||||
else
|
||||
mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
|
||||
|
||||
out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
}
|
||||
|
||||
static void mpc8xxx_gpio_set_multiple(struct gpio_chip *gc,
|
||||
unsigned long *mask, unsigned long *bits)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
for (i = 0; i < gc->ngpio; i++) {
|
||||
if (*mask == 0)
|
||||
break;
|
||||
if (__test_and_clear_bit(i, mask)) {
|
||||
if (test_bit(i, bits))
|
||||
mpc8xxx_gc->data |= mpc8xxx_gpio2mask(i);
|
||||
else
|
||||
mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(i);
|
||||
}
|
||||
}
|
||||
|
||||
out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
|
||||
mpc8xxx_gpio_set(gc, gpio, val);
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc5121_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
/* GPIO 28..31 are input only on MPC5121 */
|
||||
if (gpio >= 28)
|
||||
return -EINVAL;
|
||||
|
||||
return mpc8xxx_gpio_dir_out(gc, gpio, val);
|
||||
return mpc8xxx_gc->direction_output(gc, gpio, val);
|
||||
}
|
||||
|
||||
static int mpc5125_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
static int mpc5125_gpio_dir_out(struct gpio_chip *gc,
|
||||
unsigned int gpio, int val)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
|
||||
/* GPIO 0..3 are input only on MPC5125 */
|
||||
if (gpio <= 3)
|
||||
return -EINVAL;
|
||||
|
||||
return mpc8xxx_gpio_dir_out(gc, gpio, val);
|
||||
return mpc8xxx_gc->direction_output(gc, gpio, val);
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
@ -192,10 +98,11 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
unsigned int mask;
|
||||
|
||||
mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
|
||||
mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER)
|
||||
& gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR);
|
||||
if (mask)
|
||||
generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
|
||||
32 - ffs(mask)));
|
||||
@ -206,12 +113,14 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
|
||||
static void mpc8xxx_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
|
||||
gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
|
||||
| gc->pin2mask(gc, irqd_to_hwirq(d)));
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
}
|
||||
@ -219,12 +128,14 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
|
||||
static void mpc8xxx_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
|
||||
clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
|
||||
gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
|
||||
& ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
|
||||
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
}
|
||||
@ -232,29 +143,32 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
|
||||
static void mpc8xxx_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
|
||||
out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER,
|
||||
gc->pin2mask(gc, irqd_to_hwirq(d)));
|
||||
}
|
||||
|
||||
static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
unsigned long flags;
|
||||
|
||||
switch (flow_type) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
setbits32(mm->regs + GPIO_ICR,
|
||||
mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
|
||||
gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
|
||||
| gc->pin2mask(gc, irqd_to_hwirq(d)));
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrbits32(mm->regs + GPIO_ICR,
|
||||
mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
|
||||
gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
|
||||
& ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
@ -268,17 +182,17 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
|
||||
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
|
||||
struct gpio_chip *gc = &mpc8xxx_gc->gc;
|
||||
unsigned long gpio = irqd_to_hwirq(d);
|
||||
void __iomem *reg;
|
||||
unsigned int shift;
|
||||
unsigned long flags;
|
||||
|
||||
if (gpio < 16) {
|
||||
reg = mm->regs + GPIO_ICR;
|
||||
reg = mpc8xxx_gc->regs + GPIO_ICR;
|
||||
shift = (15 - gpio) * 2;
|
||||
} else {
|
||||
reg = mm->regs + GPIO_ICR2;
|
||||
reg = mpc8xxx_gc->regs + GPIO_ICR2;
|
||||
shift = (15 - (gpio % 16)) * 2;
|
||||
}
|
||||
|
||||
@ -286,20 +200,22 @@ static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrsetbits_be32(reg, 3 << shift, 2 << shift);
|
||||
gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift))
|
||||
| (2 << shift));
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrsetbits_be32(reg, 3 << shift, 1 << shift);
|
||||
gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift))
|
||||
| (1 << shift));
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
|
||||
clrbits32(reg, 3 << shift);
|
||||
gc->write_reg(reg, (gc->read_reg(reg) & ~(3 << shift)));
|
||||
raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
|
||||
break;
|
||||
|
||||
@ -354,8 +270,6 @@ static const struct mpc8xxx_gpio_devtype mpc8572_gpio_devtype = {
|
||||
};
|
||||
|
||||
static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = {
|
||||
.gpio_dir_out = mpc8xxx_gpio_dir_out,
|
||||
.gpio_get = mpc8xxx_gpio_get,
|
||||
.irq_set_type = mpc8xxx_irq_set_type,
|
||||
};
|
||||
|
||||
@ -374,9 +288,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct gpio_chip *gc;
|
||||
const struct of_device_id *id;
|
||||
struct gpio_chip *gc;
|
||||
const struct mpc8xxx_gpio_devtype *devtype =
|
||||
of_device_get_match_data(&pdev->dev);
|
||||
int ret;
|
||||
@ -389,12 +301,34 @@ static int mpc8xxx_probe(struct platform_device *pdev)
|
||||
|
||||
raw_spin_lock_init(&mpc8xxx_gc->lock);
|
||||
|
||||
mm_gc = &mpc8xxx_gc->mm_gc;
|
||||
gc = &mm_gc->gc;
|
||||
mpc8xxx_gc->regs = of_iomap(np, 0);
|
||||
if (!mpc8xxx_gc->regs)
|
||||
return -ENOMEM;
|
||||
|
||||
mm_gc->save_regs = mpc8xxx_gpio_save_regs;
|
||||
gc->ngpio = MPC8XXX_GPIO_PINS;
|
||||
gc->direction_input = mpc8xxx_gpio_dir_in;
|
||||
gc = &mpc8xxx_gc->gc;
|
||||
|
||||
if (of_property_read_bool(np, "little-endian")) {
|
||||
ret = bgpio_init(gc, &pdev->dev, 4,
|
||||
mpc8xxx_gc->regs + GPIO_DAT,
|
||||
NULL, NULL,
|
||||
mpc8xxx_gc->regs + GPIO_DIR, NULL,
|
||||
BGPIOF_BIG_ENDIAN);
|
||||
if (ret)
|
||||
goto err;
|
||||
dev_dbg(&pdev->dev, "GPIO registers are LITTLE endian\n");
|
||||
} else {
|
||||
ret = bgpio_init(gc, &pdev->dev, 4,
|
||||
mpc8xxx_gc->regs + GPIO_DAT,
|
||||
NULL, NULL,
|
||||
mpc8xxx_gc->regs + GPIO_DIR, NULL,
|
||||
BGPIOF_BIG_ENDIAN
|
||||
| BGPIOF_BIG_ENDIAN_BYTE_ORDER);
|
||||
if (ret)
|
||||
goto err;
|
||||
dev_dbg(&pdev->dev, "GPIO registers are BIG endian\n");
|
||||
}
|
||||
|
||||
mpc8xxx_gc->direction_output = gc->direction_output;
|
||||
|
||||
if (!devtype)
|
||||
devtype = &mpc8xxx_gpio_devtype_default;
|
||||
@ -405,18 +339,22 @@ static int mpc8xxx_probe(struct platform_device *pdev)
|
||||
*/
|
||||
mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type;
|
||||
|
||||
gc->direction_output = devtype->gpio_dir_out ?: mpc8xxx_gpio_dir_out;
|
||||
gc->get = devtype->gpio_get ?: mpc8xxx_gpio_get;
|
||||
gc->set = mpc8xxx_gpio_set;
|
||||
gc->set_multiple = mpc8xxx_gpio_set_multiple;
|
||||
if (devtype->gpio_dir_out)
|
||||
gc->direction_output = devtype->gpio_dir_out;
|
||||
if (devtype->gpio_get)
|
||||
gc->get = devtype->gpio_get;
|
||||
|
||||
gc->to_irq = mpc8xxx_gpio_to_irq;
|
||||
|
||||
ret = of_mm_gpiochip_add_data(np, mm_gc, mpc8xxx_gc);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = gpiochip_add_data(gc, mpc8xxx_gc);
|
||||
if (ret) {
|
||||
pr_err("%s: GPIO chip registration failed with status %d\n",
|
||||
np->full_name, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
mpc8xxx_gc->irqn = irq_of_parse_and_map(np, 0);
|
||||
if (mpc8xxx_gc->irqn == NO_IRQ)
|
||||
if (!mpc8xxx_gc->irqn)
|
||||
return 0;
|
||||
|
||||
mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
|
||||
@ -424,18 +362,16 @@ static int mpc8xxx_probe(struct platform_device *pdev)
|
||||
if (!mpc8xxx_gc->irq)
|
||||
return 0;
|
||||
|
||||
id = of_match_node(mpc8xxx_gpio_ids, np);
|
||||
if (id)
|
||||
mpc8xxx_gc->of_dev_id_data = id->data;
|
||||
|
||||
/* ack and mask all irqs */
|
||||
out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
|
||||
out_be32(mm_gc->regs + GPIO_IMR, 0);
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff);
|
||||
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0);
|
||||
|
||||
irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
|
||||
mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
iounmap(mpc8xxx_gc->regs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpc8xxx_remove(struct platform_device *pdev)
|
||||
@ -447,7 +383,8 @@ static int mpc8xxx_remove(struct platform_device *pdev)
|
||||
irq_domain_remove(mpc8xxx_gc->irq);
|
||||
}
|
||||
|
||||
of_mm_gpiochip_remove(&mpc8xxx_gc->mm_gc);
|
||||
gpiochip_remove(&mpc8xxx_gc->gc);
|
||||
iounmap(mpc8xxx_gc->regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
BUG();
|
||||
}
|
||||
|
||||
gpiochip_add_data(&mvchip->chip, mvchip);
|
||||
devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip);
|
||||
|
||||
/* Some gpio controllers do not provide irq support */
|
||||
if (!of_irq_count(np))
|
||||
@ -777,16 +777,14 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
|
||||
mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1);
|
||||
if (mvchip->irqbase < 0) {
|
||||
dev_err(&pdev->dev, "no irqs\n");
|
||||
err = mvchip->irqbase;
|
||||
goto err_gpiochip_add;
|
||||
return mvchip->irqbase;
|
||||
}
|
||||
|
||||
gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
|
||||
mvchip->membase, handle_level_irq);
|
||||
if (!gc) {
|
||||
dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
|
||||
err = -ENOMEM;
|
||||
goto err_gpiochip_add;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
gc->private = mvchip;
|
||||
@ -828,9 +826,6 @@ err_generic_chip:
|
||||
IRQ_LEVEL | IRQ_NOPROBE);
|
||||
kfree(gc);
|
||||
|
||||
err_gpiochip_add:
|
||||
gpiochip_remove(&mvchip->chip);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -462,14 +462,14 @@ static int mxc_gpio_probe(struct platform_device *pdev)
|
||||
port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
|
||||
pdev->id * 32;
|
||||
|
||||
err = gpiochip_add_data(&port->gc, port);
|
||||
err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);
|
||||
if (err)
|
||||
goto out_bgio;
|
||||
|
||||
irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
|
||||
if (irq_base < 0) {
|
||||
err = irq_base;
|
||||
goto out_gpiochip_remove;
|
||||
goto out_bgio;
|
||||
}
|
||||
|
||||
port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
|
||||
@ -492,8 +492,6 @@ out_irqdomain_remove:
|
||||
irq_domain_remove(port->domain);
|
||||
out_irqdesc_free:
|
||||
irq_free_descs(irq_base, 32);
|
||||
out_gpiochip_remove:
|
||||
gpiochip_remove(&port->gc);
|
||||
out_bgio:
|
||||
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
|
||||
return err;
|
||||
|
@ -117,7 +117,7 @@ static int octeon_gpio_probe(struct platform_device *pdev)
|
||||
chip->get = octeon_gpio_get;
|
||||
chip->direction_output = octeon_gpio_dir_out;
|
||||
chip->set = octeon_gpio_set;
|
||||
err = gpiochip_add_data(chip, gpio);
|
||||
err = devm_gpiochip_add_data(&pdev->dev, chip, gpio);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -126,13 +126,6 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int octeon_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_chip *chip = dev_get_platdata(&pdev->dev);
|
||||
gpiochip_remove(chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id octeon_gpio_match[] = {
|
||||
{
|
||||
.compatible = "cavium,octeon-3860-gpio",
|
||||
@ -147,7 +140,6 @@ static struct platform_driver octeon_gpio_driver = {
|
||||
.of_match_table = octeon_gpio_match,
|
||||
},
|
||||
.probe = octeon_gpio_probe,
|
||||
.remove = octeon_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(octeon_gpio_driver);
|
||||
|
@ -66,7 +66,6 @@ struct gpio_bank {
|
||||
u32 irq_usage;
|
||||
u32 dbck_enable_mask;
|
||||
bool dbck_enabled;
|
||||
struct device *dev;
|
||||
bool is_mpuio;
|
||||
bool dbck_flag;
|
||||
bool loses_context;
|
||||
@ -627,7 +626,7 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, unsigned offset,
|
||||
unsigned long flags;
|
||||
|
||||
if (bank->non_wakeup_gpios & gpio_bit) {
|
||||
dev_err(bank->dev,
|
||||
dev_err(bank->chip.parent,
|
||||
"Unable to modify wakeup on non-wakeup GPIO%d\n",
|
||||
offset);
|
||||
return -EINVAL;
|
||||
@ -669,7 +668,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
* enable the bank module.
|
||||
*/
|
||||
if (!BANK_USED(bank))
|
||||
pm_runtime_get_sync(bank->dev);
|
||||
pm_runtime_get_sync(chip->parent);
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_enable_gpio_module(bank, offset);
|
||||
@ -698,7 +697,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
* disable the bank module.
|
||||
*/
|
||||
if (!BANK_USED(bank))
|
||||
pm_runtime_put(bank->dev);
|
||||
pm_runtime_put(chip->parent);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -723,7 +722,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
|
||||
if (WARN_ON(!isr_reg))
|
||||
goto exit;
|
||||
|
||||
pm_runtime_get_sync(bank->dev);
|
||||
pm_runtime_get_sync(bank->chip.parent);
|
||||
|
||||
while (1) {
|
||||
u32 isr_saved, level_mask = 0;
|
||||
@ -776,7 +775,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
|
||||
}
|
||||
}
|
||||
exit:
|
||||
pm_runtime_put(bank->dev);
|
||||
pm_runtime_put(bank->chip.parent);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -826,7 +825,7 @@ static void omap_gpio_irq_bus_lock(struct irq_data *data)
|
||||
struct gpio_bank *bank = omap_irq_data_get_bank(data);
|
||||
|
||||
if (!BANK_USED(bank))
|
||||
pm_runtime_get_sync(bank->dev);
|
||||
pm_runtime_get_sync(bank->chip.parent);
|
||||
}
|
||||
|
||||
static void gpio_irq_bus_sync_unlock(struct irq_data *data)
|
||||
@ -838,7 +837,7 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data)
|
||||
* disable the bank module.
|
||||
*/
|
||||
if (!BANK_USED(bank))
|
||||
pm_runtime_put(bank->dev);
|
||||
pm_runtime_put(bank->chip.parent);
|
||||
}
|
||||
|
||||
static void omap_gpio_ack_irq(struct irq_data *d)
|
||||
@ -1100,7 +1099,8 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
|
||||
ret = gpiochip_add_data(&bank->chip, bank);
|
||||
if (ret) {
|
||||
dev_err(bank->dev, "Could not register gpio chip %d\n", ret);
|
||||
dev_err(bank->chip.parent,
|
||||
"Could not register gpio chip %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1114,7 +1114,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
*/
|
||||
irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
|
||||
if (irq_base < 0) {
|
||||
dev_err(bank->dev, "Couldn't allocate IRQ numbers\n");
|
||||
dev_err(bank->chip.parent, "Couldn't allocate IRQ numbers\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
@ -1131,15 +1131,17 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
IRQ_TYPE_NONE);
|
||||
|
||||
if (ret) {
|
||||
dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret);
|
||||
dev_err(bank->chip.parent,
|
||||
"Couldn't add irqchip to gpiochip %d\n", ret);
|
||||
gpiochip_remove(&bank->chip);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&bank->chip, irqc, bank->irq, NULL);
|
||||
|
||||
ret = devm_request_irq(bank->dev, bank->irq, omap_gpio_irq_handler,
|
||||
0, dev_name(bank->dev), bank);
|
||||
ret = devm_request_irq(bank->chip.parent, bank->irq,
|
||||
omap_gpio_irq_handler,
|
||||
0, dev_name(bank->chip.parent), bank);
|
||||
if (ret)
|
||||
gpiochip_remove(&bank->chip);
|
||||
|
||||
@ -1196,7 +1198,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
return bank->irq;
|
||||
}
|
||||
|
||||
bank->dev = dev;
|
||||
bank->chip.parent = dev;
|
||||
bank->chip.owner = THIS_MODULE;
|
||||
bank->dbck_flag = pdata->dbck_flag;
|
||||
@ -1235,9 +1236,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (bank->dbck_flag) {
|
||||
bank->dbck = devm_clk_get(bank->dev, "dbclk");
|
||||
bank->dbck = devm_clk_get(dev, "dbclk");
|
||||
if (IS_ERR(bank->dbck)) {
|
||||
dev_err(bank->dev,
|
||||
dev_err(dev,
|
||||
"Could not get gpio dbck. Disable debounce\n");
|
||||
bank->dbck_flag = false;
|
||||
} else {
|
||||
@ -1247,9 +1248,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, bank);
|
||||
|
||||
pm_runtime_enable(bank->dev);
|
||||
pm_runtime_irq_safe(bank->dev);
|
||||
pm_runtime_get_sync(bank->dev);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_irq_safe(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (bank->is_mpuio)
|
||||
omap_mpuio_init(bank);
|
||||
@ -1258,14 +1259,14 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
ret = omap_gpio_chip_init(bank, irqc);
|
||||
if (ret) {
|
||||
pm_runtime_put_sync(bank->dev);
|
||||
pm_runtime_disable(bank->dev);
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
omap_gpio_show_rev(bank);
|
||||
|
||||
pm_runtime_put(bank->dev);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
list_add_tail(&bank->node, &omap_gpio_list);
|
||||
|
||||
@ -1278,7 +1279,7 @@ static int omap_gpio_remove(struct platform_device *pdev)
|
||||
|
||||
list_del(&bank->node);
|
||||
gpiochip_remove(&bank->chip);
|
||||
pm_runtime_disable(bank->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (bank->dbck_flag)
|
||||
clk_unprepare(bank->dbck);
|
||||
|
||||
@ -1348,7 +1349,7 @@ static int omap_gpio_runtime_suspend(struct device *dev)
|
||||
update_gpio_context_count:
|
||||
if (bank->get_context_loss_count)
|
||||
bank->context_loss_count =
|
||||
bank->get_context_loss_count(bank->dev);
|
||||
bank->get_context_loss_count(dev);
|
||||
|
||||
omap_gpio_dbck_disable(bank);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
@ -1378,7 +1379,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
|
||||
|
||||
if (bank->get_context_loss_count)
|
||||
bank->context_loss_count =
|
||||
bank->get_context_loss_count(bank->dev);
|
||||
bank->get_context_loss_count(dev);
|
||||
}
|
||||
|
||||
omap_gpio_dbck_enable(bank);
|
||||
@ -1398,7 +1399,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
|
||||
if (!bank->get_context_loss_count) {
|
||||
omap_gpio_restore_context(bank);
|
||||
} else {
|
||||
c = bank->get_context_loss_count(bank->dev);
|
||||
c = bank->get_context_loss_count(dev);
|
||||
if (c != bank->context_loss_count) {
|
||||
omap_gpio_restore_context(bank);
|
||||
} else {
|
||||
@ -1481,7 +1482,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
|
||||
|
||||
bank->power_mode = pwr_mode;
|
||||
|
||||
pm_runtime_put_sync_suspend(bank->dev);
|
||||
pm_runtime_put_sync_suspend(bank->chip.parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1493,7 +1494,7 @@ void omap2_gpio_resume_after_idle(void)
|
||||
if (!BANK_USED(bank) || !bank->loses_context)
|
||||
continue;
|
||||
|
||||
pm_runtime_get_sync(bank->dev);
|
||||
pm_runtime_get_sync(bank->chip.parent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -195,7 +195,8 @@ static int palmas_gpio_probe(struct platform_device *pdev)
|
||||
else
|
||||
palmas_gpio->gpio_chip.base = -1;
|
||||
|
||||
ret = gpiochip_add_data(&palmas_gpio->gpio_chip, palmas_gpio);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &palmas_gpio->gpio_chip,
|
||||
palmas_gpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
|
||||
return ret;
|
||||
@ -205,20 +206,11 @@ static int palmas_gpio_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int palmas_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct palmas_gpio *palmas_gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&palmas_gpio->gpio_chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver palmas_gpio_driver = {
|
||||
.driver.name = "palmas-gpio",
|
||||
.driver.owner = THIS_MODULE,
|
||||
.driver.of_match_table = of_palmas_gpio_match,
|
||||
.probe = palmas_gpio_probe,
|
||||
.remove = palmas_gpio_remove,
|
||||
};
|
||||
|
||||
static int __init palmas_gpio_init(void)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user