All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Raspberry Pi firmware driver
@ 2015-04-27 23:14 Eric Anholt
  2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Eric Anholt @ 2015-04-27 23:14 UTC (permalink / raw)
  To: linux-arm-kernel

This is mostly a squash/rename of my previous property and power
domain drivers, on top of the new non-channels mailbox driver I sent
earlier.  I definitely like how much less boilerplate there is.

I've switched the power domains to just using the property request,
which has an obvious mapping to the on/off hooks we need to implement
(the firmware tracks which domains are currently requested by the
user).

The code can also be found at: https://github.com/anholt/linux/tree/rpi-mailbox

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] dt/bindings: Add binding for the Raspberry Pi firmware driver
  2015-04-27 23:14 [PATCH 0/3] Raspberry Pi firmware driver Eric Anholt
@ 2015-04-27 23:14 ` Eric Anholt
  2015-04-28  9:34   ` Lee Jones
  2015-04-29  1:42   ` Stephen Warren
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
  2015-04-27 23:14 ` [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT Eric Anholt
  2 siblings, 2 replies; 23+ messages in thread
From: Eric Anholt @ 2015-04-27 23:14 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 .../devicetree/bindings/arm/bcm/raspberrypi,firmware.txt   | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt

diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt
new file mode 100644
index 0000000..a74c966
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt
@@ -0,0 +1,14 @@
+Raspberry Pi VideoCore firmware driver
+
+Required properties:
+
+- compatible:	Should be "rasbperrypi,firmware"
+- mboxes:	Single-entry list which specifies which mailbox controller
+		  and channel is used.
+
+Example:
+
+firmware {
+	compatible = "rasbperrypi,firmware";
+	mboxes = <&mailbox 0>
+};
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-27 23:14 [PATCH 0/3] Raspberry Pi firmware driver Eric Anholt
  2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
@ 2015-04-27 23:14 ` Eric Anholt
  2015-04-28  7:56   ` Arnd Bergmann
                     ` (3 more replies)
  2015-04-27 23:14 ` [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT Eric Anholt
  2 siblings, 4 replies; 23+ messages in thread
From: Eric Anholt @ 2015-04-27 23:14 UTC (permalink / raw)
  To: linux-arm-kernel

This gives us a function for making mailbox property channel requests
of the firmware, and uses it to control the 3 power domains provided
by the firmware.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/mach-bcm/Kconfig                          |   2 +
 arch/arm/mach-bcm/Makefile                         |   1 +
 arch/arm/mach-bcm/raspberrypi-firmware.c           | 285 +++++++++++++++++++++
 .../dt-bindings/arm/raspberrypi-firmware-power.h   |  16 ++
 include/soc/bcm2835/raspberrypi-mailbox-property.h | 110 ++++++++
 5 files changed, 414 insertions(+)
 create mode 100644 arch/arm/mach-bcm/raspberrypi-firmware.c
 create mode 100644 include/dt-bindings/arm/raspberrypi-firmware-power.h
 create mode 100644 include/soc/bcm2835/raspberrypi-mailbox-property.h

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 8b11f44..a907bf4 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -116,6 +116,8 @@ config ARCH_BCM2835
 	select CLKSRC_OF
 	select PINCTRL
 	select PINCTRL_BCM2835
+	select PM_GENERIC_DOMAINS if PM
+	select PM_GENERIC_DOMAINS_OF if PM
 	help
 	  This enables support for the Broadcom BCM2835 SoC. This SoC is
 	  used in the Raspberry Pi and Roku 2 devices.
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 4c38674..bbdde34 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -33,6 +33,7 @@ endif
 
 # BCM2835
 obj-$(CONFIG_ARCH_BCM2835)	+= board_bcm2835.o
+obj-$(CONFIG_BCM2835_MBOX)	+= raspberrypi-firmware.o
 
 # BCM5301X
 obj-$(CONFIG_ARCH_BCM_5301X)	+= bcm_5301x.o
diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
new file mode 100644
index 0000000..194f05f
--- /dev/null
+++ b/arch/arm/mach-bcm/raspberrypi-firmware.c
@@ -0,0 +1,285 @@
+/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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.
+ */
+
+/*
+ * Defines interfaces for interacting wtih the Raspberry Pi firmware,
+ * and registers some of those services with the kernel.
+ */
+
+#include <dt-bindings/arm/raspberrypi-firmware-power.h>
+#include <linux/dma-mapping.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <soc/bcm2835/raspberrypi-mailbox-property.h>
+
+#define MBOX_MSG(chan, data28)		(((data28) & ~0xf) | ((chan) & 0xf))
+#define MBOX_CHAN(msg)			((msg) & 0xf)
+#define MBOX_DATA28(msg)		((msg) & ~0xf)
+#define MBOX_CHAN_PROPERTY		8
+
+struct raspberrypi_firmware {
+	struct device *dev;
+	struct genpd_onecell_data genpd_xlate;
+	struct mbox_client cl;
+	struct mbox_chan *chan; /* The property channel. */
+	struct completion c;
+	u32 enabled;
+};
+
+static struct raspberrypi_firmware *firmware;
+static DEFINE_MUTEX(transaction_lock);
+
+static void response_callback(struct mbox_client *cl, void *msg)
+{
+	complete(&firmware->c);
+}
+
+/*
+ * Sends a request to the firmware through the BCM2835 mailbox driver,
+ * and synchronously waits for the reply.
+ */
+static int
+raspberrypi_firmware_transaction(u32 chan, u32 data)
+{
+	u32 message = MBOX_MSG(chan, data);
+	int ret;
+
+	WARN_ON(data & 0xf);
+
+	mutex_lock(&transaction_lock);
+	reinit_completion(&firmware->c);
+	ret = mbox_send_message(firmware->chan, &message);
+	if (ret >= 0) {
+		wait_for_completion(&firmware->c);
+		ret = 0;
+	} else {
+		dev_err(firmware->cl.dev, "mbox_send_message returned %d\n",
+			ret);
+	}
+	mutex_unlock(&transaction_lock);
+
+	return ret;
+}
+
+
+/*
+ * Submits a set of concatenated tags to the VPU firmware through the
+ * mailbox property interface.
+ *
+ * The buffer header and the ending tag are added by this function and
+ * don't need to be supplied, just the actual tags for your operation.
+ * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
+ */
+int raspberrypi_firmware_property(void *data, size_t tag_size)
+{
+	size_t size = tag_size + 12;
+	u32 *buf;
+	dma_addr_t bus_addr;
+	int ret = 0;
+
+	if (!firmware)
+		return -EPROBE_DEFER;
+
+	/* Packets are processed a dword at a time. */
+	if (size & 3)
+		return -EINVAL;
+
+	buf = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &bus_addr, GFP_ATOMIC);
+	if (!buf)
+		return -ENOMEM;
+
+	/* The firmware will error out without parsing in this case. */
+	WARN_ON(size >= 1024 * 1024);
+
+	buf[0] = size;
+	buf[1] = raspberrypi_firmware_status_request;
+	memcpy(&buf[2], data, tag_size);
+	buf[size / 4 - 1] = raspberrypi_firmware_property_end;
+	wmb();
+
+	ret = raspberrypi_firmware_transaction(MBOX_CHAN_PROPERTY, bus_addr);
+
+	rmb();
+	memcpy(data, &buf[2], tag_size);
+	if (ret == 0 && buf[1] != raspberrypi_firmware_status_success) {
+		/*
+		 * The tag name here might not be the one causing the
+		 * error, if there were multiple tags in the request.
+		 * But single-tag is the most common, so go with it.
+		 */
+		dev_err(firmware->cl.dev,
+			"Request 0x%08x returned status 0x%08x\n",
+			buf[2], buf[1]);
+		ret = -EINVAL;
+	}
+
+	dma_free_coherent(NULL, PAGE_ALIGN(size), buf, bus_addr);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(raspberrypi_firmware_property);
+
+struct raspberrypi_power_domain {
+	u32 domain;
+	struct generic_pm_domain base;
+};
+
+/*
+ * Asks the firmware to enable or disable power on a specific power
+ * domain.
+ */
+static int raspberrypi_firmware_set_power(uint32_t domain, bool on)
+{
+	struct {
+		struct raspberrypi_firmware_property_tag_header header;
+		u32 domain;
+		u32 on;
+	} packet;
+	int ret;
+
+	memset(&packet, 0, sizeof(packet));
+	packet.header.tag = raspberrypi_firmware_set_power_state;
+	packet.header.buf_size = 8;
+	packet.domain = domain;
+	packet.on = on;
+	ret = raspberrypi_firmware_property(&packet, sizeof(packet));
+	if (!ret && !packet.on)
+		ret = -EINVAL;
+	return ret;
+}
+
+static int raspberrypi_domain_off(struct generic_pm_domain *domain)
+{
+	struct raspberrypi_power_domain *raspberrpi_domain =
+		container_of(domain, struct raspberrypi_power_domain, base);
+
+	return raspberrypi_firmware_set_power(raspberrpi_domain->domain, false);
+}
+
+static int raspberrypi_domain_on(struct generic_pm_domain *domain)
+{
+	struct raspberrypi_power_domain *raspberrpi_domain =
+		container_of(domain, struct raspberrypi_power_domain, base);
+
+	return raspberrypi_firmware_set_power(raspberrpi_domain->domain, true);
+}
+
+struct raspberrypi_power_domain raspberrypi_power_domain_sdcard = {
+	.domain = 0,
+	.base = {
+		.name = "SDCARD",
+		.power_off = raspberrypi_domain_off,
+		.power_on = raspberrypi_domain_on,
+	}
+};
+
+struct raspberrypi_power_domain raspberrypi_power_domain_usb = {
+	.domain = 3,
+	.base = {
+		.name = "USB",
+		.power_off = raspberrypi_domain_off,
+		.power_on = raspberrypi_domain_on,
+	}
+};
+
+struct raspberrypi_power_domain raspberrypi_power_domain_dsi = {
+	.domain = 9,
+	.base = {
+		.name = "DSI",
+		.power_off = raspberrypi_domain_off,
+		.power_on = raspberrypi_domain_on,
+	}
+};
+
+static struct generic_pm_domain *raspberrypi_power_domains[] = {
+	[POWER_DOMAIN_SDCARD] = &raspberrypi_power_domain_sdcard.base,
+	[POWER_DOMAIN_USB] = &raspberrypi_power_domain_usb.base,
+	[POWER_DOMAIN_DSI] = &raspberrypi_power_domain_dsi.base,
+};
+
+static int raspberrypi_firmware_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	int i;
+
+	firmware = devm_kzalloc(dev, sizeof(*firmware), GFP_KERNEL);
+	if (!firmware)
+		return -ENOMEM;
+
+	firmware->cl.dev = dev;
+	firmware->cl.rx_callback = response_callback;
+	firmware->cl.tx_block = true;
+
+	firmware->chan = mbox_request_channel(&firmware->cl, 0);
+	if (IS_ERR(firmware->chan)) {
+		ret = PTR_ERR(firmware->chan);
+		/* An -EBUSY from the core means it couldn't find our
+		 * channel, because the mailbox driver hadn't
+		 * registered yet.
+		 */
+		if (ret == -EBUSY)
+			ret = -EPROBE_DEFER;
+		else
+			dev_err(dev, "Failed to get mbox channel: %d\n", ret);
+		goto fail;
+	}
+
+	init_completion(&firmware->c);
+
+	platform_set_drvdata(pdev, firmware);
+
+	firmware->genpd_xlate.domains =
+		raspberrypi_power_domains;
+	firmware->genpd_xlate.num_domains =
+		ARRAY_SIZE(raspberrypi_power_domains);
+
+	for (i = 0; i < ARRAY_SIZE(raspberrypi_power_domains); i++)
+		pm_genpd_init(raspberrypi_power_domains[i], NULL, true);
+
+	of_genpd_add_provider_onecell(dev->of_node, &firmware->genpd_xlate);
+
+	return 0;
+
+fail:
+	firmware = NULL;
+	return ret;
+}
+
+static int raspberrypi_firmware_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	of_genpd_del_provider(dev->of_node);
+	mbox_free_channel(firmware->chan);
+
+	return 0;
+}
+
+static const struct of_device_id raspberrypi_firmware_of_match[] = {
+	{ .compatible = "raspberrypi,firmware", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, raspberrypi_firmware_of_match);
+
+static struct platform_driver raspberrypi_firmware_driver = {
+	.driver = {
+		.name = "raspberrypi-firmware",
+		.owner = THIS_MODULE,
+		.of_match_table = raspberrypi_firmware_of_match,
+	},
+	.probe		= raspberrypi_firmware_probe,
+	.remove		= raspberrypi_firmware_remove,
+};
+module_platform_driver(raspberrypi_firmware_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("Raspberry Pi firmware driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/dt-bindings/arm/raspberrypi-firmware-power.h b/include/dt-bindings/arm/raspberrypi-firmware-power.h
new file mode 100644
index 0000000..1e1ef3b
--- /dev/null
+++ b/include/dt-bindings/arm/raspberrypi-firmware-power.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H
+#define _DT_BINDINGS_ARM_BCM2835_MBOX_POWER_H
+
+#define POWER_DOMAIN_SDCARD 0
+#define POWER_DOMAIN_USB 1
+#define POWER_DOMAIN_DSI 2
+
+#endif
diff --git a/include/soc/bcm2835/raspberrypi-mailbox-property.h b/include/soc/bcm2835/raspberrypi-mailbox-property.h
new file mode 100644
index 0000000..787bd75
--- /dev/null
+++ b/include/soc/bcm2835/raspberrypi-mailbox-property.h
@@ -0,0 +1,110 @@
+/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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/types.h>
+
+enum raspberrypi_firmware_property_status {
+	raspberrypi_firmware_status_request = 0,
+	raspberrypi_firmware_status_success = 0x80000000,
+	raspberrypi_firmware_status_error =   0x80000001,
+};
+
+struct raspberrypi_firmware_property_tag_header {
+	/* One of enum_mbox_property_tag. */
+	u32 tag;
+
+	/* The number of bytes in the value buffer following this
+	 * struct.
+	 */
+	u32 buf_size;
+
+	/*
+	 * On submit, the length of the request (though it doesn't
+	 * appear to be currently used by the firmware).  On return,
+	 * the length of the response (always 4 byte aligned), with
+	 * the low bit set.
+	 */
+	u32 req_resp_size;
+};
+
+enum raspberrypi_firmware_property_tag {
+	raspberrypi_firmware_property_end = 0,
+	raspberrypi_firmware_get_firmware_revision =                  0x00000001,
+
+	raspberrypi_firmware_set_cursor_info =                        0x00008010,
+	raspberrypi_firmware_set_cursor_state =                       0x00008011,
+
+	raspberrypi_firmware_get_board_model =                        0x00010001,
+	raspberrypi_firmware_get_board_revision =                     0x00010002,
+	raspberrypi_firmware_get_board_mac_address =                  0x00010003,
+	raspberrypi_firmware_get_board_serial =                       0x00010004,
+	raspberrypi_firmware_get_arm_memory =                         0x00010005,
+	raspberrypi_firmware_get_vc_memory =                          0x00010006,
+	raspberrypi_firmware_get_clocks =                             0x00010007,
+	raspberrypi_firmware_get_power_state =                        0x00020001,
+	raspberrypi_firmware_get_timing =                             0x00020002,
+	raspberrypi_firmware_set_power_state =                        0x00028001,
+	raspberrypi_firmware_get_clock_state =                        0x00030001,
+	raspberrypi_firmware_get_clock_rate =                         0x00030002,
+	raspberrypi_firmware_get_voltage =                            0x00030003,
+	raspberrypi_firmware_get_max_clock_rate =                     0x00030004,
+	raspberrypi_firmware_get_max_voltage =                        0x00030005,
+	raspberrypi_firmware_get_temperature =                        0x00030006,
+	raspberrypi_firmware_get_min_clock_rate =                     0x00030007,
+	raspberrypi_firmware_get_min_voltage =                        0x00030008,
+	raspberrypi_firmware_get_turbo =                              0x00030009,
+	raspberrypi_firmware_get_max_temperature =                    0x0003000a,
+	raspberrypi_firmware_allocate_memory =                        0x0003000c,
+	raspberrypi_firmware_lock_memory =                            0x0003000d,
+	raspberrypi_firmware_unlock_memory =                          0x0003000e,
+	raspberrypi_firmware_release_memory =                         0x0003000f,
+	raspberrypi_firmware_execute_code =                           0x00030010,
+	raspberrypi_firmware_execute_qpu =                            0x00030011,
+	raspberrypi_firmware_set_enable_qpu =                         0x00030012,
+	raspberrypi_firmware_get_dispmanx_resource_mem_handle =       0x00030014,
+	raspberrypi_firmware_get_edid_block =                         0x00030020,
+	raspberrypi_firmware_set_clock_state =                        0x00038001,
+	raspberrypi_firmware_set_clock_rate =                         0x00038002,
+	raspberrypi_firmware_set_voltage =                            0x00038003,
+	raspberrypi_firmware_set_turbo =                              0x00038009,
+
+	/* Dispmanx tags */
+	raspberrypi_firmware_framebuffer_allocate =                   0x00040001,
+	raspberrypi_firmware_framebuffer_blank =                      0x00040002,
+	raspberrypi_firmware_framebuffer_get_physical_width_height =  0x00040003,
+	raspberrypi_firmware_framebuffer_get_virtual_width_height =   0x00040004,
+	raspberrypi_firmware_framebuffer_get_depth =                  0x00040005,
+	raspberrypi_firmware_framebuffer_get_pixel_order =            0x00040006,
+	raspberrypi_firmware_framebuffer_get_alpha_mode =             0x00040007,
+	raspberrypi_firmware_framebuffer_get_pitch =                  0x00040008,
+	raspberrypi_firmware_framebuffer_get_virtual_offset =         0x00040009,
+	raspberrypi_firmware_framebuffer_get_overscan =               0x0004000a,
+	raspberrypi_firmware_framebuffer_get_palette =                0x0004000b,
+	raspberrypi_firmware_framebuffer_release =                    0x00048001,
+	raspberrypi_firmware_framebuffer_test_physical_width_height = 0x00044003,
+	raspberrypi_firmware_framebuffer_test_virtual_width_height =  0x00044004,
+	raspberrypi_firmware_framebuffer_test_depth =                 0x00044005,
+	raspberrypi_firmware_framebuffer_test_pixel_order =           0x00044006,
+	raspberrypi_firmware_framebuffer_test_alpha_mode =            0x00044007,
+	raspberrypi_firmware_framebuffer_test_virtual_offset =        0x00044009,
+	raspberrypi_firmware_framebuffer_test_overscan =              0x0004400a,
+	raspberrypi_firmware_framebuffer_test_palette =               0x0004400b,
+	raspberrypi_firmware_framebuffer_set_physical_width_height =  0x00048003,
+	raspberrypi_firmware_framebuffer_set_virtual_width_height =   0x00048004,
+	raspberrypi_firmware_framebuffer_set_depth =                  0x00048005,
+	raspberrypi_firmware_framebuffer_set_pixel_order =            0x00048006,
+	raspberrypi_firmware_framebuffer_set_alpha_mode =             0x00048007,
+	raspberrypi_firmware_framebuffer_set_virtual_offset =         0x00048009,
+	raspberrypi_firmware_framebuffer_set_overscan =               0x0004800a,
+	raspberrypi_firmware_framebuffer_set_palette =                0x0004800b,
+
+	raspberrypi_firmware_get_command_line =                       0x00050001,
+	raspberrypi_firmware_get_dma_channels =                       0x00060001,
+};
+
+int raspberrypi_firmware_property(void *data, size_t tag_size);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT
  2015-04-27 23:14 [PATCH 0/3] Raspberry Pi firmware driver Eric Anholt
  2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
@ 2015-04-27 23:14 ` Eric Anholt
  2015-04-28  9:33   ` Lee Jones
  2015-04-29  1:44   ` Stephen Warren
  2 siblings, 2 replies; 23+ messages in thread
From: Eric Anholt @ 2015-04-27 23:14 UTC (permalink / raw)
  To: linux-arm-kernel

This gets the USB power domain turned on so that DWC2 can probe, even
if the bootloader didn't turn it on for us (which is the case if you
use the RPi firmware without chainloading U-Boot).

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 13 +++++++++++++
 arch/arm/boot/dts/bcm2835.dtsi     |  2 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 46780bb..fa9afd1 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,3 +1,4 @@
+#include <dt-bindings/arm/raspberrypi-firmware-power.h>
 #include "bcm2835.dtsi"
 
 / {
@@ -14,6 +15,14 @@
 			linux,default-trigger = "heartbeat";
 		};
 	};
+
+	soc {
+		firmware: firmware {
+			compatible = "raspberrypi,firmware";
+			mboxes = <&mailbox 0>;
+			#power-domain-cells = <1>;
+		};
+	};
 };
 
 &gpio {
@@ -49,3 +58,7 @@
 	status = "okay";
 	bus-width = <4>;
 };
+
+&usb {
+	power-domains = <&firmware POWER_DOMAIN_USB>;
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 664aa25..5734650 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -148,7 +148,7 @@
 			status = "disabled";
 		};
 
-		usb at 7e980000 {
+		usb: usb at 7e980000 {
 			compatible = "brcm,bcm2835-usb";
 			reg = <0x7e980000 0x10000>;
 			interrupts = <1 9>;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
@ 2015-04-28  7:56   ` Arnd Bergmann
  2015-04-28 20:07     ` Eric Anholt
  2015-04-28  9:27   ` Lee Jones
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 23+ messages in thread
From: Arnd Bergmann @ 2015-04-28  7:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 27 April 2015 16:14:08 Eric Anholt wrote:
> This gives us a function for making mailbox property channel requests
> of the firmware, and uses it to control the 3 power domains provided
> by the firmware.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  arch/arm/mach-bcm/Kconfig                          |   2 +
>  arch/arm/mach-bcm/Makefile                         |   1 +
>  arch/arm/mach-bcm/raspberrypi-firmware.c           | 285 +++++++++++++++++++++

drivers/firmware maybe?

Is this firmware the same one on the Roku 2? If so, it might need a better name.

> diff --git a/include/soc/bcm2835/raspberrypi-mailbox-property.h b/include/soc/bcm2835/raspberrypi-mailbox-property.h
> new file mode 100644
> index 0000000..787bd75
> --- /dev/null
> +++ b/include/soc/bcm2835/raspberrypi-mailbox-property.h
> @@ -0,0 +1,110 @@
> +/*
> + *  Copyright ? 2015 Broadcom
> + *
> + * 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/types.h>
> +
> +enum raspberrypi_firmware_property_status {
> +	raspberrypi_firmware_status_request = 0,
> +	raspberrypi_firmware_status_success = 0x80000000,
> +	raspberrypi_firmware_status_error =   0x80000001,
> +};

We tend to use ALL_CAPS for constants, even when they are in an enum.

> +struct raspberrypi_firmware_property_tag_header {
> +	/* One of enum_mbox_property_tag. */
> +	u32 tag;
> +
> +	/* The number of bytes in the value buffer following this
> +	 * struct.
> +	 */
> +	u32 buf_size;
> +
> +	/*
> +	 * On submit, the length of the request (though it doesn't
> +	 * appear to be currently used by the firmware).  On return,
> +	 * the length of the response (always 4 byte aligned), with
> +	 * the low bit set.
> +	 */
> +	u32 req_resp_size;
> +};

If I read your code right, this structure is only used inside of the driver and
not passed in from a device driver, so better move it inside of the firmware
code.

It might be best to do the same with the return codes above as well, and 
convert them into standard Linux calling conventions as well.

> +enum raspberrypi_firmware_property_tag {
> +	raspberrypi_firmware_property_end = 0,
> +	raspberrypi_firmware_get_firmware_revision =                  0x00000001,
> +
> +	raspberrypi_firmware_set_cursor_info =                        0x00008010,
> +	raspberrypi_firmware_set_cursor_state =                       0x00008011,
> +
> +	raspberrypi_firmware_get_board_model =                        0x00010001,
> +	raspberrypi_firmware_get_board_revision =                     0x00010002,
> +	raspberrypi_firmware_get_board_mac_address =                  0x00010003,
> +	raspberrypi_firmware_get_board_serial =                       0x00010004,
> +	raspberrypi_firmware_get_arm_memory =                         0x00010005,
> +	raspberrypi_firmware_get_vc_memory =                          0x00010006,
> +	raspberrypi_firmware_get_clocks =                             0x00010007,

How stable are these interfaces? Does the firmware guarantee to keep the ABI
working, or might we need to version these?

	Arnd

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
  2015-04-28  7:56   ` Arnd Bergmann
@ 2015-04-28  9:27   ` Lee Jones
  2015-04-28  9:28   ` Lee Jones
  2015-04-29  1:58   ` Stephen Warren
  3 siblings, 0 replies; 23+ messages in thread
From: Lee Jones @ 2015-04-28  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 27 Apr 2015, Eric Anholt wrote:

> This gives us a function for making mailbox property channel requests
> of the firmware, and uses it to control the 3 power domains provided
> by the firmware.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  arch/arm/mach-bcm/Kconfig                          |   2 +
>  arch/arm/mach-bcm/Makefile                         |   1 +
>  arch/arm/mach-bcm/raspberrypi-firmware.c           | 285 +++++++++++++++++++++

drivers/firmware ?

>  .../dt-bindings/arm/raspberrypi-firmware-power.h   |  16 ++
>  include/soc/bcm2835/raspberrypi-mailbox-property.h | 110 ++++++++
>  5 files changed, 414 insertions(+)
>  create mode 100644 arch/arm/mach-bcm/raspberrypi-firmware.c
>  create mode 100644 include/dt-bindings/arm/raspberrypi-firmware-power.h
>  create mode 100644 include/soc/bcm2835/raspberrypi-mailbox-property.h

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
  2015-04-28  7:56   ` Arnd Bergmann
  2015-04-28  9:27   ` Lee Jones
@ 2015-04-28  9:28   ` Lee Jones
  2015-04-29  1:58   ` Stephen Warren
  3 siblings, 0 replies; 23+ messages in thread
From: Lee Jones @ 2015-04-28  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

Don't forget to CC LKML.

> This gives us a function for making mailbox property channel requests
> of the firmware, and uses it to control the 3 power domains provided
> by the firmware.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  arch/arm/mach-bcm/Kconfig                          |   2 +
>  arch/arm/mach-bcm/Makefile                         |   1 +
>  arch/arm/mach-bcm/raspberrypi-firmware.c           | 285 +++++++++++++++++++++
>  .../dt-bindings/arm/raspberrypi-firmware-power.h   |  16 ++
>  include/soc/bcm2835/raspberrypi-mailbox-property.h | 110 ++++++++
>  5 files changed, 414 insertions(+)
>  create mode 100644 arch/arm/mach-bcm/raspberrypi-firmware.c
>  create mode 100644 include/dt-bindings/arm/raspberrypi-firmware-power.h
>  create mode 100644 include/soc/bcm2835/raspberrypi-mailbox-property.h

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT
  2015-04-27 23:14 ` [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT Eric Anholt
@ 2015-04-28  9:33   ` Lee Jones
  2015-04-29  1:44   ` Stephen Warren
  1 sibling, 0 replies; 23+ messages in thread
From: Lee Jones @ 2015-04-28  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 27 Apr 2015, Eric Anholt wrote:

> This gets the USB power domain turned on so that DWC2 can probe, even
> if the bootloader didn't turn it on for us (which is the case if you
> use the RPi firmware without chainloading U-Boot).
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  arch/arm/boot/dts/bcm2835-rpi.dtsi | 13 +++++++++++++
>  arch/arm/boot/dts/bcm2835.dtsi     |  2 +-
>  2 files changed, 14 insertions(+), 1 deletion(-)

Acked-by: Lee Jones <lee@kernel.org>

> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
> index 46780bb..fa9afd1 100644
> --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
> +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
> @@ -1,3 +1,4 @@
> +#include <dt-bindings/arm/raspberrypi-firmware-power.h>
>  #include "bcm2835.dtsi"
>  
>  / {
> @@ -14,6 +15,14 @@
>  			linux,default-trigger = "heartbeat";
>  		};
>  	};
> +
> +	soc {
> +		firmware: firmware {
> +			compatible = "raspberrypi,firmware";
> +			mboxes = <&mailbox 0>;
> +			#power-domain-cells = <1>;
> +		};
> +	};
>  };
>  
>  &gpio {
> @@ -49,3 +58,7 @@
>  	status = "okay";
>  	bus-width = <4>;
>  };
> +
> +&usb {
> +	power-domains = <&firmware POWER_DOMAIN_USB>;
> +};
> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
> index 664aa25..5734650 100644
> --- a/arch/arm/boot/dts/bcm2835.dtsi
> +++ b/arch/arm/boot/dts/bcm2835.dtsi
> @@ -148,7 +148,7 @@
>  			status = "disabled";
>  		};
>  
> -		usb at 7e980000 {
> +		usb: usb at 7e980000 {
>  			compatible = "brcm,bcm2835-usb";
>  			reg = <0x7e980000 0x10000>;
>  			interrupts = <1 9>;

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] dt/bindings: Add binding for the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
@ 2015-04-28  9:34   ` Lee Jones
  2015-04-29  1:42   ` Stephen Warren
  1 sibling, 0 replies; 23+ messages in thread
From: Lee Jones @ 2015-04-28  9:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 27 Apr 2015, Eric Anholt wrote:

> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  .../devicetree/bindings/arm/bcm/raspberrypi,firmware.txt   | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt
> new file mode 100644
> index 0000000..a74c966
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt
> @@ -0,0 +1,14 @@
> +Raspberry Pi VideoCore firmware driver
> +
> +Required properties:
> +
> +- compatible:	Should be "rasbperrypi,firmware"
> +- mboxes:	Single-entry list which specifies which mailbox controller
> +		  and channel is used.

#power-domain-cells?

> +Example:
> +
> +firmware {
> +	compatible = "rasbperrypi,firmware";
> +	mboxes = <&mailbox 0>
> +};

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-28  7:56   ` Arnd Bergmann
@ 2015-04-28 20:07     ` Eric Anholt
  0 siblings, 0 replies; 23+ messages in thread
From: Eric Anholt @ 2015-04-28 20:07 UTC (permalink / raw)
  To: linux-arm-kernel

Arnd Bergmann <arnd@arndb.de> writes:

> On Monday 27 April 2015 16:14:08 Eric Anholt wrote:
>> This gives us a function for making mailbox property channel requests
>> of the firmware, and uses it to control the 3 power domains provided
>> by the firmware.
>> 
>> Signed-off-by: Eric Anholt <eric@anholt.net>
>> ---
>>  arch/arm/mach-bcm/Kconfig                          |   2 +
>>  arch/arm/mach-bcm/Makefile                         |   1 +
>>  arch/arm/mach-bcm/raspberrypi-firmware.c           | 285 +++++++++++++++++++++
>
> drivers/firmware maybe?

Sounds fine to me.

> Is this firmware the same one on the Roku 2? If so, it might need a better name.

Nope.  While they apparently start from the same firmware tree, it's
quite diverged.

>> diff --git a/include/soc/bcm2835/raspberrypi-mailbox-property.h b/include/soc/bcm2835/raspberrypi-mailbox-property.h
>> new file mode 100644
>> index 0000000..787bd75
>> --- /dev/null
>> +++ b/include/soc/bcm2835/raspberrypi-mailbox-property.h
>> @@ -0,0 +1,110 @@
>> +/*
>> + *  Copyright ? 2015 Broadcom
>> + *
>> + * 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/types.h>
>> +
>> +enum raspberrypi_firmware_property_status {
>> +	raspberrypi_firmware_status_request = 0,
>> +	raspberrypi_firmware_status_success = 0x80000000,
>> +	raspberrypi_firmware_status_error =   0x80000001,
>> +};
>
> We tend to use ALL_CAPS for constants, even when they are in an enum.

Will do.

>> +struct raspberrypi_firmware_property_tag_header {
>> +	/* One of enum_mbox_property_tag. */
>> +	u32 tag;
>> +
>> +	/* The number of bytes in the value buffer following this
>> +	 * struct.
>> +	 */
>> +	u32 buf_size;
>> +
>> +	/*
>> +	 * On submit, the length of the request (though it doesn't
>> +	 * appear to be currently used by the firmware).  On return,
>> +	 * the length of the response (always 4 byte aligned), with
>> +	 * the low bit set.
>> +	 */
>> +	u32 req_resp_size;
>> +};
>
> If I read your code right, this structure is only used inside of the driver and
> not passed in from a device driver, so better move it inside of the firmware
> code.

In the code present so far, yes.  However, the vc4 driver is also making
property requests, and many of the still-downstream drivers need it too,
I believe.

> It might be best to do the same with the return codes above as well, and 
> convert them into standard Linux calling conventions as well.

The raspberrypi_firmware_status_*?  Those are getting interpreted and
turned into standard Linux return values in
raspberrypi_firmware_property().  I guess we could hide them inside that
driver, but it seems to make sense to me to live here next to the other
property channel interface enums.

>> +enum raspberrypi_firmware_property_tag {
>> +	raspberrypi_firmware_property_end = 0,
>> +	raspberrypi_firmware_get_firmware_revision =                  0x00000001,
>> +
>> +	raspberrypi_firmware_set_cursor_info =                        0x00008010,
>> +	raspberrypi_firmware_set_cursor_state =                       0x00008011,
>> +
>> +	raspberrypi_firmware_get_board_model =                        0x00010001,
>> +	raspberrypi_firmware_get_board_revision =                     0x00010002,
>> +	raspberrypi_firmware_get_board_mac_address =                  0x00010003,
>> +	raspberrypi_firmware_get_board_serial =                       0x00010004,
>> +	raspberrypi_firmware_get_arm_memory =                         0x00010005,
>> +	raspberrypi_firmware_get_vc_memory =                          0x00010006,
>> +	raspberrypi_firmware_get_clocks =                             0x00010007,
>
> How stable are these interfaces? Does the firmware guarantee to keep the ABI
> working, or might we need to version these?

They're good about ABI, as far as I can tell.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150428/93388c11/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] dt/bindings: Add binding for the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
  2015-04-28  9:34   ` Lee Jones
@ 2015-04-29  1:42   ` Stephen Warren
  1 sibling, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2015-04-29  1:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/27/2015 05:14 PM, Eric Anholt wrote:

This one really needs a patch description, to indicate what kind of
thing this patch introduces a binding for.

> diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,firmware.txt

> +Required properties:
> +
> +- compatible:	Should be "rasbperrypi,firmware"
> +- mboxes:	Single-entry list which specifies which mailbox controller
> +		  and channel is used.

It'd be nice to mention that ../../mailbox/mailbox.txt defines the
semantics of this property.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT
  2015-04-27 23:14 ` [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT Eric Anholt
  2015-04-28  9:33   ` Lee Jones
@ 2015-04-29  1:44   ` Stephen Warren
  2015-04-29 16:29     ` Eric Anholt
  1 sibling, 1 reply; 23+ messages in thread
From: Stephen Warren @ 2015-04-29  1:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/27/2015 05:14 PM, Eric Anholt wrote:
> This gets the USB power domain turned on so that DWC2 can probe, even
> if the bootloader didn't turn it on for us (which is the case if you
> use the RPi firmware without chainloading U-Boot).

> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi

> +&usb {
> +	power-domains = <&firmware POWER_DOMAIN_USB>;
> +};

That property doesn't seem to be documented in
Documentation/devicetree/bindings/usb/dwc2.txt (which defines compatible
= "brcm,bcm2835-usb"). Is it implemented?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
                     ` (2 preceding siblings ...)
  2015-04-28  9:28   ` Lee Jones
@ 2015-04-29  1:58   ` Stephen Warren
  2015-04-29  2:14     ` Jassi Brar
  2015-04-29 17:51     ` Eric Anholt
  3 siblings, 2 replies; 23+ messages in thread
From: Stephen Warren @ 2015-04-29  1:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/27/2015 05:14 PM, Eric Anholt wrote:
> This gives us a function for making mailbox property channel requests
> of the firmware, and uses it to control the 3 power domains provided
> by the firmware.

> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c

> +/*
> + * Submits a set of concatenated tags to the VPU firmware through the
> + * mailbox property interface.
> + *
> + * The buffer header and the ending tag are added by this function and
> + * don't need to be supplied, just the actual tags for your operation.
> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
> + */
> +int raspberrypi_firmware_property(void *data, size_t tag_size)
> +{
> +	size_t size = tag_size + 12;
> +	u32 *buf;
> +	dma_addr_t bus_addr;
> +	int ret = 0;
> +
> +	if (!firmware)
> +		return -EPROBE_DEFER;

I think it'd make more sense if the clients looked up the firmware
driver via phandle at their probe time. This would mean:

* No need for global "firmware", since clients could pass the firmware
driver handle into this function.

* Clients resolve deferred probe at their probe time. That way, they
won't register themselves with subsystems asserting they can provide
services, but find out they can't yet provide the service at that time.

> +static int raspberrypi_firmware_probe(struct platform_device *pdev)

BTW if you wanted, a s/raspberrypi/rpi/ in all symbols and filenames
seems reasonable. I'm not really bothered either way.

> +{

> +	firmware->chan = mbox_request_channel(&firmware->cl, 0);
> +	if (IS_ERR(firmware->chan)) {
> +		ret = PTR_ERR(firmware->chan);
> +		/* An -EBUSY from the core means it couldn't find our
> +		 * channel, because the mailbox driver hadn't
> +		 * registered yet.
> +		 */
> +		if (ret == -EBUSY)
> +			ret = -EPROBE_DEFER;
> +		else
> +			dev_err(dev, "Failed to get mbox channel: %d\n", ret);

I would have hoped that mbox_request_channel() returned -EPROBE_DEFER
itself. It really should...

> +static int raspberrypi_firmware_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +
> +	of_genpd_del_provider(dev->of_node);
> +	mbox_free_channel(firmware->chan);

firmware = NULL; ?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-29  1:58   ` Stephen Warren
@ 2015-04-29  2:14     ` Jassi Brar
  2015-04-29  2:56       ` Jassi Brar
  2015-04-29 17:51     ` Eric Anholt
  1 sibling, 1 reply; 23+ messages in thread
From: Jassi Brar @ 2015-04-29  2:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 29, 2015 at 7:28 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>
>> +     firmware->chan = mbox_request_channel(&firmware->cl, 0);
>> +     if (IS_ERR(firmware->chan)) {
>> +             ret = PTR_ERR(firmware->chan);
>> +             /* An -EBUSY from the core means it couldn't find our
>> +              * channel, because the mailbox driver hadn't
>> +              * registered yet.
>> +              */
>> +             if (ret == -EBUSY)
>> +                     ret = -EPROBE_DEFER;
>> +             else
>> +                     dev_err(dev, "Failed to get mbox channel: %d\n", ret);
>
> I would have hoped that mbox_request_channel() returned -EPROBE_DEFER
> itself. It really should...
>
Yes, it should. Let me look into it.

Thanks.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-29  2:14     ` Jassi Brar
@ 2015-04-29  2:56       ` Jassi Brar
  0 siblings, 0 replies; 23+ messages in thread
From: Jassi Brar @ 2015-04-29  2:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 29, 2015 at 7:44 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
> On Wed, Apr 29, 2015 at 7:28 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>
>>> +     firmware->chan = mbox_request_channel(&firmware->cl, 0);
>>> +     if (IS_ERR(firmware->chan)) {
>>> +             ret = PTR_ERR(firmware->chan);
>>> +             /* An -EBUSY from the core means it couldn't find our
>>> +              * channel, because the mailbox driver hadn't
>>> +              * registered yet.
>>> +              */
>>> +             if (ret == -EBUSY)
>>> +                     ret = -EPROBE_DEFER;
>>> +             else
>>> +                     dev_err(dev, "Failed to get mbox channel: %d\n", ret);
>>
>> I would have hoped that mbox_request_channel() returned -EPROBE_DEFER
>> itself. It really should...
>>
> Yes, it should. Let me look into it.
>
Turns out a patch doing that has already been submitted yesterday by
Andrew Bresticker.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT
  2015-04-29  1:44   ` Stephen Warren
@ 2015-04-29 16:29     ` Eric Anholt
  2015-04-29 23:43       ` Stephen Warren
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Anholt @ 2015-04-29 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen Warren <swarren@wwwdotorg.org> writes:

> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>> This gets the USB power domain turned on so that DWC2 can probe, even
>> if the bootloader didn't turn it on for us (which is the case if you
>> use the RPi firmware without chainloading U-Boot).
>
>> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>
>> +&usb {
>> +	power-domains = <&firmware POWER_DOMAIN_USB>;
>> +};
>
> That property doesn't seem to be documented in
> Documentation/devicetree/bindings/usb/dwc2.txt (which defines compatible
> = "brcm,bcm2835-usb"). Is it implemented?

power-domains is a generic property that's parsed by
drivers/base/power/domain.c.  See also
Documentation/devicetree/bindings/power/power_domain.txt&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150429/915b498e/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-29  1:58   ` Stephen Warren
  2015-04-29  2:14     ` Jassi Brar
@ 2015-04-29 17:51     ` Eric Anholt
  2015-04-29 23:47       ` Stephen Warren
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Anholt @ 2015-04-29 17:51 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen Warren <swarren@wwwdotorg.org> writes:

> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>> This gives us a function for making mailbox property channel requests
>> of the firmware, and uses it to control the 3 power domains provided
>> by the firmware.
>
>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>
>> +/*
>> + * Submits a set of concatenated tags to the VPU firmware through the
>> + * mailbox property interface.
>> + *
>> + * The buffer header and the ending tag are added by this function and
>> + * don't need to be supplied, just the actual tags for your operation.
>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>> + */
>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>> +{
>> +	size_t size = tag_size + 12;
>> +	u32 *buf;
>> +	dma_addr_t bus_addr;
>> +	int ret = 0;
>> +
>> +	if (!firmware)
>> +		return -EPROBE_DEFER;
>
> I think it'd make more sense if the clients looked up the firmware
> driver via phandle at their probe time. This would mean:
>
> * No need for global "firmware", since clients could pass the firmware
> driver handle into this function.
>
> * Clients resolve deferred probe at their probe time. That way, they
> won't register themselves with subsystems asserting they can provide
> services, but find out they can't yet provide the service at that time.

The one client so far (vc4) was resolving deferred probe at its probe
time, but not taking a reference on the firmware driver.  I figure I'll
have it do the phandle lookup and refcount -- do you still want the
struct platform_device passed in here?  If we de-global firmware, it's
going to mean some faffing in the power domain side of things to find
the device again, it seems.

>> +static int raspberrypi_firmware_probe(struct platform_device *pdev)
>
> BTW if you wanted, a s/raspberrypi/rpi/ in all symbols and filenames
> seems reasonable. I'm not really bothered either way.

I lean slightly toward avoiding the abbreviation, but I could go either
way as well.

> I would have hoped that mbox_request_channel() returned -EPROBE_DEFER
> itself. It really should...
>
>> +static int raspberrypi_firmware_remove(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +
>> +	of_genpd_del_provider(dev->of_node);
>> +	mbox_free_channel(firmware->chan);
>
> firmware = NULL; ?

Done.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150429/eaf6b107/attachment.sig>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT
  2015-04-29 16:29     ` Eric Anholt
@ 2015-04-29 23:43       ` Stephen Warren
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2015-04-29 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/29/15 10:29, Eric Anholt wrote:
> Stephen Warren <swarren@wwwdotorg.org> writes:
>
>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>> This gets the USB power domain turned on so that DWC2 can probe, even
>>> if the bootloader didn't turn it on for us (which is the case if you
>>> use the RPi firmware without chainloading U-Boot).
>>
>>> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>>
>>> +&usb {
>>> +	power-domains = <&firmware POWER_DOMAIN_USB>;
>>> +};
>>
>> That property doesn't seem to be documented in
>> Documentation/devicetree/bindings/usb/dwc2.txt (which defines compatible
>> = "brcm,bcm2835-usb"). Is it implemented?
>
> power-domains is a generic property that's parsed by
> drivers/base/power/domain.c.  See also
> Documentation/devicetree/bindings/power/power_domain.txt&

Sure, but the binding for the node still needs to mention that it's 
acceptable for that property to exist (a/k/a that the USB binding 
inherits from or aggregates the power domains binding). Part of 
mentioning that would be a description of what the entries in the 
power-domains property mean (how many are legal, what each index 
represents).

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-29 17:51     ` Eric Anholt
@ 2015-04-29 23:47       ` Stephen Warren
  2015-05-12 17:46         ` Eric Anholt
  0 siblings, 1 reply; 23+ messages in thread
From: Stephen Warren @ 2015-04-29 23:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/29/15 11:51, Eric Anholt wrote:
> Stephen Warren <swarren@wwwdotorg.org> writes:
>
>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>> This gives us a function for making mailbox property channel requests
>>> of the firmware, and uses it to control the 3 power domains provided
>>> by the firmware.
>>
>>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>>
>>> +/*
>>> + * Submits a set of concatenated tags to the VPU firmware through the
>>> + * mailbox property interface.
>>> + *
>>> + * The buffer header and the ending tag are added by this function and
>>> + * don't need to be supplied, just the actual tags for your operation.
>>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>>> + */
>>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>>> +{
>>> +	size_t size = tag_size + 12;
>>> +	u32 *buf;
>>> +	dma_addr_t bus_addr;
>>> +	int ret = 0;
>>> +
>>> +	if (!firmware)
>>> +		return -EPROBE_DEFER;
>>
>> I think it'd make more sense if the clients looked up the firmware
>> driver via phandle at their probe time. This would mean:
>>
>> * No need for global "firmware", since clients could pass the firmware
>> driver handle into this function.
>>
>> * Clients resolve deferred probe at their probe time. That way, they
>> won't register themselves with subsystems asserting they can provide
>> services, but find out they can't yet provide the service at that time.
>
> The one client so far (vc4) was resolving deferred probe at its probe
> time, but not taking a reference on the firmware driver.  I figure I'll
> have it do the phandle lookup and refcount -- do you still want the
> struct platform_device passed in here?  If we de-global firmware, it's
> going to mean some faffing in the power domain side of things to find
> the device again, it seems.

I think I'd expect the API in the firmware driver to require the client 
to pass the client DT node pointer plus a property name, and do all the 
lookup itself. That's what most DT resource lookup APIs in the kernel do 
now.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-04-29 23:47       ` Stephen Warren
@ 2015-05-12 17:46         ` Eric Anholt
  2015-05-12 22:08           ` Stephen Warren
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Anholt @ 2015-05-12 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen Warren <swarren@wwwdotorg.org> writes:

> On 04/29/15 11:51, Eric Anholt wrote:
>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>
>>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>>> This gives us a function for making mailbox property channel requests
>>>> of the firmware, and uses it to control the 3 power domains provided
>>>> by the firmware.
>>>
>>>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>>>
>>>> +/*
>>>> + * Submits a set of concatenated tags to the VPU firmware through the
>>>> + * mailbox property interface.
>>>> + *
>>>> + * The buffer header and the ending tag are added by this function and
>>>> + * don't need to be supplied, just the actual tags for your operation.
>>>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>>>> + */
>>>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>>>> +{
>>>> +	size_t size = tag_size + 12;
>>>> +	u32 *buf;
>>>> +	dma_addr_t bus_addr;
>>>> +	int ret = 0;
>>>> +
>>>> +	if (!firmware)
>>>> +		return -EPROBE_DEFER;
>>>
>>> I think it'd make more sense if the clients looked up the firmware
>>> driver via phandle at their probe time. This would mean:
>>>
>>> * No need for global "firmware", since clients could pass the firmware
>>> driver handle into this function.
>>>
>>> * Clients resolve deferred probe at their probe time. That way, they
>>> won't register themselves with subsystems asserting they can provide
>>> services, but find out they can't yet provide the service at that time.
>>
>> The one client so far (vc4) was resolving deferred probe at its probe
>> time, but not taking a reference on the firmware driver.  I figure I'll
>> have it do the phandle lookup and refcount -- do you still want the
>> struct platform_device passed in here?  If we de-global firmware, it's
>> going to mean some faffing in the power domain side of things to find
>> the device again, it seems.
>
> I think I'd expect the API in the firmware driver to require the client 
> to pass the client DT node pointer plus a property name, and do all the 
> lookup itself. That's what most DT resource lookup APIs in the kernel do 
> now.

I've made this change, but it's not great -- the client has to know some
details of how this driver is structured (that it sets the drvdata) in
order to figure out whether the driver is loaded or not and return
-EPROBE_DEFERRED.  I couldn't find any other existing solutions than
that in the tree.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150512/8ec643cb/attachment.sig>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-05-12 17:46         ` Eric Anholt
@ 2015-05-12 22:08           ` Stephen Warren
  2015-05-13  0:38             ` Eric Anholt
  0 siblings, 1 reply; 23+ messages in thread
From: Stephen Warren @ 2015-05-12 22:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/12/2015 11:46 AM, Eric Anholt wrote:
> Stephen Warren <swarren@wwwdotorg.org> writes:
>
>> On 04/29/15 11:51, Eric Anholt wrote:
>>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>>
>>>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>>>> This gives us a function for making mailbox property channel requests
>>>>> of the firmware, and uses it to control the 3 power domains provided
>>>>> by the firmware.
>>>>
>>>>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>>>>
>>>>> +/*
>>>>> + * Submits a set of concatenated tags to the VPU firmware through the
>>>>> + * mailbox property interface.
>>>>> + *
>>>>> + * The buffer header and the ending tag are added by this function and
>>>>> + * don't need to be supplied, just the actual tags for your operation.
>>>>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>>>>> + */
>>>>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>>>>> +{
>>>>> +	size_t size = tag_size + 12;
>>>>> +	u32 *buf;
>>>>> +	dma_addr_t bus_addr;
>>>>> +	int ret = 0;
>>>>> +
>>>>> +	if (!firmware)
>>>>> +		return -EPROBE_DEFER;
>>>>
>>>> I think it'd make more sense if the clients looked up the firmware
>>>> driver via phandle at their probe time. This would mean:
>>>>
>>>> * No need for global "firmware", since clients could pass the firmware
>>>> driver handle into this function.
>>>>
>>>> * Clients resolve deferred probe at their probe time. That way, they
>>>> won't register themselves with subsystems asserting they can provide
>>>> services, but find out they can't yet provide the service at that time.
>>>
>>> The one client so far (vc4) was resolving deferred probe at its probe
>>> time, but not taking a reference on the firmware driver.  I figure I'll
>>> have it do the phandle lookup and refcount -- do you still want the
>>> struct platform_device passed in here?  If we de-global firmware, it's
>>> going to mean some faffing in the power domain side of things to find
>>> the device again, it seems.
>>
>> I think I'd expect the API in the firmware driver to require the client
>> to pass the client DT node pointer plus a property name, and do all the
>> lookup itself. That's what most DT resource lookup APIs in the kernel do
>> now.
>
> I've made this change, but it's not great -- the client has to know some
> details of how this driver is structured (that it sets the drvdata) in
> order to figure out whether the driver is loaded or not and return
> -EPROBE_DEFERRED.  I couldn't find any other existing solutions than
> that in the tree.

The client shouldn't need to know that.

I'd expect the client to pass a DT node pointer to the provider's 
driver, and that provider driver would know and isolate all the details 
about its own internals. The provider could return some kind of 
handler/... to the provider device if required.

I would expect any subsystem that supports client->provider references 
in DT would have an example of this (e.g. IRQs, GPIOs, regulators, ...). 
However, the code for those can be rather complex to dive into for the 
first time. For a fairly simple standalone example, check out:

Provider:
drivers/amba/tegra-ahb.c
tegra_ahb_enable_smmu()

Consumer:
drivers/iommu/tegra-smmu.c
tegra_smmu_ahb_enable()
(called from tegra_smmu_probe() in the same file)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-05-12 22:08           ` Stephen Warren
@ 2015-05-13  0:38             ` Eric Anholt
  2015-05-13 18:28               ` Stephen Warren
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Anholt @ 2015-05-13  0:38 UTC (permalink / raw)
  To: linux-arm-kernel

Stephen Warren <swarren@wwwdotorg.org> writes:

> On 05/12/2015 11:46 AM, Eric Anholt wrote:
>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>
>>> On 04/29/15 11:51, Eric Anholt wrote:
>>>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>>>
>>>>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>>>>> This gives us a function for making mailbox property channel requests
>>>>>> of the firmware, and uses it to control the 3 power domains provided
>>>>>> by the firmware.
>>>>>
>>>>>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>>>>>
>>>>>> +/*
>>>>>> + * Submits a set of concatenated tags to the VPU firmware through the
>>>>>> + * mailbox property interface.
>>>>>> + *
>>>>>> + * The buffer header and the ending tag are added by this function and
>>>>>> + * don't need to be supplied, just the actual tags for your operation.
>>>>>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>>>>>> + */
>>>>>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>>>>>> +{
>>>>>> +	size_t size = tag_size + 12;
>>>>>> +	u32 *buf;
>>>>>> +	dma_addr_t bus_addr;
>>>>>> +	int ret = 0;
>>>>>> +
>>>>>> +	if (!firmware)
>>>>>> +		return -EPROBE_DEFER;
>>>>>
>>>>> I think it'd make more sense if the clients looked up the firmware
>>>>> driver via phandle at their probe time. This would mean:
>>>>>
>>>>> * No need for global "firmware", since clients could pass the firmware
>>>>> driver handle into this function.
>>>>>
>>>>> * Clients resolve deferred probe at their probe time. That way, they
>>>>> won't register themselves with subsystems asserting they can provide
>>>>> services, but find out they can't yet provide the service at that time.
>>>>
>>>> The one client so far (vc4) was resolving deferred probe at its probe
>>>> time, but not taking a reference on the firmware driver.  I figure I'll
>>>> have it do the phandle lookup and refcount -- do you still want the
>>>> struct platform_device passed in here?  If we de-global firmware, it's
>>>> going to mean some faffing in the power domain side of things to find
>>>> the device again, it seems.
>>>
>>> I think I'd expect the API in the firmware driver to require the client
>>> to pass the client DT node pointer plus a property name, and do all the
>>> lookup itself. That's what most DT resource lookup APIs in the kernel do
>>> now.
>>
>> I've made this change, but it's not great -- the client has to know some
>> details of how this driver is structured (that it sets the drvdata) in
>> order to figure out whether the driver is loaded or not and return
>> -EPROBE_DEFERRED.  I couldn't find any other existing solutions than
>> that in the tree.
>
> The client shouldn't need to know that.
>
> I'd expect the client to pass a DT node pointer to the provider's 
> driver, and that provider driver would know and isolate all the details 
> about its own internals. The provider could return some kind of 
> handler/... to the provider device if required.
>
> I would expect any subsystem that supports client->provider references 
> in DT would have an example of this (e.g. IRQs, GPIOs, regulators, ...). 
> However, the code for those can be rather complex to dive into for the 
> first time. For a fairly simple standalone example, check out:
>
> Provider:
> drivers/amba/tegra-ahb.c
> tegra_ahb_enable_smmu()
>
> Consumer:
> drivers/iommu/tegra-smmu.c
> tegra_smmu_ahb_enable()
> (called from tegra_smmu_probe() in the same file)

It's somewhat suspicious to me as an example of how -EPROBE_DEFER ought
to work, that tegra_ahb_enable_smmu()'s return value isn't being checked
by tegra_smmu_ahb_enable().

That said, this looks like this is "Yeah, just call into the producer
driver to do setup, and if it returns -EPROBE_DEFER, then bail out and
return -EPROBE_DEFER, yourself."  That's what I was doing in this
function and its consumers, that you commented on, only I wasn't passing
in the dt node.  Is that all you wanted changed?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150512/1e75a572/attachment.sig>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM: bcm2835: Add the Raspberry Pi firmware driver
  2015-05-13  0:38             ` Eric Anholt
@ 2015-05-13 18:28               ` Stephen Warren
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2015-05-13 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/12/2015 06:38 PM, Eric Anholt wrote:
> Stephen Warren <swarren@wwwdotorg.org> writes:
>
>> On 05/12/2015 11:46 AM, Eric Anholt wrote:
>>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>>
>>>> On 04/29/15 11:51, Eric Anholt wrote:
>>>>> Stephen Warren <swarren@wwwdotorg.org> writes:
>>>>>
>>>>>> On 04/27/2015 05:14 PM, Eric Anholt wrote:
>>>>>>> This gives us a function for making mailbox property channel requests
>>>>>>> of the firmware, and uses it to control the 3 power domains provided
>>>>>>> by the firmware.
>>>>>>
>>>>>>> diff --git a/arch/arm/mach-bcm/raspberrypi-firmware.c b/arch/arm/mach-bcm/raspberrypi-firmware.c
>>>>>>
>>>>>>> +/*
>>>>>>> + * Submits a set of concatenated tags to the VPU firmware through the
>>>>>>> + * mailbox property interface.
>>>>>>> + *
>>>>>>> + * The buffer header and the ending tag are added by this function and
>>>>>>> + * don't need to be supplied, just the actual tags for your operation.
>>>>>>> + * See struct raspberrypi_firmware_property_tag_header for the per-tag structure.
>>>>>>> + */
>>>>>>> +int raspberrypi_firmware_property(void *data, size_t tag_size)
>>>>>>> +{
>>>>>>> +	size_t size = tag_size + 12;
>>>>>>> +	u32 *buf;
>>>>>>> +	dma_addr_t bus_addr;
>>>>>>> +	int ret = 0;
>>>>>>> +
>>>>>>> +	if (!firmware)
>>>>>>> +		return -EPROBE_DEFER;
>>>>>>
>>>>>> I think it'd make more sense if the clients looked up the firmware
>>>>>> driver via phandle at their probe time. This would mean:
>>>>>>
>>>>>> * No need for global "firmware", since clients could pass the firmware
>>>>>> driver handle into this function.
>>>>>>
>>>>>> * Clients resolve deferred probe at their probe time. That way, they
>>>>>> won't register themselves with subsystems asserting they can provide
>>>>>> services, but find out they can't yet provide the service at that time.
>>>>>
>>>>> The one client so far (vc4) was resolving deferred probe at its probe
>>>>> time, but not taking a reference on the firmware driver.  I figure I'll
>>>>> have it do the phandle lookup and refcount -- do you still want the
>>>>> struct platform_device passed in here?  If we de-global firmware, it's
>>>>> going to mean some faffing in the power domain side of things to find
>>>>> the device again, it seems.
>>>>
>>>> I think I'd expect the API in the firmware driver to require the client
>>>> to pass the client DT node pointer plus a property name, and do all the
>>>> lookup itself. That's what most DT resource lookup APIs in the kernel do
>>>> now.
>>>
>>> I've made this change, but it's not great -- the client has to know some
>>> details of how this driver is structured (that it sets the drvdata) in
>>> order to figure out whether the driver is loaded or not and return
>>> -EPROBE_DEFERRED.  I couldn't find any other existing solutions than
>>> that in the tree.
>>
>> The client shouldn't need to know that.
>>
>> I'd expect the client to pass a DT node pointer to the provider's
>> driver, and that provider driver would know and isolate all the details
>> about its own internals. The provider could return some kind of
>> handler/... to the provider device if required.
>>
>> I would expect any subsystem that supports client->provider references
>> in DT would have an example of this (e.g. IRQs, GPIOs, regulators, ...).
>> However, the code for those can be rather complex to dive into for the
>> first time. For a fairly simple standalone example, check out:
>>
>> Provider:
>> drivers/amba/tegra-ahb.c
>> tegra_ahb_enable_smmu()
>>
>> Consumer:
>> drivers/iommu/tegra-smmu.c
>> tegra_smmu_ahb_enable()
>> (called from tegra_smmu_probe() in the same file)
>
> It's somewhat suspicious to me as an example of how -EPROBE_DEFER ought
> to work, that tegra_ahb_enable_smmu()'s return value isn't being checked
> by tegra_smmu_ahb_enable().

Oh that's certainly a bug, and needs to be fixed; both 
tegra_smmu_ahb_enable() and tegra_smmu_probe() should propagate any 
-EPROBE_DEFERRED out if they happen. I'll file a bug for that internally.

> That said, this looks like this is "Yeah, just call into the producer
> driver to do setup, and if it returns -EPROBE_DEFER, then bail out and
> return -EPROBE_DEFER, yourself."  That's what I was doing in this
> function and its consumers, that you commented on, only I wasn't passing
> in the dt node.  Is that all you wanted changed?

(very briefly looking at the quoted history above) I think the primary 
issue was the -EPROBE_DEFERRED in the patch is returned by a function 
that sends a message, rather than a function which looks up the provider.

There's no general reason to believe that a message will be sent during 
a client driver's probe, so in general a client driver may only notice 
that the firmware provider is missing when the first message is sent, 
which is too late to defer the client driver's probe.

However, any client should always look up any service provider during 
probe, and hence be able to defer its own probe.

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2015-05-13 18:28 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-27 23:14 [PATCH 0/3] Raspberry Pi firmware driver Eric Anholt
2015-04-27 23:14 ` [PATCH 1/3] dt/bindings: Add binding for the " Eric Anholt
2015-04-28  9:34   ` Lee Jones
2015-04-29  1:42   ` Stephen Warren
2015-04-27 23:14 ` [PATCH 2/3] ARM: bcm2835: Add " Eric Anholt
2015-04-28  7:56   ` Arnd Bergmann
2015-04-28 20:07     ` Eric Anholt
2015-04-28  9:27   ` Lee Jones
2015-04-28  9:28   ` Lee Jones
2015-04-29  1:58   ` Stephen Warren
2015-04-29  2:14     ` Jassi Brar
2015-04-29  2:56       ` Jassi Brar
2015-04-29 17:51     ` Eric Anholt
2015-04-29 23:47       ` Stephen Warren
2015-05-12 17:46         ` Eric Anholt
2015-05-12 22:08           ` Stephen Warren
2015-05-13  0:38             ` Eric Anholt
2015-05-13 18:28               ` Stephen Warren
2015-04-27 23:14 ` [PATCH 3/3] ARM: bcm2835: Add the necessary firmware driver information to the DT Eric Anholt
2015-04-28  9:33   ` Lee Jones
2015-04-29  1:44   ` Stephen Warren
2015-04-29 16:29     ` Eric Anholt
2015-04-29 23:43       ` Stephen Warren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.