diff options
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, ®, 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"); |