diff options
author | Peter Robinson <pbrobinson@gmail.com> | 2018-03-03 22:51:13 +0000 |
---|---|---|
committer | Peter Robinson <pbrobinson@gmail.com> | 2018-03-03 22:51:13 +0000 |
commit | 60e272367a705ccdb067c5b1e33f28dfb9fea0b9 (patch) | |
tree | b03ec11acd4b265daf323239ff788394a8354b60 /bcm283x-gpio-expander.patch | |
parent | 5860e766a687094612f3c37a219f248078148541 (diff) | |
download | kernel-60e272367a705ccdb067c5b1e33f28dfb9fea0b9.tar.gz kernel-60e272367a705ccdb067c5b1e33f28dfb9fea0b9.tar.xz kernel-60e272367a705ccdb067c5b1e33f28dfb9fea0b9.zip |
Add RPi3 GPIO expander, RPi fixes, OMAP serial update, general ARM fixes
Diffstat (limited to 'bcm283x-gpio-expander.patch')
-rw-r--r-- | bcm283x-gpio-expander.patch | 638 |
1 files changed, 638 insertions, 0 deletions
diff --git a/bcm283x-gpio-expander.patch b/bcm283x-gpio-expander.patch new file mode 100644 index 000000000..55b7ec4d7 --- /dev/null +++ b/bcm283x-gpio-expander.patch @@ -0,0 +1,638 @@ +From patchwork Tue Feb 20 12:19:31 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v5,1/5] ARM: bcm2835: sync firmware properties with downstream +From: Baruch Siach <baruch@tkos.co.il> +X-Patchwork-Id: 10229963 +Message-Id: <e7d1f1d0789f11d37957a8998bee23d035115aeb.1519128054.git.baruch@tkos.co.il> +To: Linus Walleij <linus.walleij@linaro.org>, + Dave Stevenson <dave.stevenson@raspberrypi.org>, + Eric Anholt <eric@anholt.net>, Stefan Wahren <stefan.wahren@i2se.com> +Cc: devicetree@vger.kernel.org, Baruch Siach <baruch@tkos.co.il>, + linux-gpio@vger.kernel.org, Michael Zoran <mzoran@crowfest.net>, + Rob Herring <robh+dt@kernel.org>, linux-rpi-kernel@lists.infradead.org, + Frank Rowand <frowand.list@gmail.com>, linux-arm-kernel@lists.infradead.org +Date: Tue, 20 Feb 2018 14:19:31 +0200 + +Add latest firmware property tags from the latest Raspberry Pi downstream +kernel. This is needed for the GPIO tags, so we can control the GPIO +multiplexor lines. + +Acked-by: Stefan Wahren <stefan.wahren@i2se.com> +Signed-off-by: Baruch Siach <baruch@tkos.co.il> +--- +v4: No change + +v3: Add Stefan's ack + +v2: No change +--- + include/soc/bcm2835/raspberrypi-firmware.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +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, + +From patchwork Tue Feb 20 12:19:32 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v5,2/5] dt-bindings: gpio: add raspberry pi GPIO expander binding +From: Baruch Siach <baruch@tkos.co.il> +X-Patchwork-Id: 10229965 +Message-Id: <f400b48cbcd8a138c39d4e8f63d6c1f569090dcc.1519128054.git.baruch@tkos.co.il> +To: Linus Walleij <linus.walleij@linaro.org>, + Dave Stevenson <dave.stevenson@raspberrypi.org>, + Eric Anholt <eric@anholt.net>, Stefan Wahren <stefan.wahren@i2se.com> +Cc: devicetree@vger.kernel.org, Baruch Siach <baruch@tkos.co.il>, + linux-gpio@vger.kernel.org, Michael Zoran <mzoran@crowfest.net>, + Rob Herring <robh+dt@kernel.org>, linux-rpi-kernel@lists.infradead.org, + Frank Rowand <frowand.list@gmail.com>, linux-arm-kernel@lists.infradead.org +Date: Tue, 20 Feb 2018 14:19:32 +0200 + +The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware over +I2C. The firmware mailbox interface allows the ARM core to control the +GPIO lines. + +Signed-off-by: Baruch Siach <baruch@tkos.co.il> +Reviewed-by: Rob Herring <robh@kernel.org> +--- +v5: + * Remove the 'firmware' property + * Note that the gpio node is a child of the firmware node + +v4: + * Move the example gpio node under the firmware node + * Rename gpio node name to plain 'gpio' + +v3: + * Rename node name. + +v2: + * Rename compatible string to raspberrypi,firmware-gpio +--- + .../bindings/gpio/raspberrypi,firmware-gpio.txt | 30 ++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + create mode 100644 Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt + +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>; ++ }; ++}; +From patchwork Tue Feb 20 12:19:33 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v5, + 3/5] gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox + service +From: Baruch Siach <baruch@tkos.co.il> +X-Patchwork-Id: 10229967 +Message-Id: <8c34f287ee72b340fa9d693aa0e304b25541c74c.1519128054.git.baruch@tkos.co.il> +To: Linus Walleij <linus.walleij@linaro.org>, + Dave Stevenson <dave.stevenson@raspberrypi.org>, + Eric Anholt <eric@anholt.net>, Stefan Wahren <stefan.wahren@i2se.com> +Cc: devicetree@vger.kernel.org, Baruch Siach <baruch@tkos.co.il>, + linux-gpio@vger.kernel.org, Michael Zoran <mzoran@crowfest.net>, + Rob Herring <robh+dt@kernel.org>, linux-rpi-kernel@lists.infradead.org, + Frank Rowand <frowand.list@gmail.com>, linux-arm-kernel@lists.infradead.org +Date: Tue, 20 Feb 2018 14:19:33 +0200 + +From: Dave Stevenson <dave.stevenson@raspberrypi.org> + +Pi3 and Compute Module 3 have a GPIO expander that the +VPU communicates with. +There is a mailbox service that now allows control of this +expander, so add a kernel driver that can make use of it. + +Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com> +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> +Signed-off-by: Baruch Siach <baruch@tkos.co.il> +--- +v5: + * Use the parent node to find the firmware + +v4: + * Don't set the .owner driver field + * Add Stefan's review tag + +v3: + * Tweak Kconfig driver prompt + * Make GPIO_RASPBERRYPI_EXP tristate + * Make COMPILE_TEST independent of RASPBERRYPI_FIRMWARE + * Remove redundant DMA header + * Use less code lines for dev_err() + * Check rpi_exp_gpio_get_polarity() return value + * Remove redundant platform_set_drvdata() call + +v2: + * Rename driver to gpio-raspberrypi-exp + * Populate the gpiochip parent device pointer + * Use macro for the mailbox base GPIO number + * Drop linux/gpio.h and GPIOF_DIR_* + * Check and print firmware error value + * Use devm_gpiochip_add_data(); drop .remove + * A few more minor tweaks +--- + drivers/gpio/Kconfig | 9 ++ + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-raspberrypi-exp.c | 252 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 262 insertions(+) + create mode 100644 drivers/gpio/gpio-raspberrypi-exp.c + +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index 8dbb2280538d..fd0562a37f68 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -122,6 +122,15 @@ 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 ++ depends on (ARCH_BCM2835 && RASPBERRYPI_FIRMWARE) || COMPILE_TEST ++ 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) +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index cccb0d40846c..76dc0a02bd56 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 +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"); +From patchwork Tue Feb 20 12:19:34 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v5,4/5] ARM: dts: bcm2835: make the firmware node into a bus +From: Baruch Siach <baruch@tkos.co.il> +X-Patchwork-Id: 10229961 +Message-Id: <43f9082a6835df6d7bcd3e16d79db687c52826d2.1519128054.git.baruch@tkos.co.il> +To: Linus Walleij <linus.walleij@linaro.org>, + Dave Stevenson <dave.stevenson@raspberrypi.org>, + Eric Anholt <eric@anholt.net>, Stefan Wahren <stefan.wahren@i2se.com> +Cc: devicetree@vger.kernel.org, Baruch Siach <baruch@tkos.co.il>, + linux-gpio@vger.kernel.org, Michael Zoran <mzoran@crowfest.net>, + Rob Herring <robh+dt@kernel.org>, linux-rpi-kernel@lists.infradead.org, + Frank Rowand <frowand.list@gmail.com>, linux-arm-kernel@lists.infradead.org +Date: Tue, 20 Feb 2018 14:19:34 +0200 + +This allows adding devices for which the firmware exposes control interface +via the mailbox. An example of such device is the GPIO expander. + +Signed-off-by: Baruch Siach <baruch@tkos.co.il> +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +--- +v4: New patch in this series +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index e36c392a2b8f..0198bd46ef7c 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -18,7 +18,9 @@ + + soc { + firmware: firmware { +- compatible = "raspberrypi,bcm2835-firmware"; ++ compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; ++ #address-cells = <0>; ++ #size-cells = <0>; + mboxes = <&mailbox>; + }; + +From patchwork Tue Feb 20 12:19:35 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v5,5/5] ARM: dts: bcm2837-rpi-3-b: add GPIO expander +From: Baruch Siach <baruch@tkos.co.il> +X-Patchwork-Id: 10229995 +Message-Id: <a6d59692dc4847e0b1639a26542e28c95ad5240f.1519128054.git.baruch@tkos.co.il> +To: Linus Walleij <linus.walleij@linaro.org>, + Dave Stevenson <dave.stevenson@raspberrypi.org>, + Eric Anholt <eric@anholt.net>, Stefan Wahren <stefan.wahren@i2se.com> +Cc: devicetree@vger.kernel.org, Baruch Siach <baruch@tkos.co.il>, + linux-gpio@vger.kernel.org, Michael Zoran <mzoran@crowfest.net>, + Rob Herring <robh+dt@kernel.org>, linux-rpi-kernel@lists.infradead.org, + Frank Rowand <frowand.list@gmail.com>, linux-arm-kernel@lists.infradead.org +Date: Tue, 20 Feb 2018 14:19:35 +0200 + +Add a description of the RPi3 GPIO expander that the VC4 firmware controls. + +Acked-by: Stefan Wahren <stefan.wahren@i2se.com> +Signed-off-by: Baruch Siach <baruch@tkos.co.il> +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +--- +v5: + * Drop the 'firmware' property + +v4: + * Move the gpio node under the firmware node + * Rename the gpio node to plain 'gpio' + * Add Stefan's ack + +v3: + * List GPIO names one per line. + +v2: + * Move GPIO expander node out of the soc container + * Rename compatible string + * Add gpio-line-names property +--- + arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +index 3e4ed7c5b0b3..0b31d995a066 100644 +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +@@ -25,6 +25,23 @@ + }; + }; + ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "BT_ON", ++ "WL_ON", ++ "STATUS_LED", ++ "LAN_RUN", ++ "HPD_N", ++ "CAM_GPIO0", ++ "CAM_GPIO1", ++ "PWR_LOW_N"; ++ status = "okay"; ++ }; ++}; ++ + /* uart0 communicates with the BT module */ + &uart0 { + pinctrl-names = "default"; |