summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-sprd.txt28
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt45
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-tz1090.txt88
-rw-r--r--Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt27
-rw-r--r--Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt30
-rw-r--r--Documentation/devicetree/bindings/powerpc/nintendo/wii.txt9
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/x86/Kconfig10
-rw-r--r--drivers/gpio/Kconfig59
-rw-r--r--drivers/gpio/Makefile5
-rw-r--r--drivers/gpio/gpio-davinci.c6
-rw-r--r--drivers/gpio/gpio-dwapb.c61
-rw-r--r--drivers/gpio/gpio-ftgpio010.c6
-rw-r--r--drivers/gpio/gpio-hlwd.c115
-rw-r--r--drivers/gpio/gpio-intel-mid.c4
-rw-r--r--drivers/gpio/gpio-merrifield.c4
-rw-r--r--drivers/gpio/gpio-ml-ioh.c1
-rw-r--r--drivers/gpio/gpio-mockup.c4
-rw-r--r--drivers/gpio/gpio-omap.c6
-rw-r--r--drivers/gpio/gpio-raspberrypi-exp.c252
-rw-r--r--drivers/gpio/gpio-rcar.c60
-rw-r--r--drivers/gpio/gpio-sprd.c290
-rw-r--r--drivers/gpio/gpio-tegra.c16
-rw-r--r--drivers/gpio/gpio-timberdale.c7
-rw-r--r--drivers/gpio/gpio-tps68470.c10
-rw-r--r--drivers/gpio/gpio-tz1090-pdc.c231
-rw-r--r--drivers/gpio/gpio-tz1090.c602
-rw-r--r--drivers/gpio/gpio-wm831x.c2
-rw-r--r--drivers/gpio/gpiolib.c2
-rw-r--r--drivers/gpio/gpiolib.h2
-rw-r--r--drivers/iio/adc/Kconfig3
-rw-r--r--drivers/iio/counter/Kconfig3
-rw-r--r--drivers/iio/dac/Kconfig3
-rw-r--r--drivers/watchdog/Kconfig3
-rw-r--r--include/soc/bcm2835/raspberrypi-firmware.h18
-rw-r--r--init/Kconfig2
-rw-r--r--tools/gpio/gpio-event-mon.c2
37 files changed, 945 insertions, 1073 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio-sprd.txt b/Documentation/devicetree/bindings/gpio/gpio-sprd.txt
new file mode 100644
index 000000000000..eca97d45388f
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-sprd.txt
@@ -0,0 +1,28 @@
+Spreadtrum GPIO controller bindings
+
+The controller's registers are organized as sets of sixteen 16-bit
+registers with each set controlling a bank of up to 16 pins. A single
+interrupt is shared for all of the banks handled by the controller.
+
+Required properties:
+- compatible: Should be "sprd,sc9860-gpio".
+- reg: Define the base and range of the I/O address space containing
+the GPIO controller registers.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be <2>. The first cell is the gpio number and
+the second cell is used to specify optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be <2>. Specifies the number of cells needed
+to encode interrupt source.
+- interrupts: Should be the port interrupt shared by all the gpios.
+
+Example:
+ ap_gpio: gpio@40280000 {
+ compatible = "sprd,sc9860-gpio";
+ reg = <0 0x40280000 0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
deleted file mode 100644
index 528f5ef5a893..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-ImgTec TZ1090 PDC GPIO Controller
-
-Required properties:
-- compatible: Compatible property value should be "img,tz1090-pdc-gpio".
-
-- reg: Physical base address of the controller and length of memory mapped
- region. This starts at and cover the SOC_GPIO_CONTROL registers.
-
-- gpio-controller: Specifies that the node is a gpio controller.
-
-- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
- nodes should have the following values.
- <[phandle of the gpio controller node]
- [PDC gpio number]
- [gpio flags]>
-
- Values for gpio specifier:
- - GPIO number: a value in the range 0 to 6.
- - GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
- Only the following flags are supported:
- GPIO_ACTIVE_HIGH
- GPIO_ACTIVE_LOW
-
-Optional properties:
-- gpio-ranges: Mapping to pin controller pins (as described in
- Documentation/devicetree/bindings/gpio/gpio.txt)
-
-- interrupts: Individual syswake interrupts (other GPIOs cannot interrupt)
-
-
-Example:
-
- pdc_gpios: gpio-controller@2006500 {
- gpio-controller;
- #gpio-cells = <2>;
-
- compatible = "img,tz1090-pdc-gpio";
- reg = <0x02006500 0x100>;
-
- interrupt-parent = <&pdc>;
- interrupts = <8 IRQ_TYPE_NONE>, /* Syswake 0 */
- <9 IRQ_TYPE_NONE>, /* Syswake 1 */
- <10 IRQ_TYPE_NONE>; /* Syswake 2 */
- gpio-ranges = <&pdc_pinctrl 0 0 7>;
- };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
deleted file mode 100644
index b05a90e0ab29..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-ImgTec TZ1090 GPIO Controller
-
-Required properties:
-- compatible: Compatible property value should be "img,tz1090-gpio".
-
-- reg: Physical base address of the controller and length of memory mapped
- region.
-
-- #address-cells: Should be 1 (for bank subnodes)
-
-- #size-cells: Should be 0 (for bank subnodes)
-
-- Each bank of GPIOs should have a subnode to represent it.
-
- Bank subnode required properties:
- - reg: Index of bank in the range 0 to 2.
-
- - gpio-controller: Specifies that the node is a gpio controller.
-
- - #gpio-cells: Should be 2. The syntax of the gpio specifier used by client
- nodes should have the following values.
- <[phandle of the gpio controller node]
- [gpio number within the gpio bank]
- [gpio flags]>
-
- Values for gpio specifier:
- - GPIO number: a value in the range 0 to 29.
- - GPIO flags: bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
- Only the following flags are supported:
- GPIO_ACTIVE_HIGH
- GPIO_ACTIVE_LOW
-
- Bank subnode optional properties:
- - gpio-ranges: Mapping to pin controller pins (as described in
- Documentation/devicetree/bindings/gpio/gpio.txt)
-
- - interrupts: Interrupt for the entire bank
-
- - interrupt-controller: Specifies that the node is an interrupt controller
-
- - #interrupt-cells: Should be 2. The syntax of the interrupt specifier used by
- client nodes should have the following values.
- <[phandle of the interurupt controller]
- [gpio number within the gpio bank]
- [irq flags]>
-
- Values for irq specifier:
- - GPIO number: a value in the range 0 to 29
- - IRQ flags: value to describe edge and level triggering, as defined in
- <dt-bindings/interrupt-controller/irq.h>. Only the following flags are
- supported:
- IRQ_TYPE_EDGE_RISING
- IRQ_TYPE_EDGE_FALLING
- IRQ_TYPE_EDGE_BOTH
- IRQ_TYPE_LEVEL_HIGH
- IRQ_TYPE_LEVEL_LOW
-
-
-
-Example:
-
- gpios: gpio-controller@2005800 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "img,tz1090-gpio";
- reg = <0x02005800 0x90>;
-
- /* bank 0 with an interrupt */
- gpios0: bank@0 {
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- reg = <0>;
- interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 0 30>;
- interrupt-controller;
- };
-
- /* bank 2 without interrupt */
- gpios2: bank@2 {
- #gpio-cells = <2>;
- reg = <2>;
- gpio-controller;
- gpio-ranges = <&pinctrl 0 60 30>;
- };
- };
-
-
diff --git a/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt b/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
new file mode 100644
index 000000000000..20fc72d9e61e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
@@ -0,0 +1,27 @@
+Nintendo Wii (Hollywood) GPIO controller
+
+Required properties:
+- compatible: "nintendo,hollywood-gpio
+- reg: Physical base address and length of the controller's registers.
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be <2>. The first cell is the pin number and the
+ second cell is used to specify optional parameters:
+ - bit 0 specifies polarity (0 for normal, 1 for inverted).
+
+Optional properties:
+- ngpios: see Documentation/devicetree/bindings/gpio/gpio.txt
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Should be two.
+- interrupts: Interrupt specifier for the controller's Broadway (PowerPC)
+ interrupt.
+- interrupt-parent: phandle of the parent interrupt controller.
+
+Example:
+
+ GPIO: gpio@d8000c0 {
+ #gpio-cells = <2>;
+ compatible = "nintendo,hollywood-gpio";
+ reg = <0x0d8000c0 0x40>;
+ gpio-controller;
+ ngpios = <24>;
+ }
diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
new file mode 100644
index 000000000000..ce97265e23ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
@@ -0,0 +1,30 @@
+Raspberry Pi GPIO expander
+
+The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
+firmware exposes a mailbox interface that allows the ARM core to control the
+GPIO lines on the expander.
+
+The Raspberry Pi GPIO expander node must be a child node of the Raspberry Pi
+firmware node.
+
+Required properties:
+
+- compatible : Should be "raspberrypi,firmware-gpio"
+- 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 the gpio polarity:
+ 0 = active high
+ 1 = active low
+
+Example:
+
+firmware: firmware-rpi {
+ compatible = "raspberrypi,bcm2835-firmware";
+ mboxes = <&mailbox>;
+
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
index 36afa322b04b..a3dc4b9fa11a 100644
--- a/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
+++ b/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
@@ -152,14 +152,7 @@ Nintendo Wii device tree
1.l) The General Purpose I/O (GPIO) controller node
- Represents the dual access 32 GPIO controller interface.
-
- Required properties:
-
- - #gpio-cells : <2>
- - compatible : should be "nintendo,hollywood-gpio"
- - reg : should contain the IPC registers location and length
- - gpio-controller
+ see Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt
1.m) The control node
diff --git a/MAINTAINERS b/MAINTAINERS
index 4623caf8d72d..95cb0e0e9e5b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6016,7 +6016,7 @@ S: Maintained
F: drivers/media/rc/gpio-ir-tx.c
GPIO MOCKUP DRIVER
-M: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
+M: Bamvor Jian Zhang <bamv2005@gmail.com>
R: Bartosz Golaszewski <brgl@bgdev.pl>
L: linux-gpio@vger.kernel.org
S: Maintained
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0fa71a78ec99..2b31e438eb40 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2668,11 +2668,13 @@ config PCI_CNB20LE_QUIRK
source "drivers/pci/Kconfig"
config ISA_BUS
- bool "ISA-style bus support on modern systems" if EXPERT
- select ISA_BUS_API
+ bool "ISA bus support on modern systems" if EXPERT
help
- Enables ISA-style drivers on modern systems. This is necessary to
- support PC/104 devices on X86_64 platforms.
+ Expose ISA bus device drivers and options available for selection and
+ configuration. Enable this option if your target machine has an ISA
+ bus. ISA is an older system, displaced by PCI and newer bus
+ architectures -- if your target machine is modern, it probably does
+ not have an ISA bus.
If unsure, say N.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8dbb2280538d..6b1ee11295d5 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -122,6 +122,17 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
+config GPIO_RASPBERRYPI_EXP
+ tristate "Raspberry Pi 3 GPIO Expander"
+ default RASPBERRYPI_FIRMWARE
+ depends on OF_GPIO
+ # Make sure not 'y' when RASPBERRYPI_FIRMWARE is 'm'. This can only
+ # happen when COMPILE_TEST=y, hence the added !RASPBERRYPI_FIRMWARE.
+ depends on (ARCH_BCM2835 && RASPBERRYPI_FIRMWARE) || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
+ help
+ Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
+ the firmware mailbox to communicate with VideoCore on BCM283x chips.
+
config GPIO_BCM_KONA
bool "Broadcom Kona GPIO"
depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
@@ -223,6 +234,15 @@ config GPIO_GRGPIO
Select this to support Aeroflex Gaisler GRGPIO cores from the GRLIB
VHDL IP core library.
+config GPIO_HLWD
+ tristate "Nintendo Wii (Hollywood) GPIO"
+ depends on OF_GPIO
+ select GPIO_GENERIC
+ help
+ Select this to support the GPIO controller of the Nintendo Wii.
+
+ If unsure, say N.
+
config GPIO_ICH
tristate "Intel ICH GPIO"
depends on PCI && X86
@@ -398,6 +418,14 @@ config GPIO_SPEAR_SPICS
help
Say yes here to support ST SPEAr SPI Chip Select as GPIO device
+config GPIO_SPRD
+ tristate "Spreadtrum GPIO support"
+ depends on ARCH_SPRD || COMPILE_TEST
+ depends on OF_GPIO
+ select GPIOLIB_IRQCHIP
+ help
+ Say yes here to support Spreadtrum GPIO device.
+
config GPIO_STA2X11
bool "STA2x11/ConneXt GPIO support"
depends on MFD_STA2X11
@@ -462,21 +490,6 @@ config GPIO_THUNDERX
Say yes here to support the on-chip GPIO lines on the ThunderX
and OCTEON-TX families of SoCs.
-config GPIO_TZ1090
- bool "Toumaz Xenif TZ1090 GPIO support"
- depends on SOC_TZ1090
- select GENERIC_IRQ_CHIP
- default y
- help
- Say yes here to support Toumaz Xenif TZ1090 GPIOs.
-
-config GPIO_TZ1090_PDC
- bool "Toumaz Xenif TZ1090 PDC GPIO support"
- depends on SOC_TZ1090
- default y
- help
- Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs.
-
config GPIO_UNIPHIER
tristate "UniPhier GPIO support"
depends on ARCH_UNIPHIER || COMPILE_TEST
@@ -590,7 +603,8 @@ menu "Port-mapped I/O GPIO drivers"
config GPIO_104_DIO_48E
tristate "ACCES 104-DIO-48E GPIO support"
- depends on PC104 && ISA_BUS_API
+ depends on PC104
+ select ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E,
@@ -600,7 +614,8 @@ config GPIO_104_DIO_48E
config GPIO_104_IDIO_16
tristate "ACCES 104-IDIO-16 GPIO support"
- depends on PC104 && ISA_BUS_API
+ depends on PC104
+ select ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16,
@@ -611,7 +626,8 @@ config GPIO_104_IDIO_16
config GPIO_104_IDI_48
tristate "ACCES 104-IDI-48 GPIO support"
- depends on PC104 && ISA_BUS_API
+ depends on PC104
+ select ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A,
@@ -631,7 +647,8 @@ config GPIO_F7188X
config GPIO_GPIO_MM
tristate "Diamond Systems GPIO-MM GPIO support"
- depends on PC104 && ISA_BUS_API
+ depends on PC104
+ select ISA_BUS_API
help
Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12.
@@ -700,7 +717,7 @@ config GPIO_TS5500
config GPIO_WINBOND
tristate "Winbond Super I/O GPIO support"
- depends on ISA_BUS_API
+ select ISA_BUS_API
help
This option enables support for GPIOs found on Winbond Super I/O
chips.
@@ -716,7 +733,7 @@ config GPIO_WINBOND
config GPIO_WS16C48
tristate "WinSystems WS16C48 GPIO support"
- depends on ISA_BUS_API
+ select ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the WinSystems WS16C48. The base port
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index cccb0d40846c..5c1f087c65aa 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
+obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
@@ -53,6 +54,7 @@ obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
+obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
obj-$(CONFIG_GPIO_INGENIC) += gpio-ingenic.o
@@ -108,6 +110,7 @@ obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o
+obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o
@@ -131,8 +134,6 @@ obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
-obj-$(CONFIG_GPIO_TZ1090) += gpio-tz1090.o
-obj-$(CONFIG_GPIO_TZ1090_PDC) += gpio-tz1090-pdc.o
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index 0b951ca78ec4..987126c4c6f6 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/irqchip/chained_irq.h>
@@ -225,6 +226,11 @@ static int davinci_gpio_probe(struct platform_device *pdev)
chips->chip.of_gpio_n_cells = 2;
chips->chip.parent = dev;
chips->chip.of_node = dev->of_node;
+
+ if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
+ chips->chip.request = gpiochip_generic_request;
+ chips->chip.free = gpiochip_generic_free;
+ }
#endif
spin_lock_init(&chips->lock);
bank_base += ngpio;
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 6730c6642ce3..b0704a883513 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -9,8 +9,6 @@
*/
#include <linux/acpi.h>
#include <linux/gpio/driver.h>
-/* FIXME: for gpio_get_value(), replace this with direct register read */
-#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -53,9 +51,9 @@
#define GPIO_EXT_PORTD 0x5c
#define DWAPB_MAX_PORTS 4
-#define GPIO_EXT_PORT_SIZE (GPIO_EXT_PORTB - GPIO_EXT_PORTA)
-#define GPIO_SWPORT_DR_SIZE (GPIO_SWPORTB_DR - GPIO_SWPORTA_DR)
-#define GPIO_SWPORT_DDR_SIZE (GPIO_SWPORTB_DDR - GPIO_SWPORTA_DDR)
+#define GPIO_EXT_PORT_STRIDE 0x04 /* register stride 32 bits */
+#define GPIO_SWPORT_DR_STRIDE 0x0c /* register stride 3*32 bits */
+#define GPIO_SWPORT_DDR_STRIDE 0x0c /* register stride 3*32 bits */
#define GPIO_REG_OFFSET_V2 1
@@ -153,16 +151,40 @@ static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return irq_find_mapping(gpio->domain, offset);
}
+static struct dwapb_gpio_port *dwapb_offs_to_port(struct dwapb_gpio *gpio, unsigned int offs)
+{
+ struct dwapb_gpio_port *port;
+ int i;
+
+ for (i = 0; i < gpio->nr_ports; i++) {
+ port = &gpio->ports[i];
+ if (port->idx == offs / 32)
+ return port;
+ }
+
+ return NULL;
+}
+
static void dwapb_toggle_trigger(struct dwapb_gpio *gpio, unsigned int offs)
{
- u32 v = dwapb_read(gpio, GPIO_INT_POLARITY);
+ struct dwapb_gpio_port *port = dwapb_offs_to_port(gpio, offs);
+ struct gpio_chip *gc;
+ u32 pol;
+ int val;
+
+ if (!port)
+ return;
+ gc = &port->gc;
- if (gpio_get_value(gpio->ports[0].gc.base + offs))
- v &= ~BIT(offs);
+ pol = dwapb_read(gpio, GPIO_INT_POLARITY);
+ /* Just read the current value right out of the data register */
+ val = gc->get(gc, offs % 32);
+ if (val)
+ pol &= ~BIT(offs);
else
- v |= BIT(offs);
+ pol |= BIT(offs);
- dwapb_write(gpio, GPIO_INT_POLARITY, v);
+ dwapb_write(gpio, GPIO_INT_POLARITY, pol);
}
static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
@@ -476,11 +498,12 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio,
return -ENOMEM;
#endif
- dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_SIZE);
- set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_SIZE);
+ dat = gpio->regs + GPIO_EXT_PORTA + (pp->idx * GPIO_EXT_PORT_STRIDE);
+ set = gpio->regs + GPIO_SWPORTA_DR + (pp->idx * GPIO_SWPORT_DR_STRIDE);
dirout = gpio->regs + GPIO_SWPORTA_DDR +
- (pp->idx * GPIO_SWPORT_DDR_SIZE);
+ (pp->idx * GPIO_SWPORT_DDR_STRIDE);
+ /* This registers 32 GPIO lines per port */
err = bgpio_init(&port->gc, gpio->dev, 4, dat, set, NULL, dirout,
NULL, 0);
if (err) {
@@ -710,13 +733,13 @@ static int dwapb_gpio_suspend(struct device *dev)
BUG_ON(!ctx);
- offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE;
+ offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
ctx->dir = dwapb_read(gpio, offset);
- offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE;
+ offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
ctx->data = dwapb_read(gpio, offset);
- offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE;
+ offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
ctx->ext = dwapb_read(gpio, offset);
/* Only port A can provide interrupts */
@@ -753,13 +776,13 @@ static int dwapb_gpio_resume(struct device *dev)
BUG_ON(!ctx);
- offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_SIZE;
+ offset = GPIO_SWPORTA_DR + idx * GPIO_SWPORT_DR_STRIDE;
dwapb_write(gpio, offset, ctx->data);
- offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_SIZE;
+ offset = GPIO_SWPORTA_DDR + idx * GPIO_SWPORT_DDR_STRIDE;
dwapb_write(gpio, offset, ctx->dir);
- offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_SIZE;
+ offset = GPIO_EXT_PORTA + idx * GPIO_EXT_PORT_STRIDE;
dwapb_write(gpio, offset, ctx->ext);
/* Only port A can provide interrupts */
diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c
index b7a3a2db699b..e80634c464a9 100644
--- a/drivers/gpio/gpio-ftgpio010.c
+++ b/drivers/gpio/gpio-ftgpio010.c
@@ -21,12 +21,14 @@
#define GPIO_DATA_OUT 0x00
#define GPIO_DATA_IN 0x04
#define GPIO_DIR 0x08
+#define GPIO_BYPASS_IN 0x0C
#define GPIO_DATA_SET 0x10
#define GPIO_DATA_CLR 0x14
#define GPIO_PULL_EN 0x18
#define GPIO_PULL_TYPE 0x1C
#define GPIO_INT_EN 0x20
-#define GPIO_INT_STAT 0x24
+#define GPIO_INT_STAT_RAW 0x24
+#define GPIO_INT_STAT_MASKED 0x28
#define GPIO_INT_MASK 0x2C
#define GPIO_INT_CLR 0x30
#define GPIO_INT_TYPE 0x34
@@ -147,7 +149,7 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(irqchip, desc);
- stat = readl(g->base + GPIO_INT_STAT);
+ stat = readl(g->base + GPIO_INT_STAT_RAW);
if (stat)
for_each_set_bit(offset, &stat, gc->ngpio)
generic_handle_irq(irq_find_mapping(gc->irq.domain,
diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c
new file mode 100644
index 000000000000..a63136a68ba3
--- /dev/null
+++ b/drivers/gpio/gpio-hlwd.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (C) 2008-2009 The GameCube Linux Team
+// Copyright (C) 2008,2009 Albert Herranz
+// Copyright (C) 2017-2018 Jonathan Neuschäfer
+//
+// Nintendo Wii (Hollywood) GPIO driver
+
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+/*
+ * Register names and offsets courtesy of WiiBrew:
+ * https://wiibrew.org/wiki/Hardware/Hollywood_GPIOs
+ *
+ * Note that for most registers, there are two versions:
+ * - HW_GPIOB_* Is always accessible by the Broadway PowerPC core, but does
+ * always give access to all GPIO lines
+ * - HW_GPIO_* Is only accessible by the Broadway PowerPC code if the memory
+ * firewall (AHBPROT) in the Hollywood chipset has been configured to allow
+ * such access.
+ *
+ * The ownership of each GPIO line can be configured in the HW_GPIO_OWNER
+ * register: A one bit configures the line for access via the HW_GPIOB_*
+ * registers, a zero bit indicates access via HW_GPIO_*. This driver uses
+ * HW_GPIOB_*.
+ */
+#define HW_GPIOB_OUT 0x00
+#define HW_GPIOB_DIR 0x04
+#define HW_GPIOB_IN 0x08
+#define HW_GPIOB_INTLVL 0x0c
+#define HW_GPIOB_INTFLAG 0x10
+#define HW_GPIOB_INTMASK 0x14
+#define HW_GPIOB_INMIR 0x18
+#define HW_GPIO_ENABLE 0x1c
+#define HW_GPIO_OUT 0x20
+#define HW_GPIO_DIR 0x24
+#define HW_GPIO_IN 0x28
+#define HW_GPIO_INTLVL 0x2c
+#define HW_GPIO_INTFLAG 0x30
+#define HW_GPIO_INTMASK 0x34
+#define HW_GPIO_INMIR 0x38
+#define HW_GPIO_OWNER 0x3c
+
+struct hlwd_gpio {
+ struct gpio_chip gpioc;
+ void __iomem *regs;
+};
+
+static int hlwd_gpio_probe(struct platform_device *pdev)
+{
+ struct hlwd_gpio *hlwd;
+ struct resource *regs_resource;
+ u32 ngpios;
+ int res;
+
+ hlwd = devm_kzalloc(&pdev->dev, sizeof(*hlwd), GFP_KERNEL);
+ if (!hlwd)
+ return -ENOMEM;
+
+ regs_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hlwd->regs = devm_ioremap_resource(&pdev->dev, regs_resource);
+ if (IS_ERR(hlwd->regs))
+ return PTR_ERR(hlwd->regs);
+
+ /*
+ * Claim all GPIOs using the OWNER register. This will not work on
+ * systems where the AHBPROT memory firewall hasn't been configured to
+ * permit PPC access to HW_GPIO_*.
+ *
+ * Note that this has to happen before bgpio_init reads the
+ * HW_GPIOB_OUT and HW_GPIOB_DIR, because otherwise it reads the wrong
+ * values.
+ */
+ iowrite32be(0xffffffff, hlwd->regs + HW_GPIO_OWNER);
+
+ res = bgpio_init(&hlwd->gpioc, &pdev->dev, 4,
+ hlwd->regs + HW_GPIOB_IN, hlwd->regs + HW_GPIOB_OUT,
+ NULL, hlwd->regs + HW_GPIOB_DIR, NULL,
+ BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+ if (res < 0) {
+ dev_warn(&pdev->dev, "bgpio_init failed: %d\n", res);
+ return res;
+ }
+
+ res = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios);
+ if (res)
+ ngpios = 32;
+ hlwd->gpioc.ngpio = ngpios;
+
+ return devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
+}
+
+static const struct of_device_id hlwd_gpio_match[] = {
+ { .compatible = "nintendo,hollywood-gpio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, hlwd_gpio_match);
+
+static struct platform_driver hlwd_gpio_driver = {
+ .driver = {
+ .name = "gpio-hlwd",
+ .of_match_table = hlwd_gpio_match,
+ },
+ .probe = hlwd_gpio_probe,
+};
+module_platform_driver(hlwd_gpio_driver);
+
+MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
+MODULE_DESCRIPTION("Nintendo Wii GPIO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c
index 629575ea46a0..028d64c2cb1e 100644
--- a/drivers/gpio/gpio-intel-mid.c
+++ b/drivers/gpio/gpio-intel-mid.c
@@ -361,10 +361,8 @@ static int intel_gpio_probe(struct pci_dev *pdev,
pcim_iounmap_regions(pdev, 1 << 1);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "can't allocate chip data\n");
+ if (!priv)
return -ENOMEM;
- }
priv->reg_base = pcim_iomap_table(pdev)[0];
priv->chip.label = dev_name(&pdev->dev);
diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c
index c38624ea0251..97421bd4a60f 100644
--- a/drivers/gpio/gpio-merrifield.c
+++ b/drivers/gpio/gpio-merrifield.c
@@ -416,10 +416,8 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
pcim_iounmap_regions(pdev, BIT(1));
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "can't allocate chip data\n");
+ if (!priv)
return -ENOMEM;
- }
priv->dev = &pdev->dev;
priv->reg_base = pcim_iomap_table(pdev)[0];
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 4b80e996d976..b3678bd1c120 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -445,7 +445,6 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL);
if (chip_save == NULL) {
- dev_err(&pdev->dev, "%s : kzalloc failed", __func__);
ret = -ENOMEM;
goto err_kzalloc;
}
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
index 3a545ad17817..21422b8e487b 100644
--- a/drivers/gpio/gpio-mockup.c
+++ b/drivers/gpio/gpio-mockup.c
@@ -2,7 +2,7 @@
* GPIO Testing Device Driver
*
* Copyright (C) 2014 Kamlakant Patel <kamlakant.patel@broadcom.com>
- * Copyright (C) 2015-2016 Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
+ * Copyright (C) 2015-2016 Bamvor Jian Zhang <bamv2005@gmail.com>
* Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
*
* This program is free software; you can redistribute it and/or modify it
@@ -411,7 +411,7 @@ module_init(gpio_mockup_init);
module_exit(gpio_mockup_exit);
MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
-MODULE_AUTHOR("Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>");
+MODULE_AUTHOR("Bamvor Jian Zhang <bamv2005@gmail.com>");
MODULE_AUTHOR("Bartosz Golaszewski <brgl@bgdev.pl>");
MODULE_DESCRIPTION("GPIO Testing driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index ab5035b96886..35971a341c40 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1157,11 +1157,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;
- bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
- if (!bank) {
- dev_err(dev, "Memory alloc failed\n");
+ bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
+ if (!bank)
return -ENOMEM;
- }
irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
if (!irqc)
diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
new file mode 100644
index 000000000000..d6d36d537e37
--- /dev/null
+++ b/drivers/gpio/gpio-raspberrypi-exp.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Raspberry Pi 3 expander GPIO driver
+ *
+ * Uses the firmware mailbox service to communicate with the
+ * GPIO expander on the VPU.
+ *
+ * Copyright (C) 2017 Raspberry Pi Trading Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define MODULE_NAME "raspberrypi-exp-gpio"
+#define NUM_GPIO 8
+
+#define RPI_EXP_GPIO_BASE 128
+
+#define RPI_EXP_GPIO_DIR_IN 0
+#define RPI_EXP_GPIO_DIR_OUT 1
+
+struct rpi_exp_gpio {
+ struct gpio_chip gc;
+ struct rpi_firmware *fw;
+};
+
+/* VC4 firmware mailbox interface data structures */
+
+struct gpio_set_config {
+ u32 gpio;
+ u32 direction;
+ u32 polarity;
+ u32 term_en;
+ u32 term_pull_up;
+ u32 state;
+};
+
+struct gpio_get_config {
+ u32 gpio;
+ u32 direction;
+ u32 polarity;
+ u32 term_en;
+ u32 term_pull_up;
+};
+
+struct gpio_get_set_state {
+ u32 gpio;
+ u32 state;
+};
+
+static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_config get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n",
+ off, ret, get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return get.polarity;
+}
+
+static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_set_config set_in;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set_in.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set_in.direction = RPI_EXP_GPIO_DIR_IN;
+ set_in.term_en = 0; /* termination disabled */
+ set_in.term_pull_up = 0; /* n/a as termination disabled */
+ set_in.state = 0; /* n/a as configured as an input */
+
+ ret = rpi_exp_gpio_get_polarity(gc, off);
+ if (ret < 0)
+ return ret;
+ set_in.polarity = ret; /* Retain existing setting */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+ &set_in, sizeof(set_in));
+ if (ret || set_in.gpio != 0) {
+ dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n",
+ off, ret, set_in.gpio);
+ return ret ? ret : -EIO;
+ }
+ return 0;
+}
+
+static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_set_config set_out;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set_out.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set_out.direction = RPI_EXP_GPIO_DIR_OUT;
+ set_out.term_en = 0; /* n/a as an output */
+ set_out.term_pull_up = 0; /* n/a as termination disabled */
+ set_out.state = val; /* Output state */
+
+ ret = rpi_exp_gpio_get_polarity(gc, off);
+ if (ret < 0)
+ return ret;
+ set_out.polarity = ret; /* Retain existing setting */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+ &set_out, sizeof(set_out));
+ if (ret || set_out.gpio != 0) {
+ dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n",
+ off, ret, set_out.gpio);
+ return ret ? ret : -EIO;
+ }
+ return 0;
+}
+
+static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_config get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent,
+ "Failed to get GPIO %u config (%d %x)\n", off, ret,
+ get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return !get.direction;
+}
+
+static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_set_state get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ get.state = 0; /* storage for returned value */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent,
+ "Failed to get GPIO %u state (%d %x)\n", off, ret,
+ get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return !!get.state;
+}
+
+static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_set_state set;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set.state = val; /* Output state */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
+ &set, sizeof(set));
+ if (ret || set.gpio != 0)
+ dev_err(gc->parent,
+ "Failed to set GPIO %u state (%d %x)\n", off, ret,
+ set.gpio);
+}
+
+static int rpi_exp_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *fw_node;
+ struct rpi_firmware *fw;
+ struct rpi_exp_gpio *rpi_gpio;
+
+ fw_node = of_get_parent(np);
+ if (!fw_node) {
+ dev_err(dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+
+ fw = rpi_firmware_get(fw_node);
+ if (!fw)
+ return -EPROBE_DEFER;
+
+ rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
+ if (!rpi_gpio)
+ return -ENOMEM;
+
+ rpi_gpio->fw = fw;
+ rpi_gpio->gc.parent = dev;
+ rpi_gpio->gc.label = MODULE_NAME;
+ rpi_gpio->gc.owner = THIS_MODULE;
+ rpi_gpio->gc.of_node = np;
+ rpi_gpio->gc.base = -1;
+ rpi_gpio->gc.ngpio = NUM_GPIO;
+
+ rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
+ rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
+ rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
+ rpi_gpio->gc.get = rpi_exp_gpio_get;
+ rpi_gpio->gc.set = rpi_exp_gpio_set;
+ rpi_gpio->gc.can_sleep = true;
+
+ return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
+}
+
+static const struct of_device_id rpi_exp_gpio_ids[] = {
+ { .compatible = "raspberrypi,firmware-gpio" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
+
+static struct platform_driver rpi_exp_gpio_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
+ },
+ .probe = rpi_exp_gpio_probe,
+};
+module_platform_driver(rpi_exp_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
+MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
+MODULE_ALIAS("platform:rpi-exp-gpio");
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index ebaea8b1594b..350390c0b290 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -30,6 +30,16 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
+struct gpio_rcar_bank_info {
+ u32 iointsel;
+ u32 inoutsel;
+ u32 outdt;
+ u32 posneg;
+ u32 edglevel;
+ u32 bothedge;
+ u32 intmsk;
+};
+
struct gpio_rcar_priv {
void __iomem *base;
spinlock_t lock;
@@ -39,6 +49,7 @@ struct gpio_rcar_priv {
unsigned int irq_parent;
atomic_t wakeup_path;
bool has_both_edge_trigger;
+ struct gpio_rcar_bank_info bank_info;
};
#define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */
@@ -512,17 +523,62 @@ static int gpio_rcar_remove(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused gpio_rcar_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int gpio_rcar_suspend(struct device *dev)
{
struct gpio_rcar_priv *p = dev_get_drvdata(dev);
+ p->bank_info.iointsel = gpio_rcar_read(p, IOINTSEL);
+ p->bank_info.inoutsel = gpio_rcar_read(p, INOUTSEL);
+ p->bank_info.outdt = gpio_rcar_read(p, OUTDT);
+ p->bank_info.intmsk = gpio_rcar_read(p, INTMSK);
+ p->bank_info.posneg = gpio_rcar_read(p, POSNEG);
+ p->bank_info.edglevel = gpio_rcar_read(p, EDGLEVEL);
+ if (p->has_both_edge_trigger)
+ p->bank_info.bothedge = gpio_rcar_read(p, BOTHEDGE);
+
if (atomic_read(&p->wakeup_path))
device_set_wakeup_path(dev);
return 0;
}
-static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL);
+static int gpio_rcar_resume(struct device *dev)
+{
+ struct gpio_rcar_priv *p = dev_get_drvdata(dev);
+ unsigned int offset;
+ u32 mask;
+
+ for (offset = 0; offset < p->gpio_chip.ngpio; offset++) {
+ mask = BIT(offset);
+ /* I/O pin */
+ if (!(p->bank_info.iointsel & mask)) {
+ if (p->bank_info.inoutsel & mask)
+ gpio_rcar_direction_output(
+ &p->gpio_chip, offset,
+ !!(p->bank_info.outdt & mask));
+ else
+ gpio_rcar_direction_input(&p->gpio_chip,
+ offset);
+ } else {
+ /* Interrupt pin */
+ gpio_rcar_config_interrupt_input_mode(
+ p,
+ offset,
+ !(p->bank_info.posneg & mask),
+ !(p->bank_info.edglevel & mask),
+ !!(p->bank_info.bothedge & mask));
+
+ if (p->bank_info.intmsk & mask)
+ gpio_rcar_write(p, MSKCLR, mask);
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP*/
+
+static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, gpio_rcar_resume);
static struct platform_driver gpio_rcar_device_driver = {
.probe = gpio_rcar_probe,
diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c
new file mode 100644
index 000000000000..55072d2b367f
--- /dev/null
+++ b/drivers/gpio/gpio-sprd.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Spreadtrum Communications Inc.
+ * Copyright (C) 2018 Linaro Ltd.
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* GPIO registers definition */
+#define SPRD_GPIO_DATA 0x0
+#define SPRD_GPIO_DMSK 0x4
+#define SPRD_GPIO_DIR 0x8
+#define SPRD_GPIO_IS 0xc
+#define SPRD_GPIO_IBE 0x10
+#define SPRD_GPIO_IEV 0x14
+#define SPRD_GPIO_IE 0x18
+#define SPRD_GPIO_RIS 0x1c
+#define SPRD_GPIO_MIS 0x20
+#define SPRD_GPIO_IC 0x24
+#define SPRD_GPIO_INEN 0x28
+
+/* We have 16 banks GPIOs and each bank contain 16 GPIOs */
+#define SPRD_GPIO_BANK_NR 16
+#define SPRD_GPIO_NR 256
+#define SPRD_GPIO_BANK_SIZE 0x80
+#define SPRD_GPIO_BANK_MASK GENMASK(15, 0)
+#define SPRD_GPIO_BIT(x) ((x) & (SPRD_GPIO_BANK_NR - 1))
+
+struct sprd_gpio {
+ struct gpio_chip chip;
+ void __iomem *base;
+ spinlock_t lock;
+ int irq;
+};
+
+static inline void __iomem *sprd_gpio_bank_base(struct sprd_gpio *sprd_gpio,
+ unsigned int bank)
+{
+ return sprd_gpio->base + SPRD_GPIO_BANK_SIZE * bank;
+}
+
+static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset,
+ u16 reg, int val)
+{
+ struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+ void __iomem *base = sprd_gpio_bank_base(sprd_gpio,
+ offset / SPRD_GPIO_BANK_NR);
+ unsigned long flags;
+ u32 tmp;
+
+ spin_lock_irqsave(&sprd_gpio->lock, flags);
+ tmp = readl_relaxed(base + reg);
+
+ if (val)
+ tmp |= BIT(SPRD_GPIO_BIT(offset));
+ else
+ tmp &= ~BIT(SPRD_GPIO_BIT(offset));
+
+ writel_relaxed(tmp, base + reg);
+ spin_unlock_irqrestore(&sprd_gpio->lock, flags);
+}
+
+static int sprd_gpio_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
+{
+ struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+ void __iomem *base = sprd_gpio_bank_base(sprd_gpio,
+ offset / SPRD_GPIO_BANK_NR);
+
+ return !!(readl_relaxed(base + reg) & BIT(SPRD_GPIO_BIT(offset)));
+}
+
+static int sprd_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DMSK, 1);
+ return 0;
+}
+
+static void sprd_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DMSK, 0);
+}
+
+static int sprd_gpio_direction_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DIR, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_INEN, 1);
+ return 0;
+}
+
+static int sprd_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DIR, 1);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_INEN, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DATA, value);
+ return 0;
+}
+
+static int sprd_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ return sprd_gpio_read(chip, offset, SPRD_GPIO_DATA);
+}
+
+static void sprd_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ sprd_gpio_update(chip, offset, SPRD_GPIO_DATA, value);
+}
+
+static void sprd_gpio_irq_mask(struct irq_data *data)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+ u32 offset = irqd_to_hwirq(data);
+
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 0);
+}
+
+static void sprd_gpio_irq_ack(struct irq_data *data)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+ u32 offset = irqd_to_hwirq(data);
+
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IC, 1);
+}
+
+static void sprd_gpio_irq_unmask(struct irq_data *data)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+ u32 offset = irqd_to_hwirq(data);
+
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IE, 1);
+}
+
+static int sprd_gpio_irq_set_type(struct irq_data *data,
+ unsigned int flow_type)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+ u32 offset = irqd_to_hwirq(data);
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 1);
+ irq_set_handler_locked(data, handle_edge_irq);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 0);
+ irq_set_handler_locked(data, handle_edge_irq);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 1);
+ irq_set_handler_locked(data, handle_edge_irq);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 1);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 1);
+ irq_set_handler_locked(data, handle_level_irq);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 1);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0);
+ sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 0);
+ irq_set_handler_locked(data, handle_level_irq);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void sprd_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct gpio_chip *chip = irq_desc_get_handler_data(desc);
+ struct irq_chip *ic = irq_desc_get_chip(desc);
+ struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
+ u32 bank, n, girq;
+
+ chained_irq_enter(ic, desc);
+
+ for (bank = 0; bank * SPRD_GPIO_BANK_NR < chip->ngpio; bank++) {
+ void __iomem *base = sprd_gpio_bank_base(sprd_gpio, bank);
+ unsigned long reg = readl_relaxed(base + SPRD_GPIO_MIS) &
+ SPRD_GPIO_BANK_MASK;
+
+ for_each_set_bit(n, &reg, SPRD_GPIO_BANK_NR) {
+ girq = irq_find_mapping(chip->irq.domain,
+ bank * SPRD_GPIO_BANK_NR + n);
+
+ generic_handle_irq(girq);
+ }
+
+ }
+ chained_irq_exit(ic, desc);
+}
+
+static struct irq_chip sprd_gpio_irqchip = {
+ .name = "sprd-gpio",
+ .irq_ack = sprd_gpio_irq_ack,
+ .irq_mask = sprd_gpio_irq_mask,
+ .irq_unmask = sprd_gpio_irq_unmask,
+ .irq_set_type = sprd_gpio_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static int sprd_gpio_probe(struct platform_device *pdev)
+{
+ struct gpio_irq_chip *irq;
+ struct sprd_gpio *sprd_gpio;
+ struct resource *res;
+ int ret;
+
+ sprd_gpio = devm_kzalloc(&pdev->dev, sizeof(*sprd_gpio), GFP_KERNEL);
+ if (!sprd_gpio)
+ return -ENOMEM;
+
+ sprd_gpio->irq = platform_get_irq(pdev, 0);
+ if (sprd_gpio->irq < 0) {
+ dev_err(&pdev->dev, "Failed to get GPIO interrupt.\n");
+ return sprd_gpio->irq;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ sprd_gpio->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(sprd_gpio->base))
+ return PTR_ERR(sprd_gpio->base);
+
+ spin_lock_init(&sprd_gpio->lock);
+
+ sprd_gpio->chip.label = dev_name(&pdev->dev);
+ sprd_gpio->chip.ngpio = SPRD_GPIO_NR;
+ sprd_gpio->chip.base = -1;
+ sprd_gpio->chip.parent = &pdev->dev;
+ sprd_gpio->chip.of_node = pdev->dev.of_node;
+ sprd_gpio->chip.request = sprd_gpio_request;
+ sprd_gpio->chip.free = sprd_gpio_free;
+ sprd_gpio->chip.get = sprd_gpio_get;
+ sprd_gpio->chip.set = sprd_gpio_set;
+ sprd_gpio->chip.direction_input = sprd_gpio_direction_input;
+ sprd_gpio->chip.direction_output = sprd_gpio_direction_output;
+
+ irq = &sprd_gpio->chip.irq;
+ irq->chip = &sprd_gpio_irqchip;
+ irq->handler = handle_bad_irq;
+ irq->default_type = IRQ_TYPE_NONE;
+ irq->parent_handler = sprd_gpio_irq_handler;
+ irq->parent_handler_data = sprd_gpio;
+ irq->num_parents = 1;
+ irq->parents = &sprd_gpio->irq;
+
+ ret = devm_gpiochip_add_data(&pdev->dev, &sprd_gpio->chip, sprd_gpio);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Could not register gpiochip %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, sprd_gpio);
+ return 0;
+}
+
+static const struct of_device_id sprd_gpio_of_match[] = {
+ { .compatible = "sprd,sc9860-gpio", },
+ { /* end of list */ }
+};
+MODULE_DEVICE_TABLE(of, sprd_gpio_of_match);
+
+static struct platform_driver sprd_gpio_driver = {
+ .probe = sprd_gpio_probe,
+ .driver = {
+ .name = "sprd-gpio",
+ .of_match_table = sprd_gpio_of_match,
+ },
+};
+
+module_platform_driver_probe(sprd_gpio_driver, sprd_gpio_probe);
+
+MODULE_DESCRIPTION("Spreadtrum GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 02fa8fe2292a..94396caaca75 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -506,7 +506,7 @@ static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
#include <linux/debugfs.h>
#include <linux/seq_file.h>
-static int dbg_gpio_show(struct seq_file *s, void *unused)
+static int tegra_dbg_gpio_show(struct seq_file *s, void *unused)
{
struct tegra_gpio_info *tgi = s->private;
unsigned int i, j;
@@ -530,22 +530,12 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
return 0;
}
-static int dbg_gpio_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dbg_gpio_show, inode->i_private);
-}
-
-static const struct file_operations debug_fops = {
- .open = dbg_gpio_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(tegra_dbg_gpio);
static void tegra_gpio_debuginit(struct tegra_gpio_info *tgi)
{
(void) debugfs_create_file("tegra_gpio", 0444,
- NULL, tgi, &debug_fops);
+ NULL, tgi, &tegra_dbg_gpio_fops);
}
#else
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c
index 181f86ce00cd..6520a8475910 100644
--- a/drivers/gpio/gpio-timberdale.c
+++ b/drivers/gpio/gpio-timberdale.c
@@ -238,11 +238,10 @@ static int timbgpio_probe(struct platform_device *pdev)
return -EINVAL;
}
- tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL);
- if (!tgpio) {
- dev_err(dev, "Memory alloc failed\n");
+ tgpio = devm_kzalloc(dev, sizeof(*tgpio), GFP_KERNEL);
+ if (!tgpio)
return -EINVAL;
- }
+
tgpio->irq_base = pdata->irq_base;
spin_lock_init(&tgpio->lock);
diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c
index fa2662f8b026..aff6e504c666 100644
--- a/drivers/gpio/gpio-tps68470.c
+++ b/drivers/gpio/gpio-tps68470.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* GPIO driver for TPS68470 PMIC
*
@@ -8,15 +9,6 @@
* Tianshu Qiu <tian.shu.qiu@intel.com>
* Jian Xu Zheng <jian.xu.zheng@intel.com>
* Yuning Pu <yuning.pu@intel.com>
- *
- * 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.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/gpio/driver.h>
diff --git a/drivers/gpio/gpio-tz1090-pdc.c b/drivers/gpio/gpio-tz1090-pdc.c
deleted file mode 100644
index 5b7781741ee9..000000000000
--- a/drivers/gpio/gpio-tz1090-pdc.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Toumaz Xenif TZ1090 PDC GPIO handling.
- *
- * Copyright (C) 2012-2013 Imagination Technologies Ltd.
- *
- * 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.
- */
-
-#include <linux/bitops.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/syscore_ops.h>
-#include <asm/global_lock.h>
-
-/* Register offsets from SOC_GPIO_CONTROL0 */
-#define REG_SOC_GPIO_CONTROL0 0x00
-#define REG_SOC_GPIO_CONTROL1 0x04
-#define REG_SOC_GPIO_CONTROL2 0x08
-#define REG_SOC_GPIO_CONTROL3 0x0c
-#define REG_SOC_GPIO_STATUS 0x80
-
-/* PDC GPIOs go after normal GPIOs */
-#define GPIO_PDC_BASE 90
-#define GPIO_PDC_NGPIO 7
-
-/* Out of PDC gpios, only syswakes have irqs */
-#define GPIO_PDC_IRQ_FIRST 2
-#define GPIO_PDC_NIRQ 3
-
-/**
- * struct tz1090_pdc_gpio - GPIO bank private data
- * @chip: Generic GPIO chip for GPIO bank
- * @reg: Base of registers, offset for this GPIO bank
- * @irq: IRQ numbers for Syswake GPIOs
- *
- * This is the main private data for the PDC GPIO driver. It encapsulates a
- * gpio_chip, and the callbacks for the gpio_chip can access the private data
- * with the to_pdc() macro below.
- */
-struct tz1090_pdc_gpio {
- struct gpio_chip chip;
- void __iomem *reg;
- int irq[GPIO_PDC_NIRQ];
-};
-
-/* Register accesses into the PDC MMIO area */
-
-static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs,
- unsigned int data)
-{
- writel(data, priv->reg + reg_offs);
-}
-
-static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv,
- unsigned int reg_offs)
-{
- return readl(priv->reg + reg_offs);
-}
-
-/* Generic GPIO interface */
-
-static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip,
- unsigned int offset)
-{
- struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
- u32 value;
- int lstat;
-
- __global_lock2(lstat);
- value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
- value |= BIT(offset);
- pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
- __global_unlock2(lstat);
-
- return 0;
-}
-
-static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip,
- unsigned int offset,
- int output_value)
-{
- struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
- u32 value;
- int lstat;
-
- __global_lock2(lstat);
- /* EXT_POWER doesn't seem to have an output value bit */
- if (offset < 6) {
- value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
- if (output_value)
- value |= BIT(offset);
- else
- value &= ~BIT(offset);
- pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
- }
-
- value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
- value &= ~BIT(offset);
- pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
- __global_unlock2(lstat);
-
- return 0;
-}
-
-static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
- return !!(pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset));
-}
-
-static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int output_value)
-{
- struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
- u32 value;
- int lstat;
-
- /* EXT_POWER doesn't seem to have an output value bit */
- if (offset >= 6)
- return;
-
- __global_lock2(lstat);
- value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
- if (output_value)
- value |= BIT(offset);
- else
- value &= ~BIT(offset);
- pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
- __global_unlock2(lstat);
-}
-
-static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
- unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST;
- int irq;
-
- /* only syswakes have irqs */
- if (syswake >= GPIO_PDC_NIRQ)
- return -EINVAL;
-
- irq = priv->irq[syswake];
- if (!irq)
- return -EINVAL;
-
- return irq;
-}
-
-static int tz1090_pdc_gpio_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct resource *res_regs;
- struct tz1090_pdc_gpio *priv;
- unsigned int i;
-
- if (!np) {
- dev_err(&pdev->dev, "must be instantiated via devicetree\n");
- return -ENOENT;
- }
-
- res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res_regs) {
- dev_err(&pdev->dev, "cannot find registers resource\n");
- return -ENOENT;
- }
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "unable to allocate driver data\n");
- return -ENOMEM;
- }
-
- /* Ioremap the registers */
- priv->reg = devm_ioremap(&pdev->dev, res_regs->start,
- resource_size(res_regs));
- if (!priv->reg) {
- dev_err(&pdev->dev, "unable to ioremap registers\n");
- return -ENOMEM;
- }
-
- /* Set up GPIO chip */
- priv->chip.label = "tz1090-pdc-gpio";
- priv->chip.parent = &pdev->dev;
- priv->chip.direction_input = tz1090_pdc_gpio_direction_input;
- priv->chip.direction_output = tz1090_pdc_gpio_direction_output;
- priv->chip.get = tz1090_pdc_gpio_get;
- priv->chip.set = tz1090_pdc_gpio_set;
- priv->chip.free = gpiochip_generic_free;
- priv->chip.request = gpiochip_generic_request;
- priv->chip.to_irq = tz1090_pdc_gpio_to_irq;
- priv->chip.of_node = np;
-
- /* GPIO numbering */
- priv->chip.base = GPIO_PDC_BASE;
- priv->chip.ngpio = GPIO_PDC_NGPIO;
-
- /* Map the syswake irqs */
- for (i = 0; i < GPIO_PDC_NIRQ; ++i)
- priv->irq[i] = irq_of_parse_and_map(np, i);
-
- /* Add the GPIO bank */
- gpiochip_add_data(&priv->chip, priv);
-
- return 0;
-}
-
-static struct of_device_id tz1090_pdc_gpio_of_match[] = {
- { .compatible = "img,tz1090-pdc-gpio" },
- { },
-};
-
-static struct platform_driver tz1090_pdc_gpio_driver = {
- .driver = {
- .name = "tz1090-pdc-gpio",
- .of_match_table = tz1090_pdc_gpio_of_match,
- },
- .probe = tz1090_pdc_gpio_probe,
-};
-
-static int __init tz1090_pdc_gpio_init(void)
-{
- return platform_driver_register(&tz1090_pdc_gpio_driver);
-}
-subsys_initcall(tz1090_pdc_gpio_init);
diff --git a/drivers/gpio/gpio-tz1090.c b/drivers/gpio/gpio-tz1090.c
deleted file mode 100644
index 0bb9bb583889..000000000000
--- a/drivers/gpio/gpio-tz1090.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Toumaz Xenif TZ1090 GPIO handling.
- *
- * Copyright (C) 2008-2013 Imagination Technologies Ltd.
- *
- * Based on ARM PXA code and others.
- *
- * 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.
- */
-
-#include <linux/bitops.h>
-#include <linux/export.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/kernel.h>
-#include <linux/of_irq.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/syscore_ops.h>
-#include <asm/global_lock.h>
-
-/* Register offsets from bank base address */
-#define REG_GPIO_DIR 0x00
-#define REG_GPIO_IRQ_PLRT 0x20
-#define REG_GPIO_IRQ_TYPE 0x30
-#define REG_GPIO_IRQ_EN 0x40
-#define REG_GPIO_IRQ_STS 0x50
-#define REG_GPIO_BIT_EN 0x60
-#define REG_GPIO_DIN 0x70
-#define REG_GPIO_DOUT 0x80
-
-/* REG_GPIO_IRQ_PLRT */
-#define REG_GPIO_IRQ_PLRT_LOW 0
-#define REG_GPIO_IRQ_PLRT_HIGH 1
-
-/* REG_GPIO_IRQ_TYPE */
-#define REG_GPIO_IRQ_TYPE_LEVEL 0
-#define REG_GPIO_IRQ_TYPE_EDGE 1
-
-/**
- * struct tz1090_gpio_bank - GPIO bank private data
- * @chip: Generic GPIO chip for GPIO bank
- * @domain: IRQ domain for GPIO bank (may be NULL)
- * @reg: Base of registers, offset for this GPIO bank
- * @irq: IRQ number for GPIO bank
- * @label: Debug GPIO bank label, used for storage of chip->label
- *
- * This is the main private data for a GPIO bank. It encapsulates a gpio_chip,
- * and the callbacks for the gpio_chip can access the private data with the
- * to_bank() macro below.
- */
-struct tz1090_gpio_bank {
- struct gpio_chip chip;
- struct irq_domain *domain;
- void __iomem *reg;
- int irq;
- char label[16];
-};
-
-/**
- * struct tz1090_gpio - Overall GPIO device private data
- * @dev: Device (from platform device)
- * @reg: Base of GPIO registers
- *
- * Represents the overall GPIO device. This structure is actually only
- * temporary, and used during init.
- */
-struct tz1090_gpio {
- struct device *dev;
- void __iomem *reg;
-};
-
-/**
- * struct tz1090_gpio_bank_info - Temporary registration info for GPIO bank
- * @priv: Overall GPIO device private data
- * @node: Device tree node specific to this GPIO bank
- * @index: Index of bank in range 0-2
- */
-struct tz1090_gpio_bank_info {
- struct tz1090_gpio *priv;
- struct device_node *node;
- unsigned int index;
-};
-
-/* Convenience register accessors */
-static inline void tz1090_gpio_write(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs, u32 data)
-{
- iowrite32(data, bank->reg + reg_offs);
-}
-
-static inline u32 tz1090_gpio_read(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs)
-{
- return ioread32(bank->reg + reg_offs);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_clear_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset)
-{
- u32 value;
-
- value = tz1090_gpio_read(bank, reg_offs);
- value &= ~BIT(offset);
- tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_clear_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset)
-{
- int lstat;
-
- __global_lock2(lstat);
- _tz1090_gpio_clear_bit(bank, reg_offs, offset);
- __global_unlock2(lstat);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_set_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset)
-{
- u32 value;
-
- value = tz1090_gpio_read(bank, reg_offs);
- value |= BIT(offset);
- tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_set_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset)
-{
- int lstat;
-
- __global_lock2(lstat);
- _tz1090_gpio_set_bit(bank, reg_offs, offset);
- __global_unlock2(lstat);
-}
-
-/* caller must hold LOCK2 */
-static inline void _tz1090_gpio_mod_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset,
- bool val)
-{
- u32 value;
-
- value = tz1090_gpio_read(bank, reg_offs);
- value &= ~BIT(offset);
- if (val)
- value |= BIT(offset);
- tz1090_gpio_write(bank, reg_offs, value);
-}
-
-static void tz1090_gpio_mod_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset,
- bool val)
-{
- int lstat;
-
- __global_lock2(lstat);
- _tz1090_gpio_mod_bit(bank, reg_offs, offset, val);
- __global_unlock2(lstat);
-}
-
-static inline int tz1090_gpio_read_bit(struct tz1090_gpio_bank *bank,
- unsigned int reg_offs,
- unsigned int offset)
-{
- return tz1090_gpio_read(bank, reg_offs) & BIT(offset);
-}
-
-/* GPIO chip callbacks */
-
-static int tz1090_gpio_direction_input(struct gpio_chip *chip,
- unsigned int offset)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
- tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
-
- return 0;
-}
-
-static int tz1090_gpio_direction_output(struct gpio_chip *chip,
- unsigned int offset, int output_value)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
- int lstat;
-
- __global_lock2(lstat);
- _tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
- _tz1090_gpio_clear_bit(bank, REG_GPIO_DIR, offset);
- __global_unlock2(lstat);
-
- return 0;
-}
-
-/*
- * Return GPIO level
- */
-static int tz1090_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
- return !!tz1090_gpio_read_bit(bank, REG_GPIO_DIN, offset);
-}
-
-/*
- * Set output GPIO level
- */
-static void tz1090_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int output_value)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
- tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
-}
-
-static int tz1090_gpio_request(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
- int ret;
-
- ret = pinctrl_gpio_request(chip->base + offset);
- if (ret)
- return ret;
-
- tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
- tz1090_gpio_set_bit(bank, REG_GPIO_BIT_EN, offset);
-
- return 0;
-}
-
-static void tz1090_gpio_free(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
- pinctrl_gpio_free(chip->base + offset);
-
- tz1090_gpio_clear_bit(bank, REG_GPIO_BIT_EN, offset);
-}
-
-static int tz1090_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
- struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
-
- if (!bank->domain)
- return -EINVAL;
-
- return irq_create_mapping(bank->domain, offset);
-}
-
-/* IRQ chip handlers */
-
-/* Get TZ1090 GPIO chip from irq data provided to generic IRQ callbacks */
-static inline struct tz1090_gpio_bank *irqd_to_gpio_bank(struct irq_data *data)
-{
- return (struct tz1090_gpio_bank *)data->domain->host_data;
-}
-
-static void tz1090_gpio_irq_polarity(struct tz1090_gpio_bank *bank,
- unsigned int offset, unsigned int polarity)
-{
- tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_PLRT, offset, polarity);
-}
-
-static void tz1090_gpio_irq_type(struct tz1090_gpio_bank *bank,
- unsigned int offset, unsigned int type)
-{
- tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_TYPE, offset, type);
-}
-
-/* set polarity to trigger on next edge, whether rising or falling */
-static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
- unsigned int offset)
-{
- unsigned int value_p, value_i;
- int lstat;
-
- /*
- * Set the GPIO's interrupt polarity to the opposite of the current
- * input value so that the next edge triggers an interrupt.
- */
- __global_lock2(lstat);
- value_i = ~tz1090_gpio_read(bank, REG_GPIO_DIN);
- value_p = tz1090_gpio_read(bank, REG_GPIO_IRQ_PLRT);
- value_p &= ~BIT(offset);
- value_p |= value_i & BIT(offset);
- tz1090_gpio_write(bank, REG_GPIO_IRQ_PLRT, value_p);
- __global_unlock2(lstat);
-}
-
-static unsigned int gpio_startup_irq(struct irq_data *data)
-{
- /*
- * This warning indicates that the type of the irq hasn't been set
- * before enabling the irq. This would normally be done by passing some
- * trigger flags to request_irq().
- */
- WARN(irqd_get_trigger_type(data) == IRQ_TYPE_NONE,
- "irq type not set before enabling gpio irq %d", data->irq);
-
- irq_gc_ack_clr_bit(data);
- irq_gc_mask_set_bit(data);
- return 0;
-}
-
-static int gpio_set_irq_type(struct irq_data *data, unsigned int flow_type)
-{
- struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
- unsigned int type;
- unsigned int polarity;
-
- switch (flow_type) {
- case IRQ_TYPE_EDGE_BOTH:
- type = REG_GPIO_IRQ_TYPE_EDGE;
- polarity = REG_GPIO_IRQ_PLRT_LOW;
- break;
- case IRQ_TYPE_EDGE_RISING:
- type = REG_GPIO_IRQ_TYPE_EDGE;
- polarity = REG_GPIO_IRQ_PLRT_HIGH;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- type = REG_GPIO_IRQ_TYPE_EDGE;
- polarity = REG_GPIO_IRQ_PLRT_LOW;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- type = REG_GPIO_IRQ_TYPE_LEVEL;
- polarity = REG_GPIO_IRQ_PLRT_HIGH;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- type = REG_GPIO_IRQ_TYPE_LEVEL;
- polarity = REG_GPIO_IRQ_PLRT_LOW;
- break;
- default:
- return -EINVAL;
- }
-
- tz1090_gpio_irq_type(bank, data->hwirq, type);
- irq_setup_alt_chip(data, flow_type);
-
- if (flow_type == IRQ_TYPE_EDGE_BOTH)
- tz1090_gpio_irq_next_edge(bank, data->hwirq);
- else
- tz1090_gpio_irq_polarity(bank, data->hwirq, polarity);
-
- return 0;
-}
-
-#ifdef CONFIG_SUSPEND
-static int gpio_set_irq_wake(struct irq_data *data, unsigned int on)
-{
- struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
-
-#ifdef CONFIG_PM_DEBUG
- pr_info("irq_wake irq%d state:%d\n", data->irq, on);
-#endif
-
- /* wake on gpio block interrupt */
- return irq_set_irq_wake(bank->irq, on);
-}
-#else
-#define gpio_set_irq_wake NULL
-#endif
-
-static void tz1090_gpio_irq_handler(struct irq_desc *desc)
-{
- irq_hw_number_t hw;
- unsigned int irq_stat, irq_no;
- struct tz1090_gpio_bank *bank;
- struct irq_desc *child_desc;
-
- bank = (struct tz1090_gpio_bank *)irq_desc_get_handler_data(desc);
- irq_stat = tz1090_gpio_read(bank, REG_GPIO_DIR) &
- tz1090_gpio_read(bank, REG_GPIO_IRQ_STS) &
- tz1090_gpio_read(bank, REG_GPIO_IRQ_EN) &
- 0x3FFFFFFF; /* 30 bits only */
-
- for (hw = 0; irq_stat; irq_stat >>= 1, ++hw) {
- if (!(irq_stat & 1))
- continue;
-
- irq_no = irq_linear_revmap(bank->domain, hw);
- child_desc = irq_to_desc(irq_no);
-
- /* Toggle edge for pin with both edges triggering enabled */
- if (irqd_get_trigger_type(&child_desc->irq_data)
- == IRQ_TYPE_EDGE_BOTH)
- tz1090_gpio_irq_next_edge(bank, hw);
-
- generic_handle_irq_desc(child_desc);
- }
-}
-
-static int tz1090_gpio_bank_probe(struct tz1090_gpio_bank_info *info)
-{
- struct device_node *np = info->node;
- struct device *dev = info->priv->dev;
- struct tz1090_gpio_bank *bank;
- struct irq_chip_generic *gc;
- int err;
-
- bank = devm_kzalloc(dev, sizeof(*bank), GFP_KERNEL);
- if (!bank) {
- dev_err(dev, "unable to allocate driver data\n");
- return -ENOMEM;
- }
-
- /* Offset the main registers to the first register in this bank */
- bank->reg = info->priv->reg + info->index * 4;
-
- /* Set up GPIO chip */
- snprintf(bank->label, sizeof(bank->label), "tz1090-gpio-%u",
- info->index);
- bank->chip.label = bank->label;
- bank->chip.parent = dev;
- bank->chip.direction_input = tz1090_gpio_direction_input;
- bank->chip.direction_output = tz1090_gpio_direction_output;
- bank->chip.get = tz1090_gpio_get;
- bank->chip.set = tz1090_gpio_set;
- bank->chip.free = tz1090_gpio_free;
- bank->chip.request = tz1090_gpio_request;
- bank->chip.to_irq = tz1090_gpio_to_irq;
- bank->chip.of_node = np;
-
- /* GPIO numbering from 0 */
- bank->chip.base = info->index * 30;
- bank->chip.ngpio = 30;
-
- /* Add the GPIO bank */
- gpiochip_add_data(&bank->chip, bank);
-
- /* Get the GPIO bank IRQ if provided */
- bank->irq = irq_of_parse_and_map(np, 0);
-
- /* The interrupt is optional (it may be used by another core on chip) */
- if (!bank->irq) {
- dev_info(dev, "IRQ not provided for bank %u, IRQs disabled\n",
- info->index);
- return 0;
- }
-
- dev_info(dev, "Setting up IRQs for GPIO bank %u\n",
- info->index);
-
- /*
- * Initialise all interrupts to disabled so we don't get
- * spurious ones on a dirty boot and hit the BUG_ON in the
- * handler.
- */
- tz1090_gpio_write(bank, REG_GPIO_IRQ_EN, 0);
-
- /* Add a virtual IRQ for each GPIO */
- bank->domain = irq_domain_add_linear(np,
- bank->chip.ngpio,
- &irq_generic_chip_ops,
- bank);
-
- /* Set up a generic irq chip with 2 chip types (level and edge) */
- err = irq_alloc_domain_generic_chips(bank->domain, bank->chip.ngpio, 2,
- bank->label, handle_bad_irq, 0, 0,
- IRQ_GC_INIT_NESTED_LOCK);
- if (err) {
- dev_info(dev,
- "irq_alloc_domain_generic_chips failed for bank %u, IRQs disabled\n",
- info->index);
- irq_domain_remove(bank->domain);
- return 0;
- }
-
- gc = irq_get_domain_generic_chip(bank->domain, 0);
- gc->reg_base = bank->reg;
-
- /* level chip type */
- gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
- gc->chip_types[0].handler = handle_level_irq;
- gc->chip_types[0].regs.ack = REG_GPIO_IRQ_STS;
- gc->chip_types[0].regs.mask = REG_GPIO_IRQ_EN;
- gc->chip_types[0].chip.irq_startup = gpio_startup_irq;
- gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit;
- gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
- gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
- gc->chip_types[0].chip.irq_set_type = gpio_set_irq_type;
- gc->chip_types[0].chip.irq_set_wake = gpio_set_irq_wake;
- gc->chip_types[0].chip.flags = IRQCHIP_MASK_ON_SUSPEND;
-
- /* edge chip type */
- gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
- gc->chip_types[1].handler = handle_edge_irq;
- gc->chip_types[1].regs.ack = REG_GPIO_IRQ_STS;
- gc->chip_types[1].regs.mask = REG_GPIO_IRQ_EN;
- gc->chip_types[1].chip.irq_startup = gpio_startup_irq;
- gc->chip_types[1].chip.irq_ack = irq_gc_ack_clr_bit;
- gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit;
- gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit;
- gc->chip_types[1].chip.irq_set_type = gpio_set_irq_type;
- gc->chip_types[1].chip.irq_set_wake = gpio_set_irq_wake;
- gc->chip_types[1].chip.flags = IRQCHIP_MASK_ON_SUSPEND;
-
- /* Setup chained handler for this GPIO bank */
- irq_set_chained_handler_and_data(bank->irq, tz1090_gpio_irq_handler,
- bank);
-
- return 0;
-}
-
-static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
-{
- struct device_node *np = priv->dev->of_node;
- struct device_node *node;
-
- for_each_available_child_of_node(np, node) {
- struct tz1090_gpio_bank_info info;
- u32 addr;
- int ret;
-
- ret = of_property_read_u32(node, "reg", &addr);
- if (ret) {
- dev_err(priv->dev, "invalid reg on %pOF\n", node);
- continue;
- }
- if (addr >= 3) {
- dev_err(priv->dev, "index %u in %pOF out of range\n",
- addr, node);
- continue;
- }
-
- info.index = addr;
- info.node = of_node_get(node);
- info.priv = priv;
-
- ret = tz1090_gpio_bank_probe(&info);
- if (ret) {
- dev_err(priv->dev, "failure registering %pOF\n", node);
- of_node_put(node);
- continue;
- }
- }
-}
-
-static int tz1090_gpio_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct resource *res_regs;
- struct tz1090_gpio priv;
-
- if (!np) {
- dev_err(&pdev->dev, "must be instantiated via devicetree\n");
- return -ENOENT;
- }
-
- res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res_regs) {
- dev_err(&pdev->dev, "cannot find registers resource\n");
- return -ENOENT;
- }
-
- priv.dev = &pdev->dev;
-
- /* Ioremap the registers */
- priv.reg = devm_ioremap(&pdev->dev, res_regs->start,
- resource_size(res_regs));
- if (!priv.reg) {
- dev_err(&pdev->dev, "unable to ioremap registers\n");
- return -ENOMEM;
- }
-
- /* Look for banks */
- tz1090_gpio_register_banks(&priv);
-
- return 0;
-}
-
-static struct of_device_id tz1090_gpio_of_match[] = {
- { .compatible = "img,tz1090-gpio" },
- { },
-};
-
-static struct platform_driver tz1090_gpio_driver = {
- .driver = {
- .name = "tz1090-gpio",
- .of_match_table = tz1090_gpio_of_match,
- },
- .probe = tz1090_gpio_probe,
-};
-
-static int __init tz1090_gpio_init(void)
-{
- return platform_driver_register(&tz1090_gpio_driver);
-}
-subsys_initcall(tz1090_gpio_init);
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c
index 938bbe3f831c..324813e8304e 100644
--- a/drivers/gpio/gpio-wm831x.c
+++ b/drivers/gpio/gpio-wm831x.c
@@ -182,7 +182,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
dev_err(wm831x->dev,
"GPIO control %d read failed: %d\n",
gpio, reg);
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
continue;
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d66de67ef307..f220d844b607 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3689,7 +3689,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
}
if (IS_ERR(desc)) {
- dev_dbg(dev, "lookup for GPIO %s failed\n", con_id);
+ dev_dbg(dev, "No GPIO consumer %s found\n", con_id);
return desc;
}
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index b17ec6795c81..ad456b6f9d8b 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -13,13 +13,13 @@
#define GPIOLIB_H
#include <linux/gpio/driver.h>
+#include <linux/gpio/consumer.h> /* for enum gpiod_flags */
#include <linux/err.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/cdev.h>
enum of_gpio_flags;
-enum gpiod_flags;
enum gpio_lookup_flags;
struct acpi_device;
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 72bc2b71765a..aa333184ddcf 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -698,7 +698,8 @@ config STM32_DFSDM_ADC
config STX104
tristate "Apex Embedded Systems STX104 driver"
- depends on PC104 && X86 && ISA_BUS_API
+ depends on PC104 && X86
+ select ISA_BUS_API
select GPIOLIB
help
Say yes here to build support for the Apex Embedded Systems STX104
diff --git a/drivers/iio/counter/Kconfig b/drivers/iio/counter/Kconfig
index 474e1ac4e7c0..bf1e559ad7cd 100644
--- a/drivers/iio/counter/Kconfig
+++ b/drivers/iio/counter/Kconfig
@@ -7,7 +7,8 @@ menu "Counters"
config 104_QUAD_8
tristate "ACCES 104-QUAD-8 driver"
- depends on PC104 && X86 && ISA_BUS_API
+ depends on PC104 && X86
+ select ISA_BUS_API
help
Say yes here to build support for the ACCES 104-QUAD-8 quadrature
encoder counter/interface device family (104-QUAD-8, 104-QUAD-4).
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 965d5c0d2468..76db0768e454 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -195,7 +195,8 @@ config AD7303
config CIO_DAC
tristate "Measurement Computing CIO-DAC IIO driver"
- depends on X86 && ISA_BUS_API
+ depends on X86 && (ISA_BUS || PC104)
+ select ISA_BUS_API
help
Say yes here to build support for the Measurement Computing CIO-DAC
analog output device family (CIO-DAC16, CIO-DAC08, PC104-DAC06). The
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 37460cd6cabb..c9f5e778c05e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -883,7 +883,8 @@ config ALIM7101_WDT
config EBC_C384_WDT
tristate "WinSystems EBC-C384 Watchdog Timer"
- depends on X86 && ISA_BUS_API
+ depends on X86
+ select ISA_BUS_API
select WATCHDOG_CORE
help
Enables watchdog timer support for the watchdog timer on the
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index cb979ad90401..50df5b28d2c9 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -63,6 +63,7 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008,
RPI_FIRMWARE_GET_TURBO = 0x00030009,
RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a,
+ RPI_FIRMWARE_GET_STC = 0x0003000b,
RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c,
RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d,
RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e,
@@ -72,12 +73,22 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012,
RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014,
RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020,
+ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021,
RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030,
RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001,
RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002,
RPI_FIRMWARE_SET_VOLTAGE = 0x00038003,
RPI_FIRMWARE_SET_TURBO = 0x00038009,
+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021,
RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030,
+ RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041,
+ RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041,
+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042,
+ RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043,
+ RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043,
+ RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045,
+ RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045,
+
/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
@@ -91,6 +102,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009,
RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a,
RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b,
+ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f,
+ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010,
RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001,
RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004,
@@ -100,6 +113,7 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009,
RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a,
RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b,
+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e,
RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003,
RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004,
RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005,
@@ -108,6 +122,10 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009,
RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a,
RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,
RPI_FIRMWARE_VCHIQ_INIT = 0x00048010,
diff --git a/init/Kconfig b/init/Kconfig
index e37f4b2a6445..221cac95044f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1438,7 +1438,7 @@ config PERF_USE_VMALLOC
See tools/perf/design.txt for details
config PC104
- bool "PC/104 support"
+ bool "PC/104 support" if EXPERT
help
Expose PC/104 form factor device drivers and options available for
selection and configuration. Enable this option if your target
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index dac4d4131d9b..c864544efe05 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -99,7 +99,7 @@ int monitor_device(const char *device_name,
ret = -EIO;
break;
}
- fprintf(stdout, "GPIO EVENT %" PRIu64 ": ", event.timestamp);
+ fprintf(stdout, "GPIO EVENT %llu: ", event.timestamp);
switch (event.id) {
case GPIOEVENT_EVENT_RISING_EDGE:
fprintf(stdout, "rising edge");