summaryrefslogtreecommitdiffstats
path: root/configs/platform-rpi/patches
diff options
context:
space:
mode:
Diffstat (limited to 'configs/platform-rpi/patches')
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch66
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch75
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch25
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch444
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch68
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch141
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch30
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch94
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch34
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch28
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch32
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch374
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch69
-rw-r--r--configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch60
-rw-r--r--configs/platform-rpi/patches/linux-4.4/series17
15 files changed, 1557 insertions, 0 deletions
diff --git a/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch b/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch
new file mode 100644
index 0000000..ac782ab
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch
@@ -0,0 +1,66 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 16 Dec 2015 12:25:00 -0800
+Subject: [PATCH] irq: bcm2836: Fix initialization of the LOCAL_IRQ_CNT*IRQ
+ timers
+
+The irqchip's register area includes the the setup for the timer's
+scaling factors, and for the platform we want a fixed configuration of
+these registers.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ drivers/irqchip/irq-bcm2836.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
+index f68708281fcf..6ec125ef3607 100644
+--- a/drivers/irqchip/irq-bcm2836.c
++++ b/drivers/irqchip/irq-bcm2836.c
+@@ -21,6 +21,9 @@
+ #include <linux/irqdomain.h>
+ #include <asm/exception.h>
+
++#define LOCAL_CONTROL 0x000
++#define LOCAL_PRESCALER 0x008
++
+ /*
+ * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
+ * next 2 bits identify the CPU that the GPU FIQ goes to.
+@@ -237,6 +240,27 @@ bcm2836_arm_irqchip_smp_init(void)
+ #endif
+ }
+
++/*
++ * The LOCAL_IRQ_CNT* timer firings are based off of the external
++ * oscillator with some scaling. The firmware sets up CNTFRQ to
++ * report 19.2Mhz, but doesn't set up the scaling registers.
++ */
++static void bcm2835_init_local_timer_frequency(void)
++{
++ /*
++ * Set the timer to source from the 19.2Mhz crystal clock (bit
++ * 8 unset), and only increment by 1 instead of 2 (bit 9
++ * unset).
++ */
++ writel(0, intc.base + LOCAL_CONTROL);
++
++ /*
++ * Set the timer prescaler to 1:1 (timer freq = input freq *
++ * 2**31 / prescaler)
++ */
++ writel(0x80000000, intc.base + LOCAL_PRESCALER);
++}
++
+ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
+ struct device_node *parent)
+ {
+@@ -246,6 +270,8 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
+ node->full_name);
+ }
+
++ bcm2835_init_local_timer_frequency();
++
+ intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1,
+ &bcm2836_arm_irqchip_intc_ops,
+ NULL);
diff --git a/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch b/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch
new file mode 100644
index 0000000..2e25c68
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch
@@ -0,0 +1,75 @@
+From: Andrea Merello <andrea.merello@gmail.com>
+Date: Sun, 3 May 2015 01:03:11 +0200
+Subject: [PATCH] irq: bcm2836: Add SMP support for the 2836
+
+The firmware sets the secondaries spinning waiting for a non-NULL
+value to show up in the last IPI mailbox.
+
+The original SMP port from the downstream tree was done by Andrea, and
+Eric cleaned it up/rewrote it a few times from there.
+
+Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ drivers/irqchip/irq-bcm2836.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
+index 6ec125ef3607..c5ef4dfb5bb0 100644
+--- a/drivers/irqchip/irq-bcm2836.c
++++ b/drivers/irqchip/irq-bcm2836.c
+@@ -53,14 +53,16 @@
+ /* Same status bits as above, but for FIQ. */
+ #define LOCAL_FIQ_PENDING0 0x070
+ /*
+- * Mailbox0 write-to-set bits. There are 16 mailboxes, 4 per CPU, and
++ * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
+ * these bits are organized by mailbox number and then CPU number. We
+ * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
+ * any bit is set.
+ */
+ #define LOCAL_MAILBOX0_SET0 0x080
+-/* Mailbox0 write-to-clear bits. */
++#define LOCAL_MAILBOX3_SET0 0x08c
++/* Mailbox write-to-clear bits. */
+ #define LOCAL_MAILBOX0_CLR0 0x0c0
++#define LOCAL_MAILBOX3_CLR0 0x0cc
+
+ #define LOCAL_IRQ_CNTPSIRQ 0
+ #define LOCAL_IRQ_CNTPNSIRQ 1
+@@ -226,6 +228,26 @@ static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
+ .xlate = irq_domain_xlate_onecell
+ };
+
++#ifdef CONFIG_SMP
++int __init bcm2836_smp_boot_secondary(unsigned int cpu,
++ struct task_struct *idle)
++{
++ unsigned long secondary_startup_phys =
++ (unsigned long)virt_to_phys((void *)secondary_startup);
++
++ dsb();
++ writel(secondary_startup_phys,
++ intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
++
++ return 0;
++}
++
++static const struct smp_operations bcm2836_smp_ops __initconst = {
++ .smp_boot_secondary = bcm2836_smp_boot_secondary,
++};
++
++#endif
++
+ static void
+ bcm2836_arm_irqchip_smp_init(void)
+ {
+@@ -237,6 +259,7 @@ bcm2836_arm_irqchip_smp_init(void)
+ register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier);
+
+ set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
++ smp_set_ops(&bcm2836_smp_ops);
+ #endif
+ }
+
diff --git a/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch b/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch
new file mode 100644
index 0000000..062781e
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch
@@ -0,0 +1,25 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 21 Apr 2015 09:42:21 -0700
+Subject: [PATCH] dt-bindings: Add root properties for Raspberry Pi 2
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
+index c78576bb7729..11d3056dc2bd 100644
+--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
++++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
+@@ -26,6 +26,10 @@ Raspberry Pi Model B+
+ Required root node properties:
+ compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
+
++Raspberry Pi 2 Model B
++Required root node properties:
++compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
++
+ Raspberry Pi Compute Module
+ Required root node properties:
+ compatible = "raspberrypi,compute-module", "brcm,bcm2835";
diff --git a/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch b/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch
new file mode 100644
index 0000000..1d01eb3
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch
@@ -0,0 +1,444 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 16 Dec 2015 13:24:40 -0800
+Subject: [PATCH] ARM: bcm2835: Split the DT for peripherals from the DT for
+ the CPU
+
+The set of peripherals remained constant across bcm2835 (Raspberry Pi
+1) and bcm2836 (Raspberry Pi 2), but the CPU was swapped out. Split
+the files so that we can include just peripheral setup in 2836.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/boot/dts/bcm2835.dtsi | 194 +-------------------------------------
+ arch/arm/boot/dts/bcm283x.dtsi | 209 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 210 insertions(+), 193 deletions(-)
+ create mode 100644 arch/arm/boot/dts/bcm283x.dtsi
+
+diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
+index aef64de77495..b83b32639358 100644
+--- a/arch/arm/boot/dts/bcm2835.dtsi
++++ b/arch/arm/boot/dts/bcm2835.dtsi
+@@ -1,206 +1,14 @@
+-#include <dt-bindings/pinctrl/bcm2835.h>
+-#include <dt-bindings/clock/bcm2835.h>
+-#include "skeleton.dtsi"
++#include "bcm283x.dtsi"
+
+ / {
+ compatible = "brcm,bcm2835";
+- model = "BCM2835";
+- interrupt-parent = <&intc>;
+-
+- chosen {
+- bootargs = "earlyprintk console=ttyAMA0";
+- };
+
+ soc {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <1>;
+ ranges = <0x7e000000 0x20000000 0x02000000>;
+ dma-ranges = <0x40000000 0x00000000 0x20000000>;
+
+- timer@7e003000 {
+- compatible = "brcm,bcm2835-system-timer";
+- reg = <0x7e003000 0x1000>;
+- interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
+- /* This could be a reference to BCM2835_CLOCK_TIMER,
+- * but we don't have the driver using the common clock
+- * support yet.
+- */
+- clock-frequency = <1000000>;
+- };
+-
+- dma: dma@7e007000 {
+- compatible = "brcm,bcm2835-dma";
+- reg = <0x7e007000 0xf00>;
+- interrupts = <1 16>,
+- <1 17>,
+- <1 18>,
+- <1 19>,
+- <1 20>,
+- <1 21>,
+- <1 22>,
+- <1 23>,
+- <1 24>,
+- <1 25>,
+- <1 26>,
+- <1 27>,
+- <1 28>;
+-
+- #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x7f35>;
+- };
+-
+- intc: interrupt-controller@7e00b200 {
+- compatible = "brcm,bcm2835-armctrl-ic";
+- reg = <0x7e00b200 0x200>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- };
+-
+- watchdog@7e100000 {
+- compatible = "brcm,bcm2835-pm-wdt";
+- reg = <0x7e100000 0x28>;
+- };
+-
+- clocks: cprman@7e101000 {
+- compatible = "brcm,bcm2835-cprman";
+- #clock-cells = <1>;
+- reg = <0x7e101000 0x2000>;
+-
+- /* CPRMAN derives everything from the platform's
+- * oscillator.
+- */
+- clocks = <&clk_osc>;
+- };
+-
+- rng@7e104000 {
+- compatible = "brcm,bcm2835-rng";
+- reg = <0x7e104000 0x10>;
+- };
+-
+- mailbox: mailbox@7e00b800 {
+- compatible = "brcm,bcm2835-mbox";
+- reg = <0x7e00b880 0x40>;
+- interrupts = <0 1>;
+- #mbox-cells = <0>;
+- };
+-
+- gpio: gpio@7e200000 {
+- compatible = "brcm,bcm2835-gpio";
+- reg = <0x7e200000 0xb4>;
+- /*
+- * The GPIO IP block is designed for 3 banks of GPIOs.
+- * Each bank has a GPIO interrupt for itself.
+- * There is an overall "any bank" interrupt.
+- * In order, these are GIC interrupts 17, 18, 19, 20.
+- * Since the BCM2835 only has 2 banks, the 2nd bank
+- * interrupt output appears to be mirrored onto the
+- * 3rd bank's interrupt signal.
+- * So, a bank0 interrupt shows up on 17, 20, and
+- * a bank1 interrupt shows up on 18, 19, 20!
+- */
+- interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
+-
+- gpio-controller;
+- #gpio-cells = <2>;
+-
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- };
+-
+- uart0: uart@7e201000 {
+- compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
+- reg = <0x7e201000 0x1000>;
+- interrupts = <2 25>;
+- clocks = <&clocks BCM2835_CLOCK_UART>,
+- <&clocks BCM2835_CLOCK_VPU>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- };
+-
+- i2s: i2s@7e203000 {
+- compatible = "brcm,bcm2835-i2s";
+- reg = <0x7e203000 0x20>,
+- <0x7e101098 0x02>;
+-
+- dmas = <&dma 2>,
+- <&dma 3>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- spi: spi@7e204000 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7e204000 0x1000>;
+- interrupts = <2 22>;
+- clocks = <&clocks BCM2835_CLOCK_VPU>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c0: i2c@7e205000 {
+- compatible = "brcm,bcm2835-i2c";
+- reg = <0x7e205000 0x1000>;
+- interrupts = <2 21>;
+- clocks = <&clocks BCM2835_CLOCK_VPU>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- sdhci: sdhci@7e300000 {
+- compatible = "brcm,bcm2835-sdhci";
+- reg = <0x7e300000 0x100>;
+- interrupts = <2 30>;
+- clocks = <&clocks BCM2835_CLOCK_EMMC>;
+- status = "disabled";
+- };
+-
+- i2c1: i2c@7e804000 {
+- compatible = "brcm,bcm2835-i2c";
+- reg = <0x7e804000 0x1000>;
+- interrupts = <2 21>;
+- clocks = <&clocks BCM2835_CLOCK_VPU>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c2: i2c@7e805000 {
+- compatible = "brcm,bcm2835-i2c";
+- reg = <0x7e805000 0x1000>;
+- interrupts = <2 21>;
+- clocks = <&clocks BCM2835_CLOCK_VPU>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- usb@7e980000 {
+- compatible = "brcm,bcm2835-usb";
+- reg = <0x7e980000 0x10000>;
+- interrupts = <1 9>;
+- };
+-
+ arm-pmu {
+ compatible = "arm,arm1176-pmu";
+ };
+ };
+-
+- clocks {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- /* The oscillator is the root of the clock tree. */
+- clk_osc: clock@3 {
+- compatible = "fixed-clock";
+- reg = <3>;
+- #clock-cells = <0>;
+- clock-output-names = "osc";
+- clock-frequency = <19200000>;
+- };
+-
+- };
+ };
+diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
+new file mode 100644
+index 000000000000..bf74e8afbe88
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -0,0 +1,209 @@
++#include <dt-bindings/pinctrl/bcm2835.h>
++#include <dt-bindings/clock/bcm2835.h>
++#include "skeleton.dtsi"
++
++/* This include file covers the common peripherals and configuration between
++ * bcm2835 and bcm2836 implementations, leaving the CPU configuration to
++ * bcm2835.dtsi and bcm2836.dtsi.
++ */
++
++/ {
++ compatible = "brcm,bcm2835";
++ model = "BCM2835";
++ interrupt-parent = <&intc>;
++
++ chosen {
++ bootargs = "earlyprintk console=ttyAMA0";
++ };
++
++ soc {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ timer@7e003000 {
++ compatible = "brcm,bcm2835-system-timer";
++ reg = <0x7e003000 0x1000>;
++ interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
++ /* This could be a reference to BCM2835_CLOCK_TIMER,
++ * but we don't have the driver using the common clock
++ * support yet.
++ */
++ clock-frequency = <1000000>;
++ };
++
++ dma: dma@7e007000 {
++ compatible = "brcm,bcm2835-dma";
++ reg = <0x7e007000 0xf00>;
++ interrupts = <1 16>,
++ <1 17>,
++ <1 18>,
++ <1 19>,
++ <1 20>,
++ <1 21>,
++ <1 22>,
++ <1 23>,
++ <1 24>,
++ <1 25>,
++ <1 26>,
++ <1 27>,
++ <1 28>;
++
++ #dma-cells = <1>;
++ brcm,dma-channel-mask = <0x7f35>;
++ };
++
++ intc: interrupt-controller@7e00b200 {
++ compatible = "brcm,bcm2835-armctrl-ic";
++ reg = <0x7e00b200 0x200>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ watchdog@7e100000 {
++ compatible = "brcm,bcm2835-pm-wdt";
++ reg = <0x7e100000 0x28>;
++ };
++
++ clocks: cprman@7e101000 {
++ compatible = "brcm,bcm2835-cprman";
++ #clock-cells = <1>;
++ reg = <0x7e101000 0x2000>;
++
++ /* CPRMAN derives everything from the platform's
++ * oscillator.
++ */
++ clocks = <&clk_osc>;
++ };
++
++ rng@7e104000 {
++ compatible = "brcm,bcm2835-rng";
++ reg = <0x7e104000 0x10>;
++ };
++
++ mailbox: mailbox@7e00b800 {
++ compatible = "brcm,bcm2835-mbox";
++ reg = <0x7e00b880 0x40>;
++ interrupts = <0 1>;
++ #mbox-cells = <0>;
++ };
++
++ gpio: gpio@7e200000 {
++ compatible = "brcm,bcm2835-gpio";
++ reg = <0x7e200000 0xb4>;
++ /*
++ * The GPIO IP block is designed for 3 banks of GPIOs.
++ * Each bank has a GPIO interrupt for itself.
++ * There is an overall "any bank" interrupt.
++ * In order, these are GIC interrupts 17, 18, 19, 20.
++ * Since the BCM2835 only has 2 banks, the 2nd bank
++ * interrupt output appears to be mirrored onto the
++ * 3rd bank's interrupt signal.
++ * So, a bank0 interrupt shows up on 17, 20, and
++ * a bank1 interrupt shows up on 18, 19, 20!
++ */
++ interrupts = <2 17>, <2 18>, <2 19>, <2 20>;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ uart0: uart@7e201000 {
++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
++ reg = <0x7e201000 0x1000>;
++ interrupts = <2 25>;
++ clocks = <&clocks BCM2835_CLOCK_UART>,
++ <&clocks BCM2835_CLOCK_VPU>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ };
++
++ i2s: i2s@7e203000 {
++ compatible = "brcm,bcm2835-i2s";
++ reg = <0x7e203000 0x20>,
++ <0x7e101098 0x02>;
++
++ dmas = <&dma 2>,
++ <&dma 3>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ spi: spi@7e204000 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7e204000 0x1000>;
++ interrupts = <2 22>;
++ clocks = <&clocks BCM2835_CLOCK_VPU>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@7e205000 {
++ compatible = "brcm,bcm2835-i2c";
++ reg = <0x7e205000 0x1000>;
++ interrupts = <2 21>;
++ clocks = <&clocks BCM2835_CLOCK_VPU>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ sdhci: sdhci@7e300000 {
++ compatible = "brcm,bcm2835-sdhci";
++ reg = <0x7e300000 0x100>;
++ interrupts = <2 30>;
++ clocks = <&clocks BCM2835_CLOCK_EMMC>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@7e804000 {
++ compatible = "brcm,bcm2835-i2c";
++ reg = <0x7e804000 0x1000>;
++ interrupts = <2 21>;
++ clocks = <&clocks BCM2835_CLOCK_VPU>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@7e805000 {
++ compatible = "brcm,bcm2835-i2c";
++ reg = <0x7e805000 0x1000>;
++ interrupts = <2 21>;
++ clocks = <&clocks BCM2835_CLOCK_VPU>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ usb@7e980000 {
++ compatible = "brcm,bcm2835-usb";
++ reg = <0x7e980000 0x10000>;
++ interrupts = <1 9>;
++ };
++
++ arm-pmu {
++ compatible = "arm,arm1176-pmu";
++ };
++ };
++
++ clocks {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* The oscillator is the root of the clock tree. */
++ clk_osc: clock@3 {
++ compatible = "fixed-clock";
++ reg = <3>;
++ #clock-cells = <0>;
++ clock-output-names = "osc";
++ clock-frequency = <19200000>;
++ };
++
++ };
++};
diff --git a/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch b/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch
new file mode 100644
index 0000000..1a71a3f
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch
@@ -0,0 +1,68 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 16 Dec 2015 14:43:52 -0800
+Subject: [PATCH] ARM: bcm2835: Move the CPU/peripheral include out of common
+ RPi DT.
+
+For Raspberry Pi 2, we want to use the same general pin assignment
+bits, but need to use bcm2836.dtsi for the CPU instead.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 1 +
+ arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 1 +
+ arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 1 +
+ arch/arm/boot/dts/bcm2835-rpi-b.dts | 1 +
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 --
+ 5 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+index b2bff43b135c..228614ffff44 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+@@ -1,4 +1,5 @@
+ /dts-v1/;
++#include "bcm2835.dtsi"
+ #include "bcm2835-rpi.dtsi"
+
+ / {
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+index 668442b1bda5..ef5405025223 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+@@ -1,4 +1,5 @@
+ /dts-v1/;
++#include "bcm2835.dtsi"
+ #include "bcm2835-rpi.dtsi"
+
+ / {
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+index eab8b5916e8a..86f1f2f598a7 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+@@ -1,4 +1,5 @@
+ /dts-v1/;
++#include "bcm2835.dtsi"
+ #include "bcm2835-rpi.dtsi"
+
+ / {
+diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
+index ff6b2d1c6c90..4859e9d81b23 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
+@@ -1,4 +1,5 @@
+ /dts-v1/;
++#include "bcm2835.dtsi"
+ #include "bcm2835-rpi.dtsi"
+
+ / {
+diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+index 3572f0367baf..3afb9fefe2d1 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -1,5 +1,3 @@
+-#include "bcm2835.dtsi"
+-
+ / {
+ memory {
+ reg = <0 0x10000000>;
diff --git a/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch b/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch
new file mode 100644
index 0000000..9adf7a3
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch
@@ -0,0 +1,141 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 16 Apr 2015 15:26:45 -0700
+Subject: [PATCH] ARM: bcm2835: Add devicetree for bcm2836 and Raspberry Pi 2 B
+
+The Pi 2 B ends up like a Pi 1 B+, with the same peripherals and
+pinout, but the CPU and memory layout changed to use the 2836.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 35 ++++++++++++++++
+ arch/arm/boot/dts/bcm2836.dtsi | 78 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 113 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+ create mode 100644 arch/arm/boot/dts/bcm2836.dtsi
+
+diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+new file mode 100644
+index 000000000000..ff946661bd13
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+@@ -0,0 +1,35 @@
++/dts-v1/;
++#include "bcm2836.dtsi"
++#include "bcm2835-rpi.dtsi"
++
++/ {
++ compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
++ model = "Raspberry Pi 2 Model B";
++
++ memory {
++ reg = <0 0x40000000>;
++ };
++
++ leds {
++ act {
++ gpios = <&gpio 47 0>;
++ };
++
++ pwr {
++ label = "PWR";
++ gpios = <&gpio 35 0>;
++ default-state = "keep";
++ linux,default-trigger = "default-on";
++ };
++ };
++};
++
++&gpio {
++ pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
++
++ /* I2S interface */
++ i2s_alt0: i2s_alt0 {
++ brcm,pins = <18 19 20 21>;
++ brcm,function = <BCM2835_FSEL_ALT0>;
++ };
++};
+diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi
+new file mode 100644
+index 000000000000..9d0651d8f373
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2836.dtsi
+@@ -0,0 +1,78 @@
++#include "bcm283x.dtsi"
++
++/ {
++ compatible = "brcm,bcm2836";
++
++ soc {
++ ranges = <0x7e000000 0x3f000000 0x1000000>,
++ <0x40000000 0x40000000 0x00001000>;
++ dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
++
++ local_intc: local_intc {
++ compatible = "brcm,bcm2836-l1-intc";
++ reg = <0x40000000 0x100>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&local_intc>;
++ };
++
++ arm-pmu {
++ compatible = "arm,cortex-a7-pmu";
++ interrupt-parent = <&local_intc>;
++ interrupts = <9>;
++ };
++ };
++
++ timer {
++ compatible = "arm,armv7-timer";
++ interrupt-parent = <&local_intc>;
++ interrupts = <0>, // PHYS_SECURE_PPI
++ <1>, // PHYS_NONSECURE_PPI
++ <3>, // VIRT_PPI
++ <2>; // HYP_PPI
++ always-on;
++ };
++
++ cpus: cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ v7_cpu0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0xf00>;
++ clock-frequency = <800000000>;
++ };
++
++ v7_cpu1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0xf01>;
++ clock-frequency = <800000000>;
++ };
++
++ v7_cpu2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0xf02>;
++ clock-frequency = <800000000>;
++ };
++
++ v7_cpu3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0xf03>;
++ clock-frequency = <800000000>;
++ };
++ };
++};
++
++/* Make the BCM2835-style global interrupt controller be a child of the
++ * CPU-local interrupt controller.
++ */
++&intc {
++ compatible = "brcm,bcm2836-armctrl-ic";
++ reg = <0x7e00b200 0x200>;
++ interrupt-parent = <&local_intc>;
++ interrupts = <8>;
++};
diff --git a/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch b/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch
new file mode 100644
index 0000000..794ac9d
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch
@@ -0,0 +1,30 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 13 Mar 2015 10:18:06 -0700
+Subject: [PATCH] ARM: bcm2835: Add a compat string for bcm2836 machine probe
+
+Supporting the 2836 requires using the new interrupt controller, which
+we have support for.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/mach-bcm/board_bcm2835.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
+index 0f7b9eac3d15..834d67684e20 100644
+--- a/arch/arm/mach-bcm/board_bcm2835.c
++++ b/arch/arm/mach-bcm/board_bcm2835.c
+@@ -36,7 +36,12 @@ static void __init bcm2835_init(void)
+ }
+
+ static const char * const bcm2835_compat[] = {
++#ifdef CONFIG_ARCH_MULTI_V6
+ "brcm,bcm2835",
++#endif
++#ifdef CONFIG_ARCH_MULTI_V7
++ "brcm,bcm2836",
++#endif
+ NULL
+ };
+
diff --git a/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch b/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch
new file mode 100644
index 0000000..18d0f16
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch
@@ -0,0 +1,94 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 24 Feb 2015 15:07:55 +0000
+Subject: [PATCH] ARM: bcm2835: Add Kconfig support for bcm2836
+
+This should be a complete port of bcm2835 functionality to bcm2836
+(Raspberry Pi 2).
+
+v2: Implement Arnd's feedback to not split to ARCH_BCM2836, and
+ instead use more conditionals in ARCH_BCM2835. Also reduce diff
+ between 2835 and 2836.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/Kconfig.debug | 10 ++++++++--
+ arch/arm/boot/dts/Makefile | 3 ++-
+ arch/arm/mach-bcm/Kconfig | 8 ++++----
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index 259c0ca9c99a..957b876fda92 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -143,7 +143,12 @@ choice
+
+ config DEBUG_BCM2835
+ bool "Kernel low-level debugging on BCM2835 PL011 UART"
+- depends on ARCH_BCM2835
++ depends on ARCH_BCM2835 && ARCH_MULTI_V6
++ select DEBUG_UART_PL01X
++
++ config DEBUG_BCM2836
++ bool "Kernel low-level debugging on BCM2836 PL011 UART"
++ depends on ARCH_BCM2835 && ARCH_MULTI_V7
+ select DEBUG_UART_PL01X
+
+ config DEBUG_BCM_5301X
+@@ -1402,6 +1407,7 @@ config DEBUG_UART_PHYS
+ default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
+ default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
+ default 0x20201000 if DEBUG_BCM2835
++ default 0x3f201000 if DEBUG_BCM2836
+ default 0x3e000000 if DEBUG_BCM_KONA_UART
+ default 0x4000e400 if DEBUG_LL_UART_EFM32
+ default 0x40081000 if DEBUG_LPC18XX_UART0
+@@ -1485,7 +1491,7 @@ config DEBUG_UART_VIRT
+ default 0xf0000be0 if ARCH_EBSA110
+ default 0xf0010000 if DEBUG_ASM9260_UART
+ default 0xf01fb000 if DEBUG_NOMADIK_UART
+- default 0xf0201000 if DEBUG_BCM2835
++ default 0xf0201000 if DEBUG_BCM2835 || DEBUG_BCM2836
+ default 0xf1000300 if DEBUG_BCM_5301X
+ default 0xf1002000 if DEBUG_MT8127_UART0
+ default 0xf1006000 if DEBUG_MT6589_UART0
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 30bbc3746130..54e8f6bc038f 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -60,7 +60,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2835-rpi-b.dtb \
+ bcm2835-rpi-b-rev2.dtb \
+ bcm2835-rpi-b-plus.dtb \
+- bcm2835-rpi-a-plus.dtb
++ bcm2835-rpi-a-plus.dtb \
++ bcm2836-rpi-2-b.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+ bcm4708-asus-rt-ac56u.dtb \
+ bcm4708-asus-rt-ac68u.dtb \
+diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
+index 8c53c55be1fe..d7cada994295 100644
+--- a/arch/arm/mach-bcm/Kconfig
++++ b/arch/arm/mach-bcm/Kconfig
+@@ -122,17 +122,17 @@ config ARCH_BCM_MOBILE_SMP
+ comment "Other Architectures"
+
+ config ARCH_BCM2835
+- bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
++ bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 || ARCH_MULTI_V7
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+- select ARM_ERRATA_411920
++ select ARM_ERRATA_411920 if ARCH_MULTI_V6
+ select ARM_TIMER_SP804
+ select CLKSRC_OF
+ select PINCTRL
+ select PINCTRL_BCM2835
+ help
+- This enables support for the Broadcom BCM2835 SoC. This SoC is
+- used in the Raspberry Pi and Roku 2 devices.
++ This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
++ This SoC is used in the Raspberry Pi and Roku 2 devices.
+
+ config ARCH_BCM_63XX
+ bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
diff --git a/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch b/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch
new file mode 100644
index 0000000..49f4df9
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch
@@ -0,0 +1,34 @@
+From: Andrea Merello <andrea.merello@gmail.com>
+Date: Sat, 26 Dec 2015 13:47:23 -0800
+Subject: [PATCH] irqchip: bcm2836: tolerate IRQs while no flag is set in ISR
+
+On my RPi2 I got a lot of:
+unexpected IRQ trap at vector 00
+
+This happens because bcm2836_arm_irqchip_handle_irq() is sometimes
+invoked even if the ISR is clear, and this case is not handled.
+
+This patch explicitly handle this case, fixing the kernel complaints
+about the bad IRQ lookup.
+
+Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ drivers/irqchip/irq-bcm2836.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
+index c5ef4dfb5bb0..e314cce70201 100644
+--- a/drivers/irqchip/irq-bcm2836.c
++++ b/drivers/irqchip/irq-bcm2836.c
+@@ -177,7 +177,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
+ writel(1 << ipi, mailbox0);
+ handle_IPI(ipi, regs);
+ #endif
+- } else {
++ } else if (stat) {
+ u32 hwirq = ffs(stat) - 1;
+
+ handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
diff --git a/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch b/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch
new file mode 100644
index 0000000..7a4315d
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0010-irqchip-bcm2836-make-code-more-readable.patch
@@ -0,0 +1,28 @@
+From: Andrea Merello <andrea.merello@gmail.com>
+Date: Sat, 26 Dec 2015 13:47:24 -0800
+Subject: [PATCH] irqchip: bcm2836: make code more readable
+
+Avoid using hardcoded magics. We have a #define for this number.
+No functional changes.
+
+Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ drivers/irqchip/irq-bcm2836.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
+index e314cce70201..6c9aaad0e4f1 100644
+--- a/drivers/irqchip/irq-bcm2836.c
++++ b/drivers/irqchip/irq-bcm2836.c
+@@ -167,7 +167,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
+ u32 stat;
+
+ stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu);
+- if (stat & 0x10) {
++ if (stat & BIT(LOCAL_IRQ_MAILBOX0)) {
+ #ifdef CONFIG_SMP
+ void __iomem *mailbox0 = (intc.base +
+ LOCAL_MAILBOX0_CLR0 + 16 * cpu);
diff --git a/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch b/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch
new file mode 100644
index 0000000..807084e
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch
@@ -0,0 +1,32 @@
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 16 Dec 2015 16:26:46 -0800
+Subject: [PATCH] ARM: bcm2835: Define two new packets from the latest
+ firmware.
+
+These packets give us direct access to the firmware's power management
+code, as opposed to GET/SET_POWER_STATE packets that only had a couple
+of domains implemented.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
+index c07d74aa39bf..3fb357193f09 100644
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -72,10 +72,12 @@ 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_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_DOMAIN_STATE = 0x00038030,
+
+ /* Dispmanx TAGS */
+ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
diff --git a/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch b/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch
new file mode 100644
index 0000000..e4aad60
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0012-ARM-bcm2835-add-rpi-power-domain-driver.patch
@@ -0,0 +1,374 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Wed, 16 Dec 2015 16:26:47 -0800
+Subject: [PATCH] ARM: bcm2835: add rpi power domain driver
+
+This patch adds support for several power domains on Raspberry Pi,
+including USB (so it can be enabled even if the bootloader didn't do
+it), and graphics.
+
+This patch is the combined work of Eric Anholt (who wrote USB support
+inside of the Raspberry Pi firmware driver, and wrote the non-USB
+domain support) and Alexander Aring (who separated the original USB
+work out from the firmware driver).
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ drivers/soc/Kconfig | 1 +
+ drivers/soc/Makefile | 1 +
+ drivers/soc/bcm/Kconfig | 9 +
+ drivers/soc/bcm/Makefile | 1 +
+ drivers/soc/bcm/raspberrypi-power.c | 247 ++++++++++++++++++++++++++++
+ include/dt-bindings/soc/raspberrypi-power.h | 41 +++++
+ 6 files changed, 300 insertions(+)
+ create mode 100644 drivers/soc/bcm/Kconfig
+ create mode 100644 drivers/soc/bcm/Makefile
+ create mode 100644 drivers/soc/bcm/raspberrypi-power.c
+ create mode 100644 include/dt-bindings/soc/raspberrypi-power.h
+
+diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
+index 4e853ed2c82b..844142620031 100644
+--- a/drivers/soc/Kconfig
++++ b/drivers/soc/Kconfig
+@@ -1,5 +1,6 @@
+ menu "SOC (System On Chip) specific Drivers"
+
++source "drivers/soc/bcm/Kconfig"
+ source "drivers/soc/brcmstb/Kconfig"
+ source "drivers/soc/mediatek/Kconfig"
+ source "drivers/soc/qcom/Kconfig"
+diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
+index f2ba2e932ae1..f3f955cdb04b 100644
+--- a/drivers/soc/Makefile
++++ b/drivers/soc/Makefile
+@@ -2,6 +2,7 @@
+ # Makefile for the Linux Kernel SOC specific device drivers.
+ #
+
++obj-y += bcm/
+ obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/
+ obj-$(CONFIG_MACH_DOVE) += dove/
+ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
+new file mode 100644
+index 000000000000..5ba1827fe36f
+--- /dev/null
++++ b/drivers/soc/bcm/Kconfig
+@@ -0,0 +1,9 @@
++config RASPBERRYPI_POWER
++ bool "Raspberry Pi power domain driver"
++ depends on ARCH_BCM2835 || COMPILE_TEST
++ depends on RASPBERRYPI_FIRMWARE
++ select PM_GENERIC_DOMAINS if PM
++ select PM_GENERIC_DOMAINS_OF if PM
++ help
++ This enables support for the RPi power domains which can be enabled
++ or disabled via the RPi firmware.
+diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile
+new file mode 100644
+index 000000000000..63aa3eb23087
+--- /dev/null
++++ b/drivers/soc/bcm/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o
+diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c
+new file mode 100644
+index 000000000000..d5bab0696580
+--- /dev/null
++++ b/drivers/soc/bcm/raspberrypi-power.c
+@@ -0,0 +1,247 @@
++/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
++ *
++ * 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.
++ *
++ * Authors:
++ * Alexander Aring <aar@pengutronix.de>
++ * Eric Anholt <eric@anholt.net>
++ */
++
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/platform_device.h>
++#include <linux/pm_domain.h>
++#include <dt-bindings/soc/raspberrypi-power.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++/*
++ * Firmware indices for the old power domains interface. Only a few
++ * of them were actually implemented.
++ */
++#define RPI_OLD_POWER_DOMAIN_USB 3
++#define RPI_OLD_POWER_DOMAIN_V3D 10
++
++struct rpi_power_domain {
++ u32 domain;
++ bool enabled;
++ bool old_interface;
++ struct generic_pm_domain base;
++ struct rpi_firmware *fw;
++};
++
++struct rpi_power_domains {
++ bool has_new_interface;
++ struct genpd_onecell_data xlate;
++ struct rpi_firmware *fw;
++ struct rpi_power_domain domains[RPI_POWER_DOMAIN_COUNT];
++};
++
++/*
++ * Packet definition used by RPI_FIRMWARE_SET_POWER_STATE and
++ * RPI_FIRMWARE_SET_DOMAIN_STATE
++ */
++struct rpi_power_domain_packet {
++ u32 domain;
++ u32 on;
++} __packet;
++
++/*
++ * Asks the firmware to enable or disable power on a specific power
++ * domain.
++ */
++static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on)
++{
++ struct rpi_power_domain_packet packet;
++
++ packet.domain = rpi_domain->domain;
++ packet.on = on;
++ return rpi_firmware_property(rpi_domain->fw,
++ rpi_domain->old_interface ?
++ RPI_FIRMWARE_SET_POWER_STATE :
++ RPI_FIRMWARE_SET_DOMAIN_STATE,
++ &packet, sizeof(packet));
++}
++
++static int rpi_domain_off(struct generic_pm_domain *domain)
++{
++ struct rpi_power_domain *rpi_domain =
++ container_of(domain, struct rpi_power_domain, base);
++
++ return rpi_firmware_set_power(rpi_domain, false);
++}
++
++static int rpi_domain_on(struct generic_pm_domain *domain)
++{
++ struct rpi_power_domain *rpi_domain =
++ container_of(domain, struct rpi_power_domain, base);
++
++ return rpi_firmware_set_power(rpi_domain, true);
++}
++
++static void rpi_common_init_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ dom->fw = rpi_domains->fw;
++
++ dom->base.name = name;
++ dom->base.power_on = rpi_domain_on;
++ dom->base.power_off = rpi_domain_off;
++
++ /*
++ * Treat all power domains as off at boot.
++ *
++ * The firmware itself may be keeping some domains on, but
++ * from Linux's perspective all we control is the refcounts
++ * that we give to the firmware, and we can't ask the firmware
++ * to turn off something that we haven't ourselves turned on.
++ */
++ pm_genpd_init(&dom->base, NULL, true);
++
++ rpi_domains->xlate.domains[xlate_index] = &dom->base;
++}
++
++static void rpi_init_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ if (!rpi_domains->has_new_interface)
++ return;
++
++ /* The DT binding index is the firmware's domain index minus one. */
++ dom->domain = xlate_index + 1;
++
++ rpi_common_init_power_domain(rpi_domains, xlate_index, name);
++}
++
++static void rpi_init_old_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, int domain,
++ const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ dom->old_interface = true;
++ dom->domain = domain;
++
++ rpi_common_init_power_domain(rpi_domains, xlate_index, name);
++}
++
++/*
++ * Detects whether the firmware supports the new power domains interface.
++ *
++ * The firmware doesn't actually return an error on an unknown tag,
++ * and just skips over it, so we do the detection by putting an
++ * unexpected value in the return field and checking if it was
++ * unchanged.
++ */
++static bool
++rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains)
++{
++ struct rpi_power_domain_packet packet;
++ int ret;
++
++ packet.domain = RPI_POWER_DOMAIN_ARM;
++ packet.on = ~0;
++
++ ret = rpi_firmware_property(rpi_domains->fw,
++ RPI_FIRMWARE_GET_DOMAIN_STATE,
++ &packet, sizeof(packet));
++
++ return ret == 0 && packet.on != ~0;
++}
++
++static int rpi_power_probe(struct platform_device *pdev)
++{
++ struct device_node *fw_np;
++ struct device *dev = &pdev->dev;
++ struct rpi_power_domains *rpi_domains;
++
++ rpi_domains = devm_kzalloc(dev, sizeof(*rpi_domains), GFP_KERNEL);
++ if (!rpi_domains)
++ return -ENOMEM;
++
++ rpi_domains->xlate.domains =
++ devm_kzalloc(dev, sizeof(*rpi_domains->xlate.domains) *
++ RPI_POWER_DOMAIN_COUNT, GFP_KERNEL);
++ if (!rpi_domains->xlate.domains)
++ return -ENOMEM;
++
++ rpi_domains->xlate.num_domains = RPI_POWER_DOMAIN_COUNT;
++
++ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
++ if (!fw_np) {
++ dev_err(&pdev->dev, "no firmware node\n");
++ return -ENODEV;
++ }
++
++ rpi_domains->fw = rpi_firmware_get(fw_np);
++ of_node_put(fw_np);
++ if (!rpi_domains->fw)
++ return -EPROBE_DEFER;
++
++ rpi_domains->has_new_interface =
++ rpi_has_new_domain_support(rpi_domains);
++
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C0, "I2C0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C1, "I2C1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C2, "I2C2");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VIDEO_SCALER,
++ "VIDEO_SCALER");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VPU1, "VPU1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_HDMI, "HDMI");
++
++ /*
++ * Use the old firmware interface for USB power, so that we
++ * can turn it on even if the firmware hasn't been updated.
++ */
++ rpi_init_old_power_domain(rpi_domains, RPI_POWER_DOMAIN_USB,
++ RPI_OLD_POWER_DOMAIN_USB, "USB");
++
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VEC, "VEC");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_JPEG, "JPEG");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_H264, "H264");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_V3D, "V3D");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ISP, "ISP");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM0, "UNICAM0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM1, "UNICAM1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2RX, "CCP2RX");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CSI2, "CSI2");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CPI, "CPI");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI0, "DSI0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI1, "DSI1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_TRANSPOSER,
++ "TRANSPOSER");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2TX, "CCP2TX");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CDP, "CDP");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ARM, "ARM");
++
++ of_genpd_add_provider_onecell(dev->of_node, &rpi_domains->xlate);
++
++ platform_set_drvdata(pdev, rpi_domains);
++
++ return 0;
++}
++
++static const struct of_device_id rpi_power_of_match[] = {
++ { .compatible = "raspberrypi,bcm2835-power", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rpi_power_of_match);
++
++static struct platform_driver rpi_power_driver = {
++ .driver = {
++ .name = "raspberrypi-power",
++ .of_match_table = rpi_power_of_match,
++ },
++ .probe = rpi_power_probe,
++};
++builtin_platform_driver(rpi_power_driver);
++
++MODULE_AUTHOR("Alexander Aring <aar@pengutronix.de>");
++MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
++MODULE_DESCRIPTION("Raspberry Pi power domain driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/dt-bindings/soc/raspberrypi-power.h b/include/dt-bindings/soc/raspberrypi-power.h
+new file mode 100644
+index 000000000000..b3ff8e09a78f
+--- /dev/null
++++ b/include/dt-bindings/soc/raspberrypi-power.h
+@@ -0,0 +1,41 @@
++/*
++ * 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_RPI_POWER_H
++#define _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
++
++/* These power domain indices are the firmware interface's indices
++ * minus one.
++ */
++#define RPI_POWER_DOMAIN_I2C0 0
++#define RPI_POWER_DOMAIN_I2C1 1
++#define RPI_POWER_DOMAIN_I2C2 2
++#define RPI_POWER_DOMAIN_VIDEO_SCALER 3
++#define RPI_POWER_DOMAIN_VPU1 4
++#define RPI_POWER_DOMAIN_HDMI 5
++#define RPI_POWER_DOMAIN_USB 6
++#define RPI_POWER_DOMAIN_VEC 7
++#define RPI_POWER_DOMAIN_JPEG 8
++#define RPI_POWER_DOMAIN_H264 9
++#define RPI_POWER_DOMAIN_V3D 10
++#define RPI_POWER_DOMAIN_ISP 11
++#define RPI_POWER_DOMAIN_UNICAM0 12
++#define RPI_POWER_DOMAIN_UNICAM1 13
++#define RPI_POWER_DOMAIN_CCP2RX 14
++#define RPI_POWER_DOMAIN_CSI2 15
++#define RPI_POWER_DOMAIN_CPI 16
++#define RPI_POWER_DOMAIN_DSI0 17
++#define RPI_POWER_DOMAIN_DSI1 18
++#define RPI_POWER_DOMAIN_TRANSPOSER 19
++#define RPI_POWER_DOMAIN_CCP2TX 20
++#define RPI_POWER_DOMAIN_CDP 21
++#define RPI_POWER_DOMAIN_ARM 22
++
++#define RPI_POWER_DOMAIN_COUNT 23
++
++#endif /* _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H */
diff --git a/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch b/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch
new file mode 100644
index 0000000..e8cab3a
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch
@@ -0,0 +1,69 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Wed, 16 Dec 2015 16:26:48 -0800
+Subject: [PATCH] dt-bindings: add rpi power domain driver bindings
+
+This patch adds devicetree tree bindings for the Raspberry Pi power
+domain driver.
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ .../bindings/soc/bcm/raspberrypi,bcm2835-power.txt | 47 ++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
+
+diff --git a/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
+new file mode 100644
+index 000000000000..30942cf7992b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/soc/bcm/raspberrypi,bcm2835-power.txt
+@@ -0,0 +1,47 @@
++Raspberry Pi power domain driver
++
++Required properties:
++
++- compatible: Should be "raspberrypi,bcm2835-power".
++- firmware: Reference to the RPi firmware device node.
++- #power-domain-cells: Should be <1>, we providing multiple power domains.
++
++The valid defines for power domain are:
++
++ RPI_POWER_DOMAIN_I2C0
++ RPI_POWER_DOMAIN_I2C1
++ RPI_POWER_DOMAIN_I2C2
++ RPI_POWER_DOMAIN_VIDEO_SCALER
++ RPI_POWER_DOMAIN_VPU1
++ RPI_POWER_DOMAIN_HDMI
++ RPI_POWER_DOMAIN_USB
++ RPI_POWER_DOMAIN_VEC
++ RPI_POWER_DOMAIN_JPEG
++ RPI_POWER_DOMAIN_H264
++ RPI_POWER_DOMAIN_V3D
++ RPI_POWER_DOMAIN_ISP
++ RPI_POWER_DOMAIN_UNICAM0
++ RPI_POWER_DOMAIN_UNICAM1
++ RPI_POWER_DOMAIN_CCP2RX
++ RPI_POWER_DOMAIN_CSI2
++ RPI_POWER_DOMAIN_CPI
++ RPI_POWER_DOMAIN_DSI0
++ RPI_POWER_DOMAIN_DSI1
++ RPI_POWER_DOMAIN_TRANSPOSER
++ RPI_POWER_DOMAIN_CCP2TX
++ RPI_POWER_DOMAIN_CDP
++ RPI_POWER_DOMAIN_ARM
++
++Example:
++
++power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++};
++
++Example for using power domain:
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
diff --git a/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch b/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch
new file mode 100644
index 0000000..6bbce3f
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch
@@ -0,0 +1,60 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Wed, 16 Dec 2015 16:26:49 -0800
+Subject: [PATCH] ARM: bcm2835: Add the Raspberry Pi power domain driver to the
+ DT.
+
+This connects the USB driver to the USB power domain, so that USB can
+actually be turned on at boot if the bootloader didn't do it for us.
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+---
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 12 ++++++++++++
+ arch/arm/boot/dts/bcm283x.dtsi | 2 +-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+index 3afb9fefe2d1..aad668c81d8c 100644
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -1,3 +1,5 @@
++#include <dt-bindings/soc/raspberrypi-power.h>
++
+ / {
+ memory {
+ reg = <0 0x10000000>;
+@@ -18,6 +20,12 @@
+ compatible = "raspberrypi,bcm2835-firmware";
+ mboxes = <&mailbox>;
+ };
++
++ power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++ };
+ };
+ };
+
+@@ -58,3 +66,7 @@
+ status = "okay";
+ bus-width = <4>;
+ };
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
+diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
+index bf74e8afbe88..c8e8e4b98097 100644
+--- a/arch/arm/boot/dts/bcm283x.dtsi
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -180,7 +180,7 @@
+ status = "disabled";
+ };
+
+- usb@7e980000 {
++ usb: usb@7e980000 {
+ compatible = "brcm,bcm2835-usb";
+ reg = <0x7e980000 0x10000>;
+ interrupts = <1 9>;
diff --git a/configs/platform-rpi/patches/linux-4.4/series b/configs/platform-rpi/patches/linux-4.4/series
new file mode 100644
index 0000000..6ab99e2
--- /dev/null
+++ b/configs/platform-rpi/patches/linux-4.4/series
@@ -0,0 +1,17 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+0001-irq-bcm2836-Fix-initialization-of-the-LOCAL_IRQ_CNT-.patch
+0002-irq-bcm2836-Add-SMP-support-for-the-2836.patch
+0003-dt-bindings-Add-root-properties-for-Raspberry-Pi-2.patch
+0004-ARM-bcm2835-Split-the-DT-for-peripherals-from-the-DT.patch
+0005-ARM-bcm2835-Move-the-CPU-peripheral-include-out-of-c.patch
+0006-ARM-bcm2835-Add-devicetree-for-bcm2836-and-Raspberry.patch
+0007-ARM-bcm2835-Add-a-compat-string-for-bcm2836-machine-.patch
+0008-ARM-bcm2835-Add-Kconfig-support-for-bcm2836.patch
+0009-irqchip-bcm2836-tolerate-IRQs-while-no-flag-is-set-i.patch
+0010-irqchip-bcm2836-make-code-more-readable.patch
+0011-ARM-bcm2835-Define-two-new-packets-from-the-latest-f.patch
+0012-ARM-bcm2835-add-rpi-power-domain-driver.patch
+0013-dt-bindings-add-rpi-power-domain-driver-bindings.patch
+0014-ARM-bcm2835-Add-the-Raspberry-Pi-power-domain-driver.patch
+# bb2d21d7e88e49e7345c57522cc98977 - git-ptx-patches magic