8803f47
From 08af112e79cab22f318ca0ad1a48187eee5ac2f0 Mon Sep 17 00:00:00 2001
60e2723
From: Baruch Siach <baruch@tkos.co.il>
60e2723
Date: Tue, 20 Feb 2018 14:19:31 +0200
8803f47
Subject: soc: bcm2835: sync firmware properties with downstream
60e2723
60e2723
Add latest firmware property tags from the latest Raspberry Pi downstream
60e2723
kernel. This is needed for the GPIO tags, so we can control the GPIO
60e2723
multiplexor lines.
60e2723
60e2723
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
60e2723
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
8803f47
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
60e2723
---
60e2723
 include/soc/bcm2835/raspberrypi-firmware.h | 18 ++++++++++++++++++
60e2723
 1 file changed, 18 insertions(+)
60e2723
60e2723
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
8803f47
index cb979ad..50df5b2 100644
60e2723
--- a/include/soc/bcm2835/raspberrypi-firmware.h
60e2723
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
60e2723
@@ -63,6 +63,7 @@ enum rpi_firmware_property_tag {
60e2723
 	RPI_FIRMWARE_GET_MIN_VOLTAGE =                        0x00030008,
60e2723
 	RPI_FIRMWARE_GET_TURBO =                              0x00030009,
60e2723
 	RPI_FIRMWARE_GET_MAX_TEMPERATURE =                    0x0003000a,
60e2723
+	RPI_FIRMWARE_GET_STC =                                0x0003000b,
60e2723
 	RPI_FIRMWARE_ALLOCATE_MEMORY =                        0x0003000c,
60e2723
 	RPI_FIRMWARE_LOCK_MEMORY =                            0x0003000d,
60e2723
 	RPI_FIRMWARE_UNLOCK_MEMORY =                          0x0003000e,
60e2723
@@ -72,12 +73,22 @@ enum rpi_firmware_property_tag {
60e2723
 	RPI_FIRMWARE_SET_ENABLE_QPU =                         0x00030012,
60e2723
 	RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
60e2723
 	RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
60e2723
+	RPI_FIRMWARE_GET_CUSTOMER_OTP =                       0x00030021,
60e2723
 	RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
60e2723
 	RPI_FIRMWARE_SET_CLOCK_STATE =                        0x00038001,
60e2723
 	RPI_FIRMWARE_SET_CLOCK_RATE =                         0x00038002,
60e2723
 	RPI_FIRMWARE_SET_VOLTAGE =                            0x00038003,
60e2723
 	RPI_FIRMWARE_SET_TURBO =                              0x00038009,
60e2723
+	RPI_FIRMWARE_SET_CUSTOMER_OTP =                       0x00038021,
60e2723
 	RPI_FIRMWARE_SET_DOMAIN_STATE =                       0x00038030,
60e2723
+	RPI_FIRMWARE_GET_GPIO_STATE =                         0x00030041,
60e2723
+	RPI_FIRMWARE_SET_GPIO_STATE =                         0x00038041,
60e2723
+	RPI_FIRMWARE_SET_SDHOST_CLOCK =                       0x00038042,
60e2723
+	RPI_FIRMWARE_GET_GPIO_CONFIG =                        0x00030043,
60e2723
+	RPI_FIRMWARE_SET_GPIO_CONFIG =                        0x00038043,
60e2723
+	RPI_FIRMWARE_GET_PERIPH_REG =                         0x00030045,
60e2723
+	RPI_FIRMWARE_SET_PERIPH_REG =                         0x00038045,
60e2723
+
60e2723
 
60e2723
 	/* Dispmanx TAGS */
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE =                   0x00040001,
60e2723
@@ -91,6 +102,8 @@ enum rpi_firmware_property_tag {
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET =         0x00040009,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN =               0x0004000a,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE =                0x0004000b,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF =               0x0004000f,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF =            0x00040010,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_RELEASE =                    0x00048001,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT =  0x00044004,
60e2723
@@ -100,6 +113,7 @@ enum rpi_firmware_property_tag {
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET =        0x00044009,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN =              0x0004400a,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE =               0x0004400b,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC =                 0x0004400e,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT =  0x00048003,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT =   0x00048004,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH =                  0x00048005,
60e2723
@@ -108,6 +122,10 @@ enum rpi_firmware_property_tag {
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET =         0x00048009,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN =               0x0004800a,
60e2723
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE =                0x0004800b,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF =               0x0004801f,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF =            0x00048020,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC =                  0x0004800e,
60e2723
+	RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT =              0x0004800f,
60e2723
 
60e2723
 	RPI_FIRMWARE_VCHIQ_INIT =                             0x00048010,
60e2723
 
8803f47
-- 
8803f47
cgit v1.1
8803f47
From 9777d8099a4a9df1625b4caaee1388c0158478c5 Mon Sep 17 00:00:00 2001
60e2723
From: Baruch Siach <baruch@tkos.co.il>
60e2723
Date: Tue, 20 Feb 2018 14:19:32 +0200
8803f47
Subject: dt-bindings: gpio: add raspberry pi GPIO expander binding
60e2723
60e2723
The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware over
60e2723
I2C. The firmware mailbox interface allows the ARM core to control the
60e2723
GPIO lines.
60e2723
60e2723
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
60e2723
Reviewed-by: Rob Herring <robh@kernel.org>
8803f47
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
60e2723
---
60e2723
 .../bindings/gpio/raspberrypi,firmware-gpio.txt    | 30 ++++++++++++++++++++++
60e2723
 1 file changed, 30 insertions(+)
60e2723
 create mode 100644 Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
60e2723
60e2723
diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
60e2723
new file mode 100644
8803f47
index 0000000..ce97265
60e2723
--- /dev/null
60e2723
+++ b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
60e2723
@@ -0,0 +1,30 @@
60e2723
+Raspberry Pi GPIO expander
60e2723
+
60e2723
+The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
60e2723
+firmware exposes a mailbox interface that allows the ARM core to control the
60e2723
+GPIO lines on the expander.
60e2723
+
60e2723
+The Raspberry Pi GPIO expander node must be a child node of the Raspberry Pi
60e2723
+firmware node.
60e2723
+
60e2723
+Required properties:
60e2723
+
60e2723
+- compatible : Should be "raspberrypi,firmware-gpio"
60e2723
+- gpio-controller : Marks the device node as a gpio controller
60e2723
+- #gpio-cells : Should be two.  The first cell is the pin number, and
60e2723
+  the second cell is used to specify the gpio polarity:
60e2723
+  0 = active high
60e2723
+  1 = active low
60e2723
+
60e2723
+Example:
60e2723
+
60e2723
+firmware: firmware-rpi {
60e2723
+	compatible = "raspberrypi,bcm2835-firmware";
60e2723
+	mboxes = <&mailbox>;
60e2723
+
60e2723
+	expgpio: gpio {
60e2723
+		 compatible = "raspberrypi,firmware-gpio";
60e2723
+		 gpio-controller;
60e2723
+		 #gpio-cells = <2>;
60e2723
+	 };
60e2723
+};
8803f47
-- 
8803f47
cgit v1.1
8803f47
From a98d90e7d588045716c3c85d63f93dc3f15a079b Mon Sep 17 00:00:00 2001
feae0be
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
8803f47
Date: Tue, 20 Feb 2018 14:19:33 +0200
8803f47
Subject: gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox
8803f47
 service
60e2723
60e2723
Pi3 and Compute Module 3 have a GPIO expander that the
60e2723
VPU communicates with.
60e2723
There is a mailbox service that now allows control of this
60e2723
expander, so add a kernel driver that can make use of it.
60e2723
60e2723
Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com>
60e2723
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
60e2723
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
8803f47
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
60e2723
---
60e2723
 drivers/gpio/Kconfig                |   9 ++
60e2723
 drivers/gpio/Makefile               |   1 +
60e2723
 drivers/gpio/gpio-raspberrypi-exp.c | 252 ++++++++++++++++++++++++++++++++++++
60e2723
 3 files changed, 262 insertions(+)
60e2723
 create mode 100644 drivers/gpio/gpio-raspberrypi-exp.c
60e2723
60e2723
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
8803f47
index 8dbb228..fd0562a 100644
60e2723
--- a/drivers/gpio/Kconfig
60e2723
+++ b/drivers/gpio/Kconfig
60e2723
@@ -122,6 +122,15 @@ config GPIO_ATH79
60e2723
 	  Select this option to enable GPIO driver for
60e2723
 	  Atheros AR71XX/AR724X/AR913X SoC devices.
60e2723
 
60e2723
+config GPIO_RASPBERRYPI_EXP
60e2723
+	tristate "Raspberry Pi 3 GPIO Expander"
60e2723
+	default RASPBERRYPI_FIRMWARE
60e2723
+	depends on OF_GPIO
60e2723
+	depends on (ARCH_BCM2835 && RASPBERRYPI_FIRMWARE) || COMPILE_TEST
60e2723
+	help
60e2723
+	  Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
60e2723
+	  the firmware mailbox to communicate with VideoCore on BCM283x chips.
60e2723
+
60e2723
 config GPIO_BCM_KONA
60e2723
 	bool "Broadcom Kona GPIO"
60e2723
 	depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
60e2723
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
8803f47
index cccb0d4..76dc0a0 100644
60e2723
--- a/drivers/gpio/Makefile
60e2723
+++ b/drivers/gpio/Makefile
60e2723
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_AMDPT)	+= gpio-amdpt.o
60e2723
 obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
60e2723
 obj-$(CONFIG_GPIO_ATH79)	+= gpio-ath79.o
60e2723
 obj-$(CONFIG_GPIO_ASPEED)	+= gpio-aspeed.o
60e2723
+obj-$(CONFIG_GPIO_RASPBERRYPI_EXP)	+= gpio-raspberrypi-exp.o
60e2723
 obj-$(CONFIG_GPIO_BCM_KONA)	+= gpio-bcm-kona.o
60e2723
 obj-$(CONFIG_GPIO_BD9571MWV)	+= gpio-bd9571mwv.o
60e2723
 obj-$(CONFIG_GPIO_BRCMSTB)	+= gpio-brcmstb.o
60e2723
diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
60e2723
new file mode 100644
8803f47
index 0000000..d6d36d5
60e2723
--- /dev/null
60e2723
+++ b/drivers/gpio/gpio-raspberrypi-exp.c
60e2723
@@ -0,0 +1,252 @@
60e2723
+// SPDX-License-Identifier: GPL-2.0+
60e2723
+/*
60e2723
+ *  Raspberry Pi 3 expander GPIO driver
60e2723
+ *
60e2723
+ *  Uses the firmware mailbox service to communicate with the
60e2723
+ *  GPIO expander on the VPU.
60e2723
+ *
60e2723
+ *  Copyright (C) 2017 Raspberry Pi Trading Ltd.
60e2723
+ */
60e2723
+
60e2723
+#include <linux/err.h>
60e2723
+#include <linux/gpio/driver.h>
60e2723
+#include <linux/module.h>
60e2723
+#include <linux/platform_device.h>
60e2723
+#include <soc/bcm2835/raspberrypi-firmware.h>
60e2723
+
60e2723
+#define MODULE_NAME "raspberrypi-exp-gpio"
60e2723
+#define NUM_GPIO 8
60e2723
+
60e2723
+#define RPI_EXP_GPIO_BASE	128
60e2723
+
60e2723
+#define RPI_EXP_GPIO_DIR_IN	0
60e2723
+#define RPI_EXP_GPIO_DIR_OUT	1
60e2723
+
60e2723
+struct rpi_exp_gpio {
60e2723
+	struct gpio_chip gc;
60e2723
+	struct rpi_firmware *fw;
60e2723
+};
60e2723
+
60e2723
+/* VC4 firmware mailbox interface data structures */
60e2723
+
60e2723
+struct gpio_set_config {
60e2723
+	u32 gpio;
60e2723
+	u32 direction;
60e2723
+	u32 polarity;
60e2723
+	u32 term_en;
60e2723
+	u32 term_pull_up;
60e2723
+	u32 state;
60e2723
+};
60e2723
+
60e2723
+struct gpio_get_config {
60e2723
+	u32 gpio;
60e2723
+	u32 direction;
60e2723
+	u32 polarity;
60e2723
+	u32 term_en;
60e2723
+	u32 term_pull_up;
60e2723
+};
60e2723
+
60e2723
+struct gpio_get_set_state {
60e2723
+	u32 gpio;
60e2723
+	u32 state;
60e2723
+};
60e2723
+
60e2723
+static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_get_config get;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
60e2723
+				    &get, sizeof(get));
60e2723
+	if (ret || get.gpio != 0) {
60e2723
+		dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n",
60e2723
+			off, ret, get.gpio);
60e2723
+		return ret ? ret : -EIO;
60e2723
+	}
60e2723
+	return get.polarity;
60e2723
+}
60e2723
+
60e2723
+static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_set_config set_in;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	set_in.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+	set_in.direction = RPI_EXP_GPIO_DIR_IN;
60e2723
+	set_in.term_en = 0;		/* termination disabled */
60e2723
+	set_in.term_pull_up = 0;	/* n/a as termination disabled */
60e2723
+	set_in.state = 0;		/* n/a as configured as an input */
60e2723
+
60e2723
+	ret = rpi_exp_gpio_get_polarity(gc, off);
60e2723
+	if (ret < 0)
60e2723
+		return ret;
60e2723
+	set_in.polarity = ret;		/* Retain existing setting */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
60e2723
+				    &set_in, sizeof(set_in));
60e2723
+	if (ret || set_in.gpio != 0) {
60e2723
+		dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n",
60e2723
+			off, ret, set_in.gpio);
60e2723
+		return ret ? ret : -EIO;
60e2723
+	}
60e2723
+	return 0;
60e2723
+}
60e2723
+
60e2723
+static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_set_config set_out;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	set_out.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+	set_out.direction = RPI_EXP_GPIO_DIR_OUT;
60e2723
+	set_out.term_en = 0;		/* n/a as an output */
60e2723
+	set_out.term_pull_up = 0;	/* n/a as termination disabled */
60e2723
+	set_out.state = val;		/* Output state */
60e2723
+
60e2723
+	ret = rpi_exp_gpio_get_polarity(gc, off);
60e2723
+	if (ret < 0)
60e2723
+		return ret;
60e2723
+	set_out.polarity = ret;		/* Retain existing setting */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
60e2723
+				    &set_out, sizeof(set_out));
60e2723
+	if (ret || set_out.gpio != 0) {
60e2723
+		dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n",
60e2723
+			off, ret, set_out.gpio);
60e2723
+		return ret ? ret : -EIO;
60e2723
+	}
60e2723
+	return 0;
60e2723
+}
60e2723
+
60e2723
+static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_get_config get;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
60e2723
+				    &get, sizeof(get));
60e2723
+	if (ret || get.gpio != 0) {
60e2723
+		dev_err(gc->parent,
60e2723
+			"Failed to get GPIO %u config (%d %x)\n", off, ret,
60e2723
+			get.gpio);
60e2723
+		return ret ? ret : -EIO;
60e2723
+	}
60e2723
+	return !get.direction;
60e2723
+}
60e2723
+
60e2723
+static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_get_set_state get;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	get.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+	get.state = 0;		/* storage for returned value */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
60e2723
+					 &get, sizeof(get));
60e2723
+	if (ret || get.gpio != 0) {
60e2723
+		dev_err(gc->parent,
60e2723
+			"Failed to get GPIO %u state (%d %x)\n", off, ret,
60e2723
+			get.gpio);
60e2723
+		return ret ? ret : -EIO;
60e2723
+	}
60e2723
+	return !!get.state;
60e2723
+}
60e2723
+
60e2723
+static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
60e2723
+{
60e2723
+	struct rpi_exp_gpio *gpio;
60e2723
+	struct gpio_get_set_state set;
60e2723
+	int ret;
60e2723
+
60e2723
+	gpio = gpiochip_get_data(gc);
60e2723
+
60e2723
+	set.gpio = off + RPI_EXP_GPIO_BASE;	/* GPIO to update */
60e2723
+	set.state = val;	/* Output state */
60e2723
+
60e2723
+	ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
60e2723
+					 &set, sizeof(set));
60e2723
+	if (ret || set.gpio != 0)
60e2723
+		dev_err(gc->parent,
60e2723
+			"Failed to set GPIO %u state (%d %x)\n", off, ret,
60e2723
+			set.gpio);
60e2723
+}
60e2723
+
60e2723
+static int rpi_exp_gpio_probe(struct platform_device *pdev)
60e2723
+{
60e2723
+	struct device *dev = &pdev->dev;
60e2723
+	struct device_node *np = dev->of_node;
60e2723
+	struct device_node *fw_node;
60e2723
+	struct rpi_firmware *fw;
60e2723
+	struct rpi_exp_gpio *rpi_gpio;
60e2723
+
60e2723
+	fw_node = of_get_parent(np);
60e2723
+	if (!fw_node) {
60e2723
+		dev_err(dev, "Missing firmware node\n");
60e2723
+		return -ENOENT;
60e2723
+	}
60e2723
+
60e2723
+	fw = rpi_firmware_get(fw_node);
60e2723
+	if (!fw)
60e2723
+		return -EPROBE_DEFER;
60e2723
+
60e2723
+	rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
60e2723
+	if (!rpi_gpio)
60e2723
+		return -ENOMEM;
60e2723
+
60e2723
+	rpi_gpio->fw = fw;
60e2723
+	rpi_gpio->gc.parent = dev;
60e2723
+	rpi_gpio->gc.label = MODULE_NAME;
60e2723
+	rpi_gpio->gc.owner = THIS_MODULE;
60e2723
+	rpi_gpio->gc.of_node = np;
60e2723
+	rpi_gpio->gc.base = -1;
60e2723
+	rpi_gpio->gc.ngpio = NUM_GPIO;
60e2723
+
60e2723
+	rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
60e2723
+	rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
60e2723
+	rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
60e2723
+	rpi_gpio->gc.get = rpi_exp_gpio_get;
60e2723
+	rpi_gpio->gc.set = rpi_exp_gpio_set;
60e2723
+	rpi_gpio->gc.can_sleep = true;
60e2723
+
60e2723
+	return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
60e2723
+}
60e2723
+
60e2723
+static const struct of_device_id rpi_exp_gpio_ids[] = {
60e2723
+	{ .compatible = "raspberrypi,firmware-gpio" },
60e2723
+	{ }
60e2723
+};
60e2723
+MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
60e2723
+
60e2723
+static struct platform_driver rpi_exp_gpio_driver = {
60e2723
+	.driver	= {
60e2723
+		.name		= MODULE_NAME,
60e2723
+		.of_match_table	= of_match_ptr(rpi_exp_gpio_ids),
60e2723
+	},
60e2723
+	.probe	= rpi_exp_gpio_probe,
60e2723
+};
60e2723
+module_platform_driver(rpi_exp_gpio_driver);
60e2723
+
60e2723
+MODULE_LICENSE("GPL");
60e2723
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
60e2723
+MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
60e2723
+MODULE_ALIAS("platform:rpi-exp-gpio");
8803f47
-- 
8803f47
cgit v1.1
8803f47
From b0c07c5af6d286f3d3b907743998e9d41f6ab042 Mon Sep 17 00:00:00 2001
60e2723
From: Baruch Siach <baruch@tkos.co.il>
60e2723
Date: Tue, 20 Feb 2018 14:19:34 +0200
8803f47
Subject: ARM: dts: bcm2835: make the firmware node into a bus
60e2723
60e2723
This allows adding devices for which the firmware exposes control interface
60e2723
via the mailbox. An example of such device is the GPIO expander.
60e2723
60e2723
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
60e2723
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
8803f47
Reviewed-by: Eric Anholt <eric@anholt.net>
8803f47
Signed-off-by: Eric Anholt <eric@anholt.net>
60e2723
---
60e2723
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 +++-
60e2723
 1 file changed, 3 insertions(+), 1 deletion(-)
60e2723
60e2723
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
8803f47
index e36c392..0198bd4 100644
60e2723
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
60e2723
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
60e2723
@@ -18,7 +18,9 @@
60e2723
 
60e2723
 	soc {
60e2723
 		firmware: firmware {
60e2723
-			compatible = "raspberrypi,bcm2835-firmware";
60e2723
+			compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
60e2723
+			#address-cells = <0>;
60e2723
+			#size-cells = <0>;
60e2723
 			mboxes = <&mailbox>;
60e2723
 		};
60e2723
 
8803f47
-- 
8803f47
cgit v1.1
8803f47
From 4d5b2eaf3ca80c56a59f230208c4ff11e3f68d55 Mon Sep 17 00:00:00 2001
60e2723
From: Baruch Siach <baruch@tkos.co.il>
60e2723
Date: Tue, 20 Feb 2018 14:19:35 +0200
8803f47
Subject: ARM: dts: bcm2837-rpi-3-b: add GPIO expander
60e2723
60e2723
Add a description of the RPi3 GPIO expander that the VC4 firmware controls.
60e2723
60e2723
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
60e2723
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
60e2723
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
8803f47
Reviewed-by: Eric Anholt <eric@anholt.net>
8803f47
Signed-off-by: Eric Anholt <eric@anholt.net>
60e2723
---
60e2723
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 17 +++++++++++++++++
60e2723
 1 file changed, 17 insertions(+)
60e2723
60e2723
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
8803f47
index 3e4ed7c..0b31d99 100644
60e2723
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
60e2723
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
60e2723
@@ -25,6 +25,23 @@
60e2723
 	};
60e2723
 };
60e2723
 
60e2723
+&firmware {
60e2723
+	expgpio: gpio {
60e2723
+		compatible = "raspberrypi,firmware-gpio";
60e2723
+		gpio-controller;
60e2723
+		#gpio-cells = <2>;
60e2723
+		gpio-line-names = "BT_ON",
60e2723
+				  "WL_ON",
60e2723
+				  "STATUS_LED",
60e2723
+				  "LAN_RUN",
60e2723
+				  "HPD_N",
60e2723
+				  "CAM_GPIO0",
60e2723
+				  "CAM_GPIO1",
60e2723
+				  "PWR_LOW_N";
60e2723
+		status = "okay";
60e2723
+	};
60e2723
+};
60e2723
+
60e2723
 /* uart0 communicates with the BT module */
60e2723
 &uart0 {
60e2723
 	pinctrl-names = "default";
8803f47
-- 
8803f47
cgit v1.1