diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index fce60a62ce..ac6f79e6d1 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ -From 3cc8c1beb520133149f9cb5d394cbc1c8bbb01b0 Mon Sep 17 00:00:00 2001 +From e25d546f3718eac8527f09bba58083d175247f19 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 001/251] smsx95xx: fix crimes against truesize +Subject: [PATCH 001/114] smsx95xx: fix crimes against truesize smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. @@ -9,44 +9,56 @@ This patch stops smsc95xx from changing truesize. Signed-off-by: Steve Glendinning --- - drivers/net/usb/smsc95xx.c | 2 -- - 1 file changed, 2 deletions(-) - mode change 100644 => 100755 drivers/net/usb/smsc95xx.c + drivers/net/usb/smsc95xx.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100644 -new mode 100755 -index 66b3ab9..b544181 +index 66b3ab9..ea2dbe5 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -1785,7 +1785,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +@@ -74,6 +74,10 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + ++static bool truesize_mode = false; ++module_param(truesize_mode, bool, 0644); ++MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); ++ + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +@@ -1785,7 +1789,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(skb); skb_trim(skb, skb->len - 4); /* remove fcs */ - skb->truesize = size + sizeof(struct sk_buff); ++ if (truesize_mode) ++ skb->truesize = size + sizeof(struct sk_buff); return 1; } -@@ -1803,7 +1802,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +@@ -1803,7 +1808,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(ax_skb); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ - ax_skb->truesize = size + sizeof(struct sk_buff); ++ if (truesize_mode) ++ ax_skb->truesize = size + sizeof(struct sk_buff); usbnet_skb_return(dev, ax_skb); } -From d41a067375e9d557ee14ad6ecefbc559b724087c Mon Sep 17 00:00:00 2001 +From 607cb751d33b6af0d182a82a96eb14e4ff7c2ed7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 002/251] smsc95xx: Disable turbo mode by default +Subject: [PATCH 002/114] smsc95xx: Disable turbo mode by default --- drivers/net/usb/smsc95xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index b544181..9c0da18 100755 +index ea2dbe5..714cfe0 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -70,7 +70,7 @@ struct smsc95xx_priv { @@ -59,10 +71,41 @@ index b544181..9c0da18 100755 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); -From 52a67e5a346e7dfcd6af9115800108d6c9fca84e Mon Sep 17 00:00:00 2001 +From 1f222ae94cf97c02532c10a907fba8a7e1d57f08 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 9 Mar 2016 13:28:24 +0000 +Subject: [PATCH 003/114] serial: Take care starting a hung-up tty's port + +tty_port_hangup sets a port's tty field to NULL (holding the port lock), +but uart_tx_stopped, called from __uart_start (with the port lock), +uses the tty field without checking for NULL. + +Change uart_tx_stopped to treat a NULL tty field as another stopped +indication. + +Signed-off-by: Phil Elwell +--- + include/linux/serial_core.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index cbfcf38..96bc15a 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -403,7 +403,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); + static inline int uart_tx_stopped(struct uart_port *port) + { + struct tty_struct *tty = port->state->port.tty; +- if (tty->stopped || port->hw_stopped) ++ if (!tty || tty->stopped || port->hw_stopped) + return 1; + return 0; + } + +From dc048b33ed7346ea328d4e513f10549f37d98fb7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 003/251] vmstat: Workaround for issue where dirty page count +Subject: [PATCH 004/114] vmstat: Workaround for issue where dirty page count goes negative See: @@ -73,10 +116,10 @@ http://www.spinics.net/lists/linux-mm/msg72236.html 1 file changed, 4 insertions(+) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 3e5d907..2539068 100644 +index 73fae8c..5dd1278 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h -@@ -219,7 +219,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -220,7 +220,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) { atomic_long_dec(&zone->vm_stat[item]); @@ -89,16 +132,43 @@ index 3e5d907..2539068 100644 static inline void __inc_zone_page_state(struct page *page, -From 5956e14120ab88b53fe2f68f7de6c197eae4a811 Mon Sep 17 00:00:00 2001 +From 39ff92a84c78a9a9732ac7f72de3691a1462060d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 18 Dec 2014 16:07:15 -0800 +Subject: [PATCH 005/114] mm: Remove the PFN busy warning + +See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is +expected sometimes when using CMA. However, that commit still spams +my kernel log with these warnings. + +Signed-off-by: Eric Anholt +--- + mm/page_alloc.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 59de90d..a7b5691 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -7101,8 +7101,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, + + /* Make sure the range is really isolated. */ + if (test_pages_isolated(outer_start, end, false)) { +- pr_info("%s: [%lx, %lx) PFNs busy\n", +- __func__, outer_start, end); + ret = -EBUSY; + goto done; + } + +From c9a338a0415713d87a65f1df36e158c496f88fd1 Mon Sep 17 00:00:00 2001 From: Robert Tiemann Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 004/251] BCM2835_DT: Fix I2S register map +Subject: [PATCH 006/114] BCM2835_DT: Fix I2S register map --- Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- - 3 files changed, 6 insertions(+), 6 deletions(-) + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt index 1396078..2db8294 100644 @@ -130,26 +200,11 @@ index 65783de..a89fe42 100644 dmas = <&dma 2>, <&dma 3>; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index aef64de..864a3ef 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -120,8 +120,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -From bd8d0148b99e3281aaa294257961377c93a9381d Mon Sep 17 00:00:00 2001 +From aca2671953e17069ad8f56e130163101381fc736 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 4 Dec 2015 17:41:50 +0000 -Subject: [PATCH 005/251] irq-bcm2836: Prevent spurious interrupts, and trap +Subject: [PATCH 007/114] irq-bcm2836: Prevent spurious interrupts, and trap them early The old arch-specific IRQ macros included a dsb to ensure the @@ -160,30 +215,26 @@ precaution to avoid spurious interrupts. Spurious interrupts are still possible for other reasons, though, so trap them early. --- - drivers/irqchip/irq-bcm2836.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + drivers/irqchip/irq-bcm2836.c | 1 + + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c -index f687082..4cd8ebe 100644 +index b6e950d..bbb92c2 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c -@@ -170,9 +170,10 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) +@@ -175,6 +175,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) u32 ipi = ffs(mbox_val) - 1; writel(1 << ipi, mailbox0); + dsb(); handle_IPI(ipi, regs); #endif -- } else { -+ } else if (stat) { - u32 hwirq = ffs(stat) - 1; - - handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); + } else if (stat) { -From 2311742728ef10f5d7ed17debc4065e90cb25c7e Mon Sep 17 00:00:00 2001 +From d1d05c91acf24e5222af4522c7c2c9d615ab68cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 12 Jun 2015 19:01:05 +0200 -Subject: [PATCH 006/251] irqchip: bcm2835: Add FIQ support +Subject: [PATCH 008/114] irqchip: bcm2835: Add FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -201,12 +252,12 @@ Acked-by: Stephen Warren 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig -index 8c53c55..c943747 100644 +index 7ef1214..b1a5a7b 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig -@@ -128,6 +128,7 @@ config ARCH_BCM2835 - select ARM_ERRATA_411920 +@@ -143,6 +143,7 @@ config ARCH_BCM2835 select ARM_TIMER_SP804 + select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select CLKSRC_OF + select FIQ select PINCTRL @@ -312,10 +363,10 @@ index bf9cc5f..3f601f9 100644 } -From 60f12c460c71c04609a23be23df6eb986481c365 Mon Sep 17 00:00:00 2001 +From bdf258bc4df61515e3de2a4caa597ccc96b519ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 23 Oct 2015 16:26:55 +0200 -Subject: [PATCH 007/251] irqchip: irq-bcm2835: Add 2836 FIQ support +Subject: [PATCH 009/114] irqchip: irq-bcm2835: Add 2836 FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -411,17 +462,41 @@ index 3f601f9..20deb28 100644 for (b = 0; b < NR_BANKS; b++) { for (i = 0; i < bank_irqs[b]; i++) { -From 8de2ecc5c42ae0a909fbc23da58ef2fa552d4c5b Mon Sep 17 00:00:00 2001 +From e623ec6ba4ad40fa1863a573ec86e71c3efa1955 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 14 Jul 2015 10:26:09 +0100 +Subject: [PATCH 010/114] spidev: Add "spidev" compatible string to silence + warning + +See: https://github.com/raspberrypi/linux/issues/1054 +--- + drivers/spi/spidev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index e3c19f3..f4963e3 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -695,6 +695,7 @@ static struct class *spidev_class; + static const struct of_device_id spidev_dt_ids[] = { + { .compatible = "rohm,dh2228fv" }, + { .compatible = "lineartechnology,ltc2488" }, ++ { .compatible = "spidev" }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); + +From 27fe80aa5b09a161ff66c1d6e5588a41e7d19225 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 008/251] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 011/114] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index 3912646..b51a59c 100644 +index 2f4f5ee..edc1355 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -509,6 +509,8 @@ static void __init serial8250_isa_init_ports(void) @@ -434,10 +509,10 @@ index 3912646..b51a59c 100644 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From 2567dee80cdc0654788137d07308fa428d3dc8fb Mon Sep 17 00:00:00 2001 +From 46789d89b66ad2a8bb68da0ddeb16665dffe5f5a Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 009/251] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 012/114] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -446,7 +521,7 @@ Signed-off-by: Noralf Tronnes 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 17dd8fe..613be28 100644 +index 08b1d93..0a23c81 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -373,7 +373,7 @@ static struct gpio_chip bcm2835_gpio_chip = { @@ -459,10 +534,10 @@ index 17dd8fe..613be28 100644 .can_sleep = false, }; -From f23532983c575cac8b55c4bceb1e45a1439f7e0e Mon Sep 17 00:00:00 2001 +From bcb2842b04e0e339a863fd5cc5f760d1c84e10ca Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 010/251] pinctrl-bcm2835: Fix interrupt handling for GPIOs +Subject: [PATCH 013/114] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has @@ -483,7 +558,7 @@ the pins are often used for I2S instead. 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 613be28..a06cf9e 100644 +index 0a23c81..b793bbd 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ @@ -608,10 +683,10 @@ index 613be28..a06cf9e 100644 }, }; -From fe30b946aef6315884bd029f889f6eb3692705e5 Mon Sep 17 00:00:00 2001 +From 4bcd8fc5cde916b2bd2807045d65cdcf9372ef53 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 011/251] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 014/114] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -625,7 +700,7 @@ interface, is unlikely to be a problem. 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index a06cf9e..32f779e 100644 +index b793bbd..8683a1b 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -1029,6 +1029,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) @@ -638,10 +713,10 @@ index a06cf9e..32f779e 100644 pc->irq_data[i].irqgroup = i; -From cc544ca7cb8b033c7bf3d884277f32887a1417a7 Mon Sep 17 00:00:00 2001 +From 6ccfd268fe86872db44f61ba61d4dbac59c57186 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 012/251] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 015/114] spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the @@ -658,7 +733,7 @@ Signed-off-by: Phil Elwell 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index cf04960..a2b1f45 100644 +index f35cc10..5dfe20f 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -688,6 +688,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) @@ -722,10 +797,10 @@ index cf04960..a2b1f45 100644 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From 8cf07dd13a251b72f28805060d58b942b582feef Mon Sep 17 00:00:00 2001 +From 91bab1f8dcc81e282512c8f808b8d9ca2f7975b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 013/251] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 016/114] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -750,7 +825,7 @@ Signed-off-by: Noralf Trønnes 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 0f7b9ea..1e6f1cf 100644 +index 834d676..3b68a8d 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -17,12 +17,16 @@ @@ -783,78 +858,10 @@ index 0f7b9ea..1e6f1cf 100644 static const char * const bcm2835_compat[] = { -From 902ceaaea891e7883c141d45e52dde7d859e2324 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 16:44:05 +0200 -Subject: [PATCH 014/251] bcm2835-i2s: get base address for DMA from devicetree - -Code copied from spi-bcm2835. Get physical address from devicetree -instead of using hardcoded constant. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 8c435be..0bc4f47 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -158,10 +159,6 @@ static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { - #define BCM2835_I2S_INT_RXR BIT(1) - #define BCM2835_I2S_INT_TXW BIT(0) - --/* I2S DMA interface */ --/* FIXME: Needs IOMMU support */ --#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) -- - /* General device struct */ - struct bcm2835_i2s_dev { - struct device *dev; -@@ -791,6 +788,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - int ret; - struct regmap *regmap[2]; - struct resource *mem[2]; -+ const __be32 *addr; -+ dma_addr_t dma_reg_base; -+ -+ addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); -+ if (!addr) { -+ dev_err(&pdev->dev, "could not get DMA-register address\n"); -+ return -ENODEV; -+ } -+ dma_reg_base = be32_to_cpup(addr); - - /* Request both ioareas */ - for (i = 0; i <= 1; i++) { -@@ -817,12 +823,10 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - - /* Set the DMA address */ - dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = -- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG -- + BCM2835_VCMMU_SHIFT; -+ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - - dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = -- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG -- + BCM2835_VCMMU_SHIFT; -+ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - - /* Set the bus width */ - dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = - -From c89c8dc0cde738e6d2a5d07dbfd2aaa72f4a07d0 Mon Sep 17 00:00:00 2001 +From 9b4fc474912bed145c59cc8dcb76a48006cb46ea Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:21:16 +0200 -Subject: [PATCH 015/251] bcm2835-i2s: add 24bit support, update bclk_ratio to +Subject: [PATCH 017/114] bcm2835-i2s: add 24bit support, update bclk_ratio to more correct values Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -882,32 +889,24 @@ https://github.com/raspberrypi/linux/issues/681 Signed-off-by: Matthias Reichl --- - sound/soc/bcm/bcm2835-i2s.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) + sound/soc/bcm/bcm2835-i2s.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 0bc4f47..cf60390 100644 +index 1c1f221..d2663e7 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -340,11 +340,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - switch (params_format(params)) { +@@ -259,6 +259,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S16_LE: data_length = 16; -- bclk_ratio = 40; -+ bclk_ratio = 50; -+ break; + break; + case SNDRV_PCM_FORMAT_S24_LE: + data_length = 24; -+ bclk_ratio = 50; - break; ++ break; case SNDRV_PCM_FORMAT_S32_LE: data_length = 32; -- bclk_ratio = 80; -+ bclk_ratio = 100; break; - default: - return -EINVAL; -@@ -420,7 +424,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, +@@ -279,7 +282,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* Setup the frame format */ format = BCM2835_I2S_CHEN; @@ -916,7 +915,7 @@ index 0bc4f47..cf60390 100644 format |= BCM2835_I2S_CHWEX; format |= BCM2835_I2S_CHWID((data_length-8)&0xf); -@@ -711,6 +715,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { +@@ -570,6 +573,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE @@ -924,7 +923,7 @@ index 0bc4f47..cf60390 100644 | SNDRV_PCM_FMTBIT_S32_LE }, .capture = { -@@ -718,6 +723,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { +@@ -577,6 +581,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE @@ -933,107 +932,10 @@ index 0bc4f47..cf60390 100644 }, .ops = &bcm2835_i2s_dai_ops, -From da23963f1f4c8999ec76bb99234aec3864b0e56f Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 15:25:51 +0200 -Subject: [PATCH 016/251] bcm2835-i2s: setup clock only if CPU is clock master - -Code ported from bcm2708-i2s driver in Raspberry Pi tree. - -RPi commit c14827ecdaa36607f6110f9ce8df96e698672191 ("bcm2708: Allow -option card devices to be configured via DT") - -Original work by Zoltan Szenczi, committed to RPi tree by -Phil Elwell. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 28 +++++++++++++++++++--------- - 1 file changed, 19 insertions(+), 9 deletions(-) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index cf60390..4ac4e92 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -411,15 +411,25 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - divf = dividend & BCM2835_CLK_DIVF_MASK; - } - -- /* Set clock divider */ -- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD -- | BCM2835_CLK_DIVI(divi) -- | BCM2835_CLK_DIVF(divf)); -- -- /* Setup clock, but don't start it yet */ -- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD -- | BCM2835_CLK_MASH(mash) -- | BCM2835_CLK_SRC(clk_src)); -+ /* Clock should only be set up here if CPU is clock master */ -+ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ case SND_SOC_DAIFMT_CBS_CFM: -+ /* Set clock divider */ -+ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, -+ BCM2835_CLK_PASSWD -+ | BCM2835_CLK_DIVI(divi) -+ | BCM2835_CLK_DIVF(divf)); -+ -+ /* Setup clock, but don't start it yet */ -+ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, -+ BCM2835_CLK_PASSWD -+ | BCM2835_CLK_MASH(mash) -+ | BCM2835_CLK_SRC(clk_src)); -+ break; -+ default: -+ break; -+ } - - /* Setup the frame format */ - format = BCM2835_I2S_CHEN; - -From 611d61511eefc080a178187b36c9d86aec9bb8b0 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 15:49:51 +0200 -Subject: [PATCH 017/251] bcm2835-i2s: Eliminate debugfs directory error - -Code ported from bcm2708-i2s driver in Raspberry Pi tree. - -RPi commit fd7d7a3dbe9262d16971ef81c234ed28c6499dd7 ("bcm2708: -Eliminate i2s debugfs directory error") - -Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') -to avoid the name clash when registering debugfs entries. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 4ac4e92..aab3df9 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -782,6 +782,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { - .precious_reg = bcm2835_i2s_precious_reg, - .volatile_reg = bcm2835_i2s_volatile_reg, - .cache_type = REGCACHE_RBTREE, -+ .name = "i2s", - }, - { - .reg_bits = 32, -@@ -790,6 +791,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { - .max_register = BCM2835_CLK_PCMDIV_REG, - .volatile_reg = bcm2835_clk_volatile_reg, - .cache_type = REGCACHE_RBTREE, -+ .name = "clk", - }, - }; - - -From bb6885bf7549495ca00d9a839954dcd35c4b9e61 Mon Sep 17 00:00:00 2001 +From ad1d838172d12324cf8029f18a445ed35d895a6a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:35:20 +0200 -Subject: [PATCH 018/251] bcm2835-i2s: Register PCM device +Subject: [PATCH 018/114] bcm2835-i2s: Register PCM device Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -1055,10 +957,10 @@ Signed-off-by: Matthias Reichl 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index aab3df9..0e5c787 100644 +index d2663e7..3a8468d 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -799,6 +799,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { +@@ -625,6 +625,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { .name = "bcm2835-i2s-comp", }; @@ -1084,7 +986,7 @@ index aab3df9..0e5c787 100644 static int bcm2835_i2s_probe(struct platform_device *pdev) { struct bcm2835_i2s_dev *dev; -@@ -870,7 +889,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) +@@ -697,7 +716,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) return ret; } @@ -1096,10 +998,10 @@ index aab3df9..0e5c787 100644 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); return ret; -From 7eced106f678f81b479e3f4fcc0de5b0c8e1dbd9 Mon Sep 17 00:00:00 2001 +From 724a0c2c6cac52d4ea41db9d5c45fea6e1a3d34d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:55:21 +0200 -Subject: [PATCH 019/251] bcm2835-i2s: Enable MMAP support via a DT property +Subject: [PATCH 019/114] bcm2835-i2s: Enable MMAP support via a DT property Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -1118,10 +1020,10 @@ Signed-off-by: Matthias Reichl 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 0e5c787..04c1d13 100644 +index 3a8468d..c7f3fc7 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -799,7 +799,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { +@@ -625,7 +625,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { .name = "bcm2835-i2s-comp", }; @@ -1130,23 +1032,23 @@ index 0e5c787..04c1d13 100644 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX, .formats = SNDRV_PCM_FMTBIT_S16_LE | -@@ -835,6 +835,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - } - dma_reg_base = be32_to_cpup(addr); +@@ -653,6 +653,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + const __be32 *addr; + dma_addr_t dma_base; + if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) + bcm2835_pcm_hardware.info |= + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID; + - /* Request both ioareas */ - for (i = 0; i <= 1; i++) { - void __iomem *base; + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), + GFP_KERNEL); + if (!dev) -From 6de25eb4521167e2d9d5a9c777333cec1542192f Mon Sep 17 00:00:00 2001 +From 3c8b0d34e47e2b73f9f67ee92013abf7c873cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Thu, 9 Apr 2015 12:34:11 +0200 -Subject: [PATCH 020/251] dmaengine: bcm2835: Add slave dma support +Subject: [PATCH 020/114] dmaengine: bcm2835: Add slave dma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1466,10 +1368,10 @@ index 996c4b0..b278c66 100644 +MODULE_AUTHOR("Gellert Weisz "); MODULE_LICENSE("GPL v2"); -From 6090e63c27886fcd841ba451d8646c093a179b8d Mon Sep 17 00:00:00 2001 +From 21af238b62b6bf7ee2091692c8d88689299743b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 3 Oct 2015 15:58:59 +0200 -Subject: [PATCH 021/251] dmaengine: bcm2835: set residue_granularity field +Subject: [PATCH 021/114] dmaengine: bcm2835: set residue_granularity field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1498,10 +1400,10 @@ index b278c66..696fb30 100644 INIT_LIST_HEAD(&od->ddev.channels); spin_lock_init(&od->lock); -From ea0d9861bde9e049f8d5e43ae89dcf7844cb5e8d Mon Sep 17 00:00:00 2001 +From 7f42da09fd073abe725120c913ee14a5e9651f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 3 Oct 2015 22:22:55 +0200 -Subject: [PATCH 022/251] dmaengine: bcm2835: Load driver early and support +Subject: [PATCH 022/114] dmaengine: bcm2835: Load driver early and support legacy API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -1519,7 +1421,7 @@ Signed-off-by: Noralf Trønnes 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index e6cd1a3..060306e 100644 +index d96d87c..4d0425c 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -108,7 +108,7 @@ config COH901318 @@ -1601,10 +1503,10 @@ index 696fb30..5db0a95 100644 MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); -From 8947371bab57f6f0adb8c9519ceeba017fa5fc6a Mon Sep 17 00:00:00 2001 +From f5754ddf7a7c2406cc893b2bd890f0f91b321ae5 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 10 Oct 2015 12:29:18 +0200 -Subject: [PATCH 023/251] bcm2835-dma: Fix dreq not set for slave transfers +Subject: [PATCH 023/114] bcm2835-dma: Fix dreq not set for slave transfers Set dreq to slave_id if it is not set like in bcm2708-dmaengine. --- @@ -1625,10 +1527,10 @@ index 5db0a95..fe1fd60 100644 return 0; } -From 22399cbc5ece0905650012b73e51a366d1c754e6 Mon Sep 17 00:00:00 2001 +From 994a4cb73ee2a4f781959989cfeb9e90fddc508a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 12:28:30 +0200 -Subject: [PATCH 024/251] bcm2835-dma: Limit cyclic transfers on lite channels +Subject: [PATCH 024/114] bcm2835-dma: Limit cyclic transfers on lite channels to 32k Transfers larger than 32k cause repeated clicking with I2S soundcards. @@ -1665,10 +1567,98 @@ index fe1fd60..0adc347 100644 max_size = MAX_NORMAL_TRANSFER; period_len = min(period_len, max_size); -From 1e8033be36dd0c3b000c014245cc45f94118faa0 Mon Sep 17 00:00:00 2001 +From ea1c91a95f363d023dc256319c80a7e75e94ef74 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 16 Nov 2015 14:05:35 +0000 +Subject: [PATCH 025/114] bcm2835-dma: Fix up convert to DMA pool + +--- + drivers/dma/bcm2835-dma.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c +index 0adc347..985019b 100644 +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -488,6 +488,17 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( + c->cyclic = true; + + return vchan_tx_prep(&c->vc, &d->vd, flags); ++error_cb: ++ i--; ++ for (; i >= 0; i--) { ++ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; ++ ++ dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr); ++ } ++ ++ kfree(d->cb_list); ++ kfree(d); ++ return NULL; + } + + static struct dma_async_tx_descriptor * +@@ -534,6 +545,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + if (!d) + return NULL; + ++ d->c = c; + d->dir = direction; + + if (c->ch >= 8) /* LITE channel */ +@@ -553,15 +565,21 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + d->frames += len / max_size + 1; + } + +- /* Allocate memory for control blocks */ +- d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); +- d->control_block_base = dma_zalloc_coherent(chan->device->dev, +- d->control_block_size, &d->control_block_base_phys, +- GFP_NOWAIT); +- if (!d->control_block_base) { ++ d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL); ++ if (!d->cb_list) { + kfree(d); + return NULL; + } ++ /* Allocate memory for control blocks */ ++ for (i = 0; i < d->frames; i++) { ++ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; ++ ++ cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC, ++ &cb_entry->paddr); ++ ++ if (!cb_entry->cb) ++ goto error_cb; ++ } + + /* + * Iterate over all SG entries, create a control block +@@ -578,7 +596,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + + for (j = 0; j < len; j += max_size) { + struct bcm2835_dma_cb *control_block = +- &d->control_block_base[i + split_cnt]; ++ d->cb_list[i + split_cnt].cb; + + /* Setup addresses */ + if (d->dir == DMA_DEV_TO_MEM) { +@@ -620,9 +638,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + if (i < sg_len - 1 || len - j > max_size) { + /* Next block is the next frame. */ + control_block->next = +- d->control_block_base_phys + +- sizeof(struct bcm2835_dma_cb) * +- (i + split_cnt + 1); ++ d->cb_list[i + split_cnt + 1].paddr; + } else { + /* Next block is empty. */ + control_block->next = 0; + +From 0060f36936def46e53a173f34d0b2ab8862be1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 15 Aug 2015 20:50:02 +0200 -Subject: [PATCH 025/251] bcm2835: Add support for uart1 +Subject: [PATCH 026/114] bcm2835: Add support for uart1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1682,7 +1672,7 @@ Signed-off-by: Noralf Trønnes 1 file changed, 25 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 1e6f1cf..ea36eec 100644 +index 3b68a8d..e72e522 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -22,6 +22,29 @@ @@ -1725,21 +1715,17 @@ index 1e6f1cf..ea36eec 100644 static const char * const bcm2835_compat[] = { -From d97842cc1aac3d0ff132500fad402068743d08df Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:21:20 +0200 -Subject: [PATCH 026/251] firmware: bcm2835: Add missing property tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 139492dfc48f7e8ff2a26902178ef76ae790c7e3 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 25 Jan 2016 17:25:12 +0000 +Subject: [PATCH 027/114] firmware: Updated mailbox header -Signed-off-by: Noralf Trønnes --- - include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ - 1 file changed, 8 insertions(+) + include/soc/bcm2835/raspberrypi-firmware.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index c07d74a..525816d 100644 +index 3fb3571..73e4956 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -63,6 +63,7 @@ enum rpi_firmware_property_tag { @@ -1750,28 +1736,30 @@ index c07d74a..525816d 100644 RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -@@ -72,10 +73,12 @@ enum rpi_firmware_property_tag { +@@ -72,11 +73,13 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, + RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, + RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -@@ -89,6 +92,7 @@ enum rpi_firmware_property_tag { +@@ -91,6 +94,8 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -@@ -98,6 +102,7 @@ enum rpi_firmware_property_tag { +@@ -100,6 +105,7 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, @@ -1779,21 +1767,22 @@ index c07d74a..525816d 100644 RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -@@ -106,6 +111,9 @@ enum rpi_firmware_property_tag { +@@ -108,6 +114,10 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, + + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, -From f01f5606b8fe5e7ea7d70f4f2e0e7435040cabaa Mon Sep 17 00:00:00 2001 +From 43e70c9b87a98c3a6c2f6ca82e1b1ea4eeffca78 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 027/251] Main bcm2708/bcm2709 linux port +Subject: [PATCH 028/114] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1831,14 +1820,13 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 ++ arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 ++ arch/arm/mach-bcm2709/vc_mem.c | 431 +++++++++++++++++++++++ - arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-v6.S | 15 +- - arch/arm/mm/proc-v7.S | 1 + arch/arm/tools/mach-types | 2 + drivers/clocksource/Makefile | 2 +- drivers/irqchip/Makefile | 3 + + drivers/irqchip/irq-bcm2835.c | 3 +- include/linux/mmc/host.h | 1 + - 37 files changed, 2147 insertions(+), 5 deletions(-) + 36 files changed, 2147 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -1866,11 +1854,11 @@ Signed-off-by: Noralf Trønnes create mode 100644 arch/arm/mach-bcm2709/vc_mem.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 34e1569..8f06ea8 100644 +index cdfa6c2..aad7157 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -317,6 +317,52 @@ choice - default ARCH_VERSATILE if !MMU +@@ -322,6 +322,52 @@ choice + default ARM_SINGLE_ARMV7M if !MMU default ARCH_MULTIPLATFORM if MMU +config ARCH_BCM2708 @@ -1922,7 +1910,7 @@ index 34e1569..8f06ea8 100644 config ARCH_MULTIPLATFORM bool "Allow multiple platforms to be selected" depends on MMU -@@ -808,6 +854,9 @@ config ARCH_VIRT +@@ -721,6 +767,9 @@ config ARCH_VIRT # Kconfigs may be included either alphabetically (according to the # plat- suffix) or along side the corresponding mach-* source. # @@ -1933,10 +1921,10 @@ index 34e1569..8f06ea8 100644 source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index ddbb361..340b759 100644 +index 1098e91..e119675 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1240,6 +1240,14 @@ choice +@@ -1302,6 +1302,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -1952,18 +1940,18 @@ index ddbb361..340b759 100644 config DEBUG_EXYNOS_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 2c2b28e..a2e7cf7 100644 +index 8c3ce2a..c4d7d10 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -154,6 +154,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -153,6 +153,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_BCM2708) += bcm2708 +machine-$(CONFIG_ARCH_BCM2709) += bcm2709 machine-$(CONFIG_ARCH_ALPINE) += alpine + machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 - machine-$(CONFIG_ARCH_AXXIA) += axxia diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04286fd..ed82628 100644 --- a/arch/arm/kernel/head.S @@ -4203,19 +4191,6 @@ index 0000000..d2adfd1 +module_param(phys_addr, uint, 0644); +module_param(mem_size, uint, 0644); +module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 4121886..253bed8 100644 ---- a/arch/arm/mm/Kconfig -+++ b/arch/arm/mm/Kconfig -@@ -358,7 +358,7 @@ config CPU_PJ4B - - # ARMv6 - config CPU_V6 -- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) -+ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) - select CPU_32v6 - select CPU_ABRT_EV6 - select CPU_CACHE_V6 diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 06d890a..30d96e8 100644 --- a/arch/arm/mm/proc-v6.S @@ -4243,18 +4218,6 @@ index 06d890a..30d96e8 100644 ret lr ENTRY(cpu_v6_dcache_clean_area) -diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 8e1ea43..be40ccb 100644 ---- a/arch/arm/mm/proc-v7.S -+++ b/arch/arm/mm/proc-v7.S -@@ -480,6 +480,7 @@ __errata_finish: - orr r0, r0, r6 @ set them - THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions - ret lr @ return to head.S:__ret -+ .space 256 - ENDPROC(__v7_setup) - - .align 2 diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 2ed1b8a..b52d949 100644 --- a/arch/arm/tools/mach-types @@ -4269,7 +4232,7 @@ index 2ed1b8a..b52d949 100644 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile -index 56bd16e..c2ac46d 100644 +index dc2b899..c38fb1a 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -19,7 +19,7 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o @@ -4282,11 +4245,11 @@ index 56bd16e..c2ac46d 100644 obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile -index 177f78f..6a9e2d0 100644 +index b03cfcb..70cad6b 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile -@@ -2,6 +2,9 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o - +@@ -5,6 +5,9 @@ obj-$(CONFIG_ATH79) += irq-ath79-cpu.o + obj-$(CONFIG_ATH79) += irq-ath79-misc.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o +obj-$(CONFIG_ARCH_BCM2708) += irq-bcm2835.o @@ -4295,37 +4258,59 @@ index 177f78f..6a9e2d0 100644 obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index 20deb28..c02bf8a 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -82,6 +82,7 @@ + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 + #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#undef FIQ_START + #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) + + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; +@@ -256,7 +257,7 @@ static int __init armctrl_of_init(struct device_node *node, + MAKE_HWIRQ(b, i) + NUMBER_IRQS); + BUG_ON(irq <= 0); + irq_set_chip(irq, &armctrl_chip); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + } + init_FIQ(FIQ_START); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index 8673ffe..ad22ebb 100644 +index 8dd4d29..f7fe8bd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -289,6 +289,7 @@ struct mmc_host { - #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) +@@ -291,6 +291,7 @@ struct mmc_host { #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ + #define MMC_CAP2_NO_SDIO (1 << 19) /* Do not send SDIO commands during initialization */ +#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ mmc_pm_flag_t pm_caps; /* supported pm features */ -From cc5bcfaa350113324f7433660c9a3dfc0229bcdd Mon Sep 17 00:00:00 2001 +From 49892df19a70edbe8a089d8c7048c9234f30d9d3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 11 Nov 2015 21:01:15 +0000 -Subject: [PATCH 028/251] squash: include ARCH_BCM2708 / ARCH_BCM2709 +Subject: [PATCH 029/114] squash: include ARCH_BCM2708 / ARCH_BCM2709 --- drivers/char/hw_random/Kconfig | 2 +- + drivers/clk/bcm/Makefile | 4 ++-- drivers/mailbox/Kconfig | 2 +- drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- drivers/pinctrl/Makefile | 1 + drivers/pwm/Kconfig | 2 +- - drivers/spi/Kconfig | 2 +- + drivers/spi/Kconfig | 4 ++-- drivers/watchdog/Kconfig | 2 +- sound/soc/bcm/Kconfig | 2 +- - 8 files changed, 23 insertions(+), 8 deletions(-) + 9 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index dbf2271..e11e3f2 100644 +index 67ee8b0..b3ca2ee 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX @@ -4337,11 +4322,26 @@ index dbf2271..e11e3f2 100644 default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number +diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile +index 1d79bd2..fcf1bb5 100644 +--- a/drivers/clk/bcm/Makefile ++++ b/drivers/clk/bcm/Makefile +@@ -4,8 +4,8 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o + obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o +-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o +-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835-aux.o + obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o + obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o + obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 546d05f..5a045c9 100644 +index 5305923..3de0dcb 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig -@@ -65,7 +65,7 @@ config ALTERA_MBOX +@@ -74,7 +74,7 @@ config ALTERA_MBOX config BCM2835_MBOX tristate "BCM2835 Mailbox" @@ -4400,19 +4400,19 @@ index cfb4b44..d9c6c21 100644 MODULE_AUTHOR("Lubomir Rintel "); MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 738cb49..4fd086f 100644 +index e4bc115..d996fe7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o +@@ -35,6 +35,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o +obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += bcm/ obj-$(CONFIG_ARCH_BCM) += bcm/ - obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ obj-y += freescale/ diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig -index 2f4641a..d5c1a5d 100644 +index c182efc..fe0f845 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -85,7 +85,7 @@ config PWM_BCM_KONA @@ -4425,23 +4425,32 @@ index 2f4641a..d5c1a5d 100644 PWM framework driver for BCM2835 controller (Raspberry Pi) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 8b9c2a3..e842e86 100644 +index 9d8c84b..2a27a37 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -78,7 +78,7 @@ config SPI_ATMEL +@@ -94,7 +94,7 @@ config SPI_AXI_SPI_ENGINE config SPI_BCM2835 tristate "BCM2835 SPI controller" depends on GPIOLIB - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on GPIOLIB help This selects a driver for the Broadcom BCM2835 SPI master. + +@@ -105,7 +105,7 @@ config SPI_BCM2835 + + config SPI_BCM2835AUX + tristate "BCM2835 SPI auxiliary controller" +- depends on (ARCH_BCM2835 && GPIOLIB) || COMPILE_TEST ++ depends on ((ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709) && GPIOLIB) || COMPILE_TEST + help + This selects a driver for the Broadcom BCM2835 SPI aux master. + diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 1c427be..3c03d17 100644 +index fb94765..8b2de7f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -1282,7 +1282,7 @@ config BCM63XX_WDT +@@ -1401,7 +1401,7 @@ config BCM63XX_WDT config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" @@ -4463,10 +4472,10 @@ index 6a834e1..c5070ae 100644 select REGMAP_MMIO help -From d23b18d79e915fa0a5820230ee7a35d682e7af42 Mon Sep 17 00:00:00 2001 +From e169f708f57c5898a4d4303dd6530b3af53b5866 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 029/251] Add dwc_otg driver +Subject: [PATCH 030/114] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -4929,6 +4938,35 @@ Also add error checking on the returned irq number. Signed-off-by: Noralf Trønnes dwc_otg: Remove duplicate gadget probe/unregister function + +dwc_otg: Properly set the HFIR + +Douglas Anderson reported: + +According to the most up to date version of the dwc2 databook, the FRINT +field of the HFIR register should be programmed to: +* 125 us * (PHY clock freq for HS) - 1 +* 1000 us * (PHY clock freq for FS/LS) - 1 + +This is opposed to older versions of the doc that claimed it should be: +* 125 us * (PHY clock freq for HS) +* 1000 us * (PHY clock freq for FS/LS) + +and reported lower timing jitter on a USB analyser + +dcw_otg: trim xfer length when buffer larger than allocated size is received + +dwc_otg: Don't free qh align buffers in atomic context + +dwc_otg: Enable the hack for Split Interrupt transactions by default + +dwc_otg.fiq_fsm_mask=0xF has long been a suggestion for users with audio stutters or other USB bandwidth issues. +So far we are aware of many success stories but no failure caused by this setting. +Make it a default to learn more. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=70437 + +Signed-off-by: popcornmix --- arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + @@ -4986,9 +5024,9 @@ dwc_otg: Remove duplicate gadget probe/unregister function drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 862 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2714 ++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2727 ++++++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 1005 +++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 962 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 266 + @@ -5000,7 +5038,7 @@ dwc_otg: Remove duplicate gadget probe/unregister function drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 70 files changed, 59867 insertions(+), 16 deletions(-) + 70 files changed, 59885 insertions(+), 16 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -5107,7 +5145,7 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile -index d5c57f1..0e15a22 100644 +index dca7856..5c467de 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -7,6 +7,7 @@ @@ -5131,10 +5169,10 @@ index 358ca8d..abaac7c 100644 return i; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 2a27488..ae4dca1 100644 +index 38cc4ba..61b8bb5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4973,7 +4973,7 @@ static void port_event(struct usb_hub *hub, int port1) +@@ -5044,7 +5044,7 @@ static void port_event(struct usb_hub *hub, int port1) if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; @@ -9073,10 +9111,10 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 3bb0887..0905a86 100644 +index 3050b18..bbb5f3e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig -@@ -735,6 +735,19 @@ config USB_HWA_HCD +@@ -752,6 +752,19 @@ config USB_HWA_HCD To compile this driver a module, choose M here: the module will be called "hwa-hc". @@ -9097,18 +9135,18 @@ index 3bb0887..0905a86 100644 tristate "i.MX21 HCD support" depends on ARM && ARCH_MXC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index e7558ab..0bb50e6 100644 +index a9ddd3c..11d7761 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile -@@ -69,6 +69,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o +@@ -73,6 +73,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o + +obj-$(CONFIG_USB_DWCOTG) += dwc_otg/ dwc_common_port/ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o - obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o - obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o + obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o + obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile new file mode 100644 index 0000000..f10d466 @@ -26083,7 +26121,7 @@ index 0000000..55fd337 +#endif /* (__DWC_OTG_CFI_H__) */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c new file mode 100644 -index 0000000..beaa8b3 +index 0000000..38abd0b --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c @@ -0,0 +1,7141 @@ @@ -29247,10 +29285,10 @@ index 0000000..beaa8b3 + clock = 48; + if (hprt0.b.prtspd == 0) + /* High speed case */ -+ return 125 * clock; ++ return 125 * clock - 1; + else + /* FS/LS case */ -+ return 1000 * clock; ++ return 1000 * clock - 1; +} + +/** @@ -37134,7 +37172,7 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..95edadf +index 0000000..cb060a7 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c @@ -0,0 +1,1757 @@ @@ -37387,7 +37425,7 @@ index 0000000..95edadf +//Bulk split-transaction NAK holdoff in microframes +uint16_t nak_holdoff = 8; + -+unsigned short fiq_fsm_mask = 0x07; ++unsigned short fiq_fsm_mask = 0x0F; + +/** + * This function shows the Driver Version. @@ -47504,10 +47542,10 @@ index 0000000..fb57db0 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c new file mode 100644 -index 0000000..8db3dfc +index 0000000..e6b38ac --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -0,0 +1,2714 @@ +@@ -0,0 +1,2727 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $ + * $Revision: #89 $ @@ -48247,6 +48285,12 @@ index 0000000..8db3dfc + DWC_OTG_HC_XFER_COMPLETE, + &short_read); + ++ if (urb->actual_length + xfer_length > urb->length) { ++ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", ++ hc->dev_addr, __func__, __LINE__); ++ xfer_length = urb->length - urb->actual_length; ++ } ++ + /* non DWORD-aligned buffer case handling. */ + if (hc->align_buff && xfer_length && hc->ep_is_in) { + dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, @@ -48933,6 +48977,13 @@ index 0000000..8db3dfc +{ + uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, + halt_status, NULL); ++ ++ if (urb->actual_length + bytes_transferred > urb->length) { ++ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", ++ hc->dev_addr, __func__, __LINE__); ++ bytes_transferred = urb->length - urb->actual_length; ++ } ++ + /* non DWORD-aligned buffer case handling. */ + if (hc->align_buff && bytes_transferred && hc->ep_is_in) { + dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, @@ -51235,10 +51286,10 @@ index 0000000..2ceed42 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c new file mode 100644 -index 0000000..acd0dd7 +index 0000000..3b2a607 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -0,0 +1,957 @@ +@@ -0,0 +1,962 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $ + * $Revision: #44 $ @@ -51297,6 +51348,9 @@ index 0000000..acd0dd7 +{ + dwc_otg_qtd_t *qtd, *qtd_tmp; + dwc_irqflags_t flags; ++ uint32_t buf_size = 0; ++ uint8_t *align_buf_virt = NULL; ++ dwc_dma_t align_buf_dma; + + /* Free each QTD in the QTD list */ + DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); @@ -51308,17 +51362,19 @@ index 0000000..acd0dd7 + if (hcd->core_if->dma_desc_enable) { + dwc_otg_hcd_qh_free_ddma(hcd, qh); + } else if (qh->dw_align_buf) { -+ uint32_t buf_size; + if (qh->ep_type == UE_ISOCHRONOUS) { + buf_size = 4096; + } else { + buf_size = hcd->core_if->core_params->max_transfer_size; + } -+ DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma); ++ align_buf_virt = qh->dw_align_buf; ++ align_buf_dma = qh->dw_align_buf_dma; + } + + DWC_FREE(qh); + DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ if (align_buf_virt) ++ DWC_DMA_FREE(buf_size, align_buf_virt, align_buf_dma); + return; +} + @@ -65445,10 +65501,10 @@ index 0000000..cdc9963 +test_main(); +0; -From 09d89e5bb8c9adc39556accbf5bb118e1609fb80 Mon Sep 17 00:00:00 2001 +From ab5ddf2c310bafc8375a88ba494d5eba214abd7e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 030/251] bcm2708 framebuffer driver +Subject: [PATCH 031/114] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -65530,10 +65586,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 drivers/video/fbdev/bcm2708_fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index e6d16d6..0f33a78 100644 +index 983280e..ee72c3a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -224,6 +224,20 @@ config FB_TILEBLITTING +@@ -228,6 +228,20 @@ config FB_TILEBLITTING comment "Frame buffer hardware drivers" depends on FB @@ -65555,7 +65611,7 @@ index e6d16d6..0f33a78 100644 tristate "Aeroflex Gaisler framebuffer support" depends on FB && SPARC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 50ed1b4..9b086ac 100644 +index 65fb150..df473d8 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o @@ -68910,10 +68966,10 @@ index 3c14e43..7626beb 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 185a83f51686987a770243702f0c54304c60cca2 Mon Sep 17 00:00:00 2001 +From b6332fb3df52fe7808c7de394a428252fc9749b4 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 031/251] dmaengine: Add support for BCM2708 +Subject: [PATCH 032/114] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -69070,10 +69126,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index 060306e..33e36b9 100644 +index 4d0425c..b7863f0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig -@@ -470,6 +470,10 @@ config TIMB_DMA +@@ -474,6 +474,10 @@ config TIMB_DMA help Enable support for the Timberdale FPGA DMA engine. @@ -69085,7 +69141,7 @@ index 060306e..33e36b9 100644 tristate "AM33xx CPPI41 DMA support" depends on ARCH_OMAP diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile -index ef9c099..e0cf5e6 100644 +index 6084127..8188c36 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o @@ -69533,10 +69589,10 @@ index 0000000..99cc7fd + +#endif /* _PLAT_BCM2708_DMA_H */ -From dd0f809dccd2522c01727b2822f484ce8e9ce23a Mon Sep 17 00:00:00 2001 +From eaa0834b46389ca5b48a699ca1fe40e164c0400b Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 032/251] MMC: added alternative MMC driver +Subject: [PATCH 033/114] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -69602,39 +69658,59 @@ In non-DT mode, don't add the device in the board file. Signed-off-by: Noralf Trønnes bcm2835-mmc: Don't overwrite MMC capabilities from DT + +bcm2835-mmc: Don't override bus width capabilities from devicetree + +Take out the force setting of the MMC_CAP_4_BIT_DATA host capability +so that the result read from devicetree via mmc_of_parse() is +preserved. + +bcm2835-mmc: Only claim one DMA channel + +With both MMC controllers enabled there are few DMA channels left. The +bcm2835-mmc driver only uses DMA in one direction at a time, so it +doesn't need to claim two channels. + +See: https://github.com/raspberrypi/linux/issues/1327 + +Signed-off-by: Phil Elwell --- - drivers/mmc/core/quirks.c | 6 + + drivers/mmc/core/quirks.c | 10 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1542 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 1578 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 1571 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 1611 insertions(+) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index fad660b..87ae2e9 100644 +index fad660b..b79fe14 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c -@@ -53,6 +53,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { +@@ -53,6 +53,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) { ++#ifdef CONFIG_MMC_BCM2835 + extern unsigned mmc_debug; ++#endif const struct mmc_fixup *f; u64 rev = cid_rev_card(card); -@@ -77,5 +78,10 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) +@@ -77,5 +80,12 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) f->vendor_fixup(card, f->data); } } + /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. + * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). + */ ++#ifdef CONFIG_MMC_BCM2835 + if (mmc_debug & (1<<13)) + card->quirks |= MMC_QUIRK_BLK_NO_CMD23; ++#endif } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 1dee533..9b72d2c 100644 +index 04feea8..e258577 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -69674,7 +69750,7 @@ index 1dee533..9b72d2c 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 3595f83..6cf6457 100644 +index af918d2..3ba94f0 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -69687,10 +69763,10 @@ index 3595f83..6cf6457 100644 obj-$(CONFIG_MMC_MTK) += mtk-sd.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..43aed6e +index 0000000..ceb3793 --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1542 @@ +@@ -0,0 +1,1571 @@ +/* + * BCM2835 MMC host driver. + * @@ -69801,8 +69877,9 @@ index 0000000..43aed6e + u32 shadow; + + /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ ++ struct dma_slave_config dma_cfg_rx; ++ struct dma_slave_config dma_cfg_tx; + struct dma_async_tx_descriptor *tx_desc; /* descriptor */ + + bool have_dma; @@ -70035,7 +70112,7 @@ index 0000000..43aed6e + + if (host->data && !(host->data->flags & MMC_DATA_WRITE)) { + /* otherwise handled in SDHCI IRQ */ -+ dma_chan = host->dma_chan_rx; ++ dma_chan = host->dma_chan_rxtx; + dir_data = DMA_FROM_DEVICE; + + dma_unmap_sg(dma_chan->device->dev, @@ -70186,16 +70263,21 @@ index 0000000..43aed6e + if (host->blocks == 0) + return; + ++ dma_chan = host->dma_chan_rxtx; + if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { -+ dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } + ++ /* The parameters have already been validated, so this will not fail */ ++ (void)dmaengine_slave_config(dma_chan, ++ (dir_data == DMA_FROM_DEVICE) ? ++ &host->dma_cfg_rx : ++ &host->dma_cfg_tx); ++ + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); + BUG_ON(!host->data->sg); @@ -70629,7 +70711,7 @@ index 0000000..43aed6e + if (host->data->flags & MMC_DATA_WRITE) { + /* IRQ handled here */ + -+ dma_chan = host->dma_chan_tx; ++ dma_chan = host->dma_chan_rxtx; + dir_data = DMA_TO_DEVICE; + dma_unmap_sg(dma_chan->device->dev, + host->data->sg, host->data->sg_len, @@ -70998,7 +71080,7 @@ index 0000000..43aed6e + /* host controller capabilities */ + mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | + MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; ++ MMC_CAP_MMC_HIGHSPEED; + + mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; + @@ -71009,28 +71091,47 @@ index 0000000..43aed6e + dev_info(dev, "Forcing PIO mode\n"); + host->have_dma = false; +#else -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n", ++ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { ++ dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n", + DRIVER_NAME); + host->have_dma = false; + } else { -+ dev_info(dev, "DMA channels allocated"); -+ host->have_dma = true; ++ dev_info(dev, "DMA channel allocated"); + + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.slave_id = 11; /* DREQ channel */ + ++ /* Validate the slave configurations */ ++ + cfg.direction = DMA_MEM_TO_DEV; + cfg.src_addr = 0; + cfg.dst_addr = host->bus_addr + SDHCI_BUFFER; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); + -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ ++ if (ret == 0) { ++ host->dma_cfg_tx = cfg; ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; ++ cfg.dst_addr = 0; ++ ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ } ++ ++ if (ret == 0) { ++ host->dma_cfg_rx = cfg; ++ ++ host->use_dma = true; ++ } else { ++ pr_err("%s: unable to configure DMA channel. " ++ "Faling back to PIO\n", ++ mmc_hostname(mmc)); ++ dma_release_channel(host->dma_chan_rxtx); ++ host->dma_chan_rxtx = NULL; ++ host->use_dma = false; ++ } + } +#endif + mmc->max_segs = 128; @@ -71109,16 +71210,20 @@ index 0000000..43aed6e + +#ifndef FORCE_PIO + if (node) { -+ host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); ++ host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx"); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ + dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = dma_request_channel(mask, NULL, NULL); ++ host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL); + } +#endif + clk = devm_clk_get(dev, NULL); @@ -71234,10 +71339,10 @@ index 0000000..43aed6e +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From e15ccca87e0a679797cbcaf24bbf2304b1e8eba3 Mon Sep 17 00:00:00 2001 +From 4674c122d3fa842a1065f255b3e50f61683692a0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 033/251] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 034/114] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -71310,15 +71415,64 @@ The MMC card-discovery process generates timeouts. This is expected behaviour, so reporting it to the user serves no purpose. Suppress the reporting of timeout errors unless the debug flag is on. + +bcm2835-sdhost: Add workaround for odd behaviour on some cards + +For reasons not understood, the sdhost driver fails when reading +sectors very near the end of some SD cards. The problem could +be related to the similar issue that reading the final sector +of any card as part of a multiple read never completes, and the +workaround is an extension of the mechanism introduced to solve +that problem which ensures those sectors are always read singly. + +bcm2835-sdhost: Major revision + +This is a significant revision of the bcm2835-sdhost driver. It +improves on the original in a number of ways: + +1) Through the use of CMD23 for reads it appears to avoid problems + reading some sectors on certain high speed cards. +2) Better atomicity to prevent crashes. +3) Higher performance. +4) Activity logging included, for easier diagnosis in the event + of a problem. + +Signed-off-by: Phil Elwell + +bcm2835-sdhost: Restore ATOMIC flag to PIO sg mapping + +Allocation problems have been seen in a wireless driver, and +this is the only change which might have been responsible. + +SQUASH: bcm2835-sdhost: Only claim one DMA channel + +With both MMC controllers enabled there are few DMA channels left. The +bcm2835-sdhost driver only uses DMA in one direction at a time, so it +doesn't need to claim two channels. + +See: https://github.com/raspberrypi/linux/issues/1327 + +Signed-off-by: Phil Elwell + +bcm2835-sdhost: Workaround for "slow" sectors + +Some cards have been seen to cause timeouts after certain sectors are +read. This workaround enforces a minimum delay between the stop after +reading one of those sectors and a subsequent data command. + +Using CMD23 (SET_BLOCK_COUNT) avoids this problem, so good cards will +not be penalised by this workaround. + +Signed-off-by: Phil Elwell --- drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1907 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1918 insertions(+) + drivers/mmc/host/bcm2835-sdhost.c | 2121 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 2132 insertions(+) create mode 100644 drivers/mmc/host/bcm2835-sdhost.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 9b72d2c..d509d10 100644 +index e258577..4cdd8cd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER @@ -71339,7 +71493,7 @@ index 9b72d2c..d509d10 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 6cf6457..df27ae9 100644 +index 3ba94f0..8daaa94 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -71352,15 +71506,15 @@ index 6cf6457..df27ae9 100644 obj-$(CONFIG_MMC_AU1X) += au1xmmc.o diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c new file mode 100644 -index 0000000..da08998 +index 0000000..f43aae0 --- /dev/null +++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1907 @@ +@@ -0,0 +1,2121 @@ +/* + * BCM2835 SD host driver. + * + * Author: Phil Elwell -+ * Copyright 2015 ++ * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd. + * + * Based on + * mmc-bcm2835.c by Gellert Weisz @@ -71382,12 +71536,13 @@ index 0000000..da08998 + * along with this program. If not, see . + */ + -+#define SAFE_READ_THRESHOLD 4 -+#define SAFE_WRITE_THRESHOLD 4 -+#define ALLOW_DMA 1 -+#define ALLOW_CMD23 0 -+#define ALLOW_FAST 1 -+#define USE_BLOCK_IRQ 1 ++#define FIFO_READ_THRESHOLD 4 ++#define FIFO_WRITE_THRESHOLD 4 ++#define ALLOW_CMD23_READ 1 ++#define ALLOW_CMD23_WRITE 0 ++#define ENABLE_LOG 1 ++#define SDDATA_FIFO_PIO_BURST 8 ++#define CMD_DALLY_US 1 + +#include +#include @@ -71406,6 +71561,7 @@ index 0000000..da08998 +#include +#include +#include ++#include + +#define DRIVER_NAME "sdhost-bcm2835" + @@ -71468,6 +71624,28 @@ index 0000000..da08998 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + ++#define SDEDM_FSM_MASK 0xf ++#define SDEDM_FSM_IDENTMODE 0x0 ++#define SDEDM_FSM_DATAMODE 0x1 ++#define SDEDM_FSM_READDATA 0x2 ++#define SDEDM_FSM_WRITEDATA 0x3 ++#define SDEDM_FSM_READWAIT 0x4 ++#define SDEDM_FSM_READCRC 0x5 ++#define SDEDM_FSM_WRITECRC 0x6 ++#define SDEDM_FSM_WRITEWAIT1 0x7 ++#define SDEDM_FSM_POWERDOWN 0x8 ++#define SDEDM_FSM_POWERUP 0x9 ++#define SDEDM_FSM_WRITESTART1 0xa ++#define SDEDM_FSM_WRITESTART2 0xb ++#define SDEDM_FSM_GENPULSES 0xc ++#define SDEDM_FSM_WRITEWAIT2 0xd ++#define SDEDM_FSM_STARTPOWDOWN 0xf ++ ++#define SDDATA_FIFO_WORDS 16 ++ ++#define USE_CMD23_FLAGS ((ALLOW_CMD23_READ * MMC_DATA_READ) | \ ++ (ALLOW_CMD23_WRITE * MMC_DATA_WRITE)) ++ +#define MHZ 1000000 + + @@ -71489,15 +71667,17 @@ index 0000000..da08998 + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + -+ struct timer_list timer; /* Timer for timeouts */ ++ struct work_struct cmd_wait_wq; /* Workqueue function */ + -+ struct timer_list pio_timer; /* PIO error detection timer */ ++ struct timer_list timer; /* Timer for timeouts */ + + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + + int irq; /* Device IRQ */ + ++ u32 cmd_quick_poll_retries; ++ u32 ns_per_fifo_word; + + /* cached registers */ + u32 hcfg; @@ -71512,27 +71692,126 @@ index 0000000..da08998 + + unsigned int use_busy:1; /* Wait for busy interrupt */ + ++ unsigned int use_sbc:1; /* Send CMD23 */ ++ + unsigned int debug:1; /* Enable debug output */ + -+ u32 thread_isr; -+ + /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ ++ struct dma_chan *dma_chan; /* Channel in use */ ++ struct dma_slave_config dma_cfg_rx; ++ struct dma_slave_config dma_cfg_tx; ++ struct dma_async_tx_descriptor *dma_desc; ++ u32 dma_dir; ++ u32 drain_words; ++ struct page *drain_page; ++ u32 drain_offset; + + bool allow_dma; -+ bool have_dma; + bool use_dma; + /*end of DMA part*/ + + int max_delay; /* maximum length of time spent waiting */ + struct timeval stop_time; /* when the last stop was issued */ + u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ ++ u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ + u32 overclock; /* Current frequency if overclocked, else zero */ + u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ ++ ++ u32 sectors; /* Cached card size in sectors */ +}; + ++#if ENABLE_LOG ++ ++struct log_entry_struct { ++ char event[4]; ++ u32 timestamp; ++ u32 param1; ++ u32 param2; ++}; ++ ++typedef struct log_entry_struct LOG_ENTRY_T; ++ ++LOG_ENTRY_T *sdhost_log_buf; ++dma_addr_t sdhost_log_addr; ++static u32 sdhost_log_idx; ++static spinlock_t log_lock; ++static void __iomem *timer_base; ++ ++#define LOG_ENTRIES (256*1) ++#define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) ++ ++static void log_init(u32 bus_to_phys) ++{ ++ spin_lock_init(&log_lock); ++ sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, ++ GFP_KERNEL); ++ if (sdhost_log_buf) { ++ pr_info("sdhost: log_buf @ %p (%x)\n", ++ sdhost_log_buf, sdhost_log_addr); ++ timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); ++ if (!timer_base) ++ pr_err("sdhost: failed to remap timer\n"); ++ } ++ else ++ pr_err("sdhost: failed to allocate log buf\n"); ++} ++ ++static void log_event_impl(const char *event, u32 param1, u32 param2) ++{ ++ if (sdhost_log_buf) { ++ LOG_ENTRY_T *entry; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&log_lock, flags); ++ ++ entry = sdhost_log_buf + sdhost_log_idx; ++ memcpy(entry->event, event, 4); ++ entry->timestamp = (readl(timer_base + 4) & 0x3fffffff) + ++ (smp_processor_id()<<30); ++ entry->param1 = param1; ++ entry->param2 = param2; ++ sdhost_log_idx = (sdhost_log_idx + 1) % LOG_ENTRIES; ++ ++ spin_unlock_irqrestore(&log_lock, flags); ++ } ++} ++ ++static void log_dump(void) ++{ ++ if (sdhost_log_buf) { ++ LOG_ENTRY_T *entry; ++ unsigned long flags; ++ int idx; ++ ++ spin_lock_irqsave(&log_lock, flags); ++ ++ idx = sdhost_log_idx; ++ do { ++ entry = sdhost_log_buf + idx; ++ if (entry->event[0] != '\0') ++ pr_err("[%08x] %.4s %x %x\n", ++ entry->timestamp, ++ entry->event, ++ entry->param1, ++ entry->param2); ++ idx = (idx + 1) % LOG_ENTRIES; ++ } while (idx != sdhost_log_idx); ++ ++ spin_unlock_irqrestore(&log_lock, flags); ++ } ++} ++ ++#define log_event(event, param1, param2) log_event_impl(event, param1, param2) ++ ++#else ++ ++#define log_init(x) (void)0 ++#define log_event(event, param1, param2) (void)0 ++#define log_dump() (void)0 ++ ++#endif + +static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) +{ @@ -71554,7 +71833,7 @@ index 0000000..da08998 + const char *label) +{ + if (cmd) -+ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", ++ pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", + mmc_hostname(host->mmc), + (cmd == host->cmd) ? '>' : ' ', + label, cmd->opcode, cmd->arg, cmd->flags, @@ -71564,77 +71843,81 @@ index 0000000..da08998 + +static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) +{ -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ if (host->mrq) ++ { ++ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); ++ if (host->mrq->data) ++ pr_err("%s: data blocks %x blksz %x - err %d\n", ++ mmc_hostname(host->mmc), ++ host->mrq->data->blocks, ++ host->mrq->data->blksz, ++ host->mrq->data->error); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ } + -+ pr_info("%s: =========== REGISTER DUMP ===========\n", ++ pr_err("%s: =========== REGISTER DUMP ===========\n", + mmc_hostname(host->mmc)); + -+ pr_info("%s: SDCMD 0x%08x\n", ++ pr_err("%s: SDCMD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCMD)); -+ pr_info("%s: SDARG 0x%08x\n", ++ pr_err("%s: SDARG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDARG)); -+ pr_info("%s: SDTOUT 0x%08x\n", ++ pr_err("%s: SDTOUT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info("%s: SDCDIV 0x%08x\n", ++ pr_err("%s: SDCDIV 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info("%s: SDRSP0 0x%08x\n", ++ pr_err("%s: SDRSP0 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info("%s: SDRSP1 0x%08x\n", ++ pr_err("%s: SDRSP1 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info("%s: SDRSP2 0x%08x\n", ++ pr_err("%s: SDRSP2 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info("%s: SDRSP3 0x%08x\n", ++ pr_err("%s: SDRSP3 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info("%s: SDHSTS 0x%08x\n", ++ pr_err("%s: SDHSTS 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info("%s: SDVDD 0x%08x\n", ++ pr_err("%s: SDVDD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDVDD)); -+ pr_info("%s: SDEDM 0x%08x\n", ++ pr_err("%s: SDEDM 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDEDM)); -+ pr_info("%s: SDHCFG 0x%08x\n", ++ pr_err("%s: SDHCFG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info("%s: SDHBCT 0x%08x\n", ++ pr_err("%s: SDHBCT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info("%s: SDHBLC 0x%08x\n", ++ pr_err("%s: SDHBLC 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBLC)); + -+ pr_info("%s: ===========================================\n", ++ pr_err("%s: ===========================================\n", + mmc_hostname(host->mmc)); +} + -+ +static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) +{ + bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); +} + -+ +static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) +{ + u32 temp; + ++ if (host->debug) ++ pr_info("%s: reset\n", mmc_hostname(host->mmc)); ++ + bcm2835_sdhost_set_power(host, false); + + bcm2835_sdhost_write(host, 0, SDCMD); @@ -71650,26 +71933,25 @@ index 0000000..da08998 + temp = bcm2835_sdhost_read(host, SDEDM); + temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; ++ host->sectors = 0; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + mmiowb(); +} + -+ +static void bcm2835_sdhost_reset(struct mmc_host *mmc) +{ + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(mmc)); + spin_lock_irqsave(&host->lock, flags); ++ log_event("RST<", 0, 0); + + bcm2835_sdhost_reset_internal(host); + @@ -71694,82 +71976,48 @@ index 0000000..da08998 + } +} + -+static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+{ -+ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -+ -+ if (!write_complete) { -+ /* Request an IRQ for the last block */ -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -+ /* The write has now completed. Disable the interrupt -+ and clear the status flag */ -+ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -+ write_complete = true; -+ } -+ } -+ -+ return write_complete; -+} -+ -+static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) ++static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) +{ + int timediff; -+#ifdef DEBUG -+ static struct timeval start_time; -+ static int max_stall_time = 0; -+ static int total_stall_time = 0; -+ struct timeval before, after; ++ u32 alternate_idle; ++ u32 edm; + -+ do_gettimeofday(&before); -+ if (max_stall_time == 0) -+ start_time = before; -+#endif ++ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ? ++ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; ++ ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ ++ log_event("WTC<", edm, 0); + + timediff = 0; + + while (1) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm & 0xf) == 1) ++ u32 fsm = edm & SDEDM_FSM_MASK; ++ if ((fsm == SDEDM_FSM_IDENTMODE) || ++ (fsm == SDEDM_FSM_DATAMODE)) + break; -+ timediff++; -+ if (timediff > 5000000) { -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); ++ if (fsm == alternate_idle) { ++ bcm2835_sdhost_write(host, ++ edm | SDEDM_FORCE_DATA_MODE, ++ SDEDM); ++ break; ++ } + -+ pr_err(" wait_write_complete - still waiting after %dus\n", ++ timediff++; ++ if (timediff == 100000) { ++ pr_err("%s: wait_transfer_complete - still waiting after %d retries\n", ++ mmc_hostname(host->mmc), + timediff); -+#else -+ pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff); -+#endif ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; ++ host->mrq->data->error = -ETIMEDOUT; ++ log_event("WTC!", edm, 0); + return; + } ++ cpu_relax(); ++ edm = bcm2835_sdhost_read(host, SDEDM); + } -+ -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -+ -+ total_stall_time += timediff; -+ if (timediff > max_stall_time) -+ max_stall_time = timediff; -+ -+ if ((after.tv_sec - start_time.tv_sec) > 10) { -+ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -+ max_stall_time, total_stall_time); -+ start_time = after; -+ max_stall_time = 0; -+ total_stall_time = 0; -+ } -+#endif ++ log_event("WTC>", edm, 0); +} + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); @@ -71777,98 +72025,128 @@ index 0000000..da08998 +static void bcm2835_sdhost_dma_complete(void *param) +{ + struct bcm2835_host *host = param; -+ struct dma_chan *dma_chan; ++ struct mmc_data *data = host->data; + unsigned long flags; -+ u32 dir_data; + + spin_lock_irqsave(&host->lock, flags); ++ log_event("DMA<", (u32)host->data, bcm2835_sdhost_read(host, SDHSTS)); ++ log_event("DMA ", bcm2835_sdhost_read(host, SDCMD), ++ bcm2835_sdhost_read(host, SDEDM)); + -+ if (host->data) { -+ bool write_complete; -+ if (USE_BLOCK_IRQ) -+ write_complete = bcm2835_sdhost_is_write_complete(host); -+ else { -+ bcm2835_sdhost_wait_write_complete(host); -+ write_complete = true; -+ } -+ pr_debug("dma_complete() - write_complete=%d\n", -+ write_complete); ++ if (host->dma_chan) { ++ dma_unmap_sg(host->dma_chan->device->dev, ++ data->sg, data->sg_len, ++ host->dma_dir); + -+ if (write_complete || (host->data->flags & MMC_DATA_READ)) -+ { -+ if (write_complete) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ } else { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ } -+ -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } ++ host->dma_chan = NULL; + } + ++ if (host->drain_words) { ++ void *page; ++ u32 *buf; ++ ++ page = kmap_atomic(host->drain_page); ++ buf = page + host->drain_offset; ++ ++ while (host->drain_words) { ++ u32 edm = bcm2835_sdhost_read(host, SDEDM); ++ if ((edm >> 4) & 0x1f) ++ *(buf++) = bcm2835_sdhost_read(host, ++ SDDATA); ++ host->drain_words--; ++ } ++ ++ kunmap_atomic(page); ++ } ++ ++ bcm2835_sdhost_finish_data(host); ++ ++ log_event("DMA>", (u32)host->data, 0); + spin_unlock_irqrestore(&host->lock, flags); +} + -+static bool data_transfer_wait(struct bcm2835_host *host) -+{ -+ unsigned long timeout = 1000000; -+ while (timeout) -+ { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_DATA_FLAG) { -+ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); -+ break; -+ } -+ timeout--; -+ } -+ if (timeout == 0) { -+ pr_err("%s: Data %s timeout\n", -+ mmc_hostname(host->mmc), -+ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return false; -+ } -+ return true; -+} -+ +static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len; + u32 *buf; ++ unsigned long wait_max; + + blksize = host->data->blksz; + ++ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); ++ + local_irq_save(flags); + + while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); ++ int copy_words; ++ u32 hsts = 0; ++ ++ if (!sg_miter_next(&host->sg_miter)) { ++ host->data->error = -EINVAL; ++ break; ++ } + + len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); ++ if (len % 4) { ++ host->data->error = -EINVAL; ++ break; ++ } + + blksize -= len; + host->sg_miter.consumed = len; + + buf = (u32 *)host->sg_miter.addr; + -+ while (len) { -+ if (!data_transfer_wait(host)) -+ break; ++ copy_words = len/4; + -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ len -= 4; ++ while (copy_words) { ++ int burst_words, words; ++ u32 edm; ++ ++ burst_words = SDDATA_FIFO_PIO_BURST; ++ if (burst_words > copy_words) ++ burst_words = copy_words; ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ words = ((edm >> 4) & 0x1f); ++ ++ if (words < burst_words) { ++ int fsm_state = (edm & SDEDM_FSM_MASK); ++ if ((fsm_state != SDEDM_FSM_READDATA) && ++ (fsm_state != SDEDM_FSM_READWAIT) && ++ (fsm_state != SDEDM_FSM_READCRC)) { ++ hsts = bcm2835_sdhost_read(host, ++ SDHSTS); ++ pr_err("%s: fsm %x, hsts %x\n", ++ mmc_hostname(host->mmc), ++ fsm_state, hsts); ++ if (hsts & SDHSTS_ERROR_MASK) ++ break; ++ } ++ ++ if (time_after(jiffies, wait_max)) { ++ pr_err("%s: PIO read timeout - EDM %x\n", ++ mmc_hostname(host->mmc), ++ edm); ++ hsts = SDHSTS_REW_TIME_OUT; ++ break; ++ } ++ ndelay((burst_words - words) * ++ host->ns_per_fifo_word); ++ continue; ++ } else if (words > copy_words) { ++ words = copy_words; ++ } ++ ++ copy_words -= words; ++ ++ while (words) { ++ *(buf++) = bcm2835_sdhost_read(host, SDDATA); ++ words--; ++ } + } + -+ if (host->data->error) ++ if (hsts & SDHSTS_ERROR_MASK) + break; + } + @@ -71882,32 +72160,83 @@ index 0000000..da08998 + unsigned long flags; + size_t blksize, len; + u32 *buf; ++ unsigned long wait_max; + + blksize = host->data->blksz; + ++ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); ++ + local_irq_save(flags); + + while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); ++ int copy_words; ++ u32 hsts = 0; ++ ++ if (!sg_miter_next(&host->sg_miter)) { ++ host->data->error = -EINVAL; ++ break; ++ } + + len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); ++ if (len % 4) { ++ host->data->error = -EINVAL; ++ break; ++ } + + blksize -= len; + host->sg_miter.consumed = len; + -+ buf = host->sg_miter.addr; ++ buf = (u32 *)host->sg_miter.addr; + -+ while (len) { -+ if (!data_transfer_wait(host)) -+ break; ++ copy_words = len/4; + -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ len -= 4; ++ while (copy_words) { ++ int burst_words, words; ++ u32 edm; ++ ++ burst_words = SDDATA_FIFO_PIO_BURST; ++ if (burst_words > copy_words) ++ burst_words = copy_words; ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f); ++ ++ if (words < burst_words) { ++ int fsm_state = (edm & SDEDM_FSM_MASK); ++ if ((fsm_state != SDEDM_FSM_WRITEDATA) && ++ (fsm_state != SDEDM_FSM_WRITESTART1) && ++ (fsm_state != SDEDM_FSM_WRITESTART2)) { ++ hsts = bcm2835_sdhost_read(host, ++ SDHSTS); ++ pr_err("%s: fsm %x, hsts %x\n", ++ mmc_hostname(host->mmc), ++ fsm_state, hsts); ++ if (hsts & SDHSTS_ERROR_MASK) ++ break; ++ } ++ ++ if (time_after(jiffies, wait_max)) { ++ pr_err("%s: PIO write timeout - EDM %x\n", ++ mmc_hostname(host->mmc), ++ edm); ++ hsts = SDHSTS_REW_TIME_OUT; ++ break; ++ } ++ ndelay((burst_words - words) * ++ host->ns_per_fifo_word); ++ continue; ++ } else if (words > copy_words) { ++ words = copy_words; ++ } ++ ++ copy_words -= words; ++ ++ while (words) { ++ bcm2835_sdhost_write(host, *(buf++), SDDATA); ++ words--; ++ } + } + -+ if (host->data->error) ++ if (hsts & SDHSTS_ERROR_MASK) + break; + } + @@ -71916,12 +72245,12 @@ index 0000000..da08998 + local_irq_restore(flags); +} + -+ +static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) +{ + u32 sdhsts; + bool is_read; + BUG_ON(!host->data); ++ log_event("XFP<", (u32)host->data, host->blocks); + + is_read = (host->data->flags & MMC_DATA_READ) != 0; + if (is_read) @@ -71945,65 +72274,99 @@ index 0000000..da08998 + is_read ? "read" : "write", + sdhsts); + host->data->error = -ETIMEDOUT; -+ } else if (!is_read && !host->data->error) { -+ /* Start a timer in case a transfer error occurs because -+ there is no error interrupt */ -+ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); + } ++ log_event("XFP>", (u32)host->data, host->blocks); +} + -+ -+static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) ++static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, ++ struct mmc_data *data) +{ -+ u32 len, dir_data, dir_slave; ++ int len, dir_data, dir_slave; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *dma_chan; + -+ pr_debug("bcm2835_sdhost_transfer_dma()\n"); ++ log_event("PRD<", (u32)data, 0); ++ pr_debug("bcm2835_sdhost_prepare_dma()\n"); + -+ WARN_ON(!host->data); -+ -+ if (!host->data) -+ return; -+ -+ if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; ++ dma_chan = host->dma_chan_rxtx; ++ if (data->flags & MMC_DATA_READ) { + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { -+ dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } ++ log_event("PRD1", (u32)dma_chan, 0); + + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); -+ BUG_ON(!host->data->sg); ++ BUG_ON(!data->sg); + -+ len = dma_map_sg(dma_chan->device->dev, host->data->sg, -+ host->data->sg_len, dir_data); -+ if (len > 0) { -+ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, ++ /* The block doesn't manage the FIFO DREQs properly for multi-block ++ transfers, so don't attempt to DMA the final few words. ++ Unfortunately this requires the final sg entry to be trimmed. ++ N.B. This code demands that the overspill is contained in ++ a single sg entry. ++ */ ++ ++ host->drain_words = 0; ++ if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) { ++ struct scatterlist *sg; ++ u32 len; ++ int i; ++ ++ len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4, ++ (u32)data->blocks * data->blksz); ++ ++ for_each_sg(data->sg, sg, data->sg_len, i) { ++ if (sg_is_last(sg)) { ++ BUG_ON(sg->length < len); ++ sg->length -= len; ++ host->drain_page = (struct page *)sg->page_link; ++ host->drain_offset = sg->offset + sg->length; ++ } ++ } ++ host->drain_words = len/4; ++ } ++ ++ /* The parameters have already been validated, so this will not fail */ ++ (void)dmaengine_slave_config(dma_chan, ++ (dir_data == DMA_FROM_DEVICE) ? ++ &host->dma_cfg_rx : ++ &host->dma_cfg_tx); ++ ++ len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, ++ dir_data); ++ ++ log_event("PRD2", len, 0); ++ if (len > 0) ++ desc = dmaengine_prep_slave_sg(dma_chan, data->sg, + len, dir_slave, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ } else { -+ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -+ } ++ log_event("PRD3", (u32)desc, 0); ++ + if (desc) { + desc->callback = bcm2835_sdhost_dma_complete; + desc->callback_param = host; -+ dmaengine_submit(desc); -+ dma_async_issue_pending(dma_chan); ++ host->dma_desc = desc; ++ host->dma_chan = dma_chan; ++ host->dma_dir = dir_data; + } -+ ++ log_event("PDM>", (u32)data, 0); +} + ++static void bcm2835_sdhost_start_dma(struct bcm2835_host *host) ++{ ++ log_event("SDMA", (u32)host->data, (u32)host->dma_chan); ++ dmaengine_submit(host->dma_desc); ++ dma_async_issue_pending(host->dma_chan); ++} + +static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) +{ + u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | + SDHCFG_BUSY_IRPT_EN; -+ if (host->use_dma) ++ if (host->dma_desc) + host->hcfg = (host->hcfg & ~all_irqs) | + SDHCFG_BUSY_IRPT_EN; + else @@ -72014,13 +72377,13 @@ index 0000000..da08998 + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); +} + -+ +static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) +{ + struct mmc_data *data = cmd->data; + + WARN_ON(host->data); + ++ host->data = data; + if (!data) + return; + @@ -72029,16 +72392,32 @@ index 0000000..da08998 + BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + -+ host->data = data; + host->data_complete = 0; + host->flush_fifo = 0; + host->data->bytes_xfered = 0; + -+ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); -+ if (!host->use_dma) { -+ int flags; ++ if (!host->sectors && host->mmc->card) { ++ struct mmc_card *card = host->mmc->card; ++ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { ++ /* ++ * The EXT_CSD sector count is in number of 512 byte ++ * sectors. ++ */ ++ host->sectors = card->ext_csd.sectors; ++ } else { ++ /* ++ * The CSD capacity field is in units of read_blkbits. ++ * set_capacity takes units of 512 bytes. ++ */ ++ host->sectors = card->csd.capacity << ++ (card->csd.read_blkbits - 9); ++ } ++ } ++ ++ if (!host->dma_desc) { ++ /* Use PIO */ ++ int flags = SG_MITER_ATOMIC; + -+ flags = SG_MITER_ATOMIC; + if (data->flags & MMC_DATA_READ) + flags |= SG_MITER_TO_SG; + else @@ -72050,19 +72429,20 @@ index 0000000..da08998 + bcm2835_sdhost_set_transfer_irqs(host); + + bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); ++ bcm2835_sdhost_write(host, data->blocks, SDHBLC); + + BUG_ON(!host->data); +} + -+ -+void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) ++bool bcm2835_sdhost_send_command(struct bcm2835_host *host, ++ struct mmc_command *cmd) +{ + u32 sdcmd, sdhsts; + unsigned long timeout; + int delay; + + WARN_ON(host->cmd); ++ log_event("CMD<", cmd->opcode, cmd->arg); + + if (cmd->data) + pr_debug("%s: send_command %d 0x%x " @@ -72085,9 +72465,9 @@ index 0000000..da08998 + pr_err("%s: previous command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); -+ cmd->error = -EIO; ++ cmd->error = -EILSEQ; + tasklet_schedule(&host->finish_tasklet); -+ return; ++ return false; + } + timeout--; + udelay(10); @@ -72115,23 +72495,24 @@ index 0000000..da08998 + if (sdhsts & SDHSTS_ERROR_MASK) + bcm2835_sdhost_write(host, sdhsts, SDHSTS); + -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + pr_err("%s: unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); -+ return; ++ return false; + } + ++ bcm2835_sdhost_prepare_data(host, cmd); ++ ++ bcm2835_sdhost_write(host, cmd->arg, SDARG); ++ + sdcmd = cmd->opcode & SDCMD_CMD_MASK; + -+ if (!(cmd->flags & MMC_RSP_PRESENT)) ++ host->use_busy = 0; ++ if (!(cmd->flags & MMC_RSP_PRESENT)) { + sdcmd |= SDCMD_NO_RESPONSE; -+ else { ++ } else { + if (cmd->flags & MMC_RSP_136) + sdcmd |= SDCMD_LONG_RESPONSE; + if (cmd->flags & MMC_RSP_BUSY) { @@ -72141,7 +72522,8 @@ index 0000000..da08998 + } + + if (cmd->data) { -+ if (host->delay_after_stop) { ++ log_event("CMDD", cmd->data->blocks, cmd->data->blksz); ++ if (host->delay_after_this_stop) { + struct timeval now; + int time_since_stop; + do_gettimeofday(&now); @@ -72150,12 +72532,32 @@ index 0000000..da08998 + /* Possibly less than one second */ + time_since_stop = time_since_stop * 1000000 + + (now.tv_usec - host->stop_time.tv_usec); -+ if (time_since_stop < host->delay_after_stop) -+ udelay(host->delay_after_stop - ++ if (time_since_stop < ++ host->delay_after_this_stop) ++ udelay(host->delay_after_this_stop - + time_since_stop); + } + } + ++ host->delay_after_this_stop = host->delay_after_stop; ++ if ((cmd->data->flags & MMC_DATA_READ) && !host->use_sbc) { ++ /* See if read crosses one of the hazardous sectors */ ++ u32 first_blk, last_blk; ++ ++ /* Intentionally include the following sector because ++ without CMD23/SBC the read may run on. */ ++ first_blk = host->mrq->cmd->arg; ++ last_blk = first_blk + cmd->data->blocks; ++ ++ if (((last_blk >= (host->sectors - 64)) && ++ (first_blk <= (host->sectors - 64))) || ++ ((last_blk >= (host->sectors - 32)) && ++ (first_blk <= (host->sectors - 32)))) { ++ host->delay_after_this_stop = ++ max(250u, host->delay_after_stop); ++ } ++ } ++ + if (cmd->data->flags & MMC_DATA_WRITE) + sdcmd |= SDCMD_WRITE_CMD; + if (cmd->data->flags & MMC_DATA_READ) @@ -72163,10 +72565,12 @@ index 0000000..da08998 + } + + bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); ++ ++ return true; +} + -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, ++ unsigned long *irq_flags); +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) @@ -72176,6 +72580,7 @@ index 0000000..da08998 + data = host->data; + BUG_ON(!data); + ++ log_event("FDA<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_data(error %d, stop %d, sbc %d)\n", + data->error, data->stop ? 1 : 0, + host->mrq->sbc ? 1 : 0); @@ -72183,10 +72588,7 @@ index 0000000..da08998 + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + -+ if (data->error) { -+ data->bytes_xfered = 0; -+ } else -+ data->bytes_xfered = data->blksz * data->blocks; ++ data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks); + + host->data_complete = 1; + @@ -72201,9 +72603,9 @@ index 0000000..da08998 + } + else + bcm2835_sdhost_transfer_complete(host); ++ log_event("FDA>", (u32)host->mrq, (u32)host->cmd); +} + -+ +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) +{ + struct mmc_data *data; @@ -72215,6 +72617,7 @@ index 0000000..da08998 + data = host->data; + host->data = NULL; + ++ log_event("TCM<", (u32)data, data->error); + pr_debug("transfer_complete(error %d, stop %d)\n", + data->error, data->stop ? 1 : 0); + @@ -72223,88 +72626,114 @@ index 0000000..da08998 + * a) open-ended multiblock transfer (no CMD23) + * b) error in multiblock transfer + */ -+ if (data->stop && -+ (data->error || -+ !host->mrq->sbc)) { -+ host->flush_fifo = 1; -+ bcm2835_sdhost_send_command(host, data->stop); -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); ++ if (host->mrq->stop && (data->error || !host->use_sbc)) { ++ if (bcm2835_sdhost_send_command(host, host->mrq->stop)) { ++ /* No busy, so poll for completion */ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, NULL); ++ ++ if (host->delay_after_this_stop) ++ do_gettimeofday(&host->stop_time); ++ } + } else { ++ bcm2835_sdhost_wait_transfer_complete(host); + tasklet_schedule(&host->finish_tasklet); + } ++ log_event("TCM>", (u32)data, 0); +} + -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) ++/* If irq_flags is valid, the caller is in a thread context and is allowed ++ to sleep */ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, ++ unsigned long *irq_flags) +{ + u32 sdcmd; -+ unsigned long timeout; ++ u32 retries; +#ifdef DEBUG + struct timeval before, after; + int timediff = 0; +#endif + ++ log_event("FCM<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); + + BUG_ON(!host->cmd || !host->mrq); + -+#ifdef DEBUG -+ do_gettimeofday(&before); -+#endif -+ /* Wait max 100 ms */ -+ timeout = 10000; ++ /* Poll quickly at first */ ++ ++ retries = host->cmd_quick_poll_retries; ++ if (!retries) { ++ /* Work out how many polls take 1us by timing 10us */ ++ struct timeval start, now; ++ int us_diff; ++ ++ retries = 1; ++ do { ++ int i; ++ ++ retries *= 2; ++ ++ do_gettimeofday(&start); ++ ++ for (i = 0; i < retries; i++) { ++ cpu_relax(); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ } ++ ++ do_gettimeofday(&now); ++ us_diff = (now.tv_sec - start.tv_sec) * 1000000 + ++ (now.tv_usec - start.tv_usec); ++ } while (us_diff < 10); ++ ++ host->cmd_quick_poll_retries = ((retries * us_diff + 9)*CMD_DALLY_US)/10 + 1; ++ retries = 1; // We've already waited long enough this time ++ } ++ ++ retries = host->cmd_quick_poll_retries; + for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ (sdcmd & SDCMD_NEW_FLAG) && timeout; -+ timeout--) { -+ if (host->flush_fifo) { -+ while (bcm2835_sdhost_read(host, SDHSTS) & -+ SDHSTS_DATA_FLAG) -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ udelay(10); ++ (sdcmd & SDCMD_NEW_FLAG) && !(sdcmd & SDCMD_FAIL_FLAG) && retries; ++ retries--) { ++ cpu_relax(); + sdcmd = bcm2835_sdhost_read(host, SDCMD); + } -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); + -+ pr_debug(" finish_command - waited %dus\n", timediff); -+#endif ++ if (!retries) { ++ unsigned long wait_max; + -+ if (timeout == 0) { ++ if (!irq_flags) { ++ /* Schedule the work */ ++ log_event("CWWQ", 0, 0); ++ schedule_work(&host->cmd_wait_wq); ++ return; ++ } ++ ++ /* Wait max 100 ms */ ++ wait_max = jiffies + msecs_to_jiffies(100); ++ while (time_before(jiffies, wait_max)) { ++ spin_unlock_irqrestore(&host->lock, *irq_flags); ++ usleep_range(1, 10); ++ spin_lock_irqsave(&host->lock, *irq_flags); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ if (!(sdcmd & SDCMD_NEW_FLAG) || ++ (sdcmd & SDCMD_FAIL_FLAG)) ++ break; ++ } ++ } ++ ++ /* Check for errors */ ++ if (sdcmd & SDCMD_NEW_FLAG) { + pr_err("%s: command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + host->cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; -+ } -+ -+ if (host->flush_fifo) { -+ for (timeout = 100; -+ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -+ timeout--) { -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ host->flush_fifo = 0; -+ if (timeout == 0) { -+ pr_err("%s: FIFO never drained.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ } -+ -+ /* Check for errors */ -+ if (sdcmd & SDCMD_FAIL_FLAG) -+ { ++ } else if (sdcmd & SDCMD_FAIL_FLAG) { + u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); + ++ /* Clear the errors */ ++ bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS); ++ + if (host->debug) + pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", + mmc_hostname(host->mmc), sdcmd, sdhsts, @@ -72327,7 +72756,7 @@ index 0000000..da08998 + mmc_hostname(host->mmc), + host->cmd->opcode); + bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; ++ host->cmd->error = -EILSEQ; + } + tasklet_schedule(&host->finish_tasklet); + return; @@ -72342,31 +72771,31 @@ index 0000000..da08998 + pr_debug("%s: finish_command %08x %08x %08x %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); ++ log_event("RSP ", host->cmd->resp[0], host->cmd->resp[1]); + } else { + host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); + pr_debug("%s: finish_command %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0]); ++ log_event("RSP ", host->cmd->resp[0], 0); + } + } + -+ host->cmd->error = 0; -+ + if (host->cmd == host->mrq->sbc) { + /* Finished CMD23, now send actual command. */ + host->cmd = NULL; -+ bcm2835_sdhost_send_command(host, host->mrq->cmd); ++ if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) { ++ if (host->data && host->dma_desc) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_start_dma(host); + -+ if (host->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else if (host->cmd == host->mrq->stop) ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, NULL); ++ } ++ } else if (host->cmd == host->mrq->stop) { + /* Finished CMD12 */ + tasklet_schedule(&host->finish_tasklet); -+ else { ++ } else { + /* Processed actual command. */ + host->cmd = NULL; + if (!host->data) @@ -72374,6 +72803,7 @@ index 0000000..da08998 + else if (host->data_complete) + bcm2835_sdhost_transfer_complete(host); + } ++ log_event("FCM>", (u32)host->mrq, (u32)host->cmd); +} + +static void bcm2835_sdhost_timeout(unsigned long data) @@ -72384,10 +72814,12 @@ index 0000000..da08998 + host = (struct bcm2835_host *)data; + + spin_lock_irqsave(&host->lock, flags); ++ log_event("TIM<", 0, 0); + + if (host->mrq) { + pr_err("%s: timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); ++ log_dump(); + bcm2835_sdhost_dumpregs(host); + + if (host->data) { @@ -72408,74 +72840,15 @@ index 0000000..da08998 + spin_unlock_irqrestore(&host->lock, flags); +} + -+static void bcm2835_sdhost_pio_timeout(unsigned long data) ++static void bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) +{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ if (sdhsts & SDHSTS_REW_TIME_OUT) { -+ pr_err("%s: transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ } else { -+ pr_err("%s: unexpected transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) -+{ -+ if (enable) -+ host->hcfg |= SDHCFG_SDIO_IRPT_EN; -+ else -+ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); -+ spin_lock_irqsave(&host->lock, flags); -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -+ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR); -+ ++ log_event("IRQB", (u32)host->cmd, intmask); + if (!host->cmd) { + pr_err("%s: got command busy interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return 0; ++ return; + } + + if (!host->use_busy) { @@ -72483,7 +72856,7 @@ index 0000000..da08998 + "though not expecting one.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return 0; ++ return; + } + host->use_busy = 0; + @@ -72506,28 +72879,23 @@ index 0000000..da08998 + } else if (intmask & SDHSTS_CMD_TIME_OUT) + host->cmd->error = -ETIMEDOUT; + ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); + } + else -+ bcm2835_sdhost_finish_command(host); -+ -+ return handled; ++ bcm2835_sdhost_finish_command(host, NULL); +} + -+static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); -+ + /* There are no dedicated data/space available interrupt + status bits, so it is necessary to use the single shared + data/space available FIFO status bits. It is therefore not + an error to get here when there is no data transfer in + progress. */ ++ log_event("IRQD", (u32)host->data, intmask); + if (!host->data) -+ return 0; ++ return; + + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR | @@ -72538,46 +72906,37 @@ index 0000000..da08998 + else + host->data->error = -ETIMEDOUT; + -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; ++ if (host->debug) { ++ log_dump(); ++ bcm2835_sdhost_dumpregs(host); ++ } + } + -+ /* Use the block interrupt for writes after the first block */ -+ if (host->data->flags & MMC_DATA_WRITE) { ++ if (host->data->error) { ++ bcm2835_sdhost_finish_data(host); ++ } else if (host->data->flags & MMC_DATA_WRITE) { ++ /* Use the block interrupt for writes after the first block */ + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); + host->hcfg |= SDHCFG_BLOCK_IRPT_EN; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if (host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); ++ bcm2835_sdhost_transfer_pio(host); + } else { -+ if (!host->data->error) { -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; -+ } ++ bcm2835_sdhost_transfer_pio(host); ++ host->blocks--; + if ((host->blocks == 0) || host->data->error) + bcm2835_sdhost_finish_data(host); + } -+ -+ return handled; +} + -+static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) +{ -+ struct dma_chan *dma_chan; -+ u32 dir_data; -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); -+ ++ log_event("IRQK", (u32)host->data, intmask); + if (!host->data) { + pr_err("%s: got block interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return handled; ++ return; + } + + if (intmask & (SDHSTS_CRC16_ERROR | @@ -72589,145 +72948,69 @@ index 0000000..da08998 + else + host->data->error = -ETIMEDOUT; + -+ if (host->debug) ++ if (host->debug) { ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; ++ } + } + -+ if (!host->use_dma) { ++ if (!host->dma_desc) { + BUG_ON(!host->blocks); -+ host->blocks--; -+ if ((host->blocks == 0) || host->data->error) { -+ /* Cancel the timer */ -+ del_timer(&host->pio_timer); -+ ++ if (host->data->error || (--host->blocks == 0)) { + bcm2835_sdhost_finish_data(host); + } else { + bcm2835_sdhost_transfer_pio(host); -+ -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); + } + } else if (host->data->flags & MMC_DATA_WRITE) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ + bcm2835_sdhost_finish_data(host); + } -+ -+ return handled; +} + -+ +static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) +{ + irqreturn_t result = IRQ_NONE; + struct bcm2835_host *host = dev_id; -+ u32 unexpected = 0, early = 0; -+ int loops = 0; ++ u32 intmask; + + spin_lock(&host->lock); + -+ for (loops = 0; loops < 1; loops++) { -+ u32 intmask, handled; ++ intmask = bcm2835_sdhost_read(host, SDHSTS); ++ log_event("IRQ<", intmask, 0); + -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ handled = intmask & (SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && -+ (loops == 0) && !host->data) { -+ pr_err("%s: sdhost_irq data interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), -+ (unsigned)intmask); -+ -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ if (!handled) -+ break; -+ -+ if (loops) -+ early |= handled; ++ bcm2835_sdhost_write(host, ++ SDHSTS_BUSY_IRPT | ++ SDHSTS_BLOCK_IRPT | ++ SDHSTS_SDIO_IRPT | ++ SDHSTS_DATA_FLAG, ++ SDHSTS); + ++ if (intmask & SDHSTS_BLOCK_IRPT) { ++ bcm2835_sdhost_block_irq(host, intmask); + result = IRQ_HANDLED; ++ } + -+ /* Clear all interrupts and notifications */ -+ bcm2835_sdhost_write(host, intmask, SDHSTS); ++ if (intmask & SDHSTS_BUSY_IRPT) { ++ bcm2835_sdhost_busy_irq(host, intmask); ++ result = IRQ_HANDLED; ++ } + -+ if (intmask & SDHSTS_BUSY_IRPT) -+ handled |= bcm2835_sdhost_busy_irq(host, intmask); -+ -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) -+ handled |= bcm2835_sdhost_data_irq(host, intmask); -+ -+ if (intmask & SDHSTS_BLOCK_IRPT) -+ handled |= bcm2835_sdhost_block_irq(host, intmask); -+ -+ if (intmask & SDHSTS_SDIO_IRPT) { -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -+ host->thread_isr |= SDHSTS_SDIO_IRPT; -+ result = IRQ_WAKE_THREAD; -+ } -+ -+ unexpected |= (intmask & ~handled); ++ /* There is no true data interrupt status bit, so it is ++ necessary to qualify the data flag with the interrupt ++ enable bit */ ++ if ((intmask & SDHSTS_DATA_FLAG) && ++ (host->hcfg & SDHCFG_DATA_IRPT_EN)) { ++ bcm2835_sdhost_data_irq(host, intmask); ++ result = IRQ_HANDLED; + } + + mmiowb(); + ++ log_event("IRQ>", bcm2835_sdhost_read(host, SDHSTS), 0); + spin_unlock(&host->lock); + -+ if (early) -+ pr_debug("%s: early %x (loops %d)\n", -+ mmc_hostname(host->mmc), early, loops); -+ -+ if (unexpected) { -+ pr_err("%s: unexpected interrupt 0x%08x.\n", -+ mmc_hostname(host->mmc), unexpected); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ + return result; +} + -+static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_host *host = dev_id; -+ unsigned long flags; -+ u32 isr; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ isr = host->thread_isr; -+ host->thread_isr = 0; -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (isr & SDHSTS_SDIO_IRPT) { -+ sdio_run_irqs(host->mmc); -+ -+/* Is this necessary? Why re-enable an interrupt which is enabled? -+ spin_lock_irqsave(&host->lock, flags); -+ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -+ spin_unlock_irqrestore(&host->lock, flags); -+*/ -+ } -+ -+ return isr ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+ -+ +void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) +{ + int div = 0; /* Initialized for compiler warning */ @@ -72737,9 +73020,8 @@ index 0000000..da08998 + pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); + + if ((host->overclock_50 > 50) && -+ (clock == 50*MHZ)) { ++ (clock == 50*MHZ)) + clock = host->overclock_50 * MHZ + (MHZ - 1); -+ } + + /* The SDCDIV register has 11 bits, and holds (div - 2). + But in data mode the max is 50MHz wihout a minimum, and only the @@ -72786,6 +73068,11 @@ index 0000000..da08998 + clock = host->max_clk / (div + 2); + host->mmc->actual_clock = clock; + ++ /* Calibrate some delays */ ++ ++ host->ns_per_fifo_word = (1000000000/clock) * ++ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); ++ + if (clock > input_clock) { + /* Save the closest value, to make it easier + to reduce in the event of error */ @@ -72821,6 +73108,7 @@ index 0000000..da08998 +{ + struct bcm2835_host *host; + unsigned long flags; ++ u32 edm, fsm; + + host = mmc_priv(mmc); + @@ -72841,6 +73129,8 @@ index 0000000..da08998 + } + + /* Reset the error statuses in case this is a retry */ ++ if (mrq->sbc) ++ mrq->sbc->error = 0; + if (mrq->cmd) + mrq->cmd->error = 0; + if (mrq->data) @@ -72856,29 +73146,59 @@ index 0000000..da08998 + return; + } + ++ if (host->use_dma && mrq->data && ++ (mrq->data->blocks > host->pio_limit)) ++ bcm2835_sdhost_prepare_dma(host, mrq->data); ++ + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); -+ + host->mrq = mrq; + -+ if (mrq->sbc) -+ bcm2835_sdhost_send_command(host, mrq->sbc); -+ else -+ bcm2835_sdhost_send_command(host, mrq->cmd); ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ fsm = edm & SDEDM_FSM_MASK; + ++ log_event("REQ<", (u32)mrq, edm); ++ if ((fsm != SDEDM_FSM_IDENTMODE) && ++ (fsm != SDEDM_FSM_DATAMODE)) { ++ pr_err("%s: previous command (%d) not complete (EDM %x)\n", ++ mmc_hostname(host->mmc), ++ bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, ++ edm); ++ log_event("REQ!", (u32)mrq, edm); ++ log_dump(); ++ bcm2835_sdhost_dumpregs(host); ++ mrq->cmd->error = -EILSEQ; ++ tasklet_schedule(&host->finish_tasklet); ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ host->use_sbc = !!mrq->sbc && ++ (host->mrq->data->flags & USE_CMD23_FLAGS); ++ if (host->use_sbc) { ++ if (bcm2835_sdhost_send_command(host, mrq->sbc)) { ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, &flags); ++ } ++ } else if (bcm2835_sdhost_send_command(host, mrq->cmd)) { ++ if (host->data && host->dma_desc) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_start_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, &flags); ++ } ++ ++ log_event("CMD ", (u32)mrq->cmd->opcode, ++ mrq->data ? (u32)mrq->data->blksz : 0); + mmiowb(); ++ ++ log_event("REQ>", (u32)mrq, 0); + spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (!mrq->sbc && mrq->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); +} + -+ +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + @@ -72894,6 +73214,8 @@ index 0000000..da08998 + + spin_lock_irqsave(&host->lock, flags); + ++ log_event("IOS<", ios->clock, 0); ++ + if (!ios->clock || ios->clock != host->clock) { + bcm2835_sdhost_set_clock(host, ios->clock); + host->clock = ios->clock; @@ -72916,44 +73238,53 @@ index 0000000..da08998 + spin_unlock_irqrestore(&host->lock, flags); +} + -+static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -+ unsigned int direction, -+ u32 blk_pos, int blk_size) -+{ -+ /* There is a bug in the host controller hardware that makes -+ reading the final sector of the card as part of a multiple read -+ problematic. Detect that case and shorten the read accordingly. -+ */ -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ -+ return blk_size; -+} -+ -+ +static struct mmc_host_ops bcm2835_sdhost_ops = { + .request = bcm2835_sdhost_request, + .set_ios = bcm2835_sdhost_set_ios, -+ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, + .hw_reset = bcm2835_sdhost_reset, -+ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, +}; + ++static void bcm2835_sdhost_cmd_wait_work(struct work_struct *work) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = container_of(work, struct bcm2835_host, cmd_wait_wq); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ log_event("CWK<", (u32)host->cmd, (u32)host->mrq); ++ ++ /* ++ * If this tasklet gets rescheduled while running, it will ++ * be run again afterwards but without any active request. ++ */ ++ if (!host->mrq) { ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ bcm2835_sdhost_finish_command(host, &flags); ++ ++ mmiowb(); ++ ++ log_event("CWK>", (u32)host->cmd, 0); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} + +static void bcm2835_sdhost_tasklet_finish(unsigned long param) +{ + struct bcm2835_host *host; + unsigned long flags; + struct mmc_request *mrq; ++ struct dma_chan *terminate_chan = NULL; + + host = (struct bcm2835_host *)param; + + spin_lock_irqsave(&host->lock, flags); + ++ log_event("TSK<", (u32)host->mrq, 0); + /* + * If this tasklet gets rescheduled while running, it will + * be run again afterwards but without any active request. @@ -72988,12 +73319,24 @@ index 0000000..da08998 + + mmiowb(); + ++ host->dma_desc = NULL; ++ terminate_chan = host->dma_chan; ++ host->dma_chan = NULL; ++ + spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (terminate_chan) ++ { ++ int err = dmaengine_terminate_all(terminate_chan); ++ if (err) ++ pr_err("%s: failed to terminate DMA (%d)\n", ++ mmc_hostname(host->mmc), err); ++ } ++ + mmc_request_done(host->mmc, mrq); ++ log_event("TSK>", (u32)mrq, 0); +} + -+ -+ +int bcm2835_sdhost_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc; @@ -73014,39 +73357,57 @@ index 0000000..da08998 + mmc->f_max, mmc->f_min, mmc->max_busy_timeout); + + /* host controller capabilities */ -+ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | ++ mmc->caps |= + MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | + MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | -+ (ALLOW_CMD23 * MMC_CAP_CMD23); ++ ((ALLOW_CMD23_READ|ALLOW_CMD23_WRITE) * MMC_CAP_CMD23); + + spin_lock_init(&host->lock); + + if (host->allow_dma) { -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ pr_err("%s: unable to initialise DMA channels. " ++ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { ++ pr_err("%s: unable to initialise DMA channel. " + "Falling back to PIO\n", + mmc_hostname(mmc)); -+ host->have_dma = false; ++ host->use_dma = false; + } else { -+ host->have_dma = true; -+ + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.slave_id = 13; /* DREQ channel */ + ++ /* Validate the slave configurations */ ++ + cfg.direction = DMA_MEM_TO_DEV; + cfg.src_addr = 0; + cfg.dst_addr = host->bus_addr + SDDATA; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); + -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDDATA; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ ++ if (ret == 0) { ++ host->dma_cfg_tx = cfg; ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->bus_addr + SDDATA; ++ cfg.dst_addr = 0; ++ ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ } ++ ++ if (ret == 0) { ++ host->dma_cfg_rx = cfg; ++ ++ host->use_dma = true; ++ } else { ++ pr_err("%s: unable to configure DMA channel. " ++ "Falling back to PIO\n", ++ mmc_hostname(mmc)); ++ dma_release_channel(host->dma_chan_rxtx); ++ host->dma_chan_rxtx = NULL; ++ host->use_dma = false; ++ } + } + } else { -+ host->have_dma = false; ++ host->use_dma = false; + } + + mmc->max_segs = 128; @@ -73061,16 +73422,15 @@ index 0000000..da08998 + tasklet_init(&host->finish_tasklet, + bcm2835_sdhost_tasklet_finish, (unsigned long)host); + ++ INIT_WORK(&host->cmd_wait_wq, bcm2835_sdhost_cmd_wait_work); ++ + setup_timer(&host->timer, bcm2835_sdhost_timeout, + (unsigned long)host); + -+ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ (unsigned long)host); -+ + bcm2835_sdhost_init(host, 0); -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -+ bcm2835_sdhost_thread_irq, -+ IRQF_SHARED, mmc_hostname(mmc), host); ++ ++ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, ++ mmc_hostname(mmc), host); + if (ret) { + pr_err("%s: failed to request IRQ %d: %d\n", + mmc_hostname(mmc), host->irq, ret); @@ -73081,11 +73441,11 @@ index 0000000..da08998 + mmc_add_host(mmc); + + pio_limit_string[0] = '\0'; -+ if (host->have_dma && (host->pio_limit > 0)) ++ if (host->use_dma && (host->pio_limit > 0)) + sprintf(pio_limit_string, " (>%d)", host->pio_limit); + pr_info("%s: %s loaded - DMA %s%s\n", + mmc_hostname(mmc), DRIVER_NAME, -+ host->have_dma ? "enabled" : "disabled", ++ host->use_dma ? "enabled" : "disabled", + pio_limit_string); + + return 0; @@ -73115,8 +73475,11 @@ index 0000000..da08998 + mmc->ops = &bcm2835_sdhost_ops; + host = mmc_priv(mmc); + host->mmc = mmc; ++ host->cmd_quick_poll_retries = 0; + host->pio_timeout = msecs_to_jiffies(500); ++ host->pio_limit = 1; + host->max_delay = 1; /* Warn if over 1ms */ ++ host->allow_dma = 1; + spin_lock_init(&host->lock); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -73132,13 +73495,12 @@ index 0000000..da08998 + return -ENODEV; + } + host->bus_addr = be32_to_cpup(addr); ++ log_init(iomem->start - host->bus_addr); + pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", + (unsigned long)host->ioaddr, + (unsigned long)iomem->start, + (unsigned long)host->bus_addr); + -+ host->allow_dma = ALLOW_DMA; -+ + if (node) { + /* Read any custom properties */ + of_property_read_u32(node, @@ -73150,26 +73512,35 @@ index 0000000..da08998 + of_property_read_u32(node, + "brcm,pio-limit", + &host->pio_limit); -+ host->allow_dma = ALLOW_DMA && ++ host->allow_dma = + !of_property_read_bool(node, "brcm,force-pio"); + host->debug = of_property_read_bool(node, "brcm,debug"); + } + ++ host->dma_chan = NULL; ++ host->dma_desc = NULL; ++ ++ /* Formally recognise the other way of disabling DMA */ ++ if (host->pio_limit == 0x7fffffff) ++ host->allow_dma = false; ++ + if (host->allow_dma) { + if (node) { -+ host->dma_chan_tx = -+ dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = -+ dma_request_slave_channel(dev, "rx"); ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx-tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx"); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ + dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = -+ dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = ++ host->dma_chan_rxtx = + dma_request_channel(mask, NULL, NULL); + } + } @@ -73239,15 +73610,12 @@ index 0000000..da08998 + return 0; +} + -+ +static const struct of_device_id bcm2835_sdhost_match[] = { + { .compatible = "brcm,bcm2835-sdhost" }, + { } +}; +MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); + -+ -+ +static struct platform_driver bcm2835_sdhost_driver = { + .probe = bcm2835_sdhost_probe, + .remove = bcm2835_sdhost_remove, @@ -73264,10 +73632,10 @@ index 0000000..da08998 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From a5a139f18bcc782f2cc3a1de66c936ce2dbb6ffb Mon Sep 17 00:00:00 2001 +From e3dd7794f6746e34aef2cff941ab2a79f3942099 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 034/251] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 035/114] cma: Add vc_cma driver to enable use of CMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -73299,7 +73667,7 @@ Signed-off-by: Noralf Trønnes create mode 100644 include/linux/broadcom/vc_cma.h diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index a043107..2ba2d82 100644 +index 3ec0766..aec9337 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -4,6 +4,8 @@ @@ -74610,10 +74978,10 @@ index 0000000..be2819d + +#endif /* VC_CMA_H */ -From 79708ff24769bfa53cc800dd05f951340829cc5d Mon Sep 17 00:00:00 2001 +From 00dc76905d2070f2f9080fcf0c93a0d94b0826bc Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 035/251] bcm2708: alsa sound driver +Subject: [PATCH 036/114] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -74668,7 +75036,7 @@ Signed-off-by: Noralf Trønnes create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index e040621..7746e5d 100644 +index e040621..7746e5d2 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig @@ -40,5 +40,13 @@ config SND_PXA2XX_AC97 @@ -76500,7 +76868,7 @@ index 0000000..3de3094 +MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c new file mode 100644 -index 0000000..6b545e7 +index 0000000..7a2ed78 --- /dev/null +++ b/sound/arm/bcm2835.c @@ -0,0 +1,511 @@ @@ -76609,7 +76977,7 @@ index 0000000..6b545e7 + numchans); + } + -+ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); ++ err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); + if (err) { + dev_err(dev, "Failed to create soundcard structure\n"); + return err; @@ -76689,7 +77057,7 @@ index 0000000..6b545e7 + if (dev > 0) + goto add_register_map; + -+ err = snd_card_new(NULL, index[dev], id[dev], THIS_MODULE, 0, &g_card); ++ err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE, 0, &g_card); + if (err < 0) + goto out; + @@ -77311,10 +77679,10 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From 522686ae5036c50971853fee0fdb371ed8309222 Mon Sep 17 00:00:00 2001 +From d5ba929f0e3f3ea5bce2e0f10a33492c20a2fd2d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 036/251] bcm2708 vchiq driver +Subject: [PATCH 037/114] bcm2708 vchiq driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -77484,6 +77852,26 @@ vchiq_arm: Sort out the vmalloc case See: https://github.com/raspberrypi/linux/issues/1055 vchiq: hack: Add include depecated dma include file + +vchiq_arm: Tweak the logging output + +Signed-off-by: Phil Elwell + +vchiq_arm: Access the dequeue_pending flag locked + +Reading through this code looking for another problem (now found in userland) +the use of dequeue_pending outside a lock didn't seem safe. + +Signed-off-by: Phil Elwell + +vchiq_arm: Service callbacks must not fail + +Service callbacks are not allowed to return an error. The internal callback +that delivers events and messages to user tasks does not enqueue them if +the service is closing, but this is not an error and should not be +reported as such. + +Signed-off-by: Phil Elwell --- arch/arm/mach-bcm2708/include/mach/platform.h | 2 + arch/arm/mach-bcm2709/include/mach/platform.h | 2 + @@ -77501,13 +77889,13 @@ vchiq: hack: Add include depecated dma include file .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + .../interface/vchiq_arm/vchiq_2835_arm.c | 586 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2903 +++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2910 +++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + .../interface/vchiq_arm/vchiq_connected.c | 120 + .../interface/vchiq_arm/vchiq_connected.h | 50 + - .../vc04_services/interface/vchiq_arm/vchiq_core.c | 3934 ++++++++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_core.c | 3929 ++++++++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 712 ++++ .../interface/vchiq_arm/vchiq_debugfs.c | 383 ++ .../interface/vchiq_arm/vchiq_debugfs.h | 52 + @@ -77522,7 +77910,7 @@ vchiq: hack: Add include depecated dma include file .../vc04_services/interface/vchiq_arm/vchiq_util.c | 156 + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 82 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 37 files changed, 12819 insertions(+) + 37 files changed, 12821 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -77584,10 +77972,10 @@ index 311b9f2..9a638f5 100644 /* * Watchdog diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 22892c7..b859ce0 100644 +index a216b46..90af750 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -533,6 +533,7 @@ source "drivers/misc/lis3lv02d/Kconfig" +@@ -812,6 +812,7 @@ source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" source "drivers/misc/vmw_vmci/Kconfig" @@ -77596,7 +77984,7 @@ index 22892c7..b859ce0 100644 source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 537d7f3..ac24d77 100644 +index b2fb6dbf..1a58cf7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_INTEL_MEI) += mei/ @@ -79794,10 +80182,10 @@ index 0000000..c29040f +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..e11c0e0 +index 0000000..a5cc385 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2903 @@ +@@ -0,0 +1,2910 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -80024,7 +80412,7 @@ index 0000000..e11c0e0 + } else if (instance->closing) { + vchiq_log_info(vchiq_arm_log_level, + "service_callback closing"); -+ return VCHIQ_ERROR; ++ return VCHIQ_SUCCESS; + } + DEBUG_TRACE(SERVICE_CALLBACK_LINE); + } @@ -80079,6 +80467,7 @@ index 0000000..e11c0e0 + USER_SERVICE_T *user_service; + VCHIQ_SERVICE_T *service; + VCHIQ_INSTANCE_T instance; ++ int skip_completion = 0; + DEBUG_INITIALISE(g_state.local) + + DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -80145,9 +80534,6 @@ index 0000000..e11c0e0 + user_service->msg_queue[user_service->msg_insert & + (MSG_QUEUE_SIZE - 1)] = header; + user_service->msg_insert++; -+ spin_unlock(&msg_queue_spinlock); -+ -+ up(&user_service->insert_event); + + /* If there is a thread waiting in DEQUEUE_MESSAGE, or if + ** there is a MESSAGE_AVAILABLE in the completion queue then @@ -80156,13 +80542,22 @@ index 0000000..e11c0e0 + if (((user_service->message_available_pos - + instance->completion_remove) >= 0) || + user_service->dequeue_pending) { -+ DEBUG_TRACE(SERVICE_CALLBACK_LINE); + user_service->dequeue_pending = 0; -+ return VCHIQ_SUCCESS; ++ skip_completion = 1; + } + ++ spin_unlock(&msg_queue_spinlock); ++ ++ up(&user_service->insert_event); ++ + header = NULL; + } ++ ++ if (skip_completion) { ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ return VCHIQ_SUCCESS; ++ } ++ + DEBUG_TRACE(SERVICE_CALLBACK_LINE); + + return add_completion(instance, reason, header, user_service, @@ -83229,10 +83624,10 @@ index 0000000..863b3e3 +#endif /* VCHIQ_CONNECTED_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c new file mode 100644 -index 0000000..2c98da4 +index 0000000..160db24 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -0,0 +1,3934 @@ +@@ -0,0 +1,3929 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -84126,16 +84521,14 @@ index 0000000..2c98da4 + error_count); + return VCHIQ_ERROR; + } -+ if (i == 0) { -+ if (SRVTRACE_ENABLED(service, -+ VCHIQ_LOG_INFO)) -+ vchiq_log_dump_mem("Sent", 0, -+ header->data + pos, -+ min(64u, -+ elements[0].size)); -+ } + } + ++ if (SRVTRACE_ENABLED(service, ++ VCHIQ_LOG_INFO)) ++ vchiq_log_dump_mem("Sent", 0, ++ header->data, ++ min(16, pos)); ++ + spin_lock("a_spinlock); + service_quota->message_use_count++; + @@ -84274,16 +84667,13 @@ index 0000000..2c98da4 + error_count); + return VCHIQ_ERROR; + } -+ if (i == 0) { -+ if (vchiq_sync_log_level >= -+ VCHIQ_LOG_TRACE) -+ vchiq_log_dump_mem("Sent Sync", -+ 0, header->data + pos, -+ min(64u, -+ elements[0].size)); -+ } + } + ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("Sent Sync", ++ 0, header->data, ++ min(16, pos)); ++ + VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); + } else { @@ -84955,7 +85345,7 @@ index 0000000..2c98da4 + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, -+ min(64, size)); ++ min(16, size)); + } + + if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) @@ -85422,7 +85812,7 @@ index 0000000..2c98da4 + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, -+ min(64, size)); ++ min(16, size)); + } + + switch (type) { @@ -90619,10 +91009,10 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From a4ad9bf42376a39e5314f41ecd1ea8fbafb4ca46 Mon Sep 17 00:00:00 2001 +From 62b4dcdac24e9da625a03d47365898e1c57ae1d5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 16:07:06 +0100 -Subject: [PATCH 037/251] vc_mem: Add vc_mem driver +Subject: [PATCH 038/114] vc_mem: Add vc_mem driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -91627,10 +92017,10 @@ index 0000000..20a4753 + +#endif /* _VC_MEM_H */ -From c18ab896c13c1824cdc4c8c544f2576e778d4595 Mon Sep 17 00:00:00 2001 +From 5e3c755951a4886d0e8a7673dabfabd6f0e0a11a Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 038/251] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 039/114] vcsm: VideoCore shared memory service for BCM2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -96046,10 +96436,10 @@ index 0000000..334f36d + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ -From d778ec78cbc50597690495a4767dad44d9329547 Mon Sep 17 00:00:00 2001 +From c3063fdb979a493f5d9bec3535410b807465f82f Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 039/251] Add /dev/gpiomem device for rootless user GPIO access +Subject: [PATCH 040/114] Add /dev/gpiomem device for rootless user GPIO access Signed-off-by: Luke Wren @@ -96360,10 +96750,10 @@ index 0000000..911f5b7 +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); -From 684fa35717d47554b4e019f45e513b58823b50dc Mon Sep 17 00:00:00 2001 +From 51660273781e15d356a98ffdc38671cdde96cf78 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 040/251] Add SMI driver +Subject: [PATCH 041/114] Add SMI driver Signed-off-by: Luke Wren --- @@ -96895,7 +97285,7 @@ index 0000000..d6efd92 + "Character device driver for BCM2835's secondary memory interface"); +MODULE_AUTHOR("Luke Wren "); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index b859ce0..b978ba9 100644 +index 90af750..7011b2d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D @@ -96914,7 +97304,7 @@ index b859ce0..b978ba9 100644 tristate "Analog Devices Digital Potentiometers" depends on (I2C || SPI) && SYSFS diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index ac24d77..1acff5b 100644 +index 1a58cf7..28989fa 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o @@ -98314,18 +98704,18 @@ index 0000000..ee3a75e + +#endif /* BCM2835_SMI_H */ -From d6893b8f68df96a0dd728a1ea8518af748d3de55 Mon Sep 17 00:00:00 2001 +From 4fcf517853295325de2791f6ec1a647c1ec88a53 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 041/251] Add SMI NAND driver +Subject: [PATCH 042/114] Add SMI NAND driver Signed-off-by: Luke Wren --- .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ drivers/mtd/nand/Kconfig | 7 + drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ - 4 files changed, 318 insertions(+) + drivers/mtd/nand/bcm2835_smi_nand.c | 267 +++++++++++++++++++++ + 4 files changed, 317 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c @@ -98379,7 +98769,7 @@ index 0000000..159544d +}; \ No newline at end of file diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 2896640..56ff00b 100644 +index f05e0e9..8c69541 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -41,6 +41,13 @@ config MTD_SM_COMMON @@ -98397,7 +98787,7 @@ index 2896640..56ff00b 100644 tristate diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 2c7f014..30e22f0 100644 +index f553353..ea8d647 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o @@ -98410,10 +98800,10 @@ index 2c7f014..30e22f0 100644 obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c new file mode 100644 -index 0000000..b747326 +index 0000000..02adda6 --- /dev/null +++ b/drivers/mtd/nand/bcm2835_smi_nand.c -@@ -0,0 +1,268 @@ +@@ -0,0 +1,267 @@ +/** + * NAND flash driver for Broadcom Secondary Memory Interface + * @@ -98606,7 +98996,6 @@ index 0000000..b747326 + mtd->owner = THIS_MODULE; + mtd->dev.parent = dev; + mtd->name = DRIVER_NAME; -+ ppdata.of_node = node; + + /* 20 us command delay time... */ + this->chip_delay = 20; @@ -98683,10 +99072,10 @@ index 0000000..b747326 + ("Driver for NAND chips using Broadcom Secondary Memory Interface"); +MODULE_AUTHOR("Luke Wren "); -From 90d547aa8fc1259726f56f404af4ecf9dff6ba0e Mon Sep 17 00:00:00 2001 +From 370d2f9b37ffe70748bbec0a41c59fc1a0f29fb6 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 042/251] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 043/114] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -98771,7 +99160,7 @@ index 5430adf..9e53cd0 100644 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c new file mode 100644 -index 0000000..cd09c99 +index 0000000..0624439 --- /dev/null +++ b/drivers/staging/media/lirc/lirc_rpi.c @@ -0,0 +1,730 @@ @@ -99048,7 +99437,7 @@ index 0000000..cd09c99 + data = PULSE_MASK; /* really long time */ + if (!(signal^sense)) { + /* sanity check */ -+ printk(KERN_WARNING LIRC_DRIVER_NAME ++ printk(KERN_DEBUG LIRC_DRIVER_NAME + ": AIEEEE: %d %d %lx %lx %lx %lx\n", + signal, sense, tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); @@ -99535,10 +99924,10 @@ index 0000000..fb69624 + +#endif -From c220c109c1a18cf786523a205b85a4ebca638624 Mon Sep 17 00:00:00 2001 +From ad8d0254434814507570bf2f39b74e65f041a58c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 043/251] Add cpufreq driver +Subject: [PATCH 044/114] Add cpufreq driver Signed-off-by: popcornmix --- @@ -99549,12 +99938,12 @@ Signed-off-by: popcornmix create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index b1f8a73..930b3ef 100644 +index 14b1f93..c6e8bd5 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -217,6 +217,15 @@ config ARM_SPEAR_CPUFREQ - help - This adds the CPUFreq driver support for SPEAr SOCs. +@@ -229,6 +229,15 @@ config ARM_STI_CPUFREQ + this config option if you wish to add CPUFreq support for STi based + SoCs. +config ARM_BCM2835_CPUFREQ + depends on RASPBERRYPI_FIRMWARE @@ -99569,13 +99958,13 @@ index b1f8a73..930b3ef 100644 bool "Tegra20 CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index c0af1a1..f6a753a 100644 +index 9e63fb1..9e55083 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -73,6 +73,7 @@ obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o - obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o +@@ -74,6 +74,7 @@ obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o + obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o +obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o @@ -99800,10 +100189,10 @@ index 0000000..3eb9e93 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From 1184f7bb9072fe8b453e3c9a71938a16943a708f Mon Sep 17 00:00:00 2001 +From 58567c0d357f8c1311e43791effa972482306217 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 044/251] Added hwmon/thermal driver for reporting core +Subject: [PATCH 045/114] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -99824,10 +100213,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index 8cc4ac6..b273311 100644 +index c37eedc..0705996 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -285,6 +285,13 @@ config INTEL_POWERCLAMP +@@ -292,6 +292,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. @@ -99842,7 +100231,7 @@ index 8cc4ac6..b273311 100644 tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index cfae6a6..b0e336f 100644 +index 8e9cbc3..497014c 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o @@ -100001,10 +100390,10 @@ index 0000000..08d8dc7 +MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); +MODULE_LICENSE("GPL"); -From 418bd7563b83b568046489b0f4b8c67391d31445 Mon Sep 17 00:00:00 2001 +From a61b0d97dc8cd059cb38e51fd0854e6cabec3967 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 045/251] Add Chris Boot's i2c driver +Subject: [PATCH 046/114] Add Chris Boot's i2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100085,15 +100474,17 @@ validity of the chip_select value. i2c-bcm2708: Remove non-DT support Signed-off-by: Noralf Trønnes + +Set the BSC_CLKT clock streching timeout to 35ms as per SMBus specs. --- drivers/i2c/busses/Kconfig | 21 +- drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 493 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 515 insertions(+), 1 deletion(-) + drivers/i2c/busses/i2c-bcm2708.c | 508 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 drivers/i2c/busses/i2c-bcm2708.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 7b0aa82..effadb0 100644 +index faa8e68..2bd4f7f 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" @@ -100146,10 +100537,10 @@ index 37f2819..e309579 100644 diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c new file mode 100644 -index 0000000..85f411c +index 0000000..c9b8e5c --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,493 @@ +@@ -0,0 +1,508 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * @@ -100223,7 +100614,7 @@ index 0000000..85f411c + +#define DRV_NAME "bcm2708_i2c" + -+static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; ++static unsigned int baudrate; +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(baudrate, "The I2C baudrate"); + @@ -100239,6 +100630,7 @@ index 0000000..85f411c + int irq; + struct clk *clk; + u32 cdiv; ++ u32 clk_tout; + + struct completion done; + @@ -100278,7 +100670,7 @@ index 0000000..85f411c + +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) +{ -+ u32 cdiv, s; ++ u32 cdiv, s, clk_tout; + u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; + int wait_loops = I2C_WAIT_LOOP_COUNT; + @@ -100286,12 +100678,14 @@ index 0000000..85f411c + * Use the value that we cached in the probe. + */ + cdiv = bi->cdiv; ++ clk_tout = bi->clk_tout; + + if (bi->msg->flags & I2C_M_RD) + c |= BSC_C_INTR | BSC_C_READ; + else + c |= BSC_C_INTT; + ++ bcm2708_wr(bi, BSC_CLKT, clk_tout); + bcm2708_wr(bi, BSC_DIV, cdiv); + bcm2708_wr(bi, BSC_A, bi->msg->addr); + bcm2708_wr(bi, BSC_DLEN, bi->msg->len); @@ -100464,7 +100858,10 @@ index 0000000..85f411c + struct bcm2708_i2c *bi; + struct i2c_adapter *adap; + unsigned long bus_hz; -+ u32 cdiv; ++ u32 cdiv, clk_tout; ++ u32 baud; ++ ++ baud = CONFIG_I2C_BCM2708_BAUDRATE; + + if (pdev->dev.of_node) { + u32 bus_clk_rate; @@ -100475,12 +100872,15 @@ index 0000000..85f411c + } + if (!of_property_read_u32(pdev->dev.of_node, + "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; ++ baud = bus_clk_rate; + else + dev_warn(&pdev->dev, + "Could not read clock-frequency property\n"); + } + ++ if (baudrate) ++ baud = baudrate; ++ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "could not get IO memory\n"); @@ -100564,15 +100964,21 @@ index 0000000..85f411c + } + + bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; ++ cdiv = bus_hz / baud; + if (cdiv > 0xffff) { + cdiv = 0xffff; -+ baudrate = bus_hz / cdiv; ++ baud = bus_hz / cdiv; + } ++ ++ clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs. ++ if (clk_tout > 0xffff) ++ clk_tout = 0xffff; ++ + bi->cdiv = cdiv; ++ bi->clk_tout = clk_tout; + + dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -+ pdev->id, (unsigned long)regs->start, irq, baudrate); ++ pdev->id, (unsigned long)regs->start, irq, baud); + + return 0; + @@ -100644,10 +101050,10 @@ index 0000000..85f411c +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From 3c15dbca1ea1cf9b6843cb55e2fd01d4701ef874 Mon Sep 17 00:00:00 2001 +From ee6a578174b8f43710c3d897c1b3c74d31b99466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:27:06 +0200 -Subject: [PATCH 046/251] char: broadcom: Add vcio module +Subject: [PATCH 047/114] char: broadcom: Add vcio module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100873,10 +101279,10 @@ index 0000000..c19bc20 +MODULE_DESCRIPTION("Mailbox userspace access"); +MODULE_LICENSE("GPL"); -From 8481c7c7094e5395ab47c8ecc6c7c12d654baf5a Mon Sep 17 00:00:00 2001 +From 44bce7a87a61fc4a18a9b65c9dc1ecfcdc53351d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:25:01 +0200 -Subject: [PATCH 047/251] firmware: bcm2835: Support ARCH_BCM270x +Subject: [PATCH 048/114] firmware: bcm2835: Support ARCH_BCM270x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100982,10 +101388,10 @@ index dd506cd..b980d53 100644 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -From 7e74c5de1a6c613a28ee5a5cc871661ceadd0fcd Mon Sep 17 00:00:00 2001 +From 9c0359b11195a31b974f7b893d9f7c0088816c8c Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 048/251] bcm2835: add v4l2 camera device +Subject: [PATCH 049/114] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -101262,13 +101668,19 @@ are now returned as they are being flushed on stop_streaming. squash: Fixup bcm2835-camera for changes in kernel 4.4 api + +v4l2: Fix up driver to upstream timestamp changes + +bcm2835-camera: fix a bug in computation of frame timestamp + +Fixes #1318 --- Documentation/video4linux/bcm2835-v4l2.txt | 60 + drivers/media/platform/Kconfig | 2 + drivers/media/platform/Makefile | 2 + drivers/media/platform/bcm2835/Kconfig | 25 + drivers/media/platform/bcm2835/Makefile | 5 + - drivers/media/platform/bcm2835/bcm2835-camera.c | 1844 +++++++++++++++++++++ + drivers/media/platform/bcm2835/bcm2835-camera.c | 1845 +++++++++++++++++++++ drivers/media/platform/bcm2835/bcm2835-camera.h | 126 ++ drivers/media/platform/bcm2835/controls.c | 1324 +++++++++++++++ drivers/media/platform/bcm2835/mmal-common.h | 53 + @@ -101280,7 +101692,7 @@ squash: Fixup bcm2835-camera for changes in kernel 4.4 api drivers/media/platform/bcm2835/mmal-parameters.h | 656 ++++++++ drivers/media/platform/bcm2835/mmal-vchiq.c | 1916 ++++++++++++++++++++++ drivers/media/platform/bcm2835/mmal-vchiq.h | 178 ++ - 17 files changed, 6960 insertions(+) + 17 files changed, 6961 insertions(+) create mode 100644 Documentation/video4linux/bcm2835-v4l2.txt create mode 100644 drivers/media/platform/bcm2835/Kconfig create mode 100644 drivers/media/platform/bcm2835/Makefile @@ -101364,7 +101776,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index ccbc974..63c9715 100644 +index 201f5c2..b798ab8 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -101377,7 +101789,7 @@ index ccbc974..63c9715 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index efa0295..8c0b3b5 100644 +index bbb7bd1..6fe5b3f 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -101386,9 +101798,9 @@ index efa0295..8c0b3b5 100644 +obj-$(CONFIG_VIDEO_BCM2835) += bcm2835/ + - obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o + obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig new file mode 100644 index 0000000..99a5cbc @@ -101433,10 +101845,10 @@ index 0000000..f17c79c +ccflags-$(CONFIG_VIDEO_BCM2835) += -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c new file mode 100644 -index 0000000..e83334c +index 0000000..fbf89a2 --- /dev/null +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -0,0 +1,1844 @@ +@@ -0,0 +1,1845 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -101791,6 +102203,7 @@ index 0000000..e83334c + if (dev->capture.frame_count) { + if (dev->capture.vc_start_timestamp != -1 && + pts != 0) { ++ struct timeval timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; + u32 div = 0; @@ -101798,16 +102211,15 @@ index 0000000..e83334c + + div = + div_u64_rem(runtime_us, USEC_PER_SEC, &rem); -+ buf->vb.timestamp.tv_sec = -+ dev->capture.kernel_start_ts.tv_sec - 1 + -+ div; -+ buf->vb.timestamp.tv_usec = ++ timestamp.tv_sec = ++ dev->capture.kernel_start_ts.tv_sec + div; ++ timestamp.tv_usec = + dev->capture.kernel_start_ts.tv_usec + rem; + -+ if (buf->vb.timestamp.tv_usec >= ++ if (timestamp.tv_usec >= + USEC_PER_SEC) { -+ buf->vb.timestamp.tv_sec++; -+ buf->vb.timestamp.tv_usec -= ++ timestamp.tv_sec++; ++ timestamp.tv_usec -= + USEC_PER_SEC; + } + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, @@ -101818,11 +102230,12 @@ index 0000000..e83334c + (int)dev->capture.kernel_start_ts. + tv_usec, + dev->capture.vc_start_timestamp, pts, -+ (int)buf->vb.timestamp.tv_sec, -+ (int)buf->vb.timestamp. -+ tv_usec); ++ (int)timestamp.tv_sec, ++ (int)timestamp.tv_usec); ++ buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + ++ timestamp.tv_usec * 1000ULL; + } else { -+ v4l2_get_timestamp(&buf->vb.timestamp); ++ buf->vb.vb2_buf.timestamp = ktime_get_ns(); + } + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); @@ -106265,7 +106678,7 @@ index 0000000..aa0fd18 +}; diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c new file mode 100644 -index 0000000..7813225 +index 0000000..78132254 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-vchiq.c @@ -0,0 +1,1916 @@ @@ -108370,10 +108783,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 2a1cb83a705ce839581fbabeb9a8db3dad478ccf Mon Sep 17 00:00:00 2001 +From 9889d89cb74b96f8bbaff5a7c451e262af26fbb9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 049/251] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 050/114] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -108838,20 +109251,20 @@ index 0000000..3998d43 + return (($val eq 'y') || ($val eq '1')); +} -From 3c9e2867950ad9a36623e07c2d1641445bab50dd Mon Sep 17 00:00:00 2001 +From c962a4d9204d97b1b62ab32f274c22bac54ad8d5 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 050/251] fdt: Add support for the CONFIG_CMDLINE_EXTEND option +Subject: [PATCH 051/114] fdt: Add support for the CONFIG_CMDLINE_EXTEND option --- drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 655f79d..fdc4501 100644 +index 3349d2a..1e26605 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c -@@ -954,19 +954,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, +@@ -960,19 +960,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, /* Retrieve command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); @@ -108896,10 +109309,10 @@ index 655f79d..fdc4501 100644 pr_debug("Command line is: %s\n", (char*)data); -From 336ecbfbddc122378578b727f46bfe71858aaa05 Mon Sep 17 00:00:00 2001 +From 829ab8a2cb98b039ceba5b4407522442ef629ba0 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 051/251] BCM2708: Add core Device Tree support +Subject: [PATCH 052/114] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -108965,62 +109378,89 @@ squash: Add cprman to dt BCM270X_DT: Use clk_core for I2C interfaces --- - arch/arm/boot/dts/Makefile | 30 + - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 145 +++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 135 +++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 102 ++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 40 ++ - arch/arm/boot/dts/bcm2708.dtsi | 40 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 347 +++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 145 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 102 ++++ - arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 +++ - arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + - arch/arm/boot/dts/overlays/Makefile | 69 +++ - arch/arm/boot/dts/overlays/README | 648 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 +++ - .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + - arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 ++ - .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++ - .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ - .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 +++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 55 ++ - arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + - arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 +++ - arch/arm/boot/dts/overlays/mmc-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 111 ++++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 +++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 ++++ - arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++ - arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++ - arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++ - arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 +++ - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + - arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 29 + - arch/arm/boot/dts/overlays/sdio-overlay.dts | 32 + - arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + - arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 +++ - arch/arm/boot/dts/overlays/smi-overlay.dts | 37 ++ - .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++ - arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++ - arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ - .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - 55 files changed, 4203 insertions(+) + arch/arm/boot/dts/Makefile | 31 + + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 150 +++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 140 +++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 102 ++ + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 52 + + arch/arm/boot/dts/bcm2708.dtsi | 40 + + arch/arm/boot/dts/bcm2708_common.dtsi | 379 ++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 150 +++ + arch/arm/boot/dts/bcm2709.dtsi | 102 ++ + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 197 ++++ + arch/arm/boot/dts/bcm2710.dtsi | 102 ++ + arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 ++ + arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/overlays/Makefile | 88 ++ + arch/arm/boot/dts/overlays/README | 1014 ++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 89 ++ + arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 57 ++ + .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 + + arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 20 + + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 29 + + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 53 + + arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 45 + + .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 + + .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 + + .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 + + .../dts/overlays/hifiberry-dacplus-overlay.dts | 54 ++ + .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 + + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 93 ++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 148 +++ + arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 28 + + .../boot/dts/overlays/i2c-mux-pca9548a-overlay.dts | 67 ++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 63 ++ + .../arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 36 + + .../arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 37 + + arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 + + .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 43 + + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ + .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 73 ++ + .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 73 ++ + arch/arm/boot/dts/overlays/mmc-overlay.dts | 38 + + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 117 +++ + arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 27 + + .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 46 + + .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 64 ++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 102 ++ + arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 106 ++ + .../dts/overlays/pitft28-capacitive-overlay.dts | 91 ++ + .../dts/overlays/pitft28-resistive-overlay.dts | 121 +++ + arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 + + arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 53 + + arch/arm/boot/dts/overlays/pwm-overlay.dts | 49 + + arch/arm/boot/dts/overlays/qca7000-overlay.dts | 52 + + arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 + + .../boot/dts/overlays/rpi-backlight-overlay.dts | 21 + + arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 + + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 89 ++ + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 + + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 + + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 32 + + arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts | 36 + + arch/arm/boot/dts/overlays/sdio-overlay.dts | 36 + + arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 23 + + arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + + arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/smi-overlay.dts | 37 + + .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + + arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 57 ++ + arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 81 ++ + arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 57 ++ + arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 81 ++ + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 222 +++++ + arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 + + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 95 ++ + arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 + + .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 + + arch/arm/boot/dts/overlays/wittypi-overlay.dts | 44 + + 82 files changed, 6392 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -109029,14 +109469,20 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b.dts + create mode 100644 arch/arm/boot/dts/bcm2710.dtsi create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dts create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dtsi create mode 100644 arch/arm/boot/dts/overlays/Makefile create mode 100644 arch/arm/boot/dts/overlays/README create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dwc-otg-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dwc2-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts @@ -109044,7 +109490,11 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts @@ -109053,34 +109503,51 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/qca7000-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/wittypi-overlay.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 30bbc37..d583e67 100644 +index 95c1923..a4db123 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,25 @@ +@@ -1,5 +1,26 @@ ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-b.dtb @@ -109088,6 +109555,7 @@ index 30bbc37..d583e67 100644 +dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-cm.dtb +dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb +dtb-$(CONFIG_ARCH_BCM2709) += bcm2709-rpi-2-b.dtb ++dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb + +# Raspberry Pi +ifeq ($(CONFIG_ARCH_BCM2708),y) @@ -109105,8 +109573,8 @@ index 30bbc37..d583e67 100644 + dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb - dtb-$(CONFIG_MACH_ASM9260) += \ -@@ -777,10 +797,20 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + dtb-$(CONFIG_MACH_ARTPEC6) += \ +@@ -839,10 +860,20 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb @@ -109129,10 +109597,10 @@ index 30bbc37..d583e67 100644 +endif diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts new file mode 100644 -index 0000000..2e4df17 +index 0000000..0e9a22d --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,145 @@ +@@ -0,0 +1,150 @@ +/dts-v1/; + +#include "bcm2708.dtsi" @@ -109194,7 +109662,7 @@ index 0000000..2e4df17 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109202,7 +109670,7 @@ index 0000000..2e4df17 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109255,6 +109723,7 @@ index 0000000..2e4df17 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109276,14 +109745,18 @@ index 0000000..2e4df17 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts new file mode 100644 -index 0000000..0445b46 +index 0000000..a60342c --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,135 @@ +@@ -0,0 +1,140 @@ +/dts-v1/; + +#include "bcm2708.dtsi" @@ -109345,7 +109818,7 @@ index 0000000..0445b46 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109353,7 +109826,7 @@ index 0000000..0445b46 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109400,6 +109873,7 @@ index 0000000..0445b46 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109417,11 +109891,15 @@ index 0000000..0445b46 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts new file mode 100755 -index 0000000..87c1a54 +index 0000000..cd0e1ac --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -0,0 +1,102 @@ @@ -109469,7 +109947,7 @@ index 0000000..87c1a54 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109477,7 +109955,7 @@ index 0000000..87c1a54 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109516,6 +109994,7 @@ index 0000000..87c1a54 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109524,15 +110003,14 @@ index 0000000..87c1a54 + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi new file mode 100644 -index 0000000..3c8bdde +index 0000000..90e330d --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,40 @@ +@@ -0,0 +1,52 @@ +#include "bcm2708.dtsi" + +&gpio { @@ -109542,6 +110020,13 @@ index 0000000..3c8bdde + }; +}; + ++&gpio { ++ mmc_pins: mmc_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <7>; /* alt3 */ ++ }; ++}; ++ +&leds { + act_led: act { + label = "led0"; @@ -109550,12 +110035,14 @@ index 0000000..3c8bdde + }; +}; + -+&sdhost { ++ ++&mmc { + pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ bus-width = <4>; ++ pinctrl-0 = <&mmc_pins>; + non-removable; ++ bus-width = <4>; + status = "okay"; ++ brcm,overclock-50 = <0>; +}; + +&fb { @@ -109564,6 +110051,8 @@ index 0000000..3c8bdde + +/ { + __overrides__ { ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; @@ -109571,6 +110060,7 @@ index 0000000..3c8bdde + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&mmc>,"brcm,overclock-50:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi @@ -109621,10 +110111,11 @@ index 0000000..f5a44cd +}; diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi new file mode 100644 -index 0000000..75fb4ce +index 0000000..e0be77a --- /dev/null +++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,347 @@ +@@ -0,0 +1,379 @@ ++#include +#include "skeleton.dtsi" + +/ { @@ -109632,6 +110123,7 @@ index 0000000..75fb4ce + + aliases { + audio = &audio; ++ aux = &aux; + sound = &sound; + soc = &soc; + dma = &dma; @@ -109646,6 +110138,8 @@ index 0000000..75fb4ce + spi0 = &spi0; + i2c0 = &i2c0; + uart1 = &uart1; ++ spi1 = &spi1; ++ spi2 = &spi2; + mmc = &mmc; + i2c1 = &i2c1; + i2c2 = &i2c2; @@ -109759,9 +110253,9 @@ index 0000000..75fb4ce + reg = <0x7e202000 0x100>; + interrupts = <2 24>; + clocks = <&clk_core>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; ++ dmas = <&dma 13>; ++ dma-names = "rx-tx"; ++ brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; + status = "disabled"; + }; @@ -109812,6 +110306,14 @@ index 0000000..75fb4ce + status = "disabled"; + }; + ++ aux: aux@0x7e215004 { ++ compatible = "brcm,bcm2835-aux"; ++ #clock-cells = <1>; ++ reg = <0x7e215000 0x8>; ++ clocks = <&clk_core>; ++ status = "disabled"; ++ }; ++ + uart1: uart@7e215040 { + compatible = "brcm,bcm2835-aux-uart", "ns16550"; + reg = <0x7e215040 0x40>; @@ -109820,16 +110322,36 @@ index 0000000..75fb4ce + reg-shift = <2>; + no-loopback-test; + status = "disabled"; -+ }; ++ }; ++ ++ spi1: spi@7e215080 { ++ compatible = "brcm,bcm2835-aux-spi"; ++ reg = <0x7e215080 0x40>, <0x7e215000 0x8>; ++ interrupts = <1 29>; ++ clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi2: spi@7e2150C0 { ++ compatible = "brcm,bcm2835-aux-spi"; ++ reg = <0x7e2150C0 0x40>, <0x7e215000 0x8>; ++ interrupts = <1 29>; ++ clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; + + mmc: mmc@7e300000 { + compatible = "brcm,bcm2835-mmc"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; ++ dmas = <&dma 11>; ++ dma-names = "rx-tx"; ++ brcm,overclock-50 = <0>; + status = "disabled"; + }; + @@ -109974,10 +110496,10 @@ index 0000000..75fb4ce +}; diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..5206ba2 +index 0000000..9176d57 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,145 @@ +@@ -0,0 +1,150 @@ +/dts-v1/; + +#include "bcm2709.dtsi" @@ -110039,7 +110561,7 @@ index 0000000..5206ba2 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -110047,7 +110569,7 @@ index 0000000..5206ba2 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -110100,6 +110622,7 @@ index 0000000..5206ba2 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -110121,6 +110644,10 @@ index 0000000..5206ba2 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi @@ -110231,6 +110758,317 @@ index 0000000..a8cfd7c + interrupt-parent = <&local_intc>; + interrupts = <8>; +}; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +new file mode 100644 +index 0000000..adba682 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -0,0 +1,197 @@ ++/dts-v1/; ++ ++#include "bcm2710.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2710","brcm,bcm2709"; ++ model = "Raspberry Pi 3 Model B"; ++}; ++ ++&gpio { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <7>; // alt3 = SD1 ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = <43>; ++ brcm,function = <4>; /* alt0:GPCLK2 */ ++ brcm,pull = <0>; ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <32 33>; ++ brcm,function = <7>; /* alt3=UART0 */ ++ brcm,pull = <0 2>; ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++}; ++ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <4>; ++ status = "okay"; ++ brcm,overclock-50 = <0>; ++}; ++ ++&soc { ++ virtgpio: virtgpio { ++ compatible = "brcm,bcm2835-virtgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&random { ++ status = "okay"; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&virtgpio 0 0>; ++ }; ++}; ++ ++/ { ++ chosen { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi +new file mode 100644 +index 0000000..1a48686 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -0,0 +1,102 @@ ++#include "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2710","brcm,bcm2709"; ++ model = "BCM2710"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x3f000000 0x01000000>, ++ <0x40000000 0x40000000 0x00040000>; ++ ++ 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>; ++ }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ clock-frequency = <19200000>; ++ interrupt-parent = <&local_intc>; ++ interrupts = <0>, // PHYS_SECURE_PPI ++ <1>, // PHYS_NONSECURE_PPI ++ <3>, // VIRT_PPI ++ <2>; // HYP_PPI ++ always-on; ++ }; ++ ++ syscon@40000000 { ++ compatible = "brcm,bcm2836-arm-local", "syscon"; ++ reg = <0x40000000 0x100>; ++ }; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ v7_cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x000>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x001>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x002>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x003>; ++ clock-frequency = <800000000>; ++ }; ++ }; ++ ++ __overrides__ { ++ arm_freq = <&v7_cpu0>, "clock-frequency:0", ++ <&v7_cpu1>, "clock-frequency:0", ++ <&v7_cpu2>, "clock-frequency:0", ++ <&v7_cpu3>, "clock-frequency:0"; ++ }; ++}; ++ ++&watchdog { ++ status = "okay"; ++}; ++ ++&intc { ++ compatible = "brcm,bcm2836-armctrl-ic"; ++ interrupt-parent = <&local_intc>; ++ interrupts = <8>; ++}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dts b/arch/arm/boot/dts/bcm2835-rpi-cm.dts new file mode 100644 index 0000000..c6e6860 @@ -110368,10 +111206,10 @@ index 0000000..9c4000f +}; diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile new file mode 100644 -index 0000000..d8c2771 +index 0000000..7c4fc30 --- /dev/null +++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,69 @@ +@@ -0,0 +1,88 @@ +ifeq ($(CONFIG_OF),y) + +# Overlays for the Raspberry Pi platform @@ -110386,67 +111224,86 @@ index 0000000..d8c2771 + RPI_DT_OVERLAYS=y +endif + -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb ++dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += enc28j60.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += gpio-ir.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += gpio-poweroff.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dacplus.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += lirc-rpi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-act-led.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += piscreen2r.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pitft28-capacitive.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += qca7000.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-display.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-ft5406.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-proto.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-sense.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdhost.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdtweak.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi-dev.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi-nand.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-1cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-2cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-3cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-1cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-2cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-3cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi-gpio35-39.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += tinylcd35.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += uart1.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += wittypi.dtbo + +targets += dtbs dtbs_install -+targets += $(dtb-y) ++targets += $(dtbo-y) + +endif + -+always := $(dtb-y) -+clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif ++always := $(dtbo-y) ++clean-files := *.dtbo diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README new file mode 100644 -index 0000000..268d400 +index 0000000..e88e7c8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,648 @@ +@@ -0,0 +1,1014 @@ +Introduction +============ + @@ -110502,8 +111359,8 @@ index 0000000..268d400 +Using Overlays +============== + -+Overlays are loaded using the "dtoverlay" directive. As an example, consider the -+popular lirc-rpi module, the Linux Infrared Remote Control driver. In the ++Overlays are loaded using the "dtoverlay" directive. As an example, consider ++the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the +pre-DT world this would be loaded from /etc/modules, with an explicit +"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, +this becomes a line in config.txt: @@ -110518,71 +111375,87 @@ index 0000000..268d400 + +Parameters always have default values, although in some cases (e.g. "w1-gpio") +it is necessary to provided multiple overlays in order to get the desired -+behaviour. See the list of overlays below for a description of the parameters and their defaults. ++behaviour. See the list of overlays below for a description of the parameters ++and their defaults. + +The Overlay and Parameter Reference +=================================== + -+N.B. When editing this file, please preserve the indentation levels to make it simple to parse -+programmatically. NO HARD TABS. ++N.B. When editing this file, please preserve the indentation levels to make it ++simple to parse programmatically. NO HARD TABS. + + +Name: +Info: Configures the base Raspberry Pi hardware +Load: +Params: -+ audio Set to "on" to enable the onboard ALSA audio -+ interface (default "off") ++ audio Set to "on" to enable the onboard ALSA audio ++ interface (default "off") + -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") ++ i2c_arm Set to "on" to enable the ARM's i2c interface ++ (default "off") + -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") ++ i2c_vc Set to "on" to enable the i2c interface ++ usually reserved for the VideoCore processor ++ (default "off") + -+ i2c An alias for i2c_arm ++ i2c An alias for i2c_arm + -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") ++ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface ++ (default "100000") + -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") ++ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface ++ (default "100000") + -+ i2c_baudrate An alias for i2c_arm_baudrate ++ i2c_baudrate An alias for i2c_arm_baudrate + -+ i2s Set to "on" to enable the i2s interface -+ (default "off") ++ i2s Set to "on" to enable the i2s interface ++ (default "off") + -+ spi Set to "on" to enable the spi interfaces -+ (default "off") ++ spi Set to "on" to enable the spi interfaces ++ (default "off") + -+ random Set to "on" to enable the hardware random -+ number generator (default "on") ++ random Set to "on" to enable the hardware random ++ number generator (default "on") + -+ uart0 Set to "off" to disable uart0 (default "on") ++ sd_overclock Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ watchdog Set to "on" to enable the hardware watchdog -+ (default "off") ++ sd_force_pio Disable DMA support for SD driver (default off) + -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") ++ sd_pio_limit Number of blocks above which to use DMA for ++ SD card (default 1) + -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") ++ sd_debug Enable debug output from SD driver (default off) + -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) ++ uart0 Set to "off" to disable uart0 (default "on") ++ ++ uart1 Set to "on" or "off" to enable or disable uart1 ++ (default varies) ++ ++ watchdog Set to "on" to enable the hardware watchdog ++ (default "off") ++ ++ act_led_trigger Choose which activity the LED tracks. ++ Use "heartbeat" for a nice load indicator. ++ (default "mmc") ++ ++ act_led_activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ N.B. For Pi3 see pi3-act-led overlay. ++ ++ act_led_gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ (default "16" on a non-Plus board, "47" on a ++ Plus or Pi 2) ++ N.B. For Pi3 see pi3-act-led overlay. + + pwr_led_trigger + pwr_led_activelow + pwr_led_gpio -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. ++ As for act_led_*, but using the PWR LED. ++ Not available on Model A/B boards. + + N.B. It is recommended to only enable those interfaces that are needed. + Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc @@ -110597,19 +111470,19 @@ index 0000000..268d400 +Name: ads7846 +Info: ADS7846 Touch controller +Load: dtoverlay=ads7846,= -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) ++Params: cs SPI bus Chip Select (default 1) ++ speed SPI bus speed (default 2MHz, max 3.25MHz) ++ penirq GPIO used for PENIRQ. REQUIRED ++ penirq_pull Set GPIO pull (default 0=none, 2=pullup) ++ swapxy Swap x and y axis ++ xmin Minimum value on the X axis (default 0) ++ ymin Minimum value on the Y axis (default 0) ++ xmax Maximum value on the X axis (default 4095) ++ ymax Maximum value on the Y axis (default 4095) ++ pmin Minimum reported pressure value (default 0) ++ pmax Maximum reported pressure value (default 65535) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ (default 400) + + penirq is required and usually xohms (60-100) has to be set as well. + Apart from that, pmax (255) and swapxy are also common. @@ -110619,6 +111492,18 @@ index 0000000..268d400 + www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt + + ++Name: at86rf233 ++Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, ++ connected to spi0.0 ++Load: dtoverlay=at86rf233,= ++Params: interrupt GPIO used for INT (default 23) ++ reset GPIO used for Reset (default 24) ++ sleep GPIO used for Sleep (default 25) ++ speed SPI bus speed in Hz (default 3000000) ++ trim Fine tuning of the internal capacitance ++ arrays (0=+0pF, 15=+4.5pF, default 15) ++ ++ +Name: bmp085_i2c-sensor +Info: Configures the BMP085/BMP180 digital barometric pressure and temperature + sensors from Bosch Sensortec @@ -110630,8 +111515,29 @@ index 0000000..268d400 +Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors + Also sometimes found with the part number(s) AM230x. +Load: dtoverlay=dht11,= -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) ++Params: gpiopin GPIO connected to the sensor's DATA output. ++ (default 4) ++ ++ ++Name: dwc-otg ++Info: Selects the dwc_otg USB controller driver which has fiq support. This ++ is the default on all except the Pi Zero which defaults to dwc2. ++Load: dtoverlay=dwc-otg ++Params: ++ ++ ++Name: dwc2 ++Info: Selects the dwc2 USB controller driver ++Load: dtoverlay=dwc2,= ++Params: dr_mode Dual role mode: "host", "peripheral" or "otg" ++ ++ g-rx-fifo-size Size of rx fifo size in gadget mode ++ ++ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget ++ mode ++ ++ g-tx-fifo-size Size of periodic tx fifo per endpoint ++ (except ep0) in gadget mode + + +[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] @@ -110640,22 +111546,38 @@ index 0000000..268d400 +Name: enc28j60 +Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) +Load: dtoverlay=enc28j60,= -+Params: int_pin GPIO used for INT (default 25) ++Params: int_pin GPIO used for INT (default 25) + -+ speed SPI bus speed (default 12000000) ++ speed SPI bus speed (default 12000000) ++ ++ ++Name: gpio-ir ++Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- ++ based gpio_ir_recv driver maps received keys directly to a ++ /dev/input/event* device, all decoding is done by the kernel - LIRC is ++ not required! The key mapping and other decoding parameters can be ++ configured by "ir-keytable" tool. ++Load: dtoverlay=gpio-ir,= ++Params: gpio_pin Input pin number. Default is 18. ++ ++ gpio_pull Desired pull-up/down state (off, down, up) ++ Default is "down". ++ ++ rc-map-name Default rc keymap (can also be changed by ++ ir-keytable), defaults to "rc-rc6-mce" + + +Name: gpio-poweroff +Info: Drives a GPIO high or low on reboot +Load: dtoverlay=gpio-poweroff,= -+Params: gpiopin GPIO for signalling (default 26) ++Params: gpiopin GPIO for signalling (default 26) + -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. ++ active_low Set if the power control device requires a ++ high->low transition to trigger a power-down. ++ Note that this will require the support of a ++ custom dt-blob.bin to prevent a power-down ++ during the boot process, and that a reboot ++ will also cause the pin to go low. + + +Name: hifiberry-amp @@ -110672,8 +111594,21 @@ index 0000000..268d400 + +Name: hifiberry-dacplus +Info: Configures the HifiBerry DAC+ audio card -+Load: dtoverlay=hifiberry-dacplus -+Params: ++Load: dtoverlay=hifiberry-dacplus,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24dB_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) + + +Name: hifiberry-digi @@ -110686,54 +111621,91 @@ index 0000000..268d400 +Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28a,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + -+ resetgpio GPIO used to reset controller ++ resetgpio GPIO used to reset controller + -+ ledgpio GPIO used to control backlight ++ ledgpio GPIO used to control backlight + + +Name: hy28b +Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28b,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + -+ resetgpio GPIO used to reset controller ++ resetgpio GPIO used to reset controller + -+ ledgpio GPIO used to control backlight ++ ledgpio GPIO used to control backlight ++ ++ ++Name: i2c-gpio ++Info: Adds support for software i2c controller on gpio pins ++Load: dtoverlay=i2c-gpio,= ++Params: i2c_gpio_sda GPIO used for I2C data (default "23") ++ ++ i2c_gpio_scl GPIO used for I2C clock (default "24") ++ ++ i2c_gpio_delay_us Clock delay in microseconds ++ (default "2" = ~100kHz) ++ ++ ++Name: i2c-mux-pca9548a ++Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm ++Load: dtoverlay=i2c-mux-pca9548a,= ++Params: addr I2C address of PCA9548A (default 0x70) + + +Name: i2c-rtc +Info: Adds support for a number of I2C Real Time Clock devices -+Load: dtoverlay=i2c-rtc, -+Params: ds1307 Select the DS1307 device ++Load: dtoverlay=i2c-rtc,= ++Params: ds1307 Select the DS1307 device + -+ ds3231 Select the DS3231 device ++ ds1339 Select the DS1339 device + -+ mcp7941x Select the MCP7941x device ++ ds3231 Select the DS3231 device + -+ pcf2127 Select the PCF2127 device ++ mcp7941x Select the MCP7941x device + -+ pcf8523 Select the PCF8523 device ++ pcf2127 Select the PCF2127 device + -+ pcf8563 Select the PCF8563 device ++ pcf8523 Select the PCF8523 device ++ ++ pcf8563 Select the PCF8563 device ++ ++ trickle-resistor-ohms Resistor value for trickle charge (DS1339-only) ++ ++ ++Name: i2c0-bcm2708 ++Info: Enable the i2c_bcm2708 driver for the i2c0 bus ++Load: dtoverlay=i2c0-bcm2708,= ++Params: sda0_pin GPIO pin for SDA0 (0, 28 [or 44] - default 0) ++ scl0_pin GPIO pin for SCL0 (1, 29 [or 45] - default 1) ++ ++ ++Name: i2c1-bcm2708 ++Info: Enable the i2c_bcm2708 driver for the i2c1 bus ++Load: dtoverlay=i2c1-bcm2708,= ++Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) ++ scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) ++ pin_func Alternative pin function (4 (alt0), 6 (alt2) - ++ default 4) + + +Name: i2s-mmap @@ -110750,78 +111722,90 @@ index 0000000..268d400 + +Name: iqaudio-dacplus +Info: Configures the IQaudio DAC+ audio card -+Load: dtoverlay=iqaudio-dacplus -+Params: ++Load: dtoverlay=iqaudio-dacplus,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=iqaudio-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24db_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) + + +Name: lirc-rpi +Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) + Consult the module documentation for more details. -+Load: dtoverlay=lirc-rpi,=,... -+Params: gpio_out_pin GPIO for output (default "17") ++Load: dtoverlay=lirc-rpi,= ++Params: gpio_out_pin GPIO for output (default "17") + -+ gpio_in_pin GPIO for input (default "18") ++ gpio_in_pin GPIO for input (default "18") + -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") ++ gpio_in_pull Pull up/down/off on the input pin ++ (default "down") + -+ sense Override the IR receive auto-detection logic: -+ "0" = force active-high -+ "1" = force active-low -+ "-1" = use auto-detection -+ (default "-1") ++ sense Override the IR receive auto-detection logic: ++ "0" = force active-high ++ "1" = force active-low ++ "-1" = use auto-detection ++ (default "-1") + -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") ++ softcarrier Turn the software carrier "on" or "off" ++ (default "on") + -+ invert "on" = invert the output pin (default "off") ++ invert "on" = invert the output pin (default "off") + -+ debug "on" = enable additional debug messages -+ (default "off") ++ debug "on" = enable additional debug messages ++ (default "off") + + +Name: mcp2515-can0 +Info: Configures the MCP2515 CAN controller on spi0.0 +Load: dtoverlay=mcp2515-can0,= -+Params: oscillator Clock frequency for the CAN controller (Hz) ++Params: oscillator Clock frequency for the CAN controller (Hz) + -+ spimaxfrequency Maximum SPI frequence (Hz) ++ spimaxfrequency Maximum SPI frequence (Hz) + -+ interrupt GPIO for interrupt signal ++ interrupt GPIO for interrupt signal + + +Name: mcp2515-can1 +Info: Configures the MCP2515 CAN controller on spi0.1 +Load: dtoverlay=mcp2515-can1,= -+Params: oscillator Clock frequency for the CAN controller (Hz) ++Params: oscillator Clock frequency for the CAN controller (Hz) + -+ spimaxfrequency Maximum SPI frequence (Hz) ++ spimaxfrequency Maximum SPI frequence (Hz) + -+ interrupt GPIO for interrupt signal ++ interrupt GPIO for interrupt signal + + +Name: mmc +Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock +Load: dtoverlay=mmc,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz + + +Name: mz61581 +Info: MZ61581 display by Tontec +Load: dtoverlay=mz61581,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ txbuflen Transmit buffer length (default 32768) ++ txbuflen Transmit buffer length (default 32768) + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + + +[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] @@ -110833,36 +111817,109 @@ index 0000000..268d400 +[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] + + ++Name: pi3-act-led ++Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed ++ from the VPU. There is a special driver for this with a separate DT ++ node, which has the unfortunate consequence of breaking the ++ act_led_gpio and act_led_activelow dtparams. ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++Load: dtoverlay=pi3-act-led,= ++Params: activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ ++ gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ REQUIRED ++ ++ ++Name: pi3-disable-bt ++Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 ++ N.B. To disable the systemd service that initialises the modem so it ++ doesn't use the UART, use 'sudo systemctl disable hciuart'. ++Load: dtoverlay=pi3-disable-bt ++Params: ++ ++ ++Name: pi3-miniuart-bt ++Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore ++ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum ++ usable baudrate. ++ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service ++ and replace ttyAMA0 with ttyS0, unless you have a system with udev rules ++ that create /dev/serial0 and /dev/serial1, in which case use ++ /dev/serial1 instead because it will always be correct. ++Load: dtoverlay=pi3-miniuart-bt ++Params: ++ ++ +Name: piscreen +Info: PiScreen display by OzzMaker.com +Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: piscreen2r ++Info: PiScreen 2 with resistive TP display by OzzMaker.com ++Load: dtoverlay=piscreen2r,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: pitft28-capacitive ++Info: Adafruit PiTFT 2.8" capacitive touch screen ++Load: dtoverlay=pitft28-capacitive,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ touch-sizex Touchscreen size x (default 240) ++ ++ touch-sizey Touchscreen size y (default 320) ++ ++ touch-invx Touchscreen inverted x axis ++ ++ touch-invy Touchscreen inverted y axis ++ ++ touch-swapxy Touchscreen swapped x y axis + + +Name: pitft28-resistive +Info: Adafruit PiTFT 2.8" resistive touch screen +Load: dtoverlay=pitft28-resistive,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + + +Name: pps-gpio +Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). +Load: dtoverlay=pps-gpio,= -+Params: gpiopin Input GPIO (default "18") ++Params: gpiopin Input GPIO (default "18") + + +Name: pwm @@ -110879,9 +111936,9 @@ index 0000000..268d400 + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm,= -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) ++Params: pin Output pin (default 18) - see table ++ func Pin function (default 2 = Alt5) - see above ++ clock PWM clock frequency (informational) + + +Name: pwm-2chan @@ -110898,11 +111955,19 @@ index 0000000..268d400 + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm-2chan,= -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) ++Params: pin Output pin (default 18) - see table ++ pin2 Output pin for other channel (default 19) ++ func Pin function (default 2 = Alt5) - see above ++ func2 Function for pin2 (default 2 = Alt5) ++ clock PWM clock frequency (informational) ++ ++ ++Name: qca7000 ++Info: I2SE's Evaluation Board for PLC Stamp micro ++Load: dtoverlay=qca7000,= ++Params: int_pin GPIO pin for interrupt signal (default 23) ++ ++ speed SPI bus speed (default 12 MHz) + + +Name: raspidac3 @@ -110911,6 +111976,12 @@ index 0000000..268d400 +Params: + + ++Name: rpi-backlight ++Info: Raspberry Pi official display backlight driver ++Load: dtoverlay=rpi-backlight ++Params: ++ ++ +Name: rpi-dac +Info: Configures the RPi DAC audio card +Load: dtoverlay=rpi-dac @@ -110920,15 +111991,12 @@ index 0000000..268d400 +Name: rpi-display +Info: RPi-Display - 2.8" Touch Display by Watterott +Load: dtoverlay=rpi-display,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) ++Params: speed Display SPI bus speed ++ rotate Display rotation {0,90,180,270} ++ fps Delay between frame updates ++ debug Debug output level {0-7} ++ xohms Touchpanel sensitivity (X-plate resistance) ++ swapxy Swap x and y axis + + +Name: rpi-ft5406 @@ -110952,33 +112020,73 @@ index 0000000..268d400 +Name: sdhost +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock +Load: dtoverlay=sdhost,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ force_pio Disable DMA support (default off) ++ force_pio Disable DMA support (default off) + -+ pio_limit Number of blocks above which to use DMA -+ (default 1) ++ pio_limit Number of blocks above which to use DMA ++ (default 1) + -+ debug Enable debug output (default off) ++ debug Enable debug output (default off) + + +Name: sdio +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, + and enables SDIO via GPIOs 22-27. +Load: dtoverlay=sdio,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz ++Params: overclock_50 SD Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ force_pio Disable DMA support (default off) ++ sdio_overclock SDIO Clock (in MHz) to use when the MMC ++ framework requests 50MHz + -+ pio_limit Number of blocks above which to use DMA -+ (default 1) ++ force_pio Disable DMA support (default off) + -+ debug Enable debug output (default off) ++ pio_limit Number of blocks above which to use DMA ++ (default 1) + -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) ++ debug Enable debug output (default off) ++ ++ poll_once Disable SDIO-device polling every second ++ (default on: polling once at boot-time) ++ ++ bus_width Set the SDIO host bus width (default 4 bits) ++ ++ ++Name: sdio-1bit ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, ++ and enables 1-bit SDIO via GPIOs 22-25. ++Load: dtoverlay=sdio-1bit,= ++Params: overclock_50 SD Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ sdio_overclock SDIO Clock (in MHz) to use when the MMC ++ framework requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ poll_once Disable SDIO-device polling every second ++ (default on: polling once at boot-time) ++ ++ ++Name: sdtweak ++Info: Tunes the bcm2835-sdhost SD/MMC driver ++Load: dtoverlay=sdtweak,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) + + +Name: smi @@ -111005,29 +112113,128 @@ index 0000000..268d400 +Params: + + ++Name: spi1-1cs ++Info: Enables spi1 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi1-2cs ++Info: Enables spi1 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.1 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi1-3cs ++Info: Enables spi1 with three chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-3cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). ++ cs2_pin GPIO pin for CS2 (default 16 - BCM SPI1_CE2). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.1 (default ++ is 'okay' or enabled). ++ cs2_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.2 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-1cs ++Info: Enables spi2 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-2cs ++Info: Enables spi2 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.1 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-3cs ++Info: Enables spi2 with three chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-3cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). ++ cs2_pin GPIO pin for CS2 (default 45 - BCM SPI2_CE2). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.1 (default ++ is 'okay' or enabled). ++ cs2_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.2 (default ++ is 'okay' or enabled). ++ ++ +Name: tinylcd35 +Info: 3.5" Color TFT Display by www.tinylcd.com + Options: Touch, RTC, keypad +Load: dtoverlay=tinylcd35,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ touch Enable touch panel ++ touch Enable touch panel + -+ touchgpio Touch controller IRQ GPIO ++ touchgpio Touch controller IRQ GPIO + -+ xohms Touchpanel: Resistance of X-plate in ohms ++ xohms Touchpanel: Resistance of X-plate in ohms + -+ rtc-pcf PCF8563 Real Time Clock ++ rtc-pcf PCF8563 Real Time Clock + -+ rtc-ds DS1307 Real Time Clock ++ rtc-ds DS1307 Real Time Clock + -+ keypad Enable keypad ++ keypad Enable keypad + + Examples: + Display with touchpanel, PCF8563 RTC and keypad: @@ -111039,9 +112246,17 @@ index 0000000..268d400 +Name: uart1 +Info: Enable uart1 in place of uart0 +Load: dtoverlay=uart1,= -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) ++Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) + -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ ++ ++Name: vc4-kms-v3d ++Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. Running startx or ++ booting to GUI while this overlay is in use will cause interesting ++ lockups. ++Load: dtoverlay=vc4-kms-v3d ++Params: + + +Name: vga666 @@ -111056,22 +112271,30 @@ index 0000000..268d400 +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *don't* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio,= -+Params: gpiopin GPIO for I/O (default "4") ++Params: gpiopin GPIO for I/O (default "4") + -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature + + +Name: w1-gpio-pullup +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *do* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio-pullup,= -+Params: gpiopin GPIO for I/O (default "4") ++Params: gpiopin GPIO for I/O (default "4") + -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature + -+ extpullup GPIO for external pullup (default "5") ++ extpullup GPIO for external pullup (default "5") ++ ++ ++Name: wittypi ++Info: Configures the wittypi RTC module. ++Load: dtoverlay=wittypi,= ++Params: led_gpio GPIO for LED (default "17") ++ led_trigger Choose which activity the LED tracks (default ++ "default-on") + + +Troubleshooting @@ -111097,10 +112320,10 @@ index 0000000..268d400 +http://www.raspberrypi.org/documentation/configuration/device-tree.md diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts new file mode 100644 -index 0000000..6a92cd1 +index 0000000..edf2dc9 --- /dev/null +++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -0,0 +1,83 @@ +@@ -0,0 +1,89 @@ +/* + * Generic Device Tree overlay for the ADS7846 touch controller + * @@ -111116,18 +112339,24 @@ index 0000000..6a92cd1 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + ads7846_pins: ads7846_pins { @@ -111138,7 +112367,7 @@ index 0000000..6a92cd1 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111184,6 +112413,69 @@ index 0000000..6a92cd1 + xohms = <&ads7846>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts +new file mode 100644 +index 0000000..880c753 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ lowpan0: at86rf233@0 { ++ compatible = "atmel,at86rf233"; ++ reg = <0>; ++ interrupt-parent = <&gpio>; ++ interrupts = <23 4>; /* active high */ ++ reset-gpio = <&gpio 24 1>; ++ sleep-gpio = <&gpio 25 1>; ++ spi-max-frequency = <3000000>; ++ xtal-trim = /bits/ 8 <0xf>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ lowpan0_pins: lowpan0_pins { ++ brcm,pins = <23 24 25>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ interrupt = <&lowpan0>, "interrupts:0", ++ <&lowpan0_pins>, "brcm,pins:0"; ++ reset = <&lowpan0>, "reset-gpio:4", ++ <&lowpan0_pins>, "brcm,pins:4"; ++ sleep = <&lowpan0>, "sleep-gpio:4", ++ <&lowpan0_pins>, "brcm,pins:8"; ++ speed = <&lowpan0>, "spi-max-frequency:0"; ++ trim = <&lowpan0>, "xtal-trim.0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts new file mode 100644 index 0000000..782b171 @@ -111258,12 +112550,73 @@ index 0000000..9bf67fd + <&dht11>,"gpios:4"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +new file mode 100644 +index 0000000..fc48bd1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&usb>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ __overlay__ { ++ compatible = "brcm,bcm2708-usb"; ++ reg = <0x7e980000 0x10000>, ++ <0x7e006000 0x1000>; ++ interrupts = <2 0>, ++ <1 9>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +new file mode 100644 +index 0000000..527abc9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&usb>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ dwc2_usb: __overlay__ { ++ compatible = "brcm,bcm2835-usb"; ++ reg = <0x7e980000 0x10000>; ++ interrupts = <1 9>; ++ dr_mode = "otg"; ++ g-np-tx-fifo-size = <32>; ++ g-rx-fifo-size = <256>; ++ g-tx-fifo-size = <256 128 128 64 64 64 32>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ dr_mode = <&dwc2_usb>, "dr_mode"; ++ g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; ++ g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; ++ g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts new file mode 100644 -index 0000000..8fae869 +index 0000000..db8a8fe --- /dev/null +++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -0,0 +1,50 @@ +@@ -0,0 +1,53 @@ +// Overlay for the Microchip ENC28J60 Ethernet Controller +/dts-v1/; +/plugin/; @@ -111280,10 +112633,6 @@ index 0000000..8fae869 + + status = "okay"; + -+ spidev@0{ -+ status = "disabled"; -+ }; -+ + eth1: enc28j60@0{ + compatible = "microchip,enc28j60"; + reg = <0>; /* CE0 */ @@ -111298,6 +112647,13 @@ index 0000000..8fae869 + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + eth1_pins: eth1_pins { @@ -111314,6 +112670,57 @@ index 0000000..8fae869 + speed = <ð1>, "spi-max-frequency:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +new file mode 100644 +index 0000000..a2d6bc7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +@@ -0,0 +1,45 @@ ++// Definitions for ir-gpio module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ gpio_ir: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ ++ // pin number, high or low ++ gpios = <&gpio 18 1>; ++ ++ // parameter for keymap name ++ linux,rc-map-name = "rc-rc6-mce"; ++ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ gpio_ir_pins: gpio_ir_pins { ++ brcm,pins = <18>; // pin 18 ++ brcm,function = <0>; // in ++ brcm,pull = <1>; // down ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ // parameters ++ gpio_pin = <&gpio_ir>,"gpios:4", ++ <&gpio_ir_pins>,"brcm,pins:0", ++ <&gpio_ir_pins>,"brcm,pull:0"; // pin number ++ gpio_pull = <&gpio_ir_pins>,"brcm,pull:0"; // pull-up/down state ++ ++ rc-map-name = <&gpio_ir>,"linux,rc-map-name"; // default rc map ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts new file mode 100644 index 0000000..ff8cb36 @@ -111441,10 +112848,10 @@ index 0000000..5e7633a +}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts new file mode 100644 -index 0000000..deb9c62 +index 0000000..42a0194 --- /dev/null +++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,54 @@ +// Definitions for HiFiBerry DAC+ +/dts-v1/; +/plugin/; @@ -111453,22 +112860,32 @@ index 0000000..deb9c62 + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&sound>; ++ target-path = "/clocks"; + __overlay__ { ++ dacpro_osc: dacpro_osc { ++ compatible = "hifiberry,dacpro-clk"; ++ #clock-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&sound>; ++ frag1: __overlay__ { + compatible = "hifiberry,hifiberry-dacplus"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + -+ fragment@1 { ++ fragment@2 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + -+ fragment@2 { ++ fragment@3 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -111479,10 +112896,15 @@ index 0000000..deb9c62 + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; ++ clocks = <&dacpro_osc>; + status = "okay"; + }; + }; + }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag1>,"hifiberry,24db_digital_gain?"; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts new file mode 100644 @@ -111531,10 +112953,10 @@ index 0000000..d0e0d8a +}; diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts new file mode 100644 -index 0000000..3cd3083 +index 0000000..ac0f3c2 --- /dev/null +++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -0,0 +1,87 @@ +@@ -0,0 +1,93 @@ +/* + * Device Tree overlay for HY28A display + * @@ -111550,18 +112972,24 @@ index 0000000..3cd3083 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + hy28a_pins: hy28a_pins { @@ -111571,7 +112999,7 @@ index 0000000..3cd3083 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111624,10 +113052,10 @@ index 0000000..3cd3083 +}; diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts new file mode 100644 -index 0000000..f774c4a +index 0000000..8018aeb --- /dev/null +++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -0,0 +1,142 @@ +@@ -0,0 +1,148 @@ +/* + * Device Tree overlay for HY28b display shield by Texy + * @@ -111643,18 +113071,24 @@ index 0000000..f774c4a + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + hy28b_pins: hy28b_pins { @@ -111664,7 +113098,7 @@ index 0000000..f774c4a + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111770,12 +113204,119 @@ index 0000000..f774c4a + <&hy28b_pins>, "brcm,pins:2"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +new file mode 100644 +index 0000000..2a2dc98 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +@@ -0,0 +1,28 @@ ++// Overlay for i2c_gpio bitbanging host bus. ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ i2c_gpio: i2c@0 { ++ compatible = "i2c-gpio"; ++ gpios = <&gpio 23 0 /* sda */ ++ &gpio 24 0 /* scl */ ++ >; ++ i2c-gpio,delay-us = <2>; /* ~100 kHz */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; ++ i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; ++ i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; ++ }; ++}; ++ +diff --git a/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts +new file mode 100644 +index 0000000..1729fd6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts +@@ -0,0 +1,67 @@ ++// Definitions for NXP PCA9548A I2C mux on ARM I2C bus. ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ i2cmux: mux@70 { ++ compatible = "nxp,pca9548"; ++ reg = <0x70>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ i2c@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ }; ++ i2c@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <1>; ++ }; ++ i2c@2 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <2>; ++ }; ++ i2c@3 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <3>; ++ }; ++ i2c@4 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <4>; ++ }; ++ i2c@5 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <5>; ++ }; ++ i2c@6 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <6>; ++ }; ++ i2c@7 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <7>; ++ }; ++ }; ++ }; ++ }; ++ __overrides__ { ++ addr = <&i2cmux>,"reg:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts new file mode 100644 -index 0000000..fed4bd8 +index 0000000..eecec16 --- /dev/null +++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,55 @@ +@@ -0,0 +1,63 @@ +// Definitions for several I2C based Real Time Clocks +/dts-v1/; +/plugin/; @@ -111795,6 +113336,12 @@ index 0000000..fed4bd8 + reg = <0x68>; + status = "disable"; + }; ++ ds1339: ds1339@68 { ++ compatible = "dallas,ds1339"; ++ trickle-resistor-ohms = <0>; ++ reg = <0x68>; ++ status = "disable"; ++ }; + mcp7941x: mcp7941x@6f { + compatible = "microchip,mcp7941x"; + reg = <0x6f>; @@ -111824,13 +113371,100 @@ index 0000000..fed4bd8 + }; + __overrides__ { + ds1307 = <&ds1307>,"status"; ++ ds1339 = <&ds1339>,"status"; + ds3231 = <&ds3231>,"status"; + mcp7941x = <&mcp7941x>,"status"; + pcf2127 = <&pcf2127>,"status"; + pcf8523 = <&pcf8523>,"status"; + pcf8563 = <&pcf8563>,"status"; ++ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +new file mode 100644 +index 0000000..5c0e55b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +@@ -0,0 +1,36 @@ ++/* ++ * Device tree overlay for i2c_bcm2708, i2c0 bus ++ * ++ * Compile: ++ * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c0>; ++ __overlay__ { ++ pinctrl-0 = <&i2c0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ sda0_pin = <&i2c0_pins>,"brcm,pins:0"; ++ scl0_pin = <&i2c0_pins>,"brcm,pins:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +new file mode 100644 +index 0000000..e303b9c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +@@ -0,0 +1,37 @@ ++/* ++ * Device tree overlay for i2c_bcm2708, i2c1 bus ++ * ++ * Compile: ++ * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ sda1_pin = <&i2c1_pins>,"brcm,pins:0"; ++ scl1_pin = <&i2c1_pins>,"brcm,pins:4"; ++ pin_func = <&i2c1_pins>,"brcm,function:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts new file mode 100644 index 0000000..a11160a @@ -111897,10 +113531,10 @@ index 0000000..ea8173e +}; diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts new file mode 100644 -index 0000000..735d8ab +index 0000000..e0aaf8f --- /dev/null +++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,43 @@ +// Definitions for IQaudIO DAC+ +/dts-v1/; +/plugin/; @@ -111910,7 +113544,7 @@ index 0000000..735d8ab + + fragment@0 { + target = <&sound>; -+ __overlay__ { ++ frag0: __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + status = "okay"; @@ -111939,6 +113573,10 @@ index 0000000..735d8ab + }; + }; + }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts new file mode 100644 @@ -112005,10 +113643,10 @@ index 0000000..7d5d82b +}; diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts new file mode 100755 -index 0000000..398d59c +index 0000000..c96cdae --- /dev/null +++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -0,0 +1,69 @@ +@@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can0 on spi0.0 + */ @@ -112023,14 +113661,18 @@ index 0000000..398d59c + target = <&spi0>; + __overlay__ { + status = "okay"; -+ spidev@0{ -+ status = "disabled"; -+ }; + }; + }; + -+ /* the interrupt pin of the can-controller */ + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + can0_pins: can0_pins { @@ -112041,7 +113683,7 @@ index 0000000..398d59c + }; + + /* the clock/oscillator of the can-controller */ -+ fragment@2 { ++ fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on SPI0.0 */ @@ -112054,7 +113696,7 @@ index 0000000..398d59c + }; + + /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112080,10 +113722,10 @@ index 0000000..398d59c +}; diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts new file mode 100644 -index 0000000..6bef9ae +index 0000000..67bd0d9 --- /dev/null +++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -0,0 +1,69 @@ +@@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner + */ @@ -112098,14 +113740,18 @@ index 0000000..6bef9ae + target = <&spi0>; + __overlay__ { + status = "okay"; -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + -+ /* the interrupt pin of the can-controller */ + fragment@1 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + can1_pins: can1_pins { @@ -112116,7 +113762,7 @@ index 0000000..6bef9ae + }; + + /* the clock/oscillator of the can-controller */ -+ fragment@2 { ++ fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on spi0.1 */ @@ -112129,7 +113775,7 @@ index 0000000..6bef9ae + }; + + /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112155,10 +113801,10 @@ index 0000000..6bef9ae +}; diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts new file mode 100644 -index 0000000..00a22be +index 0000000..d32b02c --- /dev/null +++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,38 @@ +/dts-v1/; +/plugin/; + @@ -112195,15 +113841,14 @@ index 0000000..00a22be + + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts new file mode 100644 -index 0000000..9242a6e +index 0000000..2c29aae --- /dev/null +++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,111 @@ +@@ -0,0 +1,117 @@ +/* + * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec + * @@ -112219,18 +113864,24 @@ index 0000000..9242a6e + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + mz61581_pins: mz61581_pins { @@ -112240,7 +113891,7 @@ index 0000000..9242a6e + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112315,12 +113966,167 @@ index 0000000..9242a6e + xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +new file mode 100644 +index 0000000..14a59dc +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed ++ from the VPU. There is a special driver for this with a separate DT node, ++ which has the unfortunate consequence of breaking the act_led_gpio and ++ act_led_activelow dtparams. ++ ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&act_led>; ++ frag0: __overlay__ { ++ gpios = <&gpio 0 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ gpio = <&frag0>,"gpios:4"; ++ activelow = <&frag0>,"gpios:8"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +new file mode 100644 +index 0000000..68f6069 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +@@ -0,0 +1,46 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. ++ To disable the systemd service that initialises the modem so it doesn't use ++ the UART: ++ ++ sudo systemctl disable hciuart ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/uart@7e201000"; ++ serial1 = "/soc/uart@7e215040"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +new file mode 100644 +index 0000000..17d04cf +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +@@ -0,0 +1,64 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore ++ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum ++ usable baudrate. ++ ++ It is also necessary to edit /lib/systemd/system/hciuart.service and ++ replace ttyAMA0 with ttyS0, unless you have a system with udev rules ++ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 ++ instead because it will always be correct. ++ ++ If cmdline.txt uses the alias serial0 to refer to the user-accessable port ++ then the firmware will replace with the appropriate port whether or not ++ this overlay is used. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins &bt_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&uart1_pins>; ++ __overlay__ { ++ brcm,pins = <32 33>; ++ brcm,function = <2>; /* alt5=UART1 */ ++ brcm,pull = <0 2>; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/uart@7e201000"; ++ serial1 = "/soc/uart@7e215040"; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts new file mode 100644 -index 0000000..ba4ad33 +index 0000000..40a1f29 --- /dev/null +++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -0,0 +1,96 @@ +@@ -0,0 +1,102 @@ +/* + * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker + * @@ -112336,18 +114142,24 @@ index 0000000..ba4ad33 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + piscreen_pins: piscreen_pins { @@ -112357,7 +114169,7 @@ index 0000000..ba4ad33 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112417,12 +114229,221 @@ index 0000000..ba4ad33 + xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +new file mode 100644 +index 0000000..9c0bed8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +@@ -0,0 +1,106 @@ ++ /* ++ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&gpio>; ++ __overlay__ { ++ piscreen2_pins: piscreen2_pins { ++ brcm,pins = <17 25 24 22>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ piscreen2: piscreen2@0{ ++ compatible = "ilitek,ili9486"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&piscreen2_pins>; ++ bgr; ++ spi-max-frequency = <64000000>; ++ rotate = <90>; ++ fps = <30>; ++ buswidth = <8>; ++ regwidth = <16>; ++ txbuflen = <32768>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 22 1>; ++ debug = <0>; ++ ++ init = <0x10000b0 0x00 ++ 0x1000011 ++ 0x20000ff ++ 0x100003a 0x55 ++ 0x1000036 0x28 ++ 0x10000c0 0x11 0x09 ++ 0x10000c1 0x41 ++ 0x10000c5 0x00 0x00 0x00 0x00 ++ 0x10000b6 0x00 0x02 ++ 0x10000f7 0xa9 0x51 0x2c 0x2 ++ 0x10000be 0x00 0x04 ++ 0x10000e9 0x00 ++ 0x1000011 ++ 0x1000029>; ++ ++ }; ++ ++ piscreen2_ts: piscreen2-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,swap-xy; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&piscreen2>,"spi-max-frequency:0"; ++ rotate = <&piscreen2>,"rotate:0"; ++ fps = <&piscreen2>,"fps:0"; ++ debug = <&piscreen2>,"debug:0"; ++ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; ++ +diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts +new file mode 100644 +index 0000000..5c07526 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts +@@ -0,0 +1,91 @@ ++/* ++ * Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ pitft_pins: pitft_pins { ++ brcm,pins = <24 25>; ++ brcm,function = <0 1>; /* in out */ ++ brcm,pull = <2 0>; /* pullup none */ ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pitft: pitft@0{ ++ compatible = "ilitek,ili9340"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pitft_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <90>; ++ fps = <25>; ++ bgr; ++ buswidth = <8>; ++ dc-gpios = <&gpio 25 0>; ++ debug = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c1>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ft6236: ft6236@38 { ++ compatible = "focaltech,ft6236"; ++ reg = <0x38>; ++ ++ interrupt-parent = <&gpio>; ++ interrupts = <24 2>; ++ touchscreen-size-x = <240>; ++ touchscreen-size-y = <320>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&pitft>,"spi-max-frequency:0"; ++ rotate = <&pitft>,"rotate:0"; ++ fps = <&pitft>,"fps:0"; ++ debug = <&pitft>,"debug:0"; ++ touch-sizex = <&ft6236>,"touchscreen-size-x?"; ++ touch-sizey = <&ft6236>,"touchscreen-size-y?"; ++ touch-invx = <&ft6236>,"touchscreen-inverted-x?"; ++ touch-invy = <&ft6236>,"touchscreen-inverted-y?"; ++ touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts new file mode 100644 -index 0000000..d506eae +index 0000000..ed2afc2 --- /dev/null +++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ +@@ -0,0 +1,121 @@ +/* + * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen + * @@ -112438,18 +114459,24 @@ index 0000000..d506eae + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { @@ -112460,7 +114487,7 @@ index 0000000..d506eae + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112520,7 +114547,7 @@ index 0000000..d506eae + }; + }; + -+ fragment@3 { ++ fragment@5 { + target-path = "/soc"; + __overlay__ { + backlight { @@ -112580,10 +114607,10 @@ index 0000000..40bf0e1 +}; diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts new file mode 100644 -index 0000000..957e1a4 +index 0000000..18e4e4f --- /dev/null +++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,53 @@ +/dts-v1/; +/plugin/; + @@ -112622,20 +114649,27 @@ index 0000000..957e1a4 + }; + }; + ++ fragment@2 { ++ target = <&clk_pwm>; ++ frag2: __overlay__ { ++ clock-frequency = <100000000>; ++ }; ++ }; ++ + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + pin2 = <&pwm_pins>,"brcm,pins:4"; + func = <&pwm_pins>,"brcm,function:0"; + func2 = <&pwm_pins>,"brcm,function:4"; -+ clock = <&clk_pwm>,"clock-frequency:0"; ++ clock = <&frag2>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts new file mode 100644 -index 0000000..ddd67ff +index 0000000..bf030a6 --- /dev/null +++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -0,0 +1,42 @@ +@@ -0,0 +1,49 @@ +/dts-v1/; +/plugin/; + @@ -112672,10 +114706,75 @@ index 0000000..ddd67ff + }; + }; + ++ fragment@2 { ++ target = <&clk_pwm>; ++ frag2: __overlay__ { ++ clock-frequency = <100000000>; ++ }; ++ }; ++ + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + func = <&pwm_pins>,"brcm,function:0"; -+ clock = <&clk_pwm>,"clock-frequency:0"; ++ clock = <&frag2>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/qca7000-overlay.dts b/arch/arm/boot/dts/overlays/qca7000-overlay.dts +new file mode 100644 +index 0000000..b4e6013 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts +@@ -0,0 +1,52 @@ ++// Overlay for the Qualcomm Atheros QCA7000 on I2SE's PLC Stamp micro EVK ++// Visit: https://www.i2se.com/product/plc-stamp-micro-evk for details ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ spidev@0 { ++ status = "disabled"; ++ }; ++ ++ eth1: qca7000@0 { ++ compatible = "qca,qca7000"; ++ reg = <0>; /* CE0 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð1_pins>; ++ interrupt-parent = <&gpio>; ++ interrupts = <23 0x1>; /* rising edge */ ++ spi-max-frequency = <12000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ eth1_pins: eth1_pins { ++ brcm,pins = <23>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ int_pin = <ð1>, "interrupts:0", ++ <ð1_pins>, "brcm,pins:0"; ++ speed = <ð1>, "spi-max-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts @@ -112729,6 +114828,33 @@ index 0000000..1bd8054 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts +new file mode 100644 +index 0000000..c021d02 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts +@@ -0,0 +1,21 @@ ++/* ++ * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display ++ * backlight controller ++ */ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ rpi_backlight: rpi_backlight { ++ compatible = "raspberrypi,rpi-backlight"; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts new file mode 100644 index 0000000..7fc6ac9 @@ -112771,10 +114897,10 @@ index 0000000..7fc6ac9 +}; diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts new file mode 100644 -index 0000000..a8fa974 +index 0000000..d7e72ee --- /dev/null +++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -0,0 +1,82 @@ +@@ -0,0 +1,89 @@ +/* + * Device Tree overlay for rpi-display by Watterott + * @@ -112790,18 +114916,24 @@ index 0000000..a8fa974 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + rpi_display_pins: rpi_display_pins { @@ -112812,7 +114944,7 @@ index 0000000..a8fa974 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112855,6 +114987,7 @@ index 0000000..a8fa974 + fps = <&rpidisplay>,"fps:0"; + debug = <&rpidisplay>,"debug:0"; + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; ++ swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts @@ -112980,45 +115113,90 @@ index 0000000..2715324 +}; diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts new file mode 100644 -index 0000000..85f0725 +index 0000000..a431177 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,29 @@ +@@ -0,0 +1,32 @@ +/dts-v1/; +/plugin/; + ++/* Provide backwards compatible aliases for the old sdhost dtparams. */ ++ +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { ++ target = <&sdhost>; ++ frag0: __overlay__ { ++ brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; ++ brcm,debug-flags = <0>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; + -+ fragment@1 { -+ target = <&sdhost>; -+ frag1: __overlay__ { ++ __overrides__ { ++ overclock_50 = <&frag0>,"brcm,overclock-50:0"; ++ force_pio = <&frag0>,"brcm,force-pio?"; ++ pio_limit = <&frag0>,"brcm,pio-limit:0"; ++ debug = <&frag0>,"brcm,debug?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts +new file mode 100644 +index 0000000..46d4538 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts +@@ -0,0 +1,36 @@ ++/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ ++ ++/include/ "sdhost-overlay.dts" ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@3 { ++ target = <&mmc>; ++ sdio_mmc: __overlay__ { ++ compatible = "brcm,bcm2835-mmc"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <1>; + brcm,overclock-50 = <0>; -+ brcm,pio-limit = <1>; + status = "okay"; + }; + }; + ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ sdio_pins: sdio_pins { ++ brcm,pins = <22 23 24 25>; ++ brcm,function = <7 7 7 7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2>; ++ }; ++ }; ++ }; ++ + __overrides__ { -+ overclock_50 = <&frag1>,"brcm,overclock-50:0"; -+ force_pio = <&frag1>,"brcm,force-pio?"; -+ pio_limit = <&frag1>,"brcm,pio-limit:0"; -+ debug = <&frag1>,"brcm,debug?"; ++ poll_once = <&sdio_mmc>,"non-removable?"; ++ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts new file mode 100644 -index 0000000..afc8742 +index 0000000..398bd81 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -0,0 +1,32 @@ +@@ -0,0 +1,36 @@ +/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ + +/include/ "sdhost-overlay.dts" @@ -113032,6 +115210,8 @@ index 0000000..afc8742 + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + non-removable; ++ bus-width = <4>; ++ brcm,overclock-50 = <0>; + status = "okay"; + }; + }; @@ -113049,6 +115229,37 @@ index 0000000..afc8742 + + __overrides__ { + poll_once = <&sdio_mmc>,"non-removable?"; ++ bus_width = <&sdio_mmc>,"bus-width:0"; ++ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts +new file mode 100644 +index 0000000..e4a4677 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Provide backwards compatible aliases for the old sdhost dtparams. */ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sdhost>; ++ frag0: __overlay__ { ++ brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; ++ }; ++ }; ++ ++ __overrides__ { ++ overclock_50 = <&frag0>,"brcm,overclock-50:0"; ++ force_pio = <&frag0>,"brcm,force-pio?"; ++ pio_limit = <&frag0>,"brcm,pio-limit:0"; ++ debug = <&frag0>,"brcm,debug?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts @@ -113230,12 +115441,462 @@ index 0000000..9648063 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts +new file mode 100644 +index 0000000..71c2439 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts +new file mode 100644 +index 0000000..2ae0885 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts +@@ -0,0 +1,69 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18 17>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>, <&gpio 17 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ cs1_spidev = <&spidev1_1>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts +new file mode 100644 +index 0000000..8f79044 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts +@@ -0,0 +1,81 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18 17 16>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>, <&gpio 17 1>, <&gpio 16 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_2: spidev@2 { ++ compatible = "spidev"; ++ reg = <2>; /* CE2 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs2_pin = <&spi1_cs_pins>,"brcm,pins:8", ++ <&frag1>,"cs-gpios:28"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ cs1_spidev = <&spidev1_1>,"status"; ++ cs2_spidev = <&spidev1_2>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts +new file mode 100644 +index 0000000..6f57bc7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts +new file mode 100644 +index 0000000..d090631 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts +@@ -0,0 +1,69 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43 44>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>, <&gpio 44 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ cs1_spidev = <&spidev2_1>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts +new file mode 100644 +index 0000000..e258672 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts +@@ -0,0 +1,81 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43 44 45>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_2: spidev@2 { ++ compatible = "spidev"; ++ reg = <2>; /* CE2 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs2_pin = <&spi2_cs_pins>,"brcm,pins:8", ++ <&frag1>,"cs-gpios:28"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ cs1_spidev = <&spidev2_1>,"status"; ++ cs2_spidev = <&spidev2_2>,"status"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts new file mode 100644 -index 0000000..f7102c8 +index 0000000..33c0651 --- /dev/null +++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ +@@ -0,0 +1,222 @@ +/* + * tinylcd35-overlay.dts + * @@ -113268,18 +115929,24 @@ index 0000000..f7102c8 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + tinylcd35_pins: tinylcd35_pins { @@ -113298,7 +115965,7 @@ index 0000000..f7102c8 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -113362,7 +116029,7 @@ index 0000000..f7102c8 + + /* RTC */ + -+ fragment@3 { ++ fragment@5 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -113376,7 +116043,7 @@ index 0000000..f7102c8 + }; + }; + -+ fragment@4 { ++ fragment@6 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -113394,7 +116061,7 @@ index 0000000..f7102c8 + * Values for input event code is found under the + * 'Keys and buttons' heading in include/uapi/linux/input.h + */ -+ fragment@5 { ++ fragment@7 { + target-path = "/soc"; + __overlay__ { + keypad: keypad { @@ -113496,6 +116163,107 @@ index 0000000..fa73e1f + rxd1_pin = <&uart1_pins>,"brcm,pins:4"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +new file mode 100644 +index 0000000..da37483 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -0,0 +1,95 @@ ++/* ++ * vc4-kms-v3d-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++#include "dt-bindings/clock/bcm2835.h" ++#include "dt-bindings/gpio/gpio.h" ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&cprman>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&fb>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pixelvalve@7e206000 { ++ compatible = "brcm,bcm2835-pixelvalve0"; ++ reg = <0x7e206000 0x100>; ++ interrupts = <2 13>; /* pwa0 */ ++ }; ++ ++ pixelvalve@7e207000 { ++ compatible = "brcm,bcm2835-pixelvalve1"; ++ reg = <0x7e207000 0x100>; ++ interrupts = <2 14>; /* pwa1 */ ++ }; ++ ++ hvs@7e400000 { ++ compatible = "brcm,bcm2835-hvs"; ++ reg = <0x7e400000 0x6000>; ++ interrupts = <2 1>; ++ }; ++ ++ pixelvalve@7e807000 { ++ compatible = "brcm,bcm2835-pixelvalve2"; ++ reg = <0x7e807000 0x100>; ++ interrupts = <2 10>; /* pixelvalve */ ++ }; ++ ++ hdmi@7e902000 { ++ compatible = "brcm,bcm2835-hdmi"; ++ reg = <0x7e902000 0x600>, ++ <0x7e808000 0x100>; ++ interrupts = <2 8>, <2 9>; ++ ddc = <&i2c2>; ++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; ++ clocks = <&cprman BCM2835_PLLH_PIX>, ++ <&cprman BCM2835_CLOCK_HSM>; ++ clock-names = "pixel", "hdmi"; ++ }; ++ ++ v3d@7ec00000 { ++ compatible = "brcm,vc4-v3d"; ++ reg = <0x7ec00000 0x1000>; ++ interrupts = <1 10>; ++ }; ++ ++ gpu@7e4c0000 { ++ compatible = "brcm,bcm2835-vc4"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/chosen"; ++ __overlay__ { ++ bootargs = "cma=256M@512M"; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts new file mode 100644 index 0000000..7fcab96 @@ -113624,532 +116392,61 @@ index 0000000..66a98f6 + pullup = <&w1>,"rpi,parasitic-power:0"; + }; +}; - -From 83d747d78be86190ad18c8c49e0d5518ac6bf83b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 15 Aug 2015 20:47:07 +0200 -Subject: [PATCH 052/251] bcm2835: Match with BCM2708 Device Trees -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 132 ++++++++++++++++++--- - arch/arm/boot/dts/bcm2835-rpi-b.dts | 115 ++++++++++++++++-- - arch/arm/boot/dts/bcm2835.dtsi | 195 +++---------------------------- - 3 files changed, 237 insertions(+), 205 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index 668442b..17e2443 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -1,30 +1,128 @@ - /dts-v1/; --#include "bcm2835-rpi.dtsi" -+#include "bcm2835.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; - }; --}; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -+ i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = ; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; +diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts +new file mode 100644 +index 0000000..8498134 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts +@@ -0,0 +1,44 @@ ++/* ++ * Device Tree overlay for Witty Pi extension board by UUGear ++ * ++ */ + -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+ -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; -+ }; -+}; ++/dts-v1/; ++/plugin/; + +/ { ++ ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ compatible = "gpio-leds"; ++ wittypi_led: wittypi_led { ++ label = "wittypi_led"; ++ linux,default-trigger = "default-on"; ++ gpios = <&gpio 17 0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtc: ds1337@68 { ++ compatible = "dallas,ds1337"; ++ reg = <0x68>; ++ wakeup-source; ++ }; ++ }; ++ }; ++ + __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index ff6b2d1..221d252 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -1,17 +1,118 @@ - /dts-v1/; --#include "bcm2835-rpi.dtsi" -+#include "bcm2835.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; -+}; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ ++ led_gpio = <&wittypi_led>,"gpios:4"; ++ led_trigger = <&wittypi_led>,"linux,default-trigger"; + }; + -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = <6>; /* alt2 */ - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &alt3>; -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 16 1>; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; -+ }; - }; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 864a3ef..3256bff 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -1,206 +1,39 @@ --#include --#include --#include "skeleton.dtsi" -+#include "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2835"; - model = "BCM2835"; -- interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - - soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -- ranges = <0x7e000000 0x20000000 0x02000000>; -+ ranges = <0x7e000000 0x20000000 0x01000000>; - 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 0x24>, -- <0x7e101098 0x08>; -- -- 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>; -+ aux_enable: aux_enable@0x7e215004 { -+ compatible = "bcrm,bcm2835-aux-enable"; -+ reg = <0x7e215004 0x04>; - }; -- - }; - }; -+ -+&intc { -+ compatible = "brcm,bcm2835-armctrl-ic"; -+}; -+ -+&watchdog { -+ status = "okay"; +}; -From 1b4ab4d431eed3ced1dfdcb4ac14ce3937b74244 Mon Sep 17 00:00:00 2001 +From 2984afc661362f0232f374a91edc59a2cafcc302 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 053/251] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 053/114] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -114164,7 +116461,7 @@ Signed-off-by: Siarhei Siamashka 2 files changed, 35 insertions(+) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index 0705d88..771992a 100644 +index 4e73b6f..d3a8cc3 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) @@ -114242,10 +116539,10 @@ index fb795c3..fa72af0 100644 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ -From 25f558f2cb3b7c357c2b3fff66afca442b8462f9 Mon Sep 17 00:00:00 2001 +From f125245cdc2f65f3f085c9146bc3ce5b373b9def Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 054/251] Speed up console framebuffer imageblit function +Subject: [PATCH 054/114] Speed up console framebuffer imageblit function Especially on platforms with a slower CPU but a relatively high framebuffer fill bandwidth, like current ARM devices, the existing @@ -114454,10 +116751,10 @@ index a2bb276..436494f 100644 start_index, pitch_index); } else -From 0490dab9480fa92983af098b472d6a6e6e573e29 Mon Sep 17 00:00:00 2001 +From c158f1cc55e3166d2eac6a0c7e06bd93d6c4c244 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 055/251] Allow mac address to be set in smsc95xx +Subject: [PATCH 055/114] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -114465,7 +116762,7 @@ Signed-off-by: popcornmix 1 file changed, 56 insertions(+) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 9c0da18..3244a90 100755 +index 714cfe0..08ced57 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -59,6 +59,7 @@ @@ -114476,9 +116773,9 @@ index 9c0da18..3244a90 100755 struct smsc95xx_priv { u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); +@@ -78,6 +79,10 @@ static bool truesize_mode = false; + module_param(truesize_mode, bool, 0644); + MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); +static char *macaddr = ":"; +module_param(macaddr, charp, 0); @@ -114487,7 +116784,7 @@ index 9c0da18..3244a90 100755 static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data, int in_pm) { -@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +@@ -767,8 +772,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } @@ -114548,10 +116845,10 @@ index 9c0da18..3244a90 100755 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -From 5f3d302d1cd2e2684c1a4a21953c4677809a2f87 Mon Sep 17 00:00:00 2001 +From 7dc5a6f1fb813263ee414e2d7898d3e03d79edd8 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 056/251] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 056/114] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -114801,32 +117098,32 @@ index d58594a..feae942 100644 unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From bc26cb5ca41caddb82d291450e32b27e56d9b87f Mon Sep 17 00:00:00 2001 +From 79e36090cb7c4f81295a6764dcb5879f30d0ddb4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 057/251] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 057/114] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- - kernel/cgroup.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) + kernel/cgroup.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index dc94f8b..3dda8a8 100644 +index 671dc05..fbbf2e6 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5302,7 +5302,7 @@ int __init cgroup_init_early(void) +@@ -5521,7 +5521,7 @@ int __init cgroup_init_early(void) return 0; } --static unsigned long cgroup_disable_mask __initdata; -+static unsigned long cgroup_disable_mask __initdata = 1<<0; +-static u16 cgroup_disable_mask __initdata; ++static u16 cgroup_disable_mask __initdata = 1<<0; /** * cgroup_init - cgroup initialization -@@ -5798,6 +5798,27 @@ static int __init cgroup_disable(char *str) +@@ -6051,6 +6051,28 @@ static int __init cgroup_no_v1(char *str) } - __setup("cgroup_disable=", cgroup_disable); + __setup("cgroup_no_v1=", cgroup_no_v1); +static int __init cgroup_enable(char *str) +{ @@ -114842,6 +117139,7 @@ index dc94f8b..3dda8a8 100644 + if (strcmp(token, ss->name) && + strcmp(token, ss->legacy_name)) + continue; ++ + cgroup_disable_mask &= ~(1 << i); + } + } @@ -114853,10 +117151,10 @@ index dc94f8b..3dda8a8 100644 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry * @dentry: directory dentry of interest -From 22689d60a6ca6191119ef7ab70c5b23991a41e16 Mon Sep 17 00:00:00 2001 +From a46b0a5f799ac1798512ee52f694802873027e6a Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 058/251] ASoC: Add support for PCM5102A codec +Subject: [PATCH 058/114] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. @@ -114870,20 +117168,20 @@ Signed-off-by: Florian Meier create mode 100644 sound/soc/codecs/pcm5102a.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index cfdafc4..bd38590 100644 +index 649e92a..ba4aad4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -89,6 +89,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C +@@ -100,6 +100,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_RT298 if I2C + select SND_SOC_RT5514 if I2C + select SND_SOC_RT5616 if I2C + select SND_SOC_PCM5102A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -549,6 +550,10 @@ config SND_SOC_RT298 - tristate - depends on I2C +@@ -630,6 +631,10 @@ config SND_SOC_RT5514 + config SND_SOC_RT5616 + tristate "Realtek RT5616 CODEC" +config SND_SOC_PCM5102A + tristate @@ -114893,21 +117191,21 @@ index cfdafc4..bd38590 100644 tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index f632fc4..7ba76ba 100644 +index 185a712..7522017 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -85,6 +85,7 @@ snd-soc-rl6231-objs := rl6231.o - snd-soc-rl6347a-objs := rl6347a.o - snd-soc-rt286-objs := rt286.o +@@ -98,6 +98,7 @@ snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o + snd-soc-rt5514-objs := rt5514.o + snd-soc-rt5616-objs := rt5616.o +snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o -@@ -280,6 +281,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o +@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o + obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o + obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o +obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o @@ -114989,10 +117287,10 @@ index 0000000..7c6598e +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 26aeeecaac62fdee4bff333a743680693009f15a Mon Sep 17 00:00:00 2001 +From 49142e5a7faec4059b97245bb91b5b4c5ab243e6 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 059/251] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 059/114] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -115002,8 +117300,8 @@ Signed-off-by: Florian Meier --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 4 ++ - sound/soc/bcm/hifiberry_dac.c | 122 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 133 insertions(+) + sound/soc/bcm/hifiberry_dac.c | 123 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 134 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_dac.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115035,10 +117333,10 @@ index bc816b7..b877d38 100644 +obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c new file mode 100644 -index 0000000..3ab0f47 +index 0000000..29ecc08 --- /dev/null +++ b/sound/soc/bcm/hifiberry_dac.c -@@ -0,0 +1,122 @@ +@@ -0,0 +1,123 @@ +/* + * ASoC Driver for HifiBerry DAC + * @@ -115104,6 +117402,7 @@ index 0000000..3ab0f47 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_dac = { + .name = "snd_rpi_hifiberry_dac", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), +}; @@ -115162,19 +117461,19 @@ index 0000000..3ab0f47 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From 5bf2d31cda2340e5d7d73c35ea876225d2f8e9a1 Mon Sep 17 00:00:00 2001 +From a2bfef45c070bc2ac4990f930c03f6bf71c80eb3 Mon Sep 17 00:00:00 2001 From: Florian Meier -Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 060/251] ASoC: Add support for Rpi-DAC +Date: Mon, 25 Jan 2016 15:48:59 +0000 +Subject: [PATCH 060/114] ASoC: Add support for Rpi-DAC --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 118 ++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/rpi-dac.c | 119 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/Kconfig | 9 ++++ sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 69 ++++++++++++++++++++++++++ - 6 files changed, 207 insertions(+) + sound/soc/codecs/pcm1794a.c | 69 +++++++++++++++++++++++++ + 6 files changed, 208 insertions(+) create mode 100644 sound/soc/bcm/rpi-dac.c create mode 100644 sound/soc/codecs/pcm1794a.c @@ -115207,10 +117506,10 @@ index b877d38..99c96b4 100644 +obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c new file mode 100644 -index 0000000..d5fac1b +index 0000000..59dc89e --- /dev/null +++ b/sound/soc/bcm/rpi-dac.c -@@ -0,0 +1,118 @@ +@@ -0,0 +1,119 @@ +/* + * ASoC Driver for RPi-DAC. + * @@ -115273,6 +117572,7 @@ index 0000000..d5fac1b +/* audio machine driver */ +static struct snd_soc_card snd_rpi_rpi_dac = { + .name = "snd_rpi_rpi_dac", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_rpi_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), +}; @@ -115330,20 +117630,20 @@ index 0000000..d5fac1b +MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index bd38590..b63f2fb 100644 +index ba4aad4..214af16 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -90,6 +90,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_RT286 if I2C - select SND_SOC_RT298 if I2C +@@ -101,6 +101,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_RT5514 if I2C + select SND_SOC_RT5616 if I2C select SND_SOC_PCM5102A if I2C + select SND_SOC_PCM1794A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -550,6 +551,14 @@ config SND_SOC_RT298 - tristate - depends on I2C +@@ -631,6 +632,14 @@ config SND_SOC_RT5514 + config SND_SOC_RT5616 + tristate "Realtek RT5616 CODEC" +config SND_SOC_RT298 + tristate @@ -115357,21 +117657,21 @@ index bd38590..b63f2fb 100644 tristate depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 7ba76ba..2147436 100644 +index 7522017..b87e845 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -85,6 +85,7 @@ snd-soc-rl6231-objs := rl6231.o - snd-soc-rl6347a-objs := rl6347a.o - snd-soc-rt286-objs := rt286.o +@@ -98,6 +98,7 @@ snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o + snd-soc-rt5514-objs := rt5514.o + snd-soc-rt5616-objs := rt5616.o +snd-soc-pcm1794a-objs := pcm1794a.o snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o -@@ -281,6 +282,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o +@@ -308,6 +309,7 @@ obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o + obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o + obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o +obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o @@ -115452,10 +117752,10 @@ index 0000000..afe1b41 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 2b8d51c50a053f52a94bf0965ad472d7e411a737 Mon Sep 17 00:00:00 2001 +From 6328cc72836700f65568fd7b69e5cc81eb5aecb8 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 061/251] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 061/114] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -115495,10 +117795,10 @@ index 8d91470..5795fb1 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -From ef7ccc94b42ad0827735d8fadac43b23548a0b35 Mon Sep 17 00:00:00 2001 +From 6c0cc4423bccc53163746eb1ff6d4a44d1358b76 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 062/251] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 062/114] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -115519,8 +117819,8 @@ adds the sample rate bits in the SPDIF status block. --- sound/soc/bcm/Kconfig | 7 ++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_digi.c | 223 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 232 insertions(+) + sound/soc/bcm/hifiberry_digi.c | 224 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 233 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_digi.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115557,10 +117857,10 @@ index 99c96b4..4d53c58 100644 obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c new file mode 100644 -index 0000000..80732b8 +index 0000000..9840e15 --- /dev/null +++ b/sound/soc/bcm/hifiberry_digi.c -@@ -0,0 +1,223 @@ +@@ -0,0 +1,224 @@ +/* + * ASoC Driver for HifiBerry Digi + * @@ -115727,6 +118027,7 @@ index 0000000..80732b8 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_digi = { + .name = "snd_rpi_hifiberry_digi", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_digi_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), +}; @@ -115785,10 +118086,10 @@ index 0000000..80732b8 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From 9871f390c47d90a75d21d20be88e88aa49536fd5 Mon Sep 17 00:00:00 2001 +From 6e7576347357e152cab8a18b678fe679ec81b68f Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 063/251] ASoC: wm8804: Set idle_bias_off to false Idle bias +Subject: [PATCH 063/114] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -115810,10 +118111,10 @@ index 5795fb1..c846716 100644 .dapm_widgets = wm8804_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), -From bad079610353ec3b8632ca9109da462435b41ba3 Mon Sep 17 00:00:00 2001 +From f03a1430b5f631cfac3bf79d7b0266d628627a39 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 064/251] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 064/114] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -115821,11 +118122,17 @@ The main volume control in the PCM512x DAC has a range up to +24dB. This is dangerously loud and can potentially cause massive clipping in the output stages. Therefore this sets a sensible limit of 0dB for this control. + +Allow up to 24dB digital gain to be applied when using IQAudIO DAC+ + +24db_digital_gain DT param can be used to specify that PCM512x +codec "Digital" volume control should not be limited to 0dB gain, +and if specified will allow the full 24dB gain. --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/iqaudio-dac.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 141 insertions(+) + sound/soc/bcm/iqaudio-dac.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 150 insertions(+) create mode 100644 sound/soc/bcm/iqaudio-dac.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115859,10 +118166,10 @@ index 4d53c58..08e4dc5 100644 +obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c new file mode 100644 -index 0000000..37038d4 +index 0000000..a5eaa9e --- /dev/null +++ b/sound/soc/bcm/iqaudio-dac.c -@@ -0,0 +1,132 @@ +@@ -0,0 +1,141 @@ +/* + * ASoC Driver for IQaudIO DAC + * @@ -115888,14 +118195,19 @@ index 0000000..37038d4 +#include +#include + ++static bool digital_gain_0db_limit = true; ++ +static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) +{ -+ int ret; -+ struct snd_soc_card *card = rtd->card; ++ if (digital_gain_0db_limit) ++ { ++ int ret; ++ struct snd_soc_card *card = rtd->card; + -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } + + return 0; +} @@ -115937,6 +118249,7 @@ index 0000000..37038d4 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_iqaudio_dac = { + .name = "IQaudIODAC", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_iqaudio_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), +}; @@ -115959,6 +118272,9 @@ index 0000000..37038d4 + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } ++ ++ digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, ++ "iqaudio,24db_digital_gain"); + } + + ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); @@ -115996,10 +118312,10 @@ index 0000000..37038d4 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From a5a08b66a1ac4a02bc9aaac168e363dd45f28087 Mon Sep 17 00:00:00 2001 +From 8ca6dfd134bd0117e548b050e0af99bd09f1fd92 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 065/251] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 065/114] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -116007,7 +118323,7 @@ Reduces overhead when using X 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index 5dd426f..9ae0cd5 100644 +index ae83af6..4a7af9d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -49,7 +49,7 @@ @@ -116019,7 +118335,7 @@ index 5dd426f..9ae0cd5 100644 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1091,8 +1091,12 @@ static int usbhid_start(struct hid_device *hid) +@@ -1083,8 +1083,12 @@ static int usbhid_start(struct hid_device *hid) } /* Change the polling interval of mice. */ @@ -116035,20 +118351,214 @@ index 5dd426f..9ae0cd5 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From 6181933c3fb422cf92cf1f2720064e48d1f93955 Mon Sep 17 00:00:00 2001 +From 84f1f5340ba06631612745253d8989998e324f5a Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 066/251] Added support for HiFiBerry DAC+ +Subject: [PATCH 066/114] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. + +Add support for the HiFiBerry DAC+ Pro. + +The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. + +An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. + +Limit PCM512x "Digital" gain to 0dB by default with HiFiBerry DAC+ + +24db_digital_gain DT param can be used to specify that PCM512x +codec "Digital" volume control should not be limited to 0dB gain, +and if specified will allow the full 24dB gain. --- - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_dacplus.c | 141 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 150 insertions(+) + drivers/clk/Makefile | 1 + + drivers/clk/clk-hifiberry-dacpro.c | 160 +++++++++++++++++ + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplus.c | 352 +++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/pcm512x.c | 3 +- + 6 files changed, 524 insertions(+), 1 deletion(-) + create mode 100644 drivers/clk/clk-hifiberry-dacpro.c create mode 100644 sound/soc/bcm/hifiberry_dacplus.c +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 46869d6..a202e6f 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o + obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o + obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o + obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o + obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o + obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o + obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o +diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c +new file mode 100644 +index 0000000..3e35d45 +--- /dev/null ++++ b/drivers/clk/clk-hifiberry-dacpro.c +@@ -0,0 +1,160 @@ ++/* ++ * Clock Driver for HiFiBerry DAC Pro ++ * ++ * Author: Stuart MacLean ++ * Copyright 2015 ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++/** ++ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro ++ * @hw: clk_hw for the common clk framework ++ * @mode: 0 => CLK44EN, 1 => CLK48EN ++ */ ++struct clk_hifiberry_hw { ++ struct clk_hw hw; ++ uint8_t mode; ++}; ++ ++#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) ++ ++static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { ++ { .compatible = "hifiberry,dacpro-clk",}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); ++ ++static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : ++ CLK_48EN_RATE; ++} ++ ++static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, ++ unsigned long rate, unsigned long *parent_rate) ++{ ++ long actual_rate; ++ ++ if (rate <= CLK_44EN_RATE) { ++ actual_rate = (long)CLK_44EN_RATE; ++ } else if (rate >= CLK_48EN_RATE) { ++ actual_rate = (long)CLK_48EN_RATE; ++ } else { ++ long diff44Rate = (long)(rate - CLK_44EN_RATE); ++ long diff48Rate = (long)(CLK_48EN_RATE - rate); ++ ++ if (diff44Rate < diff48Rate) ++ actual_rate = (long)CLK_44EN_RATE; ++ else ++ actual_rate = (long)CLK_48EN_RATE; ++ } ++ return actual_rate; ++} ++ ++ ++static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, ++ unsigned long rate, unsigned long parent_rate) ++{ ++ unsigned long actual_rate; ++ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); ++ ++ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, ++ &parent_rate); ++ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; ++ return 0; ++} ++ ++ ++const struct clk_ops clk_hifiberry_dacpro_rate_ops = { ++ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, ++ .round_rate = clk_hifiberry_dacpro_round_rate, ++ .set_rate = clk_hifiberry_dacpro_set_rate, ++}; ++ ++static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) ++{ ++ int ret; ++ struct clk_hifiberry_hw *proclk; ++ struct clk *clk; ++ struct device *dev; ++ struct clk_init_data init; ++ ++ dev = &pdev->dev; ++ ++ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); ++ if (!proclk) ++ return -ENOMEM; ++ ++ init.name = "clk-hifiberry-dacpro"; ++ init.ops = &clk_hifiberry_dacpro_rate_ops; ++ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; ++ init.parent_names = NULL; ++ init.num_parents = 0; ++ ++ proclk->mode = 0; ++ proclk->hw.init = &init; ++ ++ clk = devm_clk_register(dev, &proclk->hw); ++ if (!IS_ERR(clk)) { ++ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, ++ clk); ++ } else { ++ dev_err(dev, "Fail to register clock driver\n"); ++ kfree(proclk); ++ ret = PTR_ERR(clk); ++ } ++ return ret; ++} ++ ++static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) ++{ ++ of_clk_del_provider(pdev->dev.of_node); ++ return 0; ++} ++ ++static struct platform_driver clk_hifiberry_dacpro_driver = { ++ .probe = clk_hifiberry_dacpro_probe, ++ .remove = clk_hifiberry_dacpro_remove, ++ .driver = { ++ .name = "clk-hifiberry-dacpro", ++ .of_match_table = clk_hifiberry_dacpro_dt_ids, ++ }, ++}; ++ ++static int __init clk_hifiberry_dacpro_init(void) ++{ ++ return platform_driver_register(&clk_hifiberry_dacpro_driver); ++} ++core_initcall(clk_hifiberry_dacpro_init); ++ ++static void __exit clk_hifiberry_dacpro_exit(void) ++{ ++ platform_driver_unregister(&clk_hifiberry_dacpro_driver); ++} ++module_exit(clk_hifiberry_dacpro_exit); ++ ++MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:clk-hifiberry-dacpro"); diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig index 38dcdd9..8c338b5 100644 --- a/sound/soc/bcm/Kconfig @@ -116087,15 +118597,15 @@ index 08e4dc5..a29538e 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c new file mode 100644 -index 0000000..11e4f39 +index 0000000..03d8d2a --- /dev/null +++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -0,0 +1,141 @@ +@@ -0,0 +1,352 @@ +/* -+ * ASoC Driver for HiFiBerry DAC+ ++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro + * -+ * Author: Daniel Matuschek -+ * Copyright 2014 ++ * Author: Daniel Matuschek, Stuart MacLean ++ * Copyright 2014-2015 + * based on code by Florian Meier + * + * This program is free software; you can redistribute it and/or @@ -116110,6 +118620,13 @@ index 0000000..11e4f39 + +#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include +#include @@ -116119,34 +118636,233 @@ index 0000000..11e4f39 + +#include "../codecs/pcm512x.h" + ++#define HIFIBERRY_DACPRO_NOCLOCK 0 ++#define HIFIBERRY_DACPRO_CLK44EN 1 ++#define HIFIBERRY_DACPRO_CLK48EN 2 ++ ++struct pcm512x_priv { ++ struct regmap *regmap; ++ struct clk *sclk; ++}; ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++static bool snd_rpi_hifiberry_is_dacpro; ++static bool digital_gain_0db_limit = true; ++ ++static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, ++ int clk_id) ++{ ++ switch (clk_id) { ++ case HIFIBERRY_DACPRO_NOCLOCK: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); ++ break; ++ case HIFIBERRY_DACPRO_CLK44EN: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); ++ break; ++ case HIFIBERRY_DACPRO_CLK48EN: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); ++ break; ++ } ++} ++ ++static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) ++{ ++ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) ++{ ++ int sck; ++ ++ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); ++ return (!(sck & 0x40)); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( ++ struct snd_soc_codec *codec) ++{ ++ msleep(2); ++ return snd_rpi_hifiberry_dacplus_is_sclk(codec); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) ++{ ++ bool isClk44EN, isClk48En, isNoClk; ++ ++ snd_rpi_hifiberry_dacplus_clk_gpio(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); ++ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); ++ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); ++ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ return (isClk44EN && isClk48En && !isNoClk); ++} ++ ++static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) ++{ ++ int type; ++ ++ switch (sample_rate) { ++ case 11025: ++ case 22050: ++ case 44100: ++ case 88200: ++ case 176400: ++ type = HIFIBERRY_DACPRO_CLK44EN; ++ break; ++ default: ++ type = HIFIBERRY_DACPRO_CLK48EN; ++ break; ++ } ++ return type; ++} ++ ++static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, ++ int sample_rate) ++{ ++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); ++ ++ if (!IS_ERR(pcm512x->sclk)) { ++ int ctype; ++ ++ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); ++ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) ++ ? CLK_44EN_RATE : CLK_48EN_RATE); ++ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); ++ } ++} ++ +static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; ++ struct pcm512x_priv *priv; ++ ++ snd_rpi_hifiberry_is_dacpro ++ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_dai_link *dai = rtd->dai_link; ++ ++ dai->name = "HiFiBerry DAC+ Pro"; ++ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; ++ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBM_CFM; ++ ++ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); ++ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); ++ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); ++ } else { ++ priv = snd_soc_codec_get_drvdata(codec); ++ priv->sclk = ERR_PTR(-ENOENT); ++ } ++ + snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ ++ if (digital_gain_0db_limit) ++ { ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } ++ + return 0; +} + -+static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) ++static int snd_rpi_hifiberry_dacplus_update_rate_den( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); ++ struct snd_ratnum *rats_no_pll; ++ unsigned int num = 0, den = 0; ++ int err; ++ ++ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); ++ if (!rats_no_pll) ++ return -ENOMEM; ++ ++ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; ++ rats_no_pll->den_min = 1; ++ rats_no_pll->den_max = 128; ++ rats_no_pll->den_step = 1; ++ ++ err = snd_interval_ratnum(hw_param_interval(params, ++ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); ++ if (err >= 0 && den) { ++ params->rate_num = num; ++ params->rate_den = den; ++ } ++ ++ devm_kfree(rtd->dev, rats_no_pll); + return 0; +} + -+static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { ++static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( ++ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) ++{ ++ int bratio = snd_pcm_format_physical_width(params_format(params)) ++ * params_channels(params); ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); ++} ++ ++static int snd_rpi_hifiberry_dacplus_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ int ret; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_rpi_hifiberry_dacplus_set_sclk(codec, ++ params_rate(params)); ++ ++ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, ++ params); ++ if (!ret) ++ ret = snd_rpi_hifiberry_dacplus_update_rate_den( ++ substream, params); ++ } else { ++ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++ } ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dacplus_startup( ++ struct snd_pcm_substream *substream) ++{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); ++ ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplus_shutdown( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); +} + +/* machine stream operations */ @@ -116174,6 +118890,7 @@ index 0000000..11e4f39 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_dacplus = { + .name = "snd_rpi_hifiberry_dacplus", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_dacplus_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), +}; @@ -116183,19 +118900,23 @@ index 0000000..11e4f39 + int ret = 0; + + snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ + if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; + -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } ++ dai = &snd_rpi_hifiberry_dacplus_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ ++ digital_gain_0db_limit = !of_property_read_bool( ++ pdev->dev.of_node, "hifiberry,24db_digital_gain"); + } + + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); @@ -116232,11 +118953,25 @@ index 0000000..11e4f39 +MODULE_AUTHOR("Daniel Matuschek "); +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c +index 047c489..090fe0e 100644 +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -854,7 +854,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, + int fssp; + int gpio; + +- lrclk_div = snd_soc_params_to_frame_size(params); ++ lrclk_div = snd_pcm_format_physical_width(params_format(params)) ++ * params_channels(params); + if (lrclk_div == 0) { + dev_err(dev, "No LRCLK?\n"); + return -EINVAL; -From 2804c1880d7b34b85e35eaa503fee6d648c243de Mon Sep 17 00:00:00 2001 +From 85af785da011ab32246855f5d2bbb57354e66feb Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 067/251] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 067/114] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. @@ -116254,12 +118989,12 @@ Some code to load the driver based on device-tree-overlays was missing. This is --- sound/soc/bcm/Kconfig | 7 + sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_amp.c | 127 +++++++++++++++ + sound/soc/bcm/hifiberry_amp.c | 128 +++++++++++++++ sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/tas5713.h | 210 ++++++++++++++++++++++++ - 7 files changed, 721 insertions(+) + 7 files changed, 722 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_amp.c create mode 100644 sound/soc/codecs/tas5713.c create mode 100644 sound/soc/codecs/tas5713.h @@ -116302,10 +119037,10 @@ index a29538e..30db495 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c new file mode 100644 -index 0000000..5903915 +index 0000000..0bb12e4 --- /dev/null +++ b/sound/soc/bcm/hifiberry_amp.c -@@ -0,0 +1,127 @@ +@@ -0,0 +1,128 @@ +/* + * ASoC Driver for HifiBerry AMP + * @@ -116369,6 +119104,7 @@ index 0000000..5903915 + +static struct snd_soc_card snd_rpi_hifiberry_amp = { + .name = "snd_rpi_hifiberry_amp", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_amp_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), +}; @@ -116434,10 +119170,10 @@ index 0000000..5903915 +MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index b63f2fb..fe32cca 100644 +index 214af16..06be5a2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -117,6 +117,7 @@ config SND_SOC_ALL_CODECS +@@ -129,6 +129,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TFA9879 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER @@ -116445,7 +119181,7 @@ index b63f2fb..fe32cca 100644 select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC31XX if I2C select SND_SOC_TLV320AIC32X4 if I2C -@@ -674,6 +675,9 @@ config SND_SOC_TFA9879 +@@ -758,6 +759,9 @@ config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C @@ -116456,10 +119192,10 @@ index b63f2fb..fe32cca 100644 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 2147436..dbb213d 100644 +index b87e845..9974a13 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -118,6 +118,7 @@ snd-soc-sti-sas-objs := sti-sas.o +@@ -132,6 +132,7 @@ snd-soc-sti-sas-objs := sti-sas.o snd-soc-tas5086-objs := tas5086.o snd-soc-tas571x-objs := tas571x.o snd-soc-tfa9879-objs := tfa9879.o @@ -116467,7 +119203,7 @@ index 2147436..dbb213d 100644 snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -312,6 +313,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o +@@ -340,6 +341,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o @@ -117067,10 +119803,10 @@ index 0000000..8f019e0 + +#endif /* _TAS5713_H */ -From cb468b5a1270e4819be26c8cacfd0cb6c70be776 Mon Sep 17 00:00:00 2001 +From f8bae62b0dd99d5820498f1e20e77d366af8dcfe Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 068/251] Update ds1307 driver for device-tree support +Subject: [PATCH 068/114] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -117078,10 +119814,10 @@ Signed-off-by: Ryan Coe 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index aa705bb..1cb13fe 100644 +index b2156ee..4ba33ee 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c -@@ -1207,6 +1207,14 @@ static int ds1307_remove(struct i2c_client *client) +@@ -1605,6 +1605,14 @@ static int ds1307_remove(struct i2c_client *client) return 0; } @@ -117097,10 +119833,10 @@ index aa705bb..1cb13fe 100644 .driver = { .name = "rtc-ds1307", -From e545dfb5383a8d5d775818282c7f95ae7a2e1f72 Mon Sep 17 00:00:00 2001 +From 095e4b2962f86a593d2ee02655e5a4ad03701fba Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 069/251] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 069/114] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support @@ -117130,35 +119866,28 @@ See: https://github.com/raspberrypi/linux/issues/1064 create mode 100644 drivers/leds/trigger/ledtrig-input.c diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 5db4515..685a8b5 100644 +index 61143f5..e98df59 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c -@@ -42,6 +42,13 @@ static void gpio_led_work(struct work_struct *work) - led_dat->platform_gpio_blink_set(led_dat->gpiod, - led_dat->new_level, NULL, NULL); +@@ -46,8 +46,15 @@ static void gpio_led_set(struct led_classdev *led_cdev, + led_dat->platform_gpio_blink_set(led_dat->gpiod, level, + NULL, NULL); led_dat->blinking = 0; + } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { + gpiod_direction_input(led_dat->gpiod); + led_dat->cdev.flags &= ~SET_GPIO_INPUT; -+ } -+ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { -+ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); ++ } else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { ++ gpiod_direction_output(led_dat->gpiod, level); + led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; - } else - gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); - } -@@ -62,7 +69,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, - * seem to have a reliable way to know if we're already in one; so - * let's just assume the worst. - */ -- if (led_dat->can_sleep) { -+ if (led_dat->can_sleep || -+ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { - led_dat->new_level = level; - schedule_work(&led_dat->work); } else { -@@ -75,6 +83,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, - } +- if (led_dat->can_sleep) ++ if (led_dat->can_sleep || ++ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) + gpiod_set_value_cansleep(led_dat->gpiod, level); + else + gpiod_set_value(led_dat->gpiod, level); +@@ -61,6 +68,13 @@ static int gpio_led_set_blocking(struct led_classdev *led_cdev, + return 0; } +static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) @@ -117171,10 +119900,11 @@ index 5db4515..685a8b5 100644 static int gpio_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { -@@ -131,6 +146,7 @@ static int create_gpio_led(const struct gpio_led *template, +@@ -120,6 +134,8 @@ static int create_gpio_led(const struct gpio_led *template, + led_dat->platform_gpio_blink_set = blink_set; led_dat->cdev.blink_set = gpio_blink_set; } - led_dat->cdev.brightness_set = gpio_led_set; ++ led_dat->cdev.brightness_set = gpio_led_set; + led_dat->cdev.brightness_get = gpio_led_get; if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) state = !!gpiod_get_value_cansleep(led_dat->gpiod); @@ -117206,7 +119936,7 @@ index 1abf48d..c03afdc 100644 +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c new file mode 100644 -index 0000000..07d1219 +index 0000000..27f8ebe --- /dev/null +++ b/drivers/leds/trigger/ledtrig-input.c @@ -0,0 +1,54 @@ @@ -117233,13 +119963,13 @@ index 0000000..07d1219 +static void input_trig_activate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_INPUT; -+ led_set_brightness_async(led_cdev, 0); ++ led_set_brightness(led_cdev, 0); +} + +static void input_trig_deactivate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_OUTPUT; -+ led_set_brightness_async(led_cdev, 0); ++ led_set_brightness(led_cdev, 0); +} + +static struct led_trigger input_led_trigger = { @@ -117265,24 +119995,24 @@ index 0000000..07d1219 +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); diff --git a/include/linux/leds.h b/include/linux/leds.h -index fa359c7..4b25a1a 100644 +index f203a8f..555cf15 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h -@@ -48,6 +48,9 @@ struct led_classdev { - #define SET_BRIGHTNESS_ASYNC (1 << 21) - #define SET_BRIGHTNESS_SYNC (1 << 22) +@@ -50,6 +50,9 @@ struct led_classdev { + #define LED_SYSFS_DISABLE (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) + #define LED_HW_PLUGGABLE (1 << 24) + /* Additions for Raspberry Pi PWR LED */ +#define SET_GPIO_INPUT (1 << 30) +#define SET_GPIO_OUTPUT (1 << 31) - /* Set LED brightness level */ - /* Must not sleep, use a workqueue if needed */ + /* Set LED brightness level + * Must not sleep. Use brightness_set_blocking for drivers -From f6d9d6ba910f1604a3d488091f052a57f14cd998 Mon Sep 17 00:00:00 2001 +From 1cfd22d5f3cbc9b1c6eadee234f07e9285ae46fe Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 070/251] enc28j60: Add device tree compatible string and an +Subject: [PATCH 070/114] enc28j60: Add device tree compatible string and an overlay --- @@ -117311,10 +120041,10 @@ index 86ea17e..a1b20c1 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From 68eb237af6a1c15b68fb1eff1596d152f06eeaa5 Mon Sep 17 00:00:00 2001 +From 28eeb1b06004f5a4e3e89f516e4678ca3c4c82d9 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 071/251] Add driver for rpi-proto +Subject: [PATCH 071/114] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -117329,8 +120059,8 @@ Signed-off-by: Waldemar Brodkorb --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 162 insertions(+) + sound/soc/bcm/rpi-proto.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 163 insertions(+) create mode 100644 sound/soc/bcm/rpi-proto.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -117371,10 +120101,10 @@ index 30db495..4f5ab1f 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/rpi-proto.c b/sound/soc/bcm/rpi-proto.c new file mode 100644 -index 0000000..c6e45a0 +index 0000000..9db678e --- /dev/null +++ b/sound/soc/bcm/rpi-proto.c -@@ -0,0 +1,153 @@ +@@ -0,0 +1,154 @@ +/* + * ASoC driver for PROTO AudioCODEC (with a WM8731) + * connected to a Raspberry Pi @@ -117468,6 +120198,7 @@ index 0000000..c6e45a0 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_proto = { + .name = "snd_rpi_proto", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_proto_dai, + .num_links = ARRAY_SIZE(snd_rpi_proto_dai), +}; @@ -117529,24 +120260,24 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From d76384c130898ee68885a8cddfbe4686ad41aa0f Mon Sep 17 00:00:00 2001 +From 6f2334146dea18d259dba83c9f89b42caba6efab Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 072/251] config: Add default configs +Subject: [PATCH 072/114] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1254 +++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1265 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 2519 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1262 +++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1271 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 2533 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..16062bf +index 0000000..177745a --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1254 @@ +@@ -0,0 +1,1262 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -117564,12 +120295,12 @@ index 0000000..16062bf +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y @@ -117589,6 +120320,7 @@ index 0000000..16062bf +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_ARCH_BCM2709=y +# CONFIG_CACHE_L2X0 is not set ++# CONFIG_DEBUG_RODATA is not set +CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_VMSPLIT_2G=y @@ -117648,1260 +120380,6 @@ index 0000000..16062bf +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=m -+CONFIG_IRCOMM=m -+CONFIG_IRDA_ULTRA=y -+CONFIG_IRDA_CACHE_LAST_LSAP=y -+CONFIG_IRDA_FAST_RR=y -+CONFIG_IRTTY_SIR=m -+CONFIG_KINGSUN_DONGLE=m -+CONFIG_KSDAZZLE_DONGLE=m -+CONFIG_KS959_DONGLE=m -+CONFIG_USB_IRDA=m -+CONFIG_SIGMATEL_FIR=m -+CONFIG_MCS_FIR=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m -+CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m -+CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m -+CONFIG_USB_NET_SMSC95XX=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_FT6236=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM_VC_SM=y -+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=y -+CONFIG_RAW_DRIVER=y -+CONFIG_I2C=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_SPI=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=m -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m -+CONFIG_FB=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_UDL=m -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_MIXER_OSS=m -+CONFIG_SND_PCM_OSS=m -+CONFIG_SND_SEQUENCER_OSS=y -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_BCM2835=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=y -+CONFIG_UHID=m -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m -+CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_LED=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m -+CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+CONFIG_LEDS_TRIGGER_ONESHOT=y -+CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y -+CONFIG_LEDS_TRIGGER_CPU=y -+CONFIG_LEDS_TRIGGER_GPIO=y -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m -+CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_RPI=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9163=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER=y -+CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_KFIFO_BUF=m -+CONFIG_MCP320X=m -+CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m -+CONFIG_RASPBERRYPI_FIRMWARE=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y -+CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+CONFIG_DLM=m -+CONFIG_PRINTK_TIME=y -+CONFIG_BOOT_PRINTK_DELAY=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_TIMER_STATS=y -+CONFIG_IRQSOFF_TRACER=y -+CONFIG_SCHED_TRACER=y -+CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set -+CONFIG_FUNCTION_PROFILER=y -+CONFIG_KGDB=y -+CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+CONFIG_CRYPTO_USER_API_SKCIPHER=m -+# CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_AES_ARM_BS=m -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -new file mode 100644 -index 0000000..1d1b799 ---- /dev/null -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1265 @@ -+# CONFIG_ARM_PATCH_PHYS_VIRT is not set -+CONFIG_PHYS_OFFSET=0 -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_FHANDLE=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y -+CONFIG_NAMESPACES=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_EMBEDDED=y -+# CONFIG_COMPAT_BRK is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y -+CONFIG_JUMP_LABEL=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y -+CONFIG_ARCH_BCM2708=y -+CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_UACCESS_WITH_MEMCPY=y -+CONFIG_SECCOMP=y -+# CONFIG_ATAGS is not set -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 -+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_VFP=y -+CONFIG_BINFMT_MISC=m -+# CONFIG_SUSPEND is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m @@ -119179,6 +120657,8 @@ index 0000000..1d1b799 +CONFIG_BT_6LOWPAN=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m @@ -119203,6 +120683,7 @@ index 0000000..1d1b799 +CONFIG_MTD_BLOCK=m +CONFIG_MTD_NAND=m +CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y +CONFIG_ZRAM=m +CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y @@ -119245,6 +120726,7 @@ index 0000000..1d1b799 +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_ENC28J60=m ++CONFIG_QCA7000=m +CONFIG_MDIO_BITBANG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m @@ -119296,31 +120778,29 @@ index 0000000..1d1b799 +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m +CONFIG_B43=m +# CONFIG_B43_PHY_N is not set +CONFIG_B43LEGACY=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m @@ -119329,12 +120809,12 @@ index 0000000..1d1b799 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m ++CONFIG_RTL8187=m +CONFIG_RTL8192CU=m ++CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m @@ -119388,17 +120868,1280 @@ index 0000000..1d1b799 +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_BCM2708=m ++CONFIG_I2C_GPIO=m +CONFIG_SPI=y +CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m ++CONFIG_SPI_SPIDEV=y ++CONFIG_PPS=m ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_BCM_VIRT=y ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2760=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_W1_SLAVE_BQ27000=m ++CONFIG_BATTERY_DS2760=m ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m ++CONFIG_THERMAL=y ++CONFIG_THERMAL_BCM2835=y ++CONFIG_WATCHDOG=y ++CONFIG_BCM2835_WDT=m ++CONFIG_UCB1400_CORE=m ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_LIRC=m ++CONFIG_RC_DEVICES=y ++CONFIG_RC_ATI_REMOTE=m ++CONFIG_IR_IMON=m ++CONFIG_IR_MCEUSB=m ++CONFIG_IR_REDRAT3=m ++CONFIG_IR_STREAMZAP=m ++CONFIG_IR_IGUANA=m ++CONFIG_IR_TTUSBIR=m ++CONFIG_RC_LOOPBACK=m ++CONFIG_IR_GPIO_CIR=m ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_STK1160_AC97=y ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_RC=y ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++CONFIG_DVB_USB=m ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_CXUSB=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_VP7045=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_FRIIO=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835=y ++CONFIG_VIDEO_BCM2835_MMAL=m ++CONFIG_RADIO_SI470X=y ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV7640=m ++CONFIG_VIDEO_MT9V011=m ++CONFIG_DRM=m ++CONFIG_DRM_VC4=m ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_UDL=m ++CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m ++CONFIG_BACKLIGHT_GPIO=m ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HIDRAW=y ++CONFIG_UHID=m ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_ELO=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_PRINTER=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_F81232=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SPI=m ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++CONFIG_LEDS_TRIGGER_GPIO=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_ISL12057=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2835=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m ++CONFIG_STAGING=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_R8723AU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_LIRC_STAGING=y ++CONFIG_LIRC_IMON=m ++CONFIG_LIRC_RPI=m ++CONFIG_LIRC_SASEM=m ++CONFIG_LIRC_SERIAL=m ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_ILI9163=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2835_MBOX=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=m ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_MCP320X=m ++CONFIG_MCP3422=m ++CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_QFMT_V1=m ++CONFIG_QFMT_V2=m ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_NTFS_RW=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_DLM=m ++CONFIG_PRINTK_TIME=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_KPROBE_EVENT is not set ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_USER_API_SKCIPHER=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_AES_ARM_BS=m ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +new file mode 100644 +index 0000000..0b87299 +--- /dev/null ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -0,0 +1,1271 @@ ++# CONFIG_ARM_PATCH_PHYS_VIRT is not set ++CONFIG_PHYS_OFFSET=0 ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_FHANDLE=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_PREEMPT_VOLUNTARY=y ++CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y ++CONFIG_UACCESS_WITH_MEMCPY=y ++CONFIG_SECCOMP=y ++# CONFIG_ATAGS is not set ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=m ++CONFIG_CPU_FREQ_STAT_DETAILS=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++# CONFIG_SUSPEND is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_DIAG=m ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CT_PROTO_DCCP=m ++CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_IEEE802154=m ++CONFIG_IEEE802154_6LOWPAN=m ++CONFIG_MAC802154=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRNET=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_6LOWPAN=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_BT_WILINK=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_MD_RAID0=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_ENC28J60=m ++CONFIG_QCA7000=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8187=m ++CONFIG_RTL8192CU=m ++CONFIG_USB_ZD1201=m ++CONFIG_ZD1211RW=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_IEEE802154_AT86RF230=m ++CONFIG_IEEE802154_MRF24J40=m ++CONFIG_IEEE802154_CC2520=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_FT6236=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y ++CONFIG_DEVPTS_MULTIPLE_INSTANCES=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++CONFIG_RAW_DRIVER=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX_PCA954x=m ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_GPIO=m ++CONFIG_SPI=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_SPIDEV=y +CONFIG_PPS=m +CONFIG_PPS_CLIENT_LDISC=m @@ -119604,12 +122347,15 @@ index 0000000..1d1b799 +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m ++CONFIG_DRM=m ++CONFIG_DRM_VC4=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_UDL=m +CONFIG_FB_SSD1307=m +CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y @@ -119836,14 +122582,12 @@ index 0000000..1d1b799 +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_ISL12057=m +CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m @@ -119859,12 +122603,13 @@ index 0000000..1d1b799 +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_BCM2708=y @@ -119923,6 +122668,7 @@ index 0000000..1d1b799 +CONFIG_IIO_BUFFER_CB=m +CONFIG_IIO_KFIFO_BUF=m +CONFIG_MCP320X=m ++CONFIG_MCP3422=m +CONFIG_DHT11=m +CONFIG_PWM_BCM2835=m +CONFIG_RASPBERRYPI_FIRMWARE=y @@ -119969,7 +122715,6 @@ index 0000000..1d1b799 +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_CONFIGFS_FS=y +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m @@ -120073,1439 +122818,10 @@ index 0000000..1d1b799 +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 704b0ef1532a29776c5a9df0fe8d93eabdff6f4d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 073/251] bcm2835: bcm2835_defconfig -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some options in bcm2835_defconfig are now the default and -some have changed. Update to keep functionality. - -No longer available: SCSI_MULTI_LUN and RESOURCE_COUNTERS. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig enable MMC_BCM2835 - -Enable the downstream bcm2835-mmc driver and DMA support. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig enable BCM2708_MBOX - -Enable the mailbox driver. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig use FB_BCM2708 - -Enable the bcm2708 framebuffer driver. -Disable the simple framebuffer driver, which matches the -device handed over by u-boot. - -Signed-off-by: Noralf Trønnes - -bcm2835: Merge bcm2835_defconfig with bcmrpi_defconfig - -These commands where used to make this commit: - -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_I2C_BCM2708 -CONFIG_SPI_BCM2708 -CONFIG_SND_BCM2708_SOC_I2S -CONFIG_USB_DWCOTG -CONFIG_LIRC_RPI -EOF - -grep -F -v -f filter merge.cfg > filtered.cfg - -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -ARCH=arm make oldconfig - -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -rm merge.cfg filter filtered.cfg added.cfg defconfig - -ARCH=arm make bcm2835_defconfig -ARCH=arm make oldconfig - -Signed-off-by: Noralf Trønnes - -configs: Incorporate v4.1 dependency changes - -Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a -dependency on TI_ST instead of selecting it, disabling: -CONFIG_BT_WILINK=m -CONFIG_RADIO_WL128X=m - -Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a -depency on ARM_CRYPTO, disabling: -CONFIG_CRYPTO_SHA*_ARM*=m -CONFIG_CRYPTO_AES_ARM*=m - -Signed-off-by: Noralf Trønnes - -Conflicts: - arch/arm/configs/bcm2709_defconfig - -bcm2835: Sync bcm2835_defconfig with bcmrpi_defconfig - -These commands where used to make this commit: - -: Get changed and new config values from a merge -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -: Remove these options -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_SPI_BCM2708 -EOF - -: Apply filter -grep -F -v -f filter merge.cfg > filtered.cfg - -: Add these options -: watchdog contains the restart/poweroff code. -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_I2C_BCM2835=m -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -: Create new config -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -: Verify -ARCH=arm make oldconfig - -: Update bcm2835_defconfig -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -: Clean up -rm merge.cfg filter filtered.cfg added.cfg defconfig - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 1166 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1140 insertions(+), 26 deletions(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..fdb2e2a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,105 +1,1103 @@ - # CONFIG_LOCALVERSION_AUTO is not set - CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y - CONFIG_FHANDLE=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_BSD_PROCESS_ACCT=y - CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y - CONFIG_LOG_BUF_SHIFT=18 - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y --CONFIG_RESOURCE_COUNTERS=y -+CONFIG_MEMCG=y - CONFIG_CGROUP_PERF=y - CONFIG_CFS_BANDWIDTH=y - CONFIG_RT_GROUP_SCHED=y -+CONFIG_BLK_CGROUP=y - CONFIG_NAMESPACES=y - CONFIG_SCHED_AUTOGROUP=y --CONFIG_RELAY=y - CONFIG_BLK_DEV_INITRD=y --CONFIG_RD_BZIP2=y --CONFIG_RD_LZMA=y --CONFIG_RD_XZ=y --CONFIG_RD_LZO=y - CONFIG_CC_OPTIMIZE_FOR_SIZE=y --CONFIG_KALLSYMS_ALL=y - CONFIG_EMBEDDED=y - # CONFIG_COMPAT_BRK is not set - CONFIG_PROFILING=y --CONFIG_OPROFILE=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y - CONFIG_JUMP_LABEL=y -+CONFIG_CC_STACKPROTECTOR_REGULAR=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_ARCH_MULTI_V6=y - # CONFIG_ARCH_MULTI_V7 is not set - CONFIG_ARCH_BCM=y - CONFIG_ARCH_BCM2835=y --CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_PREEMPT=y - CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y - CONFIG_KSM=y - CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y --CONFIG_CC_STACKPROTECTOR=y -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 - CONFIG_KEXEC=y - CONFIG_CRASH_DUMP=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - CONFIG_VFP=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_BINFMT_MISC=m - # CONFIG_SUSPEND is not set - CONFIG_NET=y - CONFIG_PACKET=y - CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m - CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y - CONFIG_NETWORK_SECMARK=y - CONFIG_NETFILTER=y --CONFIG_CFG80211=y --CONFIG_MAC80211=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=m -+CONFIG_IRCOMM=m -+CONFIG_IRDA_ULTRA=y -+CONFIG_IRDA_CACHE_LAST_LSAP=y -+CONFIG_IRDA_FAST_RR=y -+CONFIG_IRTTY_SIR=m -+CONFIG_KINGSUN_DONGLE=m -+CONFIG_KSDAZZLE_DONGLE=m -+CONFIG_KS959_DONGLE=m -+CONFIG_USB_IRDA=m -+CONFIG_SIGMATEL_FIR=m -+CONFIG_MCS_FIR=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - # CONFIG_STANDALONE is not set -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y --CONFIG_SCSI_MULTI_LUN=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m - CONFIG_SCSI_CONSTANTS=y - CONFIG_SCSI_SCAN_ASYNC=y -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m - CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m - CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m - CONFIG_USB_NET_SMSC95XX=y --CONFIG_ZD1211RW=y --CONFIG_INPUT_EVDEV=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM_VC_SM=y -+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m -+CONFIG_RAW_DRIVER=y - CONFIG_I2C=y --CONFIG_I2C_CHARDEV=y --CONFIG_I2C_BCM2835=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_I2C_BCM2835=m - CONFIG_SPI=y --CONFIG_SPI_BCM2835=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=y -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y --CONFIG_FB_SIMPLE=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_MIXER_OSS=m -+CONFIG_SND_PCM_OSS=m -+CONFIG_SND_SEQUENCER_OSS=y -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_BCM2835=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=y -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y - CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m - CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_DWC2=y -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_LED=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m - CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y - CONFIG_LEDS_TRIGGER_CPU=y - CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y --CONFIG_LEDS_TRIGGER_TRANSIENT=y --CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y --CONFIG_USB_DWC2=y --CONFIG_USB_DWC2_HOST=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_RPI=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER=y -+CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_KFIFO_BUF=m -+CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y -@@ -107,18 +1105,110 @@ CONFIG_EXT3_FS=y - CONFIG_EXT3_FS_POSIX_ACL=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --# CONFIG_MISC_FILESYSTEMS is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y - CONFIG_NFS_FS=y --CONFIG_NFSD=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" - CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m - CONFIG_NLS_ASCII=y --CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m - CONFIG_NLS_UTF8=y -+CONFIG_DLM=m - CONFIG_PRINTK_TIME=y - CONFIG_BOOT_PRINTK_DELAY=y - CONFIG_DYNAMIC_DEBUG=y -@@ -128,14 +1218,38 @@ CONFIG_DEBUG_INFO=y - CONFIG_UNUSED_SYMBOLS=y - CONFIG_DEBUG_MEMORY_INIT=y - CONFIG_LOCKUP_DETECTOR=y -+CONFIG_TIMER_STATS=y -+# CONFIG_DEBUG_PREEMPT is not set -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y - CONFIG_SCHED_TRACER=y - CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set - CONFIG_FUNCTION_PROFILER=y - CONFIG_TEST_KSTRTOX=y - CONFIG_KGDB=y - CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y - CONFIG_STRICT_DEVMEM=y - CONFIG_DEBUG_LL=y - CONFIG_EARLY_PRINTK=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CRYPTD=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA512=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set - # CONFIG_XZ_DEC_ARMTHUMB is not set - -From e3d855ae8766391b2c35d6c61b852e79ca9f9047 Mon Sep 17 00:00:00 2001 +From a1e6971294e3e911c461f9aefdc7882a154a0a9d Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 074/251] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 073/114] rpi-ft5406: Add touchscreen driver for pi LCD display Fix driver detection failure Check that the buffer response is non-zero meaning the touchscreen was detected @@ -121518,10 +122834,10 @@ rpi-ft5406: Use firmware API create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index ae33da7..5935716 100644 +index 8ecdc38..1e4e7a0 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -608,6 +608,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -630,6 +630,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. @@ -121536,7 +122852,7 @@ index ae33da7..5935716 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index cbaa6ab..13ab8c0 100644 +index f42975e..92590b3 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o @@ -121800,10 +123116,10 @@ index 0000000..b27dbee +MODULE_DESCRIPTION("Touchscreen driver for memory based FT5406"); +MODULE_LICENSE("GPL"); -From 7298b88fd999f55dc6dde8cb6288562f68b05e56 Mon Sep 17 00:00:00 2001 +From 3442c1202309c020f8dd61c76574cf414240daed Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 075/251] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 074/114] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use @@ -121812,6 +123128,15 @@ optimised memcpy/memmove/memcmp/memset implementations. arch/arm: Add mmiocpy/set aliases for memcpy/set See: https://github.com/raspberrypi/linux/issues/1082 + +copy_from_user: CPU_SW_DOMAIN_PAN compatibility + +The downstream copy_from_user acceleration must also play nice with +CONFIG_CPU_SW_DOMAIN_PAN. + +See: https://github.com/raspberrypi/linux/issues/1381 + +Signed-off-by: Phil Elwell --- arch/arm/include/asm/string.h | 5 + arch/arm/include/asm/uaccess.h | 3 + @@ -121824,8 +123149,8 @@ See: https://github.com/raspberrypi/linux/issues/1082 arch/arm/lib/memcpymove.h | 506 +++++++++++++++++++++++++++++++++++++ arch/arm/lib/memmove_rpi.S | 61 +++++ arch/arm/lib/memset_rpi.S | 123 +++++++++ - arch/arm/lib/uaccess_with_memcpy.c | 112 +++++++- - 12 files changed, 1365 insertions(+), 6 deletions(-) + arch/arm/lib/uaccess_with_memcpy.c | 120 ++++++++- + 12 files changed, 1373 insertions(+), 6 deletions(-) create mode 100644 arch/arm/lib/arm-mem.h create mode 100644 arch/arm/lib/exports_rpi.c create mode 100644 arch/arm/lib/memcmp_rpi.S @@ -123191,7 +124516,7 @@ index 0000000..7067415 +ENDPROC(memset) +ENDPROC(mmioset) diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index 588bbc2..c29df92 100644 +index 6bd1089..cd17dd1 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -22,6 +22,14 @@ @@ -123209,7 +124534,7 @@ index 588bbc2..c29df92 100644 static int pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) { -@@ -85,7 +93,44 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) +@@ -84,7 +92,44 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) return 1; } @@ -123255,13 +124580,14 @@ index 588bbc2..c29df92 100644 __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) { unsigned long ua_flags; -@@ -138,6 +183,54 @@ out: +@@ -137,6 +182,57 @@ out: return n; } +unsigned long noinline +__copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) +{ ++ unsigned long ua_flags; + int atomic; + + if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { @@ -123293,7 +124619,9 @@ index 588bbc2..c29df92 100644 + if (tocopy > n) + tocopy = n; + ++ ua_flags = uaccess_save_and_enable(); + memcpy(to, (const void *)from, tocopy); ++ uaccess_restore(ua_flags); + to += tocopy; + from += tocopy; + n -= tocopy; @@ -123310,7 +124638,7 @@ index 588bbc2..c29df92 100644 unsigned long arm_copy_to_user(void __user *to, const void *from, unsigned long n) { -@@ -148,7 +241,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -147,7 +243,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) * With frame pointer disabled, tail call optimization kicks in * as well making this test almost invisible. */ @@ -123319,7 +124647,7 @@ index 588bbc2..c29df92 100644 unsigned long ua_flags = uaccess_save_and_enable(); n = __copy_to_user_std(to, from, n); uaccess_restore(ua_flags); -@@ -157,6 +250,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -156,6 +252,26 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) } return n; } @@ -123334,18 +124662,23 @@ index 588bbc2..c29df92 100644 + * With frame pointer disabled, tail call optimization kicks in + * as well making this test almost invisible. + */ -+ if (n < COPY_FROM_USER_THRESHOLD) -+ return __copy_from_user_std(to, from, n); -+ return __copy_from_user_memcpy(to, from, n); ++ if (n < COPY_TO_USER_THRESHOLD) { ++ unsigned long ua_flags = uaccess_save_and_enable(); ++ n = __copy_from_user_std(to, from, n); ++ uaccess_restore(ua_flags); ++ } else { ++ n = __copy_from_user_memcpy(to, from, n); ++ } ++ return n; +} static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From e8f27792e51eda819e6918697a67dc85a2d2fc13 Mon Sep 17 00:00:00 2001 +From 0813a534e8677a29f014d32722f373e42bf2aa93 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 076/251] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 075/114] gpio-poweroff: Allow it to work on Raspberry Pi The Raspberry Pi firmware manages the power-down and reboot process. To do this it installs a pm_power_off handler, causing @@ -123380,4442 +124713,10 @@ index be3d81f..a030ae9 100644 "%s: pm_power_off function already registered", __func__); -From e1cb11c1118f942ad55724ec8036065cbba41a62 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 077/251] spidev: Add "spidev" compatible string to silence - warning - -See: https://github.com/raspberrypi/linux/issues/1054 ---- - drivers/spi/spidev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index d0e7dfc..57b0760 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -695,6 +695,7 @@ static struct class *spidev_class; - static const struct of_device_id spidev_dt_ids[] = { - { .compatible = "rohm,dh2228fv" }, - { .compatible = "lineartechnology,ltc2488" }, -+ { .compatible = "spidev" }, - {}, - }; - MODULE_DEVICE_TABLE(of, spidev_dt_ids); - -From e74c88c3ce4685417d4a3aee8ce6cd22092c5315 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 17:00:18 +0100 -Subject: [PATCH 078/251] scripts/dtc: Add overlay support - ---- - scripts/dtc/checks.c | 119 ++- - scripts/dtc/dtc-lexer.l | 5 + - scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++----- - scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++++++--------------- - scripts/dtc/dtc-parser.tab.h_shipped | 107 +- - scripts/dtc/dtc-parser.y | 23 +- - scripts/dtc/dtc.c | 9 +- - scripts/dtc/dtc.h | 38 + - scripts/dtc/flattree.c | 141 ++- - scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1685 insertions(+), 1145 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index e81a8c7..efd1bc6 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -458,21 +458,91 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -+ struct fixup *f, **fp; -+ struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -+ int has_phandle_refs; -+ -+ has_phandle_refs = 0; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ has_phandle_refs = 1; -+ break; -+ } -+ -+ if (!has_phandle_refs) -+ return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -+ if (!refnode && !symbol_fixup_support) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); -+ if (!refnode) { -+ /* allocate fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* search for an already existing fixup */ -+ for_each_fixup(dt, f) -+ if (strcmp(f->ref, m->ref) == 0) -+ break; -+ -+ /* no fixup found, add new */ -+ if (f == NULL) { -+ f = xmalloc(sizeof(*f)); -+ f->ref = m->ref; -+ f->entries = NULL; -+ f->next = NULL; -+ -+ /* add it to the tree */ -+ fp = &dt->fixups; -+ while (*fp) -+ fp = &(*fp)->next; -+ *fp = f; -+ } -+ -+ /* and now append fixup entry */ -+ fep = &f->entries; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ -+ /* mark the entry as unresolved */ -+ phandle = 0xdeadbeef; -+ } else { -+ phandle = get_node_phandle(dt, refnode); -+ -+ /* if it's a plugin, we need to record it */ -+ if (symbol_fixup_support && dt->is_plugin) { -+ -+ /* allocate a new local fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* append it to the local fixups */ -+ fep = &dt->local_fixups; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ } -+ } -+ -+ *((cell_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(phandle); - } - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -@@ -652,6 +722,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - -+static void check_auto_label_phandles(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct label *l; -+ struct symbol *s, **sp; -+ int has_label; -+ -+ if (!symbol_fixup_support) -+ return; -+ -+ has_label = 0; -+ for_each_label(node->labels, l) { -+ has_label = 1; -+ break; -+ } -+ -+ if (!has_label) -+ return; -+ -+ /* force allocation of a phandle for this node */ -+ (void)get_node_phandle(dt, node); -+ -+ /* add the symbol */ -+ for_each_label(node->labels, l) { -+ -+ s = xmalloc(sizeof(*s)); -+ s->label = l; -+ s->node = node; -+ s->next = NULL; -+ -+ /* add it to the symbols list */ -+ sp = &dt->symbols; -+ while (*sp) -+ sp = &((*sp)->next); -+ *sp = s; -+ } -+} -+NODE_WARNING(auto_label_phandles, NULL); -+ - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -670,6 +779,8 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -+ &auto_label_phandles, -+ - &always_fail, - }; - -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 0ee1caf..dd44ba2 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 11cd78e..1518525 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -9,7 +9,7 @@ - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 - #define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 39 -+#define YY_FLEX_SUBMINOR_VERSION 35 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -162,12 +162,7 @@ typedef unsigned int flex_uint32_t; - typedef struct yy_buffer_state *YY_BUFFER_STATE; - #endif - --#ifndef YY_TYPEDEF_YY_SIZE_T --#define YY_TYPEDEF_YY_SIZE_T --typedef size_t yy_size_t; --#endif -- --extern yy_size_t yyleng; -+extern int yyleng; - - extern FILE *yyin, *yyout; - -@@ -176,7 +171,6 @@ extern FILE *yyin, *yyout; - #define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) -- #define YY_LINENO_REWIND_TO(ptr) - - /* Return all but the first "n" matched characters back to the input stream. */ - #define yyless(n) \ -@@ -194,6 +188,11 @@ extern FILE *yyin, *yyout; - - #define unput(c) yyunput( c, (yytext_ptr) ) - -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ - #ifndef YY_STRUCT_YY_BUFFER_STATE - #define YY_STRUCT_YY_BUFFER_STATE - struct yy_buffer_state -@@ -211,7 +210,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- yy_size_t yy_n_chars; -+ int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -281,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ --yy_size_t yyleng; -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ -+int yyleng; - - /* Points to current character in buffer. */ - static char *yy_c_buf_p = (char *) 0; -@@ -310,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - - YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); - YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - - void *yyalloc (yy_size_t ); - void *yyrealloc (void *,yy_size_t ); -@@ -342,7 +341,7 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap() 1 -+#define yywrap(n) 1 - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; -@@ -373,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -382,25 +381,26 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[159] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst flex_int32_t yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[173] = -+static yyconst flex_int16_t yy_base[180] = - { 0, -- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -- -- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -- 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[173] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[438] = -+static yyconst flex_int16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -- -- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -- -- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[438] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -- -- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -- -- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -662,7 +664,7 @@ static int dts_version = 1; - static void push_input_file(const char *filename); - static bool pop_input_file(void); - static void lexical_error(const char *fmt, ...); --#line 666 "dtc-lexer.lex.c" -+#line 668 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -704,7 +706,7 @@ FILE *yyget_out (void ); - - void yyset_out (FILE * out_str ); - --yy_size_t yyget_leng (void ); -+int yyget_leng (void ); - - char *yyget_text (void ); - -@@ -853,6 +855,10 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - -+#line 68 "dtc-lexer.l" -+ -+#line 861 "dtc-lexer.lex.c" -+ - if ( !(yy_init) ) - { - (yy_init) = 1; -@@ -879,11 +885,6 @@ YY_DECL - yy_load_buffer_state( ); - } - -- { --#line 68 "dtc-lexer.l" -- --#line 886 "dtc-lexer.lex.c" -- - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); -@@ -901,7 +902,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; -+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -910,13 +911,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 158 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -1007,23 +1008,31 @@ case 5: - YY_RULE_SETUP - #line 116 "dtc-lexer.l" - { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 121 "dtc-lexer.l" -+{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 122 "dtc-lexer.l" -+#line 127 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 128 "dtc-lexer.l" -+#line 133 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1031,9 +1040,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 135 "dtc-lexer.l" -+#line 140 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1041,9 +1050,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 142 "dtc-lexer.l" -+#line 147 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1051,9 +1060,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 149 "dtc-lexer.l" -+#line 154 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1073,10 +1082,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 168 "dtc-lexer.l" -+#line 173 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1098,18 +1107,18 @@ YY_RULE_SETUP - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 189 "dtc-lexer.l" -+#line 194 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 195 "dtc-lexer.l" -+#line 200 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1117,27 +1126,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 202 "dtc-lexer.l" -+#line 207 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 208 "dtc-lexer.l" -+#line 213 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 214 "dtc-lexer.l" -+#line 219 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1146,75 +1155,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 222 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 227 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 228 "dtc-lexer.l" --/* eat C-style comments */ -+#line 232 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 229 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 233 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 231 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 234 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 232 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 236 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 233 "dtc-lexer.l" --{ return DT_LE; }; -+#line 237 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 234 "dtc-lexer.l" --{ return DT_GE; }; -+#line 238 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 235 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 239 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 236 "dtc-lexer.l" --{ return DT_NE; }; -+#line 240 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 237 "dtc-lexer.l" --{ return DT_AND; }; -+#line 241 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 238 "dtc-lexer.l" --{ return DT_OR; }; -+#line 242 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 240 "dtc-lexer.l" -+#line 243 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 245 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1230,12 +1239,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 255 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1239 "dtc-lexer.lex.c" -+#line 1248 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1365,7 +1374,6 @@ ECHO; - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -- } /* end of user's declarations */ - } /* end of yylex */ - - /* yy_get_next_buffer - try to read in a new buffer -@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) - - else - { -- yy_size_t num_to_read = -+ int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { -- yy_size_t new_size = b->yy_buf_size * 2; -+ int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -- (yy_n_chars), num_to_read ); -+ (yy_n_chars), (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } -@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 158); -+ yy_is_jam = (yy_current_state == 165); - -- return yy_is_jam ? 0 : yy_current_state; -+ return yy_is_jam ? 0 : yy_current_state; - } - - #ifndef YY_NO_INPUT -@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); -+ int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) - */ - static void yyensure_buffer_stack (void) - { -- yy_size_t num_to_alloc; -+ int num_to_alloc; - - if (!(yy_buffer_stack)) { - -@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- yy_size_t i; -+ int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; -@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --yy_size_t yyget_leng (void) -+int yyget_leng (void) - { - return yyleng; - } -@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 254 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 116458c..2c1784e 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 2.5. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "3.0.2" -+#define YYBISON_VERSION "2.5" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -58,13 +58,18 @@ - /* Pull parsers. */ - #define YYPULL 1 - -+/* Using locations. */ -+#define YYLSP_NEEDED 1 - - - - /* Copy the first part of user declarations. */ --#line 20 "dtc-parser.y" /* yacc.c:339 */ -+ -+/* Line 268 of yacc.c */ -+#line 20 "dtc-parser.y" - - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -80,15 +85,14 @@ extern void yyerror(char const *s); - extern struct boot_info *the_boot_info; - extern bool treesource_error; - --#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ - --# ifndef YY_NULLPTR --# if defined __cplusplus && 201103L <= __cplusplus --# define YY_NULLPTR nullptr --# else --# define YY_NULLPTR 0 --# endif --# endif -+/* Line 268 of yacc.c */ -+#line 91 "dtc-parser.tab.c" -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif - - /* Enabling verbose error messages. */ - #ifdef YYERROR_VERBOSE -@@ -98,53 +102,51 @@ extern bool treesource_error; - # define YYERROR_VERBOSE 0 - #endif - --/* In a future release of Bison, this section will be replaced -- by #include "dtc-parser.tab.h". */ --#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED --# define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Debug traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif --#if YYDEBUG --extern int yydebug; -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 - #endif - --/* Token type. */ -+ -+/* Tokens. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- enum yytokentype -- { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -- }; -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - --/* Value type. */ -+ -+ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; --union YYSTYPE -+typedef union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:355 */ -+ -+/* Line 293 of yacc.c */ -+#line 39 "dtc-parser.y" - - char *propnodename; - char *labelref; -@@ -162,37 +164,37 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - --#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ --}; -+ -+ -+/* Line 293 of yacc.c */ -+#line 173 "dtc-parser.tab.c" -+} YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE YYLTYPE; --struct YYLTYPE -+typedef struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --}; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - - --extern YYSTYPE yylval; --extern YYLTYPE yylloc; --int yyparse (void); -- --#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -- - /* Copy the second part of user declarations. */ - --#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ -+ -+/* Line 343 of yacc.c */ -+#line 198 "dtc-parser.tab.c" - - #ifdef short - # undef short -@@ -206,8 +208,11 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#else -+#elif (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - typedef signed char yytype_int8; -+#else -+typedef short int yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -227,7 +232,8 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T -+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -241,68 +247,39 @@ typedef short int yytype_int16; - # if defined YYENABLE_NLS && YYENABLE_NLS - # if ENABLE_NLS - # include /* INFRINGES ON USER NAME SPACE */ --# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -+# define YY_(msgid) dgettext ("bison-runtime", msgid) - # endif - # endif - # ifndef YY_ --# define YY_(Msgid) Msgid --# endif --#endif -- --#ifndef YY_ATTRIBUTE --# if (defined __GNUC__ \ -- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C --# define YY_ATTRIBUTE(Spec) __attribute__(Spec) --# else --# define YY_ATTRIBUTE(Spec) /* empty */ --# endif --#endif -- --#ifndef YY_ATTRIBUTE_PURE --# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) --#endif -- --#ifndef YY_ATTRIBUTE_UNUSED --# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) --#endif -- --#if !defined _Noreturn \ -- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) --# if defined _MSC_VER && 1200 <= _MSC_VER --# define _Noreturn __declspec (noreturn) --# else --# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -+# define YY_(msgid) msgid - # endif - #endif - - /* Suppress unused-variable warnings by "using" E. */ - #if ! defined lint || defined __GNUC__ --# define YYUSE(E) ((void) (E)) -+# define YYUSE(e) ((void) (e)) - #else --# define YYUSE(E) /* empty */ -+# define YYUSE(e) /* empty */ - #endif - --#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ --/* Suppress an incorrect diagnostic about yylval being uninitialized. */ --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -- _Pragma ("GCC diagnostic push") \ -- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") --# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -- _Pragma ("GCC diagnostic pop") -+/* Identity function, used to suppress warnings about constant conditions. */ -+#ifndef lint -+# define YYID(n) (n) - #else --# define YY_INITIAL_VALUE(Value) Value --#endif --#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_END -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static int -+YYID (int yyi) -+#else -+static int -+YYID (yyi) -+ int yyi; - #endif --#ifndef YY_INITIAL_VALUE --# define YY_INITIAL_VALUE(Value) /* Nothing. */ -+{ -+ return yyi; -+} - #endif - -- - #if ! defined yyoverflow || YYERROR_VERBOSE - - /* The parser invokes alloca or malloc; define the necessary symbols. */ -@@ -320,9 +297,9 @@ typedef short int yytype_int16; - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - # include /* INFRINGES ON USER NAME SPACE */ -- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 - # endif -@@ -332,8 +309,8 @@ typedef short int yytype_int16; - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's 'empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -349,7 +326,7 @@ typedef short int yytype_int16; - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -357,13 +334,15 @@ typedef short int yytype_int16; - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS -+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS -+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -373,8 +352,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc -@@ -400,35 +379,35 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (0) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (YYID (0)) - - #endif - - #if defined YYCOPY_NEEDED && YYCOPY_NEEDED --/* Copy COUNT objects from SRC to DST. The source and destination do -+/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ - # ifndef YYCOPY - # if defined __GNUC__ && 1 < __GNUC__ --# define YYCOPY(Dst, Src, Count) \ -- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) - # else --# define YYCOPY(Dst, Src, Count) \ -- do \ -- { \ -- YYSIZE_T yyi; \ -- for (yyi = 0; yyi < (Count); yyi++) \ -- (Dst)[yyi] = (Src)[yyi]; \ -- } \ -- while (0) -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (YYID (0)) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -439,39 +418,37 @@ union yyalloc - #define YYLAST 136 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 47 -+#define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 29 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 80 --/* YYNSTATES -- Number of states. */ --#define YYNSTATES 144 -+#define YYNRULES 82 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 147 - --/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -- by yylex, with out-of-bounds checking. */ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 278 -+#define YYMAXUTOK 279 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -- as returned by yylex, without out-of-bounds checking. */ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, -+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, -+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -486,292 +463,335 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - }; - - #if YYDEBUG -- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const yytype_uint16 yyprhs[] = -+{ -+ 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, -+ 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, -+ 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, -+ 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, -+ 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, -+ 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, -+ 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, -+ 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, -+ 262, 265, 269 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yytype_int8 yyrhs[] = -+{ -+ 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, -+ 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, -+ 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, -+ 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, -+ -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, -+ 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, -+ -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, -+ -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, -+ 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, -+ 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, -+ 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, -+ 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, -+ -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, -+ -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, -+ 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, -+ -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, -+ 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, -+ -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, -+ -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, -+ -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, -+ 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, -+ -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, -+ -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, -+ -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, -+ 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, -+ 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, -+ 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, -+ 76, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -- 465 -+ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -+ 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, -+ 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, -+ 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, -+ 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, -+ 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, -+ 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, -+ 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, -+ 474, 478, 482 - }; - #endif - --#if YYDEBUG || YYERROR_VERBOSE || 0 -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE - /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -+ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -+ "integer_prim", "integer_expr", "integer_trinary", "integer_or", -+ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -+ "integer_eq", "integer_rela", "integer_shift", "integer_add", -+ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[NUM] -- (External) token number corresponding to the -- (internal) symbol number NUM (which must be that of a token). */ -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -- 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -+ 94, 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --#define YYPACT_NINF -81 -- --#define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-81))) -- --#define YYTABLE_NINF -1 -- --#define yytable_value_is_error(Yytable_value) \ -- 0 -- -- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --static const yytype_int8 yypact[] = -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -- 74, 25, 75, -81 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, -+ 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, -+ 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, -+ 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, -+ 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, -+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, -+ 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, -+ 76, 76, 76 - }; - -- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE does not specify something else to do. Zero -- means the default is an error. */ --static const yytype_uint8 yydefact[] = -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -- 0, 0, 0, 23 -+ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -+ 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, -+ 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, -+ 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, -+ 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, -+ 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, -+ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, -+ 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, -+ 2, 3, 2 - }; - -- /* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const yytype_uint8 yydefact[] = - { -- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -- 37, 27, 34, 38, -14, -81, 22, 24 -+ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -+ 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, -+ 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, -+ 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, -+ 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, -+ 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, -+ 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, -+ 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, -+ 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, -+ 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, -+ 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, -+ 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, -+ 23, 0, 26, 0, 0, 0, 25 - }; - -- /* YYDEFGOTO[NTERM-NUM]. */ -+/* YYDEFGOTO[NTERM-NUM]. */ - static const yytype_int16 yydefgoto[] = - { -- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 128, 94, 95 -+ -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, -+ 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, -+ 31, 32, 33, 34, 35, 36, 131, 97, 98 - }; - -- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule whose -- number is the opposite. If YYTABLE_NINF, syntax error. */ --static const yytype_uint8 yytable[] = -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -84 -+static const yytype_int8 yypact[] = - { -- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -- 0, 0, 75, 140, 0, 0, 142 -+ 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, -+ 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, -+ -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, -+ 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, -+ 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, -+ 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, -+ 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, -+ -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, -+ -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, -+ -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, -+ -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, -+ 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, -+ -84, 24, -84, 77, 24, 80, -84 - }; - --static const yytype_int16 yycheck[] = -+/* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -- -1, -1, 50, 138, -1, -1, 141 -+ -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, -+ -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, -+ 82, 29, 18, 25, 26, -17, -84, 20, 28 - }; - -- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -1 -+static const yytype_uint8 yytable[] = - { -- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -- 58, 33, 58, 34 -+ 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, -+ 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, -+ 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, -+ 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, -+ 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, -+ 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, -+ 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, -+ 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, -+ 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, -+ 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, -+ 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, -+ 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, -+ 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 143, 0, 78, 145 - }; - -- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = -+#define yypact_value_is_default(yystate) \ -+ ((yystate) == (-84)) -+ -+#define yytable_value_is_error(yytable_value) \ -+ YYID (0) -+ -+static const yytype_int16 yycheck[] = - { -- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -- 74 -+ 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, -+ 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, -+ 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, -+ 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, -+ 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, -+ 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, -+ 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, -+ 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, -+ 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, -+ 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, -+ 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, -+ 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, -+ 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, -+ -1, -1, -1, 141, -1, 53, 144 - }; - -- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -- 2 -+ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -+ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -+ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -+ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -+ 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, -+ 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, -+ 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, -+ 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, -+ 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, -+ 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, -+ 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, -+ 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, -+ 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, -+ 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, -+ 32, 34, 35, 60, 34, 60, 35 - }; - -- --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. However, -+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated -+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is -+ discussed. */ -+ -+#define YYFAIL goto yyerrlab -+#if defined YYFAIL -+ /* This is here to suppress warnings from the GCC cpp's -+ -Wunused-macros. Normally we don't worry about that warning, but -+ some users do, and we want to make it easy for users to remove -+ YYFAIL uses, which will produce warnings from Bison 2.5. */ -+#endif - - #define YYRECOVERING() (!!yyerrstatus) - --#define YYBACKUP(Token, Value) \ --do \ -- if (yychar == YYEMPTY) \ -- { \ -- yychar = (Token); \ -- yylval = (Value); \ -- YYPOPSTACK (yylen); \ -- yystate = *yyssp; \ -- goto yybackup; \ -- } \ -- else \ -- { \ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ YYPOPSTACK (1); \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (0) -+ YYERROR; \ -+ } \ -+while (YYID (0)) -+ - --/* Error token number */ --#define YYTERROR 1 --#define YYERRCODE 256 -+#define YYTERROR 1 -+#define YYERRCODE 256 - - - /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - #ifndef YYLLOC_DEFAULT --# define YYLLOC_DEFAULT(Current, Rhs, N) \ -- do \ -- if (N) \ -- { \ -- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -- } \ -- else \ -- { \ -- (Current).first_line = (Current).last_line = \ -- YYRHSLOC (Rhs, 0).last_line; \ -- (Current).first_column = (Current).last_column = \ -- YYRHSLOC (Rhs, 0).last_column; \ -- } \ -- while (0) -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (YYID (N)) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (YYID (0)) - #endif - --#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -- -- --/* Enable debugging if requested. */ --#if YYDEBUG -- --# ifndef YYFPRINTF --# include /* INFRINGES ON USER NAME SPACE */ --# define YYFPRINTF fprintf --# endif -- --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (0) -- - - /* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know -@@ -779,73 +799,82 @@ do { \ - - #ifndef YY_LOCATION_PRINT - # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif - --/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - --YY_ATTRIBUTE_UNUSED --static unsigned --yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) --{ -- unsigned res = 0; -- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -- if (0 <= yylocp->first_line) -- { -- res += YYFPRINTF (yyo, "%d", yylocp->first_line); -- if (0 <= yylocp->first_column) -- res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -- } -- if (0 <= yylocp->last_line) -- { -- if (yylocp->first_line < yylocp->last_line) -- { -- res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -- if (0 <= end_col) -- res += YYFPRINTF (yyo, ".%d", end_col); -- } -- else if (0 <= end_col && yylocp->first_column < end_col) -- res += YYFPRINTF (yyo, "-%d", end_col); -- } -- return res; -- } -+/* YYLEX -- calling `yylex' with the right arguments. */ - --# define YY_LOCATION_PRINT(File, Loc) \ -- yy_location_print_ (File, &(Loc)) -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (YYLEX_PARAM) -+#else -+# define YYLEX yylex () -+#endif - --# else --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf - # endif --#endif - -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (YYID (0)) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value, Location); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (0) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (YYID (0)) - - --/*----------------------------------------. --| Print this symbol's value on YYOUTPUT. | --`----------------------------------------*/ -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ - -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif - { -- FILE *yyo = yyoutput; -- YYUSE (yyo); -- YYUSE (yylocationp); - if (!yyvaluep) - return; -+ YYUSE (yylocationp); - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# else -+ YYUSE (yyoutput); - # endif -- YYUSE (yytype); -+ switch (yytype) -+ { -+ default: -+ break; -+ } - } - - -@@ -853,11 +882,23 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif - { -- YYFPRINTF (yyoutput, "%s %s (", -- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); -@@ -870,8 +911,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL - | TOP (included). | - `------------------------------------------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -+#else -+static void -+yy_stack_print (yybottom, yytop) -+ yytype_int16 *yybottom; -+ yytype_int16 *yytop; -+#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -882,42 +931,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (0) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (YYID (0)) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -+#else - static void --yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -+yy_reduce_print (yyvsp, yylsp, yyrule) -+ YYSTYPE *yyvsp; -+ YYLTYPE *yylsp; -+ int yyrule; -+#endif - { -- unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -+ unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, -- yystos[yyssp[yyi + 1 - yynrhs]], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- , &(yylsp[(yyi + 1) - (yynrhs)]) ); -+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ --} while (0) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyvsp, yylsp, Rule); \ -+} while (YYID (0)) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -931,7 +988,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -954,8 +1011,15 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) -+#else -+static YYSIZE_T -+yystrlen (yystr) -+ const char *yystr; -+#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -971,8 +1035,16 @@ yystrlen (const char *yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) -+#else -+static char * -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1002,27 +1074,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1045,11 +1117,12 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); - YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = YY_NULLPTR; -+ const char *yyformat = 0; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1057,6 +1130,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -+ - Assume YYFAIL is not used. It's too flawed to consider. See -+ -+ for details. YYERROR is fine as it does not invoke this -+ function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1105,13 +1182,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - break; - } - yyarg[yycount++] = yytname[yyx]; -- { -- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); -- if (! (yysize <= yysize1 -- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -- } -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ if (! (yysize <= yysize1 -+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; - } - } - } -@@ -1131,12 +1206,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - # undef YYCASE_ - } - -- { -- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); -- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -- } -+ yysize1 = yysize + yystrlen (yyformat); -+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; - - if (*yymsg_alloc < yysize) - { -@@ -1173,21 +1246,50 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep, yylocationp) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+ YYLTYPE *yylocationp; -+#endif - { - YYUSE (yyvaluep); - YYUSE (yylocationp); -+ - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -- YYUSE (yytype); -- YY_IGNORE_MAYBE_UNINITIALIZED_END -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } - } - - -+/* Prevent warnings from -Wmissing-prototypes. */ -+#ifdef YYPARSE_PARAM -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void *YYPARSE_PARAM); -+#else -+int yyparse (); -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ - - - /* The lookahead symbol. */ -@@ -1195,12 +1297,10 @@ int yychar; - - /* The semantic value of the lookahead symbol. */ - YYSTYPE yylval; -+ - /* Location data for the lookahead symbol. */ --YYLTYPE yylloc --# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -- = { 1, 1, 1, 1 } --# endif --; -+YYLTYPE yylloc; -+ - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1209,19 +1309,38 @@ int yynerrs; - | yyparse. | - `----------*/ - -+#ifdef YYPARSE_PARAM -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void *YYPARSE_PARAM) -+#else -+int -+yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- 'yyss': related to states. -- 'yyvs': related to semantic values. -- 'yyls': related to locations. -+ `yyss': related to states. -+ `yyvs': related to semantic values. -+ `yyls': related to locations. - -- Refer to the stacks through separate pointers, to allow yyoverflow -+ Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ -@@ -1247,7 +1366,7 @@ yyparse (void) - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ -- int yytoken = 0; -+ int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -@@ -1266,9 +1385,10 @@ yyparse (void) - Keep to zero when no symbol should be popped. */ - int yylen = 0; - -- yyssp = yyss = yyssa; -- yyvsp = yyvs = yyvsa; -- yylsp = yyls = yylsa; -+ yytoken = 0; -+ yyss = yyssa; -+ yyvs = yyvsa; -+ yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1277,7 +1397,21 @@ yyparse (void) - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -- yylsp[0] = yylloc; -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ yylsp = yyls; -+ -+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ /* Initialize the default location before parsing starts. */ -+ yylloc.first_line = yylloc.last_line = 1; -+ yylloc.first_column = yylloc.last_column = 1; -+#endif -+ - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1298,26 +1432,26 @@ yyparse (void) - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- YYLTYPE *yyls1 = yyls; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yyls1, yysize * sizeof (*yylsp), -- &yystacksize); -- -- yyls = yyls1; -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1325,23 +1459,23 @@ yyparse (void) - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -- YYSTACK_RELOCATE (yyls_alloc, yyls); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ -@@ -1351,10 +1485,10 @@ yyparse (void) - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1383,7 +1517,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = yylex (); -+ yychar = YYLEX; - } - - if (yychar <= YYEOF) -@@ -1423,9 +1557,7 @@ yybackup: - yychar = YYEMPTY; - - yystate = yyn; -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -- YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - -@@ -1448,7 +1580,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- '$$ = $1'. -+ `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1463,273 +1595,322 @@ yyreduce: - switch (yyn) - { - case 2: --#line 105 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 109 "dtc-parser.y" - { -- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -- guess_boot_cpuid((yyvsp[0].node))); -+ (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); -+ (yyvsp[(5) - (5)].node)->is_root = 1; -+ the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), -+ guess_boot_cpuid((yyvsp[(5) - (5)].node))); - } --#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --#line 113 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 119 "dtc-parser.y" - { -- (yyval.re) = NULL; -+ (yyval.is_plugin) = 0; - } --#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --#line 117 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 123 "dtc-parser.y" - { -- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); -+ (yyval.is_plugin) = 1; - } --#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: --#line 124 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 130 "dtc-parser.y" - { -- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); -+ (yyval.re) = NULL; - } --#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: --#line 128 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 134 "dtc-parser.y" - { -- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -- (yyval.re) = (yyvsp[0].re); -+ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); - } --#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: --#line 136 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 141 "dtc-parser.y" - { -- (yyval.node) = name_node((yyvsp[0].node), ""); -+ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); - } --#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: --#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 145 "dtc-parser.y" - { -- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); -+ add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.re) = (yyvsp[(2) - (2)].re); - } --#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: --#line 145 "dtc-parser.y" /* yacc.c:1646 */ -- { -- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -- add_label(&target->labels, (yyvsp[-2].labelref)); -- if (target) -- merge_nodes(target, (yyvsp[0].node)); -- else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[-3].node); -+/* Line 1806 of yacc.c */ -+#line 153 "dtc-parser.y" -+ { -+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); - } --#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: --#line 156 "dtc-parser.y" /* yacc.c:1646 */ -- { -- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); - -- if (target) -- merge_nodes(target, (yyvsp[0].node)); -- else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[-2].node); -+/* Line 1806 of yacc.c */ -+#line 157 "dtc-parser.y" -+ { -+ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } --#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: --#line 166 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 162 "dtc-parser.y" - { -- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); - -+ add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); - if (target) -- delete_node(target); -+ merge_nodes(target, (yyvsp[(4) - (4)].node)); - else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- -- -- (yyval.node) = (yyvsp[-3].node); -+ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -+ (yyval.node) = (yyvsp[(1) - (4)].node); - } --#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: --#line 181 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 173 "dtc-parser.y" - { -- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); -+ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[(3) - (3)].node)); -+ else -+ ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); -+ (yyval.node) = (yyvsp[(1) - (3)].node); - } --#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: --#line 188 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 183 "dtc-parser.y" - { -- (yyval.proplist) = NULL; -+ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -+ -+ if (target) -+ delete_node(target); -+ else -+ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[(1) - (4)].node); - } --#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: --#line 192 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 198 "dtc-parser.y" - { -- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); -+ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); - } --#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: --#line 199 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 205 "dtc-parser.y" - { -- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); -+ (yyval.proplist) = NULL; - } --#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: --#line 203 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 209 "dtc-parser.y" - { -- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); -+ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); - } --#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: --#line 207 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 216 "dtc-parser.y" - { -- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); -+ (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); - } --#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: --#line 211 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 220 "dtc-parser.y" - { -- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -- (yyval.prop) = (yyvsp[0].prop); -+ (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); - } --#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: --#line 219 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 224 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); -+ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); - } --#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: --#line 223 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 228 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); -+ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.prop) = (yyvsp[(2) - (2)].prop); - } --#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: --#line 227 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 236 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); -+ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); - } --#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: --#line 231 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 240 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); -+ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); - } --#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 23: --#line 235 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 244 "dtc-parser.y" - { -- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); -+ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ } -+ break; -+ -+ case 24: -+ -+/* Line 1806 of yacc.c */ -+#line 248 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -+ } -+ break; -+ -+ case 25: -+ -+/* Line 1806 of yacc.c */ -+#line 252 "dtc-parser.y" -+ { -+ FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); - struct data d; - -- if ((yyvsp[-3].integer) != 0) -- if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) -+ if ((yyvsp[(6) - (9)].integer) != 0) -+ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, -+ (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, - strerror(errno)); - -- d = data_copy_file(f, (yyvsp[-1].integer)); -+ d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); - -- (yyval.data) = data_merge((yyvsp[-8].data), d); -+ (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); - fclose(f); - } --#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --#line 251 "dtc-parser.y" /* yacc.c:1646 */ -+ case 26: -+ -+/* Line 1806 of yacc.c */ -+#line 268 "dtc-parser.y" - { -- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[-4].data), d); -+ (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); - fclose(f); - } --#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --#line 261 "dtc-parser.y" /* yacc.c:1646 */ -+ case 27: -+ -+/* Line 1806 of yacc.c */ -+#line 278 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --#line 268 "dtc-parser.y" /* yacc.c:1646 */ -+ case 28: -+ -+/* Line 1806 of yacc.c */ -+#line 285 "dtc-parser.y" - { - (yyval.data) = empty_data; - } --#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --#line 272 "dtc-parser.y" /* yacc.c:1646 */ -+ case 29: -+ -+/* Line 1806 of yacc.c */ -+#line 289 "dtc-parser.y" - { -- (yyval.data) = (yyvsp[-1].data); -+ (yyval.data) = (yyvsp[(1) - (2)].data); - } --#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --#line 276 "dtc-parser.y" /* yacc.c:1646 */ -+ case 30: -+ -+/* Line 1806 of yacc.c */ -+#line 293 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --#line 283 "dtc-parser.y" /* yacc.c:1646 */ -+ case 31: -+ -+/* Line 1806 of yacc.c */ -+#line 300 "dtc-parser.y" - { - unsigned long long bits; - -- bits = (yyvsp[-1].integer); -+ bits = (yyvsp[(2) - (3)].integer); - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { -- ERROR(&(yylsp[-1]), "Array elements must be" -+ ERROR(&(yylsp[(2) - (3)]), "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } -@@ -1737,23 +1918,25 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } --#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --#line 299 "dtc-parser.y" /* yacc.c:1646 */ -+ case 32: -+ -+/* Line 1806 of yacc.c */ -+#line 316 "dtc-parser.y" - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } --#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --#line 304 "dtc-parser.y" /* yacc.c:1646 */ -+ case 33: -+ -+/* Line 1806 of yacc.c */ -+#line 321 "dtc-parser.y" - { -- if ((yyvsp[-1].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; -+ if ((yyvsp[(1) - (2)].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1762,258 +1945,293 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -- ERROR(&(yylsp[0]), "Value out of range for" -- " %d-bit array element", (yyvsp[-1].array).bits); -+ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[(2) - (2)]), "Value out of range for" -+ " %d-bit array element", (yyvsp[(1) - (2)].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); - } --#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: --#line 323 "dtc-parser.y" /* yacc.c:1646 */ -+ case 34: -+ -+/* Line 1806 of yacc.c */ -+#line 340 "dtc-parser.y" - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); - -- if ((yyvsp[-1].array).bits == 32) -- (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, -+ if ((yyvsp[(1) - (2)].array).bits == 32) -+ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, - REF_PHANDLE, -- (yyvsp[0].labelref)); -+ (yyvsp[(2) - (2)].labelref)); - else -- ERROR(&(yylsp[0]), "References are only allowed in " -+ ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); - } --#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: --#line 337 "dtc-parser.y" /* yacc.c:1646 */ -+ case 35: -+ -+/* Line 1806 of yacc.c */ -+#line 354 "dtc-parser.y" - { -- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); -+ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 36: --#line 346 "dtc-parser.y" /* yacc.c:1646 */ -+ case 38: -+ -+/* Line 1806 of yacc.c */ -+#line 363 "dtc-parser.y" - { -- (yyval.integer) = (yyvsp[-1].integer); -+ (yyval.integer) = (yyvsp[(2) - (3)].integer); - } --#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; -- -- case 39: --#line 357 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } --#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 41: --#line 362 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } --#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 374 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } - break; - - case 43: --#line 367 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } --#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 379 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } - break; - - case 45: --#line 372 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } --#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 384 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } - break; - - case 47: --#line 377 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } --#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 389 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } - break; - - case 49: --#line 382 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } --#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 394 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } - break; - - case 51: --#line 387 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } --#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 399 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } - break; - -- case 52: --#line 388 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } --#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 53: -+ -+/* Line 1806 of yacc.c */ -+#line 404 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } - break; - - case 54: --#line 393 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } --#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; - -- case 55: --#line 394 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } --#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 405 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } - break; - - case 56: --#line 395 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } --#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 410 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } - break; - - case 57: --#line 396 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } --#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 411 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } - break; - - case 58: --#line 400 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } --#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 412 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } - break; - - case 59: --#line 401 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } --#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 413 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -+ break; -+ -+ case 60: -+ -+/* Line 1806 of yacc.c */ -+#line 417 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } - break; - - case 61: --#line 406 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } --#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 418 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } - break; - -- case 62: --#line 407 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } --#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 63: -+ -+/* Line 1806 of yacc.c */ -+#line 423 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } - break; - - case 64: --#line 412 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } --#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; - -- case 65: --#line 413 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } --#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 424 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } - break; - - case 66: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } --#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 429 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } - break; - -- case 69: --#line 420 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = -(yyvsp[0].integer); } --#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 67: -+ -+/* Line 1806 of yacc.c */ -+#line 430 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } - break; - -- case 70: --#line 421 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 68: -+ -+/* Line 1806 of yacc.c */ -+#line 431 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } - break; - - case 71: --#line 422 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = !(yyvsp[0].integer); } --#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 437 "dtc-parser.y" -+ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } - break; - - case 72: --#line 427 "dtc-parser.y" /* yacc.c:1646 */ -- { -- (yyval.data) = empty_data; -- } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 438 "dtc-parser.y" -+ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } - break; - - case 73: --#line 431 "dtc-parser.y" /* yacc.c:1646 */ -- { -- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); -- } --#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 439 "dtc-parser.y" -+ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } - break; - - case 74: --#line 435 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 444 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = empty_data; - } --#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: --#line 442 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 448 "dtc-parser.y" - { -- (yyval.nodelist) = NULL; -+ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); - } --#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: --#line 446 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 452 "dtc-parser.y" - { -- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: --#line 450 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 459 "dtc-parser.y" - { -- ERROR(&(yylsp[0]), "Properties must precede subnodes"); -- YYERROR; -+ (yyval.nodelist) = NULL; - } --#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 463 "dtc-parser.y" - { -- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); -+ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); - } --#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 467 "dtc-parser.y" - { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); -+ ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); -+ YYERROR; - } --#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 80: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 475 "dtc-parser.y" - { -- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[0].node); -+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); - } --#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -+ case 81: - --#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 479 "dtc-parser.y" -+ { -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -+ } -+ break; -+ -+ case 82: -+ -+/* Line 1806 of yacc.c */ -+#line 483 "dtc-parser.y" -+ { -+ add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.node) = (yyvsp[(2) - (2)].node); -+ } -+ break; -+ -+ -+ -+/* Line 1806 of yacc.c */ -+#line 2235 "dtc-parser.tab.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2036,7 +2254,7 @@ yyreduce: - *++yyvsp = yyval; - *++yylsp = yyloc; - -- /* Now 'shift' the result of the reduction. Determine what state -+ /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2051,9 +2269,9 @@ yyreduce: - goto yynewstate; - - --/*--------------------------------------. --| yyerrlab -- here on detecting error. | --`--------------------------------------*/ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2104,20 +2322,20 @@ yyerrlab: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval, &yylloc); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2137,7 +2355,7 @@ yyerrorlab: - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; -- /* Do not reclaim the symbols of the rule whose action triggered -+ /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2150,37 +2368,35 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -+ YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp, yylsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -- YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of -@@ -2209,7 +2425,7 @@ yyabortlab: - yyresult = 1; - goto yyreturn; - --#if !defined yyoverflow || YYERROR_VERBOSE -+#if !defined(yyoverflow) || YYERROR_VERBOSE - /*-------------------------------------------------. - | yyexhaustedlab -- memory exhaustion comes here. | - `-------------------------------------------------*/ -@@ -2228,14 +2444,14 @@ yyreturn: - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule whose action triggered -+ /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp, yylsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2246,12 +2462,18 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- return yyresult; -+ /* Make sure YYID is used. */ -+ return YYID (yyresult); - } --#line 472 "dtc-parser.y" /* yacc.c:1906 */ -+ -+ -+ -+/* Line 2067 of yacc.c */ -+#line 489 "dtc-parser.y" - - - void yyerror(char const *s) - { - ERROR(&yylloc, "%s", s); - } -+ -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 30867c6..0b22bbb 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 2.5. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,55 +26,50 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - --#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED --# define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Debug traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif --#if YYDEBUG --extern int yydebug; --#endif - --/* Token type. */ -+/* Tokens. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- enum yytokentype -- { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -- }; -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - --/* Value type. */ -+ -+ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; --union YYSTYPE -+typedef union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:1909 */ -+ -+/* Line 2068 of yacc.c */ -+#line 39 "dtc-parser.y" - - char *propnodename; - char *labelref; -@@ -92,30 +87,32 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; -+ -+ - --#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ --}; -+/* Line 2068 of yacc.c */ -+#line 96 "dtc-parser.tab.h" -+} YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --/* Location type. */ -+extern YYSTYPE yylval; -+ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE YYLTYPE; --struct YYLTYPE -+typedef struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --}; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - -- --extern YYSTYPE yylval; - extern YYLTYPE yylloc; --int yyparse (void); - --#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 5a897e3..56b9c15 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,6 +19,7 @@ - */ - %{ - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -52,9 +53,11 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -71,6 +74,7 @@ extern bool treesource_error; - - %type propdata - %type propdataprefix -+%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -101,10 +105,23 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ DT_V1 ';' plugindecl memreserves devicetree - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ $5->is_plugin = $3; -+ $5->is_root = 1; -+ the_boot_info = build_boot_info($4, $5, -+ guess_boot_cpuid($5)); -+ } -+ ; -+ -+plugindecl: -+ /* empty */ -+ { -+ $$ = 0; -+ } -+ | DT_PLUGIN ';' -+ { -+ $$ = 1; - } - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 8c4add6..0cbb14c 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- -+ case '@': -+ symbol_fixup_support = 1; -+ break; - case 'h': - usage(NULL); - default: -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 56212c8..fe45748 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -132,6 +133,25 @@ struct label { - struct label *next; - }; - -+struct fixup_entry { -+ int offset; -+ struct node *node; -+ struct property *prop; -+ struct fixup_entry *next; -+}; -+ -+struct fixup { -+ char *ref; -+ struct fixup_entry *entries; -+ struct fixup *next; -+}; -+ -+struct symbol { -+ struct label *label; -+ struct node *node; -+ struct symbol *next; -+}; -+ - struct property { - bool deleted; - char *name; -@@ -158,6 +178,12 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ -+ int is_root; -+ int is_plugin; -+ struct fixup *fixups; -+ struct symbol *symbols; -+ struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -181,6 +207,18 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - -+#define for_each_fixup(n, f) \ -+ for ((f) = (n)->fixups; (f); (f) = (f)->next) -+ -+#define for_each_fixup_entry(f, fe) \ -+ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -+ -+#define for_each_symbol(n, s) \ -+ for ((s) = (n)->symbols; (s); (s) = (s)->next) -+ -+#define for_each_local_fixup_entry(n, fe) \ -+ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -+ - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index bd99fa2..f439b40 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -262,6 +262,12 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - struct property *prop; - struct node *child; - bool seen_name_prop = false; -+ struct symbol *sym; -+ struct fixup *f; -+ struct fixup_entry *fe; -+ char *name, *s; -+ const char *fullpath; -+ int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -276,8 +282,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -- int nameoff; -- - if (streq(prop->name, "name")) - seen_name_prop = true; - -@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -+ if (!symbol_fixup_support) -+ goto no_symbols; -+ -+ /* add the symbol nodes (if any) */ -+ if (tree->symbols) { -+ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__symbols__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_symbol(tree, sym) { -+ -+ vallen = strlen(sym->node->fullpath); -+ -+ nameoff = stringtable_insert(strbuf, sym->label->label); -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, sym->node->fullpath, -+ strlen(sym->node->fullpath)); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ emit->endnode(etarget, NULL); -+ } -+ -+ /* add the fixup nodes */ -+ if (tree->fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_fixup(tree, f) { -+ -+ namesz = 0; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, -+ fe->prop->name, fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, f->ref); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ } -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+ /* add the local fixup property */ -+ if (tree->local_fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__local_fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ namesz = 0; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, fe->prop->name, -+ fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, "fixup"); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 5b8c7d5..86b7338 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd" -+#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" - -From 682bf3cce9aab7644697e66b2a3e3e9ae5ccdf1c Mon Sep 17 00:00:00 2001 +From 8fa5e143ce9adb6f48f952b89d71990b5a560ae1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 079/251] mfd: Add Raspberry Pi Sense HAT core driver +Subject: [PATCH 076/114] mfd: Add Raspberry Pi Sense HAT core driver --- drivers/input/joystick/Kconfig | 8 + @@ -128025,7 +124926,7 @@ index 0000000..6a41676 +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 4d92df6..c5730dc 100644 +index eea61e3..d2c3b72 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -10,6 +10,14 @@ config MFD_CORE @@ -128044,10 +124945,10 @@ index 4d92df6..c5730dc 100644 tristate "AMD CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index a8b76b8..e6339d2 100644 +index 5eaa6465d..8dc2dde 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile -@@ -194,3 +194,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o +@@ -203,3 +203,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o @@ -128217,10 +125118,10 @@ index 0000000..eea9312 +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index 0f33a78..4caa417 100644 +index ee72c3a..5be1a31 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -2506,3 +2506,16 @@ config FB_SM712 +@@ -2502,3 +2502,16 @@ config FB_SM712 This driver is also available as a module. The module will be called sm712fb. If you want to compile it as a module, say M here and read . @@ -128238,10 +125139,10 @@ index 0f33a78..4caa417 100644 + help + This is the framebuffer driver for the Raspberry Pi Sense HAT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 9b086ac..7101277 100644 +index df473d8..474c567 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile -@@ -150,6 +150,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o +@@ -149,6 +149,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o obj-$(CONFIG_FB_MXS) += mxsfb.o obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o obj-$(CONFIG_FB_SIMPLE) += simplefb.o @@ -128681,10 +125582,10 @@ index 0000000..56196dc + +#endif -From 28fda0b00b2fe4e5a5151024124e57a3821c1ec4 Mon Sep 17 00:00:00 2001 +From 8b9a3c692dcb44ba033bb131b4873e035ce5ff76 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 080/251] RaspiDAC3 support +Subject: [PATCH 077/114] RaspiDAC3 support Signed-off-by: Jan Grulich @@ -128697,8 +125598,8 @@ Signed-off-by: Matthias Reichl --- sound/soc/bcm/Kconfig | 8 ++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/raspidac3.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 201 insertions(+) + sound/soc/bcm/raspidac3.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 202 insertions(+) create mode 100644 sound/soc/bcm/raspidac3.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -128736,10 +125637,10 @@ index 4f5ab1f..b21e11e 100644 +obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o diff --git a/sound/soc/bcm/raspidac3.c b/sound/soc/bcm/raspidac3.c new file mode 100644 -index 0000000..3cabf5b +index 0000000..e7422e2 --- /dev/null +++ b/sound/soc/bcm/raspidac3.c -@@ -0,0 +1,191 @@ +@@ -0,0 +1,192 @@ +/* + * ASoC Driver for RaspiDAC v3 + * @@ -128870,6 +125771,7 @@ index 0000000..3cabf5b +/* audio machine driver */ +static struct snd_soc_card snd_rpi_raspidac3 = { + .name = "RaspiDAC Rev.3x HiFi Audio Card", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_raspidac3_dai, + .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai), +}; @@ -128932,10 +125834,10 @@ index 0000000..3cabf5b +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 852162b9ea81d2a87bd17ad36b1e347dd02039e2 Mon Sep 17 00:00:00 2001 +From 0e83954993c856c53c4bccb3a1987bff50e58533 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:02:34 +0100 -Subject: [PATCH 081/251] tpa6130a2: Add headphone switch control +Subject: [PATCH 078/114] tpa6130a2: Add headphone switch control Signed-off-by: Jan Grulich --- @@ -129026,41 +125928,10 @@ index 11d85c5..3caaa17 100644 /* -From a75c4939c66e03c683d86b01d793d28c074818eb Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 28 Sep 2015 23:38:59 +0100 -Subject: [PATCH 082/251] irq-bcm2835: Fix building with 2708 - ---- - drivers/irqchip/irq-bcm2835.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c -index 20deb28..c02bf8a 100644 ---- a/drivers/irqchip/irq-bcm2835.c -+++ b/drivers/irqchip/irq-bcm2835.c -@@ -82,6 +82,7 @@ - #define NR_BANKS 3 - #define IRQS_PER_BANK 32 - #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) -+#undef FIQ_START - #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - - static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; -@@ -256,7 +257,7 @@ static int __init armctrl_of_init(struct device_node *node, - MAKE_HWIRQ(b, i) + NUMBER_IRQS); - BUG_ON(irq <= 0); - irq_set_chip(irq, &armctrl_chip); -- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ irq_set_probe(irq); - } - } - init_FIQ(FIQ_START); - -From ef612ffab83e04751eca4f4d4a5017fecaab9cae Mon Sep 17 00:00:00 2001 +From 4e521b9a6f05e7f2b5ed358804ee6c36d1c23c4e Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 083/251] rpi_display: add backlight driver and overlay +Subject: [PATCH 079/114] rpi_display: add backlight driver and overlay Add a mailbox-driven backlight controller for the Raspberry Pi DSI touchscreen display. Requires updated GPU firmware to recognise the @@ -129068,99 +125939,12 @@ mailbox request. Signed-off-by: Gordon Hollingworth --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++ - .../boot/dts/overlays/rpi-backlight-overlay.dts | 21 ++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/video/backlight/Kconfig | 6 ++ - drivers/video/backlight/Makefile | 1 + - drivers/video/backlight/rpi_backlight.c | 119 +++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 9 files changed, 157 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts + drivers/video/backlight/Kconfig | 6 ++ + drivers/video/backlight/Makefile | 1 + + drivers/video/backlight/rpi_backlight.c | 119 ++++++++++++++++++++++++++++++++ + 3 files changed, 126 insertions(+) create mode 100644 drivers/video/backlight/rpi_backlight.c -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d8c2771..fb7ac49 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-backlight-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 268d400..d7f2979 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -462,6 +462,12 @@ Load: dtoverlay=raspidac3 - Params: - - -+Name: rpi-backlight -+Info: Raspberry Pi official display backlight driver -+Load: dtoverlay=rpi-backlight -+Params: -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -new file mode 100644 -index 0000000..c021d02 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -@@ -0,0 +1,21 @@ -+/* -+ * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display -+ * backlight controller -+ */ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ rpi_backlight: rpi_backlight { -+ compatible = "raspberrypi,rpi-backlight"; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 16062bf..13999af 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -808,6 +808,7 @@ CONFIG_FB_UDL=m - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_LOGO=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 1d1b799..146add9 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -801,6 +801,7 @@ CONFIG_FB_UDL=m - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_LOGO=y diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 5ffa4b4..c3023ab 100644 --- a/drivers/video/backlight/Kconfig @@ -129315,111 +126099,11 @@ index 0000000..14a0d9b +MODULE_AUTHOR("Gordon Hollingworth "); +MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver"); +MODULE_LICENSE("GPL"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 525816d..b011489 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -112,6 +112,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, - - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - -From 9e683aed13baf656729ca37b7efb70d595781f85 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Mon, 16 Nov 2015 14:05:35 +0000 -Subject: [PATCH 084/251] bcm2835-dma: Fix up convert to DMA pool - ---- - drivers/dma/bcm2835-dma.c | 36 ++++++++++++++++++++++++++---------- - 1 file changed, 26 insertions(+), 10 deletions(-) - -diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c -index 0adc347..985019b 100644 ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -488,6 +488,17 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( - c->cyclic = true; - - return vchan_tx_prep(&c->vc, &d->vd, flags); -+error_cb: -+ i--; -+ for (; i >= 0; i--) { -+ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; -+ -+ dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr); -+ } -+ -+ kfree(d->cb_list); -+ kfree(d); -+ return NULL; - } - - static struct dma_async_tx_descriptor * -@@ -534,6 +545,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - if (!d) - return NULL; - -+ d->c = c; - d->dir = direction; - - if (c->ch >= 8) /* LITE channel */ -@@ -553,15 +565,21 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - d->frames += len / max_size + 1; - } - -- /* Allocate memory for control blocks */ -- d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); -- d->control_block_base = dma_zalloc_coherent(chan->device->dev, -- d->control_block_size, &d->control_block_base_phys, -- GFP_NOWAIT); -- if (!d->control_block_base) { -+ d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL); -+ if (!d->cb_list) { - kfree(d); - return NULL; - } -+ /* Allocate memory for control blocks */ -+ for (i = 0; i < d->frames; i++) { -+ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; -+ -+ cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC, -+ &cb_entry->paddr); -+ -+ if (!cb_entry->cb) -+ goto error_cb; -+ } - - /* - * Iterate over all SG entries, create a control block -@@ -578,7 +596,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - - for (j = 0; j < len; j += max_size) { - struct bcm2835_dma_cb *control_block = -- &d->control_block_base[i + split_cnt]; -+ d->cb_list[i + split_cnt].cb; - - /* Setup addresses */ - if (d->dir == DMA_DEV_TO_MEM) { -@@ -620,9 +638,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - if (i < sg_len - 1 || len - j > max_size) { - /* Next block is the next frame. */ - control_block->next = -- d->control_block_base_phys + -- sizeof(struct bcm2835_dma_cb) * -- (i + split_cnt + 1); -+ d->cb_list[i + split_cnt + 1].paddr; - } else { - /* Next block is empty. */ - control_block->next = 0; - -From 17d171c260c02491c27b1d89e84c09053f825ac2 Mon Sep 17 00:00:00 2001 +From 5ecd9e700a81663147a2457cef2a93fd5ae621cd Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 Nov 2015 11:38:59 +0000 -Subject: [PATCH 085/251] scripts: Multi-platform support for mkknlimg and +Subject: [PATCH 080/114] scripts: Multi-platform support for mkknlimg and knlinfo The firmware uses tags in the kernel trailer to choose which dtb file @@ -129668,17179 +126352,10 @@ index 3998d43..005f404 100755 - return (($val eq 'y') || ($val eq '1')); -} -From 3daa279385ccf4297bb8beb5b1f770ea535e7245 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 2 Mar 2015 13:01:12 -0800 -Subject: [PATCH 086/251] drm/vc4: Add suport for 3D rendering using the V3D - engine. - -This is a squash of the out-of-tree development series. Since that -series contained code from the first "get a demo triangle rendered -using a hacked up driver using binary shader code" to "plug the last -known security hole", it's hard to reconstruct a different series of -incremental development that's mergeable without security holes -throughout it. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/Makefile | 11 +- - drivers/gpu/drm/vc4/vc4_bo.c | 476 +++++++++++++- - drivers/gpu/drm/vc4/vc4_crtc.c | 98 ++- - drivers/gpu/drm/vc4/vc4_debugfs.c | 3 + - drivers/gpu/drm/vc4/vc4_drv.c | 45 +- - drivers/gpu/drm/vc4/vc4_drv.h | 317 ++++++++++ - drivers/gpu/drm/vc4/vc4_gem.c | 686 +++++++++++++++++++++ - drivers/gpu/drm/vc4/vc4_irq.c | 211 +++++++ - drivers/gpu/drm/vc4/vc4_kms.c | 148 ++++- - drivers/gpu/drm/vc4/vc4_packet.h | 384 ++++++++++++ - drivers/gpu/drm/vc4/vc4_plane.c | 40 ++ - drivers/gpu/drm/vc4/vc4_qpu_defines.h | 268 ++++++++ - drivers/gpu/drm/vc4/vc4_render_cl.c | 448 ++++++++++++++ - drivers/gpu/drm/vc4/vc4_trace.h | 63 ++ - drivers/gpu/drm/vc4/vc4_trace_points.c | 14 + - drivers/gpu/drm/vc4/vc4_v3d.c | 268 ++++++++ - drivers/gpu/drm/vc4/vc4_validate.c | 958 +++++++++++++++++++++++++++++ - drivers/gpu/drm/vc4/vc4_validate_shaders.c | 521 ++++++++++++++++ - include/uapi/drm/vc4_drm.h | 229 +++++++ - 19 files changed, 5173 insertions(+), 15 deletions(-) - create mode 100644 drivers/gpu/drm/vc4/vc4_gem.c - create mode 100644 drivers/gpu/drm/vc4/vc4_irq.c - create mode 100644 drivers/gpu/drm/vc4/vc4_packet.h - create mode 100644 drivers/gpu/drm/vc4/vc4_qpu_defines.h - create mode 100644 drivers/gpu/drm/vc4/vc4_render_cl.c - create mode 100644 drivers/gpu/drm/vc4/vc4_trace.h - create mode 100644 drivers/gpu/drm/vc4/vc4_trace_points.c - create mode 100644 drivers/gpu/drm/vc4/vc4_v3d.c - create mode 100644 drivers/gpu/drm/vc4/vc4_validate.c - create mode 100644 drivers/gpu/drm/vc4/vc4_validate_shaders.c - create mode 100644 include/uapi/drm/vc4_drm.h - -diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile -index 32b4f9c..4c6a99f 100644 ---- a/drivers/gpu/drm/vc4/Makefile -+++ b/drivers/gpu/drm/vc4/Makefile -@@ -8,10 +8,19 @@ vc4-y := \ - vc4_crtc.o \ - vc4_drv.o \ - vc4_kms.o \ -+ vc4_gem.o \ - vc4_hdmi.o \ - vc4_hvs.o \ -- vc4_plane.o -+ vc4_irq.o \ -+ vc4_plane.o \ -+ vc4_render_cl.o \ -+ vc4_trace_points.o \ -+ vc4_v3d.o \ -+ vc4_validate.o \ -+ vc4_validate_shaders.o - - vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o - - obj-$(CONFIG_DRM_VC4) += vc4.o -+ -+CFLAGS_vc4_trace_points.o := -I$(src) -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index ab9f510..bfa605f 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -15,16 +15,174 @@ - */ - - #include "vc4_drv.h" -+#include "uapi/drm/vc4_drm.h" - --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size) -+static void vc4_bo_stats_dump(struct vc4_dev *vc4) - { -+ DRM_INFO("num bos allocated: %d\n", -+ vc4->bo_stats.num_allocated); -+ DRM_INFO("size bos allocated: %dkb\n", -+ vc4->bo_stats.size_allocated / 1024); -+ DRM_INFO("num bos used: %d\n", -+ vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached); -+ DRM_INFO("size bos used: %dkb\n", -+ (vc4->bo_stats.size_allocated - -+ vc4->bo_stats.size_cached) / 1024); -+ DRM_INFO("num bos cached: %d\n", -+ vc4->bo_stats.num_cached); -+ DRM_INFO("size bos cached: %dkb\n", -+ vc4->bo_stats.size_cached / 1024); -+} -+ -+static uint32_t bo_page_index(size_t size) -+{ -+ return (size / PAGE_SIZE) - 1; -+} -+ -+/* Must be called with bo_lock held. */ -+static void vc4_bo_destroy(struct vc4_bo *bo) -+{ -+ struct drm_gem_object *obj = &bo->base.base; -+ struct vc4_dev *vc4 = to_vc4_dev(obj->dev); -+ -+ if (bo->validated_shader) { -+ kfree(bo->validated_shader->texture_samples); -+ kfree(bo->validated_shader); -+ bo->validated_shader = NULL; -+ } -+ -+ vc4->bo_stats.num_allocated--; -+ vc4->bo_stats.size_allocated -= obj->size; -+ drm_gem_cma_free_object(obj); -+} -+ -+/* Must be called with bo_lock held. */ -+static void vc4_bo_remove_from_cache(struct vc4_bo *bo) -+{ -+ struct drm_gem_object *obj = &bo->base.base; -+ struct vc4_dev *vc4 = to_vc4_dev(obj->dev); -+ -+ vc4->bo_stats.num_cached--; -+ vc4->bo_stats.size_cached -= obj->size; -+ -+ list_del(&bo->unref_head); -+ list_del(&bo->size_head); -+} -+ -+static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, -+ size_t size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t page_index = bo_page_index(size); -+ -+ if (vc4->bo_cache.size_list_size <= page_index) { -+ uint32_t new_size = max(vc4->bo_cache.size_list_size * 2, -+ page_index + 1); -+ struct list_head *new_list; -+ uint32_t i; -+ -+ new_list = kmalloc(new_size * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!new_list) -+ return NULL; -+ -+ /* Rebase the old cached BO lists to their new list -+ * head locations. -+ */ -+ for (i = 0; i < vc4->bo_cache.size_list_size; i++) { -+ struct list_head *old_list = &vc4->bo_cache.size_list[i]; -+ if (list_empty(old_list)) -+ INIT_LIST_HEAD(&new_list[i]); -+ else -+ list_replace(old_list, &new_list[i]); -+ } -+ /* And initialize the brand new BO list heads. */ -+ for (i = vc4->bo_cache.size_list_size; i < new_size; i++) -+ INIT_LIST_HEAD(&new_list[i]); -+ -+ kfree(vc4->bo_cache.size_list); -+ vc4->bo_cache.size_list = new_list; -+ vc4->bo_cache.size_list_size = new_size; -+ } -+ -+ return &vc4->bo_cache.size_list[page_index]; -+} -+ -+void vc4_bo_cache_purge(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ spin_lock(&vc4->bo_lock); -+ while (!list_empty(&vc4->bo_cache.time_list)) { -+ struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, -+ struct vc4_bo, unref_head); -+ vc4_bo_remove_from_cache(bo); -+ vc4_bo_destroy(bo); -+ } -+ spin_unlock(&vc4->bo_lock); -+} -+ -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t size = roundup(unaligned_size, PAGE_SIZE); -+ uint32_t page_index = bo_page_index(size); - struct drm_gem_cma_object *cma_obj; -+ int pass; - -- cma_obj = drm_gem_cma_create(dev, size); -- if (IS_ERR(cma_obj)) -+ if (size == 0) - return NULL; -- else -- return to_vc4_bo(&cma_obj->base); -+ -+ /* First, try to get a vc4_bo from the kernel BO cache. */ -+ spin_lock(&vc4->bo_lock); -+ if (page_index < vc4->bo_cache.size_list_size && -+ !list_empty(&vc4->bo_cache.size_list[page_index])) { -+ struct vc4_bo *bo = -+ list_first_entry(&vc4->bo_cache.size_list[page_index], -+ struct vc4_bo, size_head); -+ vc4_bo_remove_from_cache(bo); -+ spin_unlock(&vc4->bo_lock); -+ kref_init(&bo->base.base.refcount); -+ return bo; -+ } -+ spin_unlock(&vc4->bo_lock); -+ -+ /* Otherwise, make a new BO. */ -+ for (pass = 0; ; pass++) { -+ cma_obj = drm_gem_cma_create(dev, size); -+ if (!IS_ERR(cma_obj)) -+ break; -+ -+ switch (pass) { -+ case 0: -+ /* -+ * If we've run out of CMA memory, kill the cache of -+ * CMA allocations we've got laying around and try again. -+ */ -+ vc4_bo_cache_purge(dev); -+ break; -+ case 1: -+ /* -+ * Getting desperate, so try to wait for any -+ * previous rendering to finish, free its -+ * unreferenced BOs to the cache, and then -+ * free the cache. -+ */ -+ vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, true); -+ vc4_job_handle_completed(vc4); -+ vc4_bo_cache_purge(dev); -+ break; -+ case 3: -+ DRM_ERROR("Failed to allocate from CMA:\n"); -+ vc4_bo_stats_dump(vc4); -+ return NULL; -+ } -+ } -+ -+ vc4->bo_stats.num_allocated++; -+ vc4->bo_stats.size_allocated += size; -+ -+ return to_vc4_bo(&cma_obj->base); - } - - int vc4_dumb_create(struct drm_file *file_priv, -@@ -41,7 +199,7 @@ int vc4_dumb_create(struct drm_file *file_priv, - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; - -- bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE)); -+ bo = vc4_bo_create(dev, args->size); - if (!bo) - return -ENOMEM; - -@@ -50,3 +208,309 @@ int vc4_dumb_create(struct drm_file *file_priv, - - return ret; - } -+ -+static void -+vc4_bo_cache_free_old(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long expire_time = jiffies - msecs_to_jiffies(1000); -+ -+ spin_lock(&vc4->bo_lock); -+ while (!list_empty(&vc4->bo_cache.time_list)) { -+ struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, -+ struct vc4_bo, unref_head); -+ if (time_before(expire_time, bo->free_time)) { -+ mod_timer(&vc4->bo_cache.time_timer, -+ round_jiffies_up(jiffies + -+ msecs_to_jiffies(1000))); -+ spin_unlock(&vc4->bo_lock); -+ return; -+ } -+ -+ vc4_bo_remove_from_cache(bo); -+ vc4_bo_destroy(bo); -+ } -+ spin_unlock(&vc4->bo_lock); -+} -+ -+/* Called on the last userspace/kernel unreference of the BO. Returns -+ * it to the BO cache if possible, otherwise frees it. -+ * -+ * Note that this is called with the struct_mutex held. -+ */ -+void vc4_free_object(struct drm_gem_object *gem_bo) -+{ -+ struct drm_device *dev = gem_bo->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo *bo = to_vc4_bo(gem_bo); -+ struct list_head *cache_list; -+ -+ /* If the object references someone else's memory, we can't cache it. -+ */ -+ if (gem_bo->import_attach) { -+ vc4_bo_destroy(bo); -+ return; -+ } -+ -+ /* Don't cache if it was publicly named. */ -+ if (gem_bo->name) { -+ vc4_bo_destroy(bo); -+ return; -+ } -+ -+ spin_lock(&vc4->bo_lock); -+ cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); -+ if (!cache_list) { -+ vc4_bo_destroy(bo); -+ spin_unlock(&vc4->bo_lock); -+ return; -+ } -+ -+ if (bo->validated_shader) { -+ kfree(bo->validated_shader->texture_samples); -+ kfree(bo->validated_shader); -+ bo->validated_shader = NULL; -+ } -+ -+ bo->free_time = jiffies; -+ list_add(&bo->size_head, cache_list); -+ list_add(&bo->unref_head, &vc4->bo_cache.time_list); -+ -+ vc4->bo_stats.num_cached++; -+ vc4->bo_stats.size_cached += gem_bo->size; -+ spin_unlock(&vc4->bo_lock); -+ -+ vc4_bo_cache_free_old(dev); -+} -+ -+static void vc4_bo_cache_time_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, bo_cache.time_work); -+ struct drm_device *dev = vc4->dev; -+ -+ vc4_bo_cache_free_old(dev); -+} -+ -+static void vc4_bo_cache_time_timer(unsigned long data) -+{ -+ struct drm_device *dev = (struct drm_device *)data; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ schedule_work(&vc4->bo_cache.time_work); -+} -+ -+struct dma_buf * -+vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("Attempting to export shader BO\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_prime_export(dev, obj, flags); -+} -+ -+int -+vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_create_bo *args = data; -+ struct vc4_bo *bo = NULL; -+ int ret; -+ -+ bo = vc4_bo_create(dev, args->size); -+ if (!bo) -+ return -ENOMEM; -+ -+ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); -+ drm_gem_object_unreference_unlocked(&bo->base.base); -+ -+ return ret; -+} -+ -+int -+vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_create_shader_bo *args = data; -+ struct vc4_bo *bo = NULL; -+ int ret; -+ -+ if (args->size == 0) -+ return -EINVAL; -+ -+ if (args->size % sizeof(u64) != 0) -+ return -EINVAL; -+ -+ if (args->flags != 0) { -+ DRM_INFO("Unknown flags set: 0x%08x\n", args->flags); -+ return -EINVAL; -+ } -+ -+ if (args->pad != 0) { -+ DRM_INFO("Pad set: 0x%08x\n", args->pad); -+ return -EINVAL; -+ } -+ -+ bo = vc4_bo_create(dev, args->size); -+ if (!bo) -+ return -ENOMEM; -+ -+ ret = copy_from_user(bo->base.vaddr, -+ (void __user *)(uintptr_t)args->data, -+ args->size); -+ if (ret != 0) -+ goto fail; -+ -+ bo->validated_shader = vc4_validate_shader(&bo->base); -+ if (!bo->validated_shader) { -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ /* We have to create the handle after validation, to avoid -+ * races for users to do doing things like mmap the shader BO. -+ */ -+ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); -+ -+ fail: -+ drm_gem_object_unreference_unlocked(&bo->base.base); -+ -+ return ret; -+} -+ -+int -+vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_mmap_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ -+ /* The mmap offset was set up at BO allocation time. */ -+ args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -+ -+ drm_gem_object_unreference(gem_obj); -+ return 0; -+} -+ -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ int ret; -+ -+ ret = drm_gem_mmap(filp, vma); -+ if (ret) -+ return ret; -+ -+ gem_obj = vma->vm_private_data; -+ bo = to_vc4_bo(gem_obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -+ * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -+ * the whole buffer. -+ */ -+ vma->vm_flags &= ~VM_PFNMAP; -+ vma->vm_pgoff = 0; -+ -+ ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -+ bo->base.vaddr, bo->base.paddr, -+ vma->vm_end - vma->vm_start); -+ if (ret) -+ drm_gem_vm_close(vma); -+ -+ return ret; -+} -+ -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ return drm_gem_cma_prime_mmap(obj, vma); -+} -+ -+void *vc4_prime_vmap(struct drm_gem_object *obj) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_cma_prime_vmap(obj); -+} -+ -+void vc4_bo_cache_init(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ spin_lock_init(&vc4->bo_lock); -+ -+ INIT_LIST_HEAD(&vc4->bo_cache.time_list); -+ -+ INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); -+ setup_timer(&vc4->bo_cache.time_timer, -+ vc4_bo_cache_time_timer, -+ (unsigned long) dev); -+} -+ -+void vc4_bo_cache_destroy(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ del_timer(&vc4->bo_cache.time_timer); -+ cancel_work_sync(&vc4->bo_cache.time_work); -+ -+ vc4_bo_cache_purge(dev); -+ -+ if (vc4->bo_stats.num_allocated) { -+ DRM_ERROR("Destroying BO cache while BOs still allocated:\n"); -+ vc4_bo_stats_dump(vc4); -+ } -+} -+ -+#ifdef CONFIG_DEBUG_FS -+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo_stats stats; -+ -+ spin_lock(&vc4->bo_lock); -+ stats = vc4->bo_stats; -+ spin_unlock(&vc4->bo_lock); -+ -+ seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); -+ seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -+ seq_printf(m, "num bos used: %d\n", (stats.num_allocated - -+ stats.num_cached)); -+ seq_printf(m, "size bos used: %dkb\n", (stats.size_allocated - -+ stats.size_cached) / 1024); -+ seq_printf(m, "num bos cached: %d\n", stats.num_cached); -+ seq_printf(m, "size bos cached: %dkb\n", stats.size_cached / 1024); -+ -+ return 0; -+} -+#endif -diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c -index 265064c..3be2720 100644 ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -35,6 +35,7 @@ - #include "drm_atomic_helper.h" - #include "drm_crtc_helper.h" - #include "linux/clk.h" -+#include "drm_fb_cma_helper.h" - #include "linux/component.h" - #include "linux/of_device.h" - #include "vc4_drv.h" -@@ -476,10 +477,105 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) - return ret; - } - -+struct vc4_async_flip_state { -+ struct drm_crtc *crtc; -+ struct drm_framebuffer *fb; -+ struct drm_pending_vblank_event *event; -+ -+ struct vc4_seqno_cb cb; -+}; -+ -+/* Called when the V3D execution for the BO being flipped to is done, so that -+ * we can actually update the plane's address to point to it. -+ */ -+static void -+vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) -+{ -+ struct vc4_async_flip_state *flip_state = -+ container_of(cb, struct vc4_async_flip_state, cb); -+ struct drm_crtc *crtc = flip_state->crtc; -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_plane *plane = crtc->primary; -+ -+ vc4_plane_async_set_fb(plane, flip_state->fb); -+ if (flip_state->event) { -+ unsigned long flags; -+ spin_lock_irqsave(&dev->event_lock, flags); -+ drm_crtc_send_vblank_event(crtc, flip_state->event); -+ spin_unlock_irqrestore(&dev->event_lock, flags); -+ } -+ -+ drm_framebuffer_unreference(flip_state->fb); -+ kfree(flip_state); -+ -+ up(&vc4->async_modeset); -+} -+ -+/* Implements async (non-vblank-synced) page flips. -+ * -+ * The page flip ioctl needs to return immediately, so we grab the -+ * modeset semaphore on the pipe, and queue the address update for -+ * when V3D is done with the BO being flipped to. -+ */ -+static int vc4_async_page_flip(struct drm_crtc *crtc, -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) -+{ -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_plane *plane = crtc->primary; -+ int ret = 0; -+ struct vc4_async_flip_state *flip_state; -+ struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); -+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ -+ flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); -+ if (!flip_state) -+ return -ENOMEM; -+ -+ drm_framebuffer_reference(fb); -+ flip_state->fb = fb; -+ flip_state->crtc = crtc; -+ flip_state->event = event; -+ -+ /* Make sure all other async modesetes have landed. */ -+ ret = down_interruptible(&vc4->async_modeset); -+ if (ret) { -+ kfree(flip_state); -+ return ret; -+ } -+ -+ /* Immediately update the plane's legacy fb pointer, so that later -+ * modeset prep sees the state that will be present when the semaphore -+ * is released. -+ */ -+ drm_atomic_set_fb_for_plane(plane->state, fb); -+ plane->fb = fb; -+ -+ vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, -+ vc4_async_page_flip_complete); -+ -+ /* Driver takes ownership of state on successful async commit. */ -+ return 0; -+} -+ -+static int vc4_page_flip(struct drm_crtc *crtc, -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) -+{ -+ if (flags & DRM_MODE_PAGE_FLIP_ASYNC) -+ return vc4_async_page_flip(crtc, fb, event, flags); -+ else -+ return drm_atomic_helper_page_flip(crtc, fb, event, flags); -+} -+ - static const struct drm_crtc_funcs vc4_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, - .destroy = vc4_crtc_destroy, -- .page_flip = drm_atomic_helper_page_flip, -+ .page_flip = vc4_page_flip, - .set_property = NULL, - .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ - .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ -diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c -index 4297b0a..d76ad10 100644 ---- a/drivers/gpu/drm/vc4/vc4_debugfs.c -+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c -@@ -16,11 +16,14 @@ - #include "vc4_regs.h" - - static const struct drm_info_list vc4_debugfs_list[] = { -+ {"bo_stats", vc4_bo_stats_debugfs, 0}, - {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, - {"hvs_regs", vc4_hvs_debugfs_regs, 0}, - {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, - {"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1}, - {"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2}, -+ {"v3d_ident", vc4_v3d_debugfs_ident, 0}, -+ {"v3d_regs", vc4_v3d_debugfs_regs, 0}, - }; - - #define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list) -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index d5db9e0..3baf1fc 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -14,8 +14,10 @@ - #include - #include - #include -+#include - #include "drm_fb_cma_helper.h" - -+#include "uapi/drm/vc4_drm.h" - #include "vc4_drv.h" - #include "vc4_regs.h" - -@@ -63,7 +65,7 @@ static const struct file_operations vc4_drm_fops = { - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, -- .mmap = drm_gem_cma_mmap, -+ .mmap = vc4_mmap, - .poll = drm_poll, - .read = drm_read, - #ifdef CONFIG_COMPAT -@@ -73,16 +75,28 @@ static const struct file_operations vc4_drm_fops = { - }; - - static const struct drm_ioctl_desc vc4_drm_ioctls[] = { -+ DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), - }; - - static struct drm_driver vc4_drm_driver = { - .driver_features = (DRIVER_MODESET | - DRIVER_ATOMIC | - DRIVER_GEM | -+ DRIVER_HAVE_IRQ | - DRIVER_PRIME), - .lastclose = vc4_lastclose, - .preclose = vc4_drm_preclose, - -+ .irq_handler = vc4_irq, -+ .irq_preinstall = vc4_irq_preinstall, -+ .irq_postinstall = vc4_irq_postinstall, -+ .irq_uninstall = vc4_irq_uninstall, -+ - .enable_vblank = vc4_enable_vblank, - .disable_vblank = vc4_disable_vblank, - .get_vblank_counter = drm_vblank_count, -@@ -92,18 +106,18 @@ static struct drm_driver vc4_drm_driver = { - .debugfs_cleanup = vc4_debugfs_cleanup, - #endif - -- .gem_free_object = drm_gem_cma_free_object, -+ .gem_free_object = vc4_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_import = drm_gem_prime_import, -- .gem_prime_export = drm_gem_prime_export, -+ .gem_prime_export = vc4_prime_export, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, -- .gem_prime_vmap = drm_gem_cma_prime_vmap, -+ .gem_prime_vmap = vc4_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, -- .gem_prime_mmap = drm_gem_cma_prime_mmap, -+ .gem_prime_mmap = vc4_prime_mmap, - - .dumb_create = vc4_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, -@@ -113,6 +127,8 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -+ .gem_obj_size = sizeof(struct vc4_bo), -+ - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, -@@ -153,6 +169,7 @@ static int vc4_drm_bind(struct device *dev) - struct drm_device *drm; - struct drm_connector *connector; - struct vc4_dev *vc4; -+ struct device_node *firmware_node; - int ret = 0; - - dev->coherent_dma_mask = DMA_BIT_MASK(32); -@@ -161,6 +178,14 @@ static int vc4_drm_bind(struct device *dev) - if (!vc4) - return -ENOMEM; - -+ firmware_node = of_parse_phandle(dev->of_node, "firmware", 0); -+ vc4->firmware = rpi_firmware_get(firmware_node); -+ if (!vc4->firmware) { -+ DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); -+ return -EPROBE_DEFER; -+ } -+ of_node_put(firmware_node); -+ - drm = drm_dev_alloc(&vc4_drm_driver, dev); - if (!drm) - return -ENOMEM; -@@ -170,13 +195,17 @@ static int vc4_drm_bind(struct device *dev) - - drm_dev_set_unique(drm, dev_name(dev)); - -+ vc4_bo_cache_init(drm); -+ - drm_mode_config_init(drm); - if (ret) - goto unref; - -+ vc4_gem_init(drm); -+ - ret = component_bind_all(dev, drm); - if (ret) -- goto unref; -+ goto gem_destroy; - - ret = drm_dev_register(drm, 0); - if (ret < 0) -@@ -200,8 +229,11 @@ unregister: - drm_dev_unregister(drm); - unbind_all: - component_unbind_all(dev, drm); -+gem_destroy: -+ vc4_gem_destroy(drm); - unref: - drm_dev_unref(drm); -+ vc4_bo_cache_destroy(drm); - return ret; - } - -@@ -228,6 +260,7 @@ static struct platform_driver *const component_drivers[] = { - &vc4_hdmi_driver, - &vc4_crtc_driver, - &vc4_hvs_driver, -+ &vc4_v3d_driver, - }; - - static int vc4_platform_drm_probe(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index fd8319f..8cc89d1 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -15,8 +15,85 @@ struct vc4_dev { - struct vc4_hdmi *hdmi; - struct vc4_hvs *hvs; - struct vc4_crtc *crtc[3]; -+ struct vc4_v3d *v3d; - - struct drm_fbdev_cma *fbdev; -+ struct rpi_firmware *firmware; -+ -+ /* The kernel-space BO cache. Tracks buffers that have been -+ * unreferenced by all other users (refcounts of 0!) but not -+ * yet freed, so we can do cheap allocations. -+ */ -+ struct vc4_bo_cache { -+ /* Array of list heads for entries in the BO cache, -+ * based on number of pages, so we can do O(1) lookups -+ * in the cache when allocating. -+ */ -+ struct list_head *size_list; -+ uint32_t size_list_size; -+ -+ /* List of all BOs in the cache, ordered by age, so we -+ * can do O(1) lookups when trying to free old -+ * buffers. -+ */ -+ struct list_head time_list; -+ struct work_struct time_work; -+ struct timer_list time_timer; -+ } bo_cache; -+ -+ struct vc4_bo_stats { -+ u32 num_allocated; -+ u32 size_allocated; -+ u32 num_cached; -+ u32 size_cached; -+ } bo_stats; -+ -+ /* Protects bo_cache and the BO stats. */ -+ spinlock_t bo_lock; -+ -+ /* Sequence number for the last job queued in job_list. -+ * Starts at 0 (no jobs emitted). -+ */ -+ uint64_t emit_seqno; -+ -+ /* Sequence number for the last completed job on the GPU. -+ * Starts at 0 (no jobs completed). -+ */ -+ uint64_t finished_seqno; -+ -+ /* List of all struct vc4_exec_info for jobs to be executed. -+ * The first job in the list is the one currently programmed -+ * into ct0ca/ct1ca for execution. -+ */ -+ struct list_head job_list; -+ /* List of the finished vc4_exec_infos waiting to be freed by -+ * job_done_work. -+ */ -+ struct list_head job_done_list; -+ spinlock_t job_lock; -+ wait_queue_head_t job_wait_queue; -+ struct work_struct job_done_work; -+ -+ /* List of struct vc4_seqno_cb for callbacks to be made from a -+ * workqueue when the given seqno is passed. -+ */ -+ struct list_head seqno_cb_list; -+ -+ /* The binner overflow memory that's currently set up in -+ * BPOA/BPOS registers. When overflow occurs and a new one is -+ * allocated, the previous one will be moved to -+ * vc4->current_exec's free list. -+ */ -+ struct vc4_bo *overflow_mem; -+ struct work_struct overflow_mem_work; -+ -+ struct { -+ uint32_t last_ct0ca, last_ct1ca; -+ struct timer_list timer; -+ struct work_struct reset_work; -+ } hangcheck; -+ -+ struct semaphore async_modeset; - }; - - static inline struct vc4_dev * -@@ -27,6 +104,25 @@ to_vc4_dev(struct drm_device *dev) - - struct vc4_bo { - struct drm_gem_cma_object base; -+ -+ /* seqno of the last job to render to this BO. */ -+ uint64_t seqno; -+ -+ /* List entry for the BO's position in either -+ * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list -+ */ -+ struct list_head unref_head; -+ -+ /* Time in jiffies when the BO was put in vc4->bo_cache. */ -+ unsigned long free_time; -+ -+ /* List entry for the BO's position in vc4_dev->bo_cache.size_list */ -+ struct list_head size_head; -+ -+ /* Struct for shader validation state, if created by -+ * DRM_IOCTL_VC4_CREATE_SHADER_BO. -+ */ -+ struct vc4_validated_shader_info *validated_shader; - }; - - static inline struct vc4_bo * -@@ -35,6 +131,17 @@ to_vc4_bo(struct drm_gem_object *bo) - return (struct vc4_bo *)bo; - } - -+struct vc4_seqno_cb { -+ struct work_struct work; -+ uint64_t seqno; -+ void (*func)(struct vc4_seqno_cb *cb); -+}; -+ -+struct vc4_v3d { -+ struct platform_device *pdev; -+ void __iomem *regs; -+}; -+ - struct vc4_hvs { - struct platform_device *pdev; - void __iomem *regs; -@@ -72,9 +179,151 @@ to_vc4_encoder(struct drm_encoder *encoder) - return container_of(encoder, struct vc4_encoder, base); - } - -+#define V3D_READ(offset) readl(vc4->v3d->regs + offset) -+#define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset) - #define HVS_READ(offset) readl(vc4->hvs->regs + offset) - #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) - -+enum vc4_bo_mode { -+ VC4_MODE_UNDECIDED, -+ VC4_MODE_RENDER, -+ VC4_MODE_SHADER, -+}; -+ -+struct vc4_bo_exec_state { -+ struct drm_gem_cma_object *bo; -+ enum vc4_bo_mode mode; -+}; -+ -+struct vc4_exec_info { -+ /* Sequence number for this bin/render job. */ -+ uint64_t seqno; -+ -+ /* Kernel-space copy of the ioctl arguments */ -+ struct drm_vc4_submit_cl *args; -+ -+ /* This is the array of BOs that were looked up at the start of exec. -+ * Command validation will use indices into this array. -+ */ -+ struct vc4_bo_exec_state *bo; -+ uint32_t bo_count; -+ -+ /* Pointers for our position in vc4->job_list */ -+ struct list_head head; -+ -+ /* List of other BOs used in the job that need to be released -+ * once the job is complete. -+ */ -+ struct list_head unref_list; -+ -+ /* Current unvalidated indices into @bo loaded by the non-hardware -+ * VC4_PACKET_GEM_HANDLES. -+ */ -+ uint32_t bo_index[2]; -+ -+ /* This is the BO where we store the validated command lists, shader -+ * records, and uniforms. -+ */ -+ struct drm_gem_cma_object *exec_bo; -+ -+ /** -+ * This tracks the per-shader-record state (packet 64) that -+ * determines the length of the shader record and the offset -+ * it's expected to be found at. It gets read in from the -+ * command lists. -+ */ -+ struct vc4_shader_state { -+ uint8_t packet; -+ uint32_t addr; -+ /* Maximum vertex index referenced by any primitive using this -+ * shader state. -+ */ -+ uint32_t max_index; -+ } *shader_state; -+ -+ /** How many shader states the user declared they were using. */ -+ uint32_t shader_state_size; -+ /** How many shader state records the validator has seen. */ -+ uint32_t shader_state_count; -+ -+ bool found_tile_binning_mode_config_packet; -+ bool found_start_tile_binning_packet; -+ bool found_increment_semaphore_packet; -+ uint8_t bin_tiles_x, bin_tiles_y; -+ struct drm_gem_cma_object *tile_bo; -+ uint32_t tile_alloc_offset; -+ -+ /** -+ * Computed addresses pointing into exec_bo where we start the -+ * bin thread (ct0) and render thread (ct1). -+ */ -+ uint32_t ct0ca, ct0ea; -+ uint32_t ct1ca, ct1ea; -+ -+ /* Pointers to the shader recs. These paddr gets incremented as CL -+ * packets are relocated in validate_gl_shader_state, and the vaddrs -+ * (u and v) get incremented and size decremented as the shader recs -+ * themselves are validated. -+ */ -+ void *shader_rec_u; -+ void *shader_rec_v; -+ uint32_t shader_rec_p; -+ uint32_t shader_rec_size; -+ -+ /* Pointers to the uniform data. These pointers are incremented, and -+ * size decremented, as each batch of uniforms is uploaded. -+ */ -+ void *uniforms_u; -+ void *uniforms_v; -+ uint32_t uniforms_p; -+ uint32_t uniforms_size; -+}; -+ -+static inline struct vc4_exec_info * -+vc4_first_job(struct vc4_dev *vc4) -+{ -+ if (list_empty(&vc4->job_list)) -+ return NULL; -+ return list_first_entry(&vc4->job_list, struct vc4_exec_info, head); -+} -+ -+/** -+ * struct vc4_texture_sample_info - saves the offsets into the UBO for texture -+ * setup parameters. -+ * -+ * This will be used at draw time to relocate the reference to the texture -+ * contents in p0, and validate that the offset combined with -+ * width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO. -+ * Note that the hardware treats unprovided config parameters as 0, so not all -+ * of them need to be set up for every texure sample, and we'll store ~0 as -+ * the offset to mark the unused ones. -+ * -+ * See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit -+ * Setup") for definitions of the texture parameters. -+ */ -+struct vc4_texture_sample_info { -+ bool is_direct; -+ uint32_t p_offset[4]; -+}; -+ -+/** -+ * struct vc4_validated_shader_info - information about validated shaders that -+ * needs to be used from command list validation. -+ * -+ * For a given shader, each time a shader state record references it, we need -+ * to verify that the shader doesn't read more uniforms than the shader state -+ * record's uniform BO pointer can provide, and we need to apply relocations -+ * and validate the shader state record's uniforms that define the texture -+ * samples. -+ */ -+struct vc4_validated_shader_info -+{ -+ uint32_t uniforms_size; -+ uint32_t uniforms_src_size; -+ uint32_t num_texture_samples; -+ struct vc4_texture_sample_info *texture_samples; -+}; -+ - /** - * _wait_for - magic (register) wait macro - * -@@ -111,6 +360,18 @@ int vc4_dumb_create(struct drm_file *file_priv, - struct drm_mode_create_dumb *args); - struct dma_buf *vc4_prime_export(struct drm_device *dev, - struct drm_gem_object *obj, int flags); -+int vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma); -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); -+void *vc4_prime_vmap(struct drm_gem_object *obj); -+void vc4_bo_cache_init(struct drm_device *dev); -+void vc4_bo_cache_destroy(struct drm_device *dev); -+int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); - - /* vc4_crtc.c */ - extern struct platform_driver vc4_crtc_driver; -@@ -126,10 +387,34 @@ void vc4_debugfs_cleanup(struct drm_minor *minor); - /* vc4_drv.c */ - void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); - -+/* vc4_gem.c */ -+void vc4_gem_init(struct drm_device *dev); -+void vc4_gem_destroy(struct drm_device *dev); -+int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_wait_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+void vc4_submit_next_job(struct drm_device *dev); -+int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, -+ uint64_t timeout_ns, bool interruptible); -+void vc4_job_handle_completed(struct vc4_dev *vc4); -+int vc4_queue_seqno_cb(struct drm_device *dev, -+ struct vc4_seqno_cb *cb, uint64_t seqno, -+ void (*func)(struct vc4_seqno_cb *cb)); -+ - /* vc4_hdmi.c */ - extern struct platform_driver vc4_hdmi_driver; - int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused); - -+/* vc4_irq.c */ -+irqreturn_t vc4_irq(int irq, void *arg); -+void vc4_irq_preinstall(struct drm_device *dev); -+int vc4_irq_postinstall(struct drm_device *dev); -+void vc4_irq_uninstall(struct drm_device *dev); -+void vc4_irq_reset(struct drm_device *dev); -+ - /* vc4_hvs.c */ - extern struct platform_driver vc4_hvs_driver; - void vc4_hvs_dump_state(struct drm_device *dev); -@@ -143,3 +428,35 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, - enum drm_plane_type type); - u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); - u32 vc4_plane_dlist_size(struct drm_plane_state *state); -+void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb); -+ -+/* vc4_v3d.c */ -+extern struct platform_driver vc4_v3d_driver; -+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); -+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); -+int vc4_v3d_set_power(struct vc4_dev *vc4, bool on); -+ -+/* vc4_validate.c */ -+int -+vc4_validate_bin_cl(struct drm_device *dev, -+ void *validated, -+ void *unvalidated, -+ struct vc4_exec_info *exec); -+ -+int -+vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); -+ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -+ -+bool vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj); -+ -+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); -+ -+bool vc4_check_tex_size(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *fbo, -+ uint32_t offset, uint8_t tiling_format, -+ uint32_t width, uint32_t height, uint8_t cpp); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -new file mode 100644 -index 0000000..361390b ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -0,0 +1,686 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+#include "vc4_trace.h" -+ -+static void -+vc4_queue_hangcheck(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ mod_timer(&vc4->hangcheck.timer, -+ round_jiffies_up(jiffies + msecs_to_jiffies(100))); -+} -+ -+static void -+vc4_reset(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ DRM_INFO("Resetting GPU.\n"); -+ vc4_v3d_set_power(vc4, false); -+ vc4_v3d_set_power(vc4, true); -+ -+ vc4_irq_reset(dev); -+ -+ /* Rearm the hangcheck -- another job might have been waiting -+ * for our hung one to get kicked off, and vc4_irq_reset() -+ * would have started it. -+ */ -+ vc4_queue_hangcheck(dev); -+} -+ -+static void -+vc4_reset_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, hangcheck.reset_work); -+ -+ vc4_reset(vc4->dev); -+} -+ -+static void -+vc4_hangcheck_elapsed(unsigned long data) -+{ -+ struct drm_device *dev = (struct drm_device *)data; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t ct0ca, ct1ca; -+ -+ /* If idle, we can stop watching for hangs. */ -+ if (list_empty(&vc4->job_list)) -+ return; -+ -+ ct0ca = V3D_READ(V3D_CTNCA(0)); -+ ct1ca = V3D_READ(V3D_CTNCA(1)); -+ -+ /* If we've made any progress in execution, rearm the timer -+ * and wait. -+ */ -+ if (ct0ca != vc4->hangcheck.last_ct0ca || -+ ct1ca != vc4->hangcheck.last_ct1ca) { -+ vc4->hangcheck.last_ct0ca = ct0ca; -+ vc4->hangcheck.last_ct1ca = ct1ca; -+ vc4_queue_hangcheck(dev); -+ return; -+ } -+ -+ /* We've gone too long with no progress, reset. This has to -+ * be done from a work struct, since resetting can sleep and -+ * this timer hook isn't allowed to. -+ */ -+ schedule_work(&vc4->hangcheck.reset_work); -+} -+ -+static void -+submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Stop any existing thread and set state to "stopped at halt" */ -+ V3D_WRITE(V3D_CTNCS(thread), V3D_CTRUN); -+ barrier(); -+ -+ V3D_WRITE(V3D_CTNCA(thread), start); -+ barrier(); -+ -+ /* Set the end address of the control list. Writing this -+ * register is what starts the job. -+ */ -+ V3D_WRITE(V3D_CTNEA(thread), end); -+ barrier(); -+} -+ -+int -+vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, -+ bool interruptible) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret = 0; -+ unsigned long timeout_expire; -+ DEFINE_WAIT(wait); -+ -+ if (vc4->finished_seqno >= seqno) -+ return 0; -+ -+ if (timeout_ns == 0) -+ return -ETIME; -+ -+ timeout_expire = jiffies + nsecs_to_jiffies(timeout_ns); -+ -+ trace_vc4_wait_for_seqno_begin(dev, seqno, timeout_ns); -+ for (;;) { -+ prepare_to_wait(&vc4->job_wait_queue, &wait, -+ interruptible ? TASK_INTERRUPTIBLE : -+ TASK_UNINTERRUPTIBLE); -+ -+ if (interruptible && signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ -+ if (vc4->finished_seqno >= seqno) -+ break; -+ -+ if (timeout_ns != ~0ull) { -+ if (time_after_eq(jiffies, timeout_expire)) { -+ ret = -ETIME; -+ break; -+ } -+ schedule_timeout(timeout_expire - jiffies); -+ } else { -+ schedule(); -+ } -+ } -+ -+ finish_wait(&vc4->job_wait_queue, &wait); -+ trace_vc4_wait_for_seqno_end(dev, seqno); -+ -+ if (ret && ret != -ERESTARTSYS) { -+ DRM_ERROR("timeout waiting for render thread idle\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void -+vc4_flush_caches(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Flush the GPU L2 caches. These caches sit on top of system -+ * L3 (the 128kb or so shared with the CPU), and are -+ * non-allocating in the L3. -+ */ -+ V3D_WRITE(V3D_L2CACTL, -+ V3D_L2CACTL_L2CCLR); -+ -+ V3D_WRITE(V3D_SLCACTL, -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_T1CC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_T0CC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_UCC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); -+} -+ -+/* Sets the registers for the next job to be actually be executed in -+ * the hardware. -+ * -+ * The job_lock should be held during this. -+ */ -+void -+vc4_submit_next_job(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_exec_info *exec = vc4_first_job(vc4); -+ -+ if (!exec) -+ return; -+ -+ vc4_flush_caches(dev); -+ -+ /* Disable the binner's pre-loaded overflow memory address */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ if (exec->ct0ca != exec->ct0ea) -+ submit_cl(dev, 0, exec->ct0ca, exec->ct0ea); -+ submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); -+} -+ -+static void -+vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) -+{ -+ struct vc4_bo *bo; -+ unsigned i; -+ -+ for (i = 0; i < exec->bo_count; i++) { -+ bo = to_vc4_bo(&exec->bo[i].bo->base); -+ bo->seqno = seqno; -+ } -+ -+ list_for_each_entry(bo, &exec->unref_list, unref_head) { -+ bo->seqno = seqno; -+ } -+} -+ -+/* Queues a struct vc4_exec_info for execution. If no job is -+ * currently executing, then submits it. -+ * -+ * Unlike most GPUs, our hardware only handles one command list at a -+ * time. To queue multiple jobs at once, we'd need to edit the -+ * previous command list to have a jump to the new one at the end, and -+ * then bump the end address. That's a change for a later date, -+ * though. -+ */ -+static void -+vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint64_t seqno = ++vc4->emit_seqno; -+ unsigned long irqflags; -+ -+ exec->seqno = seqno; -+ vc4_update_bo_seqnos(exec, seqno); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ list_add_tail(&exec->head, &vc4->job_list); -+ -+ /* If no job was executing, kick ours off. Otherwise, it'll -+ * get started when the previous job's frame done interrupt -+ * occurs. -+ */ -+ if (vc4_first_job(vc4) == exec) { -+ vc4_submit_next_job(dev); -+ vc4_queue_hangcheck(dev); -+ } -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+} -+ -+/** -+ * Looks up a bunch of GEM handles for BOs and stores the array for -+ * use in the command validator that actually writes relocated -+ * addresses pointing to them. -+ */ -+static int -+vc4_cl_lookup_bos(struct drm_device *dev, -+ struct drm_file *file_priv, -+ struct vc4_exec_info *exec) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ uint32_t *handles; -+ int ret = 0; -+ int i; -+ -+ exec->bo_count = args->bo_handle_count; -+ -+ if (!exec->bo_count) { -+ /* See comment on bo_index for why we have to check -+ * this. -+ */ -+ DRM_ERROR("Rendering requires BOs to validate\n"); -+ return -EINVAL; -+ } -+ -+ exec->bo = kcalloc(exec->bo_count, sizeof(struct vc4_bo_exec_state), -+ GFP_KERNEL); -+ if (!exec->bo) { -+ DRM_ERROR("Failed to allocate validated BO pointers\n"); -+ return -ENOMEM; -+ } -+ -+ handles = drm_malloc_ab(exec->bo_count, sizeof(uint32_t)); -+ if (!handles) { -+ DRM_ERROR("Failed to allocate incoming GEM handles\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(handles, -+ (void __user *)(uintptr_t)args->bo_handles, -+ exec->bo_count * sizeof(uint32_t)); -+ if (ret) { -+ DRM_ERROR("Failed to copy in GEM handles\n"); -+ goto fail; -+ } -+ -+ spin_lock(&file_priv->table_lock); -+ for (i = 0; i < exec->bo_count; i++) { -+ struct drm_gem_object *bo = idr_find(&file_priv->object_idr, -+ handles[i]); -+ if (!bo) { -+ DRM_ERROR("Failed to look up GEM BO %d: %d\n", -+ i, handles[i]); -+ ret = -EINVAL; -+ spin_unlock(&file_priv->table_lock); -+ goto fail; -+ } -+ drm_gem_object_reference(bo); -+ exec->bo[i].bo = (struct drm_gem_cma_object *)bo; -+ } -+ spin_unlock(&file_priv->table_lock); -+ -+fail: -+ kfree(handles); -+ return 0; -+} -+ -+static int -+vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ void *temp = NULL; -+ void *bin; -+ int ret = 0; -+ uint32_t bin_offset = 0; -+ uint32_t shader_rec_offset = roundup(bin_offset + args->bin_cl_size, -+ 16); -+ uint32_t uniforms_offset = shader_rec_offset + args->shader_rec_size; -+ uint32_t exec_size = uniforms_offset + args->uniforms_size; -+ uint32_t temp_size = exec_size + (sizeof(struct vc4_shader_state) * -+ args->shader_rec_count); -+ struct vc4_bo *bo; -+ -+ if (uniforms_offset < shader_rec_offset || -+ exec_size < uniforms_offset || -+ args->shader_rec_count >= (UINT_MAX / -+ sizeof(struct vc4_shader_state)) || -+ temp_size < exec_size) { -+ DRM_ERROR("overflow in exec arguments\n"); -+ goto fail; -+ } -+ -+ /* Allocate space where we'll store the copied in user command lists -+ * and shader records. -+ * -+ * We don't just copy directly into the BOs because we need to -+ * read the contents back for validation, and I think the -+ * bo->vaddr is uncached access. -+ */ -+ temp = kmalloc(temp_size, GFP_KERNEL); -+ if (!temp) { -+ DRM_ERROR("Failed to allocate storage for copying " -+ "in bin/render CLs.\n"); -+ ret = -ENOMEM; -+ goto fail; -+ } -+ bin = temp + bin_offset; -+ exec->shader_rec_u = temp + shader_rec_offset; -+ exec->uniforms_u = temp + uniforms_offset; -+ exec->shader_state = temp + exec_size; -+ exec->shader_state_size = args->shader_rec_count; -+ -+ ret = copy_from_user(bin, -+ (void __user *)(uintptr_t)args->bin_cl, -+ args->bin_cl_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in bin cl\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(exec->shader_rec_u, -+ (void __user *)(uintptr_t)args->shader_rec, -+ args->shader_rec_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in shader recs\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(exec->uniforms_u, -+ (void __user *)(uintptr_t)args->uniforms, -+ args->uniforms_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in uniforms cl\n"); -+ goto fail; -+ } -+ -+ bo = vc4_bo_create(dev, exec_size); -+ if (!bo) { -+ DRM_ERROR("Couldn't allocate BO for binning\n"); -+ ret = PTR_ERR(exec->exec_bo); -+ goto fail; -+ } -+ exec->exec_bo = &bo->base; -+ -+ list_add_tail(&to_vc4_bo(&exec->exec_bo->base)->unref_head, -+ &exec->unref_list); -+ -+ exec->ct0ca = exec->exec_bo->paddr + bin_offset; -+ -+ exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; -+ exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; -+ exec->shader_rec_size = args->shader_rec_size; -+ -+ exec->uniforms_v = exec->exec_bo->vaddr + uniforms_offset; -+ exec->uniforms_p = exec->exec_bo->paddr + uniforms_offset; -+ exec->uniforms_size = args->uniforms_size; -+ -+ ret = vc4_validate_bin_cl(dev, -+ exec->exec_bo->vaddr + bin_offset, -+ bin, -+ exec); -+ if (ret) -+ goto fail; -+ -+ ret = vc4_validate_shader_recs(dev, exec); -+ -+fail: -+ kfree(temp); -+ return ret; -+} -+ -+static void -+vc4_complete_exec(struct vc4_exec_info *exec) -+{ -+ unsigned i; -+ -+ if (exec->bo) { -+ for (i = 0; i < exec->bo_count; i++) -+ drm_gem_object_unreference(&exec->bo[i].bo->base); -+ kfree(exec->bo); -+ } -+ -+ while (!list_empty(&exec->unref_list)) { -+ struct vc4_bo *bo = list_first_entry(&exec->unref_list, -+ struct vc4_bo, unref_head); -+ list_del(&bo->unref_head); -+ drm_gem_object_unreference(&bo->base.base); -+ } -+ -+ kfree(exec); -+} -+ -+void -+vc4_job_handle_completed(struct vc4_dev *vc4) -+{ -+ unsigned long irqflags; -+ struct vc4_seqno_cb *cb, *cb_temp; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ while (!list_empty(&vc4->job_done_list)) { -+ struct vc4_exec_info *exec = -+ list_first_entry(&vc4->job_done_list, -+ struct vc4_exec_info, head); -+ list_del(&exec->head); -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ vc4_complete_exec(exec); -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ } -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ list_for_each_entry_safe(cb, cb_temp, &vc4->seqno_cb_list, work.entry) { -+ if (cb->seqno <= vc4->finished_seqno) { -+ list_del_init(&cb->work.entry); -+ schedule_work(&cb->work); -+ } -+ } -+} -+ -+static void vc4_seqno_cb_work(struct work_struct *work) -+{ -+ struct vc4_seqno_cb *cb = container_of(work, struct vc4_seqno_cb, work); -+ cb->func(cb); -+} -+ -+int vc4_queue_seqno_cb(struct drm_device *dev, -+ struct vc4_seqno_cb *cb, uint64_t seqno, -+ void (*func)(struct vc4_seqno_cb *cb)) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret = 0; -+ -+ cb->func = func; -+ INIT_WORK(&cb->work, vc4_seqno_cb_work); -+ -+ mutex_lock(&dev->struct_mutex); -+ if (seqno > vc4->finished_seqno) { -+ cb->seqno = seqno; -+ list_add_tail(&cb->work.entry, &vc4->seqno_cb_list); -+ } else { -+ schedule_work(&cb->work); -+ } -+ mutex_unlock(&dev->struct_mutex); -+ -+ return ret; -+} -+ -+/* Scheduled when any job has been completed, this walks the list of -+ * jobs that had completed and unrefs their BOs and frees their exec -+ * structs. -+ */ -+static void -+vc4_job_done_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, job_done_work); -+ struct drm_device *dev = vc4->dev; -+ -+ /* Need the struct lock for drm_gem_object_unreference(). */ -+ mutex_lock(&dev->struct_mutex); -+ vc4_job_handle_completed(vc4); -+ mutex_unlock(&dev->struct_mutex); -+} -+ -+static int -+vc4_wait_for_seqno_ioctl_helper(struct drm_device *dev, -+ uint64_t seqno, -+ uint64_t *timeout_ns) -+{ -+ unsigned long start = jiffies; -+ int ret = vc4_wait_for_seqno(dev, seqno, *timeout_ns, true); -+ -+ if ((ret == -EINTR || ret == -ERESTARTSYS) && *timeout_ns != ~0ull) { -+ uint64_t delta = jiffies_to_nsecs(jiffies - start); -+ if (*timeout_ns >= delta) -+ *timeout_ns -= delta; -+ } -+ -+ return ret; -+} -+ -+int -+vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_wait_seqno *args = data; -+ -+ return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, -+ &args->timeout_ns); -+} -+ -+int -+vc4_wait_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ int ret; -+ struct drm_vc4_wait_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ bo = to_vc4_bo(gem_obj); -+ -+ ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, &args->timeout_ns); -+ -+ drm_gem_object_unreference(gem_obj); -+ return ret; -+} -+ -+/** -+ * Submits a command list to the VC4. -+ * -+ * This is what is called batchbuffer emitting on other hardware. -+ */ -+int -+vc4_submit_cl_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_vc4_submit_cl *args = data; -+ struct vc4_exec_info *exec; -+ int ret; -+ -+ if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) { -+ DRM_ERROR("Unknown flags: 0x%02x\n", args->flags); -+ return -EINVAL; -+ } -+ -+ exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); -+ if (!exec) { -+ DRM_ERROR("malloc failure on exec struct\n"); -+ return -ENOMEM; -+ } -+ -+ exec->args = args; -+ INIT_LIST_HEAD(&exec->unref_list); -+ -+ mutex_lock(&dev->struct_mutex); -+ -+ ret = vc4_cl_lookup_bos(dev, file_priv, exec); -+ if (ret) -+ goto fail; -+ -+ if (exec->args->bin_cl_size != 0) { -+ ret = vc4_get_bcl(dev, exec); -+ if (ret) -+ goto fail; -+ } else { -+ exec->ct0ca = exec->ct0ea = 0; -+ } -+ -+ ret = vc4_get_rcl(dev, exec); -+ if (ret) -+ goto fail; -+ -+ /* Clear this out of the struct we'll be putting in the queue, -+ * since it's part of our stack. -+ */ -+ exec->args = NULL; -+ -+ vc4_queue_submit(dev, exec); -+ -+ /* Return the seqno for our job. */ -+ args->seqno = vc4->emit_seqno; -+ -+ mutex_unlock(&dev->struct_mutex); -+ -+ return 0; -+ -+fail: -+ vc4_complete_exec(exec); -+ -+ mutex_unlock(&dev->struct_mutex); -+ -+ return ret; -+} -+ -+void -+vc4_gem_init(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ INIT_LIST_HEAD(&vc4->job_list); -+ INIT_LIST_HEAD(&vc4->job_done_list); -+ INIT_LIST_HEAD(&vc4->seqno_cb_list); -+ spin_lock_init(&vc4->job_lock); -+ -+ INIT_WORK(&vc4->hangcheck.reset_work, vc4_reset_work); -+ setup_timer(&vc4->hangcheck.timer, -+ vc4_hangcheck_elapsed, -+ (unsigned long) dev); -+ -+ INIT_WORK(&vc4->job_done_work, vc4_job_done_work); -+} -+ -+void -+vc4_gem_destroy(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Waiting for exec to finish would need to be done before -+ * unregistering V3D. -+ */ -+ WARN_ON(vc4->emit_seqno != vc4->finished_seqno); -+ -+ /* V3D should already have disabled its interrupt and cleared -+ * the overflow allocation registers. Now free the object. -+ */ -+ if (vc4->overflow_mem) { -+ drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -+ vc4->overflow_mem = NULL; -+ } -+ -+ vc4_bo_cache_destroy(dev); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -new file mode 100644 -index 0000000..f29b796 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -0,0 +1,211 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** DOC: Interrupt management for the V3D engine. -+ * -+ * We have an interrupt status register (V3D_INTCTL) which reports -+ * interrupts, and where writing 1 bits clears those interrupts. -+ * There are also a pair of interrupt registers -+ * (V3D_INTENA/V3D_INTDIS) where writing a 1 to their bits enables or -+ * disables that specific interrupt, and 0s written are ignored -+ * (reading either one returns the set of enabled interrupts). -+ * -+ * When we take a render frame interrupt, we need to wake the -+ * processes waiting for some frame to be done, and get the next frame -+ * submitted ASAP (so the hardware doesn't sit idle when there's work -+ * to do). -+ * -+ * When we take the binner out of memory interrupt, we need to -+ * allocate some new memory and pass it to the binner so that the -+ * current job can make progress. -+ */ -+ -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+ -+#define V3D_DRIVER_IRQS (V3D_INT_OUTOMEM | \ -+ V3D_INT_FRDONE) -+ -+DECLARE_WAIT_QUEUE_HEAD(render_wait); -+ -+static void -+vc4_overflow_mem_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, overflow_mem_work); -+ struct drm_device *dev = vc4->dev; -+ struct vc4_bo *bo; -+ -+ bo = vc4_bo_create(dev, 256 * 1024); -+ if (!bo) { -+ DRM_ERROR("Couldn't allocate binner overflow mem\n"); -+ return; -+ } -+ -+ /* If there's a job executing currently, then our previous -+ * overflow allocation is getting used in that job and we need -+ * to queue it to be released when the job is done. But if no -+ * job is executing at all, then we can free the old overflow -+ * object direcctly. -+ * -+ * No lock necessary for this pointer since we're the only -+ * ones that update the pointer, and our workqueue won't -+ * reenter. -+ */ -+ if (vc4->overflow_mem) { -+ struct vc4_exec_info *current_exec; -+ unsigned long irqflags; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ current_exec = vc4_first_job(vc4); -+ if (current_exec) { -+ vc4->overflow_mem->seqno = vc4->finished_seqno + 1; -+ list_add_tail(&vc4->overflow_mem->unref_head, -+ ¤t_exec->unref_list); -+ vc4->overflow_mem = NULL; -+ } -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ } -+ -+ if (vc4->overflow_mem) { -+ drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -+ } -+ vc4->overflow_mem = bo; -+ -+ V3D_WRITE(V3D_BPOA, bo->base.paddr); -+ V3D_WRITE(V3D_BPOS, bo->base.base.size); -+ V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM); -+ V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM); -+} -+ -+static void -+vc4_irq_finish_job(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_exec_info *exec = vc4_first_job(vc4); -+ -+ if (!exec) -+ return; -+ -+ vc4->finished_seqno++; -+ list_move_tail(&exec->head, &vc4->job_done_list); -+ vc4_submit_next_job(dev); -+ -+ wake_up_all(&vc4->job_wait_queue); -+ schedule_work(&vc4->job_done_work); -+} -+ -+irqreturn_t -+vc4_irq(int irq, void *arg) -+{ -+ struct drm_device *dev = arg; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t intctl; -+ irqreturn_t status = IRQ_NONE; -+ -+ barrier(); -+ intctl = V3D_READ(V3D_INTCTL); -+ -+ /* Acknowledge the interrupts we're handling here. The render -+ * frame done interrupt will be cleared, while OUTOMEM will -+ * stay high until the underlying cause is cleared. -+ */ -+ V3D_WRITE(V3D_INTCTL, intctl); -+ -+ if (intctl & V3D_INT_OUTOMEM) { -+ /* Disable OUTOMEM until the work is done. */ -+ V3D_WRITE(V3D_INTDIS, V3D_INT_OUTOMEM); -+ schedule_work(&vc4->overflow_mem_work); -+ status = IRQ_HANDLED; -+ } -+ -+ if (intctl & V3D_INT_FRDONE) { -+ spin_lock(&vc4->job_lock); -+ vc4_irq_finish_job(dev); -+ spin_unlock(&vc4->job_lock); -+ status = IRQ_HANDLED; -+ } -+ -+ return status; -+} -+ -+void -+vc4_irq_preinstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ init_waitqueue_head(&vc4->job_wait_queue); -+ INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work); -+ -+ /* Clear any pending interrupts someone might have left around -+ * for us. -+ */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+} -+ -+int -+vc4_irq_postinstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Enable both the render done and out of memory interrupts. */ -+ V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); -+ -+ return 0; -+} -+ -+void -+vc4_irq_uninstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Disable sending interrupts for our driver's IRQs. */ -+ V3D_WRITE(V3D_INTDIS, V3D_DRIVER_IRQS); -+ -+ /* Clear any pending interrupts we might have left. */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+ -+ cancel_work_sync(&vc4->overflow_mem_work); -+} -+ -+/** Reinitializes interrupt registers when a GPU reset is performed. */ -+void vc4_irq_reset(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long irqflags; -+ -+ /* Acknowledge any stale IRQs. */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+ -+ /* -+ * Turn all our interrupts on. Binner out of memory is the -+ * only one we expect to trigger at this point, since we've -+ * just come from poweron and haven't supplied any overflow -+ * memory yet. -+ */ -+ V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ vc4_irq_finish_job(dev); -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index 2e5597d..c83287a 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -15,6 +15,7 @@ - */ - - #include "drm_crtc.h" -+#include "drm_atomic.h" - #include "drm_atomic_helper.h" - #include "drm_crtc_helper.h" - #include "drm_plane_helper.h" -@@ -29,10 +30,151 @@ static void vc4_output_poll_changed(struct drm_device *dev) - drm_fbdev_cma_hotplug_event(vc4->fbdev); - } - -+struct vc4_commit { -+ struct drm_device *dev; -+ struct drm_atomic_state *state; -+ struct vc4_seqno_cb cb; -+}; -+ -+static void -+vc4_atomic_complete_commit(struct vc4_commit *c) -+{ -+ struct drm_atomic_state *state = c->state; -+ struct drm_device *dev = state->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ drm_atomic_helper_commit_modeset_disables(dev, state); -+ -+ drm_atomic_helper_commit_planes(dev, state); -+ -+ drm_atomic_helper_commit_modeset_enables(dev, state); -+ -+ drm_atomic_helper_wait_for_vblanks(dev, state); -+ -+ drm_atomic_helper_cleanup_planes(dev, state); -+ -+ drm_atomic_state_free(state); -+ -+ up(&vc4->async_modeset); -+ -+ kfree(c); -+} -+ -+static void -+vc4_atomic_complete_commit_seqno_cb(struct vc4_seqno_cb *cb) -+{ -+ struct vc4_commit *c = container_of(cb, struct vc4_commit, cb); -+ -+ vc4_atomic_complete_commit(c); -+} -+ -+static struct vc4_commit *commit_init(struct drm_atomic_state *state) -+{ -+ struct vc4_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); -+ -+ if (!c) -+ return NULL; -+ c->dev = state->dev; -+ c->state = state; -+ -+ return c; -+} -+ -+/** -+ * vc4_atomic_commit - commit validated state object -+ * @dev: DRM device -+ * @state: the driver state object -+ * @async: asynchronous commit -+ * -+ * This function commits a with drm_atomic_helper_check() pre-validated state -+ * object. This can still fail when e.g. the framebuffer reservation fails. For -+ * now this doesn't implement asynchronous commits. -+ * -+ * RETURNS -+ * Zero for success or -errno. -+ */ -+static int vc4_atomic_commit(struct drm_device *dev, -+ struct drm_atomic_state *state, -+ bool async) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret; -+ int i; -+ uint64_t wait_seqno = 0; -+ struct vc4_commit *c; -+ -+ c = commit_init(state); -+ if (!c) -+ return -ENOMEM; -+ -+ /* Make sure that any outstanding modesets have finished. */ -+ ret = down_interruptible(&vc4->async_modeset); -+ if (ret) { -+ kfree(c); -+ return ret; -+ } -+ -+ ret = drm_atomic_helper_prepare_planes(dev, state); -+ if (ret) { -+ kfree(c); -+ up(&vc4->async_modeset); -+ return ret; -+ } -+ -+ for (i = 0; i < dev->mode_config.num_total_plane; i++) { -+ struct drm_plane *plane = state->planes[i]; -+ struct drm_plane_state *new_state = state->plane_states[i]; -+ -+ if (!plane) -+ continue; -+ -+ if ((plane->state->fb != new_state->fb) && new_state->fb) { -+ struct drm_gem_cma_object *cma_bo = -+ drm_fb_cma_get_gem_obj(new_state->fb, 0); -+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ wait_seqno = max(bo->seqno, wait_seqno); -+ } -+ } -+ -+ /* -+ * This is the point of no return - everything below never fails except -+ * when the hw goes bonghits. Which means we can commit the new state on -+ * the software side now. -+ */ -+ -+ drm_atomic_helper_swap_state(dev, state); -+ -+ /* -+ * Everything below can be run asynchronously without the need to grab -+ * any modeset locks at all under one condition: It must be guaranteed -+ * that the asynchronous work has either been cancelled (if the driver -+ * supports it, which at least requires that the framebuffers get -+ * cleaned up with drm_atomic_helper_cleanup_planes()) or completed -+ * before the new state gets committed on the software side with -+ * drm_atomic_helper_swap_state(). -+ * -+ * This scheme allows new atomic state updates to be prepared and -+ * checked in parallel to the asynchronous completion of the previous -+ * update. Which is important since compositors need to figure out the -+ * composition of the next frame right after having submitted the -+ * current layout. -+ */ -+ -+ if (async) { -+ vc4_queue_seqno_cb(dev, &c->cb, wait_seqno, -+ vc4_atomic_complete_commit_seqno_cb); -+ } else { -+ vc4_wait_for_seqno(dev, wait_seqno, ~0ull, false); -+ vc4_atomic_complete_commit(c); -+ } -+ -+ return 0; -+} -+ - static const struct drm_mode_config_funcs vc4_mode_funcs = { - .output_poll_changed = vc4_output_poll_changed, - .atomic_check = drm_atomic_helper_check, -- .atomic_commit = drm_atomic_helper_commit, -+ .atomic_commit = vc4_atomic_commit, - .fb_create = drm_fb_cma_create, - }; - -@@ -41,6 +183,8 @@ int vc4_kms_load(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret; - -+ sema_init(&vc4->async_modeset, 1); -+ - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret < 0) { - dev_err(dev->dev, "failed to initialize vblank\n"); -@@ -51,6 +195,8 @@ int vc4_kms_load(struct drm_device *dev) - dev->mode_config.max_height = 2048; - dev->mode_config.funcs = &vc4_mode_funcs; - dev->mode_config.preferred_depth = 24; -+ dev->mode_config.async_page_flip = true; -+ - dev->vblank_disable_allowed = true; - - drm_mode_config_reset(dev); -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -new file mode 100644 -index 0000000..9757bc8 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -0,0 +1,384 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef VC4_PACKET_H -+#define VC4_PACKET_H -+ -+#include "vc4_regs.h" /* for VC4_MASK, VC4_GET_FIELD, VC4_SET_FIELD */ -+ -+enum vc4_packet { -+ VC4_PACKET_HALT = 0, -+ VC4_PACKET_NOP = 1, -+ -+ VC4_PACKET_FLUSH = 4, -+ VC4_PACKET_FLUSH_ALL = 5, -+ VC4_PACKET_START_TILE_BINNING = 6, -+ VC4_PACKET_INCREMENT_SEMAPHORE = 7, -+ VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -+ -+ VC4_PACKET_BRANCH = 16, -+ VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -+ -+ VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -+ VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -+ VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -+ VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -+ VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -+ -+ VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -+ VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -+ -+ VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -+ VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -+ -+ VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -+ -+ VC4_PACKET_GL_SHADER_STATE = 64, -+ VC4_PACKET_NV_SHADER_STATE = 65, -+ VC4_PACKET_VG_SHADER_STATE = 66, -+ -+ VC4_PACKET_CONFIGURATION_BITS = 96, -+ VC4_PACKET_FLAT_SHADE_FLAGS = 97, -+ VC4_PACKET_POINT_SIZE = 98, -+ VC4_PACKET_LINE_WIDTH = 99, -+ VC4_PACKET_RHT_X_BOUNDARY = 100, -+ VC4_PACKET_DEPTH_OFFSET = 101, -+ VC4_PACKET_CLIP_WINDOW = 102, -+ VC4_PACKET_VIEWPORT_OFFSET = 103, -+ VC4_PACKET_Z_CLIPPING = 104, -+ VC4_PACKET_CLIPPER_XY_SCALING = 105, -+ VC4_PACKET_CLIPPER_Z_SCALING = 106, -+ -+ VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -+ VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -+ VC4_PACKET_CLEAR_COLORS = 114, -+ VC4_PACKET_TILE_COORDINATES = 115, -+ -+ /* Not an actual hardware packet -- this is what we use to put -+ * references to GEM bos in the command stream, since we need the u32 -+ * int the actual address packet in order to store the offset from the -+ * start of the BO. -+ */ -+ VC4_PACKET_GEM_HANDLES = 254, -+} __attribute__ ((__packed__)); -+ -+#define VC4_PACKET_HALT_SIZE 1 -+#define VC4_PACKET_NOP_SIZE 1 -+#define VC4_PACKET_FLUSH_SIZE 1 -+#define VC4_PACKET_FLUSH_ALL_SIZE 1 -+#define VC4_PACKET_START_TILE_BINNING_SIZE 1 -+#define VC4_PACKET_INCREMENT_SEMAPHORE_SIZE 1 -+#define VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE 1 -+#define VC4_PACKET_BRANCH_SIZE 5 -+#define VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE 5 -+#define VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE 1 -+#define VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF_SIZE 1 -+#define VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE 5 -+#define VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE 5 -+#define VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE 7 -+#define VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE 7 -+#define VC4_PACKET_GL_INDEXED_PRIMITIVE_SIZE 14 -+#define VC4_PACKET_GL_ARRAY_PRIMITIVE_SIZE 10 -+#define VC4_PACKET_COMPRESSED_PRIMITIVE_SIZE 1 -+#define VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE_SIZE 1 -+#define VC4_PACKET_PRIMITIVE_LIST_FORMAT_SIZE 2 -+#define VC4_PACKET_GL_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_NV_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_VG_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_CONFIGURATION_BITS_SIZE 4 -+#define VC4_PACKET_FLAT_SHADE_FLAGS_SIZE 5 -+#define VC4_PACKET_POINT_SIZE_SIZE 5 -+#define VC4_PACKET_LINE_WIDTH_SIZE 5 -+#define VC4_PACKET_RHT_X_BOUNDARY_SIZE 3 -+#define VC4_PACKET_DEPTH_OFFSET_SIZE 5 -+#define VC4_PACKET_CLIP_WINDOW_SIZE 9 -+#define VC4_PACKET_VIEWPORT_OFFSET_SIZE 5 -+#define VC4_PACKET_Z_CLIPPING_SIZE 9 -+#define VC4_PACKET_CLIPPER_XY_SCALING_SIZE 9 -+#define VC4_PACKET_CLIPPER_Z_SCALING_SIZE 9 -+#define VC4_PACKET_TILE_BINNING_MODE_CONFIG_SIZE 16 -+#define VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE 11 -+#define VC4_PACKET_CLEAR_COLORS_SIZE 14 -+#define VC4_PACKET_TILE_COORDINATES_SIZE 3 -+#define VC4_PACKET_GEM_HANDLES_SIZE 9 -+ -+/** @{ -+ * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_TILE_RENDERING_MODE_CONFIG. -+*/ -+#define VC4_TILING_FORMAT_LINEAR 0 -+#define VC4_TILING_FORMAT_T 1 -+#define VC4_TILING_FORMAT_LT 2 -+/** @} */ -+ -+/** @{ -+ * -+ * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and -+ * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. -+ */ -+#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0) -+ -+/** @{ -+ * -+ * byte 2 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address) -+ */ -+ -+#define VC4_LOADSTORE_TILE_BUFFER_EOF (1 << 3) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS (1 << 1) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR (1 << 0) -+ -+/** @} */ -+ -+/** @{ -+ * -+ * byte 0-1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL -+ */ -+#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 15) -+#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR (1 << 14) -+#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR (1 << 13) -+#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP (1 << 12) -+ -+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK VC4_MASK(9, 8) -+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT 8 -+#define VC4_LOADSTORE_TILE_BUFFER_RGBA8888 0 -+#define VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER 1 -+#define VC4_LOADSTORE_TILE_BUFFER_BGR565 2 -+/** @} */ -+ -+/** @{ -+ * -+ * byte 0 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL -+ */ -+#define VC4_STORE_TILE_BUFFER_MODE_MASK VC4_MASK(7, 6) -+#define VC4_STORE_TILE_BUFFER_MODE_SHIFT 6 -+#define VC4_STORE_TILE_BUFFER_MODE_SAMPLE0 (0 << 6) -+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X4 (1 << 6) -+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X16 (2 << 6) -+ -+/** The values of the field are VC4_TILING_FORMAT_* */ -+#define VC4_LOADSTORE_TILE_BUFFER_TILING_MASK VC4_MASK(5, 4) -+#define VC4_LOADSTORE_TILE_BUFFER_TILING_SHIFT 4 -+ -+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK VC4_MASK(2, 0) -+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_SHIFT 0 -+#define VC4_LOADSTORE_TILE_BUFFER_NONE 0 -+#define VC4_LOADSTORE_TILE_BUFFER_COLOR 1 -+#define VC4_LOADSTORE_TILE_BUFFER_ZS 2 -+#define VC4_LOADSTORE_TILE_BUFFER_Z 3 -+#define VC4_LOADSTORE_TILE_BUFFER_VG_MASK 4 -+#define VC4_LOADSTORE_TILE_BUFFER_FULL 5 -+/** @} */ -+ -+#define VC4_INDEX_BUFFER_U8 (0 << 4) -+#define VC4_INDEX_BUFFER_U16 (1 << 4) -+ -+/* This flag is only present in NV shader state. */ -+#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS (1 << 3) -+#define VC4_SHADER_FLAG_ENABLE_CLIPPING (1 << 2) -+#define VC4_SHADER_FLAG_VS_POINT_SIZE (1 << 1) -+#define VC4_SHADER_FLAG_FS_SINGLE_THREAD (1 << 0) -+ -+/** @{ byte 2 of config bits. */ -+#define VC4_CONFIG_BITS_EARLY_Z_UPDATE (1 << 1) -+#define VC4_CONFIG_BITS_EARLY_Z (1 << 0) -+/** @} */ -+ -+/** @{ byte 1 of config bits. */ -+#define VC4_CONFIG_BITS_Z_UPDATE (1 << 7) -+/** same values in this 3-bit field as PIPE_FUNC_* */ -+#define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT 4 -+#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE (1 << 3) -+ -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO (0 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD (1 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR (2 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO (3 << 1) -+ -+#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT (1 << 0) -+/** @} */ -+ -+/** @{ byte 0 of config bits. */ -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_NONE (0 << 6) -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X (1 << 6) -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X (2 << 6) -+ -+#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES (1 << 4) -+#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET (1 << 3) -+#define VC4_CONFIG_BITS_CW_PRIMITIVES (1 << 2) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK (1 << 1) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT (1 << 0) -+/** @} */ -+ -+/** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */ -+#define VC4_BIN_CONFIG_DB_NON_MS (1 << 7) -+ -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK VC4_MASK(6, 5) -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_SHIFT 5 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32 0 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_64 1 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128 2 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_256 3 -+ -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK VC4_MASK(4, 3) -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_SHIFT 3 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32 0 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_64 1 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128 2 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256 3 -+ -+#define VC4_BIN_CONFIG_AUTO_INIT_TSDA (1 << 2) -+#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT (1 << 1) -+#define VC4_BIN_CONFIG_MS_MODE_4X (1 << 0) -+/** @} */ -+ -+/** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */ -+#define VC4_RENDER_CONFIG_DB_NON_MS (1 << 12) -+#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11) -+#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G (1 << 10) -+#define VC4_RENDER_CONFIG_COVERAGE_MODE (1 << 9) -+#define VC4_RENDER_CONFIG_ENABLE_VG_MASK (1 << 8) -+ -+/** The values of the field are VC4_TILING_FORMAT_* */ -+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK VC4_MASK(7, 6) -+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT 6 -+ -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_1X (0 << 4) -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_4X (1 << 4) -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_16X (2 << 4) -+ -+#define VC4_RENDER_CONFIG_FORMAT_MASK VC4_MASK(3, 2) -+#define VC4_RENDER_CONFIG_FORMAT_SHIFT 2 -+#define VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED 0 -+#define VC4_RENDER_CONFIG_FORMAT_RGBA8888 1 -+#define VC4_RENDER_CONFIG_FORMAT_BGR565 2 -+ -+#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT (1 << 1) -+#define VC4_RENDER_CONFIG_MS_MODE_4X (1 << 0) -+ -+#define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX (1 << 4) -+#define VC4_PRIMITIVE_LIST_FORMAT_32_XY (3 << 4) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_POINTS (0 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_LINES (1 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_TRIANGLES (2 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT (3 << 0) -+ -+enum vc4_texture_data_type { -+ VC4_TEXTURE_TYPE_RGBA8888 = 0, -+ VC4_TEXTURE_TYPE_RGBX8888 = 1, -+ VC4_TEXTURE_TYPE_RGBA4444 = 2, -+ VC4_TEXTURE_TYPE_RGBA5551 = 3, -+ VC4_TEXTURE_TYPE_RGB565 = 4, -+ VC4_TEXTURE_TYPE_LUMINANCE = 5, -+ VC4_TEXTURE_TYPE_ALPHA = 6, -+ VC4_TEXTURE_TYPE_LUMALPHA = 7, -+ VC4_TEXTURE_TYPE_ETC1 = 8, -+ VC4_TEXTURE_TYPE_S16F = 9, -+ VC4_TEXTURE_TYPE_S8 = 10, -+ VC4_TEXTURE_TYPE_S16 = 11, -+ VC4_TEXTURE_TYPE_BW1 = 12, -+ VC4_TEXTURE_TYPE_A4 = 13, -+ VC4_TEXTURE_TYPE_A1 = 14, -+ VC4_TEXTURE_TYPE_RGBA64 = 15, -+ VC4_TEXTURE_TYPE_RGBA32R = 16, -+ VC4_TEXTURE_TYPE_YUV422R = 17, -+}; -+ -+#define VC4_TEX_P0_OFFSET_MASK VC4_MASK(31, 12) -+#define VC4_TEX_P0_OFFSET_SHIFT 12 -+#define VC4_TEX_P0_CSWIZ_MASK VC4_MASK(11, 10) -+#define VC4_TEX_P0_CSWIZ_SHIFT 10 -+#define VC4_TEX_P0_CMMODE_MASK VC4_MASK(9, 9) -+#define VC4_TEX_P0_CMMODE_SHIFT 9 -+#define VC4_TEX_P0_FLIPY_MASK VC4_MASK(8, 8) -+#define VC4_TEX_P0_FLIPY_SHIFT 8 -+#define VC4_TEX_P0_TYPE_MASK VC4_MASK(7, 4) -+#define VC4_TEX_P0_TYPE_SHIFT 4 -+#define VC4_TEX_P0_MIPLVLS_MASK VC4_MASK(3, 0) -+#define VC4_TEX_P0_MIPLVLS_SHIFT 0 -+ -+#define VC4_TEX_P1_TYPE4_MASK VC4_MASK(31, 31) -+#define VC4_TEX_P1_TYPE4_SHIFT 31 -+#define VC4_TEX_P1_HEIGHT_MASK VC4_MASK(30, 20) -+#define VC4_TEX_P1_HEIGHT_SHIFT 20 -+#define VC4_TEX_P1_ETCFLIP_MASK VC4_MASK(19, 19) -+#define VC4_TEX_P1_ETCFLIP_SHIFT 19 -+#define VC4_TEX_P1_WIDTH_MASK VC4_MASK(18, 8) -+#define VC4_TEX_P1_WIDTH_SHIFT 8 -+ -+#define VC4_TEX_P1_MAGFILT_MASK VC4_MASK(7, 7) -+#define VC4_TEX_P1_MAGFILT_SHIFT 7 -+# define VC4_TEX_P1_MAGFILT_LINEAR 0 -+# define VC4_TEX_P1_MAGFILT_NEAREST 1 -+ -+#define VC4_TEX_P1_MINFILT_MASK VC4_MASK(6, 4) -+#define VC4_TEX_P1_MINFILT_SHIFT 4 -+# define VC4_TEX_P1_MINFILT_LINEAR 0 -+# define VC4_TEX_P1_MINFILT_NEAREST 1 -+# define VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR 2 -+# define VC4_TEX_P1_MINFILT_NEAR_MIP_LIN 3 -+# define VC4_TEX_P1_MINFILT_LIN_MIP_NEAR 4 -+# define VC4_TEX_P1_MINFILT_LIN_MIP_LIN 5 -+ -+#define VC4_TEX_P1_WRAP_T_MASK VC4_MASK(3, 2) -+#define VC4_TEX_P1_WRAP_T_SHIFT 2 -+#define VC4_TEX_P1_WRAP_S_MASK VC4_MASK(1, 0) -+#define VC4_TEX_P1_WRAP_S_SHIFT 0 -+# define VC4_TEX_P1_WRAP_REPEAT 0 -+# define VC4_TEX_P1_WRAP_CLAMP 1 -+# define VC4_TEX_P1_WRAP_MIRROR 2 -+# define VC4_TEX_P1_WRAP_BORDER 3 -+ -+#define VC4_TEX_P2_PTYPE_MASK VC4_MASK(31, 30) -+#define VC4_TEX_P2_PTYPE_SHIFT 30 -+# define VC4_TEX_P2_PTYPE_IGNORED 0 -+# define VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE 1 -+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS 2 -+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS 3 -+ -+/* VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE bits */ -+#define VC4_TEX_P2_CMST_MASK VC4_MASK(29, 12) -+#define VC4_TEX_P2_CMST_SHIFT 12 -+#define VC4_TEX_P2_BSLOD_MASK VC4_MASK(0, 0) -+#define VC4_TEX_P2_BSLOD_SHIFT 0 -+ -+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS */ -+#define VC4_TEX_P2_CHEIGHT_MASK VC4_MASK(22, 12) -+#define VC4_TEX_P2_CHEIGHT_SHIFT 12 -+#define VC4_TEX_P2_CWIDTH_MASK VC4_MASK(10, 0) -+#define VC4_TEX_P2_CWIDTH_SHIFT 0 -+ -+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS */ -+#define VC4_TEX_P2_CYOFF_MASK VC4_MASK(22, 12) -+#define VC4_TEX_P2_CYOFF_SHIFT 12 -+#define VC4_TEX_P2_CXOFF_MASK VC4_MASK(10, 0) -+#define VC4_TEX_P2_CXOFF_SHIFT 0 -+ -+#endif /* VC4_PACKET_H */ -diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c -index 887f3ca..65e5455 100644 ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -29,6 +29,14 @@ struct vc4_plane_state { - u32 *dlist; - u32 dlist_size; /* Number of dwords in allocated for the display list */ - u32 dlist_count; /* Number of used dwords in the display list. */ -+ -+ /* Offset in the dlist to pointer word 0. */ -+ u32 pw0_offset; -+ -+ /* Offset where the plane's dlist was last stored in the -+ hardware at vc4_crtc_atomic_flush() time. -+ */ -+ u32 *hw_dlist; - }; - - static inline struct vc4_plane_state * -@@ -207,6 +215,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, - /* Position Word 3: Context. Written by the HVS. */ - vc4_dlist_write(vc4_state, 0xc0c0c0c0); - -+ vc4_state->pw0_offset = vc4_state->dlist_count; -+ - /* Pointer Word 0: RGB / Y Pointer */ - vc4_dlist_write(vc4_state, bo->paddr + offset); - -@@ -258,6 +268,8 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) - struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); - int i; - -+ vc4_state->hw_dlist = dlist; -+ - /* Can't memcpy_toio() because it needs to be 32-bit writes. */ - for (i = 0; i < vc4_state->dlist_count; i++) - writel(vc4_state->dlist[i], &dlist[i]); -@@ -272,6 +284,34 @@ u32 vc4_plane_dlist_size(struct drm_plane_state *state) - return vc4_state->dlist_count; - } - -+/* Updates the plane to immediately (well, once the FIFO needs -+ * refilling) scan out from at a new framebuffer. -+ */ -+void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) -+{ -+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); -+ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -+ uint32_t addr; -+ -+ /* We're skipping the address adjustment for negative origin, -+ * because this is only called on the primary plane. -+ */ -+ WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); -+ addr = bo->paddr + fb->offsets[0]; -+ -+ /* Write the new address into the hardware immediately. The -+ * scanout will start from this address as soon as the FIFO -+ * needs to refill with pixels. -+ */ -+ writel(addr, &vc4_state->hw_dlist[vc4_state->pw0_offset]); -+ -+ /* Also update the CPU-side dlist copy, so that any later -+ * atomic updates that don't do a new modeset on our plane -+ * also use our updated address. -+ */ -+ vc4_state->dlist[vc4_state->pw0_offset] = addr; -+} -+ - static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { - .prepare_fb = NULL, - .cleanup_fb = NULL, -diff --git a/drivers/gpu/drm/vc4/vc4_qpu_defines.h b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -new file mode 100644 -index 0000000..e47c994 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -@@ -0,0 +1,268 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef VC4_QPU_DEFINES_H -+#define VC4_QPU_DEFINES_H -+ -+enum qpu_op_add { -+ QPU_A_NOP, -+ QPU_A_FADD, -+ QPU_A_FSUB, -+ QPU_A_FMIN, -+ QPU_A_FMAX, -+ QPU_A_FMINABS, -+ QPU_A_FMAXABS, -+ QPU_A_FTOI, -+ QPU_A_ITOF, -+ QPU_A_ADD = 12, -+ QPU_A_SUB, -+ QPU_A_SHR, -+ QPU_A_ASR, -+ QPU_A_ROR, -+ QPU_A_SHL, -+ QPU_A_MIN, -+ QPU_A_MAX, -+ QPU_A_AND, -+ QPU_A_OR, -+ QPU_A_XOR, -+ QPU_A_NOT, -+ QPU_A_CLZ, -+ QPU_A_V8ADDS = 30, -+ QPU_A_V8SUBS = 31, -+}; -+ -+enum qpu_op_mul { -+ QPU_M_NOP, -+ QPU_M_FMUL, -+ QPU_M_MUL24, -+ QPU_M_V8MULD, -+ QPU_M_V8MIN, -+ QPU_M_V8MAX, -+ QPU_M_V8ADDS, -+ QPU_M_V8SUBS, -+}; -+ -+enum qpu_raddr { -+ QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_R_UNIF = 32, -+ QPU_R_VARY = 35, -+ QPU_R_ELEM_QPU = 38, -+ QPU_R_NOP, -+ QPU_R_XY_PIXEL_COORD = 41, -+ QPU_R_MS_REV_FLAGS = 41, -+ QPU_R_VPM = 48, -+ QPU_R_VPM_LD_BUSY, -+ QPU_R_VPM_LD_WAIT, -+ QPU_R_MUTEX_ACQUIRE, -+}; -+ -+enum qpu_waddr { -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_W_ACC0 = 32, /* aka r0 */ -+ QPU_W_ACC1, -+ QPU_W_ACC2, -+ QPU_W_ACC3, -+ QPU_W_TMU_NOSWAP, -+ QPU_W_ACC5, -+ QPU_W_HOST_INT, -+ QPU_W_NOP, -+ QPU_W_UNIFORMS_ADDRESS, -+ QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -+ QPU_W_MS_FLAGS = 42, -+ QPU_W_REV_FLAG = 42, -+ QPU_W_TLB_STENCIL_SETUP = 43, -+ QPU_W_TLB_Z, -+ QPU_W_TLB_COLOR_MS, -+ QPU_W_TLB_COLOR_ALL, -+ QPU_W_TLB_ALPHA_MASK, -+ QPU_W_VPM, -+ QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -+ QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -+ QPU_W_MUTEX_RELEASE, -+ QPU_W_SFU_RECIP, -+ QPU_W_SFU_RECIPSQRT, -+ QPU_W_SFU_EXP, -+ QPU_W_SFU_LOG, -+ QPU_W_TMU0_S, -+ QPU_W_TMU0_T, -+ QPU_W_TMU0_R, -+ QPU_W_TMU0_B, -+ QPU_W_TMU1_S, -+ QPU_W_TMU1_T, -+ QPU_W_TMU1_R, -+ QPU_W_TMU1_B, -+}; -+ -+enum qpu_sig_bits { -+ QPU_SIG_SW_BREAKPOINT, -+ QPU_SIG_NONE, -+ QPU_SIG_THREAD_SWITCH, -+ QPU_SIG_PROG_END, -+ QPU_SIG_WAIT_FOR_SCOREBOARD, -+ QPU_SIG_SCOREBOARD_UNLOCK, -+ QPU_SIG_LAST_THREAD_SWITCH, -+ QPU_SIG_COVERAGE_LOAD, -+ QPU_SIG_COLOR_LOAD, -+ QPU_SIG_COLOR_LOAD_END, -+ QPU_SIG_LOAD_TMU0, -+ QPU_SIG_LOAD_TMU1, -+ QPU_SIG_ALPHA_MASK_LOAD, -+ QPU_SIG_SMALL_IMM, -+ QPU_SIG_LOAD_IMM, -+ QPU_SIG_BRANCH -+}; -+ -+enum qpu_mux { -+ /* hardware mux values */ -+ QPU_MUX_R0, -+ QPU_MUX_R1, -+ QPU_MUX_R2, -+ QPU_MUX_R3, -+ QPU_MUX_R4, -+ QPU_MUX_R5, -+ QPU_MUX_A, -+ QPU_MUX_B, -+ -+ /* non-hardware mux values */ -+ QPU_MUX_IMM, -+}; -+ -+enum qpu_cond { -+ QPU_COND_NEVER, -+ QPU_COND_ALWAYS, -+ QPU_COND_ZS, -+ QPU_COND_ZC, -+ QPU_COND_NS, -+ QPU_COND_NC, -+ QPU_COND_CS, -+ QPU_COND_CC, -+}; -+ -+enum qpu_pack_mul { -+ QPU_PACK_MUL_NOP, -+ QPU_PACK_MUL_8888 = 3, /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_MUL_8A, -+ QPU_PACK_MUL_8B, -+ QPU_PACK_MUL_8C, -+ QPU_PACK_MUL_8D, -+}; -+ -+enum qpu_pack_a { -+ QPU_PACK_A_NOP, -+ /* convert to 16 bit float if float input, or to int16. */ -+ QPU_PACK_A_16A, -+ QPU_PACK_A_16B, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_A_8888, -+ /* Convert to 8-bit unsigned int. */ -+ QPU_PACK_A_8A, -+ QPU_PACK_A_8B, -+ QPU_PACK_A_8C, -+ QPU_PACK_A_8D, -+ -+ /* Saturating variants of the previous instructions. */ -+ QPU_PACK_A_32_SAT, /* int-only */ -+ QPU_PACK_A_16A_SAT, /* int or float */ -+ QPU_PACK_A_16B_SAT, -+ QPU_PACK_A_8888_SAT, -+ QPU_PACK_A_8A_SAT, -+ QPU_PACK_A_8B_SAT, -+ QPU_PACK_A_8C_SAT, -+ QPU_PACK_A_8D_SAT, -+}; -+ -+enum qpu_unpack_r4 { -+ QPU_UNPACK_R4_NOP, -+ QPU_UNPACK_R4_F16A_TO_F32, -+ QPU_UNPACK_R4_F16B_TO_F32, -+ QPU_UNPACK_R4_8D_REP, -+ QPU_UNPACK_R4_8A, -+ QPU_UNPACK_R4_8B, -+ QPU_UNPACK_R4_8C, -+ QPU_UNPACK_R4_8D, -+}; -+ -+#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low)) -+/* Using the GNU statement expression extension */ -+#define QPU_SET_FIELD(value, field) \ -+ ({ \ -+ uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \ -+ assert((fieldval & ~ field ## _MASK) == 0); \ -+ fieldval & field ## _MASK; \ -+ }) -+ -+#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) -+ -+#define QPU_SIG_SHIFT 60 -+#define QPU_SIG_MASK QPU_MASK(63, 60) -+ -+#define QPU_UNPACK_SHIFT 57 -+#define QPU_UNPACK_MASK QPU_MASK(59, 57) -+ -+/** -+ * If set, the pack field means PACK_MUL or R4 packing, instead of normal -+ * regfile a packing. -+ */ -+#define QPU_PM ((uint64_t)1 << 56) -+ -+#define QPU_PACK_SHIFT 52 -+#define QPU_PACK_MASK QPU_MASK(55, 52) -+ -+#define QPU_COND_ADD_SHIFT 49 -+#define QPU_COND_ADD_MASK QPU_MASK(51, 49) -+#define QPU_COND_MUL_SHIFT 46 -+#define QPU_COND_MUL_MASK QPU_MASK(48, 46) -+ -+#define QPU_SF ((uint64_t)1 << 45) -+ -+#define QPU_WADDR_ADD_SHIFT 38 -+#define QPU_WADDR_ADD_MASK QPU_MASK(43, 38) -+#define QPU_WADDR_MUL_SHIFT 32 -+#define QPU_WADDR_MUL_MASK QPU_MASK(37, 32) -+ -+#define QPU_OP_MUL_SHIFT 29 -+#define QPU_OP_MUL_MASK QPU_MASK(31, 29) -+ -+#define QPU_RADDR_A_SHIFT 18 -+#define QPU_RADDR_A_MASK QPU_MASK(23, 18) -+#define QPU_RADDR_B_SHIFT 12 -+#define QPU_RADDR_B_MASK QPU_MASK(17, 12) -+#define QPU_SMALL_IMM_SHIFT 12 -+#define QPU_SMALL_IMM_MASK QPU_MASK(17, 12) -+ -+#define QPU_ADD_A_SHIFT 9 -+#define QPU_ADD_A_MASK QPU_MASK(11, 9) -+#define QPU_ADD_B_SHIFT 6 -+#define QPU_ADD_B_MASK QPU_MASK(8, 6) -+#define QPU_MUL_A_SHIFT 3 -+#define QPU_MUL_A_MASK QPU_MASK(5, 3) -+#define QPU_MUL_B_SHIFT 0 -+#define QPU_MUL_B_MASK QPU_MASK(2, 0) -+ -+#define QPU_WS ((uint64_t)1 << 44) -+ -+#define QPU_OP_ADD_SHIFT 24 -+#define QPU_OP_ADD_MASK QPU_MASK(28, 24) -+ -+#endif /* VC4_QPU_DEFINES_H */ -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -new file mode 100644 -index 0000000..0ffac8d ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -0,0 +1,448 @@ -+/* -+ * Copyright © 2014-2015 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * DOC: Render command list generation -+ * -+ * In the VC4 driver, render command list generation is performed by the -+ * kernel instead of userspace. We do this because validating a -+ * user-submitted command list is hard to get right and has high CPU overhead, -+ * while the number of valid configurations for render command lists is -+ * actually fairly low. -+ */ -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_packet.h" -+ -+struct vc4_rcl_setup { -+ struct drm_gem_cma_object *color_read; -+ struct drm_gem_cma_object *color_ms_write; -+ struct drm_gem_cma_object *zs_read; -+ struct drm_gem_cma_object *zs_write; -+ -+ struct drm_gem_cma_object *rcl; -+ u32 next_offset; -+}; -+ -+static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) -+{ -+ *(u8 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 1; -+} -+ -+static inline void rcl_u16(struct vc4_rcl_setup *setup, u16 val) -+{ -+ *(u16 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 2; -+} -+ -+static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val) -+{ -+ *(u32 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 4; -+} -+ -+ -+/* -+ * Emits a no-op STORE_TILE_BUFFER_GENERAL. -+ * -+ * If we emit a PACKET_TILE_COORDINATES, it must be followed by a store of -+ * some sort before another load is triggered. -+ */ -+static void vc4_store_before_load(struct vc4_rcl_setup *setup) -+{ -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, -+ VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_NONE, -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER) | -+ VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR | -+ VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR | -+ VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR); -+ rcl_u32(setup, 0); /* no address, since we're in None mode */ -+} -+ -+/* -+ * Emits a PACKET_TILE_COORDINATES if one isn't already pending. -+ * -+ * The tile coordinates packet triggers a pending load if there is one, are -+ * used for clipping during rendering, and determine where loads/stores happen -+ * relative to their base address. -+ */ -+static void vc4_tile_coordinates(struct vc4_rcl_setup *setup, -+ uint32_t x, uint32_t y) -+{ -+ rcl_u8(setup, VC4_PACKET_TILE_COORDINATES); -+ rcl_u8(setup, x); -+ rcl_u8(setup, y); -+} -+ -+static void emit_tile(struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup, -+ uint8_t x, uint8_t y, bool first, bool last) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ -+ /* Note that the load doesn't actually occur until the -+ * tile coords packet is processed, and only one load -+ * may be outstanding at a time. -+ */ -+ if (setup->color_read) { -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->color_read.bits); -+ rcl_u32(setup, -+ setup->color_read->paddr + args->color_read.offset); -+ } -+ -+ if (setup->zs_read) { -+ if (setup->color_read) { -+ /* Exec previous load. */ -+ vc4_tile_coordinates(setup, x, y); -+ vc4_store_before_load(setup); -+ } -+ -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_read.bits); -+ rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset); -+ } -+ -+ /* Clipping depends on tile coordinates having been -+ * emitted, so we always need one here. -+ */ -+ vc4_tile_coordinates(setup, x, y); -+ -+ /* Wait for the binner before jumping to the first -+ * tile's lists. -+ */ -+ if (first && has_bin) -+ rcl_u8(setup, VC4_PACKET_WAIT_ON_SEMAPHORE); -+ -+ if (has_bin) { -+ rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST); -+ rcl_u32(setup, (exec->tile_bo->paddr + -+ exec->tile_alloc_offset + -+ (y * exec->bin_tiles_x + x) * 32)); -+ } -+ -+ if (setup->zs_write) { -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_write.bits | -+ (setup->color_ms_write ? -+ VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0)); -+ rcl_u32(setup, -+ (setup->zs_write->paddr + args->zs_write.offset) | -+ ((last && !setup->color_ms_write) ? -+ VC4_LOADSTORE_TILE_BUFFER_EOF : 0)); -+ } -+ -+ if (setup->color_ms_write) { -+ if (setup->zs_write) { -+ /* Reset after previous store */ -+ vc4_tile_coordinates(setup, x, y); -+ } -+ -+ if (last) -+ rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF); -+ else -+ rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER); -+ } -+} -+ -+static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ uint8_t min_x_tile = args->min_x_tile; -+ uint8_t min_y_tile = args->min_y_tile; -+ uint8_t max_x_tile = args->max_x_tile; -+ uint8_t max_y_tile = args->max_y_tile; -+ uint8_t xtiles = max_x_tile - min_x_tile + 1; -+ uint8_t ytiles = max_y_tile - min_y_tile + 1; -+ uint8_t x, y; -+ uint32_t size, loop_body_size; -+ -+ size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE; -+ loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE; -+ -+ if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) { -+ size += VC4_PACKET_CLEAR_COLORS_SIZE + -+ VC4_PACKET_TILE_COORDINATES_SIZE + -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ -+ if (setup->color_read) { -+ loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE); -+ } -+ if (setup->zs_read) { -+ if (setup->color_read) { -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; -+ } -+ -+ if (has_bin) { -+ size += VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE; -+ loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE; -+ } -+ -+ if (setup->zs_write) -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ if (setup->color_ms_write) { -+ if (setup->zs_write) -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE; -+ } -+ size += xtiles * ytiles * loop_body_size; -+ -+ setup->rcl = &vc4_bo_create(dev, size)->base; -+ if (!setup->rcl) -+ return -ENOMEM; -+ list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, -+ &exec->unref_list); -+ -+ rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -+ rcl_u32(setup, -+ (setup->color_ms_write ? -+ (setup->color_ms_write->paddr + -+ args->color_ms_write.offset) : -+ 0)); -+ rcl_u16(setup, args->width); -+ rcl_u16(setup, args->height); -+ rcl_u16(setup, args->color_ms_write.bits); -+ -+ /* The tile buffer gets cleared when the previous tile is stored. If -+ * the clear values changed between frames, then the tile buffer has -+ * stale clear values in it, so we have to do a store in None mode (no -+ * writes) so that we trigger the tile buffer clear. -+ */ -+ if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) { -+ rcl_u8(setup, VC4_PACKET_CLEAR_COLORS); -+ rcl_u32(setup, args->clear_color[0]); -+ rcl_u32(setup, args->clear_color[1]); -+ rcl_u32(setup, args->clear_z); -+ rcl_u8(setup, args->clear_s); -+ -+ vc4_tile_coordinates(setup, 0, 0); -+ -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, VC4_LOADSTORE_TILE_BUFFER_NONE); -+ rcl_u32(setup, 0); /* no address, since we're in None mode */ -+ } -+ -+ for (y = min_y_tile; y <= max_y_tile; y++) { -+ for (x = min_x_tile; x <= max_x_tile; x++) { -+ bool first = (x == min_x_tile && y == min_y_tile); -+ bool last = (x == max_x_tile && y == max_y_tile); -+ emit_tile(exec, setup, x, y, first, last); -+ } -+ } -+ -+ BUG_ON(setup->next_offset != size); -+ exec->ct1ca = setup->rcl->paddr; -+ exec->ct1ea = setup->rcl->paddr + setup->next_offset; -+ -+ return 0; -+} -+ -+static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ uint8_t tiling = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_TILING); -+ uint8_t buffer = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER); -+ uint8_t format = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_FORMAT); -+ int cpp; -+ -+ if (surf->pad != 0) { -+ DRM_ERROR("Padding unset\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ return -EINVAL; -+ -+ if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK | -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK | -+ VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) { -+ DRM_ERROR("Unknown bits in load/store: 0x%04x\n", -+ surf->bits); -+ return -EINVAL; -+ } -+ -+ if (tiling > VC4_TILING_FORMAT_LT) { -+ DRM_ERROR("Bad tiling format\n"); -+ return -EINVAL; -+ } -+ -+ if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) { -+ if (format != 0) { -+ DRM_ERROR("No color format should be set for ZS\n"); -+ return -EINVAL; -+ } -+ cpp = 4; -+ } else if (buffer == VC4_LOADSTORE_TILE_BUFFER_COLOR) { -+ switch (format) { -+ case VC4_LOADSTORE_TILE_BUFFER_BGR565: -+ case VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER: -+ cpp = 2; -+ break; -+ case VC4_LOADSTORE_TILE_BUFFER_RGBA8888: -+ cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Bad tile buffer format\n"); -+ return -EINVAL; -+ } -+ } else { -+ DRM_ERROR("Bad load/store buffer %d.\n", buffer); -+ return -EINVAL; -+ } -+ -+ if (surf->offset & 0xf) { -+ DRM_ERROR("load/store buffer must be 16b aligned.\n"); -+ return -EINVAL; -+ } -+ -+ if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling, -+ exec->args->width, exec->args->height, cpp)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ uint8_t tiling = VC4_GET_FIELD(surf->bits, -+ VC4_RENDER_CONFIG_MEMORY_FORMAT); -+ uint8_t format = VC4_GET_FIELD(surf->bits, -+ VC4_RENDER_CONFIG_FORMAT); -+ int cpp; -+ -+ if (surf->pad != 0) { -+ DRM_ERROR("Padding unset\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK | -+ VC4_RENDER_CONFIG_FORMAT_MASK)) { -+ DRM_ERROR("Unknown bits in render config: 0x%04x\n", -+ surf->bits); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ return -EINVAL; -+ -+ if (tiling > VC4_TILING_FORMAT_LT) { -+ DRM_ERROR("Bad tiling format\n"); -+ return -EINVAL; -+ } -+ -+ switch (format) { -+ case VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED: -+ case VC4_RENDER_CONFIG_FORMAT_BGR565: -+ cpp = 2; -+ break; -+ case VC4_RENDER_CONFIG_FORMAT_RGBA8888: -+ cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Bad tile buffer format\n"); -+ return -EINVAL; -+ } -+ -+ if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling, -+ exec->args->width, exec->args->height, cpp)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct vc4_rcl_setup setup = {0}; -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ int ret; -+ -+ if (args->min_x_tile > args->max_x_tile || -+ args->min_y_tile > args->max_y_tile) { -+ DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n", -+ args->min_x_tile, args->min_y_tile, -+ args->max_x_tile, args->max_y_tile); -+ return -EINVAL; -+ } -+ -+ if (has_bin && -+ (args->max_x_tile > exec->bin_tiles_x || -+ args->max_y_tile > exec->bin_tiles_y)) { -+ DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n", -+ args->max_x_tile, args->max_y_tile, -+ exec->bin_tiles_x, exec->bin_tiles_y); -+ return -EINVAL; -+ } -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write, -+ &args->color_ms_write); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); -+ if (ret) -+ return ret; -+ -+ /* We shouldn't even have the job submitted to us if there's no -+ * surface to write out. -+ */ -+ if (!setup.color_ms_write && !setup.zs_write) { -+ DRM_ERROR("RCL requires color or Z/S write\n"); -+ return -EINVAL; -+ } -+ -+ return vc4_create_rcl_bo(dev, exec, &setup); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_trace.h b/drivers/gpu/drm/vc4/vc4_trace.h -new file mode 100644 -index 0000000..ad7b1ea ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_trace.h -@@ -0,0 +1,63 @@ -+/* -+ * Copyright (C) 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. -+ */ -+ -+#if !defined(_VC4_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -+#define _VC4_TRACE_H_ -+ -+#include -+#include -+#include -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM vc4 -+#define TRACE_INCLUDE_FILE vc4_trace -+ -+TRACE_EVENT(vc4_wait_for_seqno_begin, -+ TP_PROTO(struct drm_device *dev, uint64_t seqno, uint64_t timeout), -+ TP_ARGS(dev, seqno, timeout), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ __field(u64, timeout) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ __entry->timeout = timeout; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu, timeout=%llu", -+ __entry->dev, __entry->seqno, __entry->timeout) -+); -+ -+TRACE_EVENT(vc4_wait_for_seqno_end, -+ TP_PROTO(struct drm_device *dev, uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, __entry->seqno) -+); -+ -+#endif /* _VC4_TRACE_H_ */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#include -diff --git a/drivers/gpu/drm/vc4/vc4_trace_points.c b/drivers/gpu/drm/vc4/vc4_trace_points.c -new file mode 100644 -index 0000000..e6278f2 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_trace_points.c -@@ -0,0 +1,14 @@ -+/* -+ * Copyright (C) 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 "vc4_drv.h" -+ -+#ifndef __CHECKER__ -+#define CREATE_TRACE_POINTS -+#include "vc4_trace.h" -+#endif -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -new file mode 100644 -index 0000000..b9cb7cf ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -0,0 +1,268 @@ -+/* -+ * Copyright (c) 2014 The Linux Foundation. All rights reserved. -+ * Copyright (C) 2013 Red Hat -+ * Author: Rob Clark -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include "linux/component.h" -+#include "soc/bcm2835/raspberrypi-firmware.h" -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+ -+#ifdef CONFIG_DEBUG_FS -+#define REGDEF(reg) { reg, #reg } -+static const struct { -+ uint32_t reg; -+ const char *name; -+} vc4_reg_defs[] = { -+ REGDEF(V3D_IDENT0), -+ REGDEF(V3D_IDENT1), -+ REGDEF(V3D_IDENT2), -+ REGDEF(V3D_SCRATCH), -+ REGDEF(V3D_L2CACTL), -+ REGDEF(V3D_SLCACTL), -+ REGDEF(V3D_INTCTL), -+ REGDEF(V3D_INTENA), -+ REGDEF(V3D_INTDIS), -+ REGDEF(V3D_CT0CS), -+ REGDEF(V3D_CT1CS), -+ REGDEF(V3D_CT0EA), -+ REGDEF(V3D_CT1EA), -+ REGDEF(V3D_CT0CA), -+ REGDEF(V3D_CT1CA), -+ REGDEF(V3D_CT00RA0), -+ REGDEF(V3D_CT01RA0), -+ REGDEF(V3D_CT0LC), -+ REGDEF(V3D_CT1LC), -+ REGDEF(V3D_CT0PC), -+ REGDEF(V3D_CT1PC), -+ REGDEF(V3D_PCS), -+ REGDEF(V3D_BFC), -+ REGDEF(V3D_RFC), -+ REGDEF(V3D_BPCA), -+ REGDEF(V3D_BPCS), -+ REGDEF(V3D_BPOA), -+ REGDEF(V3D_BPOS), -+ REGDEF(V3D_BXCF), -+ REGDEF(V3D_SQRSV0), -+ REGDEF(V3D_SQRSV1), -+ REGDEF(V3D_SQCNTL), -+ REGDEF(V3D_SRQPC), -+ REGDEF(V3D_SRQUA), -+ REGDEF(V3D_SRQUL), -+ REGDEF(V3D_SRQCS), -+ REGDEF(V3D_VPACNTL), -+ REGDEF(V3D_VPMBASE), -+ REGDEF(V3D_PCTRC), -+ REGDEF(V3D_PCTRE), -+ REGDEF(V3D_PCTR0), -+ REGDEF(V3D_PCTRS0), -+ REGDEF(V3D_PCTR1), -+ REGDEF(V3D_PCTRS1), -+ REGDEF(V3D_PCTR2), -+ REGDEF(V3D_PCTRS2), -+ REGDEF(V3D_PCTR3), -+ REGDEF(V3D_PCTRS3), -+ REGDEF(V3D_PCTR4), -+ REGDEF(V3D_PCTRS4), -+ REGDEF(V3D_PCTR5), -+ REGDEF(V3D_PCTRS5), -+ REGDEF(V3D_PCTR6), -+ REGDEF(V3D_PCTRS6), -+ REGDEF(V3D_PCTR7), -+ REGDEF(V3D_PCTRS7), -+ REGDEF(V3D_PCTR8), -+ REGDEF(V3D_PCTRS8), -+ REGDEF(V3D_PCTR9), -+ REGDEF(V3D_PCTRS9), -+ REGDEF(V3D_PCTR10), -+ REGDEF(V3D_PCTRS10), -+ REGDEF(V3D_PCTR11), -+ REGDEF(V3D_PCTRS11), -+ REGDEF(V3D_PCTR12), -+ REGDEF(V3D_PCTRS12), -+ REGDEF(V3D_PCTR13), -+ REGDEF(V3D_PCTRS13), -+ REGDEF(V3D_PCTR14), -+ REGDEF(V3D_PCTRS14), -+ REGDEF(V3D_PCTR15), -+ REGDEF(V3D_PCTRS15), -+ REGDEF(V3D_BGE), -+ REGDEF(V3D_FDBGO), -+ REGDEF(V3D_FDBGB), -+ REGDEF(V3D_FDBGR), -+ REGDEF(V3D_FDBGS), -+ REGDEF(V3D_ERRSTAT), -+}; -+ -+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(vc4_reg_defs); i++) { -+ seq_printf(m, "%s (0x%04x): 0x%08x\n", -+ vc4_reg_defs[i].name, vc4_reg_defs[i].reg, -+ V3D_READ(vc4_reg_defs[i].reg)); -+ } -+ -+ return 0; -+} -+ -+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t ident1 = V3D_READ(V3D_IDENT1); -+ uint32_t nslc = VC4_GET_FIELD(ident1, V3D_IDENT1_NSLC); -+ uint32_t tups = VC4_GET_FIELD(ident1, V3D_IDENT1_TUPS); -+ uint32_t qups = VC4_GET_FIELD(ident1, V3D_IDENT1_QUPS); -+ -+ seq_printf(m, "Revision: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); -+ seq_printf(m, "Slices: %d\n", nslc); -+ seq_printf(m, "TMUs: %d\n", nslc * tups); -+ seq_printf(m, "QPUs: %d\n", nslc * qups); -+ seq_printf(m, "Semaphores: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); -+ -+ return 0; -+} -+#endif /* CONFIG_DEBUG_FS */ -+ -+/* -+ * Asks the firmware to turn on power to the V3D engine. -+ * -+ * This may be doable with just the clocks interface, though this -+ * packet does some other register setup from the firmware, too. -+ */ -+int -+vc4_v3d_set_power(struct vc4_dev *vc4, bool on) -+{ -+ u32 packet = on; -+ -+ return rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_SET_ENABLE_QPU, -+ &packet, sizeof(packet)); -+} -+ -+static void vc4_v3d_init_hw(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Take all the memory that would have been reserved for user -+ * QPU programs, since we don't have an interface for running -+ * them, anyway. -+ */ -+ V3D_WRITE(V3D_VPMBASE, 0); -+} -+ -+static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct drm_device *drm = dev_get_drvdata(master); -+ struct vc4_dev *vc4 = to_vc4_dev(drm); -+ struct vc4_v3d *v3d = NULL; -+ int ret; -+ -+ v3d = devm_kzalloc(&pdev->dev, sizeof(*v3d), GFP_KERNEL); -+ if (!v3d) -+ return -ENOMEM; -+ -+ v3d->pdev = pdev; -+ -+ v3d->regs = vc4_ioremap_regs(pdev, 0); -+ if (IS_ERR(v3d->regs)) -+ return PTR_ERR(v3d->regs); -+ -+ vc4->v3d = v3d; -+ -+ ret = vc4_v3d_set_power(vc4, true); -+ if (ret) -+ return ret; -+ -+ if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) { -+ DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n", -+ V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0); -+ return -EINVAL; -+ } -+ -+ /* Reset the binner overflow address/size at setup, to be sure -+ * we don't reuse an old one. -+ */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ vc4_v3d_init_hw(drm); -+ -+ ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); -+ if (ret) { -+ DRM_ERROR("Failed to install IRQ handler\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void vc4_v3d_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct drm_device *drm = dev_get_drvdata(master); -+ struct vc4_dev *vc4 = to_vc4_dev(drm); -+ -+ drm_irq_uninstall(drm); -+ -+ /* Disable the binner's overflow memory address, so the next -+ * driver probe (if any) doesn't try to reuse our old -+ * allocation. -+ */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ vc4_v3d_set_power(vc4, false); -+ -+ vc4->v3d = NULL; -+} -+ -+static const struct component_ops vc4_v3d_ops = { -+ .bind = vc4_v3d_bind, -+ .unbind = vc4_v3d_unbind, -+}; -+ -+static int vc4_v3d_dev_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &vc4_v3d_ops); -+} -+ -+static int vc4_v3d_dev_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &vc4_v3d_ops); -+ return 0; -+} -+ -+static const struct of_device_id vc4_v3d_dt_match[] = { -+ { .compatible = "brcm,vc4-v3d" }, -+ {} -+}; -+ -+struct platform_driver vc4_v3d_driver = { -+ .probe = vc4_v3d_dev_probe, -+ .remove = vc4_v3d_dev_remove, -+ .driver = { -+ .name = "vc4_v3d", -+ .of_match_table = vc4_v3d_dt_match, -+ }, -+}; -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -new file mode 100644 -index 0000000..ff3b62f ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -0,0 +1,958 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * Command list validator for VC4. -+ * -+ * The VC4 has no IOMMU between it and system memory. So, a user with -+ * access to execute command lists could escalate privilege by -+ * overwriting system memory (drawing to it as a framebuffer) or -+ * reading system memory it shouldn't (reading it as a texture, or -+ * uniform data, or vertex data). -+ * -+ * This validates command lists to ensure that all accesses are within -+ * the bounds of the GEM objects referenced. It explicitly whitelists -+ * packets, and looks at the offsets in any address fields to make -+ * sure they're constrained within the BOs they reference. -+ * -+ * Note that because of the validation that's happening anyway, this -+ * is where GEM relocation processing happens. -+ */ -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_packet.h" -+ -+#define VALIDATE_ARGS \ -+ struct vc4_exec_info *exec, \ -+ void *validated, \ -+ void *untrusted -+ -+ -+/** Return the width in pixels of a 64-byte microtile. */ -+static uint32_t -+utile_width(int cpp) -+{ -+ switch (cpp) { -+ case 1: -+ case 2: -+ return 8; -+ case 4: -+ return 4; -+ case 8: -+ return 2; -+ default: -+ DRM_ERROR("unknown cpp: %d\n", cpp); -+ return 1; -+ } -+} -+ -+/** Return the height in pixels of a 64-byte microtile. */ -+static uint32_t -+utile_height(int cpp) -+{ -+ switch (cpp) { -+ case 1: -+ return 8; -+ case 2: -+ case 4: -+ case 8: -+ return 4; -+ default: -+ DRM_ERROR("unknown cpp: %d\n", cpp); -+ return 1; -+ } -+} -+ -+/** -+ * The texture unit decides what tiling format a particular miplevel is using -+ * this function, so we lay out our miptrees accordingly. -+ */ -+static bool -+size_is_lt(uint32_t width, uint32_t height, int cpp) -+{ -+ return (width <= 4 * utile_width(cpp) || -+ height <= 4 * utile_height(cpp)); -+} -+ -+bool -+vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj) -+{ -+ *obj = NULL; -+ -+ if (hindex >= exec->bo_count) { -+ DRM_ERROR("BO index %d greater than BO count %d\n", -+ hindex, exec->bo_count); -+ return false; -+ } -+ -+ if (exec->bo[hindex].mode != mode) { -+ if (exec->bo[hindex].mode == VC4_MODE_UNDECIDED) { -+ exec->bo[hindex].mode = mode; -+ } else { -+ DRM_ERROR("BO index %d reused with mode %d vs %d\n", -+ hindex, exec->bo[hindex].mode, mode); -+ return false; -+ } -+ } -+ -+ *obj = exec->bo[hindex].bo; -+ return true; -+} -+ -+static bool -+vc4_use_handle(struct vc4_exec_info *exec, -+ uint32_t gem_handles_packet_index, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj) -+{ -+ return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index], -+ mode, obj); -+} -+ -+static uint32_t -+gl_shader_rec_size(uint32_t pointer_bits) -+{ -+ uint32_t attribute_count = pointer_bits & 7; -+ bool extended = pointer_bits & 8; -+ -+ if (attribute_count == 0) -+ attribute_count = 8; -+ -+ if (extended) -+ return 100 + attribute_count * 4; -+ else -+ return 36 + attribute_count * 8; -+} -+ -+bool -+vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, -+ uint32_t offset, uint8_t tiling_format, -+ uint32_t width, uint32_t height, uint8_t cpp) -+{ -+ uint32_t aligned_width, aligned_height, stride, size; -+ uint32_t utile_w = utile_width(cpp); -+ uint32_t utile_h = utile_height(cpp); -+ -+ /* The shaded vertex format stores signed 12.4 fixed point -+ * (-2048,2047) offsets from the viewport center, so we should -+ * never have a render target larger than 4096. The texture -+ * unit can only sample from 2048x2048, so it's even more -+ * restricted. This lets us avoid worrying about overflow in -+ * our math. -+ */ -+ if (width > 4096 || height > 4096) { -+ DRM_ERROR("Surface dimesions (%d,%d) too large", width, height); -+ return false; -+ } -+ -+ switch (tiling_format) { -+ case VC4_TILING_FORMAT_LINEAR: -+ aligned_width = round_up(width, utile_w); -+ aligned_height = height; -+ break; -+ case VC4_TILING_FORMAT_T: -+ aligned_width = round_up(width, utile_w * 8); -+ aligned_height = round_up(height, utile_h * 8); -+ break; -+ case VC4_TILING_FORMAT_LT: -+ aligned_width = round_up(width, utile_w); -+ aligned_height = round_up(height, utile_h); -+ break; -+ default: -+ DRM_ERROR("buffer tiling %d unsupported\n", tiling_format); -+ return false; -+ } -+ -+ stride = aligned_width * cpp; -+ size = stride * aligned_height; -+ -+ if (size + offset < size || -+ size + offset > fbo->base.size) { -+ DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %d)\n", -+ width, height, -+ aligned_width, aligned_height, -+ size, offset, fbo->base.size); -+ return false; -+ } -+ -+ return true; -+} -+ -+static int -+validate_flush_all(VALIDATE_ARGS) -+{ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("VC4_PACKET_FLUSH_ALL after " -+ "VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+validate_start_tile_binning(VALIDATE_ARGS) -+{ -+ if (exec->found_start_tile_binning_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n"); -+ return -EINVAL; -+ } -+ exec->found_start_tile_binning_packet = true; -+ -+ if (!exec->found_tile_binning_mode_config_packet) { -+ DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+validate_increment_semaphore(VALIDATE_ARGS) -+{ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ exec->found_increment_semaphore_packet = true; -+ -+ /* Once we've found the semaphore increment, there should be one FLUSH -+ * then the end of the command list. The FLUSH actually triggers the -+ * increment, so we only need to make sure there -+ */ -+ -+ return 0; -+} -+ -+static int -+validate_indexed_prim_list(VALIDATE_ARGS) -+{ -+ struct drm_gem_cma_object *ib; -+ uint32_t length = *(uint32_t *)(untrusted + 1); -+ uint32_t offset = *(uint32_t *)(untrusted + 5); -+ uint32_t max_index = *(uint32_t *)(untrusted + 9); -+ uint32_t index_size = (*(uint8_t *)(untrusted + 0) >> 4) ? 2 : 1; -+ struct vc4_shader_state *shader_state; -+ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ /* Check overflow condition */ -+ if (exec->shader_state_count == 0) { -+ DRM_ERROR("shader state must precede primitives\n"); -+ return -EINVAL; -+ } -+ shader_state = &exec->shader_state[exec->shader_state_count - 1]; -+ -+ if (max_index > shader_state->max_index) -+ shader_state->max_index = max_index; -+ -+ if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &ib)) -+ return -EINVAL; -+ -+ if (offset > ib->base.size || -+ (ib->base.size - offset) / index_size < length) { -+ DRM_ERROR("IB access overflow (%d + %d*%d > %d)\n", -+ offset, length, index_size, ib->base.size); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)(validated + 5) = ib->paddr + offset; -+ -+ return 0; -+} -+ -+static int -+validate_gl_array_primitive(VALIDATE_ARGS) -+{ -+ uint32_t length = *(uint32_t *)(untrusted + 1); -+ uint32_t base_index = *(uint32_t *)(untrusted + 5); -+ uint32_t max_index; -+ struct vc4_shader_state *shader_state; -+ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ /* Check overflow condition */ -+ if (exec->shader_state_count == 0) { -+ DRM_ERROR("shader state must precede primitives\n"); -+ return -EINVAL; -+ } -+ shader_state = &exec->shader_state[exec->shader_state_count - 1]; -+ -+ if (length + base_index < length) { -+ DRM_ERROR("primitive vertex count overflow\n"); -+ return -EINVAL; -+ } -+ max_index = length + base_index - 1; -+ -+ if (max_index > shader_state->max_index) -+ shader_state->max_index = max_index; -+ -+ return 0; -+} -+ -+static int -+validate_gl_shader_state(VALIDATE_ARGS) -+{ -+ uint32_t i = exec->shader_state_count++; -+ -+ if (i >= exec->shader_state_size) { -+ DRM_ERROR("More requests for shader states than declared\n"); -+ return -EINVAL; -+ } -+ -+ exec->shader_state[i].packet = VC4_PACKET_GL_SHADER_STATE; -+ exec->shader_state[i].addr = *(uint32_t *)untrusted; -+ exec->shader_state[i].max_index = 0; -+ -+ if (exec->shader_state[i].addr & ~0xf) { -+ DRM_ERROR("high bits set in GL shader rec reference\n"); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)validated = (exec->shader_rec_p + -+ exec->shader_state[i].addr); -+ -+ exec->shader_rec_p += -+ roundup(gl_shader_rec_size(exec->shader_state[i].addr), 16); -+ -+ return 0; -+} -+ -+static int -+validate_nv_shader_state(VALIDATE_ARGS) -+{ -+ uint32_t i = exec->shader_state_count++; -+ -+ if (i >= exec->shader_state_size) { -+ DRM_ERROR("More requests for shader states than declared\n"); -+ return -EINVAL; -+ } -+ -+ exec->shader_state[i].packet = VC4_PACKET_NV_SHADER_STATE; -+ exec->shader_state[i].addr = *(uint32_t *)untrusted; -+ -+ if (exec->shader_state[i].addr & 15) { -+ DRM_ERROR("NV shader state address 0x%08x misaligned\n", -+ exec->shader_state[i].addr); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)validated = (exec->shader_state[i].addr + -+ exec->shader_rec_p); -+ -+ return 0; -+} -+ -+static int -+validate_tile_binning_config(VALIDATE_ARGS) -+{ -+ struct drm_device *dev = exec->exec_bo->base.dev; -+ uint8_t flags; -+ uint32_t tile_state_size, tile_alloc_size; -+ uint32_t tile_count; -+ -+ if (exec->found_tile_binning_mode_config_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); -+ return -EINVAL; -+ } -+ exec->found_tile_binning_mode_config_packet = true; -+ -+ exec->bin_tiles_x = *(uint8_t *)(untrusted + 12); -+ exec->bin_tiles_y = *(uint8_t *)(untrusted + 13); -+ tile_count = exec->bin_tiles_x * exec->bin_tiles_y; -+ flags = *(uint8_t *)(untrusted + 14); -+ -+ if (exec->bin_tiles_x == 0 || -+ exec->bin_tiles_y == 0) { -+ DRM_ERROR("Tile binning config of %dx%d too small\n", -+ exec->bin_tiles_x, exec->bin_tiles_y); -+ return -EINVAL; -+ } -+ -+ if (flags & (VC4_BIN_CONFIG_DB_NON_MS | -+ VC4_BIN_CONFIG_TILE_BUFFER_64BIT | -+ VC4_BIN_CONFIG_MS_MODE_4X)) { -+ DRM_ERROR("unsupported bining config flags 0x%02x\n", flags); -+ return -EINVAL; -+ } -+ -+ /* The tile state data array is 48 bytes per tile, and we put it at -+ * the start of a BO containing both it and the tile alloc. -+ */ -+ tile_state_size = 48 * tile_count; -+ -+ /* Since the tile alloc array will follow us, align. */ -+ exec->tile_alloc_offset = roundup(tile_state_size, 4096); -+ -+ *(uint8_t *)(validated + 14) = -+ ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK | -+ VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK)) | -+ VC4_BIN_CONFIG_AUTO_INIT_TSDA | -+ VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32, -+ VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE) | -+ VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128, -+ VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE)); -+ -+ /* Initial block size. */ -+ tile_alloc_size = 32 * tile_count; -+ -+ /* -+ * The initial allocation gets rounded to the next 256 bytes before -+ * the hardware starts fulfilling further allocations. -+ */ -+ tile_alloc_size = roundup(tile_alloc_size, 256); -+ -+ /* Add space for the extra allocations. This is what gets used first, -+ * before overflow memory. It must have at least 4096 bytes, but we -+ * want to avoid overflow memory usage if possible. -+ */ -+ tile_alloc_size += 1024 * 1024; -+ -+ exec->tile_bo = &vc4_bo_create(dev, exec->tile_alloc_offset + -+ tile_alloc_size)->base; -+ if (!exec->tile_bo) -+ return -ENOMEM; -+ list_add_tail(&to_vc4_bo(&exec->tile_bo->base)->unref_head, -+ &exec->unref_list); -+ -+ /* tile alloc address. */ -+ *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + -+ exec->tile_alloc_offset); -+ /* tile alloc size. */ -+ *(uint32_t *)(validated + 4) = tile_alloc_size; -+ /* tile state address. */ -+ *(uint32_t *)(validated + 8) = exec->tile_bo->paddr; -+ -+ return 0; -+} -+ -+static int -+validate_gem_handles(VALIDATE_ARGS) -+{ -+ memcpy(exec->bo_index, untrusted, sizeof(exec->bo_index)); -+ return 0; -+} -+ -+#define VC4_DEFINE_PACKET(packet, name, func) \ -+ [packet] = { packet ## _SIZE, name, func } -+ -+static const struct cmd_info { -+ uint16_t len; -+ const char *name; -+ int (*func)(struct vc4_exec_info *exec, void *validated, -+ void *untrusted); -+} cmd_info[] = { -+ VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning), -+ VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive), -+ -+ /* This is only used by clipped primitives (packets 48 and 49), which -+ * we don't support parsing yet. -+ */ -+ VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state), -+ VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, "NV Shader State", validate_nv_shader_state), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL), -+ /* Note: The docs say this was also 105, but it was 106 in the -+ * initial userland code drop. -+ */ -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles), -+}; -+ -+int -+vc4_validate_bin_cl(struct drm_device *dev, -+ void *validated, -+ void *unvalidated, -+ struct vc4_exec_info *exec) -+{ -+ uint32_t len = exec->args->bin_cl_size; -+ uint32_t dst_offset = 0; -+ uint32_t src_offset = 0; -+ -+ while (src_offset < len) { -+ void *dst_pkt = validated + dst_offset; -+ void *src_pkt = unvalidated + src_offset; -+ u8 cmd = *(uint8_t *)src_pkt; -+ const struct cmd_info *info; -+ -+ if (cmd > ARRAY_SIZE(cmd_info)) { -+ DRM_ERROR("0x%08x: packet %d out of bounds\n", -+ src_offset, cmd); -+ return -EINVAL; -+ } -+ -+ info = &cmd_info[cmd]; -+ if (!info->name) { -+ DRM_ERROR("0x%08x: packet %d invalid\n", -+ src_offset, cmd); -+ return -EINVAL; -+ } -+ -+#if 0 -+ DRM_INFO("0x%08x: packet %d (%s) size %d processing...\n", -+ src_offset, cmd, info->name, info->len); -+#endif -+ -+ if (src_offset + info->len > len) { -+ DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x " -+ "exceeds bounds (0x%08x)\n", -+ src_offset, cmd, info->name, info->len, -+ src_offset + len); -+ return -EINVAL; -+ } -+ -+ if (cmd != VC4_PACKET_GEM_HANDLES) -+ memcpy(dst_pkt, src_pkt, info->len); -+ -+ if (info->func && info->func(exec, -+ dst_pkt + 1, -+ src_pkt + 1)) { -+ DRM_ERROR("0x%08x: packet %d (%s) failed to " -+ "validate\n", -+ src_offset, cmd, info->name); -+ return -EINVAL; -+ } -+ -+ src_offset += info->len; -+ /* GEM handle loading doesn't produce HW packets. */ -+ if (cmd != VC4_PACKET_GEM_HANDLES) -+ dst_offset += info->len; -+ -+ /* When the CL hits halt, it'll stop reading anything else. */ -+ if (cmd == VC4_PACKET_HALT) -+ break; -+ } -+ -+ exec->ct0ea = exec->ct0ca + dst_offset; -+ -+ if (!exec->found_start_tile_binning_packet) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n"); -+ return -EINVAL; -+ } -+ -+ if (!exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static bool -+reloc_tex(struct vc4_exec_info *exec, -+ void *uniform_data_u, -+ struct vc4_texture_sample_info *sample, -+ uint32_t texture_handle_index) -+ -+{ -+ struct drm_gem_cma_object *tex; -+ uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); -+ uint32_t p1 = *(uint32_t *)(uniform_data_u + sample->p_offset[1]); -+ uint32_t p2 = (sample->p_offset[2] != ~0 ? -+ *(uint32_t *)(uniform_data_u + sample->p_offset[2]) : 0); -+ uint32_t p3 = (sample->p_offset[3] != ~0 ? -+ *(uint32_t *)(uniform_data_u + sample->p_offset[3]) : 0); -+ uint32_t *validated_p0 = exec->uniforms_v + sample->p_offset[0]; -+ uint32_t offset = p0 & VC4_TEX_P0_OFFSET_MASK; -+ uint32_t miplevels = VC4_GET_FIELD(p0, VC4_TEX_P0_MIPLVLS); -+ uint32_t width = VC4_GET_FIELD(p1, VC4_TEX_P1_WIDTH); -+ uint32_t height = VC4_GET_FIELD(p1, VC4_TEX_P1_HEIGHT); -+ uint32_t cpp, tiling_format, utile_w, utile_h; -+ uint32_t i; -+ uint32_t cube_map_stride = 0; -+ enum vc4_texture_data_type type; -+ -+ if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex)) -+ return false; -+ -+ if (sample->is_direct) { -+ uint32_t remaining_size = tex->base.size - p0; -+ if (p0 > tex->base.size - 4) { -+ DRM_ERROR("UBO offset greater than UBO size\n"); -+ goto fail; -+ } -+ if (p1 > remaining_size - 4) { -+ DRM_ERROR("UBO clamp would allow reads outside of UBO\n"); -+ goto fail; -+ } -+ *validated_p0 = tex->paddr + p0; -+ return true; -+ } -+ -+ if (width == 0) -+ width = 2048; -+ if (height == 0) -+ height = 2048; -+ -+ if (p0 & VC4_TEX_P0_CMMODE_MASK) { -+ if (VC4_GET_FIELD(p2, VC4_TEX_P2_PTYPE) == -+ VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) -+ cube_map_stride = p2 & VC4_TEX_P2_CMST_MASK; -+ if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) == -+ VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) { -+ if (cube_map_stride) { -+ DRM_ERROR("Cube map stride set twice\n"); -+ goto fail; -+ } -+ -+ cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK; -+ } -+ if (!cube_map_stride) { -+ DRM_ERROR("Cube map stride not set\n"); -+ goto fail; -+ } -+ } -+ -+ type = (VC4_GET_FIELD(p0, VC4_TEX_P0_TYPE) | -+ (VC4_GET_FIELD(p1, VC4_TEX_P1_TYPE4) << 4)); -+ -+ switch (type) { -+ case VC4_TEXTURE_TYPE_RGBA8888: -+ case VC4_TEXTURE_TYPE_RGBX8888: -+ case VC4_TEXTURE_TYPE_RGBA32R: -+ cpp = 4; -+ break; -+ case VC4_TEXTURE_TYPE_RGBA4444: -+ case VC4_TEXTURE_TYPE_RGBA5551: -+ case VC4_TEXTURE_TYPE_RGB565: -+ case VC4_TEXTURE_TYPE_LUMALPHA: -+ case VC4_TEXTURE_TYPE_S16F: -+ case VC4_TEXTURE_TYPE_S16: -+ cpp = 2; -+ break; -+ case VC4_TEXTURE_TYPE_LUMINANCE: -+ case VC4_TEXTURE_TYPE_ALPHA: -+ case VC4_TEXTURE_TYPE_S8: -+ cpp = 1; -+ break; -+ case VC4_TEXTURE_TYPE_ETC1: -+ case VC4_TEXTURE_TYPE_BW1: -+ case VC4_TEXTURE_TYPE_A4: -+ case VC4_TEXTURE_TYPE_A1: -+ case VC4_TEXTURE_TYPE_RGBA64: -+ case VC4_TEXTURE_TYPE_YUV422R: -+ default: -+ DRM_ERROR("Texture format %d unsupported\n", type); -+ goto fail; -+ } -+ utile_w = utile_width(cpp); -+ utile_h = utile_height(cpp); -+ -+ if (type == VC4_TEXTURE_TYPE_RGBA32R) { -+ tiling_format = VC4_TILING_FORMAT_LINEAR; -+ } else { -+ if (size_is_lt(width, height, cpp)) -+ tiling_format = VC4_TILING_FORMAT_LT; -+ else -+ tiling_format = VC4_TILING_FORMAT_T; -+ } -+ -+ if (!vc4_check_tex_size(exec, tex, offset + cube_map_stride * 5, -+ tiling_format, width, height, cpp)) { -+ goto fail; -+ } -+ -+ /* The mipmap levels are stored before the base of the texture. Make -+ * sure there is actually space in the BO. -+ */ -+ for (i = 1; i <= miplevels; i++) { -+ uint32_t level_width = max(width >> i, 1u); -+ uint32_t level_height = max(height >> i, 1u); -+ uint32_t aligned_width, aligned_height; -+ uint32_t level_size; -+ -+ /* Once the levels get small enough, they drop from T to LT. */ -+ if (tiling_format == VC4_TILING_FORMAT_T && -+ size_is_lt(level_width, level_height, cpp)) { -+ tiling_format = VC4_TILING_FORMAT_LT; -+ } -+ -+ switch (tiling_format) { -+ case VC4_TILING_FORMAT_T: -+ aligned_width = round_up(level_width, utile_w * 8); -+ aligned_height = round_up(level_height, utile_h * 8); -+ break; -+ case VC4_TILING_FORMAT_LT: -+ aligned_width = round_up(level_width, utile_w); -+ aligned_height = round_up(level_height, utile_h); -+ break; -+ default: -+ aligned_width = round_up(level_width, utile_w); -+ aligned_height = level_height; -+ break; -+ } -+ -+ level_size = aligned_width * cpp * aligned_height; -+ -+ if (offset < level_size) { -+ DRM_ERROR("Level %d (%dx%d -> %dx%d) size %db " -+ "overflowed buffer bounds (offset %d)\n", -+ i, level_width, level_height, -+ aligned_width, aligned_height, -+ level_size, offset); -+ goto fail; -+ } -+ -+ offset -= level_size; -+ } -+ -+ *validated_p0 = tex->paddr + p0; -+ -+ return true; -+ fail: -+ DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); -+ DRM_INFO("Texture p1 at %d: 0x%08x\n", sample->p_offset[1], p1); -+ DRM_INFO("Texture p2 at %d: 0x%08x\n", sample->p_offset[2], p2); -+ DRM_INFO("Texture p3 at %d: 0x%08x\n", sample->p_offset[3], p3); -+ return false; -+} -+ -+static int -+validate_shader_rec(struct drm_device *dev, -+ struct vc4_exec_info *exec, -+ struct vc4_shader_state *state) -+{ -+ uint32_t *src_handles; -+ void *pkt_u, *pkt_v; -+ enum shader_rec_reloc_type { -+ RELOC_CODE, -+ RELOC_VBO, -+ }; -+ struct shader_rec_reloc { -+ enum shader_rec_reloc_type type; -+ uint32_t offset; -+ }; -+ static const struct shader_rec_reloc gl_relocs[] = { -+ { RELOC_CODE, 4 }, /* fs */ -+ { RELOC_CODE, 16 }, /* vs */ -+ { RELOC_CODE, 28 }, /* cs */ -+ }; -+ static const struct shader_rec_reloc nv_relocs[] = { -+ { RELOC_CODE, 4 }, /* fs */ -+ { RELOC_VBO, 12 } -+ }; -+ const struct shader_rec_reloc *relocs; -+ struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; -+ uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; -+ int i; -+ struct vc4_validated_shader_info *validated_shader; -+ -+ if (state->packet == VC4_PACKET_NV_SHADER_STATE) { -+ relocs = nv_relocs; -+ nr_fixed_relocs = ARRAY_SIZE(nv_relocs); -+ -+ packet_size = 16; -+ } else { -+ relocs = gl_relocs; -+ nr_fixed_relocs = ARRAY_SIZE(gl_relocs); -+ -+ nr_attributes = state->addr & 0x7; -+ if (nr_attributes == 0) -+ nr_attributes = 8; -+ packet_size = gl_shader_rec_size(state->addr); -+ } -+ nr_relocs = nr_fixed_relocs + nr_attributes; -+ -+ if (nr_relocs * 4 > exec->shader_rec_size) { -+ DRM_ERROR("overflowed shader recs reading %d handles " -+ "from %d bytes left\n", -+ nr_relocs, exec->shader_rec_size); -+ return -EINVAL; -+ } -+ src_handles = exec->shader_rec_u; -+ exec->shader_rec_u += nr_relocs * 4; -+ exec->shader_rec_size -= nr_relocs * 4; -+ -+ if (packet_size > exec->shader_rec_size) { -+ DRM_ERROR("overflowed shader recs copying %db packet " -+ "from %d bytes left\n", -+ packet_size, exec->shader_rec_size); -+ return -EINVAL; -+ } -+ pkt_u = exec->shader_rec_u; -+ pkt_v = exec->shader_rec_v; -+ memcpy(pkt_v, pkt_u, packet_size); -+ exec->shader_rec_u += packet_size; -+ /* Shader recs have to be aligned to 16 bytes (due to the attribute -+ * flags being in the low bytes), so round the next validated shader -+ * rec address up. This should be safe, since we've got so many -+ * relocations in a shader rec packet. -+ */ -+ BUG_ON(roundup(packet_size, 16) - packet_size > nr_relocs * 4); -+ exec->shader_rec_v += roundup(packet_size, 16); -+ exec->shader_rec_size -= packet_size; -+ -+ for (i = 0; i < nr_relocs; i++) { -+ enum vc4_bo_mode mode; -+ -+ if (i < nr_fixed_relocs && relocs[i].type == RELOC_CODE) -+ mode = VC4_MODE_SHADER; -+ else -+ mode = VC4_MODE_RENDER; -+ -+ if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) { -+ return false; -+ } -+ } -+ -+ for (i = 0; i < nr_fixed_relocs; i++) { -+ uint32_t o = relocs[i].offset; -+ uint32_t src_offset = *(uint32_t *)(pkt_u + o); -+ uint32_t *texture_handles_u; -+ void *uniform_data_u; -+ uint32_t tex; -+ -+ *(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset; -+ -+ switch (relocs[i].type) { -+ case RELOC_CODE: -+ if (src_offset != 0) { -+ DRM_ERROR("Shaders must be at offset 0 of " -+ "the BO.\n"); -+ goto fail; -+ } -+ -+ validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -+ if (!validated_shader) -+ goto fail; -+ -+ if (validated_shader->uniforms_src_size > -+ exec->uniforms_size) { -+ DRM_ERROR("Uniforms src buffer overflow\n"); -+ goto fail; -+ } -+ -+ texture_handles_u = exec->uniforms_u; -+ uniform_data_u = (texture_handles_u + -+ validated_shader->num_texture_samples); -+ -+ memcpy(exec->uniforms_v, uniform_data_u, -+ validated_shader->uniforms_size); -+ -+ for (tex = 0; -+ tex < validated_shader->num_texture_samples; -+ tex++) { -+ if (!reloc_tex(exec, -+ uniform_data_u, -+ &validated_shader->texture_samples[tex], -+ texture_handles_u[tex])) { -+ goto fail; -+ } -+ } -+ -+ *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; -+ -+ exec->uniforms_u += validated_shader->uniforms_src_size; -+ exec->uniforms_v += validated_shader->uniforms_size; -+ exec->uniforms_p += validated_shader->uniforms_size; -+ -+ break; -+ -+ case RELOC_VBO: -+ break; -+ } -+ } -+ -+ for (i = 0; i < nr_attributes; i++) { -+ struct drm_gem_cma_object *vbo = bo[nr_fixed_relocs + i]; -+ uint32_t o = 36 + i * 8; -+ uint32_t offset = *(uint32_t *)(pkt_u + o + 0); -+ uint32_t attr_size = *(uint8_t *)(pkt_u + o + 4) + 1; -+ uint32_t stride = *(uint8_t *)(pkt_u + o + 5); -+ uint32_t max_index; -+ -+ if (state->addr & 0x8) -+ stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; -+ -+ if (vbo->base.size < offset || -+ vbo->base.size - offset < attr_size) { -+ DRM_ERROR("BO offset overflow (%d + %d > %d)\n", -+ offset, attr_size, vbo->base.size); -+ return -EINVAL; -+ } -+ -+ if (stride != 0) { -+ max_index = ((vbo->base.size - offset - attr_size) / -+ stride); -+ if (state->max_index > max_index) { -+ DRM_ERROR("primitives use index %d out of supplied %d\n", -+ state->max_index, max_index); -+ return -EINVAL; -+ } -+ } -+ -+ *(uint32_t *)(pkt_v + o) = vbo->paddr + offset; -+ } -+ -+ return 0; -+ -+fail: -+ return -EINVAL; -+} -+ -+int -+vc4_validate_shader_recs(struct drm_device *dev, -+ struct vc4_exec_info *exec) -+{ -+ uint32_t i; -+ int ret = 0; -+ -+ for (i = 0; i < exec->shader_state_count; i++) { -+ ret = validate_shader_rec(dev, exec, &exec->shader_state[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return ret; -+} -diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -new file mode 100644 -index 0000000..0aab9d7 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -@@ -0,0 +1,521 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * DOC: Shader validator for VC4. -+ * -+ * The VC4 has no IOMMU between it and system memory. So, a user with access -+ * to execute shaders could escalate privilege by overwriting system memory -+ * (using the VPM write address register in the general-purpose DMA mode) or -+ * reading system memory it shouldn't (reading it as a texture, or uniform -+ * data, or vertex data). -+ * -+ * This walks over a shader starting from some offset within a BO, ensuring -+ * that its accesses are appropriately bounded, and recording how many texture -+ * accesses are made and where so that we can do relocations for them in the -+ * uniform stream. -+ * -+ * The kernel API has shaders stored in user-mapped BOs. The BOs will be -+ * forcibly unmapped from the process before validation, and any cache of -+ * validated state will be flushed if the mapping is faulted back in. -+ * -+ * Storing the shaders in BOs means that the validation process will be slow -+ * due to uncached reads, but since shaders are long-lived and shader BOs are -+ * never actually modified, this shouldn't be a problem. -+ */ -+ -+#include "vc4_drv.h" -+#include "vc4_qpu_defines.h" -+ -+struct vc4_shader_validation_state { -+ struct vc4_texture_sample_info tmu_setup[2]; -+ int tmu_write_count[2]; -+ -+ /* For registers that were last written to by a MIN instruction with -+ * one argument being a uniform, the address of the uniform. -+ * Otherwise, ~0. -+ * -+ * This is used for the validation of direct address memory reads. -+ */ -+ uint32_t live_min_clamp_offsets[32 + 32 + 4]; -+ bool live_max_clamp_regs[32 + 32 + 4]; -+}; -+ -+static uint32_t -+waddr_to_live_reg_index(uint32_t waddr, bool is_b) -+{ -+ if (waddr < 32) { -+ if (is_b) -+ return 32 + waddr; -+ else -+ return waddr; -+ } else if (waddr <= QPU_W_ACC3) { -+ -+ return 64 + waddr - QPU_W_ACC0; -+ } else { -+ return ~0; -+ } -+} -+ -+static uint32_t -+raddr_add_a_to_live_reg_index(uint64_t inst) -+{ -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ -+ if (add_a == QPU_MUX_A) { -+ return raddr_a; -+ } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) { -+ return 32 + raddr_b; -+ } else if (add_a <= QPU_MUX_R3) { -+ return 64 + add_a; -+ } else { -+ return ~0; -+ } -+} -+ -+static bool -+is_tmu_submit(uint32_t waddr) -+{ -+ return (waddr == QPU_W_TMU0_S || -+ waddr == QPU_W_TMU1_S); -+} -+ -+static bool -+is_tmu_write(uint32_t waddr) -+{ -+ return (waddr >= QPU_W_TMU0_S && -+ waddr <= QPU_W_TMU1_B); -+} -+ -+static bool -+record_validated_texture_sample(struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ int tmu) -+{ -+ uint32_t s = validated_shader->num_texture_samples; -+ int i; -+ struct vc4_texture_sample_info *temp_samples; -+ -+ temp_samples = krealloc(validated_shader->texture_samples, -+ (s + 1) * sizeof(*temp_samples), -+ GFP_KERNEL); -+ if (!temp_samples) -+ return false; -+ -+ memcpy(&temp_samples[s], -+ &validation_state->tmu_setup[tmu], -+ sizeof(*temp_samples)); -+ -+ validated_shader->num_texture_samples = s + 1; -+ validated_shader->texture_samples = temp_samples; -+ -+ for (i = 0; i < 4; i++) -+ validation_state->tmu_setup[tmu].p_offset[i] = ~0; -+ -+ return true; -+} -+ -+static bool -+check_tmu_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) -+{ -+ uint32_t waddr = (is_mul ? -+ QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -+ QPU_GET_FIELD(inst, QPU_WADDR_ADD)); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ int tmu = waddr > QPU_W_TMU0_B; -+ bool submit = is_tmu_submit(waddr); -+ bool is_direct = submit && validation_state->tmu_write_count[tmu] == 0; -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ if (is_direct) { -+ uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B); -+ uint32_t clamp_reg, clamp_offset; -+ -+ if (sig == QPU_SIG_SMALL_IMM) { -+ DRM_ERROR("direct TMU read used small immediate\n"); -+ return false; -+ } -+ -+ /* Make sure that this texture load is an add of the base -+ * address of the UBO to a clamped offset within the UBO. -+ */ -+ if (is_mul || -+ QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) { -+ DRM_ERROR("direct TMU load wasn't an add\n"); -+ return false; -+ } -+ -+ /* We assert that the the clamped address is the first -+ * argument, and the UBO base address is the second argument. -+ * This is arbitrary, but simpler than supporting flipping the -+ * two either way. -+ */ -+ clamp_reg = raddr_add_a_to_live_reg_index(inst); -+ if (clamp_reg == ~0) { -+ DRM_ERROR("direct TMU load wasn't clamped\n"); -+ return false; -+ } -+ -+ clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg]; -+ if (clamp_offset == ~0) { -+ DRM_ERROR("direct TMU load wasn't clamped\n"); -+ return false; -+ } -+ -+ /* Store the clamp value's offset in p1 (see reloc_tex() in -+ * vc4_validate.c). -+ */ -+ validation_state->tmu_setup[tmu].p_offset[1] = -+ clamp_offset; -+ -+ if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && -+ !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) { -+ DRM_ERROR("direct TMU load didn't add to a uniform\n"); -+ return false; -+ } -+ -+ validation_state->tmu_setup[tmu].is_direct = true; -+ } else { -+ if (raddr_a == QPU_R_UNIF || (sig != QPU_SIG_SMALL_IMM && -+ raddr_b == QPU_R_UNIF)) { -+ DRM_ERROR("uniform read in the same instruction as " -+ "texture setup.\n"); -+ return false; -+ } -+ } -+ -+ if (validation_state->tmu_write_count[tmu] >= 4) { -+ DRM_ERROR("TMU%d got too many parameters before dispatch\n", -+ tmu); -+ return false; -+ } -+ validation_state->tmu_setup[tmu].p_offset[validation_state->tmu_write_count[tmu]] = -+ validated_shader->uniforms_size; -+ validation_state->tmu_write_count[tmu]++; -+ /* Since direct uses a RADDR uniform reference, it will get counted in -+ * check_instruction_reads() -+ */ -+ if (!is_direct) -+ validated_shader->uniforms_size += 4; -+ -+ if (submit) { -+ if (!record_validated_texture_sample(validated_shader, -+ validation_state, tmu)) { -+ return false; -+ } -+ -+ validation_state->tmu_write_count[tmu] = 0; -+ } -+ -+ return true; -+} -+ -+static bool -+check_register_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) -+{ -+ uint32_t waddr = (is_mul ? -+ QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -+ QPU_GET_FIELD(inst, QPU_WADDR_ADD)); -+ -+ switch (waddr) { -+ case QPU_W_UNIFORMS_ADDRESS: -+ /* XXX: We'll probably need to support this for reladdr, but -+ * it's definitely a security-related one. -+ */ -+ DRM_ERROR("uniforms address load unsupported\n"); -+ return false; -+ -+ case QPU_W_TLB_COLOR_MS: -+ case QPU_W_TLB_COLOR_ALL: -+ case QPU_W_TLB_Z: -+ /* These only interact with the tile buffer, not main memory, -+ * so they're safe. -+ */ -+ return true; -+ -+ case QPU_W_TMU0_S: -+ case QPU_W_TMU0_T: -+ case QPU_W_TMU0_R: -+ case QPU_W_TMU0_B: -+ case QPU_W_TMU1_S: -+ case QPU_W_TMU1_T: -+ case QPU_W_TMU1_R: -+ case QPU_W_TMU1_B: -+ return check_tmu_write(inst, validated_shader, validation_state, -+ is_mul); -+ -+ case QPU_W_HOST_INT: -+ case QPU_W_TMU_NOSWAP: -+ case QPU_W_TLB_ALPHA_MASK: -+ case QPU_W_MUTEX_RELEASE: -+ /* XXX: I haven't thought about these, so don't support them -+ * for now. -+ */ -+ DRM_ERROR("Unsupported waddr %d\n", waddr); -+ return false; -+ -+ case QPU_W_VPM_ADDR: -+ DRM_ERROR("General VPM DMA unsupported\n"); -+ return false; -+ -+ case QPU_W_VPM: -+ case QPU_W_VPMVCD_SETUP: -+ /* We allow VPM setup in general, even including VPM DMA -+ * configuration setup, because the (unsafe) DMA can only be -+ * triggered by QPU_W_VPM_ADDR writes. -+ */ -+ return true; -+ -+ case QPU_W_TLB_STENCIL_SETUP: -+ return true; -+ } -+ -+ return true; -+} -+ -+static void -+track_live_clamps(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state) -+{ -+ uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD); -+ uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); -+ uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); -+ uint32_t cond_add = QPU_GET_FIELD(inst, QPU_COND_ADD); -+ uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A); -+ uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ bool ws = inst & QPU_WS; -+ uint32_t lri_add_a, lri_add, lri_mul; -+ bool add_a_is_min_0; -+ -+ /* Check whether OP_ADD's A argumennt comes from a live MAX(x, 0), -+ * before we clear previous live state. -+ */ -+ lri_add_a = raddr_add_a_to_live_reg_index(inst); -+ add_a_is_min_0 = (lri_add_a != ~0 && -+ validation_state->live_max_clamp_regs[lri_add_a]); -+ -+ /* Clear live state for registers written by our instruction. */ -+ lri_add = waddr_to_live_reg_index(waddr_add, ws); -+ lri_mul = waddr_to_live_reg_index(waddr_mul, !ws); -+ if (lri_mul != ~0) { -+ validation_state->live_max_clamp_regs[lri_mul] = false; -+ validation_state->live_min_clamp_offsets[lri_mul] = ~0; -+ } -+ if (lri_add != ~0) { -+ validation_state->live_max_clamp_regs[lri_add] = false; -+ validation_state->live_min_clamp_offsets[lri_add] = ~0; -+ } else { -+ /* Nothing further to do for live tracking, since only ADDs -+ * generate new live clamp registers. -+ */ -+ return; -+ } -+ -+ /* Now, handle remaining live clamp tracking for the ADD operation. */ -+ -+ if (cond_add != QPU_COND_ALWAYS) -+ return; -+ -+ if (op_add == QPU_A_MAX) { -+ /* Track live clamps of a value to a minimum of 0 (in either -+ * arg). -+ */ -+ if (sig != QPU_SIG_SMALL_IMM || raddr_b != 0 || -+ (add_a != QPU_MUX_B && add_b != QPU_MUX_B)) { -+ return; -+ } -+ -+ validation_state->live_max_clamp_regs[lri_add] = true; -+ } if (op_add == QPU_A_MIN) { -+ /* Track live clamps of a value clamped to a minimum of 0 and -+ * a maximum of some uniform's offset. -+ */ -+ if (!add_a_is_min_0) -+ return; -+ -+ if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && -+ !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF && -+ sig != QPU_SIG_SMALL_IMM)) { -+ return; -+ } -+ -+ validation_state->live_min_clamp_offsets[lri_add] = -+ validated_shader->uniforms_size; -+ } -+} -+ -+static bool -+check_instruction_writes(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state) -+{ -+ uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); -+ uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); -+ bool ok; -+ -+ if (is_tmu_write(waddr_add) && is_tmu_write(waddr_mul)) { -+ DRM_ERROR("ADD and MUL both set up textures\n"); -+ return false; -+ } -+ -+ ok = (check_register_write(inst, validated_shader, validation_state, false) && -+ check_register_write(inst, validated_shader, validation_state, true)); -+ -+ track_live_clamps(inst, validated_shader, validation_state); -+ -+ return ok; -+} -+ -+static bool -+check_instruction_reads(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader) -+{ -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ if (raddr_a == QPU_R_UNIF || -+ (raddr_b == QPU_R_UNIF && sig != QPU_SIG_SMALL_IMM)) { -+ /* This can't overflow the uint32_t, because we're reading 8 -+ * bytes of instruction to increment by 4 here, so we'd -+ * already be OOM. -+ */ -+ validated_shader->uniforms_size += 4; -+ } -+ -+ return true; -+} -+ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj) -+{ -+ bool found_shader_end = false; -+ int shader_end_ip = 0; -+ uint32_t ip, max_ip; -+ uint64_t *shader; -+ struct vc4_validated_shader_info *validated_shader; -+ struct vc4_shader_validation_state validation_state; -+ int i; -+ -+ memset(&validation_state, 0, sizeof(validation_state)); -+ -+ for (i = 0; i < 8; i++) -+ validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0; -+ for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++) -+ validation_state.live_min_clamp_offsets[i] = ~0; -+ -+ shader = shader_obj->vaddr; -+ max_ip = shader_obj->base.size / sizeof(uint64_t); -+ -+ validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL); -+ if (!validated_shader) -+ return NULL; -+ -+ for (ip = 0; ip < max_ip; ip++) { -+ uint64_t inst = shader[ip]; -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ switch (sig) { -+ case QPU_SIG_NONE: -+ case QPU_SIG_WAIT_FOR_SCOREBOARD: -+ case QPU_SIG_SCOREBOARD_UNLOCK: -+ case QPU_SIG_COLOR_LOAD: -+ case QPU_SIG_LOAD_TMU0: -+ case QPU_SIG_LOAD_TMU1: -+ case QPU_SIG_PROG_END: -+ case QPU_SIG_SMALL_IMM: -+ if (!check_instruction_writes(inst, validated_shader, -+ &validation_state)) { -+ DRM_ERROR("Bad write at ip %d\n", ip); -+ goto fail; -+ } -+ -+ if (!check_instruction_reads(inst, validated_shader)) -+ goto fail; -+ -+ if (sig == QPU_SIG_PROG_END) { -+ found_shader_end = true; -+ shader_end_ip = ip; -+ } -+ -+ break; -+ -+ case QPU_SIG_LOAD_IMM: -+ if (!check_instruction_writes(inst, validated_shader, -+ &validation_state)) { -+ DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); -+ goto fail; -+ } -+ break; -+ -+ default: -+ DRM_ERROR("Unsupported QPU signal %d at " -+ "instruction %d\n", sig, ip); -+ goto fail; -+ } -+ -+ /* There are two delay slots after program end is signaled -+ * that are still executed, then we're finished. -+ */ -+ if (found_shader_end && ip == shader_end_ip + 2) -+ break; -+ } -+ -+ if (ip == max_ip) { -+ DRM_ERROR("shader failed to terminate before " -+ "shader BO end at %d\n", -+ shader_obj->base.size); -+ goto fail; -+ } -+ -+ /* Again, no chance of integer overflow here because the worst case -+ * scenario is 8 bytes of uniforms plus handles per 8-byte -+ * instruction. -+ */ -+ validated_shader->uniforms_src_size = -+ (validated_shader->uniforms_size + -+ 4 * validated_shader->num_texture_samples); -+ -+ return validated_shader; -+ -+fail: -+ if (validated_shader) { -+ kfree(validated_shader->texture_samples); -+ kfree(validated_shader); -+ } -+ return NULL; -+} -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -new file mode 100644 -index 0000000..499daae ---- /dev/null -+++ b/include/uapi/drm/vc4_drm.h -@@ -0,0 +1,229 @@ -+/* -+ * Copyright © 2014-2015 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef _UAPI_VC4_DRM_H_ -+#define _UAPI_VC4_DRM_H_ -+ -+#include -+ -+#define DRM_VC4_SUBMIT_CL 0x00 -+#define DRM_VC4_WAIT_SEQNO 0x01 -+#define DRM_VC4_WAIT_BO 0x02 -+#define DRM_VC4_CREATE_BO 0x03 -+#define DRM_VC4_MMAP_BO 0x04 -+#define DRM_VC4_CREATE_SHADER_BO 0x05 -+ -+#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) -+#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -+#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) -+#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) -+#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) -+#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+ -+struct drm_vc4_submit_rcl_surface { -+ uint32_t hindex; /* Handle index, or ~0 if not present. */ -+ uint32_t offset; /* Offset to start of buffer. */ -+ /* -+ * Bits for either render config (color_ms_write) or load/store packet. -+ */ -+ uint16_t bits; -+ uint16_t pad; -+}; -+ -+/** -+ * struct drm_vc4_submit_cl - ioctl argument for submitting commands to the 3D -+ * engine. -+ * -+ * Drivers typically use GPU BOs to store batchbuffers / command lists and -+ * their associated state. However, because the VC4 lacks an MMU, we have to -+ * do validation of memory accesses by the GPU commands. If we were to store -+ * our commands in BOs, we'd need to do uncached readback from them to do the -+ * validation process, which is too expensive. Instead, userspace accumulates -+ * commands and associated state in plain memory, then the kernel copies the -+ * data to its own address space, and then validates and stores it in a GPU -+ * BO. -+ */ -+struct drm_vc4_submit_cl { -+ /* Pointer to the binner command list. -+ * -+ * This is the first set of commands executed, which runs the -+ * coordinate shader to determine where primitives land on the screen, -+ * then writes out the state updates and draw calls necessary per tile -+ * to the tile allocation BO. -+ */ -+ uint64_t bin_cl; -+ -+ /* Pointer to the shader records. -+ * -+ * Shader records are the structures read by the hardware that contain -+ * pointers to uniforms, shaders, and vertex attributes. The -+ * reference to the shader record has enough information to determine -+ * how many pointers are necessary (fixed number for shaders/uniforms, -+ * and an attribute count), so those BO indices into bo_handles are -+ * just stored as uint32_ts before each shader record passed in. -+ */ -+ uint64_t shader_rec; -+ -+ /* Pointer to uniform data and texture handles for the textures -+ * referenced by the shader. -+ * -+ * For each shader state record, there is a set of uniform data in the -+ * order referenced by the record (FS, VS, then CS). Each set of -+ * uniform data has a uint32_t index into bo_handles per texture -+ * sample operation, in the order the QPU_W_TMUn_S writes appear in -+ * the program. Following the texture BO handle indices is the actual -+ * uniform data. -+ * -+ * The individual uniform state blocks don't have sizes passed in, -+ * because the kernel has to determine the sizes anyway during shader -+ * code validation. -+ */ -+ uint64_t uniforms; -+ uint64_t bo_handles; -+ -+ /* Size in bytes of the binner command list. */ -+ uint32_t bin_cl_size; -+ /* Size in bytes of the set of shader records. */ -+ uint32_t shader_rec_size; -+ /* Number of shader records. -+ * -+ * This could just be computed from the contents of shader_records and -+ * the address bits of references to them from the bin CL, but it -+ * keeps the kernel from having to resize some allocations it makes. -+ */ -+ uint32_t shader_rec_count; -+ /* Size in bytes of the uniform state. */ -+ uint32_t uniforms_size; -+ -+ /* Number of BO handles passed in (size is that times 4). */ -+ uint32_t bo_handle_count; -+ -+ /* RCL setup: */ -+ uint16_t width; -+ uint16_t height; -+ uint8_t min_x_tile; -+ uint8_t min_y_tile; -+ uint8_t max_x_tile; -+ uint8_t max_y_tile; -+ struct drm_vc4_submit_rcl_surface color_read; -+ struct drm_vc4_submit_rcl_surface color_ms_write; -+ struct drm_vc4_submit_rcl_surface zs_read; -+ struct drm_vc4_submit_rcl_surface zs_write; -+ uint32_t clear_color[2]; -+ uint32_t clear_z; -+ uint8_t clear_s; -+ -+ uint32_t pad:24; -+ -+#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) -+ uint32_t flags; -+ -+ /* Returned value of the seqno of this render job (for the -+ * wait ioctl). -+ */ -+ uint64_t seqno; -+}; -+ -+/** -+ * struct drm_vc4_wait_seqno - ioctl argument for waiting for -+ * DRM_VC4_SUBMIT_CL completion using its returned seqno. -+ * -+ * timeout_ns is the timeout in nanoseconds, where "0" means "don't -+ * block, just return the status." -+ */ -+struct drm_vc4_wait_seqno { -+ uint64_t seqno; -+ uint64_t timeout_ns; -+}; -+ -+/** -+ * struct drm_vc4_wait_bo - ioctl argument for waiting for -+ * completion of the last DRM_VC4_SUBMIT_CL on a BO. -+ * -+ * This is useful for cases where multiple processes might be -+ * rendering to a BO and you want to wait for all rendering to be -+ * completed. -+ */ -+struct drm_vc4_wait_bo { -+ uint32_t handle; -+ uint32_t pad; -+ uint64_t timeout_ns; -+}; -+ -+/** -+ * struct drm_vc4_create_bo - ioctl argument for creating VC4 BOs. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_create_bo { -+ uint32_t size; -+ uint32_t flags; -+ /** Returned GEM handle for the BO. */ -+ uint32_t handle; -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_create_shader_bo - ioctl argument for creating VC4 -+ * shader BOs. -+ * -+ * Since allowing a shader to be overwritten while it's also being -+ * executed from would allow privlege escalation, shaders must be -+ * created using this ioctl, and they can't be mmapped later. -+ */ -+struct drm_vc4_create_shader_bo { -+ /* Size of the data argument. */ -+ uint32_t size; -+ /* Flags, currently must be 0. */ -+ uint32_t flags; -+ -+ /* Pointer to the data. */ -+ uint64_t data; -+ -+ /** Returned GEM handle for the BO. */ -+ uint32_t handle; -+ /* Pad, must be 0. */ -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -+ * -+ * This doesn't actually perform an mmap. Instead, it returns the -+ * offset you need to use in an mmap on the DRM device node. This -+ * means that tools like valgrind end up knowing about the mapped -+ * memory. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_mmap_bo { -+ /** Handle for the object being mapped. */ -+ uint32_t handle; -+ uint32_t flags; -+ /** offset into the drm node to use for subsequent mmap call. */ -+ uint64_t offset; -+}; -+ -+#endif /* _UAPI_VC4_DRM_H_ */ - -From 666602424fba993b28229ce2133ff8d2a16b248e Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 14 Oct 2015 11:32:14 -0700 -Subject: [PATCH 087/251] drm/vc4: Force HDMI to connected. - -For some reason on the downstream tree, the HPD GPIO isn't working. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c -index da9a36d..d15c529 100644 ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -164,6 +164,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) - struct drm_device *dev = connector->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - -+ return connector_status_connected; -+ - if (vc4->hdmi->hpd_gpio) { - if (gpio_get_value(vc4->hdmi->hpd_gpio)) - return connector_status_connected; - -From 83244506ffc629eb672d74f1e075d25188b4d081 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:23:18 -0700 -Subject: [PATCH 088/251] drm/vc4: bo cache locking fixes. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 32 ++++++++++++++++++-------------- - drivers/gpu/drm/vc4/vc4_drv.h | 2 +- - 2 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index bfa605f..af0fde6 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -112,14 +112,14 @@ void vc4_bo_cache_purge(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - } - - struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -@@ -134,18 +134,18 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - return NULL; - - /* First, try to get a vc4_bo from the kernel BO cache. */ -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - if (page_index < vc4->bo_cache.size_list_size && - !list_empty(&vc4->bo_cache.size_list[page_index])) { - struct vc4_bo *bo = - list_first_entry(&vc4->bo_cache.size_list[page_index], - struct vc4_bo, size_head); - vc4_bo_remove_from_cache(bo); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - kref_init(&bo->base.base.refcount); - return bo; - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - /* Otherwise, make a new BO. */ - for (pass = 0; ; pass++) { -@@ -215,7 +215,7 @@ vc4_bo_cache_free_old(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); -@@ -223,14 +223,14 @@ vc4_bo_cache_free_old(struct drm_device *dev) - mod_timer(&vc4->bo_cache.time_timer, - round_jiffies_up(jiffies + - msecs_to_jiffies(1000))); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - return; - } - - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - } - - /* Called on the last userspace/kernel unreference of the BO. Returns -@@ -248,21 +248,25 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - /* If the object references someone else's memory, we can't cache it. - */ - if (gem_bo->import_attach) { -+ mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -+ mutex_unlock(&vc4->bo_lock); - return; - } - - /* Don't cache if it was publicly named. */ - if (gem_bo->name) { -+ mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -+ mutex_unlock(&vc4->bo_lock); - return; - } - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); - if (!cache_list) { - vc4_bo_destroy(bo); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - return; - } - -@@ -278,7 +282,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - - vc4->bo_stats.num_cached++; - vc4->bo_stats.size_cached += gem_bo->size; -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - vc4_bo_cache_free_old(dev); - } -@@ -465,7 +469,7 @@ void vc4_bo_cache_init(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- spin_lock_init(&vc4->bo_lock); -+ mutex_init(&vc4->bo_lock); - - INIT_LIST_HEAD(&vc4->bo_cache.time_list); - -@@ -498,9 +502,9 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_bo_stats stats; - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - stats = vc4->bo_stats; -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); - seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 8cc89d1..c079b82 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -49,7 +49,7 @@ struct vc4_dev { - } bo_stats; - - /* Protects bo_cache and the BO stats. */ -- spinlock_t bo_lock; -+ struct mutex bo_lock; - - /* Sequence number for the last job queued in job_list. - * Starts at 0 (no jobs emitted). - -From 149b9d3feccb3fcc379d91cacc35fa8e6ce59dd1 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:29:41 -0700 -Subject: [PATCH 089/251] drm/vc4: bo cache locking cleanup. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index af0fde6..acd360c 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -215,7 +215,6 @@ vc4_bo_cache_free_old(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); - -- mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); -@@ -223,14 +222,12 @@ vc4_bo_cache_free_old(struct drm_device *dev) - mod_timer(&vc4->bo_cache.time_timer, - round_jiffies_up(jiffies + - msecs_to_jiffies(1000))); -- mutex_unlock(&vc4->bo_lock); - return; - } - - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- mutex_unlock(&vc4->bo_lock); - } - - /* Called on the last userspace/kernel unreference of the BO. Returns -@@ -245,29 +242,24 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - struct vc4_bo *bo = to_vc4_bo(gem_bo); - struct list_head *cache_list; - -+ mutex_lock(&vc4->bo_lock); - /* If the object references someone else's memory, we can't cache it. - */ - if (gem_bo->import_attach) { -- mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - - /* Don't cache if it was publicly named. */ - if (gem_bo->name) { -- mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - -- mutex_lock(&vc4->bo_lock); - cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); - if (!cache_list) { - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - - if (bo->validated_shader) { -@@ -282,9 +274,11 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - - vc4->bo_stats.num_cached++; - vc4->bo_stats.size_cached += gem_bo->size; -- mutex_unlock(&vc4->bo_lock); - - vc4_bo_cache_free_old(dev); -+ -+out: -+ mutex_unlock(&vc4->bo_lock); - } - - static void vc4_bo_cache_time_work(struct work_struct *work) -@@ -293,7 +287,9 @@ static void vc4_bo_cache_time_work(struct work_struct *work) - container_of(work, struct vc4_dev, bo_cache.time_work); - struct drm_device *dev = vc4->dev; - -+ mutex_lock(&vc4->bo_lock); - vc4_bo_cache_free_old(dev); -+ mutex_unlock(&vc4->bo_lock); - } - - static void vc4_bo_cache_time_timer(unsigned long data) - -From 7a42f6a5addb1961f016f14ef9010bdc19565a77 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:32:24 -0700 -Subject: [PATCH 090/251] drm/vc4: Use job_lock to protect seqno_cb_list. - -We're (mostly) not supposed to be using struct_mutex in drivers these -days. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 361390b..b1853b2 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -474,7 +474,6 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - vc4_complete_exec(exec); - spin_lock_irqsave(&vc4->job_lock, irqflags); - } -- spin_unlock_irqrestore(&vc4->job_lock, irqflags); - - list_for_each_entry_safe(cb, cb_temp, &vc4->seqno_cb_list, work.entry) { - if (cb->seqno <= vc4->finished_seqno) { -@@ -482,6 +481,8 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - schedule_work(&cb->work); - } - } -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); - } - - static void vc4_seqno_cb_work(struct work_struct *work) -@@ -496,18 +497,19 @@ int vc4_queue_seqno_cb(struct drm_device *dev, - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret = 0; -+ unsigned long irqflags; - - cb->func = func; - INIT_WORK(&cb->work, vc4_seqno_cb_work); - -- mutex_lock(&dev->struct_mutex); -+ spin_lock_irqsave(&vc4->job_lock, irqflags); - if (seqno > vc4->finished_seqno) { - cb->seqno = seqno; - list_add_tail(&cb->work.entry, &vc4->seqno_cb_list); - } else { - schedule_work(&cb->work); - } -- mutex_unlock(&dev->struct_mutex); -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); - - return ret; - } - -From bf31c306877aef83b109356b8471a69590d0a915 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:44:35 -0700 -Subject: [PATCH 091/251] drm/vc4: Drop struct_mutex around CL validation. - -We were using it so that we could make sure that shader validation -state didn't change while we were validating, but now shader -validation state is immutable. The bcl/rcl generation doesn't do any -other BO dereferencing, and seems to have no other global state -dependency not covered by job_lock / bo_lock. - -Fixes a lock order reversal between mmap_sem and struct_mutex. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index b1853b2..32f375a 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -244,13 +244,15 @@ static void - vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -- uint64_t seqno = ++vc4->emit_seqno; -+ uint64_t seqno; - unsigned long irqflags; - -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ -+ seqno = ++vc4->emit_seqno; - exec->seqno = seqno; - vc4_update_bo_seqnos(exec, seqno); - -- spin_lock_irqsave(&vc4->job_lock, irqflags); - list_add_tail(&exec->head, &vc4->job_list); - - /* If no job was executing, kick ours off. Otherwise, it'll -@@ -608,8 +610,6 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - exec->args = args; - INIT_LIST_HEAD(&exec->unref_list); - -- mutex_lock(&dev->struct_mutex); -- - ret = vc4_cl_lookup_bos(dev, file_priv, exec); - if (ret) - goto fail; -@@ -636,15 +636,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - /* Return the seqno for our job. */ - args->seqno = vc4->emit_seqno; - -- mutex_unlock(&dev->struct_mutex); -- - return 0; - - fail: - vc4_complete_exec(exec); - -- mutex_unlock(&dev->struct_mutex); -- - return ret; - } - - -From 90604ba9389fd34efcd5c4266fd9d4604f1543e4 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:44:35 -0700 -Subject: [PATCH 092/251] drm/vc4: Drop struct_mutex around CL validation. - -We were using it so that we could make sure that shader validation -state didn't change while we were validating, but now shader -validation state is immutable. The bcl/rcl generation doesn't do any -other BO dereferencing, and seems to have no other global state -dependency not covered by job_lock / bo_lock. We only need to hold -struct_mutex for object unreferencing. - -Fixes a lock order reversal between mmap_sem and struct_mutex. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 32f375a..55551ea 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -439,10 +439,12 @@ fail: - } - - static void --vc4_complete_exec(struct vc4_exec_info *exec) -+vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) - { - unsigned i; - -+ /* Need the struct lock for drm_gem_object_unreference(). */ -+ mutex_lock(&dev->struct_mutex); - if (exec->bo) { - for (i = 0; i < exec->bo_count; i++) - drm_gem_object_unreference(&exec->bo[i].bo->base); -@@ -455,6 +457,7 @@ vc4_complete_exec(struct vc4_exec_info *exec) - list_del(&bo->unref_head); - drm_gem_object_unreference(&bo->base.base); - } -+ mutex_unlock(&dev->struct_mutex); - - kfree(exec); - } -@@ -473,7 +476,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - list_del(&exec->head); - - spin_unlock_irqrestore(&vc4->job_lock, irqflags); -- vc4_complete_exec(exec); -+ vc4_complete_exec(vc4->dev, exec); - spin_lock_irqsave(&vc4->job_lock, irqflags); - } - -@@ -525,12 +528,8 @@ vc4_job_done_work(struct work_struct *work) - { - struct vc4_dev *vc4 = - container_of(work, struct vc4_dev, job_done_work); -- struct drm_device *dev = vc4->dev; - -- /* Need the struct lock for drm_gem_object_unreference(). */ -- mutex_lock(&dev->struct_mutex); - vc4_job_handle_completed(vc4); -- mutex_unlock(&dev->struct_mutex); - } - - static int -@@ -639,7 +638,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - return 0; - - fail: -- vc4_complete_exec(exec); -+ vc4_complete_exec(vc4->dev, exec); - - return ret; - } - -From dcdfacf7cbb2ad8feb6c11326919b7482b2ac3cd Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 20 Oct 2015 13:59:15 +0100 -Subject: [PATCH 093/251] drm/vc4: Add support for more display plane formats. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_plane.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c -index 65e5455..0f85eb5 100644 ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -59,6 +59,22 @@ static const struct hvs_format { - .drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, - }, -+ { -+ .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, -+ .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, -+ }, -+ { -+ .drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565, -+ .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false, -+ }, -+ { -+ .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, -+ .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, -+ }, -+ { -+ .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, -+ .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, -+ }, - }; - - static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) - -From 4f981196d46dcd9576c87c957b15acc0a68dcca8 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 12:31:56 +0100 -Subject: [PATCH 094/251] drm/vc4: No need to stop the stopped threads. - -This was leftover debug code from the hackdriver. We never submit -unless the thread is already idle. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 55551ea..eeb0925 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -104,10 +104,6 @@ submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- /* Stop any existing thread and set state to "stopped at halt" */ -- V3D_WRITE(V3D_CTNCS(thread), V3D_CTRUN); -- barrier(); -- - V3D_WRITE(V3D_CTNCA(thread), start); - barrier(); - - -From adb820489d061187ae01daa98ab1a404dbe5cd86 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 12:33:43 +0100 -Subject: [PATCH 095/251] drm/vc4: Remove extra barrier()s aroudn CTnCA/CTnEA - setup. - -The writel() that these expand to already does barriers. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index eeb0925..0cea723 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -104,14 +104,11 @@ submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- V3D_WRITE(V3D_CTNCA(thread), start); -- barrier(); -- -- /* Set the end address of the control list. Writing this -- * register is what starts the job. -+ /* Set the current and end address of the control list. -+ * Writing the end register is what starts the job. - */ -+ V3D_WRITE(V3D_CTNCA(thread), start); - V3D_WRITE(V3D_CTNEA(thread), end); -- barrier(); - } - - int - -From 90058bcf1d4a588a3ddba5e78e1f998a33d2d5b1 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 14:57:22 +0100 -Subject: [PATCH 096/251] drm/vc4: Fix a typo in a V3D debug register. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_regs.h | 2 +- - drivers/gpu/drm/vc4/vc4_v3d.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h -index 9e4e904..4e52a0a 100644 ---- a/drivers/gpu/drm/vc4/vc4_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_regs.h -@@ -154,7 +154,7 @@ - #define V3D_PCTRS14 0x006f4 - #define V3D_PCTR15 0x006f8 - #define V3D_PCTRS15 0x006fc --#define V3D_BGE 0x00f00 -+#define V3D_DBGE 0x00f00 - #define V3D_FDBGO 0x00f04 - #define V3D_FDBGB 0x00f08 - #define V3D_FDBGR 0x00f0c -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index b9cb7cf..cf35f58 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -99,7 +99,7 @@ static const struct { - REGDEF(V3D_PCTRS14), - REGDEF(V3D_PCTR15), - REGDEF(V3D_PCTRS15), -- REGDEF(V3D_BGE), -+ REGDEF(V3D_DBGE), - REGDEF(V3D_FDBGO), - REGDEF(V3D_FDBGB), - REGDEF(V3D_FDBGR), - -From fa03eea2a7fd499bd9254430e4396cf91aa96d39 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 2 Nov 2015 17:07:33 +0000 -Subject: [PATCH 097/251] drm/vc4: Enable VC4 modules, and increase CMA size - with overlay - -If using the overlay, be careful not to boot to GUI or run startx, -or the Pi will almost hang, reporting stalls in kernel threads. ---- - arch/arm/boot/dts/overlays/README | 8 ++ - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 95 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - 4 files changed, 107 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d7f2979..1fa98ce 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -601,6 +601,14 @@ Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: vc4-kms-v3d -+Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. Running startx or -+ booting to GUI while this overlay is in use will cause interesting -+ lockups. -+Load: dtoverlay=vc4-kms-v3d -+Params: -+ -+ - Name: vga666 - Info: Overlay for the Fen Logic VGA666 board - This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds -diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -new file mode 100644 -index 0000000..cf5d5c9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -0,0 +1,95 @@ -+/* -+ * vc4-kms-v3d-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include "dt-bindings/clock/bcm2835.h" -+#include "dt-bindings/gpio/gpio.h" -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2c2>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&cprman>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&fb>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ pixelvalve@7e206000 { -+ compatible = "brcm,bcm2835-pixelvalve0"; -+ reg = <0x7e206000 0x100>; -+ interrupts = <2 13>; /* pwa0 */ -+ }; -+ -+ pixelvalve@7e207000 { -+ compatible = "brcm,bcm2835-pixelvalve1"; -+ reg = <0x7e207000 0x100>; -+ interrupts = <2 14>; /* pwa1 */ -+ }; -+ -+ hvs@7e400000 { -+ compatible = "brcm,bcm2835-hvs"; -+ reg = <0x7e400000 0x6000>; -+ interrupts = <2 1>; -+ }; -+ -+ pixelvalve@7e807000 { -+ compatible = "brcm,bcm2835-pixelvalve2"; -+ reg = <0x7e807000 0x100>; -+ interrupts = <2 10>; /* pixelvalve */ -+ }; -+ -+ hdmi@7e902000 { -+ compatible = "brcm,bcm2835-hdmi"; -+ reg = <0x7e902000 0x600>, -+ <0x7e808000 0x100>; -+ interrupts = <2 8>, <2 9>; -+ ddc = <&i2c2>; -+ hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>; -+ clocks = <&cprman BCM2835_PLLH_PIX>, -+ <&cprman BCM2835_CLOCK_HSM>; -+ clock-names = "pixel", "hdmi"; -+ }; -+ -+ v3d@7ec00000 { -+ compatible = "brcm,vc4-v3d"; -+ reg = <0x7ec00000 0x1000>; -+ interrupts = <1 10>; -+ }; -+ -+ gpu@7e4c0000 { -+ compatible = "brcm,bcm2835-vc4"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target-path = "/chosen"; -+ __overlay__ { -+ bootargs = "cma=256M@512M"; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 13999af..4e474c7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -802,6 +802,8 @@ CONFIG_VIDEO_TW9903=m - CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m -+CONFIG_DRM=m -+CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 146add9..d6aa058 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -795,6 +795,8 @@ CONFIG_VIDEO_TW9903=m - CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m -+CONFIG_DRM=m -+CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m - -From de2afd5a8db4a62e65057ace15fe15b498074dff Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Nov 2015 18:29:58 +0000 -Subject: [PATCH 098/251] squash: fixups - ---- - drivers/gpu/drm/vc4/Kconfig | 2 +- - drivers/gpu/drm/vc4/vc4_drv.c | 2 +- - drivers/gpu/drm/vc4/vc4_kms.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig -index 2d7d115..71f019f 100644 ---- a/drivers/gpu/drm/vc4/Kconfig -+++ b/drivers/gpu/drm/vc4/Kconfig -@@ -1,6 +1,6 @@ - config DRM_VC4 - tristate "Broadcom VC4 Graphics" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on DRM && HAVE_DMA_ATTRS - select DRM_KMS_HELPER - select DRM_KMS_CMA_HELPER -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index 3baf1fc..e2a2be2 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -127,7 +127,7 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -- .gem_obj_size = sizeof(struct vc4_bo), -+ //.gem_obj_size = sizeof(struct vc4_bo), - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index c83287a..2082713 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -45,7 +45,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c) - - drm_atomic_helper_commit_modeset_disables(dev, state); - -- drm_atomic_helper_commit_planes(dev, state); -+ drm_atomic_helper_commit_planes(dev, state, false); - - drm_atomic_helper_commit_modeset_enables(dev, state); - - -From 454534cc445c73a8d95814b1bf8e2ef67f3c4f41 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Nov 2015 20:26:03 +0000 -Subject: [PATCH 099/251] squash: add missing vc4-kms-v3d-overlay.dtb to - makefile - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index fb7ac49..fc09bfb 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -52,6 +52,7 @@ dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vc4-kms-v3d-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -From 971c63d209cdcdeec8eba9211e9f75add0c6b10b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 12 Oct 2015 11:23:34 -0700 -Subject: [PATCH 100/251] clk: bcm2835: Also build the driver for downstream - kernels. - -Signed-off-by: Eric Anholt ---- - drivers/clk/bcm/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index 3fc9506..a1b4cbc 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -3,7 +3,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o --obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o -+obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o - -From 64297bcfecf13b8fa1939fc725b772875157b0a4 Mon Sep 17 00:00:00 2001 -From: Holger Steinhaus -Date: Sat, 14 Nov 2015 18:37:43 +0100 -Subject: [PATCH 101/251] dts: Added overlay for gpio_ir_recv driver - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 18 ++++++++++- - arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 45 ++++++++++++++++++++++++++ - 3 files changed, 63 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index fc09bfb..ebc3354 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,7 @@ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1fa98ce..b4578cc 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -196,6 +196,22 @@ Params: int_pin GPIO used for INT (default 25) - speed SPI bus speed (default 12000000) - - -+Name: gpio-ir -+Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- -+ based gpio_ir_recv driver maps received keys directly to a -+ /dev/input/event* device, all decoding is done by the kernel - LIRC is -+ not required! The key mapping and other decoding parameters can be -+ configured by "ir-keytable" tool. -+Load: dtoverlay=gpio-ir,= -+Params: gpio_pin Input pin number. Default is 18. -+ -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "down". -+ -+ rc-map-name Default rc keymap (can also be changed by -+ ir-keytable), defaults to "rc-rc6-mce" -+ -+ - Name: gpio-poweroff - Info: Drives a GPIO high or low on reboot - Load: dtoverlay=gpio-poweroff,= -@@ -308,7 +324,7 @@ Params: - Name: lirc-rpi - Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) - Consult the module documentation for more details. --Load: dtoverlay=lirc-rpi,=,... -+Load: dtoverlay=lirc-rpi,= - Params: gpio_out_pin GPIO for output (default "17") - - gpio_in_pin GPIO for input (default "18") -diff --git a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -new file mode 100644 -index 0000000..a2d6bc7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -@@ -0,0 +1,45 @@ -+// Definitions for ir-gpio module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ gpio_ir: ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ -+ // pin number, high or low -+ gpios = <&gpio 18 1>; -+ -+ // parameter for keymap name -+ linux,rc-map-name = "rc-rc6-mce"; -+ -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ gpio_ir_pins: gpio_ir_pins { -+ brcm,pins = <18>; // pin 18 -+ brcm,function = <0>; // in -+ brcm,pull = <1>; // down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ // parameters -+ gpio_pin = <&gpio_ir>,"gpios:4", -+ <&gpio_ir_pins>,"brcm,pins:0", -+ <&gpio_ir_pins>,"brcm,pull:0"; // pin number -+ gpio_pull = <&gpio_ir_pins>,"brcm,pull:0"; // pull-up/down state -+ -+ rc-map-name = <&gpio_ir>,"linux,rc-map-name"; // default rc map -+ }; -+}; - -From 1cb2b31fb379d569dd28ef81a69b04e748aa0a7e Mon Sep 17 00:00:00 2001 -From: Alistair Buxton -Date: Sun, 1 Nov 2015 22:27:56 +0000 -Subject: [PATCH 102/251] Build i2c_gpio module and add a device tree overlay - to configure it. - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 13 +++++++++++- - arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 28 +++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 43 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index ebc3354..e15d55c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b4578cc..9362443 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -287,9 +287,20 @@ Params: speed Display SPI bus speed - ledgpio GPIO used to control backlight - - -+Name: i2c-gpio -+Info: Adds support for software i2c controller on gpio pins -+Load: dtoverlay=i2c-gpio,= -+Params: i2c_gpio_sda GPIO used for I2C data (default "23") -+ -+ i2c_gpio_scl GPIO used for I2C clock (default "24") -+ -+ i2c_gpio_delay_us Clock delay in microseconds -+ (default "2" = ~100kHz) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices --Load: dtoverlay=i2c-rtc, -+Load: dtoverlay=i2c-rtc,= - Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device -diff --git a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -new file mode 100644 -index 0000000..2a2dc98 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -@@ -0,0 +1,28 @@ -+// Overlay for i2c_gpio bitbanging host bus. -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ i2c_gpio: i2c@0 { -+ compatible = "i2c-gpio"; -+ gpios = <&gpio 23 0 /* sda */ -+ &gpio 24 0 /* scl */ -+ >; -+ i2c-gpio,delay-us = <2>; /* ~100 kHz */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; -+ i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; -+ i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; -+ }; -+}; -+ -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 4e474c7..fc35254 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -595,6 +595,7 @@ CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m -+CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_SPIDEV=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index d6aa058..51dc019 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -588,6 +588,7 @@ CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m -+CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_SPIDEV=y - -From d8810f6aa46773aab926661593de341c6bd77cae Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Sun, 18 Oct 2015 17:07:24 -0700 -Subject: [PATCH 103/251] New overlay for PiScreen2r - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 +++ - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 100 ++++++++++++++++++++++ - 3 files changed, 115 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index e15d55c..8595b14 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9362443..0a21248 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -425,6 +425,20 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: piscreen2r -+Info: PiScreen 2 with resistive TP display by OzzMaker.com -+Load: dtoverlay=piscreen2r,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -new file mode 100644 -index 0000000..7c018e0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -0,0 +1,100 @@ -+ /* -+ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen2_pins: piscreen2_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen2: piscreen2@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen2_pins>; -+ bgr; -+ spi-max-frequency = <64000000>; -+ rotate = <90>; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ txbuflen = <32768>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c0 0x11 0x09 -+ 0x10000c1 0x41 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000b6 0x00 0x02 -+ 0x10000f7 0xa9 0x51 0x2c 0x2 -+ 0x10000be 0x00 0x04 -+ 0x10000e9 0x00 -+ 0x1000011 -+ 0x1000029>; -+ -+ }; -+ -+ piscreen2_ts: piscreen2-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen2>,"spi-max-frequency:0"; -+ rotate = <&piscreen2>,"rotate:0"; -+ fps = <&piscreen2>,"fps:0"; -+ debug = <&piscreen2>,"debug:0"; -+ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -+ - -From f2812d3b0fa2cda5f79e89235222c787bce2adac Mon Sep 17 00:00:00 2001 -From: Ondrej Wisniewski -Date: Fri, 6 Nov 2015 15:01:28 +0100 -Subject: [PATCH 104/251] dts: Added overlay for Adafruit PiTFT 2.8" capacitive - touch screen - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 22 ++++++ - .../dts/overlays/pitft28-capacitive-overlay.dts | 88 ++++++++++++++++++++++ - 3 files changed, 111 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 8595b14..7d747bc 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -36,6 +36,7 @@ dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0a21248..422a0d4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -439,6 +439,28 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: pitft28-capacitive -+Info: Adafruit PiTFT 2.8" capacitive touch screen -+Load: dtoverlay=pitft28-capacitive,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ touch-sizex Touchscreen size x (default 240) -+ -+ touch-sizey Touchscreen size y (default 320) -+ -+ touch-invx Touchscreen inverted x axis -+ -+ touch-invy Touchscreen inverted y axis -+ -+ touch-swapxy Touchscreen swapped x y axis -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -new file mode 100644 -index 0000000..48920e9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -@@ -0,0 +1,88 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ft6236: ft6236@38 { -+ compatible = "focaltech,ft6236"; -+ reg = <0x38>; -+ -+ interrupt-parent = <&gpio>; -+ interrupts = <24 2>; -+ touchscreen-size-x = <240>; -+ touchscreen-size-y = <320>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ touch-sizex = <&ft6236>,"touchscreen-size-x?"; -+ touch-sizey = <&ft6236>,"touchscreen-size-y?"; -+ touch-invx = <&ft6236>,"touchscreen-inverted-x?"; -+ touch-invy = <&ft6236>,"touchscreen-inverted-y?"; -+ touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?"; -+ }; -+}; - -From bc31b90ccadb0bfeaefbe40b460be9e7fa20b7f2 Mon Sep 17 00:00:00 2001 -From: Stuart MacLean -Date: Fri, 2 Oct 2015 15:12:59 +0100 -Subject: [PATCH 105/251] Add support for the HiFiBerry DAC+ Pro. - -The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. - -An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. ---- - .../dts/overlays/hifiberry-dacplus-overlay.dts | 15 +- - drivers/clk/Makefile | 1 + - drivers/clk/clk-hifiberry-dacpro.c | 160 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 244 +++++++++++++++++++-- - sound/soc/codecs/pcm512x.c | 3 +- - 5 files changed, 396 insertions(+), 27 deletions(-) - create mode 100644 drivers/clk/clk-hifiberry-dacpro.c - -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index deb9c62..f923a48 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -6,6 +6,16 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -+ target-path = "/clocks"; -+ __overlay__ { -+ dacpro_osc: dacpro_osc { -+ compatible = "hifiberry,dacpro-clk"; -+ #clock-cells = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { - target = <&sound>; - __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; -@@ -14,14 +24,14 @@ - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&i2s>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -32,6 +42,7 @@ - #sound-dai-cells = <0>; - compatible = "ti,pcm5122"; - reg = <0x4d>; -+ clocks = <&dacpro_osc>; - status = "okay"; - }; - }; -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index 820714c..94ccf03 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o - obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o - obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o - obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o - obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o - obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o - obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c -new file mode 100644 -index 0000000..3e35d45 ---- /dev/null -+++ b/drivers/clk/clk-hifiberry-dacpro.c -@@ -0,0 +1,160 @@ -+/* -+ * Clock Driver for HiFiBerry DAC Pro -+ * -+ * Author: Stuart MacLean -+ * Copyright 2015 -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+/** -+ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro -+ * @hw: clk_hw for the common clk framework -+ * @mode: 0 => CLK44EN, 1 => CLK48EN -+ */ -+struct clk_hifiberry_hw { -+ struct clk_hw hw; -+ uint8_t mode; -+}; -+ -+#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) -+ -+static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { -+ { .compatible = "hifiberry,dacpro-clk",}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); -+ -+static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : -+ CLK_48EN_RATE; -+} -+ -+static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long *parent_rate) -+{ -+ long actual_rate; -+ -+ if (rate <= CLK_44EN_RATE) { -+ actual_rate = (long)CLK_44EN_RATE; -+ } else if (rate >= CLK_48EN_RATE) { -+ actual_rate = (long)CLK_48EN_RATE; -+ } else { -+ long diff44Rate = (long)(rate - CLK_44EN_RATE); -+ long diff48Rate = (long)(CLK_48EN_RATE - rate); -+ -+ if (diff44Rate < diff48Rate) -+ actual_rate = (long)CLK_44EN_RATE; -+ else -+ actual_rate = (long)CLK_48EN_RATE; -+ } -+ return actual_rate; -+} -+ -+ -+static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ unsigned long actual_rate; -+ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); -+ -+ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, -+ &parent_rate); -+ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; -+ return 0; -+} -+ -+ -+const struct clk_ops clk_hifiberry_dacpro_rate_ops = { -+ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, -+ .round_rate = clk_hifiberry_dacpro_round_rate, -+ .set_rate = clk_hifiberry_dacpro_set_rate, -+}; -+ -+static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct clk_hifiberry_hw *proclk; -+ struct clk *clk; -+ struct device *dev; -+ struct clk_init_data init; -+ -+ dev = &pdev->dev; -+ -+ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); -+ if (!proclk) -+ return -ENOMEM; -+ -+ init.name = "clk-hifiberry-dacpro"; -+ init.ops = &clk_hifiberry_dacpro_rate_ops; -+ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; -+ init.parent_names = NULL; -+ init.num_parents = 0; -+ -+ proclk->mode = 0; -+ proclk->hw.init = &init; -+ -+ clk = devm_clk_register(dev, &proclk->hw); -+ if (!IS_ERR(clk)) { -+ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -+ clk); -+ } else { -+ dev_err(dev, "Fail to register clock driver\n"); -+ kfree(proclk); -+ ret = PTR_ERR(clk); -+ } -+ return ret; -+} -+ -+static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) -+{ -+ of_clk_del_provider(pdev->dev.of_node); -+ return 0; -+} -+ -+static struct platform_driver clk_hifiberry_dacpro_driver = { -+ .probe = clk_hifiberry_dacpro_probe, -+ .remove = clk_hifiberry_dacpro_remove, -+ .driver = { -+ .name = "clk-hifiberry-dacpro", -+ .of_match_table = clk_hifiberry_dacpro_dt_ids, -+ }, -+}; -+ -+static int __init clk_hifiberry_dacpro_init(void) -+{ -+ return platform_driver_register(&clk_hifiberry_dacpro_driver); -+} -+core_initcall(clk_hifiberry_dacpro_init); -+ -+static void __exit clk_hifiberry_dacpro_exit(void) -+{ -+ platform_driver_unregister(&clk_hifiberry_dacpro_driver); -+} -+module_exit(clk_hifiberry_dacpro_exit); -+ -+MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:clk-hifiberry-dacpro"); -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 11e4f39..a6b651c 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -1,8 +1,8 @@ - /* -- * ASoC Driver for HiFiBerry DAC+ -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro - * -- * Author: Daniel Matuschek -- * Copyright 2014 -+ * Author: Daniel Matuschek, Stuart MacLean -+ * Copyright 2014-2015 - * based on code by Florian Meier - * - * This program is free software; you can redistribute it and/or -@@ -17,6 +17,13 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #include - #include -@@ -26,34 +33,222 @@ - - #include "../codecs/pcm512x.h" - -+#define HIFIBERRY_DACPRO_NOCLOCK 0 -+#define HIFIBERRY_DACPRO_CLK44EN 1 -+#define HIFIBERRY_DACPRO_CLK48EN 2 -+ -+struct pcm512x_priv { -+ struct regmap *regmap; -+ struct clk *sclk; -+}; -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+static bool snd_rpi_hifiberry_is_dacpro; -+ -+static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, -+ int clk_id) -+{ -+ switch (clk_id) { -+ case HIFIBERRY_DACPRO_NOCLOCK: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); -+ break; -+ case HIFIBERRY_DACPRO_CLK44EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); -+ break; -+ case HIFIBERRY_DACPRO_CLK48EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); -+ break; -+ } -+} -+ -+static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) -+{ -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) -+{ -+ int sck; -+ -+ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); -+ return (!(sck & 0x40)); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( -+ struct snd_soc_codec *codec) -+{ -+ msleep(2); -+ return snd_rpi_hifiberry_dacplus_is_sclk(codec); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) -+{ -+ bool isClk44EN, isClk48En, isNoClk; -+ -+ snd_rpi_hifiberry_dacplus_clk_gpio(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); -+ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); -+ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); -+ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ return (isClk44EN && isClk48En && !isNoClk); -+} -+ -+static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) -+{ -+ int type; -+ -+ switch (sample_rate) { -+ case 11025: -+ case 22050: -+ case 44100: -+ case 88200: -+ case 176400: -+ type = HIFIBERRY_DACPRO_CLK44EN; -+ break; -+ default: -+ type = HIFIBERRY_DACPRO_CLK48EN; -+ break; -+ } -+ return type; -+} -+ -+static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, -+ int sample_rate) -+{ -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ -+ if (!IS_ERR(pcm512x->sclk)) { -+ int ctype; -+ -+ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); -+ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) -+ ? CLK_44EN_RATE : CLK_48EN_RATE); -+ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); -+ } -+} -+ - static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - { - struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *priv; -+ -+ snd_rpi_hifiberry_is_dacpro -+ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_dai_link *dai = rtd->dai_link; -+ -+ dai->name = "HiFiBerry DAC+ Pro"; -+ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBM_CFM; -+ -+ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); -+ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); -+ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); -+ } else { -+ priv = snd_soc_codec_get_drvdata(codec); -+ priv->sclk = ERR_PTR(-ENOENT); -+ } -+ - snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -- snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_update_rate_den( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ struct snd_ratnum *rats_no_pll; -+ unsigned int num = 0, den = 0; -+ int err; -+ -+ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); -+ if (!rats_no_pll) -+ return -ENOMEM; -+ -+ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; -+ rats_no_pll->den_min = 1; -+ rats_no_pll->den_max = 128; -+ rats_no_pll->den_step = 1; -+ -+ err = snd_interval_ratnum(hw_param_interval(params, -+ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); -+ if (err >= 0 && den) { -+ params->rate_num = num; -+ params->rate_den = den; -+ } -+ -+ devm_kfree(rtd->dev, rats_no_pll); - return 0; - } - --static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params) -+static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( -+ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) - { -+ int bratio = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ snd_rpi_hifiberry_dacplus_set_sclk(codec, -+ params_rate(params)); -+ -+ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, -+ params); -+ if (!ret) -+ ret = snd_rpi_hifiberry_dacplus_update_rate_den( -+ substream, params); -+ } else { -+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ } -+ return ret; - } - --static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+static int snd_rpi_hifiberry_dacplus_startup( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - return 0; - } - --static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+static void snd_rpi_hifiberry_dacplus_shutdown( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); - } - - /* machine stream operations */ -@@ -90,19 +285,20 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -- - if (pdev->dev.of_node) { -- struct device_node *i2s_node; -- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -- i2s_node = of_parse_phandle(pdev->dev.of_node, -- "i2s-controller", 0); -- -- if (i2s_node) { -- dai->cpu_dai_name = NULL; -- dai->cpu_of_node = i2s_node; -- dai->platform_name = NULL; -- dai->platform_of_node = i2s_node; -- } -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c -index 047c489..090fe0e 100644 ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -854,7 +854,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, - int fssp; - int gpio; - -- lrclk_div = snd_soc_params_to_frame_size(params); -+ lrclk_div = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); - if (lrclk_div == 0) { - dev_err(dev, "No LRCLK?\n"); - return -EINVAL; - -From 0ef9ae2d5aba6fea2fe0520a24296a8fa4b858e5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 5 Oct 2015 10:47:45 +0100 -Subject: [PATCH 106/251] BCM270X_DT: Add at86rf233 overlay - -Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 21 +++++++-- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 54 ++++++++++++++++++++++++ - 3 files changed, 72 insertions(+), 4 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 7d747bc..be9dead 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 422a0d4..d0ef256 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -69,13 +69,14 @@ DT parameters: - - Parameters always have default values, although in some cases (e.g. "w1-gpio") - it is necessary to provided multiple overlays in order to get the desired --behaviour. See the list of overlays below for a description of the parameters and their defaults. -+behaviour. See the list of overlays below for a description of the parameters -+and their defaults. - - The Overlay and Parameter Reference - =================================== - --N.B. When editing this file, please preserve the indentation levels to make it simple to parse --programmatically. NO HARD TABS. -+N.B. When editing this file, please preserve the indentation levels to make it -+simple to parse programmatically. NO HARD TABS. - - - Name: -@@ -149,7 +150,7 @@ Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= - Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) - penirq GPIO used for PENIRQ. REQUIRED - penirq_pull Set GPIO pull (default 0=none, 2=pullup) - swapxy Swap x and y axis -@@ -170,6 +171,18 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: at86rf233 -+Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, -+ connected to spi0.0 -+Load: dtoverlay=at86rf233,= -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 6000000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) -+ -+ - Name: bmp085_i2c-sensor - Info: Configures the BMP085/BMP180 digital barometric pressure and temperature - sensors from Bosch Sensortec -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -new file mode 100644 -index 0000000..0460269 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -0,0 +1,54 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ lowpan0: at86rf233@0 { -+ compatible = "atmel,at86rf233"; -+ reg = <0>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 4>; /* active high */ -+ reset-gpio = <&gpio 24 1>; -+ sleep-gpio = <&gpio 25 1>; -+ spi-max-frequency = <6000000>; -+ xtal-trim = /bits/ 8 <0xf>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lowpan0_pins: lowpan0_pins { -+ brcm,pins = <23 24 25>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&lowpan0>, "interrupts:0", -+ <&lowpan0_pins>, "brcm,pins:0"; -+ reset = <&lowpan0>, "reset-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:4"; -+ sleep = <&lowpan0>, "sleep-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:8"; -+ speed = <&lowpan0>, "spi-max-frequency:0"; -+ trim = <&lowpan0>, "xtal-trim.0"; -+ }; -+}; - -From 45d717abcc94edabe07e5909f1d984a392198921 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 18 Dec 2014 16:07:15 -0800 -Subject: [PATCH 107/251] mm: Remove the PFN busy warning - -See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is -expected sometimes when using CMA. However, that commit still spams -my kernel log with these warnings. - -Signed-off-by: Eric Anholt ---- - mm/page_alloc.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index c69531a..dc484d3 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -6780,8 +6780,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, - - /* Make sure the range is really isolated. */ - if (test_pages_isolated(outer_start, end, false)) { -- pr_info("%s: [%lx, %lx) PFNs busy\n", -- __func__, outer_start, end); - ret = -EBUSY; - goto done; - } - -From 11a46a37a0da7f87fc9e278178f294047110f6ab Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 19 Nov 2014 12:06:38 -0800 -Subject: [PATCH 108/251] drm: Put an optional field in the driver struct for - GEM obj struct size. - -This allows a driver to derive from the CMA object without copying all -of the code. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_gem_cma_helper.c | 5 ++++- - include/drm/drmP.h | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index e109b49..1c25500 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -58,8 +58,11 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size) - struct drm_gem_cma_object *cma_obj; - struct drm_gem_object *gem_obj; - int ret; -+ size_t obj_size = (drm->driver->gem_obj_size ? -+ drm->driver->gem_obj_size : -+ sizeof(*cma_obj)); - -- cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); -+ cma_obj = kzalloc(obj_size, GFP_KERNEL); - if (!cma_obj) - return ERR_PTR(-ENOMEM); - -diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 0a271ca..54f5469 100644 ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -639,6 +639,7 @@ struct drm_driver { - - u32 driver_features; - int dev_priv_size; -+ size_t gem_obj_size; - const struct drm_ioctl_desc *ioctls; - int num_ioctls; - const struct file_operations *fops; - -From b28efa9d1051537449004db1bfaf083429144d1b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 30 Oct 2015 10:09:02 -0700 -Subject: [PATCH 109/251] drm/vc4: Add an interface for capturing the GPU state - after a hang. - -This can be parsed with vc4-gpu-tools tools for trying to figure out -what was going on. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 4 +- - drivers/gpu/drm/vc4/vc4_drv.c | 1 + - drivers/gpu/drm/vc4/vc4_drv.h | 4 + - drivers/gpu/drm/vc4/vc4_gem.c | 185 ++++++++++++++++++++++++++++++++++++++++++ - include/uapi/drm/vc4_drm.h | 45 ++++++++++ - 5 files changed, 237 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index acd360c..58dcbae 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -415,8 +415,8 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma) - gem_obj = vma->vm_private_data; - bo = to_vc4_bo(gem_obj); - -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); - return -EINVAL; - } - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index e2a2be2..e8192b4 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -81,6 +81,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, DRM_ROOT_ONLY), - }; - - static struct drm_driver vc4_drm_driver = { -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index c079b82..24845c1 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -20,6 +20,8 @@ struct vc4_dev { - struct drm_fbdev_cma *fbdev; - struct rpi_firmware *firmware; - -+ struct vc4_hang_state *hang_state; -+ - /* The kernel-space BO cache. Tracks buffers that have been - * unreferenced by all other users (refcounts of 0!) but not - * yet freed, so we can do cheap allocations. -@@ -366,6 +368,8 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -+int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); - int vc4_mmap(struct file *filp, struct vm_area_struct *vma); - int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); - void *vc4_prime_vmap(struct drm_gem_object *obj); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 0cea723..d90c664 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -40,6 +40,186 @@ vc4_queue_hangcheck(struct drm_device *dev) - round_jiffies_up(jiffies + msecs_to_jiffies(100))); - } - -+struct vc4_hang_state { -+ struct drm_vc4_get_hang_state user_state; -+ -+ u32 bo_count; -+ struct drm_gem_object **bo; -+}; -+ -+static void -+vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) -+{ -+ unsigned int i; -+ -+ mutex_lock(&dev->struct_mutex); -+ for (i = 0; i < state->user_state.bo_count; i++) { -+ drm_gem_object_unreference(state->bo[i]); -+ } -+ mutex_unlock(&dev->struct_mutex); -+ -+ kfree(state); -+} -+ -+int -+vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_get_hang_state *get_state = data; -+ struct drm_vc4_get_hang_state_bo *bo_state; -+ struct vc4_hang_state *kernel_state; -+ struct drm_vc4_get_hang_state *state; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long irqflags; -+ u32 i; -+ int ret; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ kernel_state = vc4->hang_state; -+ if (!kernel_state) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return -ENOENT; -+ } -+ state = &kernel_state->user_state; -+ -+ /* If the user's array isn't big enough, just return the -+ * required array size. -+ */ -+ if (get_state->bo_count < state->bo_count) { -+ get_state->bo_count = state->bo_count; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return 0; -+ } -+ -+ vc4->hang_state = NULL; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ /* Save the user's BO pointer, so we don't stomp it with the memcpy. */ -+ state->bo = get_state->bo; -+ memcpy(get_state, state, sizeof(*state)); -+ -+ bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL); -+ if (!bo_state) { -+ ret = -ENOMEM; -+ goto err_free; -+ } -+ -+ for (i = 0; i < state->bo_count; i++) { -+ struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]); -+ u32 handle; -+ ret = drm_gem_handle_create(file_priv, kernel_state->bo[i], -+ &handle); -+ -+ if (ret) { -+ state->bo_count = i - 1; -+ goto err; -+ } -+ bo_state[i].handle = handle; -+ bo_state[i].paddr = vc4_bo->base.paddr; -+ bo_state[i].size = vc4_bo->base.base.size; -+ } -+ -+ ret = copy_to_user((void __user *)(uintptr_t)get_state->bo, -+ bo_state, -+ state->bo_count * sizeof(*bo_state)); -+ kfree(bo_state); -+ -+ err_free: -+ -+ vc4_free_hang_state(dev, kernel_state); -+ -+err: -+ return ret; -+} -+ -+static void -+vc4_save_hang_state(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_vc4_get_hang_state *state; -+ struct vc4_hang_state *kernel_state; -+ struct vc4_exec_info *exec; -+ struct vc4_bo *bo; -+ unsigned long irqflags; -+ unsigned int i, unref_list_count; -+ -+ kernel_state = kcalloc(1, sizeof(*state), GFP_KERNEL); -+ if (!kernel_state) -+ return; -+ -+ state = &kernel_state->user_state; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ exec = vc4_first_job(vc4); -+ if (!exec) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return; -+ } -+ -+ unref_list_count = 0; -+ list_for_each_entry(bo, &exec->unref_list, unref_head) -+ unref_list_count++; -+ -+ state->bo_count = exec->bo_count + unref_list_count; -+ kernel_state->bo = kcalloc(state->bo_count, sizeof(*kernel_state->bo), -+ GFP_ATOMIC); -+ if (!kernel_state->bo) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return; -+ } -+ -+ for (i = 0; i < exec->bo_count; i++) { -+ drm_gem_object_reference(&exec->bo[i].bo->base); -+ kernel_state->bo[i] = &exec->bo[i].bo->base; -+ } -+ -+ list_for_each_entry(bo, &exec->unref_list, unref_head) { -+ drm_gem_object_reference(&bo->base.base); -+ kernel_state->bo[i] = &bo->base.base; -+ i++; -+ } -+ -+ state->start_bin = exec->ct0ca; -+ state->start_render = exec->ct1ca; -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ state->ct0ca = V3D_READ(V3D_CTNCA(0)); -+ state->ct0ea = V3D_READ(V3D_CTNEA(0)); -+ -+ state->ct1ca = V3D_READ(V3D_CTNCA(1)); -+ state->ct1ea = V3D_READ(V3D_CTNEA(1)); -+ -+ state->ct0cs = V3D_READ(V3D_CTNCS(0)); -+ state->ct1cs = V3D_READ(V3D_CTNCS(1)); -+ -+ state->ct0ra0 = V3D_READ(V3D_CT00RA0); -+ state->ct1ra0 = V3D_READ(V3D_CT01RA0); -+ -+ state->bpca = V3D_READ(V3D_BPCA); -+ state->bpcs = V3D_READ(V3D_BPCS); -+ state->bpoa = V3D_READ(V3D_BPOA); -+ state->bpos = V3D_READ(V3D_BPOS); -+ -+ state->vpmbase = V3D_READ(V3D_VPMBASE); -+ -+ state->dbge = V3D_READ(V3D_DBGE); -+ state->fdbgo = V3D_READ(V3D_FDBGO); -+ state->fdbgb = V3D_READ(V3D_FDBGB); -+ state->fdbgr = V3D_READ(V3D_FDBGR); -+ state->fdbgs = V3D_READ(V3D_FDBGS); -+ state->errstat = V3D_READ(V3D_ERRSTAT); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ if (vc4->hang_state) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ vc4_free_hang_state(dev, kernel_state); -+ } else { -+ vc4->hang_state = kernel_state; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ } -+} -+ - static void - vc4_reset(struct drm_device *dev) - { -@@ -64,6 +244,8 @@ vc4_reset_work(struct work_struct *work) - struct vc4_dev *vc4 = - container_of(work, struct vc4_dev, hangcheck.reset_work); - -+ vc4_save_hang_state(vc4->dev); -+ - vc4_reset(vc4->dev); - } - -@@ -673,4 +855,7 @@ vc4_gem_destroy(struct drm_device *dev) - } - - vc4_bo_cache_destroy(dev); -+ -+ if (vc4->hang_state) -+ vc4_free_hang_state(dev, vc4->hang_state); - } -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 499daae..4a8d19f 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -32,6 +32,7 @@ - #define DRM_VC4_CREATE_BO 0x03 - #define DRM_VC4_MMAP_BO 0x04 - #define DRM_VC4_CREATE_SHADER_BO 0x05 -+#define DRM_VC4_GET_HANG_STATE 0x06 - - #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) - #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -@@ -39,6 +40,7 @@ - #define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) - #define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) - #define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) - - struct drm_vc4_submit_rcl_surface { - uint32_t hindex; /* Handle index, or ~0 if not present. */ -@@ -226,4 +228,47 @@ struct drm_vc4_mmap_bo { - uint64_t offset; - }; - -+struct drm_vc4_get_hang_state_bo { -+ uint32_t handle; -+ uint32_t paddr; -+ uint32_t size; -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_hang_state - ioctl argument for collecting state -+ * from a GPU hang for analysis. -+*/ -+struct drm_vc4_get_hang_state { -+ /** Pointer to array of struct drm_vc4_get_hang_state_bo. */ -+ uint64_t bo; -+ /** -+ * On input, the size of the bo array. Output is the number -+ * of bos to be returned. -+ */ -+ uint32_t bo_count; -+ -+ uint32_t start_bin, start_render; -+ -+ uint32_t ct0ca, ct0ea; -+ uint32_t ct1ca, ct1ea; -+ uint32_t ct0cs, ct1cs; -+ uint32_t ct0ra0, ct1ra0; -+ -+ uint32_t bpca, bpcs; -+ uint32_t bpoa, bpos; -+ -+ uint32_t vpmbase; -+ -+ uint32_t dbge; -+ uint32_t fdbgo; -+ uint32_t fdbgb; -+ uint32_t fdbgr; -+ uint32_t fdbgs; -+ uint32_t errstat; -+ -+ /* Pad that we may save more registers into in the future. */ -+ uint32_t pad[16]; -+}; -+ - #endif /* _UAPI_VC4_DRM_H_ */ - -From 341ad4b0afa7154311296be071b39f42f18fe228 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 4 Dec 2015 11:35:34 -0800 -Subject: [PATCH 110/251] drm/vc4: Update a bunch of code to match upstream - submission. - -This gets almost everything matching, except for the MSAA support and -using generic PM domains. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_gem_cma_helper.c | 13 +- - drivers/gpu/drm/vc4/vc4_bo.c | 322 +++++++++++++++++------------ - drivers/gpu/drm/vc4/vc4_crtc.c | 7 +- - drivers/gpu/drm/vc4/vc4_drv.c | 6 +- - drivers/gpu/drm/vc4/vc4_drv.h | 20 +- - drivers/gpu/drm/vc4/vc4_gem.c | 24 ++- - drivers/gpu/drm/vc4/vc4_irq.c | 5 +- - drivers/gpu/drm/vc4/vc4_kms.c | 1 + - drivers/gpu/drm/vc4/vc4_packet.h | 210 +++++++++---------- - drivers/gpu/drm/vc4/vc4_qpu_defines.h | 308 ++++++++++++++------------- - drivers/gpu/drm/vc4/vc4_render_cl.c | 4 +- - drivers/gpu/drm/vc4/vc4_v3d.c | 10 +- - drivers/gpu/drm/vc4/vc4_validate.c | 130 ++++++------ - drivers/gpu/drm/vc4/vc4_validate_shaders.c | 66 +++--- - include/drm/drmP.h | 8 +- - 15 files changed, 598 insertions(+), 536 deletions(-) - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index 1c25500..0f7b00b 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -58,15 +58,14 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size) - struct drm_gem_cma_object *cma_obj; - struct drm_gem_object *gem_obj; - int ret; -- size_t obj_size = (drm->driver->gem_obj_size ? -- drm->driver->gem_obj_size : -- sizeof(*cma_obj)); - -- cma_obj = kzalloc(obj_size, GFP_KERNEL); -- if (!cma_obj) -+ if (drm->driver->gem_create_object) -+ gem_obj = drm->driver->gem_create_object(drm, size); -+ else -+ gem_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); -+ if (!gem_obj) - return ERR_PTR(-ENOMEM); -- -- gem_obj = &cma_obj->base; -+ cma_obj = container_of(gem_obj, struct drm_gem_cma_object, base); - - ret = drm_gem_object_init(drm, gem_obj, size); - if (ret) -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index 58dcbae..6247ff8 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -12,6 +12,10 @@ - * access to system memory with no MMU in between. To support it, we - * use the GEM CMA helper functions to allocate contiguous ranges of - * physical memory for our BOs. -+ * -+ * Since the CMA allocator is very slow, we keep a cache of recently -+ * freed BOs around so that the kernel's allocation of objects for 3D -+ * rendering can return quickly. - */ - - #include "vc4_drv.h" -@@ -34,6 +38,36 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4) - vc4->bo_stats.size_cached / 1024); - } - -+#ifdef CONFIG_DEBUG_FS -+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *)m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo_stats stats; -+ -+ /* Take a snapshot of the current stats with the lock held. */ -+ mutex_lock(&vc4->bo_lock); -+ stats = vc4->bo_stats; -+ mutex_unlock(&vc4->bo_lock); -+ -+ seq_printf(m, "num bos allocated: %d\n", -+ stats.num_allocated); -+ seq_printf(m, "size bos allocated: %dkb\n", -+ stats.size_allocated / 1024); -+ seq_printf(m, "num bos used: %d\n", -+ stats.num_allocated - stats.num_cached); -+ seq_printf(m, "size bos used: %dkb\n", -+ (stats.size_allocated - stats.size_cached) / 1024); -+ seq_printf(m, "num bos cached: %d\n", -+ stats.num_cached); -+ seq_printf(m, "size bos cached: %dkb\n", -+ stats.size_cached / 1024); -+ -+ return 0; -+} -+#endif -+ - static uint32_t bo_page_index(size_t size) - { - return (size / PAGE_SIZE) - 1; -@@ -81,8 +115,8 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, - struct list_head *new_list; - uint32_t i; - -- new_list = kmalloc(new_size * sizeof(struct list_head), -- GFP_KERNEL); -+ new_list = kmalloc_array(new_size, sizeof(struct list_head), -+ GFP_KERNEL); - if (!new_list) - return NULL; - -@@ -90,7 +124,9 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, - * head locations. - */ - for (i = 0; i < vc4->bo_cache.size_list_size; i++) { -- struct list_head *old_list = &vc4->bo_cache.size_list[i]; -+ struct list_head *old_list = -+ &vc4->bo_cache.size_list[i]; -+ - if (list_empty(old_list)) - INIT_LIST_HEAD(&new_list[i]); - else -@@ -122,11 +158,60 @@ void vc4_bo_cache_purge(struct drm_device *dev) - mutex_unlock(&vc4->bo_lock); - } - --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -+static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev, -+ uint32_t size) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -- uint32_t size = roundup(unaligned_size, PAGE_SIZE); - uint32_t page_index = bo_page_index(size); -+ struct vc4_bo *bo = NULL; -+ -+ size = roundup(size, PAGE_SIZE); -+ -+ mutex_lock(&vc4->bo_lock); -+ if (page_index >= vc4->bo_cache.size_list_size) -+ goto out; -+ -+ if (list_empty(&vc4->bo_cache.size_list[page_index])) -+ goto out; -+ -+ bo = list_first_entry(&vc4->bo_cache.size_list[page_index], -+ struct vc4_bo, size_head); -+ vc4_bo_remove_from_cache(bo); -+ kref_init(&bo->base.base.refcount); -+ -+out: -+ mutex_unlock(&vc4->bo_lock); -+ return bo; -+} -+ -+/** -+ * vc4_gem_create_object - Implementation of driver->gem_create_object. -+ * -+ * This lets the CMA helpers allocate object structs for us, and keep -+ * our BO stats correct. -+ */ -+struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo *bo; -+ -+ bo = kzalloc(sizeof(*bo), GFP_KERNEL); -+ if (!bo) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_lock(&vc4->bo_lock); -+ vc4->bo_stats.num_allocated++; -+ vc4->bo_stats.size_allocated += size; -+ mutex_unlock(&vc4->bo_lock); -+ -+ return &bo->base.base; -+} -+ -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, -+ bool from_cache) -+{ -+ size_t size = roundup(unaligned_size, PAGE_SIZE); -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_gem_cma_object *cma_obj; - int pass; - -@@ -134,18 +219,12 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - return NULL; - - /* First, try to get a vc4_bo from the kernel BO cache. */ -- mutex_lock(&vc4->bo_lock); -- if (page_index < vc4->bo_cache.size_list_size && -- !list_empty(&vc4->bo_cache.size_list[page_index])) { -- struct vc4_bo *bo = -- list_first_entry(&vc4->bo_cache.size_list[page_index], -- struct vc4_bo, size_head); -- vc4_bo_remove_from_cache(bo); -- mutex_unlock(&vc4->bo_lock); -- kref_init(&bo->base.base.refcount); -- return bo; -+ if (from_cache) { -+ struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size); -+ -+ if (bo) -+ return bo; - } -- mutex_unlock(&vc4->bo_lock); - - /* Otherwise, make a new BO. */ - for (pass = 0; ; pass++) { -@@ -179,9 +258,6 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - } - } - -- vc4->bo_stats.num_allocated++; -- vc4->bo_stats.size_allocated += size; -- - return to_vc4_bo(&cma_obj->base); - } - -@@ -199,7 +275,7 @@ int vc4_dumb_create(struct drm_file *file_priv, - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; - -- bo = vc4_bo_create(dev, args->size); -+ bo = vc4_bo_create(dev, args->size, false); - if (!bo) - return -ENOMEM; - -@@ -209,8 +285,8 @@ int vc4_dumb_create(struct drm_file *file_priv, - return ret; - } - --static void --vc4_bo_cache_free_old(struct drm_device *dev) -+/* Must be called with bo_lock held. */ -+static void vc4_bo_cache_free_old(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); -@@ -313,15 +389,77 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) - return drm_gem_prime_export(dev, obj, flags); - } - --int --vc4_create_bo_ioctl(struct drm_device *dev, void *data, -- struct drm_file *file_priv) -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ int ret; -+ -+ ret = drm_gem_mmap(filp, vma); -+ if (ret) -+ return ret; -+ -+ gem_obj = vma->vm_private_data; -+ bo = to_vc4_bo(gem_obj); -+ -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -+ * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -+ * the whole buffer. -+ */ -+ vma->vm_flags &= ~VM_PFNMAP; -+ vma->vm_pgoff = 0; -+ -+ ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -+ bo->base.vaddr, bo->base.paddr, -+ vma->vm_end - vma->vm_start); -+ if (ret) -+ drm_gem_vm_close(vma); -+ -+ return ret; -+} -+ -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ return drm_gem_cma_prime_mmap(obj, vma); -+} -+ -+void *vc4_prime_vmap(struct drm_gem_object *obj) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_cma_prime_vmap(obj); -+} -+ -+int vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) - { - struct drm_vc4_create_bo *args = data; - struct vc4_bo *bo = NULL; - int ret; - -- bo = vc4_bo_create(dev, args->size); -+ /* -+ * We can't allocate from the BO cache, because the BOs don't -+ * get zeroed, and that might leak data between users. -+ */ -+ bo = vc4_bo_create(dev, args->size, false); - if (!bo) - return -ENOMEM; - -@@ -331,6 +469,25 @@ vc4_create_bo_ioctl(struct drm_device *dev, void *data, - return ret; - } - -+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_mmap_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ -+ /* The mmap offset was set up at BO allocation time. */ -+ args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -+ -+ drm_gem_object_unreference_unlocked(gem_obj); -+ return 0; -+} -+ - int - vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -@@ -355,7 +512,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - return -EINVAL; - } - -- bo = vc4_bo_create(dev, args->size); -+ bo = vc4_bo_create(dev, args->size, true); - if (!bo) - return -ENOMEM; - -@@ -364,6 +521,11 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - args->size); - if (ret != 0) - goto fail; -+ /* Clear the rest of the memory from allocating from the BO -+ * cache. -+ */ -+ memset(bo->base.vaddr + args->size, 0, -+ bo->base.base.size - args->size); - - bo->validated_shader = vc4_validate_shader(&bo->base); - if (!bo->validated_shader) { -@@ -382,85 +544,6 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - return ret; - } - --int --vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -- struct drm_file *file_priv) --{ -- struct drm_vc4_mmap_bo *args = data; -- struct drm_gem_object *gem_obj; -- -- gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -- if (!gem_obj) { -- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -- return -EINVAL; -- } -- -- /* The mmap offset was set up at BO allocation time. */ -- args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -- -- drm_gem_object_unreference(gem_obj); -- return 0; --} -- --int vc4_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- struct drm_gem_object *gem_obj; -- struct vc4_bo *bo; -- int ret; -- -- ret = drm_gem_mmap(filp, vma); -- if (ret) -- return ret; -- -- gem_obj = vma->vm_private_data; -- bo = to_vc4_bo(gem_obj); -- -- if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -- return -EINVAL; -- } -- -- /* -- * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -- * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -- * the whole buffer. -- */ -- vma->vm_flags &= ~VM_PFNMAP; -- vma->vm_pgoff = 0; -- -- ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -- bo->base.vaddr, bo->base.paddr, -- vma->vm_end - vma->vm_start); -- if (ret) -- drm_gem_vm_close(vma); -- -- return ret; --} -- --int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) --{ -- struct vc4_bo *bo = to_vc4_bo(obj); -- -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -- return -EINVAL; -- } -- -- return drm_gem_cma_prime_mmap(obj, vma); --} -- --void *vc4_prime_vmap(struct drm_gem_object *obj) --{ -- struct vc4_bo *bo = to_vc4_bo(obj); -- -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -- return ERR_PTR(-EINVAL); -- } -- -- return drm_gem_cma_prime_vmap(obj); --} -- - void vc4_bo_cache_init(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -@@ -472,7 +555,7 @@ void vc4_bo_cache_init(struct drm_device *dev) - INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); - setup_timer(&vc4->bo_cache.time_timer, - vc4_bo_cache_time_timer, -- (unsigned long) dev); -+ (unsigned long)dev); - } - - void vc4_bo_cache_destroy(struct drm_device *dev) -@@ -489,28 +572,3 @@ void vc4_bo_cache_destroy(struct drm_device *dev) - vc4_bo_stats_dump(vc4); - } - } -- --#ifdef CONFIG_DEBUG_FS --int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct vc4_bo_stats stats; -- -- mutex_lock(&vc4->bo_lock); -- stats = vc4->bo_stats; -- mutex_unlock(&vc4->bo_lock); -- -- seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); -- seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -- seq_printf(m, "num bos used: %d\n", (stats.num_allocated - -- stats.num_cached)); -- seq_printf(m, "size bos used: %dkb\n", (stats.size_allocated - -- stats.size_cached) / 1024); -- seq_printf(m, "num bos cached: %d\n", stats.num_cached); -- seq_printf(m, "size bos cached: %dkb\n", stats.size_cached / 1024); -- -- return 0; --} --#endif -diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c -index 3be2720..3c67914 100644 ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -501,6 +501,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) - vc4_plane_async_set_fb(plane, flip_state->fb); - if (flip_state->event) { - unsigned long flags; -+ - spin_lock_irqsave(&dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, flip_state->event); - spin_unlock_irqrestore(&dev->event_lock, flags); -@@ -562,9 +563,9 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, - } - - static int vc4_page_flip(struct drm_crtc *crtc, -- struct drm_framebuffer *fb, -- struct drm_pending_vblank_event *event, -- uint32_t flags) -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) - { - if (flags & DRM_MODE_PAGE_FLIP_ASYNC) - return vc4_async_page_flip(crtc, fb, event, flags); -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index e8192b4..22061ae 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -81,7 +81,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), -- DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, DRM_ROOT_ONLY), -+ DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, -+ DRM_ROOT_ONLY), - }; - - static struct drm_driver vc4_drm_driver = { -@@ -107,6 +108,7 @@ static struct drm_driver vc4_drm_driver = { - .debugfs_cleanup = vc4_debugfs_cleanup, - #endif - -+ .gem_create_object = vc4_create_object, - .gem_free_object = vc4_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - -@@ -128,8 +130,6 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -- //.gem_obj_size = sizeof(struct vc4_bo), -- - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 24845c1..53dfa8d 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -72,6 +72,9 @@ struct vc4_dev { - * job_done_work. - */ - struct list_head job_done_list; -+ /* Spinlock used to synchronize the job_list and seqno -+ * accesses between the IRQ handler and GEM ioctls. -+ */ - spinlock_t job_lock; - wait_queue_head_t job_wait_queue; - struct work_struct job_done_work; -@@ -318,8 +321,7 @@ struct vc4_texture_sample_info { - * and validate the shader state record's uniforms that define the texture - * samples. - */ --struct vc4_validated_shader_info --{ -+struct vc4_validated_shader_info { - uint32_t uniforms_size; - uint32_t uniforms_src_size; - uint32_t num_texture_samples; -@@ -355,8 +357,10 @@ struct vc4_validated_shader_info - #define wait_for(COND, MS) _wait_for(COND, MS, 1) - - /* vc4_bo.c */ -+struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); - void vc4_free_object(struct drm_gem_object *gem_obj); --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size); -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, -+ bool from_cache); - int vc4_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); -@@ -432,7 +436,8 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, - enum drm_plane_type type); - u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); - u32 vc4_plane_dlist_size(struct drm_plane_state *state); --void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb); -+void vc4_plane_async_set_fb(struct drm_plane *plane, -+ struct drm_framebuffer *fb); - - /* vc4_v3d.c */ - extern struct platform_driver vc4_v3d_driver; -@@ -450,9 +455,6 @@ vc4_validate_bin_cl(struct drm_device *dev, - int - vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); - --struct vc4_validated_shader_info * --vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -- - bool vc4_use_bo(struct vc4_exec_info *exec, - uint32_t hindex, - enum vc4_bo_mode mode, -@@ -464,3 +466,7 @@ bool vc4_check_tex_size(struct vc4_exec_info *exec, - struct drm_gem_cma_object *fbo, - uint32_t offset, uint8_t tiling_format, - uint32_t width, uint32_t height, uint8_t cpp); -+ -+/* vc4_validate_shader.c */ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index d90c664..fb0b92d 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -53,9 +53,8 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) - unsigned int i; - - mutex_lock(&dev->struct_mutex); -- for (i = 0; i < state->user_state.bo_count; i++) { -+ for (i = 0; i < state->user_state.bo_count; i++) - drm_gem_object_unreference(state->bo[i]); -- } - mutex_unlock(&dev->struct_mutex); - - kfree(state); -@@ -65,10 +64,10 @@ int - vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -- struct drm_vc4_get_hang_state *get_state = data; -+ struct drm_vc4_get_hang_state *get_state = data; - struct drm_vc4_get_hang_state_bo *bo_state; - struct vc4_hang_state *kernel_state; -- struct drm_vc4_get_hang_state *state; -+ struct drm_vc4_get_hang_state *state; - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long irqflags; - u32 i; -@@ -107,6 +106,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - for (i = 0; i < state->bo_count; i++) { - struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]); - u32 handle; -+ - ret = drm_gem_handle_create(file_priv, kernel_state->bo[i], - &handle); - -@@ -124,7 +124,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - state->bo_count * sizeof(*bo_state)); - kfree(bo_state); - -- err_free: -+err_free: - - vc4_free_hang_state(dev, kernel_state); - -@@ -578,7 +578,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - goto fail; - } - -- bo = vc4_bo_create(dev, exec_size); -+ bo = vc4_bo_create(dev, exec_size, true); - if (!bo) { - DRM_ERROR("Couldn't allocate BO for binning\n"); - ret = PTR_ERR(exec->exec_bo); -@@ -668,6 +668,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - static void vc4_seqno_cb_work(struct work_struct *work) - { - struct vc4_seqno_cb *cb = container_of(work, struct vc4_seqno_cb, work); -+ - cb->func(cb); - } - -@@ -717,6 +718,7 @@ vc4_wait_for_seqno_ioctl_helper(struct drm_device *dev, - - if ((ret == -EINTR || ret == -ERESTARTSYS) && *timeout_ns != ~0ull) { - uint64_t delta = jiffies_to_nsecs(jiffies - start); -+ - if (*timeout_ns >= delta) - *timeout_ns -= delta; - } -@@ -750,9 +752,10 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, - } - bo = to_vc4_bo(gem_obj); - -- ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, &args->timeout_ns); -+ ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, -+ &args->timeout_ns); - -- drm_gem_object_unreference(gem_obj); -+ drm_gem_object_unreference_unlocked(gem_obj); - return ret; - } - -@@ -793,7 +796,8 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - if (ret) - goto fail; - } else { -- exec->ct0ca = exec->ct0ea = 0; -+ exec->ct0ca = 0; -+ exec->ct0ea = 0; - } - - ret = vc4_get_rcl(dev, exec); -@@ -831,7 +835,7 @@ vc4_gem_init(struct drm_device *dev) - INIT_WORK(&vc4->hangcheck.reset_work, vc4_reset_work); - setup_timer(&vc4->hangcheck.timer, - vc4_hangcheck_elapsed, -- (unsigned long) dev); -+ (unsigned long)dev); - - INIT_WORK(&vc4->job_done_work, vc4_job_done_work); - } -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -index f29b796..b68060e 100644 ---- a/drivers/gpu/drm/vc4/vc4_irq.c -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -56,7 +56,7 @@ vc4_overflow_mem_work(struct work_struct *work) - struct drm_device *dev = vc4->dev; - struct vc4_bo *bo; - -- bo = vc4_bo_create(dev, 256 * 1024); -+ bo = vc4_bo_create(dev, 256 * 1024, true); - if (!bo) { - DRM_ERROR("Couldn't allocate binner overflow mem\n"); - return; -@@ -87,9 +87,8 @@ vc4_overflow_mem_work(struct work_struct *work) - spin_unlock_irqrestore(&vc4->job_lock, irqflags); - } - -- if (vc4->overflow_mem) { -+ if (vc4->overflow_mem) - drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -- } - vc4->overflow_mem = bo; - - V3D_WRITE(V3D_BPOA, bo->base.paddr); -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index 2082713..f95f2df 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -132,6 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev, - struct drm_gem_cma_object *cma_bo = - drm_fb_cma_get_gem_obj(new_state->fb, 0); - struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ - wait_seqno = max(bo->seqno, wait_seqno); - } - } -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -index 9757bc8..cee38aa 100644 ---- a/drivers/gpu/drm/vc4/vc4_packet.h -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -27,60 +27,60 @@ - #include "vc4_regs.h" /* for VC4_MASK, VC4_GET_FIELD, VC4_SET_FIELD */ - - enum vc4_packet { -- VC4_PACKET_HALT = 0, -- VC4_PACKET_NOP = 1, -- -- VC4_PACKET_FLUSH = 4, -- VC4_PACKET_FLUSH_ALL = 5, -- VC4_PACKET_START_TILE_BINNING = 6, -- VC4_PACKET_INCREMENT_SEMAPHORE = 7, -- VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -- -- VC4_PACKET_BRANCH = 16, -- VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -- -- VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -- VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -- VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -- VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -- VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -- VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -- -- VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -- VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -- -- VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -- VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -- -- VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -- -- VC4_PACKET_GL_SHADER_STATE = 64, -- VC4_PACKET_NV_SHADER_STATE = 65, -- VC4_PACKET_VG_SHADER_STATE = 66, -- -- VC4_PACKET_CONFIGURATION_BITS = 96, -- VC4_PACKET_FLAT_SHADE_FLAGS = 97, -- VC4_PACKET_POINT_SIZE = 98, -- VC4_PACKET_LINE_WIDTH = 99, -- VC4_PACKET_RHT_X_BOUNDARY = 100, -- VC4_PACKET_DEPTH_OFFSET = 101, -- VC4_PACKET_CLIP_WINDOW = 102, -- VC4_PACKET_VIEWPORT_OFFSET = 103, -- VC4_PACKET_Z_CLIPPING = 104, -- VC4_PACKET_CLIPPER_XY_SCALING = 105, -- VC4_PACKET_CLIPPER_Z_SCALING = 106, -- -- VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -- VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -- VC4_PACKET_CLEAR_COLORS = 114, -- VC4_PACKET_TILE_COORDINATES = 115, -- -- /* Not an actual hardware packet -- this is what we use to put -- * references to GEM bos in the command stream, since we need the u32 -- * int the actual address packet in order to store the offset from the -- * start of the BO. -- */ -- VC4_PACKET_GEM_HANDLES = 254, -+ VC4_PACKET_HALT = 0, -+ VC4_PACKET_NOP = 1, -+ -+ VC4_PACKET_FLUSH = 4, -+ VC4_PACKET_FLUSH_ALL = 5, -+ VC4_PACKET_START_TILE_BINNING = 6, -+ VC4_PACKET_INCREMENT_SEMAPHORE = 7, -+ VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -+ -+ VC4_PACKET_BRANCH = 16, -+ VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -+ -+ VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -+ VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -+ VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -+ VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -+ VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -+ -+ VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -+ VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -+ -+ VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -+ VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -+ -+ VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -+ -+ VC4_PACKET_GL_SHADER_STATE = 64, -+ VC4_PACKET_NV_SHADER_STATE = 65, -+ VC4_PACKET_VG_SHADER_STATE = 66, -+ -+ VC4_PACKET_CONFIGURATION_BITS = 96, -+ VC4_PACKET_FLAT_SHADE_FLAGS = 97, -+ VC4_PACKET_POINT_SIZE = 98, -+ VC4_PACKET_LINE_WIDTH = 99, -+ VC4_PACKET_RHT_X_BOUNDARY = 100, -+ VC4_PACKET_DEPTH_OFFSET = 101, -+ VC4_PACKET_CLIP_WINDOW = 102, -+ VC4_PACKET_VIEWPORT_OFFSET = 103, -+ VC4_PACKET_Z_CLIPPING = 104, -+ VC4_PACKET_CLIPPER_XY_SCALING = 105, -+ VC4_PACKET_CLIPPER_Z_SCALING = 106, -+ -+ VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -+ VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -+ VC4_PACKET_CLEAR_COLORS = 114, -+ VC4_PACKET_TILE_COORDINATES = 115, -+ -+ /* Not an actual hardware packet -- this is what we use to put -+ * references to GEM bos in the command stream, since we need the u32 -+ * int the actual address packet in order to store the offset from the -+ * start of the BO. -+ */ -+ VC4_PACKET_GEM_HANDLES = 254, - } __attribute__ ((__packed__)); - - #define VC4_PACKET_HALT_SIZE 1 -@@ -148,10 +148,10 @@ enum vc4_packet { - * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address) - */ - --#define VC4_LOADSTORE_TILE_BUFFER_EOF (1 << 3) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS (1 << 1) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR (1 << 0) -+#define VC4_LOADSTORE_TILE_BUFFER_EOF BIT(3) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK BIT(2) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS BIT(1) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR BIT(0) - - /** @} */ - -@@ -160,10 +160,10 @@ enum vc4_packet { - * byte 0-1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and - * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL - */ --#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 15) --#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR (1 << 14) --#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR (1 << 13) --#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP (1 << 12) -+#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR BIT(15) -+#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR BIT(14) -+#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR BIT(13) -+#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP BIT(12) - - #define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK VC4_MASK(9, 8) - #define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT 8 -@@ -201,28 +201,28 @@ enum vc4_packet { - #define VC4_INDEX_BUFFER_U16 (1 << 4) - - /* This flag is only present in NV shader state. */ --#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS (1 << 3) --#define VC4_SHADER_FLAG_ENABLE_CLIPPING (1 << 2) --#define VC4_SHADER_FLAG_VS_POINT_SIZE (1 << 1) --#define VC4_SHADER_FLAG_FS_SINGLE_THREAD (1 << 0) -+#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS BIT(3) -+#define VC4_SHADER_FLAG_ENABLE_CLIPPING BIT(2) -+#define VC4_SHADER_FLAG_VS_POINT_SIZE BIT(1) -+#define VC4_SHADER_FLAG_FS_SINGLE_THREAD BIT(0) - - /** @{ byte 2 of config bits. */ --#define VC4_CONFIG_BITS_EARLY_Z_UPDATE (1 << 1) --#define VC4_CONFIG_BITS_EARLY_Z (1 << 0) -+#define VC4_CONFIG_BITS_EARLY_Z_UPDATE BIT(1) -+#define VC4_CONFIG_BITS_EARLY_Z BIT(0) - /** @} */ - - /** @{ byte 1 of config bits. */ --#define VC4_CONFIG_BITS_Z_UPDATE (1 << 7) -+#define VC4_CONFIG_BITS_Z_UPDATE BIT(7) - /** same values in this 3-bit field as PIPE_FUNC_* */ - #define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT 4 --#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE (1 << 3) -+#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE BIT(3) - - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO (0 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD (1 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR (2 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO (3 << 1) - --#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT (1 << 0) -+#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT BIT(0) - /** @} */ - - /** @{ byte 0 of config bits. */ -@@ -230,15 +230,15 @@ enum vc4_packet { - #define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X (1 << 6) - #define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X (2 << 6) - --#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES (1 << 4) --#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET (1 << 3) --#define VC4_CONFIG_BITS_CW_PRIMITIVES (1 << 2) --#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK (1 << 1) --#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT (1 << 0) -+#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES BIT(4) -+#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET BIT(3) -+#define VC4_CONFIG_BITS_CW_PRIMITIVES BIT(2) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK BIT(1) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT BIT(0) - /** @} */ - - /** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */ --#define VC4_BIN_CONFIG_DB_NON_MS (1 << 7) -+#define VC4_BIN_CONFIG_DB_NON_MS BIT(7) - - #define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK VC4_MASK(6, 5) - #define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_SHIFT 5 -@@ -254,17 +254,17 @@ enum vc4_packet { - #define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128 2 - #define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256 3 - --#define VC4_BIN_CONFIG_AUTO_INIT_TSDA (1 << 2) --#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT (1 << 1) --#define VC4_BIN_CONFIG_MS_MODE_4X (1 << 0) -+#define VC4_BIN_CONFIG_AUTO_INIT_TSDA BIT(2) -+#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT BIT(1) -+#define VC4_BIN_CONFIG_MS_MODE_4X BIT(0) - /** @} */ - - /** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */ --#define VC4_RENDER_CONFIG_DB_NON_MS (1 << 12) --#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11) --#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G (1 << 10) --#define VC4_RENDER_CONFIG_COVERAGE_MODE (1 << 9) --#define VC4_RENDER_CONFIG_ENABLE_VG_MASK (1 << 8) -+#define VC4_RENDER_CONFIG_DB_NON_MS BIT(12) -+#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE BIT(11) -+#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G BIT(10) -+#define VC4_RENDER_CONFIG_COVERAGE_MODE BIT(9) -+#define VC4_RENDER_CONFIG_ENABLE_VG_MASK BIT(8) - - /** The values of the field are VC4_TILING_FORMAT_* */ - #define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK VC4_MASK(7, 6) -@@ -280,8 +280,8 @@ enum vc4_packet { - #define VC4_RENDER_CONFIG_FORMAT_RGBA8888 1 - #define VC4_RENDER_CONFIG_FORMAT_BGR565 2 - --#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT (1 << 1) --#define VC4_RENDER_CONFIG_MS_MODE_4X (1 << 0) -+#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT BIT(1) -+#define VC4_RENDER_CONFIG_MS_MODE_4X BIT(0) - - #define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX (1 << 4) - #define VC4_PRIMITIVE_LIST_FORMAT_32_XY (3 << 4) -@@ -291,24 +291,24 @@ enum vc4_packet { - #define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT (3 << 0) - - enum vc4_texture_data_type { -- VC4_TEXTURE_TYPE_RGBA8888 = 0, -- VC4_TEXTURE_TYPE_RGBX8888 = 1, -- VC4_TEXTURE_TYPE_RGBA4444 = 2, -- VC4_TEXTURE_TYPE_RGBA5551 = 3, -- VC4_TEXTURE_TYPE_RGB565 = 4, -- VC4_TEXTURE_TYPE_LUMINANCE = 5, -- VC4_TEXTURE_TYPE_ALPHA = 6, -- VC4_TEXTURE_TYPE_LUMALPHA = 7, -- VC4_TEXTURE_TYPE_ETC1 = 8, -- VC4_TEXTURE_TYPE_S16F = 9, -- VC4_TEXTURE_TYPE_S8 = 10, -- VC4_TEXTURE_TYPE_S16 = 11, -- VC4_TEXTURE_TYPE_BW1 = 12, -- VC4_TEXTURE_TYPE_A4 = 13, -- VC4_TEXTURE_TYPE_A1 = 14, -- VC4_TEXTURE_TYPE_RGBA64 = 15, -- VC4_TEXTURE_TYPE_RGBA32R = 16, -- VC4_TEXTURE_TYPE_YUV422R = 17, -+ VC4_TEXTURE_TYPE_RGBA8888 = 0, -+ VC4_TEXTURE_TYPE_RGBX8888 = 1, -+ VC4_TEXTURE_TYPE_RGBA4444 = 2, -+ VC4_TEXTURE_TYPE_RGBA5551 = 3, -+ VC4_TEXTURE_TYPE_RGB565 = 4, -+ VC4_TEXTURE_TYPE_LUMINANCE = 5, -+ VC4_TEXTURE_TYPE_ALPHA = 6, -+ VC4_TEXTURE_TYPE_LUMALPHA = 7, -+ VC4_TEXTURE_TYPE_ETC1 = 8, -+ VC4_TEXTURE_TYPE_S16F = 9, -+ VC4_TEXTURE_TYPE_S8 = 10, -+ VC4_TEXTURE_TYPE_S16 = 11, -+ VC4_TEXTURE_TYPE_BW1 = 12, -+ VC4_TEXTURE_TYPE_A4 = 13, -+ VC4_TEXTURE_TYPE_A1 = 14, -+ VC4_TEXTURE_TYPE_RGBA64 = 15, -+ VC4_TEXTURE_TYPE_RGBA32R = 16, -+ VC4_TEXTURE_TYPE_YUV422R = 17, - }; - - #define VC4_TEX_P0_OFFSET_MASK VC4_MASK(31, 12) -diff --git a/drivers/gpu/drm/vc4/vc4_qpu_defines.h b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -index e47c994..d5c2f3c 100644 ---- a/drivers/gpu/drm/vc4/vc4_qpu_defines.h -+++ b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -@@ -25,194 +25,190 @@ - #define VC4_QPU_DEFINES_H - - enum qpu_op_add { -- QPU_A_NOP, -- QPU_A_FADD, -- QPU_A_FSUB, -- QPU_A_FMIN, -- QPU_A_FMAX, -- QPU_A_FMINABS, -- QPU_A_FMAXABS, -- QPU_A_FTOI, -- QPU_A_ITOF, -- QPU_A_ADD = 12, -- QPU_A_SUB, -- QPU_A_SHR, -- QPU_A_ASR, -- QPU_A_ROR, -- QPU_A_SHL, -- QPU_A_MIN, -- QPU_A_MAX, -- QPU_A_AND, -- QPU_A_OR, -- QPU_A_XOR, -- QPU_A_NOT, -- QPU_A_CLZ, -- QPU_A_V8ADDS = 30, -- QPU_A_V8SUBS = 31, -+ QPU_A_NOP, -+ QPU_A_FADD, -+ QPU_A_FSUB, -+ QPU_A_FMIN, -+ QPU_A_FMAX, -+ QPU_A_FMINABS, -+ QPU_A_FMAXABS, -+ QPU_A_FTOI, -+ QPU_A_ITOF, -+ QPU_A_ADD = 12, -+ QPU_A_SUB, -+ QPU_A_SHR, -+ QPU_A_ASR, -+ QPU_A_ROR, -+ QPU_A_SHL, -+ QPU_A_MIN, -+ QPU_A_MAX, -+ QPU_A_AND, -+ QPU_A_OR, -+ QPU_A_XOR, -+ QPU_A_NOT, -+ QPU_A_CLZ, -+ QPU_A_V8ADDS = 30, -+ QPU_A_V8SUBS = 31, - }; - - enum qpu_op_mul { -- QPU_M_NOP, -- QPU_M_FMUL, -- QPU_M_MUL24, -- QPU_M_V8MULD, -- QPU_M_V8MIN, -- QPU_M_V8MAX, -- QPU_M_V8ADDS, -- QPU_M_V8SUBS, -+ QPU_M_NOP, -+ QPU_M_FMUL, -+ QPU_M_MUL24, -+ QPU_M_V8MULD, -+ QPU_M_V8MIN, -+ QPU_M_V8MAX, -+ QPU_M_V8ADDS, -+ QPU_M_V8SUBS, - }; - - enum qpu_raddr { -- QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -- /* 0-31 are the plain regfile a or b fields */ -- QPU_R_UNIF = 32, -- QPU_R_VARY = 35, -- QPU_R_ELEM_QPU = 38, -- QPU_R_NOP, -- QPU_R_XY_PIXEL_COORD = 41, -- QPU_R_MS_REV_FLAGS = 41, -- QPU_R_VPM = 48, -- QPU_R_VPM_LD_BUSY, -- QPU_R_VPM_LD_WAIT, -- QPU_R_MUTEX_ACQUIRE, -+ QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_R_UNIF = 32, -+ QPU_R_VARY = 35, -+ QPU_R_ELEM_QPU = 38, -+ QPU_R_NOP, -+ QPU_R_XY_PIXEL_COORD = 41, -+ QPU_R_MS_REV_FLAGS = 41, -+ QPU_R_VPM = 48, -+ QPU_R_VPM_LD_BUSY, -+ QPU_R_VPM_LD_WAIT, -+ QPU_R_MUTEX_ACQUIRE, - }; - - enum qpu_waddr { -- /* 0-31 are the plain regfile a or b fields */ -- QPU_W_ACC0 = 32, /* aka r0 */ -- QPU_W_ACC1, -- QPU_W_ACC2, -- QPU_W_ACC3, -- QPU_W_TMU_NOSWAP, -- QPU_W_ACC5, -- QPU_W_HOST_INT, -- QPU_W_NOP, -- QPU_W_UNIFORMS_ADDRESS, -- QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -- QPU_W_MS_FLAGS = 42, -- QPU_W_REV_FLAG = 42, -- QPU_W_TLB_STENCIL_SETUP = 43, -- QPU_W_TLB_Z, -- QPU_W_TLB_COLOR_MS, -- QPU_W_TLB_COLOR_ALL, -- QPU_W_TLB_ALPHA_MASK, -- QPU_W_VPM, -- QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -- QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -- QPU_W_MUTEX_RELEASE, -- QPU_W_SFU_RECIP, -- QPU_W_SFU_RECIPSQRT, -- QPU_W_SFU_EXP, -- QPU_W_SFU_LOG, -- QPU_W_TMU0_S, -- QPU_W_TMU0_T, -- QPU_W_TMU0_R, -- QPU_W_TMU0_B, -- QPU_W_TMU1_S, -- QPU_W_TMU1_T, -- QPU_W_TMU1_R, -- QPU_W_TMU1_B, -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_W_ACC0 = 32, /* aka r0 */ -+ QPU_W_ACC1, -+ QPU_W_ACC2, -+ QPU_W_ACC3, -+ QPU_W_TMU_NOSWAP, -+ QPU_W_ACC5, -+ QPU_W_HOST_INT, -+ QPU_W_NOP, -+ QPU_W_UNIFORMS_ADDRESS, -+ QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -+ QPU_W_MS_FLAGS = 42, -+ QPU_W_REV_FLAG = 42, -+ QPU_W_TLB_STENCIL_SETUP = 43, -+ QPU_W_TLB_Z, -+ QPU_W_TLB_COLOR_MS, -+ QPU_W_TLB_COLOR_ALL, -+ QPU_W_TLB_ALPHA_MASK, -+ QPU_W_VPM, -+ QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -+ QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -+ QPU_W_MUTEX_RELEASE, -+ QPU_W_SFU_RECIP, -+ QPU_W_SFU_RECIPSQRT, -+ QPU_W_SFU_EXP, -+ QPU_W_SFU_LOG, -+ QPU_W_TMU0_S, -+ QPU_W_TMU0_T, -+ QPU_W_TMU0_R, -+ QPU_W_TMU0_B, -+ QPU_W_TMU1_S, -+ QPU_W_TMU1_T, -+ QPU_W_TMU1_R, -+ QPU_W_TMU1_B, - }; - - enum qpu_sig_bits { -- QPU_SIG_SW_BREAKPOINT, -- QPU_SIG_NONE, -- QPU_SIG_THREAD_SWITCH, -- QPU_SIG_PROG_END, -- QPU_SIG_WAIT_FOR_SCOREBOARD, -- QPU_SIG_SCOREBOARD_UNLOCK, -- QPU_SIG_LAST_THREAD_SWITCH, -- QPU_SIG_COVERAGE_LOAD, -- QPU_SIG_COLOR_LOAD, -- QPU_SIG_COLOR_LOAD_END, -- QPU_SIG_LOAD_TMU0, -- QPU_SIG_LOAD_TMU1, -- QPU_SIG_ALPHA_MASK_LOAD, -- QPU_SIG_SMALL_IMM, -- QPU_SIG_LOAD_IMM, -- QPU_SIG_BRANCH -+ QPU_SIG_SW_BREAKPOINT, -+ QPU_SIG_NONE, -+ QPU_SIG_THREAD_SWITCH, -+ QPU_SIG_PROG_END, -+ QPU_SIG_WAIT_FOR_SCOREBOARD, -+ QPU_SIG_SCOREBOARD_UNLOCK, -+ QPU_SIG_LAST_THREAD_SWITCH, -+ QPU_SIG_COVERAGE_LOAD, -+ QPU_SIG_COLOR_LOAD, -+ QPU_SIG_COLOR_LOAD_END, -+ QPU_SIG_LOAD_TMU0, -+ QPU_SIG_LOAD_TMU1, -+ QPU_SIG_ALPHA_MASK_LOAD, -+ QPU_SIG_SMALL_IMM, -+ QPU_SIG_LOAD_IMM, -+ QPU_SIG_BRANCH - }; - - enum qpu_mux { -- /* hardware mux values */ -- QPU_MUX_R0, -- QPU_MUX_R1, -- QPU_MUX_R2, -- QPU_MUX_R3, -- QPU_MUX_R4, -- QPU_MUX_R5, -- QPU_MUX_A, -- QPU_MUX_B, -+ /* hardware mux values */ -+ QPU_MUX_R0, -+ QPU_MUX_R1, -+ QPU_MUX_R2, -+ QPU_MUX_R3, -+ QPU_MUX_R4, -+ QPU_MUX_R5, -+ QPU_MUX_A, -+ QPU_MUX_B, - -- /* non-hardware mux values */ -- QPU_MUX_IMM, -+ /* non-hardware mux values */ -+ QPU_MUX_IMM, - }; - - enum qpu_cond { -- QPU_COND_NEVER, -- QPU_COND_ALWAYS, -- QPU_COND_ZS, -- QPU_COND_ZC, -- QPU_COND_NS, -- QPU_COND_NC, -- QPU_COND_CS, -- QPU_COND_CC, -+ QPU_COND_NEVER, -+ QPU_COND_ALWAYS, -+ QPU_COND_ZS, -+ QPU_COND_ZC, -+ QPU_COND_NS, -+ QPU_COND_NC, -+ QPU_COND_CS, -+ QPU_COND_CC, - }; - - enum qpu_pack_mul { -- QPU_PACK_MUL_NOP, -- QPU_PACK_MUL_8888 = 3, /* replicated to each 8 bits of the 32-bit dst. */ -- QPU_PACK_MUL_8A, -- QPU_PACK_MUL_8B, -- QPU_PACK_MUL_8C, -- QPU_PACK_MUL_8D, -+ QPU_PACK_MUL_NOP, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_MUL_8888 = 3, -+ QPU_PACK_MUL_8A, -+ QPU_PACK_MUL_8B, -+ QPU_PACK_MUL_8C, -+ QPU_PACK_MUL_8D, - }; - - enum qpu_pack_a { -- QPU_PACK_A_NOP, -- /* convert to 16 bit float if float input, or to int16. */ -- QPU_PACK_A_16A, -- QPU_PACK_A_16B, -- /* replicated to each 8 bits of the 32-bit dst. */ -- QPU_PACK_A_8888, -- /* Convert to 8-bit unsigned int. */ -- QPU_PACK_A_8A, -- QPU_PACK_A_8B, -- QPU_PACK_A_8C, -- QPU_PACK_A_8D, -+ QPU_PACK_A_NOP, -+ /* convert to 16 bit float if float input, or to int16. */ -+ QPU_PACK_A_16A, -+ QPU_PACK_A_16B, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_A_8888, -+ /* Convert to 8-bit unsigned int. */ -+ QPU_PACK_A_8A, -+ QPU_PACK_A_8B, -+ QPU_PACK_A_8C, -+ QPU_PACK_A_8D, - -- /* Saturating variants of the previous instructions. */ -- QPU_PACK_A_32_SAT, /* int-only */ -- QPU_PACK_A_16A_SAT, /* int or float */ -- QPU_PACK_A_16B_SAT, -- QPU_PACK_A_8888_SAT, -- QPU_PACK_A_8A_SAT, -- QPU_PACK_A_8B_SAT, -- QPU_PACK_A_8C_SAT, -- QPU_PACK_A_8D_SAT, -+ /* Saturating variants of the previous instructions. */ -+ QPU_PACK_A_32_SAT, /* int-only */ -+ QPU_PACK_A_16A_SAT, /* int or float */ -+ QPU_PACK_A_16B_SAT, -+ QPU_PACK_A_8888_SAT, -+ QPU_PACK_A_8A_SAT, -+ QPU_PACK_A_8B_SAT, -+ QPU_PACK_A_8C_SAT, -+ QPU_PACK_A_8D_SAT, - }; - - enum qpu_unpack_r4 { -- QPU_UNPACK_R4_NOP, -- QPU_UNPACK_R4_F16A_TO_F32, -- QPU_UNPACK_R4_F16B_TO_F32, -- QPU_UNPACK_R4_8D_REP, -- QPU_UNPACK_R4_8A, -- QPU_UNPACK_R4_8B, -- QPU_UNPACK_R4_8C, -- QPU_UNPACK_R4_8D, -+ QPU_UNPACK_R4_NOP, -+ QPU_UNPACK_R4_F16A_TO_F32, -+ QPU_UNPACK_R4_F16B_TO_F32, -+ QPU_UNPACK_R4_8D_REP, -+ QPU_UNPACK_R4_8A, -+ QPU_UNPACK_R4_8B, -+ QPU_UNPACK_R4_8C, -+ QPU_UNPACK_R4_8D, - }; - --#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low)) --/* Using the GNU statement expression extension */ --#define QPU_SET_FIELD(value, field) \ -- ({ \ -- uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \ -- assert((fieldval & ~ field ## _MASK) == 0); \ -- fieldval & field ## _MASK; \ -- }) -+#define QPU_MASK(high, low) \ -+ ((((uint64_t)1 << ((high) - (low) + 1)) - 1) << (low)) - --#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) -+#define QPU_GET_FIELD(word, field) \ -+ ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) - - #define QPU_SIG_SHIFT 60 - #define QPU_SIG_MASK QPU_MASK(63, 60) -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 0ffac8d..3516354 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -63,7 +63,6 @@ static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val) - setup->next_offset += 4; - } - -- - /* - * Emits a no-op STORE_TILE_BUFFER_GENERAL. - * -@@ -217,7 +216,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - } - size += xtiles * ytiles * loop_body_size; - -- setup->rcl = &vc4_bo_create(dev, size)->base; -+ setup->rcl = &vc4_bo_create(dev, size, true)->base; - if (!setup->rcl) - return -ENOMEM; - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, -@@ -256,6 +255,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - for (x = min_x_tile; x <= max_x_tile; x++) { - bool first = (x == min_x_tile && y == min_y_tile); - bool last = (x == max_x_tile && y == max_y_tile); -+ - emit_tile(exec, setup, x, y, first, last); - } - } -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index cf35f58..29a222f 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -125,7 +125,7 @@ int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) - - int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) - { -- struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - uint32_t ident1 = V3D_READ(V3D_IDENT1); -@@ -133,11 +133,13 @@ int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) - uint32_t tups = VC4_GET_FIELD(ident1, V3D_IDENT1_TUPS); - uint32_t qups = VC4_GET_FIELD(ident1, V3D_IDENT1_QUPS); - -- seq_printf(m, "Revision: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); -+ seq_printf(m, "Revision: %d\n", -+ VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); - seq_printf(m, "Slices: %d\n", nslc); - seq_printf(m, "TMUs: %d\n", nslc * tups); - seq_printf(m, "QPUs: %d\n", nslc * qups); -- seq_printf(m, "Semaphores: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); -+ seq_printf(m, "Semaphores: %d\n", -+ VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); - - return 0; - } -@@ -218,7 +220,7 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) - } - - static void vc4_v3d_unbind(struct device *dev, struct device *master, -- void *data) -+ void *data) - { - struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index ff3b62f..e44e355 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -48,7 +48,6 @@ - void *validated, \ - void *untrusted - -- - /** Return the width in pixels of a 64-byte microtile. */ - static uint32_t - utile_width(int cpp) -@@ -192,7 +191,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, - - if (size + offset < size || - size + offset > fbo->base.size) { -- DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %d)\n", -+ DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n", - width, height, - aligned_width, aligned_height, - size, offset, fbo->base.size); -@@ -278,7 +277,7 @@ validate_indexed_prim_list(VALIDATE_ARGS) - - if (offset > ib->base.size || - (ib->base.size - offset) / index_size < length) { -- DRM_ERROR("IB access overflow (%d + %d*%d > %d)\n", -+ DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", - offset, length, index_size, ib->base.size); - return -EINVAL; - } -@@ -377,6 +376,7 @@ static int - validate_tile_binning_config(VALIDATE_ARGS) - { - struct drm_device *dev = exec->exec_bo->base.dev; -+ struct vc4_bo *tile_bo; - uint8_t flags; - uint32_t tile_state_size, tile_alloc_size; - uint32_t tile_count; -@@ -438,12 +438,12 @@ validate_tile_binning_config(VALIDATE_ARGS) - */ - tile_alloc_size += 1024 * 1024; - -- exec->tile_bo = &vc4_bo_create(dev, exec->tile_alloc_offset + -- tile_alloc_size)->base; -+ tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size, -+ true); -+ exec->tile_bo = &tile_bo->base; - if (!exec->tile_bo) - return -ENOMEM; -- list_add_tail(&to_vc4_bo(&exec->tile_bo->base)->unref_head, -- &exec->unref_list); -+ list_add_tail(&tile_bo->unref_head, &exec->unref_list); - - /* tile alloc address. */ - *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + -@@ -463,8 +463,8 @@ validate_gem_handles(VALIDATE_ARGS) - return 0; - } - --#define VC4_DEFINE_PACKET(packet, name, func) \ -- [packet] = { packet ## _SIZE, name, func } -+#define VC4_DEFINE_PACKET(packet, func) \ -+ [packet] = { packet ## _SIZE, #packet, func } - - static const struct cmd_info { - uint16_t len; -@@ -472,42 +472,43 @@ static const struct cmd_info { - int (*func)(struct vc4_exec_info *exec, void *validated, - void *untrusted); - } cmd_info[] = { -- VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", validate_flush_all), -- VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning), -- VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive), -- -- /* This is only used by clipped primitives (packets 48 and 49), which -- * we don't support parsing yet. -- */ -- VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state), -- VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, "NV Shader State", validate_nv_shader_state), -- -- VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_HALT, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_NOP, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, -+ validate_start_tile_binning), -+ VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, -+ validate_increment_semaphore), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, -+ validate_indexed_prim_list), -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, -+ validate_gl_array_primitive), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, validate_gl_shader_state), -+ VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, validate_nv_shader_state), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, NULL), - /* Note: The docs say this was also 105, but it was 106 in the - * initial userland code drop. - */ -- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, NULL), - -- VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config), -+ VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, -+ validate_tile_binning_config), - -- VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles), -+ VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, validate_gem_handles), - }; - - int -@@ -526,7 +527,7 @@ vc4_validate_bin_cl(struct drm_device *dev, - u8 cmd = *(uint8_t *)src_pkt; - const struct cmd_info *info; - -- if (cmd > ARRAY_SIZE(cmd_info)) { -+ if (cmd >= ARRAY_SIZE(cmd_info)) { - DRM_ERROR("0x%08x: packet %d out of bounds\n", - src_offset, cmd); - return -EINVAL; -@@ -539,11 +540,6 @@ vc4_validate_bin_cl(struct drm_device *dev, - return -EINVAL; - } - --#if 0 -- DRM_INFO("0x%08x: packet %d (%s) size %d processing...\n", -- src_offset, cmd, info->name, info->len); --#endif -- - if (src_offset + info->len > len) { - DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x " - "exceeds bounds (0x%08x)\n", -@@ -558,8 +554,7 @@ vc4_validate_bin_cl(struct drm_device *dev, - if (info->func && info->func(exec, - dst_pkt + 1, - src_pkt + 1)) { -- DRM_ERROR("0x%08x: packet %d (%s) failed to " -- "validate\n", -+ DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n", - src_offset, cmd, info->name); - return -EINVAL; - } -@@ -618,12 +613,14 @@ reloc_tex(struct vc4_exec_info *exec, - - if (sample->is_direct) { - uint32_t remaining_size = tex->base.size - p0; -+ - if (p0 > tex->base.size - 4) { - DRM_ERROR("UBO offset greater than UBO size\n"); - goto fail; - } - if (p1 > remaining_size - 4) { -- DRM_ERROR("UBO clamp would allow reads outside of UBO\n"); -+ DRM_ERROR("UBO clamp would allow reads " -+ "outside of UBO\n"); - goto fail; - } - *validated_p0 = tex->paddr + p0; -@@ -786,7 +783,7 @@ validate_shader_rec(struct drm_device *dev, - struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; - uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; - int i; -- struct vc4_validated_shader_info *validated_shader; -+ struct vc4_validated_shader_info *shader; - - if (state->packet == VC4_PACKET_NV_SHADER_STATE) { - relocs = nv_relocs; -@@ -841,12 +838,12 @@ validate_shader_rec(struct drm_device *dev, - else - mode = VC4_MODE_RENDER; - -- if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) { -+ if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) - return false; -- } - } - - for (i = 0; i < nr_fixed_relocs; i++) { -+ struct vc4_bo *vc4_bo; - uint32_t o = relocs[i].offset; - uint32_t src_offset = *(uint32_t *)(pkt_u + o); - uint32_t *texture_handles_u; -@@ -858,34 +855,34 @@ validate_shader_rec(struct drm_device *dev, - switch (relocs[i].type) { - case RELOC_CODE: - if (src_offset != 0) { -- DRM_ERROR("Shaders must be at offset 0 of " -- "the BO.\n"); -+ DRM_ERROR("Shaders must be at offset 0 " -+ "of the BO.\n"); - goto fail; - } - -- validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -- if (!validated_shader) -+ vc4_bo = to_vc4_bo(&bo[i]->base); -+ shader = vc4_bo->validated_shader; -+ if (!shader) - goto fail; - -- if (validated_shader->uniforms_src_size > -- exec->uniforms_size) { -+ if (shader->uniforms_src_size > exec->uniforms_size) { - DRM_ERROR("Uniforms src buffer overflow\n"); - goto fail; - } - - texture_handles_u = exec->uniforms_u; - uniform_data_u = (texture_handles_u + -- validated_shader->num_texture_samples); -+ shader->num_texture_samples); - - memcpy(exec->uniforms_v, uniform_data_u, -- validated_shader->uniforms_size); -+ shader->uniforms_size); - - for (tex = 0; -- tex < validated_shader->num_texture_samples; -+ tex < shader->num_texture_samples; - tex++) { - if (!reloc_tex(exec, - uniform_data_u, -- &validated_shader->texture_samples[tex], -+ &shader->texture_samples[tex], - texture_handles_u[tex])) { - goto fail; - } -@@ -893,9 +890,9 @@ validate_shader_rec(struct drm_device *dev, - - *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; - -- exec->uniforms_u += validated_shader->uniforms_src_size; -- exec->uniforms_v += validated_shader->uniforms_size; -- exec->uniforms_p += validated_shader->uniforms_size; -+ exec->uniforms_u += shader->uniforms_src_size; -+ exec->uniforms_v += shader->uniforms_size; -+ exec->uniforms_p += shader->uniforms_size; - - break; - -@@ -926,7 +923,8 @@ validate_shader_rec(struct drm_device *dev, - max_index = ((vbo->base.size - offset - attr_size) / - stride); - if (state->max_index > max_index) { -- DRM_ERROR("primitives use index %d out of supplied %d\n", -+ DRM_ERROR("primitives use index %d out of " -+ "supplied %d\n", - state->max_index, max_index); - return -EINVAL; - } -diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -index 0aab9d7..f67124b 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c -+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -@@ -24,24 +24,16 @@ - /** - * DOC: Shader validator for VC4. - * -- * The VC4 has no IOMMU between it and system memory. So, a user with access -- * to execute shaders could escalate privilege by overwriting system memory -- * (using the VPM write address register in the general-purpose DMA mode) or -- * reading system memory it shouldn't (reading it as a texture, or uniform -- * data, or vertex data). -+ * The VC4 has no IOMMU between it and system memory, so a user with -+ * access to execute shaders could escalate privilege by overwriting -+ * system memory (using the VPM write address register in the -+ * general-purpose DMA mode) or reading system memory it shouldn't -+ * (reading it as a texture, or uniform data, or vertex data). - * -- * This walks over a shader starting from some offset within a BO, ensuring -- * that its accesses are appropriately bounded, and recording how many texture -- * accesses are made and where so that we can do relocations for them in the -+ * This walks over a shader BO, ensuring that its accesses are -+ * appropriately bounded, and recording how many texture accesses are -+ * made and where so that we can do relocations for them in the - * uniform stream. -- * -- * The kernel API has shaders stored in user-mapped BOs. The BOs will be -- * forcibly unmapped from the process before validation, and any cache of -- * validated state will be flushed if the mapping is faulted back in. -- * -- * Storing the shaders in BOs means that the validation process will be slow -- * due to uncached reads, but since shaders are long-lived and shader BOs are -- * never actually modified, this shouldn't be a problem. - */ - - #include "vc4_drv.h" -@@ -70,7 +62,6 @@ waddr_to_live_reg_index(uint32_t waddr, bool is_b) - else - return waddr; - } else if (waddr <= QPU_W_ACC3) { -- - return 64 + waddr - QPU_W_ACC0; - } else { - return ~0; -@@ -85,15 +76,14 @@ raddr_add_a_to_live_reg_index(uint64_t inst) - uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); - uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); - -- if (add_a == QPU_MUX_A) { -+ if (add_a == QPU_MUX_A) - return raddr_a; -- } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) { -+ else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) - return 32 + raddr_b; -- } else if (add_a <= QPU_MUX_R3) { -+ else if (add_a <= QPU_MUX_R3) - return 64 + add_a; -- } else { -+ else - return ~0; -- } - } - - static bool -@@ -111,9 +101,9 @@ is_tmu_write(uint32_t waddr) - } - - static bool --record_validated_texture_sample(struct vc4_validated_shader_info *validated_shader, -- struct vc4_shader_validation_state *validation_state, -- int tmu) -+record_texture_sample(struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ int tmu) - { - uint32_t s = validated_shader->num_texture_samples; - int i; -@@ -226,8 +216,8 @@ check_tmu_write(uint64_t inst, - validated_shader->uniforms_size += 4; - - if (submit) { -- if (!record_validated_texture_sample(validated_shader, -- validation_state, tmu)) { -+ if (!record_texture_sample(validated_shader, -+ validation_state, tmu)) { - return false; - } - -@@ -238,10 +228,10 @@ check_tmu_write(uint64_t inst, - } - - static bool --check_register_write(uint64_t inst, -- struct vc4_validated_shader_info *validated_shader, -- struct vc4_shader_validation_state *validation_state, -- bool is_mul) -+check_reg_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) - { - uint32_t waddr = (is_mul ? - QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -@@ -297,7 +287,7 @@ check_register_write(uint64_t inst, - return true; - - case QPU_W_TLB_STENCIL_SETUP: -- return true; -+ return true; - } - - return true; -@@ -360,7 +350,7 @@ track_live_clamps(uint64_t inst, - } - - validation_state->live_max_clamp_regs[lri_add] = true; -- } if (op_add == QPU_A_MIN) { -+ } else if (op_add == QPU_A_MIN) { - /* Track live clamps of a value clamped to a minimum of 0 and - * a maximum of some uniform's offset. - */ -@@ -392,8 +382,10 @@ check_instruction_writes(uint64_t inst, - return false; - } - -- ok = (check_register_write(inst, validated_shader, validation_state, false) && -- check_register_write(inst, validated_shader, validation_state, true)); -+ ok = (check_reg_write(inst, validated_shader, validation_state, -+ false) && -+ check_reg_write(inst, validated_shader, validation_state, -+ true)); - - track_live_clamps(inst, validated_shader, validation_state); - -@@ -441,7 +433,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) - shader = shader_obj->vaddr; - max_ip = shader_obj->base.size / sizeof(uint64_t); - -- validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL); -+ validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); - if (!validated_shader) - return NULL; - -@@ -497,7 +489,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) - - if (ip == max_ip) { - DRM_ERROR("shader failed to terminate before " -- "shader BO end at %d\n", -+ "shader BO end at %zd\n", - shader_obj->base.size); - goto fail; - } -diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 54f5469..987c25a 100644 ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -585,6 +585,13 @@ struct drm_driver { - int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); - void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); - -+ /** -+ * Hook for allocating the GEM object struct, for use by core -+ * helpers. -+ */ -+ struct drm_gem_object *(*gem_create_object)(struct drm_device *dev, -+ size_t size); -+ - /* prime: */ - /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ - int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, -@@ -639,7 +646,6 @@ struct drm_driver { - - u32 driver_features; - int dev_priv_size; -- size_t gem_obj_size; - const struct drm_ioctl_desc *ioctls; - int num_ioctls; - const struct file_operations *fops; - -From 527fa9469f0876bade592e985a6c973ca8c84839 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 11 Dec 2015 19:45:03 -0800 -Subject: [PATCH 111/251] drm: Use the driver's gem_object_free function from - CMA helpers. - -VC4 wraps the CMA objects in its own structures, so it needs to do its -own teardown (waiting for GPU to finish, updating bo_stats tracking). -The other CMA drivers are using drm_gem_cma_free_object as their -gem_free_object, so this should be a no-op for them. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_fb_cma_helper.c | 6 +++--- - drivers/gpu/drm/drm_gem_cma_helper.c | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c -index c19a625..c1a37d3 100644 ---- a/drivers/gpu/drm/drm_fb_cma_helper.c -+++ b/drivers/gpu/drm/drm_fb_cma_helper.c -@@ -266,7 +266,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - fbi = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(fbi)) { - ret = PTR_ERR(fbi); -- goto err_drm_gem_cma_free_object; -+ goto err_gem_free_object; - } - - fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); -@@ -299,8 +299,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - - err_fb_info_destroy: - drm_fb_helper_release_fbi(helper); --err_drm_gem_cma_free_object: -- drm_gem_cma_free_object(&obj->base); -+err_gem_free_object: -+ dev->driver->gem_free_object(&obj->base); - return ret; - } - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index 0f7b00b..e5df53b 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, - return cma_obj; - - error: -- drm_gem_cma_free_object(&cma_obj->base); -+ drm->driver->gem_free_object(&cma_obj->base); - return ERR_PTR(ret); - } - EXPORT_SYMBOL_GPL(drm_gem_cma_create); -@@ -171,7 +171,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, - return cma_obj; - - err_handle_create: -- drm_gem_cma_free_object(gem_obj); -+ drm->driver->gem_free_object(gem_obj); - - return ERR_PTR(ret); - } - -From d5d7b446f3dc3c30886937f4750b96d5c40a0904 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 17 Jul 2015 13:15:50 -0700 -Subject: [PATCH 112/251] drm/vc4: Add support for MSAA rendering. - -For MSAA, you set a bit in the binner that halves the size of tiles in -each direction, so you can pack 4 samples per pixel in the tile -buffer. During rendering, you can load and store raw tile buffer -contents (to save the per-sample MSAA contents), or you can load/store -resolved tile buffer contents (loads spam the pixel value to all 4 -samples, and stores either average the 4 color samples, or store the -first sample for Z/S). - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_packet.h | 23 ++- - drivers/gpu/drm/vc4/vc4_render_cl.c | 274 ++++++++++++++++++++++++++++++------ - drivers/gpu/drm/vc4/vc4_validate.c | 5 +- - include/uapi/drm/vc4_drm.h | 11 +- - 4 files changed, 258 insertions(+), 55 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -index cee38aa..0f31cc0 100644 ---- a/drivers/gpu/drm/vc4/vc4_packet.h -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -123,6 +123,11 @@ enum vc4_packet { - #define VC4_PACKET_TILE_COORDINATES_SIZE 3 - #define VC4_PACKET_GEM_HANDLES_SIZE 9 - -+/* Number of multisamples supported. */ -+#define VC4_MAX_SAMPLES 4 -+/* Size of a full resolution color or Z tile buffer load/store. */ -+#define VC4_TILE_BUFFER_SIZE (64 * 64 * 4) -+ - /** @{ - * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and - * VC4_PACKET_TILE_RENDERING_MODE_CONFIG. -@@ -137,10 +142,20 @@ enum vc4_packet { - * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and - * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. - */ --#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3) --#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2) --#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1) --#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0) -+#define VC4_LOADSTORE_FULL_RES_EOF BIT(3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0) -+ -+/** @{ -+ * -+ * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and -+ * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. -+ */ -+#define VC4_LOADSTORE_FULL_RES_EOF BIT(3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0) - - /** @{ - * -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 3516354..8f2ec57 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -37,9 +37,11 @@ - - struct vc4_rcl_setup { - struct drm_gem_cma_object *color_read; -- struct drm_gem_cma_object *color_ms_write; -+ struct drm_gem_cma_object *color_write; - struct drm_gem_cma_object *zs_read; - struct drm_gem_cma_object *zs_write; -+ struct drm_gem_cma_object *msaa_color_write; -+ struct drm_gem_cma_object *msaa_zs_write; - - struct drm_gem_cma_object *rcl; - u32 next_offset; -@@ -82,6 +84,22 @@ static void vc4_store_before_load(struct vc4_rcl_setup *setup) - } - - /* -+ * Calculates the physical address of the start of a tile in a RCL surface. -+ * -+ * Unlike the other load/store packets, -+ * VC4_PACKET_LOAD/STORE_FULL_RES_TILE_BUFFER don't look at the tile -+ * coordinates packet, and instead just store to the address given. -+ */ -+static uint32_t vc4_full_res_offset(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *bo, -+ struct drm_vc4_submit_rcl_surface *surf, -+ uint8_t x, uint8_t y) -+{ -+ return bo->paddr + surf->offset + VC4_TILE_BUFFER_SIZE * -+ (DIV_ROUND_UP(exec->args->width, 32) * y + x); -+} -+ -+/* - * Emits a PACKET_TILE_COORDINATES if one isn't already pending. - * - * The tile coordinates packet triggers a pending load if there is one, are -@@ -108,22 +126,41 @@ static void emit_tile(struct vc4_exec_info *exec, - * may be outstanding at a time. - */ - if (setup->color_read) { -- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -- rcl_u16(setup, args->color_read.bits); -- rcl_u32(setup, -- setup->color_read->paddr + args->color_read.offset); -+ if (args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->color_read, -+ &args->color_read, x, y) | -+ VC4_LOADSTORE_FULL_RES_DISABLE_ZS); -+ } else { -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->color_read.bits); -+ rcl_u32(setup, setup->color_read->paddr + -+ args->color_read.offset); -+ } - } - - if (setup->zs_read) { -- if (setup->color_read) { -- /* Exec previous load. */ -- vc4_tile_coordinates(setup, x, y); -- vc4_store_before_load(setup); -+ if (args->zs_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->zs_read, -+ &args->zs_read, x, y) | -+ VC4_LOADSTORE_FULL_RES_DISABLE_COLOR); -+ } else { -+ if (setup->color_read) { -+ /* Exec previous load. */ -+ vc4_tile_coordinates(setup, x, y); -+ vc4_store_before_load(setup); -+ } -+ -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_read.bits); -+ rcl_u32(setup, setup->zs_read->paddr + -+ args->zs_read.offset); - } -- -- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -- rcl_u16(setup, args->zs_read.bits); -- rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset); - } - - /* Clipping depends on tile coordinates having been -@@ -144,20 +181,60 @@ static void emit_tile(struct vc4_exec_info *exec, - (y * exec->bin_tiles_x + x) * 32)); - } - -+ if (setup->msaa_color_write) { -+ bool last_tile_write = (!setup->msaa_zs_write && -+ !setup->zs_write && -+ !setup->color_write); -+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_ZS; -+ -+ if (!last_tile_write) -+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL; -+ else if (last) -+ bits |= VC4_LOADSTORE_FULL_RES_EOF; -+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->msaa_color_write, -+ &args->msaa_color_write, x, y) | -+ bits); -+ } -+ -+ if (setup->msaa_zs_write) { -+ bool last_tile_write = (!setup->zs_write && -+ !setup->color_write); -+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_COLOR; -+ -+ if (setup->msaa_color_write) -+ vc4_tile_coordinates(setup, x, y); -+ if (!last_tile_write) -+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL; -+ else if (last) -+ bits |= VC4_LOADSTORE_FULL_RES_EOF; -+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->msaa_zs_write, -+ &args->msaa_zs_write, x, y) | -+ bits); -+ } -+ - if (setup->zs_write) { -+ bool last_tile_write = !setup->color_write; -+ -+ if (setup->msaa_color_write || setup->msaa_zs_write) -+ vc4_tile_coordinates(setup, x, y); -+ - rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); - rcl_u16(setup, args->zs_write.bits | -- (setup->color_ms_write ? -- VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0)); -+ (last_tile_write ? -+ 0 : VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR)); - rcl_u32(setup, - (setup->zs_write->paddr + args->zs_write.offset) | -- ((last && !setup->color_ms_write) ? -+ ((last && last_tile_write) ? - VC4_LOADSTORE_TILE_BUFFER_EOF : 0)); - } - -- if (setup->color_ms_write) { -- if (setup->zs_write) { -- /* Reset after previous store */ -+ if (setup->color_write) { -+ if (setup->msaa_color_write || setup->msaa_zs_write || -+ setup->zs_write) { - vc4_tile_coordinates(setup, x, y); - } - -@@ -192,14 +269,26 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - } - - if (setup->color_read) { -- loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE); -+ if (args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE; -+ } else { -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; -+ } - } - if (setup->zs_read) { -- if (setup->color_read) { -- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -- loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ if (args->zs_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE; -+ } else { -+ if (setup->color_read && -+ !(args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES)) { -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; - } -- loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; - } - - if (has_bin) { -@@ -207,13 +296,23 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE; - } - -+ if (setup->msaa_color_write) -+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE; -+ if (setup->msaa_zs_write) -+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE; -+ - if (setup->zs_write) - loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -- if (setup->color_ms_write) { -- if (setup->zs_write) -- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ if (setup->color_write) - loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE; -- } -+ -+ /* We need a VC4_PACKET_TILE_COORDINATES in between each store. */ -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE * -+ ((setup->msaa_color_write != NULL) + -+ (setup->msaa_zs_write != NULL) + -+ (setup->color_write != NULL) + -+ (setup->zs_write != NULL) - 1); -+ - size += xtiles * ytiles * loop_body_size; - - setup->rcl = &vc4_bo_create(dev, size, true)->base; -@@ -224,13 +323,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - - rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); - rcl_u32(setup, -- (setup->color_ms_write ? -- (setup->color_ms_write->paddr + -- args->color_ms_write.offset) : -+ (setup->color_write ? (setup->color_write->paddr + -+ args->color_write.offset) : - 0)); - rcl_u16(setup, args->width); - rcl_u16(setup, args->height); -- rcl_u16(setup, args->color_ms_write.bits); -+ rcl_u16(setup, args->color_write.bits); - - /* The tile buffer gets cleared when the previous tile is stored. If - * the clear values changed between frames, then the tile buffer has -@@ -267,6 +365,56 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - return 0; - } - -+static int vc4_full_res_bounds_check(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32); -+ -+ if (surf->offset > obj->base.size) { -+ DRM_ERROR("surface offset %d > BO size %zd\n", -+ surf->offset, obj->base.size); -+ return -EINVAL; -+ } -+ -+ if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE < -+ render_tiles_stride * args->max_y_tile + args->max_x_tile) { -+ DRM_ERROR("MSAA tile %d, %d out of bounds " -+ "(bo size %zd, offset %d).\n", -+ args->max_x_tile, args->max_y_tile, -+ obj->base.size, -+ surf->offset); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ if (surf->flags != 0 || surf->bits != 0) { -+ DRM_ERROR("MSAA surface had nonzero flags/bits\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) -+ return -EINVAL; -+ -+ if (surf->offset & 0xf) { -+ DRM_ERROR("MSAA write must be 16b aligned.\n"); -+ return -EINVAL; -+ } -+ -+ return vc4_full_res_bounds_check(exec, *obj, surf); -+} -+ - static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - struct drm_gem_cma_object **obj, - struct drm_vc4_submit_rcl_surface *surf) -@@ -278,9 +426,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - uint8_t format = VC4_GET_FIELD(surf->bits, - VC4_LOADSTORE_TILE_BUFFER_FORMAT); - int cpp; -+ int ret; - -- if (surf->pad != 0) { -- DRM_ERROR("Padding unset\n"); -+ if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ DRM_ERROR("Extra flags set\n"); - return -EINVAL; - } - -@@ -290,6 +439,25 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) - return -EINVAL; - -+ if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ if (surf == &exec->args->zs_write) { -+ DRM_ERROR("general zs write may not be a full-res.\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->bits != 0) { -+ DRM_ERROR("load/store general bits set with " -+ "full res load/store.\n"); -+ return -EINVAL; -+ } -+ -+ ret = vc4_full_res_bounds_check(exec, *obj, surf); -+ if (!ret) -+ return ret; -+ -+ return 0; -+ } -+ - if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK | - VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK | - VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) { -@@ -341,9 +509,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - } - - static int --vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, -- struct drm_gem_cma_object **obj, -- struct drm_vc4_submit_rcl_surface *surf) -+vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) - { - uint8_t tiling = VC4_GET_FIELD(surf->bits, - VC4_RENDER_CONFIG_MEMORY_FORMAT); -@@ -351,13 +520,15 @@ vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, - VC4_RENDER_CONFIG_FORMAT); - int cpp; - -- if (surf->pad != 0) { -- DRM_ERROR("Padding unset\n"); -+ if (surf->flags != 0) { -+ DRM_ERROR("No flags supported on render config.\n"); - return -EINVAL; - } - - if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK | -- VC4_RENDER_CONFIG_FORMAT_MASK)) { -+ VC4_RENDER_CONFIG_FORMAT_MASK | -+ VC4_RENDER_CONFIG_MS_MODE_4X | -+ VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) { - DRM_ERROR("Unknown bits in render config: 0x%04x\n", - surf->bits); - return -EINVAL; -@@ -413,18 +584,20 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) - if (has_bin && - (args->max_x_tile > exec->bin_tiles_x || - args->max_y_tile > exec->bin_tiles_y)) { -- DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n", -+ DRM_ERROR("Render tiles (%d,%d) outside of bin config " -+ "(%d,%d)\n", - args->max_x_tile, args->max_y_tile, - exec->bin_tiles_x, exec->bin_tiles_y); - return -EINVAL; - } - -- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ ret = vc4_rcl_render_config_surface_setup(exec, &setup, -+ &setup.color_write, -+ &args->color_write); - if (ret) - return ret; - -- ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write, -- &args->color_ms_write); -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); - if (ret) - return ret; - -@@ -436,10 +609,21 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) - if (ret) - return ret; - -+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_color_write, -+ &args->msaa_color_write); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_zs_write, -+ &args->msaa_zs_write); -+ if (ret) -+ return ret; -+ - /* We shouldn't even have the job submitted to us if there's no - * surface to write out. - */ -- if (!setup.color_ms_write && !setup.zs_write) { -+ if (!setup.color_write && !setup.zs_write && -+ !setup.msaa_color_write && !setup.msaa_zs_write) { - DRM_ERROR("RCL requires color or Z/S write\n"); - return -EINVAL; - } -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index e44e355..2f22f19 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -400,9 +400,8 @@ validate_tile_binning_config(VALIDATE_ARGS) - } - - if (flags & (VC4_BIN_CONFIG_DB_NON_MS | -- VC4_BIN_CONFIG_TILE_BUFFER_64BIT | -- VC4_BIN_CONFIG_MS_MODE_4X)) { -- DRM_ERROR("unsupported bining config flags 0x%02x\n", flags); -+ VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) { -+ DRM_ERROR("unsupported binning config flags 0x%02x\n", flags); - return -EINVAL; - } - -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 4a8d19f..49cd992 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -46,10 +46,13 @@ struct drm_vc4_submit_rcl_surface { - uint32_t hindex; /* Handle index, or ~0 if not present. */ - uint32_t offset; /* Offset to start of buffer. */ - /* -- * Bits for either render config (color_ms_write) or load/store packet. -+ * Bits for either render config (color_write) or load/store packet. -+ * Bits should all be 0 for MSAA load/stores. - */ - uint16_t bits; -- uint16_t pad; -+ -+#define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0) -+ uint16_t flags; - }; - - /** -@@ -128,9 +131,11 @@ struct drm_vc4_submit_cl { - uint8_t max_x_tile; - uint8_t max_y_tile; - struct drm_vc4_submit_rcl_surface color_read; -- struct drm_vc4_submit_rcl_surface color_ms_write; -+ struct drm_vc4_submit_rcl_surface color_write; - struct drm_vc4_submit_rcl_surface zs_read; - struct drm_vc4_submit_rcl_surface zs_write; -+ struct drm_vc4_submit_rcl_surface msaa_color_write; -+ struct drm_vc4_submit_rcl_surface msaa_zs_write; - uint32_t clear_color[2]; - uint32_t clear_z; - uint8_t clear_s; - -From 8c5854914cb7ffd1d418a4013b2089eec87600d2 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 8 Dec 2015 14:00:43 -0800 -Subject: [PATCH 113/251] drm/vc4: A few more non-functional changes to sync to - upstream. - -At this point all that's left is the force-enable of HDMI connector, -and using direct firmware calls to turn on V3D instead of the generic -power domain support. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_v3d.c | 2 +- - include/uapi/drm/vc4_drm.h | 182 +++++++++++++++++++++--------------------- - 2 files changed, 92 insertions(+), 92 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index 29a222f..4d103f7 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -109,7 +109,7 @@ static const struct { - - int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) - { -- struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - int i; -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 49cd992..eeb37e3 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -24,7 +24,7 @@ - #ifndef _UAPI_VC4_DRM_H_ - #define _UAPI_VC4_DRM_H_ - --#include -+#include "drm.h" - - #define DRM_VC4_SUBMIT_CL 0x00 - #define DRM_VC4_WAIT_SEQNO 0x01 -@@ -34,25 +34,25 @@ - #define DRM_VC4_CREATE_SHADER_BO 0x05 - #define DRM_VC4_GET_HANG_STATE 0x06 - --#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) --#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) --#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) --#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) --#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) --#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) --#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) -+#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) -+#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -+#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) -+#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) -+#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) -+#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) - - struct drm_vc4_submit_rcl_surface { -- uint32_t hindex; /* Handle index, or ~0 if not present. */ -- uint32_t offset; /* Offset to start of buffer. */ -+ __u32 hindex; /* Handle index, or ~0 if not present. */ -+ __u32 offset; /* Offset to start of buffer. */ - /* -- * Bits for either render config (color_write) or load/store packet. -- * Bits should all be 0 for MSAA load/stores. -+ * Bits for either render config (color_write) or load/store packet. -+ * Bits should all be 0 for MSAA load/stores. - */ -- uint16_t bits; -+ __u16 bits; - - #define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0) -- uint16_t flags; -+ __u16 flags; - }; - - /** -@@ -76,7 +76,7 @@ struct drm_vc4_submit_cl { - * then writes out the state updates and draw calls necessary per tile - * to the tile allocation BO. - */ -- uint64_t bin_cl; -+ __u64 bin_cl; - - /* Pointer to the shader records. - * -@@ -85,16 +85,16 @@ struct drm_vc4_submit_cl { - * reference to the shader record has enough information to determine - * how many pointers are necessary (fixed number for shaders/uniforms, - * and an attribute count), so those BO indices into bo_handles are -- * just stored as uint32_ts before each shader record passed in. -+ * just stored as __u32s before each shader record passed in. - */ -- uint64_t shader_rec; -+ __u64 shader_rec; - - /* Pointer to uniform data and texture handles for the textures - * referenced by the shader. - * - * For each shader state record, there is a set of uniform data in the - * order referenced by the record (FS, VS, then CS). Each set of -- * uniform data has a uint32_t index into bo_handles per texture -+ * uniform data has a __u32 index into bo_handles per texture - * sample operation, in the order the QPU_W_TMUn_S writes appear in - * the program. Following the texture BO handle indices is the actual - * uniform data. -@@ -103,52 +103,52 @@ struct drm_vc4_submit_cl { - * because the kernel has to determine the sizes anyway during shader - * code validation. - */ -- uint64_t uniforms; -- uint64_t bo_handles; -+ __u64 uniforms; -+ __u64 bo_handles; - - /* Size in bytes of the binner command list. */ -- uint32_t bin_cl_size; -+ __u32 bin_cl_size; - /* Size in bytes of the set of shader records. */ -- uint32_t shader_rec_size; -+ __u32 shader_rec_size; - /* Number of shader records. - * - * This could just be computed from the contents of shader_records and - * the address bits of references to them from the bin CL, but it - * keeps the kernel from having to resize some allocations it makes. - */ -- uint32_t shader_rec_count; -+ __u32 shader_rec_count; - /* Size in bytes of the uniform state. */ -- uint32_t uniforms_size; -+ __u32 uniforms_size; - - /* Number of BO handles passed in (size is that times 4). */ -- uint32_t bo_handle_count; -+ __u32 bo_handle_count; - - /* RCL setup: */ -- uint16_t width; -- uint16_t height; -- uint8_t min_x_tile; -- uint8_t min_y_tile; -- uint8_t max_x_tile; -- uint8_t max_y_tile; -+ __u16 width; -+ __u16 height; -+ __u8 min_x_tile; -+ __u8 min_y_tile; -+ __u8 max_x_tile; -+ __u8 max_y_tile; - struct drm_vc4_submit_rcl_surface color_read; - struct drm_vc4_submit_rcl_surface color_write; - struct drm_vc4_submit_rcl_surface zs_read; - struct drm_vc4_submit_rcl_surface zs_write; - struct drm_vc4_submit_rcl_surface msaa_color_write; - struct drm_vc4_submit_rcl_surface msaa_zs_write; -- uint32_t clear_color[2]; -- uint32_t clear_z; -- uint8_t clear_s; -+ __u32 clear_color[2]; -+ __u32 clear_z; -+ __u8 clear_s; - -- uint32_t pad:24; -+ __u32 pad:24; - - #define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) -- uint32_t flags; -+ __u32 flags; - - /* Returned value of the seqno of this render job (for the - * wait ioctl). - */ -- uint64_t seqno; -+ __u64 seqno; - }; - - /** -@@ -159,8 +159,8 @@ struct drm_vc4_submit_cl { - * block, just return the status." - */ - struct drm_vc4_wait_seqno { -- uint64_t seqno; -- uint64_t timeout_ns; -+ __u64 seqno; -+ __u64 timeout_ns; - }; - - /** -@@ -172,9 +172,9 @@ struct drm_vc4_wait_seqno { - * completed. - */ - struct drm_vc4_wait_bo { -- uint32_t handle; -- uint32_t pad; -- uint64_t timeout_ns; -+ __u32 handle; -+ __u32 pad; -+ __u64 timeout_ns; - }; - - /** -@@ -184,11 +184,30 @@ struct drm_vc4_wait_bo { - * used in a future extension. - */ - struct drm_vc4_create_bo { -- uint32_t size; -- uint32_t flags; -+ __u32 size; -+ __u32 flags; - /** Returned GEM handle for the BO. */ -- uint32_t handle; -- uint32_t pad; -+ __u32 handle; -+ __u32 pad; -+}; -+ -+/** -+ * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -+ * -+ * This doesn't actually perform an mmap. Instead, it returns the -+ * offset you need to use in an mmap on the DRM device node. This -+ * means that tools like valgrind end up knowing about the mapped -+ * memory. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_mmap_bo { -+ /** Handle for the object being mapped. */ -+ __u32 handle; -+ __u32 flags; -+ /** offset into the drm node to use for subsequent mmap call. */ -+ __u64 offset; - }; - - /** -@@ -201,43 +220,24 @@ struct drm_vc4_create_bo { - */ - struct drm_vc4_create_shader_bo { - /* Size of the data argument. */ -- uint32_t size; -+ __u32 size; - /* Flags, currently must be 0. */ -- uint32_t flags; -+ __u32 flags; - - /* Pointer to the data. */ -- uint64_t data; -+ __u64 data; - - /** Returned GEM handle for the BO. */ -- uint32_t handle; -+ __u32 handle; - /* Pad, must be 0. */ -- uint32_t pad; --}; -- --/** -- * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -- * -- * This doesn't actually perform an mmap. Instead, it returns the -- * offset you need to use in an mmap on the DRM device node. This -- * means that tools like valgrind end up knowing about the mapped -- * memory. -- * -- * There are currently no values for the flags argument, but it may be -- * used in a future extension. -- */ --struct drm_vc4_mmap_bo { -- /** Handle for the object being mapped. */ -- uint32_t handle; -- uint32_t flags; -- /** offset into the drm node to use for subsequent mmap call. */ -- uint64_t offset; -+ __u32 pad; - }; - - struct drm_vc4_get_hang_state_bo { -- uint32_t handle; -- uint32_t paddr; -- uint32_t size; -- uint32_t pad; -+ __u32 handle; -+ __u32 paddr; -+ __u32 size; -+ __u32 pad; - }; - - /** -@@ -246,34 +246,34 @@ struct drm_vc4_get_hang_state_bo { - */ - struct drm_vc4_get_hang_state { - /** Pointer to array of struct drm_vc4_get_hang_state_bo. */ -- uint64_t bo; -+ __u64 bo; - /** - * On input, the size of the bo array. Output is the number - * of bos to be returned. - */ -- uint32_t bo_count; -+ __u32 bo_count; - -- uint32_t start_bin, start_render; -+ __u32 start_bin, start_render; - -- uint32_t ct0ca, ct0ea; -- uint32_t ct1ca, ct1ea; -- uint32_t ct0cs, ct1cs; -- uint32_t ct0ra0, ct1ra0; -+ __u32 ct0ca, ct0ea; -+ __u32 ct1ca, ct1ea; -+ __u32 ct0cs, ct1cs; -+ __u32 ct0ra0, ct1ra0; - -- uint32_t bpca, bpcs; -- uint32_t bpoa, bpos; -+ __u32 bpca, bpcs; -+ __u32 bpoa, bpos; - -- uint32_t vpmbase; -+ __u32 vpmbase; - -- uint32_t dbge; -- uint32_t fdbgo; -- uint32_t fdbgb; -- uint32_t fdbgr; -- uint32_t fdbgs; -- uint32_t errstat; -+ __u32 dbge; -+ __u32 fdbgo; -+ __u32 fdbgb; -+ __u32 fdbgr; -+ __u32 fdbgs; -+ __u32 errstat; - - /* Pad that we may save more registers into in the future. */ -- uint32_t pad[16]; -+ __u32 pad[16]; - }; - - #endif /* _UAPI_VC4_DRM_H_ */ - -From 96201e14bde5eadd0a63d291930c6931206dd945 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 23:46:32 +0000 -Subject: [PATCH 114/251] drm/vc4: Use "hpd-gpios" for HDMI GPIO, like what - landed upstream. - -Signed-off-by: Eric Anholt ---- - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -index cf5d5c9..da37483 100644 ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -68,7 +68,7 @@ - <0x7e808000 0x100>; - interrupts = <2 8>, <2 9>; - ddc = <&i2c2>; -- hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>; -+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; - clocks = <&cprman BCM2835_PLLH_PIX>, - <&cprman BCM2835_CLOCK_HSM>; - clock-names = "pixel", "hdmi"; - -From c23f3c3bbf31b734f44040207eda9db1fdb3d565 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 7 Dec 2015 12:35:01 -0800 -Subject: [PATCH 115/251] drm/vc4: Synchronize validation code for v2 - submission upstream. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_drv.h | 24 +-- - drivers/gpu/drm/vc4/vc4_gem.c | 14 +- - drivers/gpu/drm/vc4/vc4_render_cl.c | 6 +- - drivers/gpu/drm/vc4/vc4_validate.c | 287 +++++++++++++++--------------------- - 4 files changed, 135 insertions(+), 196 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 53dfa8d..ed93fa7 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -189,17 +189,6 @@ to_vc4_encoder(struct drm_encoder *encoder) - #define HVS_READ(offset) readl(vc4->hvs->regs + offset) - #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) - --enum vc4_bo_mode { -- VC4_MODE_UNDECIDED, -- VC4_MODE_RENDER, -- VC4_MODE_SHADER, --}; -- --struct vc4_bo_exec_state { -- struct drm_gem_cma_object *bo; -- enum vc4_bo_mode mode; --}; -- - struct vc4_exec_info { - /* Sequence number for this bin/render job. */ - uint64_t seqno; -@@ -210,7 +199,7 @@ struct vc4_exec_info { - /* This is the array of BOs that were looked up at the start of exec. - * Command validation will use indices into this array. - */ -- struct vc4_bo_exec_state *bo; -+ struct drm_gem_cma_object **bo; - uint32_t bo_count; - - /* Pointers for our position in vc4->job_list */ -@@ -238,7 +227,6 @@ struct vc4_exec_info { - * command lists. - */ - struct vc4_shader_state { -- uint8_t packet; - uint32_t addr; - /* Maximum vertex index referenced by any primitive using this - * shader state. -@@ -254,6 +242,7 @@ struct vc4_exec_info { - bool found_tile_binning_mode_config_packet; - bool found_start_tile_binning_packet; - bool found_increment_semaphore_packet; -+ bool found_flush; - uint8_t bin_tiles_x, bin_tiles_y; - struct drm_gem_cma_object *tile_bo; - uint32_t tile_alloc_offset; -@@ -265,6 +254,9 @@ struct vc4_exec_info { - uint32_t ct0ca, ct0ea; - uint32_t ct1ca, ct1ea; - -+ /* Pointer to the unvalidated bin CL (if present). */ -+ void *bin_u; -+ - /* Pointers to the shader recs. These paddr gets incremented as CL - * packets are relocated in validate_gl_shader_state, and the vaddrs - * (u and v) get incremented and size decremented as the shader recs -@@ -455,10 +447,8 @@ vc4_validate_bin_cl(struct drm_device *dev, - int - vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); - --bool vc4_use_bo(struct vc4_exec_info *exec, -- uint32_t hindex, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj); -+struct drm_gem_cma_object *vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex); - - int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index fb0b92d..39f29e7 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -169,8 +169,8 @@ vc4_save_hang_state(struct drm_device *dev) - } - - for (i = 0; i < exec->bo_count; i++) { -- drm_gem_object_reference(&exec->bo[i].bo->base); -- kernel_state->bo[i] = &exec->bo[i].bo->base; -+ drm_gem_object_reference(&exec->bo[i]->base); -+ kernel_state->bo[i] = &exec->bo[i]->base; - } - - list_for_each_entry(bo, &exec->unref_list, unref_head) { -@@ -397,7 +397,7 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) - unsigned i; - - for (i = 0; i < exec->bo_count; i++) { -- bo = to_vc4_bo(&exec->bo[i].bo->base); -+ bo = to_vc4_bo(&exec->bo[i]->base); - bo->seqno = seqno; - } - -@@ -467,7 +467,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, - return -EINVAL; - } - -- exec->bo = kcalloc(exec->bo_count, sizeof(struct vc4_bo_exec_state), -+ exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *), - GFP_KERNEL); - if (!exec->bo) { - DRM_ERROR("Failed to allocate validated BO pointers\n"); -@@ -500,7 +500,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, - goto fail; - } - drm_gem_object_reference(bo); -- exec->bo[i].bo = (struct drm_gem_cma_object *)bo; -+ exec->bo[i] = (struct drm_gem_cma_object *)bo; - } - spin_unlock(&file_priv->table_lock); - -@@ -591,6 +591,8 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - - exec->ct0ca = exec->exec_bo->paddr + bin_offset; - -+ exec->bin_u = bin; -+ - exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; - exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; - exec->shader_rec_size = args->shader_rec_size; -@@ -622,7 +624,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) - mutex_lock(&dev->struct_mutex); - if (exec->bo) { - for (i = 0; i < exec->bo_count; i++) -- drm_gem_object_unreference(&exec->bo[i].bo->base); -+ drm_gem_object_unreference(&exec->bo[i]->base); - kfree(exec->bo); - } - -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 8f2ec57..8a2a312 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -436,7 +436,8 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - if (surf->hindex == ~0) - return 0; - -- if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) - return -EINVAL; - - if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -@@ -537,7 +538,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, - if (surf->hindex == ~0) - return 0; - -- if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) - return -EINVAL; - - if (tiling > VC4_TILING_FORMAT_LT) { -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index 2f22f19..0fb5b99 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -94,42 +94,42 @@ size_is_lt(uint32_t width, uint32_t height, int cpp) - height <= 4 * utile_height(cpp)); - } - --bool --vc4_use_bo(struct vc4_exec_info *exec, -- uint32_t hindex, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj) -+struct drm_gem_cma_object * -+vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) - { -- *obj = NULL; -+ struct drm_gem_cma_object *obj; -+ struct vc4_bo *bo; - - if (hindex >= exec->bo_count) { - DRM_ERROR("BO index %d greater than BO count %d\n", - hindex, exec->bo_count); -- return false; -+ return NULL; - } -+ obj = exec->bo[hindex]; -+ bo = to_vc4_bo(&obj->base); - -- if (exec->bo[hindex].mode != mode) { -- if (exec->bo[hindex].mode == VC4_MODE_UNDECIDED) { -- exec->bo[hindex].mode = mode; -- } else { -- DRM_ERROR("BO index %d reused with mode %d vs %d\n", -- hindex, exec->bo[hindex].mode, mode); -- return false; -- } -+ if (bo->validated_shader) { -+ DRM_ERROR("Trying to use shader BO as something other than " -+ "a shader\n"); -+ return NULL; - } - -- *obj = exec->bo[hindex].bo; -- return true; -+ return obj; -+} -+ -+static struct drm_gem_cma_object * -+vc4_use_handle(struct vc4_exec_info *exec, uint32_t gem_handles_packet_index) -+{ -+ return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index]); - } - - static bool --vc4_use_handle(struct vc4_exec_info *exec, -- uint32_t gem_handles_packet_index, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj) -+validate_bin_pos(struct vc4_exec_info *exec, void *untrusted, uint32_t pos) - { -- return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index], -- mode, obj); -+ /* Note that the untrusted pointer passed to these functions is -+ * incremented past the packet byte. -+ */ -+ return (untrusted - 1 == exec->bin_u + pos); - } - - static uint32_t -@@ -202,13 +202,13 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, - } - - static int --validate_flush_all(VALIDATE_ARGS) -+validate_flush(VALIDATE_ARGS) - { -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("VC4_PACKET_FLUSH_ALL after " -- "VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 1)) { -+ DRM_ERROR("Bin CL must end with VC4_PACKET_FLUSH\n"); - return -EINVAL; - } -+ exec->found_flush = true; - - return 0; - } -@@ -233,17 +233,13 @@ validate_start_tile_binning(VALIDATE_ARGS) - static int - validate_increment_semaphore(VALIDATE_ARGS) - { -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Duplicate VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 2)) { -+ DRM_ERROR("Bin CL must end with " -+ "VC4_PACKET_INCREMENT_SEMAPHORE\n"); - return -EINVAL; - } - exec->found_increment_semaphore_packet = true; - -- /* Once we've found the semaphore increment, there should be one FLUSH -- * then the end of the command list. The FLUSH actually triggers the -- * increment, so we only need to make sure there -- */ -- - return 0; - } - -@@ -257,11 +253,6 @@ validate_indexed_prim_list(VALIDATE_ARGS) - uint32_t index_size = (*(uint8_t *)(untrusted + 0) >> 4) ? 2 : 1; - struct vc4_shader_state *shader_state; - -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -- return -EINVAL; -- } -- - /* Check overflow condition */ - if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); -@@ -272,7 +263,8 @@ validate_indexed_prim_list(VALIDATE_ARGS) - if (max_index > shader_state->max_index) - shader_state->max_index = max_index; - -- if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &ib)) -+ ib = vc4_use_handle(exec, 0); -+ if (!ib) - return -EINVAL; - - if (offset > ib->base.size || -@@ -295,11 +287,6 @@ validate_gl_array_primitive(VALIDATE_ARGS) - uint32_t max_index; - struct vc4_shader_state *shader_state; - -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -- return -EINVAL; -- } -- - /* Check overflow condition */ - if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); -@@ -329,7 +316,6 @@ validate_gl_shader_state(VALIDATE_ARGS) - return -EINVAL; - } - -- exec->shader_state[i].packet = VC4_PACKET_GL_SHADER_STATE; - exec->shader_state[i].addr = *(uint32_t *)untrusted; - exec->shader_state[i].max_index = 0; - -@@ -348,31 +334,6 @@ validate_gl_shader_state(VALIDATE_ARGS) - } - - static int --validate_nv_shader_state(VALIDATE_ARGS) --{ -- uint32_t i = exec->shader_state_count++; -- -- if (i >= exec->shader_state_size) { -- DRM_ERROR("More requests for shader states than declared\n"); -- return -EINVAL; -- } -- -- exec->shader_state[i].packet = VC4_PACKET_NV_SHADER_STATE; -- exec->shader_state[i].addr = *(uint32_t *)untrusted; -- -- if (exec->shader_state[i].addr & 15) { -- DRM_ERROR("NV shader state address 0x%08x misaligned\n", -- exec->shader_state[i].addr); -- return -EINVAL; -- } -- -- *(uint32_t *)validated = (exec->shader_state[i].addr + -- exec->shader_rec_p); -- -- return 0; --} -- --static int - validate_tile_binning_config(VALIDATE_ARGS) - { - struct drm_device *dev = exec->exec_bo->base.dev; -@@ -473,8 +434,8 @@ static const struct cmd_info { - } cmd_info[] = { - VC4_DEFINE_PACKET(VC4_PACKET_HALT, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_NOP, NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, validate_flush), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, - validate_start_tile_binning), - VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, -@@ -488,7 +449,6 @@ static const struct cmd_info { - VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, NULL), - - VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, validate_gl_shader_state), -- VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, validate_nv_shader_state), - - VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, NULL), -@@ -575,8 +535,16 @@ vc4_validate_bin_cl(struct drm_device *dev, - return -EINVAL; - } - -- if (!exec->found_increment_semaphore_packet) { -- DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ /* The bin CL must be ended with INCREMENT_SEMAPHORE and FLUSH. The -+ * semaphore is used to trigger the render CL to start up, and the -+ * FLUSH is what caps the bin lists with -+ * VC4_PACKET_RETURN_FROM_SUB_LIST (so they jump back to the main -+ * render CL when they get called to) and actually triggers the queued -+ * semaphore increment. -+ */ -+ if (!exec->found_increment_semaphore_packet || !exec->found_flush) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + " -+ "VC4_PACKET_FLUSH\n"); - return -EINVAL; - } - -@@ -607,7 +575,8 @@ reloc_tex(struct vc4_exec_info *exec, - uint32_t cube_map_stride = 0; - enum vc4_texture_data_type type; - -- if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex)) -+ tex = vc4_use_bo(exec, texture_handle_index); -+ if (!tex) - return false; - - if (sample->is_direct) { -@@ -755,51 +724,28 @@ reloc_tex(struct vc4_exec_info *exec, - } - - static int --validate_shader_rec(struct drm_device *dev, -- struct vc4_exec_info *exec, -- struct vc4_shader_state *state) -+validate_gl_shader_rec(struct drm_device *dev, -+ struct vc4_exec_info *exec, -+ struct vc4_shader_state *state) - { - uint32_t *src_handles; - void *pkt_u, *pkt_v; -- enum shader_rec_reloc_type { -- RELOC_CODE, -- RELOC_VBO, -- }; -- struct shader_rec_reloc { -- enum shader_rec_reloc_type type; -- uint32_t offset; -- }; -- static const struct shader_rec_reloc gl_relocs[] = { -- { RELOC_CODE, 4 }, /* fs */ -- { RELOC_CODE, 16 }, /* vs */ -- { RELOC_CODE, 28 }, /* cs */ -- }; -- static const struct shader_rec_reloc nv_relocs[] = { -- { RELOC_CODE, 4 }, /* fs */ -- { RELOC_VBO, 12 } -+ static const uint32_t shader_reloc_offsets[] = { -+ 4, /* fs */ -+ 16, /* vs */ -+ 28, /* cs */ - }; -- const struct shader_rec_reloc *relocs; -- struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; -- uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; -+ uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets); -+ struct drm_gem_cma_object *bo[shader_reloc_count + 8]; -+ uint32_t nr_attributes, nr_relocs, packet_size; - int i; -- struct vc4_validated_shader_info *shader; - -- if (state->packet == VC4_PACKET_NV_SHADER_STATE) { -- relocs = nv_relocs; -- nr_fixed_relocs = ARRAY_SIZE(nv_relocs); -- -- packet_size = 16; -- } else { -- relocs = gl_relocs; -- nr_fixed_relocs = ARRAY_SIZE(gl_relocs); -- -- nr_attributes = state->addr & 0x7; -- if (nr_attributes == 0) -- nr_attributes = 8; -- packet_size = gl_shader_rec_size(state->addr); -- } -- nr_relocs = nr_fixed_relocs + nr_attributes; -+ nr_attributes = state->addr & 0x7; -+ if (nr_attributes == 0) -+ nr_attributes = 8; -+ packet_size = gl_shader_rec_size(state->addr); - -+ nr_relocs = ARRAY_SIZE(shader_reloc_offsets) + nr_attributes; - if (nr_relocs * 4 > exec->shader_rec_size) { - DRM_ERROR("overflowed shader recs reading %d handles " - "from %d bytes left\n", -@@ -829,21 +775,30 @@ validate_shader_rec(struct drm_device *dev, - exec->shader_rec_v += roundup(packet_size, 16); - exec->shader_rec_size -= packet_size; - -- for (i = 0; i < nr_relocs; i++) { -- enum vc4_bo_mode mode; -+ if (!(*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD)) { -+ DRM_ERROR("Multi-threaded fragment shaders not supported.\n"); -+ return -EINVAL; -+ } - -- if (i < nr_fixed_relocs && relocs[i].type == RELOC_CODE) -- mode = VC4_MODE_SHADER; -- else -- mode = VC4_MODE_RENDER; -+ for (i = 0; i < shader_reloc_count; i++) { -+ if (src_handles[i] > exec->bo_count) { -+ DRM_ERROR("Shader handle %d too big\n", src_handles[i]); -+ return -EINVAL; -+ } - -- if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) -- return false; -+ bo[i] = exec->bo[src_handles[i]]; -+ if (!bo[i]) -+ return -EINVAL; -+ } -+ for (i = shader_reloc_count; i < nr_relocs; i++) { -+ bo[i] = vc4_use_bo(exec, src_handles[i]); -+ if (!bo[i]) -+ return -EINVAL; - } - -- for (i = 0; i < nr_fixed_relocs; i++) { -- struct vc4_bo *vc4_bo; -- uint32_t o = relocs[i].offset; -+ for (i = 0; i < shader_reloc_count; i++) { -+ struct vc4_validated_shader_info *validated_shader; -+ uint32_t o = shader_reloc_offsets[i]; - uint32_t src_offset = *(uint32_t *)(pkt_u + o); - uint32_t *texture_handles_u; - void *uniform_data_u; -@@ -851,57 +806,50 @@ validate_shader_rec(struct drm_device *dev, - - *(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset; - -- switch (relocs[i].type) { -- case RELOC_CODE: -- if (src_offset != 0) { -- DRM_ERROR("Shaders must be at offset 0 " -- "of the BO.\n"); -- goto fail; -- } -+ if (src_offset != 0) { -+ DRM_ERROR("Shaders must be at offset 0 of " -+ "the BO.\n"); -+ return -EINVAL; -+ } - -- vc4_bo = to_vc4_bo(&bo[i]->base); -- shader = vc4_bo->validated_shader; -- if (!shader) -- goto fail; -+ validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -+ if (!validated_shader) -+ return -EINVAL; - -- if (shader->uniforms_src_size > exec->uniforms_size) { -- DRM_ERROR("Uniforms src buffer overflow\n"); -- goto fail; -- } -+ if (validated_shader->uniforms_src_size > -+ exec->uniforms_size) { -+ DRM_ERROR("Uniforms src buffer overflow\n"); -+ return -EINVAL; -+ } - -- texture_handles_u = exec->uniforms_u; -- uniform_data_u = (texture_handles_u + -- shader->num_texture_samples); -- -- memcpy(exec->uniforms_v, uniform_data_u, -- shader->uniforms_size); -- -- for (tex = 0; -- tex < shader->num_texture_samples; -- tex++) { -- if (!reloc_tex(exec, -- uniform_data_u, -- &shader->texture_samples[tex], -- texture_handles_u[tex])) { -- goto fail; -- } -- } -+ texture_handles_u = exec->uniforms_u; -+ uniform_data_u = (texture_handles_u + -+ validated_shader->num_texture_samples); - -- *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; -+ memcpy(exec->uniforms_v, uniform_data_u, -+ validated_shader->uniforms_size); - -- exec->uniforms_u += shader->uniforms_src_size; -- exec->uniforms_v += shader->uniforms_size; -- exec->uniforms_p += shader->uniforms_size; -+ for (tex = 0; -+ tex < validated_shader->num_texture_samples; -+ tex++) { -+ if (!reloc_tex(exec, -+ uniform_data_u, -+ &validated_shader->texture_samples[tex], -+ texture_handles_u[tex])) { -+ return -EINVAL; -+ } -+ } - -- break; -+ *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; - -- case RELOC_VBO: -- break; -- } -+ exec->uniforms_u += validated_shader->uniforms_src_size; -+ exec->uniforms_v += validated_shader->uniforms_size; -+ exec->uniforms_p += validated_shader->uniforms_size; - } - - for (i = 0; i < nr_attributes; i++) { -- struct drm_gem_cma_object *vbo = bo[nr_fixed_relocs + i]; -+ struct drm_gem_cma_object *vbo = -+ bo[ARRAY_SIZE(shader_reloc_offsets) + i]; - uint32_t o = 36 + i * 8; - uint32_t offset = *(uint32_t *)(pkt_u + o + 0); - uint32_t attr_size = *(uint8_t *)(pkt_u + o + 4) + 1; -@@ -933,9 +881,6 @@ validate_shader_rec(struct drm_device *dev, - } - - return 0; -- --fail: -- return -EINVAL; - } - - int -@@ -946,7 +891,7 @@ vc4_validate_shader_recs(struct drm_device *dev, - int ret = 0; - - for (i = 0; i < exec->shader_state_count; i++) { -- ret = validate_shader_rec(dev, exec, &exec->shader_state[i]); -+ ret = validate_gl_shader_rec(dev, exec, &exec->shader_state[i]); - if (ret) - return ret; - } - -From 677855b754d34a5fc02b572d3605e0a6ff754843 Mon Sep 17 00:00:00 2001 -From: janluca -Date: Sun, 27 Dec 2015 14:34:04 +0100 -Subject: [PATCH 116/251] MMC: Do not use mmc_debug if CONFIG_MMC_BCM2835 is - not set - -If CONFIG_MMC_BCM2835 was not set the compiling of the kernel failed -since mmc_debug was not defined but used in drivers/mmc/core/quirks.c. - -This patch add a ifdef-check for CONFIG_MMC_BCM2835 to the change of -commit 64d395457f793250d2e582eeb38cc3403b1db98c ---- - drivers/mmc/core/quirks.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index 87ae2e9..b79fe14 100644 ---- a/drivers/mmc/core/quirks.c -+++ b/drivers/mmc/core/quirks.c -@@ -53,7 +53,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { - - void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - { -+#ifdef CONFIG_MMC_BCM2835 - extern unsigned mmc_debug; -+#endif - const struct mmc_fixup *f; - u64 rev = cid_rev_card(card); - -@@ -81,7 +83,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. - * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). - */ -+#ifdef CONFIG_MMC_BCM2835 - if (mmc_debug & (1<<13)) - card->quirks |= MMC_QUIRK_BLK_NO_CMD23; -+#endif - } - EXPORT_SYMBOL(mmc_fixup_device); - -From 6c2f1c57e559b53e84735f0a38ad50e8177b3f4d Mon Sep 17 00:00:00 2001 -From: Devon Fyson -Date: Wed, 30 Dec 2015 16:40:47 -0500 -Subject: [PATCH 117/251] Extend clock timeout, fix modprobe baudrate - parameter. - -Set the BSC_CLKT clock streching timeout to 35ms as per SMBus specs.\n- Increase priority of baudrate parameter passed to modprobe (in /etc/modprobe.d/*.conf or command line). Currently custom baudrates don't work because they are overridden by clock-frequency in the platform_device passed to the function. ---- - drivers/i2c/busses/i2c-bcm2708.c | 45 ++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 16 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 85f411c..b152639 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -71,7 +71,8 @@ - - #define DRV_NAME "bcm2708_i2c" - --static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; -+static unsigned int baudrate_default = CONFIG_I2C_BCM2708_BAUDRATE; -+static unsigned int baudrate; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - MODULE_PARM_DESC(baudrate, "The I2C baudrate"); - -@@ -87,6 +88,7 @@ struct bcm2708_i2c { - int irq; - struct clk *clk; - u32 cdiv; -+ u32 clk_tout; - - struct completion done; - -@@ -126,7 +128,7 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) - - static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - { -- u32 cdiv, s; -+ u32 cdiv, s, clk_tout; - u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; - int wait_loops = I2C_WAIT_LOOP_COUNT; - -@@ -134,12 +136,14 @@ static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - * Use the value that we cached in the probe. - */ - cdiv = bi->cdiv; -+ clk_tout = bi->clk_tout; - - if (bi->msg->flags & I2C_M_RD) - c |= BSC_C_INTR | BSC_C_READ; - else - c |= BSC_C_INTT; - -+ bcm2708_wr(bi, BSC_CLKT, clk_tout); - bcm2708_wr(bi, BSC_DIV, cdiv); - bcm2708_wr(bi, BSC_A, bi->msg->addr); - bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -@@ -312,21 +316,24 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - struct bcm2708_i2c *bi; - struct i2c_adapter *adap; - unsigned long bus_hz; -- u32 cdiv; -- -- if (pdev->dev.of_node) { -- u32 bus_clk_rate; -- pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -- if (pdev->id < 0) { -- dev_err(&pdev->dev, "alias is missing\n"); -- return -EINVAL; -+ u32 cdiv, clk_tout; -+ -+ if (!baudrate) { -+ baudrate = baudrate_default; -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; -+ } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); - } -- if (!of_property_read_u32(pdev->dev.of_node, -- "clock-frequency", &bus_clk_rate)) -- baudrate = bus_clk_rate; -- else -- dev_warn(&pdev->dev, -- "Could not read clock-frequency property\n"); - } - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -417,7 +424,13 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - cdiv = 0xffff; - baudrate = bus_hz / cdiv; - } -+ -+ clk_tout = 35/1000*baudrate; //35ms timeout as per SMBus specs. -+ if (clk_tout > 0xffff) -+ clk_tout = 0xffff; -+ - bi->cdiv = cdiv; -+ bi->clk_tout = clk_tout; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", - pdev->id, (unsigned long)regs->start, irq, baudrate); - -From 138eda1c8216d04356fa821fe6500771bf14fb10 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 31 Dec 2015 16:44:58 +0100 -Subject: [PATCH 118/251] bcm270x_dt: Add dwc2 and dwc-otg overlays - ---- - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 21 +++++++++++++++++++ - arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 20 ++++++++++++++++++ - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 29 ++++++++++++++++++++++++++ - 4 files changed, 72 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/dwc-otg-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/dwc2-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index be9dead..aaa8976 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,8 @@ endif - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dwc2-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dwc-otg-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d0ef256..4d3f974 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -198,6 +198,27 @@ Params: gpiopin GPIO connected to the sensor's DATA output. - (default 4) - - -+Name: dwc-otg -+Info: Selects the dwc_otg USB controller driver which has fiq support. This -+ is the default on all except the Pi Zero which defaults to dwc2. -+Load: dtoverlay=dwc-otg -+Params: -+ -+ -+Name: dwc2 -+Info: Selects the dwc2 USB controller driver -+Load: dtoverlay=dwc2,= -+Params: dr_mode Dual role mode: "host", "peripheral" or "otg" -+ -+ g-rx-fifo-size Size of rx fifo size in gadget mode -+ -+ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -+ mode -+ -+ g-tx-fifo-size Size of periodic tx fifo per endpoint -+ (except ep0) in gadget mode -+ -+ - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] - - -diff --git a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -new file mode 100644 -index 0000000..fc48bd1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&usb>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ __overlay__ { -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -new file mode 100644 -index 0000000..90c9811 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -0,0 +1,29 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&usb>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ __overlay__ { -+ compatible = "brcm,bcm2835-usb"; -+ reg = <0x7e980000 0x10000>; -+ interrupts = <1 9>; -+ dr_mode = "otg"; -+ g-np-tx-fifo-size = <32>; -+ g-rx-fifo-size = <256>; -+ g-tx-fifo-size = <256 128 128 64 64 64 32>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ dr_mode = <&usb>, "dr_mode"; -+ g-np-tx-fifo-size = <&usb>,"g-np-tx-fifo-size:0"; -+ g-rx-fifo-size = <&usb>,"g-rx-fifo-size:0"; -+ g-tx-fifo-size = <&usb>,"g-tx-fifo-size:0"; -+ }; -+}; - -From 534a6b55b445527c1a8aef9f0328987cb2c1c1d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Jan 2016 14:42:17 +0000 -Subject: [PATCH 119/251] BCM270X_DT: Add the sdtweak overlay, for tuning - sdhost - -The sdhost overlay declares the sdhost interface and allows parameters -to be set. This is overkill for situations where the user just wants to -tweak the parameters of a pre-declared sdhost interface, so create an -sdtweak overlay that does just that. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 ++++++++++++++ - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 21 +++++++++++++++++++++ - 3 files changed, 36 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index aaa8976..4d9d640 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -53,6 +53,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4d3f974..1c6b000 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -635,6 +635,20 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - (default on: polling once at boot-time) - - -+Name: sdtweak -+Info: Tunes the bcm2835-sdhost SD/MMC driver -+Load: dtoverlay=sdtweak,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ - Name: smi - Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! - Load: dtoverlay=smi -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -new file mode 100644 -index 0000000..74c168d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -0,0 +1,21 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sdhost>; -+ frag1: __overlay__ { -+ brcm,overclock-50 = <0>; -+ brcm,pio-limit = <1>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&frag1>,"brcm,overclock-50:0"; -+ force_pio = <&frag1>,"brcm,force-pio?"; -+ pio_limit = <&frag1>,"brcm,pio-limit:0"; -+ debug = <&frag1>,"brcm,debug?"; -+ }; -+}; - -From baed92c64a0b70434069ec7f8cb906e33f7d50b4 Mon Sep 17 00:00:00 2001 -From: Andrew Litt -Date: Mon, 11 Jan 2016 07:54:21 +0000 -Subject: [PATCH 120/251] bcm2835-mmc: Don't override bus width capabilities - from devicetree - -Take out the force setting of the MMC_CAP_4_BIT_DATA host capability -so that the result read from devicetree via mmc_of_parse() is -preserved. ---- - drivers/mmc/host/bcm2835-mmc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 43aed6e..104f93e 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1305,7 +1305,7 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - /* host controller capabilities */ - mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | - MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -- MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; -+ MMC_CAP_MMC_HIGHSPEED; - - mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; - - -From 2a12d02d01ad199df7c17296243ddef8a9ca6c33 Mon Sep 17 00:00:00 2001 -From: Andrew Litt -Date: Mon, 11 Jan 2016 07:55:54 +0000 -Subject: [PATCH 121/251] SDIO-overlay: add bus_width parameter - -Allow setting of the SDIO bus width capability of the bcm2835-mmc -host. This is helpful when only a 1 bit wide bus is connected -between host and device but both host and device advertise 4 bit -mode. ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1c6b000..34a1b7f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -634,6 +634,8 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - poll_once Disable SDIO-device polling every second - (default on: polling once at boot-time) - -+ bus_width Set the SDIO host bus width (default 4 bits) -+ - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -index afc8742..7935e7a 100644 ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -11,6 +11,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; - non-removable; -+ bus-width = <4>; - status = "okay"; - }; - }; -@@ -28,5 +29,6 @@ - - __overrides__ { - poll_once = <&sdio_mmc>,"non-removable?"; -+ bus_width = <&sdio_mmc>,"bus-width:0"; - }; - }; - -From 1589aee29dc9d1fafe145b75a018771ed993e869 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:41:45 +0100 -Subject: [PATCH 122/251] bcm2835: extend allowed range of channels and - samplerates - -Allow everything the videocore accepts. ---- - sound/arm/bcm2835-pcm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 8c86375..31e3131 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -26,9 +26,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 1, -- .channels_max = 2, -+ .channels_max = 8, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, -@@ -43,9 +43,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 44100, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 2, -- .channels_max = 2, -+ .channels_max = 8, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, - -From 768a8ae2b4eebe250c3872901caae49ecf92b483 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:42:18 +0100 -Subject: [PATCH 123/251] bcm2835: restrict channels*rate to 8*960000 - -This is required at least for SPDIF. If the bitrate goes above, -videocore will either resample the audio or corrupt it due to -underruns. Supposedly the hardware isn't designed to output -higher rates, but it can still resample it down to supported -rates. - -Some code is based on ac97_pcm.c. ---- - sound/arm/bcm2835-pcm.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 31e3131..b17ed32 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -19,6 +19,9 @@ - - #include "bcm2835.h" - -+/* The hardware can not do much more num_channels*samplerate then this value */ -+#define MAX_COMBINED_RATE 768000 -+ - /* hardware definition */ - static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -@@ -107,6 +110,31 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+ -+static int rate_hw_constraint_rate(struct snd_pcm_hw_params *params, -+ struct snd_pcm_hw_rule *rule) -+{ -+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); -+ struct snd_interval rates = { -+ .min = 8000, -+ .max = min(192000u, MAX_COMBINED_RATE / max(channels->min, 1u)), -+ }; -+ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); -+ return snd_interval_refine(rate, &rates); -+} -+ -+static int rate_hw_constraint_channels(struct snd_pcm_hw_params *params, -+ struct snd_pcm_hw_rule *rule) -+{ -+ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); -+ struct snd_interval channels_interval = { -+ .min = 1, -+ .max = min(8u, MAX_COMBINED_RATE / max(rate->min, 1u)), -+ }; -+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); -+ return snd_interval_refine(channels, &channels_interval); -+} -+ - /* open callback */ - static int snd_bcm2835_playback_open_generic( - struct snd_pcm_substream *substream, int spdif) -@@ -188,6 +216,19 @@ static int snd_bcm2835_playback_open_generic( - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - 16); - -+ /* When playing PCM, pretend that we support the full range of channels -+ * and sample rates. The GPU can't output it, but is able to resample -+ * the data to a rate the hardware can handle it. This won't work with -+ * compressed data; the resampler would just destroy it. */ -+ if (spdif) { -+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, -+ rate_hw_constraint_rate, NULL, -+ SNDRV_PCM_HW_PARAM_CHANNELS, -1); -+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, -+ rate_hw_constraint_channels, NULL, -+ SNDRV_PCM_HW_PARAM_RATE, -1); -+ } -+ - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); - -From 19d09a4d7b66ffed44ec5b9da81304f3a11f4586 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:42:48 +0100 -Subject: [PATCH 124/251] rpi: update vc_vchi_audioserv_defs.h - -Add audioserv 3 extensions. The changes were taken from the paste -linked here: - -https://github.com/raspberrypi/linux/pull/1166#issuecomment-151917067 ---- - sound/arm/vc_vchi_audioserv_defs.h | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/sound/arm/vc_vchi_audioserv_defs.h b/sound/arm/vc_vchi_audioserv_defs.h -index af3e6eb..5f4409f 100644 ---- a/sound/arm/vc_vchi_audioserv_defs.h -+++ b/sound/arm/vc_vchi_audioserv_defs.h -@@ -16,7 +16,7 @@ - #define _VC_AUDIO_DEFS_H_ - - #define VC_AUDIOSERV_MIN_VER 1 --#define VC_AUDIOSERV_VER 2 -+#define VC_AUDIOSERV_VER 3 - - // FourCC code used for VCHI connection - #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") -@@ -36,6 +36,7 @@ typedef enum { - VC_AUDIO_MSG_TYPE_START, // Configure audio - VC_AUDIO_MSG_TYPE_STOP, // Configure audio - VC_AUDIO_MSG_TYPE_WRITE, // Configure audio -+ VC_AUDIO_MSG_TYPE_LATENCY, // request latency in cycles - VC_AUDIO_MSG_TYPE_MAX - } VC_AUDIO_MSG_TYPE; - -@@ -44,6 +45,7 @@ typedef struct { - uint32_t channels; - uint32_t samplerate; - uint32_t bps; -+ uint32_t channelmap; - - } VC_AUDIO_CONFIG_T; - -@@ -84,6 +86,12 @@ typedef struct { - uint16_t max_packet; - } VC_AUDIO_WRITE_T; - -+// query latency in samples of sink -+typedef struct -+{ -+ uint32_t dummy; -+} VC_AUDIO_LATENCY_T; -+ - // Generic result for a request (VC->HOST) - typedef struct { - int32_t success; // Success value -@@ -108,9 +116,10 @@ typedef struct { - VC_AUDIO_START_T start; - VC_AUDIO_STOP_T stop; - VC_AUDIO_WRITE_T write; -+ VC_AUDIO_LATENCY_T latency; - VC_AUDIO_RESULT_T result; - VC_AUDIO_COMPLETE_T complete; - } u; - } VC_AUDIO_MSG_T; - --#endif // _VC_AUDIO_DEFS_H_ -+#endif // _VC_AUDIO_DEFS_H_ -\ No newline at end of file - -From c507443d3266d9f0cbdc1832089ad90b8943f48b Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:43:12 +0100 -Subject: [PATCH 125/251] bcm2835: implement channel map API - -Report all layouts supported by the HDMI protocol to userspace. -Make the videocore set the correct layout according to the -userspace request. - -Some code taken from patch_hdmi.c. In particular, the HDMI channel -layout table was copied without changes - with the idea in mind that -hopefully it can be shared one day. Or at least updating it will be -simpler. - -In my tests, everything appears to work, except when outputting -FL FR RL RR. Then my receiver outputs RL on both the RL and RR -speakers, while RR is never heard. ---- - sound/arm/bcm2835-ctl.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++ - sound/arm/bcm2835-pcm.c | 22 +++- - sound/arm/bcm2835-vchiq.c | 13 +++ - sound/arm/bcm2835.h | 4 + - 4 files changed, 311 insertions(+), 4 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index aad905f..92d3f76 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -300,6 +300,281 @@ static struct snd_kcontrol_new snd_bcm2835_spdif[] = { - }, - }; - -+struct cea_channel_speaker_allocation { -+ int ca_index; -+ int speakers[8]; -+}; -+ -+#define FL SNDRV_CHMAP_FL -+#define FR SNDRV_CHMAP_FR -+#define RL SNDRV_CHMAP_RL -+#define RR SNDRV_CHMAP_RR -+#define LFE SNDRV_CHMAP_LFE -+#define FC SNDRV_CHMAP_FC -+#define RLC SNDRV_CHMAP_RLC -+#define RRC SNDRV_CHMAP_RRC -+#define RC SNDRV_CHMAP_RC -+#define FLC SNDRV_CHMAP_FLC -+#define FRC SNDRV_CHMAP_FRC -+#define FLH SNDRV_CHMAP_TFL -+#define FRH SNDRV_CHMAP_TFR -+#define FLW SNDRV_CHMAP_FLW -+#define FRW SNDRV_CHMAP_FRW -+#define TC SNDRV_CHMAP_TC -+#define FCH SNDRV_CHMAP_TFC -+ -+/* -+ * CEA-861 channel maps -+ * -+ * Stolen from sound/pci/hda/patch_hdmi.c -+ * (unlike the source, this uses SNDRV_* constants directly, as by the -+ * map_tables array in patch_hdmi.c) -+ * Unknown entries use 0, which unfortunately is SNDRV_CHMAP_UNKNOWN instead -+ * of SNDRV_CHMAP_NA. -+ */ -+static struct cea_channel_speaker_allocation channel_allocations[] = { -+/* channel: 7 6 5 4 3 2 1 0 */ -+{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, -+ /* 2.1 */ -+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, -+ /* Dolby Surround */ -+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, -+ /* surround40 */ -+{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, -+ /* surround41 */ -+{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, -+ /* surround50 */ -+{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, -+ /* surround51 */ -+{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, -+ /* 6.1 */ -+{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, -+ /* surround71 */ -+{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, -+ -+{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, -+{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, -+{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, -+}; -+ -+static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, -+ unsigned int size, unsigned int __user *tlv) -+{ -+ unsigned int __user *dst; -+ int count = 0; -+ int i; -+ -+ if (size < 8) -+ return -ENOMEM; -+ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) -+ return -EFAULT; -+ size -= 8; -+ dst = tlv + 2; -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; -+ int num_chs = 0; -+ int chs_bytes; -+ int c; -+ -+ for (c = 0; c < 8; c++) { -+ if (ch->speakers[c]) -+ num_chs++; -+ } -+ -+ chs_bytes = num_chs * 4; -+ if (size < 8) -+ return -ENOMEM; -+ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || -+ put_user(chs_bytes, dst + 1)) -+ return -EFAULT; -+ dst += 2; -+ size -= 8; -+ count += 8; -+ if (size < chs_bytes) -+ return -ENOMEM; -+ size -= chs_bytes; -+ count += chs_bytes; -+ for (c = 0; c < 8; c++) { -+ int sp = ch->speakers[7 - c]; -+ if (sp) { -+ if (put_user(sp, dst)) -+ return -EFAULT; -+ dst++; -+ } -+ } -+ } -+ if (put_user(count, tlv + 1)) -+ return -EFAULT; -+ return 0; -+} -+ -+static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; -+ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -+ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); -+ struct cea_channel_speaker_allocation *ch = NULL; -+ int cur = 0; -+ int i; -+ -+ if (!substream || !substream->runtime) -+ return -ENODEV; -+ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ if (channel_allocations[i].ca_index == chip->cea_chmap) -+ ch = &channel_allocations[i]; -+ } -+ -+ /* If no layout was set yet, return a dummy. Apparently the userspace -+ * API will be confused if we don't. */ -+ if (!ch) -+ ch = &channel_allocations[0]; -+ -+ for (i = 0; i < 8; i++) { -+ if (ch->speakers[7 - i]) -+ ucontrol->value.integer.value[cur++] = ch->speakers[7 - i]; -+ } -+ while (cur < 8) -+ ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; -+ return 0; -+} -+ -+static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; -+ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -+ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); -+ int i, prepared = 0, cea_chmap = -1; -+ int remap[8]; -+ -+ if (!substream || !substream->runtime) -+ return -ENODEV; -+ -+ switch (substream->runtime->status->state) { -+ case SNDRV_PCM_STATE_OPEN: -+ case SNDRV_PCM_STATE_SETUP: -+ break; -+ case SNDRV_PCM_STATE_PREPARED: -+ prepared = 1; -+ break; -+ default: -+ return -EBUSY; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; -+ int matches = 1; -+ int cur = 0; -+ int x; -+ memset(remap, 0, sizeof(remap)); -+ for (x = 0; x < substream->runtime->channels; x++) { -+ int sp = ucontrol->value.integer.value[x]; -+ while (cur < 8 && !ch->speakers[7 - cur]) -+ cur++; -+ if (cur >= 8) { -+ /* user has more channels than ch */ -+ matches = 0; -+ break; -+ } -+ if (ch->speakers[7 - cur] != sp) { -+ matches = 0; -+ break; -+ } -+ remap[x] = cur; -+ cur++; -+ } -+ for (x = cur; x < 8; x++) { -+ if (ch->speakers[7 - x]) { -+ /* ch has more channels than user */ -+ matches = 0; -+ break; -+ } -+ } -+ if (matches) { -+ cea_chmap = ch->ca_index; -+ break; -+ } -+ } -+ -+ if (cea_chmap < 0) -+ return -EINVAL; -+ -+ /* don't change the layout if another substream is active */ -+ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) -+ return -EBUSY; /* unsure whether this is a good error code */ -+ -+ chip->cea_chmap = cea_chmap; -+ for (i = 0; i < 8; i++) -+ chip->map_channels[i] = remap[i]; -+ if (prepared) -+ snd_bcm2835_pcm_prepare_again(substream); -+ return 0; -+} -+ -+static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) -+{ -+ struct snd_pcm_chmap *chmap; -+ struct snd_kcontrol *kctl; -+ int err, i; -+ -+ err = snd_pcm_add_chmap_ctls(chip->pcm, -+ SNDRV_PCM_STREAM_PLAYBACK, -+ NULL, 8, 0, &chmap); -+ if (err < 0) -+ return err; -+ /* override handlers */ -+ chmap->private_data = chip; -+ kctl = chmap->kctl; -+ for (i = 0; i < kctl->count; i++) -+ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; -+ kctl->get = snd_bcm2835_chmap_ctl_get; -+ kctl->put = snd_bcm2835_chmap_ctl_put; -+ kctl->tlv.c = snd_bcm2835_chmap_ctl_tlv; -+ return 0; -+} -+ - int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) - { - int err; -@@ -313,6 +588,7 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) - if (err < 0) - return err; - } -+ snd_bcm2835_add_chmap_ctl(chip); - for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index b17ed32..1067460 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -231,6 +231,9 @@ static int snd_bcm2835_playback_open_generic( - - chip->alsa_stream[idx] = alsa_stream; - -+ if (!chip->opened) -+ chip->cea_chmap = -1; -+ - chip->opened |= (1 << idx); - alsa_stream->open = 1; - alsa_stream->draining = 1; -@@ -341,8 +344,7 @@ static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) - return snd_pcm_lib_free_pages(substream); - } - --/* prepare callback */ --static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) -+int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream) - { - bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; -@@ -350,8 +352,6 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - int channels; - int err; - -- audio_info(" .. IN\n"); -- - /* notify the vchiq that it should enter spdif passthrough mode by - * setting channels=0 (see - * https://github.com/raspberrypi/linux/issues/528) */ -@@ -367,6 +367,20 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - audio_error(" error setting hw params\n"); - } - -+ return err; -+} -+ -+/* prepare callback */ -+static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; -+ -+ audio_info(" .. IN\n"); -+ -+ snd_bcm2835_pcm_prepare_again(substream); -+ - bcm2835_audio_setup(alsa_stream); - - /* in preparation of the stream, set the controls (volume level) of the stream */ -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 3de3094..8ecd2d7 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -570,6 +570,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - VC_AUDIO_MSG_T m; - AUDIO_INSTANCE_T *instance = alsa_stream->instance; - int32_t success; -+ uint32_t chmap_value; -+ int i; - int ret; - LOG_DBG(" .. IN\n"); - -@@ -593,10 +595,21 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - - instance->result = -1; - -+ if (alsa_stream->chip->cea_chmap >= 0) { -+ chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; -+ } else { -+ chmap_value = 0; /* force stereo */ -+ for (i = 0; i < 8; i++) -+ alsa_stream->chip->map_channels[i] = i; -+ } -+ for (i = 0; i < 8; i++) -+ chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); -+ - m.type = VC_AUDIO_MSG_TYPE_CONFIG; - m.u.config.channels = channels; - m.u.config.samplerate = samplerate; - m.u.config.bps = bps; -+ m.u.config.channelmap = chmap_value; - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); -diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h -index 0f71c5d..997fb69 100755 ---- a/sound/arm/bcm2835.h -+++ b/sound/arm/bcm2835.h -@@ -107,6 +107,8 @@ typedef struct bcm2835_chip { - int old_volume; /* stores the volume value whist muted */ - int dest; - int mute; -+ int cea_chmap; /* currently requested Audio InfoFrame Data Byte 4 */ -+ int map_channels[8]; - - unsigned int opened; - unsigned int spdif_status; -@@ -149,6 +151,8 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip); - int snd_bcm2835_new_pcm(bcm2835_chip_t * chip); - int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip); - -+int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream); -+ - int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream); - int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream); - int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - -From 9e7ef4d08f6e2dbcdca8f7f2833f2eb38bee78e1 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:43:35 +0100 -Subject: [PATCH 126/251] bcm2835: access controls under the audio mutex - -I don't think the ALSA framework provides any kind of automatic -synchronization within the control callbacks. We most likely need -to ensure this manually, so add locking around all access to shared -mutable data. In particular, bcm2835_audio_set_ctls() should -probably always be called under our own audio lock. ---- - sound/arm/bcm2835-ctl.c | 74 +++++++++++++++++++++++++++++++++++++++++-------- - sound/arm/bcm2835-pcm.c | 4 +++ - 2 files changed, 66 insertions(+), 12 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index 92d3f76..5b8e6bd 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -94,6 +94,9 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - { - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) -@@ -103,6 +106,7 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) - ucontrol->value.integer.value[0] = chip->dest; - -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -112,11 +116,15 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int changed = 0; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { - audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); - if (chip->mute == CTRL_VOL_MUTE) { - /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ -- return 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ -+ changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ -+ goto unlock; - } - if (changed - || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { -@@ -142,6 +150,8 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, - printk(KERN_ERR "Failed to set ALSA controls..\n"); - } - -+unlock: -+ mutex_unlock(&chip->audio_mutex); - return changed; - } - -@@ -198,10 +208,14 @@ static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) && 0xff; - -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -212,12 +226,16 @@ static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, - unsigned int val = 0; - int i, change; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); - - change = val != chip->spdif_status; - chip->spdif_status = val; - -+ mutex_unlock(&chip->audio_mutex); - return change; - } - -@@ -253,9 +271,14 @@ static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) & 0xff; -+ -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -266,11 +289,15 @@ static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, - unsigned int val = 0; - int i, change; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); - change = val != chip->spdif_status; - chip->spdif_status = val; - -+ mutex_unlock(&chip->audio_mutex); - return change; - } - -@@ -454,11 +481,17 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - struct cea_channel_speaker_allocation *ch = NULL; -+ int res = 0; - int cur = 0; - int i; - -- if (!substream || !substream->runtime) -- return -ENODEV; -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ -+ if (!substream || !substream->runtime) { -+ res = -ENODEV; -+ goto unlock; -+ } - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { - if (channel_allocations[i].ca_index == chip->cea_chmap) -@@ -476,7 +509,10 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - } - while (cur < 8) - ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; -- return 0; -+ -+unlock: -+ mutex_unlock(&chip->audio_mutex); -+ return res; - } - - static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, -@@ -487,10 +523,16 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - int i, prepared = 0, cea_chmap = -1; -+ int res = 0; - int remap[8]; - -- if (!substream || !substream->runtime) -- return -ENODEV; -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ -+ if (!substream || !substream->runtime) { -+ res = -ENODEV; -+ goto unlock; -+ } - - switch (substream->runtime->status->state) { - case SNDRV_PCM_STATE_OPEN: -@@ -500,7 +542,8 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - prepared = 1; - break; - default: -- return -EBUSY; -+ res = -EBUSY; -+ goto unlock; - } - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -@@ -538,19 +581,26 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - } - } - -- if (cea_chmap < 0) -- return -EINVAL; -+ if (cea_chmap < 0) { -+ res = -EINVAL; -+ goto unlock; -+ } - - /* don't change the layout if another substream is active */ -- if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) -- return -EBUSY; /* unsure whether this is a good error code */ -+ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) { -+ res = -EBUSY; /* unsure whether this is a good error code */ -+ goto unlock; -+ } - - chip->cea_chmap = cea_chmap; - for (i = 0; i < 8; i++) - chip->map_channels[i] = remap[i]; - if (prepared) - snd_bcm2835_pcm_prepare_again(substream); -- return 0; -+ -+unlock: -+ mutex_unlock(&chip->audio_mutex); -+ return res; - } - - static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 1067460..48da3bb 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -379,6 +379,9 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - - audio_info(" .. IN\n"); - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - snd_bcm2835_pcm_prepare_again(substream); - - bcm2835_audio_setup(alsa_stream); -@@ -401,6 +404,7 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - alsa_stream->buffer_size, alsa_stream->period_size, - alsa_stream->pos, runtime->frame_bits); - -+ mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - return 0; - } - -From 04d7228226398968e0fc67ec3722760f729dbfc9 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:03 +0100 -Subject: [PATCH 127/251] bcm2835: always use 2/4/8 channels for multichannel - layouts - -Pad the unused channels with NA. This means userspace needs to write -additional, silent padding channels, which is not ideal, but better -than noise. - -Works around noise at the following channel counts: 3, 5, 6, 7 ---- - sound/arm/bcm2835-ctl.c | 89 +++++++++++++++++++++++++------------------------ - 1 file changed, 45 insertions(+), 44 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index 5b8e6bd..dec052b 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -349,6 +349,7 @@ struct cea_channel_speaker_allocation { - #define FRW SNDRV_CHMAP_FRW - #define TC SNDRV_CHMAP_TC - #define FCH SNDRV_CHMAP_TFC -+#define NA SNDRV_CHMAP_NA - - /* - * CEA-861 channel maps -@@ -356,69 +357,69 @@ struct cea_channel_speaker_allocation { - * Stolen from sound/pci/hda/patch_hdmi.c - * (unlike the source, this uses SNDRV_* constants directly, as by the - * map_tables array in patch_hdmi.c) -- * Unknown entries use 0, which unfortunately is SNDRV_CHMAP_UNKNOWN instead -- * of SNDRV_CHMAP_NA. -+ * Entries which do not have a physical output channel use 0. Entries which -+ * require userspace to output silence use NA (SNDRV_CHMAP_NA). - */ - static struct cea_channel_speaker_allocation channel_allocations[] = { - /* channel: 7 6 5 4 3 2 1 0 */ - { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, - /* 2.1 */ --{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, -+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, NA, LFE, FR, FL } }, - /* Dolby Surround */ --{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, NA, FR, FL } }, - /* surround40 */ --{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x08, .speakers = { NA, NA, RR, RL, NA, NA, FR, FL } }, - /* surround41 */ --{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x09, .speakers = { NA, NA, RR, RL, NA, LFE, FR, FL } }, - /* surround50 */ --{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x0a, .speakers = { NA, NA, RR, RL, FC, NA, FR, FL } }, - /* surround51 */ --{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0b, .speakers = { NA, NA, RR, RL, FC, LFE, FR, FL } }, - /* 6.1 */ --{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0f, .speakers = { NA, RC, RR, RL, FC, LFE, FR, FL } }, - /* surround71 */ - { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, - --{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, --{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, --{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, --{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, --{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, --{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, --{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, --{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, --{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, --{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, --{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, --{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, --{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, --{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x03, .speakers = { NA, NA, NA, NA, FC, LFE, FR, FL } }, -+{ .ca_index = 0x04, .speakers = { NA, NA, NA, RC, NA, NA, FR, FL } }, -+{ .ca_index = 0x05, .speakers = { NA, NA, NA, RC, NA, LFE, FR, FL } }, -+{ .ca_index = 0x06, .speakers = { NA, NA, NA, RC, FC, NA, FR, FL } }, -+{ .ca_index = 0x07, .speakers = { NA, NA, NA, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0c, .speakers = { NA, RC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x0d, .speakers = { NA, RC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x0e, .speakers = { NA, RC, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x14, .speakers = { FRC, FLC, NA, NA, NA, NA, FR, FL } }, -+{ .ca_index = 0x15, .speakers = { FRC, FLC, NA, NA, NA, LFE, FR, FL } }, -+{ .ca_index = 0x16, .speakers = { FRC, FLC, NA, NA, FC, NA, FR, FL } }, -+{ .ca_index = 0x17, .speakers = { FRC, FLC, NA, NA, FC, LFE, FR, FL } }, -+{ .ca_index = 0x18, .speakers = { FRC, FLC, NA, RC, NA, NA, FR, FL } }, -+{ .ca_index = 0x19, .speakers = { FRC, FLC, NA, RC, NA, LFE, FR, FL } }, -+{ .ca_index = 0x1a, .speakers = { FRC, FLC, NA, RC, FC, NA, FR, FL } }, -+{ .ca_index = 0x1b, .speakers = { FRC, FLC, NA, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x20, .speakers = { NA, FCH, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x21, .speakers = { NA, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x22, .speakers = { TC, NA, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x23, .speakers = { TC, NA, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, - }; - - -From 7a65c83035dbea9a9ac43867cc82167d64e5c233 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:24 +0100 -Subject: [PATCH 128/251] bcm2835: only allow stereo if analogue jack is - selected - -Sending more than 2 channels to videocore while outputting to analogue -mysteriously outputs heavy artifacts. So just paint it over with a -hack: if analogue is explicitly selected as destination, do not -reporting support for anything other than stereo. - -I'm not sure how to deal with the auto case (destination 0). There's -probably way to retrieve this and even to listen to plug events, but -I didn't find one yet, and it's probably not worth the trouble. Just -don't use this setting, I guess. Unless you like noise. - -Changing the setting while an audio stream is active also doesn't -work properly. We could probably interrupt running streams by -returning ENODEV or using kernel hotplug stuff (maybe), but that -also doesn't seem worth the trouble. ---- - sound/arm/bcm2835-ctl.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index dec052b..e930718 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -423,9 +423,16 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { - { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, - }; - -+static int uses_analogue(bcm2835_chip_t *chip) -+{ -+ return chip->dest == 1; -+} -+ - static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, - unsigned int size, unsigned int __user *tlv) - { -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; - unsigned int __user *dst; - int count = 0; - int i; -@@ -442,6 +449,9 @@ static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, - int chs_bytes; - int c; - -+ if (i > 0 && uses_analogue(chip)) -+ break; -+ - for (c = 0; c < 8; c++) { - if (ch->speakers[c]) - num_chs++; -@@ -552,6 +562,8 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - int matches = 1; - int cur = 0; - int x; -+ if (i > 0 && uses_analogue(chip)) -+ break; - memset(remap, 0, sizeof(remap)); - for (x = 0; x < substream->runtime->channels; x++) { - int sp = ucontrol->value.integer.value[x]; - -From 1009b70932a4980e21de9429c596dbdccac1ecdb Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:47 +0100 -Subject: [PATCH 129/251] bcm2835: interpolate audio delay - -It appears the GPU only sends us a message all 10ms to update -the playback progress. Other than this, the playback position -(what SNDRV_PCM_IOCTL_DELAY will return) is not updated at all. -Userspace will see jitter up to 10ms in the audio position. - -Make this a bit nicer for userspace by interpolating the -position using the CPU clock. - -I'm not sure if setting snd_pcm_runtime.delay is the right -approach for this. Or if there is maybe an already existing -mechanism for position interpolation in the ALSA core. - -I only set SNDRV_PCM_INFO_BATCH because this appears to remove -at least one situation snd_pcm_runtime.delay is used, so I have -to worry less in which place I have to update this field, or -how it interacts with the rest of ALSA. - -In the future, it might be nice to use VC_AUDIO_MSG_TYPE_LATENCY. -One problem is that it requires sending a videocore message, and -waiting for a reply, which could make the implementation much -harder due to locking and synchronization requirements. ---- - sound/arm/bcm2835-pcm.c | 12 +++++++++++- - sound/arm/bcm2835.h | 1 + - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 48da3bb..f3a4c6d 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -25,7 +25,7 @@ - /* hardware definition */ - static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), -+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -@@ -99,6 +99,8 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) - alsa_stream->pos %= alsa_stream->buffer_size; - } - -+ alsa_stream->interpolate_start = ktime_get_ns(); -+ - if (alsa_stream->substream) { - if (new_period) - snd_pcm_period_elapsed(alsa_stream->substream); -@@ -399,6 +401,7 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); - alsa_stream->pos = 0; -+ alsa_stream->interpolate_start = ktime_get_ns(); - - audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", - alsa_stream->buffer_size, alsa_stream->period_size, -@@ -495,6 +498,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) - { - struct snd_pcm_runtime *runtime = substream->runtime; - bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; -+ u64 now = ktime_get_ns(); - - audio_info(" .. IN\n"); - -@@ -503,6 +507,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) - frames_to_bytes(runtime, runtime->control->appl_ptr), - alsa_stream->pos); - -+ /* Give userspace better delay reporting by interpolating between GPU -+ * notifications, assuming audio speed is close enough to the clock -+ * used for ktime */ -+ if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) -+ runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); -+ - audio_info(" .. OUT\n"); - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, -diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h -index 997fb69..20ef108 100755 ---- a/sound/arm/bcm2835.h -+++ b/sound/arm/bcm2835.h -@@ -137,6 +137,7 @@ typedef struct bcm2835_alsa_stream { - unsigned int pos; - unsigned int buffer_size; - unsigned int period_size; -+ u64 interpolate_start; - - uint32_t enable_fifo_irq; - irq_handler_t fifo_irq_handler; - -From fb73e06c694d16d8be119e08e71bf5601f386352 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Jan 2016 17:16:38 +0000 -Subject: [PATCH 130/251] bcm2835-sdhost: Add workaround for odd behaviour on - some cards - -For reasons not understood, the sdhost driver fails when reading -sectors very near the end of some SD cards. The problem could -be related to the similar issue that reading the final sector -of any card as part of a multiple read never completes, and the -workaround is an extension of the mechanism introduced to solve -that problem which ensures those sectors are always read singly. ---- - drivers/mmc/host/bcm2835-sdhost.c | 61 +++++++++++++++++++++++++++++++++------ - 1 file changed, 52 insertions(+), 9 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index da08998..309633c 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -173,6 +173,9 @@ struct bcm2835_host { - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+ -+ u32 sectors; /* Cached card size in sectors */ -+ u32 single_read_sectors[8]; - }; - - -@@ -277,6 +280,9 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; - -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(host->mmc)); -+ - bcm2835_sdhost_set_power(host, false); - - bcm2835_sdhost_write(host, 0, SDCMD); -@@ -299,6 +305,8 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - bcm2835_sdhost_set_power(host, true); - mdelay(10); - host->clock = 0; -+ host->sectors = 0; -+ host->single_read_sectors[0] = ~0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); -@@ -309,8 +317,6 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - { - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; -- if (host->debug) -- pr_info("%s: reset\n", mmc_hostname(mmc)); - spin_lock_irqsave(&host->lock, flags); - - bcm2835_sdhost_reset_internal(host); -@@ -676,6 +682,32 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ if (!host->sectors && host->mmc->card) -+ { -+ struct mmc_card *card = host->mmc->card; -+ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -+ /* -+ * The EXT_CSD sector count is in number of 512 byte -+ * sectors. -+ */ -+ host->sectors = card->ext_csd.sectors; -+ pr_err("%s: using ext_csd!\n", mmc_hostname(host->mmc)); -+ } else { -+ /* -+ * The CSD capacity field is in units of read_blkbits. -+ * set_capacity takes units of 512 bytes. -+ */ -+ host->sectors = card->csd.capacity << -+ (card->csd.read_blkbits - 9); -+ } -+ host->single_read_sectors[0] = host->sectors - 65; -+ host->single_read_sectors[1] = host->sectors - 64; -+ host->single_read_sectors[2] = host->sectors - 33; -+ host->single_read_sectors[3] = host->sectors - 32; -+ host->single_read_sectors[4] = host->sectors - 1; -+ host->single_read_sectors[5] = ~0; /* Safety net */ -+ } -+ - host->use_dma = host->have_dma && (data->blocks > host->pio_limit); - if (!host->use_dma) { - int flags; -@@ -1246,6 +1278,10 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - - bcm2835_sdhost_finish_data(host); - } else { -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); -+ - bcm2835_sdhost_transfer_pio(host); - - /* Reset the timer */ -@@ -1450,8 +1486,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ /* Set the timeout to 250ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/4, SDTOUT); - - if (host->debug) - pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -@@ -1566,13 +1602,20 @@ static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, - reading the final sector of the card as part of a multiple read - problematic. Detect that case and shorten the read accordingly. - */ -- /* csd.capacity is in weird units - convert to sectors */ -- u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ struct bcm2835_host *host; -+ -+ host = mmc_priv(card->host); - -- if ((direction == MMC_DATA_READ) && -- ((blk_pos + blk_size) == card_sectors)) -- blk_size--; -+ if (direction == MMC_DATA_READ) -+ { -+ int i; -+ int sector; -+ for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -+ continue; - -+ if ((blk_pos + blk_size) > sector) -+ blk_size = (blk_pos == sector) ? 1 : (sector - blk_pos); -+ } - return blk_size; - } - - -From 6671675d3a1a7df0f838121c8166b57f0fd6f0c3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 22 Jan 2016 16:03:24 +0000 -Subject: [PATCH 131/251] bcm2835-sdhost: Add debug_flags dtparam - -Bit zero disables the single-read-sectors map: - -If the default MMC driver is bcm2835-mmc: - dtoverlay=sdhost,debug_flags=1 -If the default MMC driver is bcm2835-sdhost: - dtoverlay=sdtweak,debug_flags=1 -(although the sdhost overlay may also work, sdtweak is -less invasive and will work in more circumstances). - -Also revert the timeout change, just in case. ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 ++ - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 2 ++ - drivers/mmc/host/bcm2835-sdhost.c | 26 +++++++++++++++++++++----- - 3 files changed, 25 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 85f0725..dbe6574 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -16,6 +16,7 @@ - frag1: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -+ brcm,debug-flags = <0>; - status = "okay"; - }; - }; -@@ -25,5 +26,6 @@ - force_pio = <&frag1>,"brcm,force-pio?"; - pio_limit = <&frag1>,"brcm,pio-limit:0"; - debug = <&frag1>,"brcm,debug?"; -+ debug_flags = <&frag1>,"brcm,debug-flags:0"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -index 74c168d..b0b208c 100644 ---- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -9,6 +9,7 @@ - frag1: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -+ brcm,debug-flags = <0>; - }; - }; - -@@ -17,5 +18,6 @@ - force_pio = <&frag1>,"brcm,force-pio?"; - pio_limit = <&frag1>,"brcm,pio-limit:0"; - debug = <&frag1>,"brcm,debug?"; -+ debug_flags = <&frag1>,"brcm,debug-flags:0"; - }; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 309633c..ef9b1e6 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -174,6 +174,8 @@ struct bcm2835_host { - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - -+ u32 debug_flags; -+ - u32 sectors; /* Cached card size in sectors */ - u32 single_read_sectors[8]; - }; -@@ -682,7 +684,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- if (!host->sectors && host->mmc->card) -+ if (!host->sectors && host->mmc->card && !(host->debug_flags & 1)) - { - struct mmc_card *card = host->mmc->card; - if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -@@ -1486,8 +1488,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- /* Set the timeout to 250ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/4, SDTOUT); -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) - pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -@@ -1606,8 +1608,16 @@ static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, - - host = mmc_priv(card->host); - -- if (direction == MMC_DATA_READ) -- { -+ if (!host->sectors) { -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ return blk_size; -+ } -+ -+ if (direction == MMC_DATA_READ) { - int i; - int sector; - for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -@@ -1838,8 +1848,14 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); - host->debug = of_property_read_bool(node, "brcm,debug"); -+ of_property_read_u32(node, -+ "brcm,debug-flags", -+ &host->debug_flags); - } - -+ if (host->debug_flags) -+ dev_err(dev, "debug_flags=%x\n", host->debug_flags); -+ - if (host->allow_dma) { - if (node) { - host->dma_chan_tx = - -From 559103cc40fb480a58ff12002ac79dc204c5c19d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 25 Jan 2016 09:12:06 +0000 -Subject: [PATCH 132/251] BCM270X_DT: Add sdio_overclock parameter to sdio - overlay - -The sdio_overclock parameter is like the overclock_50 parameter, i.e. -it sets an alternate frequency (in MHz) to use when the MMC framework -requests 50MHz, except that it applies to the SDIO bus. - -Be aware that the actual frequencies achievable are limited to even integer -divisions of 250MHz, and that the driver will round up to include fractions -(e.g. 62 will include 62.5) but then round down to the nearest frequency. -In other words, the chosen frequency is the highest possible that is less than -the parameter value + 1. In practise this means that 62 is the only sensible -value. - -Examples: - 250MHz/4 = 62.5MHz (sdio_overclock=62) - 250MHz/2 = 125MHz (sdio_overclock=125) # Too fast ---- - arch/arm/boot/dts/overlays/README | 9 ++++++--- - arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 ++ - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 34a1b7f..709d3e4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -53,8 +53,8 @@ have its contents deleted (or commented out). - Using Overlays - ============== - --Overlays are loaded using the "dtoverlay" directive. As an example, consider the --popular lirc-rpi module, the Linux Infrared Remote Control driver. In the -+Overlays are loaded using the "dtoverlay" directive. As an example, consider -+the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the - pre-DT world this would be loaded from /etc/modules, with an explicit - "modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, - this becomes a line in config.txt: -@@ -621,9 +621,12 @@ Name: sdio - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, - and enables SDIO via GPIOs 22-27. - Load: dtoverlay=sdio,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - requests 50MHz - -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz -+ - force_pio Disable DMA support (default off) - - pio_limit Number of blocks above which to use DMA -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -index 7935e7a..398bd81 100644 ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -12,6 +12,7 @@ - pinctrl-0 = <&sdio_pins>; - non-removable; - bus-width = <4>; -+ brcm,overclock-50 = <0>; - status = "okay"; - }; - }; -@@ -30,5 +31,6 @@ - __overrides__ { - poll_once = <&sdio_mmc>,"non-removable?"; - bus_width = <&sdio_mmc>,"bus-width:0"; -+ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; - }; - }; - -From 73ad066f76a5c18c621dbc86b02ff90d3adc814a Mon Sep 17 00:00:00 2001 -From: Michael Lange -Date: Thu, 21 Jan 2016 18:10:16 +0100 -Subject: [PATCH 133/251] rtc: ds1307: add support for the DT property - 'wakeup-source' - -For RTC chips with no IRQ directly connected to the SoC, the RTC chip -can be forced as a wakeup source by stating that explicitly in -the device's .dts file using the "wakeup-source" boolean property. -This will guarantee the 'wakealarm' sysfs entry is available on the -device, if supported by the RTC. - -With these changes to the driver rtc-ds1307 and the necessary entries -in the .dts file, I get an working ds1337 RTC on the Witty Pi extension -board by UUGear for the Raspberry Pi. - -An example for the entry in the .dts file: - - rtc: ds1337@68 { - compatible = "dallas,ds1337"; - reg = <0x68>; - wakeup-source; - -If the "wakeup-source" property is set, do not request an IRQ. -Set also UIE mode to unsupported, to get a working 'hwclock' binary. - -Signed-off-by: Michael Lange -Signed-off-by: Alexandre Belloni ---- - drivers/rtc/rtc-ds1307.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 1cb13fe..28ca4bf 100644 ---- a/drivers/rtc/rtc-ds1307.c -+++ b/drivers/rtc/rtc-ds1307.c -@@ -860,6 +860,7 @@ static int ds1307_probe(struct i2c_client *client, - struct chip_desc *chip = &chips[id->driver_data]; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - bool want_irq = false; -+ bool ds1307_can_wakeup_device = false; - unsigned char *buf; - struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); - irq_handler_t irq_handler = ds1307_irq; -@@ -907,6 +908,20 @@ static int ds1307_probe(struct i2c_client *client, - ds1307->write_block_data = ds1307_write_block_data; - } - -+#ifdef CONFIG_OF -+/* -+ * For devices with no IRQ directly connected to the SoC, the RTC chip -+ * can be forced as a wakeup source by stating that explicitly in -+ * the device's .dts file using the "wakeup-source" boolean property. -+ * If the "wakeup-source" property is set, don't request an IRQ. -+ * This will guarantee the 'wakealarm' sysfs entry is available on the device, -+ * if supported by the RTC. -+ */ -+ if (of_property_read_bool(client->dev.of_node, "wakeup-source")) { -+ ds1307_can_wakeup_device = true; -+ } -+#endif -+ - switch (ds1307->type) { - case ds_1337: - case ds_1339: -@@ -925,11 +940,13 @@ static int ds1307_probe(struct i2c_client *client, - ds1307->regs[0] &= ~DS1337_BIT_nEOSC; - - /* -- * Using IRQ? Disable the square wave and both alarms. -+ * Using IRQ or defined as wakeup-source? -+ * Disable the square wave and both alarms. - * For some variants, be sure alarms can trigger when we're - * running on Vbackup (BBSQI/BBSQW) - */ -- if (ds1307->client->irq > 0 && chip->alarm) { -+ if (chip->alarm && (ds1307->client->irq > 0 || -+ ds1307_can_wakeup_device)) { - ds1307->regs[0] |= DS1337_BIT_INTCN - | bbsqi_bitpos[ds1307->type]; - ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); -@@ -1144,6 +1161,14 @@ read_rtc: - return PTR_ERR(ds1307->rtc); - } - -+ if (ds1307_can_wakeup_device) { -+ /* Disable request for an IRQ */ -+ want_irq = false; -+ dev_info(&client->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n"); -+ /* We cannot support UIE mode if we do not have an IRQ line */ -+ ds1307->rtc->uie_unsupported = 1; -+ } -+ - if (want_irq) { - err = devm_request_threaded_irq(&client->dev, - client->irq, NULL, irq_handler, - -From 4f6fbb96cdcdc9e66c0521d1b0a46ca0b1d2c47d Mon Sep 17 00:00:00 2001 -From: vitalogy -Date: Tue, 19 Jan 2016 07:02:02 +0100 -Subject: [PATCH 134/251] dt-overlay: add wittypi-overlay.dts - ---- - arch/arm/boot/dts/overlays/wittypi-overlay.dts | 44 ++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/wittypi-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -new file mode 100644 -index 0000000..be5987d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -@@ -0,0 +1,44 @@ -+/* -+ * Device Tree overlay for Witty Pi extension board by UUGear -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ compatible = "gpio-leds"; -+ wittypi_led: wittypi_led { -+ label = "wittypi_led"; -+ linux,default-trigger = "default-on"; -+ gpios = <&gpio 17 0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rtc: ds1337@68 { -+ compatible = "dallas,ds1337"; -+ reg = <0x68>; -+ wakeup-source; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ led_gpio = <&wittypi_led>,"gpios:4"; -+ led_trigger = <&wittypi_led>,"linux,default-trigger"; -+ }; -+ -+}; - -From ed208e16047972bbaf88000ab35b61fa82293247 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Jan 2016 16:28:05 +0000 -Subject: [PATCH 135/251] FIXUP i2c_bcm2708: Don't change module baudrate - parameter - -Overwriting the baudrate module parameter creates an apparent -forced baudrate for i2c busses after the first. Not only does this -override the baudrate from DT it also prevents the bus ID from -being initialised. - -Also fix whitespace errors. ---- - drivers/i2c/busses/i2c-bcm2708.c | 48 +++++++++++++++++++++------------------- - 1 file changed, 25 insertions(+), 23 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index b152639..c9b8e5c 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -71,7 +71,6 @@ - - #define DRV_NAME "bcm2708_i2c" - --static unsigned int baudrate_default = CONFIG_I2C_BCM2708_BAUDRATE; - static unsigned int baudrate; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - MODULE_PARM_DESC(baudrate, "The I2C baudrate"); -@@ -317,25 +316,28 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - struct i2c_adapter *adap; - unsigned long bus_hz; - u32 cdiv, clk_tout; -- -- if (!baudrate) { -- baudrate = baudrate_default; -- if (pdev->dev.of_node) { -- u32 bus_clk_rate; -- pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -- if (pdev->id < 0) { -- dev_err(&pdev->dev, "alias is missing\n"); -- return -EINVAL; -- } -- if (!of_property_read_u32(pdev->dev.of_node, -- "clock-frequency", &bus_clk_rate)) -- baudrate = bus_clk_rate; -- else -- dev_warn(&pdev->dev, -- "Could not read clock-frequency property\n"); -+ u32 baud; -+ -+ baud = CONFIG_I2C_BCM2708_BAUDRATE; -+ -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; - } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baud = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); - } - -+ if (baudrate) -+ baud = baudrate; -+ - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "could not get IO memory\n"); -@@ -419,21 +421,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - } - - bus_hz = clk_get_rate(bi->clk); -- cdiv = bus_hz / baudrate; -+ cdiv = bus_hz / baud; - if (cdiv > 0xffff) { - cdiv = 0xffff; -- baudrate = bus_hz / cdiv; -+ baud = bus_hz / cdiv; - } -- -- clk_tout = 35/1000*baudrate; //35ms timeout as per SMBus specs. -- if (clk_tout > 0xffff) -+ -+ clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs. -+ if (clk_tout > 0xffff) - clk_tout = 0xffff; - - bi->cdiv = cdiv; - bi->clk_tout = clk_tout; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -- pdev->id, (unsigned long)regs->start, irq, baudrate); -+ pdev->id, (unsigned long)regs->start, irq, baud); - - return 0; - - -From 1172f40b76155e169d23802f5bfd81555571cb7e Mon Sep 17 00:00:00 2001 -From: Digital Dreamtime -Date: Thu, 4 Feb 2016 14:14:44 +0000 -Subject: [PATCH 136/251] Allow up to 24dB digital gain to be applied when - using IQAudIO DAC+ - -24db_digital_gain DT param can be used to specify that PCM512x -codec "Digital" volume control should not be limited to 0dB gain, -and if specified will allow the full 24dB gain. ---- - arch/arm/boot/dts/overlays/README | 17 +++++++++++++++-- - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 6 +++++- - sound/soc/bcm/iqaudio-dac.c | 20 ++++++++++++++------ - 3 files changed, 34 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 709d3e4..3c8436e 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -362,8 +362,21 @@ Params: - - Name: iqaudio-dacplus - Info: Configures the IQaudio DAC+ audio card --Load: dtoverlay=iqaudio-dacplus --Params: -+Load: dtoverlay=iqaudio-dacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=iqaudio-dacplus,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) - - - Name: lirc-rpi -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -index 735d8ab..e0aaf8f 100644 ---- a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -7,7 +7,7 @@ - - fragment@0 { - target = <&sound>; -- __overlay__ { -+ frag0: __overlay__ { - compatible = "iqaudio,iqaudio-dac"; - i2s-controller = <&i2s>; - status = "okay"; -@@ -36,4 +36,8 @@ - }; - }; - }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; -+ }; - }; -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 37038d4..124d7a9 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -23,14 +23,19 @@ - #include - #include - -+static bool digital_gain_0db_limit = true; -+ - static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) - { -- int ret; -- struct snd_soc_card *card = rtd->card; -- -- ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -- if (ret < 0) -- dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } - - return 0; - } -@@ -94,6 +99,9 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - dai->platform_name = NULL; - dai->platform_of_node = i2s_node; - } -+ -+ digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, -+ "iqaudio,24db_digital_gain"); - } - - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); - -From d87eb9396da3d0cf59346531fb93cfaa452760d8 Mon Sep 17 00:00:00 2001 -From: Digital Dreamtime -Date: Thu, 4 Feb 2016 20:04:00 +0000 -Subject: [PATCH 137/251] Limit PCM512x "Digital" gain to 0dB by default with - HiFiBerry DAC+ - -24db_digital_gain DT param can be used to specify that PCM512x -codec "Digital" volume control should not be limited to 0dB gain, -and if specified will allow the full 24dB gain. ---- - arch/arm/boot/dts/overlays/README | 17 +++++++++++++++-- - .../arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 6 +++++- - sound/soc/bcm/hifiberry_dacplus.c | 14 ++++++++++++++ - 3 files changed, 34 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3c8436e..296184f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -273,8 +273,21 @@ Params: - - Name: hifiberry-dacplus - Info: Configures the HifiBerry DAC+ audio card --Load: dtoverlay=hifiberry-dacplus --Params: -+Load: dtoverlay=hifiberry-dacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=hifiberry-dacplus,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24dB_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) - - - Name: hifiberry-digi -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index f923a48..42a0194 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -17,7 +17,7 @@ - - fragment@1 { - target = <&sound>; -- __overlay__ { -+ frag1: __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; - i2s-controller = <&i2s>; - status = "okay"; -@@ -47,4 +47,8 @@ - }; - }; - }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag1>,"hifiberry,24db_digital_gain?"; -+ }; - }; -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index a6b651c..153dbcd 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -48,6 +48,7 @@ struct pcm512x_priv { - #define CLK_48EN_RATE 24576000UL - - static bool snd_rpi_hifiberry_is_dacpro; -+static bool digital_gain_0db_limit = true; - - static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, - int clk_id) -@@ -167,6 +168,16 @@ static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); - snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } -+ - return 0; - } - -@@ -299,6 +310,9 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - dai->platform_name = NULL; - dai->platform_of_node = i2s_node; - } -+ -+ digital_gain_0db_limit = !of_property_read_bool( -+ pdev->dev.of_node, "hifiberry,24db_digital_gain"); - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); - -From f279fd3295cc2407f05e56fafb77edc800148547 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 8 Feb 2016 09:46:33 +0000 -Subject: [PATCH 138/251] BCM270X_DT: Adjust overlay README formatting - ---- - arch/arm/boot/dts/overlays/README | 414 +++++++++++++++++++------------------- - 1 file changed, 207 insertions(+), 207 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 296184f..f987565 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -83,58 +83,58 @@ Name: - Info: Configures the base Raspberry Pi hardware - Load: - Params: -- audio Set to "on" to enable the onboard ALSA audio -- interface (default "off") -+ audio Set to "on" to enable the onboard ALSA audio -+ interface (default "off") - -- i2c_arm Set to "on" to enable the ARM's i2c interface -- (default "off") -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") - -- i2c_vc Set to "on" to enable the i2c interface -- usually reserved for the VideoCore processor -- (default "off") -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") - -- i2c An alias for i2c_arm -+ i2c An alias for i2c_arm - -- i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -- (default "100000") -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") - -- i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -- (default "100000") -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") - -- i2c_baudrate An alias for i2c_arm_baudrate -+ i2c_baudrate An alias for i2c_arm_baudrate - -- i2s Set to "on" to enable the i2s interface -- (default "off") -+ i2s Set to "on" to enable the i2s interface -+ (default "off") - -- spi Set to "on" to enable the spi interfaces -- (default "off") -+ spi Set to "on" to enable the spi interfaces -+ (default "off") - -- random Set to "on" to enable the hardware random -- number generator (default "on") -+ random Set to "on" to enable the hardware random -+ number generator (default "on") - -- uart0 Set to "off" to disable uart0 (default "on") -+ uart0 Set to "off" to disable uart0 (default "on") - -- watchdog Set to "on" to enable the hardware watchdog -- (default "off") -+ watchdog Set to "on" to enable the hardware watchdog -+ (default "off") - -- act_led_trigger Choose which activity the LED tracks. -- Use "heartbeat" for a nice load indicator. -- (default "mmc") -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") - -- act_led_activelow Set to "on" to invert the sense of the LED -- (default "off") -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") - -- act_led_gpio Set which GPIO to use for the activity LED -- (in case you want to connect it to an external -- device) -- (default "16" on a non-Plus board, "47" on a -- Plus or Pi 2) -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) - - pwr_led_trigger - pwr_led_activelow - pwr_led_gpio -- As for act_led_*, but using the PWR LED. -- Not available on Model A/B boards. -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. - - N.B. It is recommended to only enable those interfaces that are needed. - Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc -@@ -149,19 +149,19 @@ Params: - Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= --Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2MHz, max 3.25MHz) -- penirq GPIO used for PENIRQ. REQUIRED -- penirq_pull Set GPIO pull (default 0=none, 2=pullup) -- swapxy Swap x and y axis -- xmin Minimum value on the X axis (default 0) -- ymin Minimum value on the Y axis (default 0) -- xmax Maximum value on the X axis (default 4095) -- ymax Maximum value on the Y axis (default 4095) -- pmin Minimum reported pressure value (default 0) -- pmax Maximum reported pressure value (default 65535) -- xohms Touchpanel sensitivity (X-plate resistance) -- (default 400) -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) - - penirq is required and usually xohms (60-100) has to be set as well. - Apart from that, pmax (255) and swapxy are also common. -@@ -175,12 +175,12 @@ Name: at86rf233 - Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, - connected to spi0.0 - Load: dtoverlay=at86rf233,= --Params: interrupt GPIO used for INT (default 23) -- reset GPIO used for Reset (default 24) -- sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 6000000) -- trim Fine tuning of the internal capacitance -- arrays (0=+0pF, 15=+4.5pF, default 15) -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 6000000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) - - - Name: bmp085_i2c-sensor -@@ -194,8 +194,8 @@ Name: dht11 - Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors - Also sometimes found with the part number(s) AM230x. - Load: dtoverlay=dht11,= --Params: gpiopin GPIO connected to the sensor's DATA output. -- (default 4) -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) - - - Name: dwc-otg -@@ -208,15 +208,15 @@ Params: - Name: dwc2 - Info: Selects the dwc2 USB controller driver - Load: dtoverlay=dwc2,= --Params: dr_mode Dual role mode: "host", "peripheral" or "otg" -+Params: dr_mode Dual role mode: "host", "peripheral" or "otg" - -- g-rx-fifo-size Size of rx fifo size in gadget mode -+ g-rx-fifo-size Size of rx fifo size in gadget mode - -- g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -- mode -+ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -+ mode - -- g-tx-fifo-size Size of periodic tx fifo per endpoint -- (except ep0) in gadget mode -+ g-tx-fifo-size Size of periodic tx fifo per endpoint -+ (except ep0) in gadget mode - - - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] -@@ -225,9 +225,9 @@ Params: dr_mode Dual role mode: "host", "peripheral" or "otg" - Name: enc28j60 - Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) - Load: dtoverlay=enc28j60,= --Params: int_pin GPIO used for INT (default 25) -+Params: int_pin GPIO used for INT (default 25) - -- speed SPI bus speed (default 12000000) -+ speed SPI bus speed (default 12000000) - - - Name: gpio-ir -@@ -237,26 +237,26 @@ Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- - not required! The key mapping and other decoding parameters can be - configured by "ir-keytable" tool. - Load: dtoverlay=gpio-ir,= --Params: gpio_pin Input pin number. Default is 18. -+Params: gpio_pin Input pin number. Default is 18. - -- gpio_pull Desired pull-up/down state (off, down, up) -- Default is "down". -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "down". - -- rc-map-name Default rc keymap (can also be changed by -- ir-keytable), defaults to "rc-rc6-mce" -+ rc-map-name Default rc keymap (can also be changed by -+ ir-keytable), defaults to "rc-rc6-mce" - - - Name: gpio-poweroff - Info: Drives a GPIO high or low on reboot - Load: dtoverlay=gpio-poweroff,= --Params: gpiopin GPIO for signalling (default 26) -+Params: gpiopin GPIO for signalling (default 26) - -- active_low Set if the power control device requires a -- high->low transition to trigger a power-down. -- Note that this will require the support of a -- custom dt-blob.bin to prevent a power-down -- during the boot process, and that a reboot -- will also cause the pin to go low. -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. - - - Name: hifiberry-amp -@@ -300,65 +300,65 @@ Name: hy28a - Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics - Default values match Texy's display shield - Load: dtoverlay=hy28a,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - -- resetgpio GPIO used to reset controller -+ resetgpio GPIO used to reset controller - -- ledgpio GPIO used to control backlight -+ ledgpio GPIO used to control backlight - - - Name: hy28b - Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics - Default values match Texy's display shield - Load: dtoverlay=hy28b,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - -- resetgpio GPIO used to reset controller -+ resetgpio GPIO used to reset controller - -- ledgpio GPIO used to control backlight -+ ledgpio GPIO used to control backlight - - - Name: i2c-gpio - Info: Adds support for software i2c controller on gpio pins - Load: dtoverlay=i2c-gpio,= --Params: i2c_gpio_sda GPIO used for I2C data (default "23") -+Params: i2c_gpio_sda GPIO used for I2C data (default "23") - -- i2c_gpio_scl GPIO used for I2C clock (default "24") -+ i2c_gpio_scl GPIO used for I2C clock (default "24") - -- i2c_gpio_delay_us Clock delay in microseconds -- (default "2" = ~100kHz) -+ i2c_gpio_delay_us Clock delay in microseconds -+ (default "2" = ~100kHz) - - - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= --Params: ds1307 Select the DS1307 device -+Params: ds1307 Select the DS1307 device - -- ds3231 Select the DS3231 device -+ ds3231 Select the DS3231 device - -- mcp7941x Select the MCP7941x device -+ mcp7941x Select the MCP7941x device - -- pcf2127 Select the PCF2127 device -+ pcf2127 Select the PCF2127 device - -- pcf8523 Select the PCF8523 device -+ pcf8523 Select the PCF8523 device - -- pcf8563 Select the PCF8563 device -+ pcf8563 Select the PCF8563 device - - - Name: i2s-mmap -@@ -396,70 +396,70 @@ Name: lirc-rpi - Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) - Consult the module documentation for more details. - Load: dtoverlay=lirc-rpi,= --Params: gpio_out_pin GPIO for output (default "17") -+Params: gpio_out_pin GPIO for output (default "17") - -- gpio_in_pin GPIO for input (default "18") -+ gpio_in_pin GPIO for input (default "18") - -- gpio_in_pull Pull up/down/off on the input pin -- (default "down") -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") - -- sense Override the IR receive auto-detection logic: -- "0" = force active-high -- "1" = force active-low -- "-1" = use auto-detection -- (default "-1") -+ sense Override the IR receive auto-detection logic: -+ "0" = force active-high -+ "1" = force active-low -+ "-1" = use auto-detection -+ (default "-1") - -- softcarrier Turn the software carrier "on" or "off" -- (default "on") -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") - -- invert "on" = invert the output pin (default "off") -+ invert "on" = invert the output pin (default "off") - -- debug "on" = enable additional debug messages -- (default "off") -+ debug "on" = enable additional debug messages -+ (default "off") - - - Name: mcp2515-can0 - Info: Configures the MCP2515 CAN controller on spi0.0 - Load: dtoverlay=mcp2515-can0,= --Params: oscillator Clock frequency for the CAN controller (Hz) -+Params: oscillator Clock frequency for the CAN controller (Hz) - -- spimaxfrequency Maximum SPI frequence (Hz) -+ spimaxfrequency Maximum SPI frequence (Hz) - -- interrupt GPIO for interrupt signal -+ interrupt GPIO for interrupt signal - - - Name: mcp2515-can1 - Info: Configures the MCP2515 CAN controller on spi0.1 - Load: dtoverlay=mcp2515-can1,= --Params: oscillator Clock frequency for the CAN controller (Hz) -+Params: oscillator Clock frequency for the CAN controller (Hz) - -- spimaxfrequency Maximum SPI frequence (Hz) -+ spimaxfrequency Maximum SPI frequence (Hz) - -- interrupt GPIO for interrupt signal -+ interrupt GPIO for interrupt signal - - - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -- force_pio Disable DMA support -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support - - - Name: mz61581 - Info: MZ61581 display by Tontec - Load: dtoverlay=mz61581,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- txbuflen Transmit buffer length (default 32768) -+ txbuflen Transmit buffer length (default 32768) - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - [ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] -@@ -474,69 +474,69 @@ Params: speed Display SPI bus speed - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: piscreen2r - Info: PiScreen 2 with resistive TP display by OzzMaker.com - Load: dtoverlay=piscreen2r,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: pitft28-capacitive - Info: Adafruit PiTFT 2.8" capacitive touch screen - Load: dtoverlay=pitft28-capacitive,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- touch-sizex Touchscreen size x (default 240) -+ touch-sizex Touchscreen size x (default 240) - -- touch-sizey Touchscreen size y (default 320) -+ touch-sizey Touchscreen size y (default 320) - -- touch-invx Touchscreen inverted x axis -+ touch-invx Touchscreen inverted x axis - -- touch-invy Touchscreen inverted y axis -+ touch-invy Touchscreen inverted y axis - -- touch-swapxy Touchscreen swapped x y axis -+ touch-swapxy Touchscreen swapped x y axis - - - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - - - Name: pps-gpio - Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). - Load: dtoverlay=pps-gpio,= --Params: gpiopin Input GPIO (default "18") -+Params: gpiopin Input GPIO (default "18") - - - Name: pwm -@@ -553,9 +553,9 @@ Info: Configures a single PWM channel - 4) Currently the clock must have been enabled and configured - by other means. - Load: dtoverlay=pwm,= --Params: pin Output pin (default 18) - see table -- func Pin function (default 2 = Alt5) - see above -- clock PWM clock frequency (informational) -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) - - - Name: pwm-2chan -@@ -572,11 +572,11 @@ Info: Configures both PWM channels - 4) Currently the clock must have been enabled and configured - by other means. - Load: dtoverlay=pwm-2chan,= --Params: pin Output pin (default 18) - see table -- pin2 Output pin for other channel (default 19) -- func Pin function (default 2 = Alt5) - see above -- func2 Function for pin2 (default 2 = Alt5) -- clock PWM clock frequency (informational) -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) - - - Name: raspidac3 -@@ -600,15 +600,15 @@ Params: - Name: rpi-display - Info: RPi-Display - 2.8" Touch Display by Watterott - Load: dtoverlay=rpi-display,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: rpi-ft5406 -@@ -632,52 +632,52 @@ Params: - Name: sdhost - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - - - Name: sdio - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, - and enables SDIO via GPIOs 22-27. - Load: dtoverlay=sdio,= --Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- sdio_overclock SDIO Clock (in MHz) to use when the MMC -- framework requests 50MHz -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - -- poll_once Disable SDIO-device polling every second -- (default on: polling once at boot-time) -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) - -- bus_width Set the SDIO host bus width (default 4 bits) -+ bus_width Set the SDIO host bus width (default 4 bits) - - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver - Load: dtoverlay=sdtweak,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - - - Name: smi -@@ -708,25 +708,25 @@ Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad - Load: dtoverlay=tinylcd35,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- touch Enable touch panel -+ touch Enable touch panel - -- touchgpio Touch controller IRQ GPIO -+ touchgpio Touch controller IRQ GPIO - -- xohms Touchpanel: Resistance of X-plate in ohms -+ xohms Touchpanel: Resistance of X-plate in ohms - -- rtc-pcf PCF8563 Real Time Clock -+ rtc-pcf PCF8563 Real Time Clock - -- rtc-ds DS1307 Real Time Clock -+ rtc-ds DS1307 Real Time Clock - -- keypad Enable keypad -+ keypad Enable keypad - - Examples: - Display with touchpanel, PCF8563 RTC and keypad: -@@ -738,9 +738,9 @@ Params: speed Display SPI bus speed - Name: uart1 - Info: Enable uart1 in place of uart0 - Load: dtoverlay=uart1,= --Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - -- rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - - Name: vc4-kms-v3d -@@ -763,22 +763,22 @@ Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio,= --Params: gpiopin GPIO for I/O (default "4") -+Params: gpiopin GPIO for I/O (default "4") - -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature - - - Name: w1-gpio-pullup - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *do* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio-pullup,= --Params: gpiopin GPIO for I/O (default "4") -+Params: gpiopin GPIO for I/O (default "4") - -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature - -- extpullup GPIO for external pullup (default "5") -+ extpullup GPIO for external pullup (default "5") - - - Troubleshooting - -From 414077cd3a0694b0a49a8e1bc92b574290aa8fcf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 11 Feb 2016 16:51:01 +0000 -Subject: [PATCH 139/251] bcm2835-sdhost: Major revision - -This is a significant revision of the bcm2835-sdhost driver. It -improves on the original in a number of ways: - -1) Through the use of CMD23 for reads it appears to avoid problems - reading some sectors on certain high speed cards. -2) Better atomicity to prevent crashes. -3) Higher performance. -4) Activity logging included, for easier diagnosis in the event - of a problem. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 1284 ++++++++++++++++++++----------------- - 1 file changed, 686 insertions(+), 598 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index ef9b1e6..262180b 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -2,7 +2,7 @@ - * BCM2835 SD host driver. - * - * Author: Phil Elwell -- * Copyright 2015 -+ * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd. - * - * Based on - * mmc-bcm2835.c by Gellert Weisz -@@ -24,12 +24,13 @@ - * along with this program. If not, see . - */ - --#define SAFE_READ_THRESHOLD 4 --#define SAFE_WRITE_THRESHOLD 4 --#define ALLOW_DMA 1 --#define ALLOW_CMD23 0 --#define ALLOW_FAST 1 --#define USE_BLOCK_IRQ 1 -+#define FIFO_READ_THRESHOLD 4 -+#define FIFO_WRITE_THRESHOLD 4 -+#define ALLOW_CMD23_READ 1 -+#define ALLOW_CMD23_WRITE 0 -+#define ENABLE_LOG 1 -+#define SDDATA_FIFO_PIO_BURST 8 -+#define CMD_DALLY_US 1 - - #include - #include -@@ -48,6 +49,7 @@ - #include - #include - #include -+#include - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -110,6 +112,28 @@ - #define SDEDM_READ_THRESHOLD_SHIFT 14 - #define SDEDM_THRESHOLD_MASK 0x1f - -+#define SDEDM_FSM_MASK 0xf -+#define SDEDM_FSM_IDENTMODE 0x0 -+#define SDEDM_FSM_DATAMODE 0x1 -+#define SDEDM_FSM_READDATA 0x2 -+#define SDEDM_FSM_WRITEDATA 0x3 -+#define SDEDM_FSM_READWAIT 0x4 -+#define SDEDM_FSM_READCRC 0x5 -+#define SDEDM_FSM_WRITECRC 0x6 -+#define SDEDM_FSM_WRITEWAIT1 0x7 -+#define SDEDM_FSM_POWERDOWN 0x8 -+#define SDEDM_FSM_POWERUP 0x9 -+#define SDEDM_FSM_WRITESTART1 0xa -+#define SDEDM_FSM_WRITESTART2 0xb -+#define SDEDM_FSM_GENPULSES 0xc -+#define SDEDM_FSM_WRITEWAIT2 0xd -+#define SDEDM_FSM_STARTPOWDOWN 0xf -+ -+#define SDDATA_FIFO_WORDS 16 -+ -+#define USE_CMD23_FLAGS ((ALLOW_CMD23_READ * MMC_DATA_READ) | \ -+ (ALLOW_CMD23_WRITE * MMC_DATA_WRITE)) -+ - #define MHZ 1000000 - - -@@ -131,15 +155,17 @@ struct bcm2835_host { - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -- struct timer_list timer; /* Timer for timeouts */ -+ struct work_struct cmd_wait_wq; /* Workqueue function */ - -- struct timer_list pio_timer; /* PIO error detection timer */ -+ struct timer_list timer; /* Timer for timeouts */ - - struct sg_mapping_iter sg_miter; /* SG state for PIO */ - unsigned int blocks; /* remaining PIO blocks */ - - int irq; /* Device IRQ */ - -+ u32 cmd_quick_poll_retries; -+ u32 ns_per_fifo_word; - - /* cached registers */ - u32 hcfg; -@@ -154,16 +180,21 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -- unsigned int debug:1; /* Enable debug output */ -+ unsigned int use_sbc:1; /* Send CMD23 */ - -- u32 thread_isr; -+ unsigned int debug:1; /* Enable debug output */ - - /*DMA part*/ - struct dma_chan *dma_chan_rx; /* DMA channel for reads */ - struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ struct dma_chan *dma_chan; /* Channel in used */ -+ struct dma_async_tx_descriptor *dma_desc; -+ u32 dma_dir; -+ u32 drain_words; -+ struct page *drain_page; -+ u32 drain_offset; - - bool allow_dma; -- bool have_dma; - bool use_dma; - /*end of DMA part*/ - -@@ -173,13 +204,98 @@ struct bcm2835_host { - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+}; - -- u32 debug_flags; -+#if ENABLE_LOG - -- u32 sectors; /* Cached card size in sectors */ -- u32 single_read_sectors[8]; -+struct log_entry_struct { -+ char event[4]; -+ u32 timestamp; -+ u32 param1; -+ u32 param2; - }; - -+typedef struct log_entry_struct LOG_ENTRY_T; -+ -+LOG_ENTRY_T *sdhost_log_buf; -+dma_addr_t sdhost_log_addr; -+static u32 sdhost_log_idx; -+static spinlock_t log_lock; -+static void __iomem *timer_base; -+ -+#define LOG_ENTRIES (256*1) -+#define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) -+ -+static void log_init(u32 bus_to_phys) -+{ -+ spin_lock_init(&log_lock); -+ sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, -+ GFP_KERNEL); -+ if (sdhost_log_buf) { -+ pr_err("sdhost: log_buf @ %p (%x)\n", -+ sdhost_log_buf, sdhost_log_addr); -+ timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); -+ if (!timer_base) -+ pr_err("sdhost: failed to remap timer\n"); -+ } -+ else -+ pr_err("sdhost: failed to allocate log buf\n"); -+} -+ -+static void log_event_impl(const char *event, u32 param1, u32 param2) -+{ -+ if (sdhost_log_buf) { -+ LOG_ENTRY_T *entry; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&log_lock, flags); -+ -+ entry = sdhost_log_buf + sdhost_log_idx; -+ memcpy(entry->event, event, 4); -+ entry->timestamp = (readl(timer_base + 4) & 0x3fffffff) + -+ (smp_processor_id()<<30); -+ entry->param1 = param1; -+ entry->param2 = param2; -+ sdhost_log_idx = (sdhost_log_idx + 1) % LOG_ENTRIES; -+ -+ spin_unlock_irqrestore(&log_lock, flags); -+ } -+} -+ -+static void log_dump(void) -+{ -+ if (sdhost_log_buf) { -+ LOG_ENTRY_T *entry; -+ unsigned long flags; -+ int idx; -+ -+ spin_lock_irqsave(&log_lock, flags); -+ -+ idx = sdhost_log_idx; -+ do { -+ entry = sdhost_log_buf + idx; -+ if (entry->event[0] != '\0') -+ pr_err("[%08x] %.4s %x %x\n", -+ entry->timestamp, -+ entry->event, -+ entry->param1, -+ entry->param2); -+ idx = (idx + 1) % LOG_ENTRIES; -+ } while (idx != sdhost_log_idx); -+ -+ spin_unlock_irqrestore(&log_lock, flags); -+ } -+} -+ -+#define log_event(event, param1, param2) log_event_impl(event, param1, param2) -+ -+#else -+ -+#define log_init(x) (void)0 -+#define log_event(event, param1, param2) (void)0 -+#define log_dump() (void)0 -+ -+#endif - - static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) - { -@@ -201,7 +317,7 @@ static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, - const char *label) - { - if (cmd) -- pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", -+ pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", - mmc_hostname(host->mmc), - (cmd == host->cmd) ? '>' : ' ', - label, cmd->opcode, cmd->arg, cmd->flags, -@@ -211,73 +327,74 @@ static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, - - static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) - { -- bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -- bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -- if (host->mrq->data) -- pr_err("%s: data blocks %x blksz %x - err %d\n", -- mmc_hostname(host->mmc), -- host->mrq->data->blocks, -- host->mrq->data->blksz, -- host->mrq->data->error); -- bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ if (host->mrq) -+ { -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ } - -- pr_info("%s: =========== REGISTER DUMP ===========\n", -+ pr_err("%s: =========== REGISTER DUMP ===========\n", - mmc_hostname(host->mmc)); - -- pr_info("%s: SDCMD 0x%08x\n", -+ pr_err("%s: SDCMD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCMD)); -- pr_info("%s: SDARG 0x%08x\n", -+ pr_err("%s: SDARG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDARG)); -- pr_info("%s: SDTOUT 0x%08x\n", -+ pr_err("%s: SDTOUT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDTOUT)); -- pr_info("%s: SDCDIV 0x%08x\n", -+ pr_err("%s: SDCDIV 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCDIV)); -- pr_info("%s: SDRSP0 0x%08x\n", -+ pr_err("%s: SDRSP0 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP0)); -- pr_info("%s: SDRSP1 0x%08x\n", -+ pr_err("%s: SDRSP1 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP1)); -- pr_info("%s: SDRSP2 0x%08x\n", -+ pr_err("%s: SDRSP2 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP2)); -- pr_info("%s: SDRSP3 0x%08x\n", -+ pr_err("%s: SDRSP3 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP3)); -- pr_info("%s: SDHSTS 0x%08x\n", -+ pr_err("%s: SDHSTS 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHSTS)); -- pr_info("%s: SDVDD 0x%08x\n", -+ pr_err("%s: SDVDD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDVDD)); -- pr_info("%s: SDEDM 0x%08x\n", -+ pr_err("%s: SDEDM 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDEDM)); -- pr_info("%s: SDHCFG 0x%08x\n", -+ pr_err("%s: SDHCFG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHCFG)); -- pr_info("%s: SDHBCT 0x%08x\n", -+ pr_err("%s: SDHBCT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBCT)); -- pr_info("%s: SDHBLC 0x%08x\n", -+ pr_err("%s: SDHBLC 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBLC)); - -- pr_info("%s: ===========================================\n", -+ pr_err("%s: ===========================================\n", - mmc_hostname(host->mmc)); - } - -- - static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) - { - bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); - } - -- - static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; -@@ -300,26 +417,24 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - temp = bcm2835_sdhost_read(host, SDEDM); - temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; -- host->sectors = 0; -- host->single_read_sectors[0] = ~0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); - } - -- - static void bcm2835_sdhost_reset(struct mmc_host *mmc) - { - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); -+ log_event("RST<", 0, 0); - - bcm2835_sdhost_reset_internal(host); - -@@ -344,82 +459,48 @@ static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - } - } - --static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) - { -- bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -- -- if (!write_complete) { -- /* Request an IRQ for the last block */ -- host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -- /* The write has now completed. Disable the interrupt -- and clear the status flag */ -- host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -- write_complete = true; -- } -- } -+ int timediff; -+ u32 alternate_idle; -+ u32 edm; - -- return write_complete; --} -+ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ? -+ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; - --static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) --{ -- int timediff; --#ifdef DEBUG -- static struct timeval start_time; -- static int max_stall_time = 0; -- static int total_stall_time = 0; -- struct timeval before, after; -+ edm = bcm2835_sdhost_read(host, SDEDM); - -- do_gettimeofday(&before); -- if (max_stall_time == 0) -- start_time = before; --#endif -+ log_event("WTC<", edm, 0); - - timediff = 0; - - while (1) { -- u32 edm = bcm2835_sdhost_read(host, SDEDM); -- if ((edm & 0xf) == 1) -+ u32 fsm = edm & SDEDM_FSM_MASK; -+ if ((fsm == SDEDM_FSM_IDENTMODE) || -+ (fsm == SDEDM_FSM_DATAMODE)) - break; -- timediff++; -- if (timediff > 5000000) { --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + -- (after.tv_usec - before.tv_usec); -+ if (fsm == alternate_idle) { -+ bcm2835_sdhost_write(host, -+ edm | SDEDM_FORCE_DATA_MODE, -+ SDEDM); -+ break; -+ } - -- pr_err(" wait_write_complete - still waiting after %dus\n", -- timediff); --#else -- pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff++; -+ if (timediff == 100000) { -+ pr_err("%s: wait_transfer_complete - still waiting after %d retries\n", -+ mmc_hostname(host->mmc), - timediff); --#endif -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- host->data->error = -ETIMEDOUT; -+ host->mrq->data->error = -ETIMEDOUT; -+ log_event("WTC!", edm, 0); - return; - } -+ cpu_relax(); -+ edm = bcm2835_sdhost_read(host, SDEDM); - } -- --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -- -- total_stall_time += timediff; -- if (timediff > max_stall_time) -- max_stall_time = timediff; -- -- if ((after.tv_sec - start_time.tv_sec) > 10) { -- pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -- max_stall_time, total_stall_time); -- start_time = after; -- max_stall_time = 0; -- total_stall_time = 0; -- } --#endif -+ log_event("WTC>", edm, 0); - } - - static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); -@@ -427,65 +508,44 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); - static void bcm2835_sdhost_dma_complete(void *param) - { - struct bcm2835_host *host = param; -- struct dma_chan *dma_chan; -+ struct mmc_data *data = host->data; - unsigned long flags; -- u32 dir_data; - - spin_lock_irqsave(&host->lock, flags); -+ log_event("DMA<", (u32)host->data, bcm2835_sdhost_read(host, SDHSTS)); -+ log_event("DMA ", bcm2835_sdhost_read(host, SDCMD), -+ bcm2835_sdhost_read(host, SDEDM)); - -- if (host->data) { -- bool write_complete; -- if (USE_BLOCK_IRQ) -- write_complete = bcm2835_sdhost_is_write_complete(host); -- else { -- bcm2835_sdhost_wait_write_complete(host); -- write_complete = true; -- } -- pr_debug("dma_complete() - write_complete=%d\n", -- write_complete); -- -- if (write_complete || (host->data->flags & MMC_DATA_READ)) -- { -- if (write_complete) { -- dma_chan = host->dma_chan_tx; -- dir_data = DMA_TO_DEVICE; -- } else { -- dma_chan = host->dma_chan_rx; -- dir_data = DMA_FROM_DEVICE; -- } -- -- dma_unmap_sg(dma_chan->device->dev, -- host->data->sg, host->data->sg_len, -- dir_data); -+ if (host->dma_chan) { -+ dma_unmap_sg(host->dma_chan->device->dev, -+ data->sg, data->sg_len, -+ host->dma_dir); - -- bcm2835_sdhost_finish_data(host); -- } -+ host->dma_chan = NULL; - } - -- spin_unlock_irqrestore(&host->lock, flags); --} -+ if (host->drain_words) { -+ void *page; -+ u32 *buf; - --static bool data_transfer_wait(struct bcm2835_host *host) --{ -- unsigned long timeout = 1000000; -- while (timeout) -- { -- u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -- if (sdhsts & SDHSTS_DATA_FLAG) { -- bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); -- break; -+ page = kmap_atomic(host->drain_page); -+ buf = page + host->drain_offset; -+ -+ while (host->drain_words) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm >> 4) & 0x1f) -+ *(buf++) = bcm2835_sdhost_read(host, -+ SDDATA); -+ host->drain_words--; - } -- timeout--; -- } -- if (timeout == 0) { -- pr_err("%s: Data %s timeout\n", -- mmc_hostname(host->mmc), -- (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -- bcm2835_sdhost_dumpregs(host); -- host->data->error = -ETIMEDOUT; -- return false; -+ -+ kunmap_atomic(page); - } -- return true; -+ -+ bcm2835_sdhost_finish_data(host); -+ -+ log_event("DMA>", (u32)host->data, 0); -+ spin_unlock_irqrestore(&host->lock, flags); - } - - static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) -@@ -493,32 +553,83 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - unsigned long flags; - size_t blksize, len; - u32 *buf; -+ unsigned long wait_max; - - blksize = host->data->blksz; - -+ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); -+ - local_irq_save(flags); - - while (blksize) { -- if (!sg_miter_next(&host->sg_miter)) -- BUG(); -+ int copy_words; -+ u32 hsts = 0; -+ -+ if (!sg_miter_next(&host->sg_miter)) { -+ host->data->error = -EINVAL; -+ break; -+ } - - len = min(host->sg_miter.length, blksize); -- BUG_ON(len % 4); -+ if (len % 4) { -+ host->data->error = -EINVAL; -+ break; -+ } - - blksize -= len; - host->sg_miter.consumed = len; - - buf = (u32 *)host->sg_miter.addr; - -- while (len) { -- if (!data_transfer_wait(host)) -- break; -+ copy_words = len/4; -+ -+ while (copy_words) { -+ int burst_words, words; -+ u32 edm; -+ -+ burst_words = SDDATA_FIFO_PIO_BURST; -+ if (burst_words > copy_words) -+ burst_words = copy_words; -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ words = ((edm >> 4) & 0x1f); -+ -+ if (words < burst_words) { -+ int fsm_state = (edm & SDEDM_FSM_MASK); -+ if ((fsm_state != SDEDM_FSM_READDATA) && -+ (fsm_state != SDEDM_FSM_READWAIT) && -+ (fsm_state != SDEDM_FSM_READCRC)) { -+ hsts = bcm2835_sdhost_read(host, -+ SDHSTS); -+ pr_err("%s: fsm %x, hsts %x\n", -+ mmc_hostname(host->mmc), -+ fsm_state, hsts); -+ if (hsts & SDHSTS_ERROR_MASK) -+ break; -+ } -+ -+ if (time_after(jiffies, wait_max)) { -+ pr_err("%s: PIO read timeout - EDM %x\n", -+ mmc_hostname(host->mmc), -+ edm); -+ hsts = SDHSTS_REW_TIME_OUT; -+ break; -+ } -+ ndelay((burst_words - words) * -+ host->ns_per_fifo_word); -+ continue; -+ } else if (words > copy_words) { -+ words = copy_words; -+ } -+ -+ copy_words -= words; - -- *(buf++) = bcm2835_sdhost_read(host, SDDATA); -- len -= 4; -+ while (words) { -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ words--; -+ } - } - -- if (host->data->error) -+ if (hsts & SDHSTS_ERROR_MASK) - break; - } - -@@ -532,32 +643,83 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - unsigned long flags; - size_t blksize, len; - u32 *buf; -+ unsigned long wait_max; - - blksize = host->data->blksz; - -+ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); -+ - local_irq_save(flags); - - while (blksize) { -- if (!sg_miter_next(&host->sg_miter)) -- BUG(); -+ int copy_words; -+ u32 hsts = 0; -+ -+ if (!sg_miter_next(&host->sg_miter)) { -+ host->data->error = -EINVAL; -+ break; -+ } - - len = min(host->sg_miter.length, blksize); -- BUG_ON(len % 4); -+ if (len % 4) { -+ host->data->error = -EINVAL; -+ break; -+ } - - blksize -= len; - host->sg_miter.consumed = len; - -- buf = host->sg_miter.addr; -+ buf = (u32 *)host->sg_miter.addr; - -- while (len) { -- if (!data_transfer_wait(host)) -- break; -+ copy_words = len/4; -+ -+ while (copy_words) { -+ int burst_words, words; -+ u32 edm; -+ -+ burst_words = SDDATA_FIFO_PIO_BURST; -+ if (burst_words > copy_words) -+ burst_words = copy_words; -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f); -+ -+ if (words < burst_words) { -+ int fsm_state = (edm & SDEDM_FSM_MASK); -+ if ((fsm_state != SDEDM_FSM_WRITEDATA) && -+ (fsm_state != SDEDM_FSM_WRITESTART1) && -+ (fsm_state != SDEDM_FSM_WRITESTART2)) { -+ hsts = bcm2835_sdhost_read(host, -+ SDHSTS); -+ pr_err("%s: fsm %x, hsts %x\n", -+ mmc_hostname(host->mmc), -+ fsm_state, hsts); -+ if (hsts & SDHSTS_ERROR_MASK) -+ break; -+ } -+ -+ if (time_after(jiffies, wait_max)) { -+ pr_err("%s: PIO write timeout - EDM %x\n", -+ mmc_hostname(host->mmc), -+ edm); -+ hsts = SDHSTS_REW_TIME_OUT; -+ break; -+ } -+ ndelay((burst_words - words) * -+ host->ns_per_fifo_word); -+ continue; -+ } else if (words > copy_words) { -+ words = copy_words; -+ } -+ -+ copy_words -= words; - -- bcm2835_sdhost_write(host, *(buf++), SDDATA); -- len -= 4; -+ while (words) { -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ words--; -+ } - } - -- if (host->data->error) -+ if (hsts & SDHSTS_ERROR_MASK) - break; - } - -@@ -566,12 +728,12 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - local_irq_restore(flags); - } - -- - static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { - u32 sdhsts; - bool is_read; - BUG_ON(!host->data); -+ log_event("XFP<", (u32)host->data, host->blocks); - - is_read = (host->data->flags & MMC_DATA_READ) != 0; - if (is_read) -@@ -595,28 +757,21 @@ static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - is_read ? "read" : "write", - sdhsts); - host->data->error = -ETIMEDOUT; -- } else if (!is_read && !host->data->error) { -- /* Start a timer in case a transfer error occurs because -- there is no error interrupt */ -- mod_timer(&host->pio_timer, jiffies + host->pio_timeout); - } -+ log_event("XFP>", (u32)host->data, host->blocks); - } - -- --static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) -+static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, -+ struct mmc_data *data) - { -- u32 len, dir_data, dir_slave; -+ int len, dir_data, dir_slave; - struct dma_async_tx_descriptor *desc = NULL; - struct dma_chan *dma_chan; - -- pr_debug("bcm2835_sdhost_transfer_dma()\n"); -- -- WARN_ON(!host->data); -- -- if (!host->data) -- return; -+ log_event("PRD<", (u32)data, 0); -+ pr_debug("bcm2835_sdhost_prepare_dma()\n"); - -- if (host->data->flags & MMC_DATA_READ) { -+ if (data->flags & MMC_DATA_READ) { - dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; -@@ -625,35 +780,71 @@ static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; - } -+ log_event("PRD1", (u32)dma_chan, 0); - - BUG_ON(!dma_chan->device); - BUG_ON(!dma_chan->device->dev); -- BUG_ON(!host->data->sg); -+ BUG_ON(!data->sg); -+ -+ /* The block doesn't manage the FIFO DREQs properly for multi-block -+ transfers, so don't attempt to DMA the final few words. -+ Unfortunately this requires the final sg entry to be trimmed. -+ N.B. This code demands that the overspill is contained in -+ a single sg entry. -+ */ -+ -+ host->drain_words = 0; -+ if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) { -+ struct scatterlist *sg; -+ u32 len; -+ int i; -+ -+ len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4, -+ (u32)data->blocks * data->blksz); - -- len = dma_map_sg(dma_chan->device->dev, host->data->sg, -- host->data->sg_len, dir_data); -- if (len > 0) { -- desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, -+ for_each_sg(data->sg, sg, data->sg_len, i) { -+ if (sg_is_last(sg)) { -+ BUG_ON(sg->length < len); -+ sg->length -= len; -+ host->drain_page = (struct page *)sg->page_link; -+ host->drain_offset = sg->offset + sg->length; -+ } -+ } -+ host->drain_words = len/4; -+ } -+ -+ len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, -+ dir_data); -+ -+ log_event("PRD2", len, 0); -+ if (len > 0) -+ desc = dmaengine_prep_slave_sg(dma_chan, data->sg, - len, dir_slave, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -- } else { -- dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -- } -+ log_event("PRD3", (u32)desc, 0); -+ - if (desc) { - desc->callback = bcm2835_sdhost_dma_complete; - desc->callback_param = host; -- dmaengine_submit(desc); -- dma_async_issue_pending(dma_chan); -+ host->dma_desc = desc; -+ host->dma_chan = dma_chan; -+ host->dma_dir = dir_data; - } -- -+ log_event("PDM>", (u32)data, 0); - } - -+static void bcm2835_sdhost_start_dma(struct bcm2835_host *host) -+{ -+ log_event("SDMA", (u32)host->data, (u32)host->dma_chan); -+ dmaengine_submit(host->dma_desc); -+ dma_async_issue_pending(host->dma_chan); -+} - - static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) - { - u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | - SDHCFG_BUSY_IRPT_EN; -- if (host->use_dma) -+ if (host->dma_desc) - host->hcfg = (host->hcfg & ~all_irqs) | - SDHCFG_BUSY_IRPT_EN; - else -@@ -664,13 +855,13 @@ static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - } - -- - static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) - { - struct mmc_data *data = cmd->data; - - WARN_ON(host->data); - -+ host->data = data; - if (!data) - return; - -@@ -679,46 +870,19 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - BUG_ON(data->blksz > host->mmc->max_blk_size); - BUG_ON(data->blocks > 65535); - -- host->data = data; - host->data_complete = 0; - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- if (!host->sectors && host->mmc->card && !(host->debug_flags & 1)) -- { -- struct mmc_card *card = host->mmc->card; -- if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -- /* -- * The EXT_CSD sector count is in number of 512 byte -- * sectors. -- */ -- host->sectors = card->ext_csd.sectors; -- pr_err("%s: using ext_csd!\n", mmc_hostname(host->mmc)); -- } else { -- /* -- * The CSD capacity field is in units of read_blkbits. -- * set_capacity takes units of 512 bytes. -- */ -- host->sectors = card->csd.capacity << -- (card->csd.read_blkbits - 9); -- } -- host->single_read_sectors[0] = host->sectors - 65; -- host->single_read_sectors[1] = host->sectors - 64; -- host->single_read_sectors[2] = host->sectors - 33; -- host->single_read_sectors[3] = host->sectors - 32; -- host->single_read_sectors[4] = host->sectors - 1; -- host->single_read_sectors[5] = ~0; /* Safety net */ -- } - -- host->use_dma = host->have_dma && (data->blocks > host->pio_limit); -- if (!host->use_dma) { -+ if (!host->dma_desc) { -+ /* Use PIO */ - int flags; - -- flags = SG_MITER_ATOMIC; - if (data->flags & MMC_DATA_READ) -- flags |= SG_MITER_TO_SG; -+ flags = SG_MITER_TO_SG; - else -- flags |= SG_MITER_FROM_SG; -+ flags = SG_MITER_FROM_SG; - sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); - host->blocks = data->blocks; - } -@@ -726,19 +890,20 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -- bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); - - BUG_ON(!host->data); - } - -- --void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) -+bool bcm2835_sdhost_send_command(struct bcm2835_host *host, -+ struct mmc_command *cmd) - { - u32 sdcmd, sdhsts; - unsigned long timeout; - int delay; - - WARN_ON(host->cmd); -+ log_event("CMD<", cmd->opcode, cmd->arg); - - if (cmd->data) - pr_debug("%s: send_command %d 0x%x " -@@ -761,9 +926,9 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - pr_err("%s: previous command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); -- cmd->error = -EIO; -+ cmd->error = -EILSEQ; - tasklet_schedule(&host->finish_tasklet); -- return; -+ return false; - } - timeout--; - udelay(10); -@@ -791,23 +956,24 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - if (sdhsts & SDHSTS_ERROR_MASK) - bcm2835_sdhost_write(host, sdhsts, SDHSTS); - -- bcm2835_sdhost_prepare_data(host, cmd); -- -- bcm2835_sdhost_write(host, cmd->arg, SDARG); -- - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { - pr_err("%s: unsupported response type!\n", - mmc_hostname(host->mmc)); - cmd->error = -EINVAL; - tasklet_schedule(&host->finish_tasklet); -- return; -+ return false; - } - -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ - sdcmd = cmd->opcode & SDCMD_CMD_MASK; - -- if (!(cmd->flags & MMC_RSP_PRESENT)) -+ host->use_busy = 0; -+ if (!(cmd->flags & MMC_RSP_PRESENT)) { - sdcmd |= SDCMD_NO_RESPONSE; -- else { -+ } else { - if (cmd->flags & MMC_RSP_136) - sdcmd |= SDCMD_LONG_RESPONSE; - if (cmd->flags & MMC_RSP_BUSY) { -@@ -817,6 +983,7 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - } - - if (cmd->data) { -+ log_event("CMDD", cmd->data->blocks, cmd->data->blksz); - if (host->delay_after_stop) { - struct timeval now; - int time_since_stop; -@@ -839,10 +1006,12 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - } - - bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); --} - -+ return true; -+} - --static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, -+ unsigned long *irq_flags); - static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); - - static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) -@@ -852,6 +1021,7 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - data = host->data; - BUG_ON(!data); - -+ log_event("FDA<", (u32)host->mrq, (u32)host->cmd); - pr_debug("finish_data(error %d, stop %d, sbc %d)\n", - data->error, data->stop ? 1 : 0, - host->mrq->sbc ? 1 : 0); -@@ -859,10 +1029,7 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - -- if (data->error) { -- data->bytes_xfered = 0; -- } else -- data->bytes_xfered = data->blksz * data->blocks; -+ data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks); - - host->data_complete = 1; - -@@ -877,9 +1044,9 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - } - else - bcm2835_sdhost_transfer_complete(host); -+ log_event("FDA>", (u32)host->mrq, (u32)host->cmd); - } - -- - static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - { - struct mmc_data *data; -@@ -891,6 +1058,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - data = host->data; - host->data = NULL; - -+ log_event("TCM<", (u32)data, data->error); - pr_debug("transfer_complete(error %d, stop %d)\n", - data->error, data->stop ? 1 : 0); - -@@ -899,88 +1067,114 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - * a) open-ended multiblock transfer (no CMD23) - * b) error in multiblock transfer - */ -- if (data->stop && -- (data->error || -- !host->mrq->sbc)) { -- host->flush_fifo = 1; -- bcm2835_sdhost_send_command(host, data->stop); -- if (host->delay_after_stop) -- do_gettimeofday(&host->stop_time); -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); -+ if (host->mrq->stop && (data->error || !host->use_sbc)) { -+ if (bcm2835_sdhost_send_command(host, host->mrq->stop)) { -+ /* No busy, so poll for completion */ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, NULL); -+ -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ } - } else { -+ bcm2835_sdhost_wait_transfer_complete(host); - tasklet_schedule(&host->finish_tasklet); - } -+ log_event("TCM>", (u32)data, 0); - } - --static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) -+/* If irq_flags is valid, the caller is in a thread context and is allowed -+ to sleep */ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, -+ unsigned long *irq_flags) - { - u32 sdcmd; -- unsigned long timeout; -+ u32 retries; - #ifdef DEBUG - struct timeval before, after; - int timediff = 0; - #endif - -+ log_event("FCM<", (u32)host->mrq, (u32)host->cmd); - pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); - - BUG_ON(!host->cmd || !host->mrq); - --#ifdef DEBUG -- do_gettimeofday(&before); --#endif -- /* Wait max 100 ms */ -- timeout = 10000; -+ /* Poll quickly at first */ -+ -+ retries = host->cmd_quick_poll_retries; -+ if (!retries) { -+ /* Work out how many polls take 1us by timing 10us */ -+ struct timeval start, now; -+ int us_diff; -+ -+ retries = 1; -+ do { -+ int i; -+ -+ retries *= 2; -+ -+ do_gettimeofday(&start); -+ -+ for (i = 0; i < retries; i++) { -+ cpu_relax(); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ } -+ -+ do_gettimeofday(&now); -+ us_diff = (now.tv_sec - start.tv_sec) * 1000000 + -+ (now.tv_usec - start.tv_usec); -+ } while (us_diff < 10); -+ -+ host->cmd_quick_poll_retries = ((retries * us_diff + 9)*CMD_DALLY_US)/10 + 1; -+ retries = 1; // We've already waited long enough this time -+ } -+ -+ retries = host->cmd_quick_poll_retries; - for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -- (sdcmd & SDCMD_NEW_FLAG) && timeout; -- timeout--) { -- if (host->flush_fifo) { -- while (bcm2835_sdhost_read(host, SDHSTS) & -- SDHSTS_DATA_FLAG) -- (void)bcm2835_sdhost_read(host, SDDATA); -- } -- udelay(10); -+ (sdcmd & SDCMD_NEW_FLAG) && !(sdcmd & SDCMD_FAIL_FLAG) && retries; -+ retries--) { -+ cpu_relax(); - sdcmd = bcm2835_sdhost_read(host, SDCMD); - } --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + -- (after.tv_usec - before.tv_usec); - -- pr_debug(" finish_command - waited %dus\n", timediff); --#endif -+ if (!retries) { -+ unsigned long wait_max; -+ -+ if (!irq_flags) { -+ /* Schedule the work */ -+ log_event("CWWQ", 0, 0); -+ schedule_work(&host->cmd_wait_wq); -+ return; -+ } -+ -+ /* Wait max 100 ms */ -+ wait_max = jiffies + msecs_to_jiffies(100); -+ while (time_before(jiffies, wait_max)) { -+ spin_unlock_irqrestore(&host->lock, *irq_flags); -+ usleep_range(1, 10); -+ spin_lock_irqsave(&host->lock, *irq_flags); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ if (!(sdcmd & SDCMD_NEW_FLAG) || -+ (sdcmd & SDCMD_FAIL_FLAG)) -+ break; -+ } -+ } - -- if (timeout == 0) { -+ /* Check for errors */ -+ if (sdcmd & SDCMD_NEW_FLAG) { - pr_err("%s: command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - host->cmd->error = -EIO; - tasklet_schedule(&host->finish_tasklet); - return; -- } -- -- if (host->flush_fifo) { -- for (timeout = 100; -- (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -- timeout--) { -- (void)bcm2835_sdhost_read(host, SDDATA); -- } -- host->flush_fifo = 0; -- if (timeout == 0) { -- pr_err("%s: FIFO never drained.\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -- tasklet_schedule(&host->finish_tasklet); -- return; -- } -- } -- -- /* Check for errors */ -- if (sdcmd & SDCMD_FAIL_FLAG) -- { -+ } else if (sdcmd & SDCMD_FAIL_FLAG) { - u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -+ /* Clear the errors */ -+ bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS); -+ - if (host->debug) - pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", - mmc_hostname(host->mmc), sdcmd, sdhsts, -@@ -1003,7 +1197,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - mmc_hostname(host->mmc), - host->cmd->opcode); - bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -+ host->cmd->error = -EILSEQ; - } - tasklet_schedule(&host->finish_tasklet); - return; -@@ -1018,31 +1212,31 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - pr_debug("%s: finish_command %08x %08x %08x %08x\n", - mmc_hostname(host->mmc), - host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); -+ log_event("RSP ", host->cmd->resp[0], host->cmd->resp[1]); - } else { - host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); - pr_debug("%s: finish_command %08x\n", - mmc_hostname(host->mmc), - host->cmd->resp[0]); -+ log_event("RSP ", host->cmd->resp[0], 0); - } - } - -- host->cmd->error = 0; -- - if (host->cmd == host->mrq->sbc) { - /* Finished CMD23, now send actual command. */ - host->cmd = NULL; -- bcm2835_sdhost_send_command(host, host->mrq->cmd); -- -- if (host->cmd->data && host->use_dma) -- /* DMA transfer starts now, PIO starts after irq */ -- bcm2835_sdhost_transfer_dma(host); -+ if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) { -+ if (host->data && host->dma_desc) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_start_dma(host); - -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); -- } else if (host->cmd == host->mrq->stop) -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, NULL); -+ } -+ } else if (host->cmd == host->mrq->stop) { - /* Finished CMD12 */ - tasklet_schedule(&host->finish_tasklet); -- else { -+ } else { - /* Processed actual command. */ - host->cmd = NULL; - if (!host->data) -@@ -1050,6 +1244,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - else if (host->data_complete) - bcm2835_sdhost_transfer_complete(host); - } -+ log_event("FCM>", (u32)host->mrq, (u32)host->cmd); - } - - static void bcm2835_sdhost_timeout(unsigned long data) -@@ -1060,10 +1255,12 @@ static void bcm2835_sdhost_timeout(unsigned long data) - host = (struct bcm2835_host *)data; - - spin_lock_irqsave(&host->lock, flags); -+ log_event("TIM<", 0, 0); - - if (host->mrq) { - pr_err("%s: timeout waiting for hardware interrupt.\n", - mmc_hostname(host->mmc)); -+ log_dump(); - bcm2835_sdhost_dumpregs(host); - - if (host->data) { -@@ -1084,74 +1281,15 @@ static void bcm2835_sdhost_timeout(unsigned long data) - spin_unlock_irqrestore(&host->lock, flags); - } - --static void bcm2835_sdhost_pio_timeout(unsigned long data) -+static void bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - { -- struct bcm2835_host *host; -- unsigned long flags; -- -- host = (struct bcm2835_host *)data; -- -- spin_lock_irqsave(&host->lock, flags); -- -- if (host->data) { -- u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -- -- if (sdhsts & SDHSTS_REW_TIME_OUT) { -- pr_err("%s: transfer timeout\n", -- mmc_hostname(host->mmc)); -- if (host->debug) -- bcm2835_sdhost_dumpregs(host); -- } else { -- pr_err("%s: unexpected transfer timeout\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- } -- -- bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -- SDHSTS); -- -- host->data->error = -ETIMEDOUT; -- -- bcm2835_sdhost_finish_data(host); -- } -- -- mmiowb(); -- spin_unlock_irqrestore(&host->lock, flags); --} -- --static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) --{ -- if (enable) -- host->hcfg |= SDHCFG_SDIO_IRPT_EN; -- else -- host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- mmiowb(); --} -- --static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) --{ -- struct bcm2835_host *host = mmc_priv(mmc); -- unsigned long flags; -- -- pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); -- spin_lock_irqsave(&host->lock, flags); -- bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -- spin_unlock_irqrestore(&host->lock, flags); --} -- --static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) --{ -- const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -- SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR); -- -+ log_event("IRQB", (u32)host->cmd, intmask); - if (!host->cmd) { - pr_err("%s: got command busy interrupt 0x%08x even " - "though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return 0; -+ return; - } - - if (!host->use_busy) { -@@ -1159,7 +1297,7 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - "though not expecting one.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return 0; -+ return; - } - host->use_busy = 0; - -@@ -1182,28 +1320,23 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } else if (intmask & SDHSTS_CMD_TIME_OUT) - host->cmd->error = -ETIMEDOUT; - -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); - } - else -- bcm2835_sdhost_finish_command(host); -- -- return handled; -+ bcm2835_sdhost_finish_command(host, NULL); - } - --static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) -+static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_REW_TIME_OUT | -- SDHSTS_CRC16_ERROR | -- SDHSTS_FIFO_ERROR); -- - /* There are no dedicated data/space available interrupt - status bits, so it is necessary to use the single shared - data/space available FIFO status bits. It is therefore not - an error to get here when there is no data transfer in - progress. */ -+ log_event("IRQD", (u32)host->data, intmask); - if (!host->data) -- return 0; -+ return; - - if (intmask & (SDHSTS_CRC16_ERROR | - SDHSTS_FIFO_ERROR | -@@ -1214,46 +1347,37 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - else - host->data->error = -ETIMEDOUT; - -- bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); -- return handled; -+ if (host->debug) { -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ } - } - -- /* Use the block interrupt for writes after the first block */ -- if (host->data->flags & MMC_DATA_WRITE) { -+ if (host->data->error) { -+ bcm2835_sdhost_finish_data(host); -+ } else if (host->data->flags & MMC_DATA_WRITE) { -+ /* Use the block interrupt for writes after the first block */ - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); - host->hcfg |= SDHCFG_BLOCK_IRPT_EN; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- if (host->data->error) -- bcm2835_sdhost_finish_data(host); -- else -- bcm2835_sdhost_transfer_pio(host); -+ bcm2835_sdhost_transfer_pio(host); - } else { -- if (!host->data->error) { -- bcm2835_sdhost_transfer_pio(host); -- host->blocks--; -- } -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; - if ((host->blocks == 0) || host->data->error) - bcm2835_sdhost_finish_data(host); - } -- -- return handled; - } - --static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) -+static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - { -- struct dma_chan *dma_chan; -- u32 dir_data; -- const u32 handled = (SDHSTS_REW_TIME_OUT | -- SDHSTS_CRC16_ERROR | -- SDHSTS_FIFO_ERROR); -- -+ log_event("IRQK", (u32)host->data, intmask); - if (!host->data) { - pr_err("%s: got block interrupt 0x%08x even " - "though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return handled; -+ return; - } - - if (intmask & (SDHSTS_CRC16_ERROR | -@@ -1265,149 +1389,69 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - else - host->data->error = -ETIMEDOUT; - -- if (host->debug) -+ if (host->debug) { -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); -- return handled; -+ } - } - -- if (!host->use_dma) { -+ if (!host->dma_desc) { - BUG_ON(!host->blocks); -- host->blocks--; -- if ((host->blocks == 0) || host->data->error) { -- /* Cancel the timer */ -- del_timer(&host->pio_timer); -- -+ if (host->data->error || (--host->blocks == 0)) { - bcm2835_sdhost_finish_data(host); - } else { -- /* Reset the timer */ -- mod_timer(&host->pio_timer, -- jiffies + host->pio_timeout); -- - bcm2835_sdhost_transfer_pio(host); -- -- /* Reset the timer */ -- mod_timer(&host->pio_timer, -- jiffies + host->pio_timeout); - } - } else if (host->data->flags & MMC_DATA_WRITE) { -- dma_chan = host->dma_chan_tx; -- dir_data = DMA_TO_DEVICE; -- dma_unmap_sg(dma_chan->device->dev, -- host->data->sg, host->data->sg_len, -- dir_data); -- - bcm2835_sdhost_finish_data(host); - } -- -- return handled; - } - -- - static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - { - irqreturn_t result = IRQ_NONE; - struct bcm2835_host *host = dev_id; -- u32 unexpected = 0, early = 0; -- int loops = 0; -+ u32 intmask; - - spin_lock(&host->lock); - -- for (loops = 0; loops < 1; loops++) { -- u32 intmask, handled; -- -- intmask = bcm2835_sdhost_read(host, SDHSTS); -- handled = intmask & (SDHSTS_BUSY_IRPT | -- SDHSTS_BLOCK_IRPT | -- SDHSTS_SDIO_IRPT | -- SDHSTS_DATA_FLAG); -- if ((handled == SDHSTS_DATA_FLAG) && -- (loops == 0) && !host->data) { -- pr_err("%s: sdhost_irq data interrupt 0x%08x even " -- "though no data operation was in progress.\n", -- mmc_hostname(host->mmc), -- (unsigned)intmask); -- -- bcm2835_sdhost_dumpregs(host); -- } -- -- if (!handled) -- break; -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ log_event("IRQ<", intmask, 0); - -- if (loops) -- early |= handled; -+ bcm2835_sdhost_write(host, -+ SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG, -+ SDHSTS); - -+ if (intmask & SDHSTS_BLOCK_IRPT) { -+ bcm2835_sdhost_block_irq(host, intmask); - result = IRQ_HANDLED; -+ } - -- /* Clear all interrupts and notifications */ -- bcm2835_sdhost_write(host, intmask, SDHSTS); -- -- if (intmask & SDHSTS_BUSY_IRPT) -- handled |= bcm2835_sdhost_busy_irq(host, intmask); -- -- /* There is no true data interrupt status bit, so it is -- necessary to qualify the data flag with the interrupt -- enable bit */ -- if ((intmask & SDHSTS_DATA_FLAG) && -- (host->hcfg & SDHCFG_DATA_IRPT_EN)) -- handled |= bcm2835_sdhost_data_irq(host, intmask); -- -- if (intmask & SDHSTS_BLOCK_IRPT) -- handled |= bcm2835_sdhost_block_irq(host, intmask); -- -- if (intmask & SDHSTS_SDIO_IRPT) { -- bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -- host->thread_isr |= SDHSTS_SDIO_IRPT; -- result = IRQ_WAKE_THREAD; -- } -+ if (intmask & SDHSTS_BUSY_IRPT) { -+ bcm2835_sdhost_busy_irq(host, intmask); -+ result = IRQ_HANDLED; -+ } - -- unexpected |= (intmask & ~handled); -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) { -+ bcm2835_sdhost_data_irq(host, intmask); -+ result = IRQ_HANDLED; - } - - mmiowb(); - -+ log_event("IRQ>", bcm2835_sdhost_read(host, SDHSTS), 0); - spin_unlock(&host->lock); - -- if (early) -- pr_debug("%s: early %x (loops %d)\n", -- mmc_hostname(host->mmc), early, loops); -- -- if (unexpected) { -- pr_err("%s: unexpected interrupt 0x%08x.\n", -- mmc_hostname(host->mmc), unexpected); -- bcm2835_sdhost_dumpregs(host); -- } -- - return result; - } - --static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) --{ -- struct bcm2835_host *host = dev_id; -- unsigned long flags; -- u32 isr; -- -- spin_lock_irqsave(&host->lock, flags); -- isr = host->thread_isr; -- host->thread_isr = 0; -- spin_unlock_irqrestore(&host->lock, flags); -- -- if (isr & SDHSTS_SDIO_IRPT) { -- sdio_run_irqs(host->mmc); -- --/* Is this necessary? Why re-enable an interrupt which is enabled? -- spin_lock_irqsave(&host->lock, flags); -- if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -- bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -- spin_unlock_irqrestore(&host->lock, flags); --*/ -- } -- -- return isr ? IRQ_HANDLED : IRQ_NONE; --} -- -- -- - void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -@@ -1417,9 +1461,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); - - if ((host->overclock_50 > 50) && -- (clock == 50*MHZ)) { -+ (clock == 50*MHZ)) - clock = host->overclock_50 * MHZ + (MHZ - 1); -- } - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1466,6 +1509,11 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -+ /* Calibrate some delays */ -+ -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ - if (clock > input_clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ -@@ -1501,6 +1549,7 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - { - struct bcm2835_host *host; - unsigned long flags; -+ u32 edm, fsm; - - host = mmc_priv(mmc); - -@@ -1521,6 +1570,8 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - } - - /* Reset the error statuses in case this is a retry */ -+ if (mrq->sbc) -+ mrq->sbc->error = 0; - if (mrq->cmd) - mrq->cmd->error = 0; - if (mrq->data) -@@ -1536,28 +1587,58 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - return; - } - -+ if (host->use_dma && mrq->data && -+ (mrq->data->blocks > host->pio_limit)) -+ bcm2835_sdhost_prepare_dma(host, mrq->data); -+ - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -- - host->mrq = mrq; - -- if (mrq->sbc) -- bcm2835_sdhost_send_command(host, mrq->sbc); -- else -- bcm2835_sdhost_send_command(host, mrq->cmd); -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ fsm = edm & SDEDM_FSM_MASK; - -- mmiowb(); -- spin_unlock_irqrestore(&host->lock, flags); -+ log_event("REQ<", (u32)mrq, edm); -+ if ((fsm != SDEDM_FSM_IDENTMODE) && -+ (fsm != SDEDM_FSM_DATAMODE)) { -+ pr_err("%s: previous command (%d) not complete (EDM %x)\n", -+ mmc_hostname(host->mmc), -+ bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, -+ edm); -+ log_event("REQ!", (u32)mrq, edm); -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ mrq->cmd->error = -EILSEQ; -+ tasklet_schedule(&host->finish_tasklet); -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; -+ } - -- if (!mrq->sbc && mrq->cmd->data && host->use_dma) -- /* DMA transfer starts now, PIO starts after irq */ -- bcm2835_sdhost_transfer_dma(host); -+ host->use_sbc = !!mrq->sbc && -+ (host->mrq->data->flags & USE_CMD23_FLAGS); -+ if (host->use_sbc) { -+ if (bcm2835_sdhost_send_command(host, mrq->sbc)) { -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, &flags); -+ } -+ } else if (bcm2835_sdhost_send_command(host, mrq->cmd)) { -+ if (host->data && host->dma_desc) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_start_dma(host); - -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); --} -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, &flags); -+ } - -+ log_event("CMD ", (u32)mrq->cmd->opcode, -+ mrq->data ? (u32)mrq->data->blksz : 0); -+ mmiowb(); -+ -+ log_event("REQ>", (u32)mrq, 0); -+ spin_unlock_irqrestore(&host->lock, flags); -+} - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { -@@ -1574,6 +1655,8 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - - spin_lock_irqsave(&host->lock, flags); - -+ log_event("IOS<", ios->clock, 0); -+ - if (!ios->clock || ios->clock != host->clock) { - bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -@@ -1596,59 +1679,53 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - spin_unlock_irqrestore(&host->lock, flags); - } - --static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, -- u32 blk_pos, int blk_size) -+static struct mmc_host_ops bcm2835_sdhost_ops = { -+ .request = bcm2835_sdhost_request, -+ .set_ios = bcm2835_sdhost_set_ios, -+ .hw_reset = bcm2835_sdhost_reset, -+}; -+ -+static void bcm2835_sdhost_cmd_wait_work(struct work_struct *work) - { -- /* There is a bug in the host controller hardware that makes -- reading the final sector of the card as part of a multiple read -- problematic. Detect that case and shorten the read accordingly. -- */ - struct bcm2835_host *host; -+ unsigned long flags; - -- host = mmc_priv(card->host); -+ host = container_of(work, struct bcm2835_host, cmd_wait_wq); - -- if (!host->sectors) { -- /* csd.capacity is in weird units - convert to sectors */ -- u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -- if ((direction == MMC_DATA_READ) && -- ((blk_pos + blk_size) == card_sectors)) -- blk_size--; -- return blk_size; -- } -+ spin_lock_irqsave(&host->lock, flags); - -- if (direction == MMC_DATA_READ) { -- int i; -- int sector; -- for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -- continue; -+ log_event("CWK<", (u32)host->cmd, (u32)host->mrq); - -- if ((blk_pos + blk_size) > sector) -- blk_size = (blk_pos == sector) ? 1 : (sector - blk_pos); -+ /* -+ * If this tasklet gets rescheduled while running, it will -+ * be run again afterwards but without any active request. -+ */ -+ if (!host->mrq) { -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; - } -- return blk_size; --} - -+ bcm2835_sdhost_finish_command(host, &flags); - --static struct mmc_host_ops bcm2835_sdhost_ops = { -- .request = bcm2835_sdhost_request, -- .set_ios = bcm2835_sdhost_set_ios, -- .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -- .hw_reset = bcm2835_sdhost_reset, -- .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, --}; -+ mmiowb(); -+ -+ log_event("CWK>", (u32)host->cmd, 0); - -+ spin_unlock_irqrestore(&host->lock, flags); -+} - - static void bcm2835_sdhost_tasklet_finish(unsigned long param) - { - struct bcm2835_host *host; - unsigned long flags; - struct mmc_request *mrq; -+ struct dma_chan *terminate_chan = NULL; - - host = (struct bcm2835_host *)param; - - spin_lock_irqsave(&host->lock, flags); - -+ log_event("TSK<", (u32)host->mrq, 0); - /* - * If this tasklet gets rescheduled while running, it will - * be run again afterwards but without any active request. -@@ -1683,11 +1760,23 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - mmiowb(); - -+ host->dma_desc = NULL; -+ terminate_chan = host->dma_chan; -+ host->dma_chan = NULL; -+ - spin_unlock_irqrestore(&host->lock, flags); -- mmc_request_done(host->mmc, mrq); --} - -+ if (terminate_chan) -+ { -+ int err = dmaengine_terminate_all(terminate_chan); -+ if (err) -+ pr_err("%s: failed to terminate DMA (%d)\n", -+ mmc_hostname(host->mmc), err); -+ } - -+ mmc_request_done(host->mmc, mrq); -+ log_event("TSK>", (u32)mrq, 0); -+} - - int bcm2835_sdhost_add_host(struct bcm2835_host *host) - { -@@ -1709,10 +1798,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmc->f_max, mmc->f_min, mmc->max_busy_timeout); - - /* host controller capabilities */ -- mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | -+ mmc->caps |= - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | -- (ALLOW_CMD23 * MMC_CAP_CMD23); -+ ((ALLOW_CMD23_READ|ALLOW_CMD23_WRITE) * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - -@@ -1722,9 +1811,9 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - pr_err("%s: unable to initialise DMA channels. " - "Falling back to PIO\n", - mmc_hostname(mmc)); -- host->have_dma = false; -+ host->use_dma = false; - } else { -- host->have_dma = true; -+ host->use_dma = true; - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -@@ -1741,7 +1830,7 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); - } - } else { -- host->have_dma = false; -+ host->use_dma = false; - } - - mmc->max_segs = 128; -@@ -1756,16 +1845,15 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - tasklet_init(&host->finish_tasklet, - bcm2835_sdhost_tasklet_finish, (unsigned long)host); - -- setup_timer(&host->timer, bcm2835_sdhost_timeout, -- (unsigned long)host); -+ INIT_WORK(&host->cmd_wait_wq, bcm2835_sdhost_cmd_wait_work); - -- setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - - bcm2835_sdhost_init(host, 0); -- ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -- bcm2835_sdhost_thread_irq, -- IRQF_SHARED, mmc_hostname(mmc), host); -+ -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -1776,11 +1864,11 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmc_add_host(mmc); - - pio_limit_string[0] = '\0'; -- if (host->have_dma && (host->pio_limit > 0)) -+ if (host->use_dma && (host->pio_limit > 0)) - sprintf(pio_limit_string, " (>%d)", host->pio_limit); - pr_info("%s: %s loaded - DMA %s%s\n", - mmc_hostname(mmc), DRIVER_NAME, -- host->have_dma ? "enabled" : "disabled", -+ host->use_dma ? "enabled" : "disabled", - pio_limit_string); - - return 0; -@@ -1810,8 +1898,11 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - mmc->ops = &bcm2835_sdhost_ops; - host = mmc_priv(mmc); - host->mmc = mmc; -+ host->cmd_quick_poll_retries = 0; - host->pio_timeout = msecs_to_jiffies(500); -+ host->pio_limit = 1; - host->max_delay = 1; /* Warn if over 1ms */ -+ host->allow_dma = 1; - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -1827,13 +1918,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - return -ENODEV; - } - host->bus_addr = be32_to_cpup(addr); -+ log_init(iomem->start - host->bus_addr); - pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", - (unsigned long)host->ioaddr, - (unsigned long)iomem->start, - (unsigned long)host->bus_addr); - -- host->allow_dma = ALLOW_DMA; -- - if (node) { - /* Read any custom properties */ - of_property_read_u32(node, -@@ -1845,16 +1935,17 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,pio-limit", - &host->pio_limit); -- host->allow_dma = ALLOW_DMA && -+ host->allow_dma = - !of_property_read_bool(node, "brcm,force-pio"); - host->debug = of_property_read_bool(node, "brcm,debug"); -- of_property_read_u32(node, -- "brcm,debug-flags", -- &host->debug_flags); - } - -- if (host->debug_flags) -- dev_err(dev, "debug_flags=%x\n", host->debug_flags); -+ host->dma_chan = NULL; -+ host->dma_desc = NULL; -+ -+ /* Formally recognise the other way of disabling DMA */ -+ if (host->pio_limit == 0x7fffffff) -+ host->allow_dma = false; - - if (host->allow_dma) { - if (node) { -@@ -1940,15 +2031,12 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - return 0; - } - -- - static const struct of_device_id bcm2835_sdhost_match[] = { - { .compatible = "brcm,bcm2835-sdhost" }, - { } - }; - MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); - -- -- - static struct platform_driver bcm2835_sdhost_driver = { - .probe = bcm2835_sdhost_probe, - .remove = bcm2835_sdhost_remove, - -From 28749d393c5f8b68c20ab5827c0e519eb96c89fe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 12 Feb 2016 15:38:00 +0000 -Subject: [PATCH 140/251] BCM270X_DT: Add dtparams for the SD interface - -Add new base dtparams sd_overclock, sd_force_pio, sd_pio_limit -and sd_debug. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 13 +++++++++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++++ - arch/arm/boot/dts/overlays/README | 11 ++++++++++- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 1 - - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 27 +++++++++++++------------- - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 14 ++++++------- - 10 files changed, 58 insertions(+), 23 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 2e4df17..d2d6fa0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -141,5 +141,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 0445b46..d033ee4 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -131,5 +131,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 87c1a54..8bcafb4 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -97,6 +97,5 @@ - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -- core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 3c8bdde..e09e499 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -7,6 +7,13 @@ - }; - }; - -+&gpio { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ - &leds { - act_led: act { - label = "led0"; -@@ -29,6 +36,8 @@ - - / { - __overrides__ { -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -@@ -36,5 +45,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 75fb4ce..18d3c45 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -135,6 +135,7 @@ - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; -+ brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - status = "disabled"; - }; -@@ -203,6 +204,7 @@ - dmas = <&dma 11>, - <&dma 11>; - dma-names = "tx", "rx"; -+ brcm,overclock-50 = <0>; - status = "disabled"; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 5206ba2..aca253f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -141,5 +141,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index f987565..0a2df01 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -112,6 +112,16 @@ Params: - random Set to "on" to enable the hardware random - number generator (default "on") - -+ sd_overclock Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ sd_force_pio Disable DMA support for SD driver (default off) -+ -+ sd_pio_limit Number of blocks above which to use DMA for -+ SD card (default 1) -+ -+ sd_debug Enable debug output from SD driver (default off) -+ - uart0 Set to "off" to disable uart0 (default "on") - - watchdog Set to "on" to enable the hardware watchdog -@@ -443,7 +453,6 @@ Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -- force_pio Disable DMA support - - - Name: mz61581 -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -index 00a22be..d32b02c 100644 ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -34,6 +34,5 @@ - - __overrides__ { - overclock_50 = <&frag0>,"brcm,overclock-50:0"; -- force_pio = <&frag0>,"brcm,force-pio?"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index dbe6574..a431177 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -1,19 +1,14 @@ - /dts-v1/; - /plugin/; - -+/* Provide backwards compatible aliases for the old sdhost dtparams. */ -+ - /{ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&mmc>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- -- fragment@1 { - target = <&sdhost>; -- frag1: __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - brcm,debug-flags = <0>; -@@ -21,11 +16,17 @@ - }; - }; - -+ fragment@1 { -+ target = <&mmc>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ - __overrides__ { -- overclock_50 = <&frag1>,"brcm,overclock-50:0"; -- force_pio = <&frag1>,"brcm,force-pio?"; -- pio_limit = <&frag1>,"brcm,pio-limit:0"; -- debug = <&frag1>,"brcm,debug?"; -- debug_flags = <&frag1>,"brcm,debug-flags:0"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; -+ pio_limit = <&frag0>,"brcm,pio-limit:0"; -+ debug = <&frag0>,"brcm,debug?"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -index b0b208c..e4a4677 100644 ---- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -1,23 +1,23 @@ - /dts-v1/; - /plugin/; - -+/* Provide backwards compatible aliases for the old sdhost dtparams. */ -+ - /{ - compatible = "brcm,bcm2708"; - - fragment@0 { - target = <&sdhost>; -- frag1: __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -- brcm,debug-flags = <0>; - }; - }; - - __overrides__ { -- overclock_50 = <&frag1>,"brcm,overclock-50:0"; -- force_pio = <&frag1>,"brcm,force-pio?"; -- pio_limit = <&frag1>,"brcm,pio-limit:0"; -- debug = <&frag1>,"brcm,debug?"; -- debug_flags = <&frag1>,"brcm,debug-flags:0"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; -+ pio_limit = <&frag0>,"brcm,pio-limit:0"; -+ debug = <&frag0>,"brcm,debug?"; - }; - }; - -From bad7a004e1e990eefa9f402684b19021baa81812 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 12 Feb 2016 14:50:25 +0000 -Subject: [PATCH 141/251] dcw_otg: trim xfer length when buffer larger than - allocated size is received - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 8db3dfc..d672a76 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -737,6 +737,11 @@ static int update_urb_state_xfer_comp(dwc_hc_t * hc, - DWC_OTG_HC_XFER_COMPLETE, - &short_read); - -+ if (urb->actual_length + xfer_length > urb->length) { -+ DWC_WARN("%s(): trimming xfer length\n", __func__); -+ xfer_length = urb->length - urb->actual_length; -+ } -+ - /* non DWORD-aligned buffer case handling. */ - if (hc->align_buff && xfer_length && hc->ep_is_in) { - dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, -@@ -1423,6 +1428,12 @@ static void update_urb_state_xfer_intr(dwc_hc_t * hc, - { - uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, - halt_status, NULL); -+ -+ if (urb->actual_length + bytes_transferred > urb->length) { -+ DWC_WARN("%s(): trimming xfer length\n", __func__); -+ bytes_transferred = urb->length - urb->actual_length; -+ } -+ - /* non DWORD-aligned buffer case handling. */ - if (hc->align_buff && bytes_transferred && hc->ep_is_in) { - dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, - -From 3f19b475b6394511ee22af77c8287ea1c1b8295a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Feb 2016 10:00:27 +0000 -Subject: [PATCH 142/251] bcm2835-sdhost: Restore ATOMIC flag to PIO sg mapping - -Allocation problems have been seen in a wireless driver, and -this is the only change which might have been responsible. ---- - drivers/mmc/host/bcm2835-sdhost.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 262180b..d66385c 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -874,15 +874,14 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- - if (!host->dma_desc) { - /* Use PIO */ -- int flags; -+ int flags = SG_MITER_ATOMIC; - - if (data->flags & MMC_DATA_READ) -- flags = SG_MITER_TO_SG; -+ flags |= SG_MITER_TO_SG; - else -- flags = SG_MITER_FROM_SG; -+ flags |= SG_MITER_FROM_SG; - sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); - host->blocks = data->blocks; - } - -From 962dfa8efd816762704046d501b703eb153fca3f Mon Sep 17 00:00:00 2001 +From cc4993db27b70169abaecdbbc2e5131c10a7c2b2 Mon Sep 17 00:00:00 2001 From: Craig Roberts Date: Tue, 16 Feb 2016 10:03:42 +0000 -Subject: [PATCH 143/251] Updated smsc95xx driver to check for a valid MAC +Subject: [PATCH 081/114] Updated smsc95xx driver to check for a valid MAC address in eeprom before using smsc95xx.macaddr parameter passed on command line. @@ -146852,10 +126367,10 @@ meaning they don't end up with the same MAC address as the built-in RPi adaptor. 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 3244a90..7483222 100755 +index 08ced57..a61bd08 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -817,10 +817,6 @@ static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) +@@ -821,10 +821,6 @@ static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) static void smsc95xx_init_mac_address(struct usbnet *dev) { @@ -146866,7 +126381,7 @@ index 3244a90..7483222 100755 /* try reading mac address from EEPROM */ if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -@@ -831,7 +827,11 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) +@@ -835,7 +831,11 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) } } @@ -146880,1345 +126395,25 @@ index 3244a90..7483222 100755 netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); } -From 0139c7899ec18de29f16b6dad11ea5cddd06ae62 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 17 Feb 2016 19:02:31 +0000 -Subject: [PATCH 144/251] dcw_otg: Make trimming messages less noisy - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index d672a76..e6b38ac 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -738,7 +738,8 @@ static int update_urb_state_xfer_comp(dwc_hc_t * hc, - &short_read); - - if (urb->actual_length + xfer_length > urb->length) { -- DWC_WARN("%s(): trimming xfer length\n", __func__); -+ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", -+ hc->dev_addr, __func__, __LINE__); - xfer_length = urb->length - urb->actual_length; - } - -@@ -1430,7 +1431,8 @@ static void update_urb_state_xfer_intr(dwc_hc_t * hc, - halt_status, NULL); - - if (urb->actual_length + bytes_transferred > urb->length) { -- DWC_WARN("%s(): trimming xfer length\n", __func__); -+ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", -+ hc->dev_addr, __func__, __LINE__); - bytes_transferred = urb->length - urb->actual_length; - } - - -From e41f1f667f3d2f4e6e22dc585a6d4dabbc5aafd7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 18 Feb 2016 15:28:14 +0000 -Subject: [PATCH 145/251] BCM270X_DT: at86rf233 overlay - drop to 3MHz - -The consensus is that 6MHz is too fast, but that 3MHz is OK. - -See: https://github.com/raspberrypi/linux/issues/1294 - https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/README | 2 +- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0a2df01..4de0b6f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -188,7 +188,7 @@ Load: dtoverlay=at86rf233,= - Params: interrupt GPIO used for INT (default 23) - reset GPIO used for Reset (default 24) - sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 6000000) -+ speed SPI bus speed in Hz (default 3000000) - trim Fine tuning of the internal capacitance - arrays (0=+0pF, 15=+4.5pF, default 15) - -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index 0460269..eab4052 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -25,7 +25,7 @@ - interrupts = <23 4>; /* active high */ - reset-gpio = <&gpio 24 1>; - sleep-gpio = <&gpio 25 1>; -- spi-max-frequency = <6000000>; -+ spi-max-frequency = <3000000>; - xtal-trim = /bits/ 8 <0xf>; - }; - }; - -From 61f20e3098ef685f6a14238c58b7158e637652bc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 19 Feb 2016 12:04:48 +0000 -Subject: [PATCH 146/251] bcm2835-sdhost: Downgrade log message status - ---- - drivers/mmc/host/bcm2835-sdhost.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index d66385c..4f6cab5 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -232,8 +232,8 @@ static void log_init(u32 bus_to_phys) - sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, - GFP_KERNEL); - if (sdhost_log_buf) { -- pr_err("sdhost: log_buf @ %p (%x)\n", -- sdhost_log_buf, sdhost_log_addr); -+ pr_info("sdhost: log_buf @ %p (%x)\n", -+ sdhost_log_buf, sdhost_log_addr); - timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); - if (!timer_base) - pr_err("sdhost: failed to remap timer\n"); - -From 8d7f055a36864ccb388a526cca31a4e416125ac6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 15 Jan 2016 16:48:27 +0000 -Subject: [PATCH 147/251] config: Enable HCI over UARTs - ---- - arch/arm/configs/bcm2709_defconfig | 3 +++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - 2 files changed, 5 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index fc35254..48ecb2e 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -376,6 +376,9 @@ CONFIG_BT_BNEP_PROTO_FILTER=y - CONFIG_BT_HIDP=m - CONFIG_BT_6LOWPAN=m - CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y - CONFIG_BT_HCIBCM203X=m - CONFIG_BT_HCIBPA10X=m - CONFIG_BT_HCIBFUSB=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 51dc019..4368f0d 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -370,6 +370,8 @@ CONFIG_BT_HIDP=m - CONFIG_BT_6LOWPAN=m - CONFIG_BT_HCIBTUSB=m - CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y - CONFIG_BT_HCIBCM203X=m - CONFIG_BT_HCIBPA10X=m - CONFIG_BT_HCIBFUSB=m - -From 4e80e74fc12bf2b3f75908afce3fe399323ccb90 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Dec 2015 13:37:07 +0000 -Subject: [PATCH 148/251] hci_h5: Don't send conf_req when ACTIVE - -Without this patch, a modem and kernel can continuously bombard each -other with conf_req and conf_rsp messages, in a demented game of tag. ---- - drivers/bluetooth/hci_h5.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index abee221..2825833 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -314,7 +314,8 @@ static void h5_handle_internal_rx(struct hci_uart *hu) - h5_link_control(hu, conf_req, 3); - } else if (memcmp(data, conf_req, 2) == 0) { - h5_link_control(hu, conf_rsp, 2); -- h5_link_control(hu, conf_req, 3); -+ if (h5->state != H5_ACTIVE) -+ h5_link_control(hu, conf_req, 3); - } else if (memcmp(data, conf_rsp, 2) == 0) { - if (H5_HDR_LEN(hdr) > 2) - h5->tx_win = (data[2] & 7); - -From 7ea16aeff2daf97ada8b68b9acad503f5a922c61 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH 149/251] amba_pl011: Don't use DT aliases for numbering - -The pl011 driver looks for DT aliases of the form "serial", -and if found uses as the device ID. This can cause -/dev/ttyAMA0 to become /dev/ttyAMA1, which is confusing if the -other serial port is provided by the 8250 driver which doesn't -use the same logic. ---- - drivers/tty/serial/amba-pl011.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 899a771..68b3353 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -2313,7 +2313,12 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, - if (IS_ERR(base)) - return PTR_ERR(base); - -+ /* Don't use DT serial aliases - it causes the device to -+ be renumbered to ttyAMA1 if it is the second serial port in the -+ system, even though the other one is ttyS0. The 8250 driver -+ doesn't use this logic, so always remains ttyS0. - index = pl011_probe_dt_alias(index, dev); -+ */ - - uap->old_cr = 0; - uap->port.dev = dev; - -From cce16b3c1c46f74a3178029ac894c89aea751af4 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 15:35:57 -0800 -Subject: [PATCH 150/251] clk: bcm2835: Add bindings for the auxiliary - peripheral clock gates. - -These will be used for enabling UART1, SPI1, and SPI2. - -Signed-off-by: Eric Anholt -Acked-by: Rob Herring -Signed-off-by: Michael Turquette ---- - .../bindings/clock/brcm,bcm2835-aux-clock.txt | 31 ++++++++++++++++++++++ - include/dt-bindings/clock/bcm2835-aux.h | 17 ++++++++++++ - 2 files changed, 48 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt - create mode 100644 include/dt-bindings/clock/bcm2835-aux.h - -diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt -new file mode 100644 -index 0000000..7a837d2 ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt -@@ -0,0 +1,31 @@ -+Broadcom BCM2835 auxiliary peripheral support -+ -+This binding uses the common clock binding: -+ Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+The auxiliary peripherals (UART, SPI1, and SPI2) have a small register -+area controlling clock gating to the peripherals, and providing an IRQ -+status register. -+ -+Required properties: -+- compatible: Should be "brcm,bcm2835-aux" -+- #clock-cells: Should be <1>. The permitted clock-specifier values can be -+ found in include/dt-bindings/clock/bcm2835-aux.h -+- reg: Specifies base physical address and size of the registers -+- clocks: The parent clock phandle -+ -+Example: -+ -+ clocks: cprman@7e101000 { -+ compatible = "brcm,bcm2835-cprman"; -+ #clock-cells = <1>; -+ reg = <0x7e101000 0x2000>; -+ clocks = <&clk_osc>; -+ }; -+ -+ aux: aux@0x7e215004 { -+ compatible = "brcm,bcm2835-aux"; -+ #clock-cells = <1>; -+ reg = <0x7e215000 0x8>; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ }; -diff --git a/include/dt-bindings/clock/bcm2835-aux.h b/include/dt-bindings/clock/bcm2835-aux.h -new file mode 100644 -index 0000000..d91156e ---- /dev/null -+++ b/include/dt-bindings/clock/bcm2835-aux.h -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2015 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#define BCM2835_AUX_CLOCK_UART 0 -+#define BCM2835_AUX_CLOCK_SPI1 1 -+#define BCM2835_AUX_CLOCK_SPI2 2 -+#define BCM2835_AUX_CLOCK_COUNT 3 - -From 16aac0eab690fbafcf6cb70a19ceffd848cc8ee8 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 15:35:58 -0800 -Subject: [PATCH 151/251] clk: bcm2835: Add a driver for the auxiliary - peripheral clock gates. - -There are a pair of SPI masters and a mini UART that were last minute -additions. As a result, they didn't get integrated in the same way as -the other gates off of the VPU clock in CPRMAN. - -Signed-off-by: Eric Anholt -Signed-off-by: Michael Turquette - -updated Makefile to preserve the rasoberry pi architectures ---- - drivers/clk/bcm/Makefile | 1 + - drivers/clk/bcm/clk-bcm2835-aux.c | 85 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 86 insertions(+) - create mode 100644 drivers/clk/bcm/clk-bcm2835-aux.c - -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index a1b4cbc..84070d5 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -4,6 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o - obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o -+obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o -diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c -new file mode 100644 -index 0000000..e4f89e2 ---- /dev/null -+++ b/drivers/clk/bcm/clk-bcm2835-aux.c -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BCM2835_AUXIRQ 0x00 -+#define BCM2835_AUXENB 0x04 -+ -+static int bcm2835_aux_clk_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct clk_onecell_data *onecell; -+ const char *parent; -+ struct clk *parent_clk; -+ struct resource *res; -+ void __iomem *reg, *gate; -+ -+ parent_clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(parent_clk)) -+ return PTR_ERR(parent_clk); -+ parent = __clk_get_name(parent_clk); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ reg = devm_ioremap_resource(dev, res); -+ if (!reg) -+ return -ENODEV; -+ -+ onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); -+ if (!onecell) -+ return -ENOMEM; -+ onecell->clk_num = BCM2835_AUX_CLOCK_COUNT; -+ onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT, -+ sizeof(*onecell->clks), GFP_KERNEL); -+ if (!onecell->clks) -+ return -ENOMEM; -+ -+ gate = reg + BCM2835_AUXENB; -+ onecell->clks[BCM2835_AUX_CLOCK_UART] = -+ clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL); -+ -+ onecell->clks[BCM2835_AUX_CLOCK_SPI1] = -+ clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL); -+ -+ onecell->clks[BCM2835_AUX_CLOCK_SPI2] = -+ clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL); -+ -+ of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm2835_aux_clk_of_match[] = { -+ { .compatible = "brcm,bcm2835-aux", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_aux_clk_of_match); -+ -+static struct platform_driver bcm2835_aux_clk_driver = { -+ .driver = { -+ .name = "bcm2835-aux-clk", -+ .of_match_table = bcm2835_aux_clk_of_match, -+ }, -+ .probe = bcm2835_aux_clk_probe, -+}; -+builtin_platform_driver(bcm2835_aux_clk_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver"); -+MODULE_LICENSE("GPL v2"); - -From c7b36d3709441f04c40763f17c82e6734cc14fc1 Mon Sep 17 00:00:00 2001 -From: Fraser -Date: Tue, 23 Feb 2016 10:04:37 +1100 -Subject: [PATCH 152/251] Aux SPI 1&2 implementation - -Adds aux spi 1 & 2 devices to compatible raspberry PIs. -* Minor config of the driver build environment to ensure they get built -for CONFIG_ARCH_BCM2708 & CONFIG_ARCH_BCM2709 devices. -* Adds the aux spi driver into the defconfigs as a module. -* Adds the auxiliary and spi1/2 devices into the device tree in a -disabled state -* Provides decide tree overlays which enables the devices and gives -users a degree of control over how they are setup. ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 34 ++++++++- - arch/arm/boot/dts/overlays/Makefile | 6 ++ - arch/arm/boot/dts/overlays/README | 99 +++++++++++++++++++++++++ - arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 57 ++++++++++++++ - arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 69 +++++++++++++++++ - arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 81 ++++++++++++++++++++ - arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 57 ++++++++++++++ - arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 69 +++++++++++++++++ - arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 81 ++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/clk/bcm/Makefile | 2 +- - drivers/spi/Kconfig | 2 +- - 13 files changed, 556 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 18d3c45..4f65203 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -1,3 +1,4 @@ -+#include - #include "skeleton.dtsi" - - / { -@@ -5,6 +6,7 @@ - - aliases { - audio = &audio; -+ aux = &aux; - sound = &sound; - soc = &soc; - dma = &dma; -@@ -19,6 +21,8 @@ - spi0 = &spi0; - i2c0 = &i2c0; - uart1 = &uart1; -+ spi1 = &spi1; -+ spi2 = &spi2; - mmc = &mmc; - i2c1 = &i2c1; - i2c2 = &i2c2; -@@ -186,6 +190,14 @@ - status = "disabled"; - }; - -+ aux: aux@0x7e215004 { -+ compatible = "brcm,bcm2835-aux"; -+ #clock-cells = <1>; -+ reg = <0x7e215000 0x8>; -+ clocks = <&clk_core>; -+ status = "disabled"; -+ }; -+ - uart1: uart@7e215040 { - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; -@@ -194,7 +206,27 @@ - reg-shift = <2>; - no-loopback-test; - status = "disabled"; -- }; -+ }; -+ -+ spi1: spi@7e215080 { -+ compatible = "brcm,bcm2835-aux-spi"; -+ reg = <0x7e215080 0x40>, <0x7e215000 0x8>; -+ interrupts = <1 29>; -+ clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi2: spi@7e2150C0 { -+ compatible = "brcm,bcm2835-aux-spi"; -+ reg = <0x7e2150C0 0x40>, <0x7e215000 0x8>; -+ interrupts = <1 29>; -+ clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; - - mmc: mmc@7e300000 { - compatible = "brcm,bcm2835-mmc"; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4d9d640..a787d66 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -57,6 +57,12 @@ dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-1cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-2cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-3cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-1cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-2cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-3cs-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4de0b6f..cf5f5be 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -713,6 +713,105 @@ Load: dtoverlay=spi-gpio35-39 - Params: - - -+Name: spi1-1cs -+Info: Enables spi1 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi1-2cs -+Info: Enables spi1 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.1 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi1-3cs -+Info: Enables spi1 with three chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-3cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). -+ cs2_pin GPIO pin for CS2 (default 16 - BCM SPI1_CE2). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.1 (default -+ is 'okay' or enabled). -+ cs2_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.2 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-1cs -+Info: Enables spi2 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-2cs -+Info: Enables spi2 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.1 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-3cs -+Info: Enables spi2 with three chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-3cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). -+ cs2_pin GPIO pin for CS2 (default 45 - BCM SPI2_CE2). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.1 (default -+ is 'okay' or enabled). -+ cs2_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.2 (default -+ is 'okay' or enabled). -+ -+ - Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad -diff --git a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -new file mode 100644 -index 0000000..71c2439 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -@@ -0,0 +1,57 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -new file mode 100644 -index 0000000..2ae0885 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -@@ -0,0 +1,69 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18 17>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>, <&gpio 17 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ cs1_spidev = <&spidev1_1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -new file mode 100644 -index 0000000..8f79044 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18 17 16>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>, <&gpio 17 1>, <&gpio 16 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_2: spidev@2 { -+ compatible = "spidev"; -+ reg = <2>; /* CE2 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs2_pin = <&spi1_cs_pins>,"brcm,pins:8", -+ <&frag1>,"cs-gpios:28"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ cs1_spidev = <&spidev1_1>,"status"; -+ cs2_spidev = <&spidev1_2>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -new file mode 100644 -index 0000000..6f57bc7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -@@ -0,0 +1,57 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -new file mode 100644 -index 0000000..d090631 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -@@ -0,0 +1,69 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43 44>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>, <&gpio 44 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ cs1_spidev = <&spidev2_1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -new file mode 100644 -index 0000000..e258672 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43 44 45>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_2: spidev@2 { -+ compatible = "spidev"; -+ reg = <2>; /* CE2 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs2_pin = <&spi2_cs_pins>,"brcm,pins:8", -+ <&frag1>,"cs-gpios:28"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ cs1_spidev = <&spidev2_1>,"status"; -+ cs2_spidev = <&spidev2_2>,"status"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 48ecb2e..76b3a88 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -601,6 +601,7 @@ CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m - CONFIG_SPI_SPIDEV=y - CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 4368f0d..1ca1695 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -593,6 +593,7 @@ CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m - CONFIG_SPI_SPIDEV=y - CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index 84070d5..d60fd3f 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -4,7 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o - obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o --obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o -+obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835-aux.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index e842e86..c9d1558 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -90,7 +90,7 @@ config SPI_BCM2835 - - config SPI_BCM2835AUX - tristate "BCM2835 SPI auxiliary controller" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on GPIOLIB - help - This selects a driver for the Broadcom BCM2835 SPI aux master. - -From 9c53b072c7283c02625434a42fbc2aaa3b2b4bbc Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Tue, 23 Feb 2016 17:28:23 +0100 -Subject: [PATCH 153/251] ASoC: bcm: add missing .owner fields in sound card - drivers - -If snd_soc_card.owner is not set the kernel won't do usage refcounting -and one can remove the card driver module while it's in use (eg playback -active) - which leads to a kernel crash. - -The missing owner field also prevents ALSA slot ordering -(options snd slots=module-name1,module-name-2,...) from working with -the I2S cards as it has no module name to match against. - -Fix these issues by setting the .owner field in the snd_soc_card structs. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/hifiberry_amp.c | 1 + - sound/soc/bcm/hifiberry_dac.c | 1 + - sound/soc/bcm/hifiberry_dacplus.c | 1 + - sound/soc/bcm/hifiberry_digi.c | 1 + - sound/soc/bcm/iqaudio-dac.c | 1 + - sound/soc/bcm/raspidac3.c | 1 + - sound/soc/bcm/rpi-dac.c | 1 + - sound/soc/bcm/rpi-proto.c | 1 + - 8 files changed, 8 insertions(+) - -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -index 5903915..0bb12e4 100644 ---- a/sound/soc/bcm/hifiberry_amp.c -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -61,6 +61,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { - - static struct snd_soc_card snd_rpi_hifiberry_amp = { - .name = "snd_rpi_hifiberry_amp", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_amp_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -index 3ab0f47..29ecc08 100644 ---- a/sound/soc/bcm/hifiberry_dac.c -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -63,6 +63,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_dac = { - .name = "snd_rpi_hifiberry_dac", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 153dbcd..03d8d2a 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -287,6 +287,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_dacplus = { - .name = "snd_rpi_hifiberry_dacplus", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_dacplus_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 80732b8..9840e15 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -164,6 +164,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_digi = { - .name = "snd_rpi_hifiberry_digi", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_digi_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), - }; -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 124d7a9..a5eaa9e 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -77,6 +77,7 @@ static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_iqaudio_dac = { - .name = "IQaudIODAC", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_iqaudio_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), - }; -diff --git a/sound/soc/bcm/raspidac3.c b/sound/soc/bcm/raspidac3.c -index 3cabf5b..e7422e2 100644 ---- a/sound/soc/bcm/raspidac3.c -+++ b/sound/soc/bcm/raspidac3.c -@@ -128,6 +128,7 @@ static struct snd_soc_dai_link snd_rpi_raspidac3_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_raspidac3 = { - .name = "RaspiDAC Rev.3x HiFi Audio Card", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_raspidac3_dai, - .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai), - }; -diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c -index d5fac1b..59dc89e 100644 ---- a/sound/soc/bcm/rpi-dac.c -+++ b/sound/soc/bcm/rpi-dac.c -@@ -60,6 +60,7 @@ static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_rpi_dac = { - .name = "snd_rpi_rpi_dac", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_rpi_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), - }; -diff --git a/sound/soc/bcm/rpi-proto.c b/sound/soc/bcm/rpi-proto.c -index c6e45a0..9db678e 100644 ---- a/sound/soc/bcm/rpi-proto.c -+++ b/sound/soc/bcm/rpi-proto.c -@@ -91,6 +91,7 @@ static struct snd_soc_dai_link snd_rpi_proto_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_proto = { - .name = "snd_rpi_proto", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_proto_dai, - .num_links = ARRAY_SIZE(snd_rpi_proto_dai), - }; - -From 797d7607625bed287bdadcee2471a247ced1ded5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 20 Jan 2016 17:50:09 +0000 -Subject: [PATCH 154/251] smsx95xx: Add option to disable the crimes against - truesize fix - -It may improve iperf numbers on Pi 1, but may generate dmesg warnings and possibly cause network issues -See issue 1248. ---- - drivers/net/usb/smsc95xx.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - mode change 100755 => 100644 drivers/net/usb/smsc95xx.c - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100755 -new mode 100644 -index 7483222..a61bd08 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -75,6 +75,10 @@ static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -+static bool truesize_mode = false; -+module_param(truesize_mode, bool, 0644); -+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); -+ - static char *macaddr = ":"; - module_param(macaddr, charp, 0); - MODULE_PARM_DESC(macaddr, "MAC address"); -@@ -1841,6 +1845,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(skb); - skb_trim(skb, skb->len - 4); /* remove fcs */ -+ if (truesize_mode) -+ skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } -@@ -1858,6 +1864,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(ax_skb); - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ -+ if (truesize_mode) -+ ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } - -From 93c08f5b50bbb8181c4d34bb40fc57e4e3142f8f Mon Sep 17 00:00:00 2001 +From 2a1212d768fc0b6304908ca72aa0fb151c4d33cf Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 23 Feb 2016 19:56:04 +0000 -Subject: [PATCH 155/251] bcm2835-virtgpio: Virtual GPIO driver +Subject: [PATCH 082/114] bcm2835-virtgpio: Virtual GPIO driver Add a virtual GPIO driver that uses the firmware mailbox interface to request that the VPU toggles LEDs. --- - arch/arm/configs/bcm2709_defconfig | 1 + - drivers/gpio/Kconfig | 6 + - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-bcm-virt.c | 180 +++++++++++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 5 files changed, 189 insertions(+) + drivers/gpio/Kconfig | 6 ++ + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-bcm-virt.c | 179 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 186 insertions(+) create mode 100644 drivers/gpio/gpio-bcm-virt.c -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 76b3a88..6d6b519 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -607,6 +607,7 @@ CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m - CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_BCM_VIRT=y - CONFIG_GPIO_ARIZONA=m - CONFIG_GPIO_STMPE=y - CONFIG_W1=m diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index b18bea0..a1f4cce 100644 +index 5f3429f..86cb971 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -132,6 +132,12 @@ config GPIO_BCM_KONA +@@ -142,6 +142,12 @@ config GPIO_BCM_KONA help Turn on GPIO support for Broadcom "Kona" chips. @@ -148230,14 +126425,14 @@ index b18bea0..a1f4cce 100644 + config GPIO_BRCMSTB tristate "BRCMSTB GPIO support" - default y if ARCH_BRCMSTB + default y if (ARCH_BRCMSTB || BMIPS_GENERIC) diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index 986dbd8..b2ccc9f 100644 +index 1e0b74f..908596d 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o +@@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o - obj-$(CONFIG_ATH79) += gpio-ath79.o + obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o +obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o @@ -148245,10 +126440,10 @@ index 986dbd8..b2ccc9f 100644 obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o diff --git a/drivers/gpio/gpio-bcm-virt.c b/drivers/gpio/gpio-bcm-virt.c new file mode 100644 -index 0000000..53edcb4 +index 0000000..f3e0f16 --- /dev/null +++ b/drivers/gpio/gpio-bcm-virt.c -@@ -0,0 +1,180 @@ +@@ -0,0 +1,179 @@ +/* + * brcmvirt GPIO driver + * @@ -148264,7 +126459,6 @@ index 0000000..53edcb4 +#include +#include +#include -+#include +#include +#include + @@ -148376,7 +126570,7 @@ index 0000000..53edcb4 + + ucb->gc.label = MODULE_NAME; + ucb->gc.owner = THIS_MODULE; -+ ucb->gc.dev = dev; ++ //ucb->gc.dev = dev; + ucb->gc.of_node = np; + ucb->gc.base = 100; + ucb->gc.ngpio = NUM_GPIO; @@ -148429,1312 +126623,1550 @@ index 0000000..53edcb4 +MODULE_AUTHOR("Dom Cobley "); +MODULE_DESCRIPTION("brcmvirt GPIO driver"); +MODULE_ALIAS("platform:brcmvirt-gpio"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index b011489..c844968 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -93,6 +93,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -From 686310b3289232a8ae9d21061318e2ee3ca65c3d Mon Sep 17 00:00:00 2001 +From 50af5c701f50215b5ce53f54d40ec9682f66dd6b Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 4 Mar 2016 12:49:09 +0000 +Subject: [PATCH 083/114] DRM_VC4: Allow to be built for ARCH_BCM270x + +--- + drivers/gpu/drm/vc4/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig +index 5848104..870fea5 100644 +--- a/drivers/gpu/drm/vc4/Kconfig ++++ b/drivers/gpu/drm/vc4/Kconfig +@@ -1,6 +1,6 @@ + config DRM_VC4 + tristate "Broadcom VC4 Graphics" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST + depends on DRM + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + +From 9771718ad680a80b06fe3d20ac2851ccd78115cf Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Thu, 21 Jan 2016 17:57:49 +0000 -Subject: [PATCH 156/251] BCM270X_DT: Add Pi3 support +Date: Thu, 17 Dec 2015 13:37:07 +0000 +Subject: [PATCH 084/114] hci_h5: Don't send conf_req when ACTIVE +Without this patch, a modem and kernel can continuously bombard each +other with conf_req and conf_rsp messages, in a demented game of tag. --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 192 ++++++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2710.dtsi | 102 ++++++++++++++++++ - 3 files changed, 295 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b.dts - create mode 100644 arch/arm/boot/dts/bcm2710.dtsi + drivers/bluetooth/hci_h5.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index d583e67..fdc450f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-b-plus.dtb - dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-cm.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb - dtb-$(CONFIG_ARCH_BCM2709) += bcm2709-rpi-2-b.dtb -+dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb - - # Raspberry Pi - ifeq ($(CONFIG_ARCH_BCM2708),y) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -new file mode 100644 -index 0000000..cc06089 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -0,0 +1,192 @@ -+/dts-v1/; -+ -+#include "bcm2710.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2710","brcm,bcm2709"; -+ model = "Raspberry Pi 3 Model B"; -+}; -+ -+&gpio { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = <1>; /* output */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = <7>; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ bt_pins: bt_pins { -+ brcm,pins = <28 29 30 31 43>; -+ brcm,function = <6 6 6 6 4>; /* alt2:PCM alt0:GPCLK2 */ -+ brcm,pull = <0 0 0 0 0>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins = <32 33>; -+ brcm,function = <7>; /* alt3=UART0 */ -+ brcm,pull = <0 0>; -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 0>; -+ }; -+}; -+ -+&sdhost { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ bus-width = <4>; -+ status = "okay"; -+}; -+ -+&mmc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ bus-width = <4>; -+ status = "okay"; -+ brcm,overclock-50 = <0>; -+}; -+ -+&soc { -+ virtgpio: virtgpio { -+ compatible = "brcm,bcm2835-virtgpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins &bt_pins>; -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&random { -+ status = "okay"; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&virtgpio 0 0>; -+ }; -+}; -+ -+/ { -+ chosen { -+ bootargs = "8250.nr_uarts=1"; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi -new file mode 100644 -index 0000000..1a48686 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710.dtsi -@@ -0,0 +1,102 @@ -+#include "bcm2708_common.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2710","brcm,bcm2709"; -+ model = "BCM2710"; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc { -+ ranges = <0x7e000000 0x3f000000 0x01000000>, -+ <0x40000000 0x40000000 0x00040000>; -+ -+ 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>; -+ }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ clock-frequency = <19200000>; -+ interrupt-parent = <&local_intc>; -+ interrupts = <0>, // PHYS_SECURE_PPI -+ <1>, // PHYS_NONSECURE_PPI -+ <3>, // VIRT_PPI -+ <2>; // HYP_PPI -+ always-on; -+ }; -+ -+ syscon@40000000 { -+ compatible = "brcm,bcm2836-arm-local", "syscon"; -+ reg = <0x40000000 0x100>; -+ }; -+ }; -+ -+ cpus: cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ v7_cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x000>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x001>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu2: cpu@2 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x002>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu3: cpu@3 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x003>; -+ clock-frequency = <800000000>; -+ }; -+ }; -+ -+ __overrides__ { -+ arm_freq = <&v7_cpu0>, "clock-frequency:0", -+ <&v7_cpu1>, "clock-frequency:0", -+ <&v7_cpu2>, "clock-frequency:0", -+ <&v7_cpu3>, "clock-frequency:0"; -+ }; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -+ -+&intc { -+ compatible = "brcm,bcm2836-armctrl-ic"; -+ interrupt-parent = <&local_intc>; -+ interrupts = <8>; -+}; +diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c +index 0879d64..5161ab3 100644 +--- a/drivers/bluetooth/hci_h5.c ++++ b/drivers/bluetooth/hci_h5.c +@@ -310,7 +310,8 @@ static void h5_handle_internal_rx(struct hci_uart *hu) + h5_link_control(hu, conf_req, 3); + } else if (memcmp(data, conf_req, 2) == 0) { + h5_link_control(hu, conf_rsp, 2); +- h5_link_control(hu, conf_req, 3); ++ if (h5->state != H5_ACTIVE) ++ h5_link_control(hu, conf_req, 3); + } else if (memcmp(data, conf_rsp, 2) == 0) { + if (H5_HDR_LEN(hdr) > 2) + h5->tx_win = (data[2] & 0x07); -From 5704ec08a597c580de377bb0fca760fa30b927b0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Mon, 8 Feb 2016 23:49:41 +0000 -Subject: [PATCH 157/251] DT: Add overlays to configure I2C pins - -Lifted from -https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=120938&p=825883 -so not claiming this to be my own work. -Adds overlays i2c0-bcm2708 and i2c1-bcm2708 that allow the pin -allocations for i2c-0 and i2c-1 to be changed. ---- - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 16 ++++++++++ - .../arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 36 +++++++++++++++++++++ - .../arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 37 ++++++++++++++++++++++ - 4 files changed, 91 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index a787d66..f2bc3ce 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,8 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c0-bcm2708-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c1-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index cf5f5be..7d7bbb8 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -371,6 +371,22 @@ Params: ds1307 Select the DS1307 device - pcf8563 Select the PCF8563 device - - -+Name: i2c0-bcm2708 -+Info: Enable the i2c_bcm2708 driver for the i2c0 bus -+Load: dtoverlay=i2c0-bcm2708,= -+Params: sda0_pin GPIO pin for SDA0 (0, 28 [or 44] - default 0) -+ scl0_pin GPIO pin for SCL0 (1, 29 [or 45] - default 1) -+ -+ -+Name: i2c1-bcm2708 -+Info: Enable the i2c_bcm2708 driver for the i2c1 bus -+Load: dtoverlay=i2c1-bcm2708,= -+Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) -+ scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) -+ pin_func Alternative pin function (4 (alt0), 6 (alt2) - -+ default 4) -+ -+ - Name: i2s-mmap - Info: Enables mmap support in the bcm2708-i2s driver - Load: dtoverlay=i2s-mmap -diff --git a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -new file mode 100644 -index 0000000..5c0e55b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -@@ -0,0 +1,36 @@ -+/* -+ * Device tree overlay for i2c_bcm2708, i2c0 bus -+ * -+ * Compile: -+ * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c0>; -+ __overlay__ { -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ sda0_pin = <&i2c0_pins>,"brcm,pins:0"; -+ scl0_pin = <&i2c0_pins>,"brcm,pins:4"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e303b9c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -@@ -0,0 +1,37 @@ -+/* -+ * Device tree overlay for i2c_bcm2708, i2c1 bus -+ * -+ * Compile: -+ * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ pinctrl-0 = <&i2c1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ sda1_pin = <&i2c1_pins>,"brcm,pins:0"; -+ scl1_pin = <&i2c1_pins>,"brcm,pins:4"; -+ pin_func = <&i2c1_pins>,"brcm,function:0"; -+ }; -+}; - -From c0d707957191b16ee951b09e3b2d28e5a5cda0f3 Mon Sep 17 00:00:00 2001 -From: Dhiraj Goel -Date: Thu, 3 Mar 2016 21:10:50 -0800 -Subject: [PATCH 158/251] bcm2835-camera: fix a bug in computation of frame - timestamp - -Fixes #1318 ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index e83334c..98a892e 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -360,8 +360,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, - div = - div_u64_rem(runtime_us, USEC_PER_SEC, &rem); - buf->vb.timestamp.tv_sec = -- dev->capture.kernel_start_ts.tv_sec - 1 + -- div; -+ dev->capture.kernel_start_ts.tv_sec + div; - buf->vb.timestamp.tv_usec = - dev->capture.kernel_start_ts.tv_usec + rem; - - -From e16268752be460f8d65e4d613c690508ce985f3f Mon Sep 17 00:00:00 2001 +From 93e515c0f77abfacf54ccbc12b4d94618e0b423d Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Wed, 2 Mar 2016 10:59:05 +0000 -Subject: [PATCH 159/251] BCM270X_DT: Add pi3-disable-bt overlay +Date: Tue, 23 Feb 2016 17:26:48 +0000 +Subject: [PATCH 085/114] amba_pl011: Don't use DT aliases for numbering -Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. To disable -the systemd service that initialises the modem so it doesn't use the UART: - - sudo systemctl disable hciuart - -Signed-off-by: Phil Elwell +The pl011 driver looks for DT aliases of the form "serial", +and if found uses as the device ID. This can cause +/dev/ttyAMA0 to become /dev/ttyAMA1, which is confusing if the +other serial port is provided by the 8250 driver which doesn't +use the same logic. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 48 ++++++++++++++++++++++ - 3 files changed, 57 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts + drivers/tty/serial/amba-pl011.c | 5 +++++ + 1 file changed, 5 insertions(+) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f2bc3ce..2c2b2fa 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7d7bbb8..4f0be23 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -496,6 +496,14 @@ Params: speed Display SPI bus speed - [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 7c198e0..4f9e97b 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -2413,7 +2413,12 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, + if (IS_ERR(base)) + return PTR_ERR(base); ++ /* Don't use DT serial aliases - it causes the device to ++ be renumbered to ttyAMA1 if it is the second serial port in the ++ system, even though the other one is ttyS0. The 8250 driver ++ doesn't use this logic, so always remains ttyS0. + index = pl011_probe_dt_alias(index, dev); ++ */ -+Name: pi3-disable-bt -+Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 -+ N.B. To disable the systemd service that initialises the modem so it -+ doesn't use the UART, use 'sudo systemctl disable hciuart'. -+Load: dtoverlay=pi3-disable-bt -+Params: -+ -+ - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= -diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -new file mode 100644 -index 0000000..05403e2 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -0,0 +1,48 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. -+ To disable the systemd service that initialises the modem so it doesn't use -+ the UART: -+ -+ sudo systemctl disable hciuart -+*/ -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ uart0_pins: uart0_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <4>; /* alt0 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/uart@7e201000"; -+ serial1 = "/soc/uart@7e215040"; -+ }; -+ }; -+}; + uap->old_cr = 0; + uap->port.dev = dev; -From 59b04f45fe08783a5564c784869cfc93cd40c109 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 09:53:03 +0000 -Subject: [PATCH 160/251] BCM270X_DT: Add pi3-miniuart-bt DT overlay +From b1fc98ab68bbf110e2c839a25dc3c09eb0fd5d22 Mon Sep 17 00:00:00 2001 +From: wm4 +Date: Wed, 13 Jan 2016 19:41:45 +0100 +Subject: [PATCH 086/114] bcm2835-pcm: Numerous enhancements -Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -usable baudrate. +bcm2835: extend allowed range of channels and samplerates -It is also necessary to edit /lib/systemd/system/hciuart.server and -replace ttyAMA0 with ttyS0. +Allow everything the videocore accepts. -If cmdline.txt uses the alias serial0 to refer to the user-accessable port -then the firmware will replace with the appropriate port whether or not -this overlay is used. +bcm2835: restrict channels*rate to 8*960000 -Signed-off-by: Phil Elwell +This is required at least for SPDIF. If the bitrate goes above, +videocore will either resample the audio or corrupt it due to +underruns. Supposedly the hardware isn't designed to output +higher rates, but it can still resample it down to supported +rates. + +Some code is based on ac97_pcm.c. + +rpi: update vc_vchi_audioserv_defs.h + +Add audioserv 3 extensions. The changes were taken from the paste +linked here: + +https://github.com/raspberrypi/linux/pull/1166#issuecomment-151917067 + +bcm2835: implement channel map API + +Report all layouts supported by the HDMI protocol to userspace. +Make the videocore set the correct layout according to the +userspace request. + +Some code taken from patch_hdmi.c. In particular, the HDMI channel +layout table was copied without changes - with the idea in mind that +hopefully it can be shared one day. Or at least updating it will be +simpler. + +In my tests, everything appears to work, except when outputting +FL FR RL RR. Then my receiver outputs RL on both the RL and RR +speakers, while RR is never heard. + +bcm2835: access controls under the audio mutex + +I don't think the ALSA framework provides any kind of automatic +synchronization within the control callbacks. We most likely need +to ensure this manually, so add locking around all access to shared +mutable data. In particular, bcm2835_audio_set_ctls() should +probably always be called under our own audio lock. + +bcm2835: always use 2/4/8 channels for multichannel layouts + +Pad the unused channels with NA. This means userspace needs to write +additional, silent padding channels, which is not ideal, but better +than noise. + +Works around noise at the following channel counts: 3, 5, 6, 7 + +bcm2835: only allow stereo if analogue jack is selected + +Sending more than 2 channels to videocore while outputting to analogue +mysteriously outputs heavy artifacts. So just paint it over with a +hack: if analogue is explicitly selected as destination, do not +reporting support for anything other than stereo. + +I'm not sure how to deal with the auto case (destination 0). There's +probably way to retrieve this and even to listen to plug events, but +I didn't find one yet, and it's probably not worth the trouble. Just +don't use this setting, I guess. Unless you like noise. + +Changing the setting while an audio stream is active also doesn't +work properly. We could probably interrupt running streams by +returning ENODEV or using kernel hotplug stuff (maybe), but that +also doesn't seem worth the trouble. + +bcm2835: interpolate audio delay + +It appears the GPU only sends us a message all 10ms to update +the playback progress. Other than this, the playback position +(what SNDRV_PCM_IOCTL_DELAY will return) is not updated at all. +Userspace will see jitter up to 10ms in the audio position. + +Make this a bit nicer for userspace by interpolating the +position using the CPU clock. + +I'm not sure if setting snd_pcm_runtime.delay is the right +approach for this. Or if there is maybe an already existing +mechanism for position interpolation in the ALSA core. + +I only set SNDRV_PCM_INFO_BATCH because this appears to remove +at least one situation snd_pcm_runtime.delay is used, so I have +to worry less in which place I have to update this field, or +how it interacts with the rest of ALSA. + +In the future, it might be nice to use VC_AUDIO_MSG_TYPE_LATENCY. +One problem is that it requires sending a videocore message, and +waiting for a reply, which could make the implementation much +harder due to locking and synchronization requirements. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 10 ++++ - .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 61 ++++++++++++++++++++++ - 3 files changed, 72 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts + sound/arm/bcm2835-ctl.c | 341 ++++++++++++++++++++++++++++++++++++- + sound/arm/bcm2835-pcm.c | 87 +++++++++- + sound/arm/bcm2835-vchiq.c | 13 ++ + sound/arm/bcm2835.h | 5 + + sound/arm/vc_vchi_audioserv_defs.h | 13 +- + 5 files changed, 447 insertions(+), 12 deletions(-) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 2c2b2fa..687cc7c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -40,6 +40,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4f0be23..6a7aa31 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -504,6 +504,16 @@ Load: dtoverlay=pi3-disable-bt - Params: +diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c +index aad905f..e930718 100755 +--- a/sound/arm/bcm2835-ctl.c ++++ b/sound/arm/bcm2835-ctl.c +@@ -94,6 +94,9 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + { + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ + BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); -+Name: pi3-miniuart-bt -+Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -+ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -+ usable baudrate. -+ N.B. It is also necessary to edit /lib/systemd/system/hciuart.server -+ and replace ttyAMA0 with ttyS0. -+Load: dtoverlay=pi3-miniuart-bt -+Params: + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) +@@ -103,6 +106,7 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) + ucontrol->value.integer.value[0] = chip->dest; + ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -112,11 +116,15 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { + audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); + if (chip->mute == CTRL_VOL_MUTE) { + /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ +- return 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ ++ changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ ++ goto unlock; + } + if (changed + || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { +@@ -142,6 +150,8 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, + printk(KERN_ERR "Failed to set ALSA controls..\n"); + } + ++unlock: ++ mutex_unlock(&chip->audio_mutex); + return changed; + } + +@@ -198,10 +208,14 @@ static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -new file mode 100644 -index 0000000..ae1292a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -0,0 +1,61 @@ -+/dts-v1/; -+/plugin/; + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) && 0xff; + ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -212,12 +226,16 @@ static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, + unsigned int val = 0; + int i, change; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -+ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -+ usable baudrate. + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); + + change = val != chip->spdif_status; + chip->spdif_status = val; + ++ mutex_unlock(&chip->audio_mutex); + return change; + } + +@@ -253,9 +271,14 @@ static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+ It is also necessary to edit /lib/systemd/system/hciuart.server and -+ replace ttyAMA0 with ttyS0. + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) & 0xff; + -+ If cmdline.txt uses the alias serial0 to refer to the user-accessable port -+ then the firmware will replace with the appropriate port whether or not -+ this overlay is used. -+*/ ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -266,11 +289,15 @@ static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, + unsigned int val = 0; + int i, change; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ uart0_pins: uart0_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <4>; /* alt0 */ -+ brcm,pull = <0 2>; -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins = <32 33>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/uart@7e201000"; -+ serial1 = "/soc/uart@7e215040"; -+ }; -+ }; -+}; - -From 7c539311298d0f848ba5e300d251572d4f02a891 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 13:38:39 +0000 -Subject: [PATCH 161/251] Pi3 DT: Add dtparams for the SD interface - -Add new base dtparams sd_overclock, sd_force_pio, sd_pio_limit -and sd_debug. These were missed out of the initial Pi3 DTB. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index cc06089..36972d8 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -188,5 +188,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); + change = val != chip->spdif_status; + chip->spdif_status = val; + ++ mutex_unlock(&chip->audio_mutex); + return change; + } + +@@ -300,6 +327,317 @@ static struct snd_kcontrol_new snd_bcm2835_spdif[] = { + }, }; - -From a852495aa0826899b7cf9b7c341ef4c5baea1073 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 15:05:11 +0000 -Subject: [PATCH 162/251] vchiq_arm: Tweak the logging output - -Signed-off-by: Phil Elwell ---- - .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++------------- - 1 file changed, 13 insertions(+), 18 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -index 2c98da4..160db24 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -891,16 +891,14 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, - error_count); - return VCHIQ_ERROR; - } -- if (i == 0) { -- if (SRVTRACE_ENABLED(service, -- VCHIQ_LOG_INFO)) -- vchiq_log_dump_mem("Sent", 0, -- header->data + pos, -- min(64u, -- elements[0].size)); -- } - } -+ if (SRVTRACE_ENABLED(service, -+ VCHIQ_LOG_INFO)) -+ vchiq_log_dump_mem("Sent", 0, -+ header->data, -+ min(16, pos)); ++struct cea_channel_speaker_allocation { ++ int ca_index; ++ int speakers[8]; ++}; + - spin_lock("a_spinlock); - service_quota->message_use_count++; - -@@ -1039,16 +1037,13 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, - error_count); - return VCHIQ_ERROR; - } -- if (i == 0) { -- if (vchiq_sync_log_level >= -- VCHIQ_LOG_TRACE) -- vchiq_log_dump_mem("Sent Sync", -- 0, header->data + pos, -- min(64u, -- elements[0].size)); -- } - } - -+ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) -+ vchiq_log_dump_mem("Sent Sync", -+ 0, header->data, -+ min(16, pos)); ++#define FL SNDRV_CHMAP_FL ++#define FR SNDRV_CHMAP_FR ++#define RL SNDRV_CHMAP_RL ++#define RR SNDRV_CHMAP_RR ++#define LFE SNDRV_CHMAP_LFE ++#define FC SNDRV_CHMAP_FC ++#define RLC SNDRV_CHMAP_RLC ++#define RRC SNDRV_CHMAP_RRC ++#define RC SNDRV_CHMAP_RC ++#define FLC SNDRV_CHMAP_FLC ++#define FRC SNDRV_CHMAP_FRC ++#define FLH SNDRV_CHMAP_TFL ++#define FRH SNDRV_CHMAP_TFR ++#define FLW SNDRV_CHMAP_FLW ++#define FRW SNDRV_CHMAP_FRW ++#define TC SNDRV_CHMAP_TC ++#define FCH SNDRV_CHMAP_TFC ++#define NA SNDRV_CHMAP_NA + - VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); - VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); - } else { -@@ -1720,7 +1715,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, -- min(64, size)); -+ min(16, size)); - } - - if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) -@@ -2187,7 +2182,7 @@ sync_func(void *v) - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, -- min(64, size)); -+ min(16, size)); - } - - switch (type) { - -From e7f05008cced2d27c9b221614ca469dd48f5bc81 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 16:46:39 +0000 -Subject: [PATCH 163/251] bcm2835-sdhost: Only claim one DMA channel - -With both MMC controllers enabled there are few DMA channels left. The -bcm2835-sdhost driver only uses DMA in one direction at a time, so it -doesn't need to claim two channels. - -See: https://github.com/raspberrypi/linux/issues/1327 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +-- - drivers/mmc/host/bcm2835-sdhost.c | 70 ++++++++++++++++++++++++----------- - 2 files changed, 50 insertions(+), 25 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4f65203..4f833a9 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -136,9 +136,8 @@ - reg = <0x7e202000 0x100>; - interrupts = <2 24>; - clocks = <&clk_core>; -- dmas = <&dma 13>, -- <&dma 13>; -- dma-names = "tx", "rx"; -+ dmas = <&dma 13>; -+ dma-names = "rx-tx"; - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - status = "disabled"; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 4f6cab5..4cc4272 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -185,9 +185,10 @@ struct bcm2835_host { - unsigned int debug:1; /* Enable debug output */ - - /*DMA part*/ -- struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -- struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -- struct dma_chan *dma_chan; /* Channel in used */ -+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -+ struct dma_chan *dma_chan; /* Channel in use */ -+ struct dma_slave_config dma_cfg_rx; -+ struct dma_slave_config dma_cfg_tx; - struct dma_async_tx_descriptor *dma_desc; - u32 dma_dir; - u32 drain_words; -@@ -771,12 +772,11 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, - log_event("PRD<", (u32)data, 0); - pr_debug("bcm2835_sdhost_prepare_dma()\n"); - -+ dma_chan = host->dma_chan_rxtx; - if (data->flags & MMC_DATA_READ) { -- dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; - } else { -- dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; ++/* ++ * CEA-861 channel maps ++ * ++ * Stolen from sound/pci/hda/patch_hdmi.c ++ * (unlike the source, this uses SNDRV_* constants directly, as by the ++ * map_tables array in patch_hdmi.c) ++ * Entries which do not have a physical output channel use 0. Entries which ++ * require userspace to output silence use NA (SNDRV_CHMAP_NA). ++ */ ++static struct cea_channel_speaker_allocation channel_allocations[] = { ++/* channel: 7 6 5 4 3 2 1 0 */ ++{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, ++ /* 2.1 */ ++{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, NA, LFE, FR, FL } }, ++ /* Dolby Surround */ ++{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, NA, FR, FL } }, ++ /* surround40 */ ++{ .ca_index = 0x08, .speakers = { NA, NA, RR, RL, NA, NA, FR, FL } }, ++ /* surround41 */ ++{ .ca_index = 0x09, .speakers = { NA, NA, RR, RL, NA, LFE, FR, FL } }, ++ /* surround50 */ ++{ .ca_index = 0x0a, .speakers = { NA, NA, RR, RL, FC, NA, FR, FL } }, ++ /* surround51 */ ++{ .ca_index = 0x0b, .speakers = { NA, NA, RR, RL, FC, LFE, FR, FL } }, ++ /* 6.1 */ ++{ .ca_index = 0x0f, .speakers = { NA, RC, RR, RL, FC, LFE, FR, FL } }, ++ /* surround71 */ ++{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, ++ ++{ .ca_index = 0x03, .speakers = { NA, NA, NA, NA, FC, LFE, FR, FL } }, ++{ .ca_index = 0x04, .speakers = { NA, NA, NA, RC, NA, NA, FR, FL } }, ++{ .ca_index = 0x05, .speakers = { NA, NA, NA, RC, NA, LFE, FR, FL } }, ++{ .ca_index = 0x06, .speakers = { NA, NA, NA, RC, FC, NA, FR, FL } }, ++{ .ca_index = 0x07, .speakers = { NA, NA, NA, RC, FC, LFE, FR, FL } }, ++{ .ca_index = 0x0c, .speakers = { NA, RC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x0d, .speakers = { NA, RC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x0e, .speakers = { NA, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x14, .speakers = { FRC, FLC, NA, NA, NA, NA, FR, FL } }, ++{ .ca_index = 0x15, .speakers = { FRC, FLC, NA, NA, NA, LFE, FR, FL } }, ++{ .ca_index = 0x16, .speakers = { FRC, FLC, NA, NA, FC, NA, FR, FL } }, ++{ .ca_index = 0x17, .speakers = { FRC, FLC, NA, NA, FC, LFE, FR, FL } }, ++{ .ca_index = 0x18, .speakers = { FRC, FLC, NA, RC, NA, NA, FR, FL } }, ++{ .ca_index = 0x19, .speakers = { FRC, FLC, NA, RC, NA, LFE, FR, FL } }, ++{ .ca_index = 0x1a, .speakers = { FRC, FLC, NA, RC, FC, NA, FR, FL } }, ++{ .ca_index = 0x1b, .speakers = { FRC, FLC, NA, RC, FC, LFE, FR, FL } }, ++{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x20, .speakers = { NA, FCH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x21, .speakers = { NA, FCH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x22, .speakers = { TC, NA, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x23, .speakers = { TC, NA, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, ++}; ++ ++static int uses_analogue(bcm2835_chip_t *chip) ++{ ++ return chip->dest == 1; ++} ++ ++static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, ++ unsigned int size, unsigned int __user *tlv) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int __user *dst; ++ int count = 0; ++ int i; ++ ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) ++ return -EFAULT; ++ size -= 8; ++ dst = tlv + 2; ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; ++ int num_chs = 0; ++ int chs_bytes; ++ int c; ++ ++ if (i > 0 && uses_analogue(chip)) ++ break; ++ ++ for (c = 0; c < 8; c++) { ++ if (ch->speakers[c]) ++ num_chs++; ++ } ++ ++ chs_bytes = num_chs * 4; ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || ++ put_user(chs_bytes, dst + 1)) ++ return -EFAULT; ++ dst += 2; ++ size -= 8; ++ count += 8; ++ if (size < chs_bytes) ++ return -ENOMEM; ++ size -= chs_bytes; ++ count += chs_bytes; ++ for (c = 0; c < 8; c++) { ++ int sp = ch->speakers[7 - c]; ++ if (sp) { ++ if (put_user(sp, dst)) ++ return -EFAULT; ++ dst++; ++ } ++ } ++ } ++ if (put_user(count, tlv + 1)) ++ return -EFAULT; ++ return 0; ++} ++ ++static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ++ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); ++ struct cea_channel_speaker_allocation *ch = NULL; ++ int res = 0; ++ int cur = 0; ++ int i; ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ if (!substream || !substream->runtime) { ++ res = -ENODEV; ++ goto unlock; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ if (channel_allocations[i].ca_index == chip->cea_chmap) ++ ch = &channel_allocations[i]; ++ } ++ ++ /* If no layout was set yet, return a dummy. Apparently the userspace ++ * API will be confused if we don't. */ ++ if (!ch) ++ ch = &channel_allocations[0]; ++ ++ for (i = 0; i < 8; i++) { ++ if (ch->speakers[7 - i]) ++ ucontrol->value.integer.value[cur++] = ch->speakers[7 - i]; ++ } ++ while (cur < 8) ++ ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; ++ ++unlock: ++ mutex_unlock(&chip->audio_mutex); ++ return res; ++} ++ ++static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ++ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); ++ int i, prepared = 0, cea_chmap = -1; ++ int res = 0; ++ int remap[8]; ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ if (!substream || !substream->runtime) { ++ res = -ENODEV; ++ goto unlock; ++ } ++ ++ switch (substream->runtime->status->state) { ++ case SNDRV_PCM_STATE_OPEN: ++ case SNDRV_PCM_STATE_SETUP: ++ break; ++ case SNDRV_PCM_STATE_PREPARED: ++ prepared = 1; ++ break; ++ default: ++ res = -EBUSY; ++ goto unlock; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; ++ int matches = 1; ++ int cur = 0; ++ int x; ++ if (i > 0 && uses_analogue(chip)) ++ break; ++ memset(remap, 0, sizeof(remap)); ++ for (x = 0; x < substream->runtime->channels; x++) { ++ int sp = ucontrol->value.integer.value[x]; ++ while (cur < 8 && !ch->speakers[7 - cur]) ++ cur++; ++ if (cur >= 8) { ++ /* user has more channels than ch */ ++ matches = 0; ++ break; ++ } ++ if (ch->speakers[7 - cur] != sp) { ++ matches = 0; ++ break; ++ } ++ remap[x] = cur; ++ cur++; ++ } ++ for (x = cur; x < 8; x++) { ++ if (ch->speakers[7 - x]) { ++ /* ch has more channels than user */ ++ matches = 0; ++ break; ++ } ++ } ++ if (matches) { ++ cea_chmap = ch->ca_index; ++ break; ++ } ++ } ++ ++ if (cea_chmap < 0) { ++ res = -EINVAL; ++ goto unlock; ++ } ++ ++ /* don't change the layout if another substream is active */ ++ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) { ++ res = -EBUSY; /* unsure whether this is a good error code */ ++ goto unlock; ++ } ++ ++ chip->cea_chmap = cea_chmap; ++ for (i = 0; i < 8; i++) ++ chip->map_channels[i] = remap[i]; ++ if (prepared) ++ snd_bcm2835_pcm_prepare_again(substream); ++ ++unlock: ++ mutex_unlock(&chip->audio_mutex); ++ return res; ++} ++ ++static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) ++{ ++ struct snd_pcm_chmap *chmap; ++ struct snd_kcontrol *kctl; ++ int err, i; ++ ++ err = snd_pcm_add_chmap_ctls(chip->pcm, ++ SNDRV_PCM_STREAM_PLAYBACK, ++ NULL, 8, 0, &chmap); ++ if (err < 0) ++ return err; ++ /* override handlers */ ++ chmap->private_data = chip; ++ kctl = chmap->kctl; ++ for (i = 0; i < kctl->count; i++) ++ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; ++ kctl->get = snd_bcm2835_chmap_ctl_get; ++ kctl->put = snd_bcm2835_chmap_ctl_put; ++ kctl->tlv.c = snd_bcm2835_chmap_ctl_tlv; ++ return 0; ++} ++ + int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) + { + int err; +@@ -313,6 +651,7 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) + if (err < 0) + return err; } -@@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, - host->drain_words = len/4; ++ snd_bcm2835_add_chmap_ctl(chip); + for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); +diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c +index 8c86375..f3a4c6d 100755 +--- a/sound/arm/bcm2835-pcm.c ++++ b/sound/arm/bcm2835-pcm.c +@@ -19,16 +19,19 @@ + + #include "bcm2835.h" + ++/* The hardware can not do much more num_channels*samplerate then this value */ ++#define MAX_COMBINED_RATE 768000 ++ + /* hardware definition */ + static struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | +- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), ++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 1, +- .channels_max = 2, ++ .channels_max = 8, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, +@@ -43,9 +46,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 44100, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 2, +- .channels_max = 2, ++ .channels_max = 8, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, +@@ -96,6 +99,8 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) + alsa_stream->pos %= alsa_stream->buffer_size; } -+ /* The parameters have already been validated, so this will not fail */ -+ (void)dmaengine_slave_config(dma_chan, -+ (dir_data == DMA_FROM_DEVICE) ? -+ &host->dma_cfg_rx : -+ &host->dma_cfg_tx); ++ alsa_stream->interpolate_start = ktime_get_ns(); + - len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, - dir_data); + if (alsa_stream->substream) { + if (new_period) + snd_pcm_period_elapsed(alsa_stream->substream); +@@ -107,6 +112,31 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) + return IRQ_HANDLED; + } -@@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - spin_lock_init(&host->lock); ++ ++static int rate_hw_constraint_rate(struct snd_pcm_hw_params *params, ++ struct snd_pcm_hw_rule *rule) ++{ ++ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); ++ struct snd_interval rates = { ++ .min = 8000, ++ .max = min(192000u, MAX_COMBINED_RATE / max(channels->min, 1u)), ++ }; ++ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); ++ return snd_interval_refine(rate, &rates); ++} ++ ++static int rate_hw_constraint_channels(struct snd_pcm_hw_params *params, ++ struct snd_pcm_hw_rule *rule) ++{ ++ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); ++ struct snd_interval channels_interval = { ++ .min = 1, ++ .max = min(8u, MAX_COMBINED_RATE / max(rate->min, 1u)), ++ }; ++ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); ++ return snd_interval_refine(channels, &channels_interval); ++} ++ + /* open callback */ + static int snd_bcm2835_playback_open_generic( + struct snd_pcm_substream *substream, int spdif) +@@ -188,8 +218,24 @@ static int snd_bcm2835_playback_open_generic( + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 16); - if (host->allow_dma) { -- if (IS_ERR_OR_NULL(host->dma_chan_tx) || -- IS_ERR_OR_NULL(host->dma_chan_rx)) { -- pr_err("%s: unable to initialise DMA channels. " -+ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { -+ pr_err("%s: unable to initialise DMA channel. " - "Falling back to PIO\n", - mmc_hostname(mmc)); - host->use_dma = false; - } else { -- host->use_dma = true; ++ /* When playing PCM, pretend that we support the full range of channels ++ * and sample rates. The GPU can't output it, but is able to resample ++ * the data to a rate the hardware can handle it. This won't work with ++ * compressed data; the resampler would just destroy it. */ ++ if (spdif) { ++ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ++ rate_hw_constraint_rate, NULL, ++ SNDRV_PCM_HW_PARAM_CHANNELS, -1); ++ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, ++ rate_hw_constraint_channels, NULL, ++ SNDRV_PCM_HW_PARAM_RATE, -1); ++ } ++ + chip->alsa_stream[idx] = alsa_stream; + ++ if (!chip->opened) ++ chip->cea_chmap = -1; ++ + chip->opened |= (1 << idx); + alsa_stream->open = 1; + alsa_stream->draining = 1; +@@ -300,8 +346,7 @@ static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) + return snd_pcm_lib_free_pages(substream); + } + +-/* prepare callback */ +-static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) ++int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream) + { + bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -309,8 +354,6 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + int channels; + int err; + +- audio_info(" .. IN\n"); - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.slave_id = 13; /* DREQ channel */ - -+ /* Validate the slave configurations */ -+ - cfg.direction = DMA_MEM_TO_DEV; - cfg.src_addr = 0; - cfg.dst_addr = host->bus_addr + SDDATA; -- ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); - -- cfg.direction = DMA_DEV_TO_MEM; -- cfg.src_addr = host->bus_addr + SDDATA; -- cfg.dst_addr = 0; -- ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ -+ if (ret == 0) { -+ host->dma_cfg_tx = cfg; -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDDATA; -+ cfg.dst_addr = 0; -+ -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ } -+ -+ if (ret == 0) { -+ host->dma_cfg_rx = cfg; -+ -+ host->use_dma = true; -+ } else { -+ pr_err("%s: unable to configure DMA channel. " -+ "Falling back to PIO\n", -+ mmc_hostname(mmc)); -+ dma_release_channel(host->dma_chan_rxtx); -+ host->dma_chan_rxtx = NULL; -+ host->use_dma = false; -+ } - } - } else { - host->use_dma = false; -@@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - - if (host->allow_dma) { - if (node) { -- host->dma_chan_tx = -- dma_request_slave_channel(dev, "tx"); -- host->dma_chan_rx = -- dma_request_slave_channel(dev, "rx"); -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx-tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx"); - } else { - dma_cap_mask_t mask; - - dma_cap_zero(mask); - /* we don't care about the channel, any would work */ - dma_cap_set(DMA_SLAVE, mask); -- host->dma_chan_tx = -- dma_request_channel(mask, NULL, NULL); -- host->dma_chan_rx = -+ host->dma_chan_rxtx = - dma_request_channel(mask, NULL, NULL); - } + /* notify the vchiq that it should enter spdif passthrough mode by + * setting channels=0 (see + * https://github.com/raspberrypi/linux/issues/528) */ +@@ -326,6 +369,23 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + audio_error(" error setting hw params\n"); } + ++ return err; ++} ++ ++/* prepare callback */ ++static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ snd_bcm2835_pcm_prepare_again(substream); ++ + bcm2835_audio_setup(alsa_stream); + + /* in preparation of the stream, set the controls (volume level) of the stream */ +@@ -341,11 +401,13 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); + alsa_stream->pos = 0; ++ alsa_stream->interpolate_start = ktime_get_ns(); + + audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", + alsa_stream->buffer_size, alsa_stream->period_size, + alsa_stream->pos, runtime->frame_bits); + ++ mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + return 0; + } +@@ -436,6 +498,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ u64 now = ktime_get_ns(); + + audio_info(" .. IN\n"); + +@@ -444,6 +507,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) + frames_to_bytes(runtime, runtime->control->appl_ptr), + alsa_stream->pos); + ++ /* Give userspace better delay reporting by interpolating between GPU ++ * notifications, assuming audio speed is close enough to the clock ++ * used for ktime */ ++ if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) ++ runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); ++ + audio_info(" .. OUT\n"); + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, +diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c +index 3de3094..8ecd2d7 100755 +--- a/sound/arm/bcm2835-vchiq.c ++++ b/sound/arm/bcm2835-vchiq.c +@@ -570,6 +570,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, + VC_AUDIO_MSG_T m; + AUDIO_INSTANCE_T *instance = alsa_stream->instance; + int32_t success; ++ uint32_t chmap_value; ++ int i; + int ret; + LOG_DBG(" .. IN\n"); + +@@ -593,10 +595,21 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, + + instance->result = -1; + ++ if (alsa_stream->chip->cea_chmap >= 0) { ++ chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; ++ } else { ++ chmap_value = 0; /* force stereo */ ++ for (i = 0; i < 8; i++) ++ alsa_stream->chip->map_channels[i] = i; ++ } ++ for (i = 0; i < 8; i++) ++ chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); ++ + m.type = VC_AUDIO_MSG_TYPE_CONFIG; + m.u.config.channels = channels; + m.u.config.samplerate = samplerate; + m.u.config.bps = bps; ++ m.u.config.channelmap = chmap_value; + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); +diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h +index 0f71c5d..20ef108 100755 +--- a/sound/arm/bcm2835.h ++++ b/sound/arm/bcm2835.h +@@ -107,6 +107,8 @@ typedef struct bcm2835_chip { + int old_volume; /* stores the volume value whist muted */ + int dest; + int mute; ++ int cea_chmap; /* currently requested Audio InfoFrame Data Byte 4 */ ++ int map_channels[8]; + + unsigned int opened; + unsigned int spdif_status; +@@ -135,6 +137,7 @@ typedef struct bcm2835_alsa_stream { + unsigned int pos; + unsigned int buffer_size; + unsigned int period_size; ++ u64 interpolate_start; + + uint32_t enable_fifo_irq; + irq_handler_t fifo_irq_handler; +@@ -149,6 +152,8 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip); + int snd_bcm2835_new_pcm(bcm2835_chip_t * chip); + int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip); + ++int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream); ++ + int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream); + int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream); + int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, +diff --git a/sound/arm/vc_vchi_audioserv_defs.h b/sound/arm/vc_vchi_audioserv_defs.h +index af3e6eb..5f4409f 100644 +--- a/sound/arm/vc_vchi_audioserv_defs.h ++++ b/sound/arm/vc_vchi_audioserv_defs.h +@@ -16,7 +16,7 @@ + #define _VC_AUDIO_DEFS_H_ + + #define VC_AUDIOSERV_MIN_VER 1 +-#define VC_AUDIOSERV_VER 2 ++#define VC_AUDIOSERV_VER 3 + + // FourCC code used for VCHI connection + #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") +@@ -36,6 +36,7 @@ typedef enum { + VC_AUDIO_MSG_TYPE_START, // Configure audio + VC_AUDIO_MSG_TYPE_STOP, // Configure audio + VC_AUDIO_MSG_TYPE_WRITE, // Configure audio ++ VC_AUDIO_MSG_TYPE_LATENCY, // request latency in cycles + VC_AUDIO_MSG_TYPE_MAX + } VC_AUDIO_MSG_TYPE; + +@@ -44,6 +45,7 @@ typedef struct { + uint32_t channels; + uint32_t samplerate; + uint32_t bps; ++ uint32_t channelmap; + + } VC_AUDIO_CONFIG_T; + +@@ -84,6 +86,12 @@ typedef struct { + uint16_t max_packet; + } VC_AUDIO_WRITE_T; + ++// query latency in samples of sink ++typedef struct ++{ ++ uint32_t dummy; ++} VC_AUDIO_LATENCY_T; ++ + // Generic result for a request (VC->HOST) + typedef struct { + int32_t success; // Success value +@@ -108,9 +116,10 @@ typedef struct { + VC_AUDIO_START_T start; + VC_AUDIO_STOP_T stop; + VC_AUDIO_WRITE_T write; ++ VC_AUDIO_LATENCY_T latency; + VC_AUDIO_RESULT_T result; + VC_AUDIO_COMPLETE_T complete; + } u; + } VC_AUDIO_MSG_T; + +-#endif // _VC_AUDIO_DEFS_H_ ++#endif // _VC_AUDIO_DEFS_H_ +\ No newline at end of file -From afe2e242d78005f19d1611ad15124ce576225778 Mon Sep 17 00:00:00 2001 +From 799752a785774372412162ca01eba8f21518c833 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou +Date: Wed, 3 Dec 2014 13:23:28 +0200 +Subject: [PATCH 087/114] OF: DT-Overlay configfs interface + +This is a port of Pantelis Antoniou's v3 port that makes use of the +new upstreamed configfs support for binary attributes. + +Original commit message: + +Add a runtime interface to using configfs for generic device tree overlay +usage. With it its possible to use device tree overlays without having +to use a per-platform overlay manager. + +Please see Documentation/devicetree/configfs-overlays.txt for more info. + +Changes since v2: +- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) +- Created a documentation entry +- Slight rewording in Kconfig + +Changes since v1: +- of_resolve() -> of_resolve_phandles(). + +Originally-signed-off-by: Pantelis Antoniou +Signed-off-by: Phil Elwell +--- + Documentation/devicetree/configfs-overlays.txt | 31 +++ + drivers/of/Kconfig | 7 + + drivers/of/Makefile | 1 + + drivers/of/configfs.c | 314 +++++++++++++++++++++++++ + 4 files changed, 353 insertions(+) + create mode 100644 Documentation/devicetree/configfs-overlays.txt + create mode 100644 drivers/of/configfs.c + +diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt +new file mode 100644 +index 0000000..5fa43e0 +--- /dev/null ++++ b/Documentation/devicetree/configfs-overlays.txt +@@ -0,0 +1,31 @@ ++Howto use the configfs overlay interface. ++ ++A device-tree configfs entry is created in /config/device-tree/overlays ++and and it is manipulated using standard file system I/O. ++Note that this is a debug level interface, for use by developers and ++not necessarily something accessed by normal users due to the ++security implications of having direct access to the kernel's device tree. ++ ++* To create an overlay you mkdir the directory: ++ ++ # mkdir /config/device-tree/overlays/foo ++ ++* Either you echo the overlay firmware file to the path property file. ++ ++ # echo foo.dtbo >/config/device-tree/overlays/foo/path ++ ++* Or you cat the contents of the overlay to the dtbo file ++ ++ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo ++ ++The overlay file will be applied, and devices will be created/destroyed ++as required. ++ ++To remove it simply rmdir the directory. ++ ++ # rmdir /config/device-tree/overlays/foo ++ ++The rationalle of the dual interface (firmware & direct copy) is that each is ++better suited to different use patterns. The firmware interface is what's ++intended to be used by hardware managers in the kernel, while the copy interface ++make sense for developers (since it avoids problems with namespaces). +diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig +index e2a4841..7e5e6c4 100644 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -112,4 +112,11 @@ config OF_OVERLAY + While this option is selected automatically when needed, you can + enable it manually to improve device tree unit test coverage. + ++config OF_CONFIGFS ++ bool "Device Tree Overlay ConfigFS interface" ++ select CONFIGFS_FS ++ select OF_OVERLAY ++ help ++ Enable a simple user-space driven DT overlay interface. ++ + endif # OF +diff --git a/drivers/of/Makefile b/drivers/of/Makefile +index 156c072..46c8f57 100644 +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,4 +1,5 @@ + obj-y = base.o device.o platform.o ++obj-$(CONFIG_OF_CONFIGFS) += configfs.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +new file mode 100644 +index 0000000..7b66deb +--- /dev/null ++++ b/drivers/of/configfs.c +@@ -0,0 +1,314 @@ ++/* ++ * Configfs entries for device-tree ++ * ++ * Copyright (C) 2013 - Pantelis Antoniou ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "of_private.h" ++ ++struct cfs_overlay_item { ++ struct config_item item; ++ ++ char path[PATH_MAX]; ++ ++ const struct firmware *fw; ++ struct device_node *overlay; ++ int ov_id; ++ ++ void *dtbo; ++ int dtbo_size; ++}; ++ ++static int create_overlay(struct cfs_overlay_item *overlay, void *blob) ++{ ++ int err; ++ ++ /* unflatten the tree */ ++ of_fdt_unflatten_tree(blob, &overlay->overlay); ++ if (overlay->overlay == NULL) { ++ pr_err("%s: failed to unflatten tree\n", __func__); ++ err = -EINVAL; ++ goto out_err; ++ } ++ pr_debug("%s: unflattened OK\n", __func__); ++ ++ /* mark it as detached */ ++ of_node_set_flag(overlay->overlay, OF_DETACHED); ++ ++ /* perform resolution */ ++ err = of_resolve_phandles(overlay->overlay); ++ if (err != 0) { ++ pr_err("%s: Failed to resolve tree\n", __func__); ++ goto out_err; ++ } ++ pr_debug("%s: resolved OK\n", __func__); ++ ++ err = of_overlay_create(overlay->overlay); ++ if (err < 0) { ++ pr_err("%s: Failed to create overlay (err=%d)\n", ++ __func__, err); ++ goto out_err; ++ } ++ overlay->ov_id = err; ++ ++out_err: ++ return err; ++} ++ ++static inline struct cfs_overlay_item *to_cfs_overlay_item( ++ struct config_item *item) ++{ ++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; ++} ++ ++static ssize_t cfs_overlay_item_path_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ return sprintf(page, "%s\n", overlay->path); ++} ++ ++static ssize_t cfs_overlay_item_path_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ const char *p = page; ++ char *s; ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy to path buffer (and make sure it's always zero terminated */ ++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); ++ overlay->path[sizeof(overlay->path) - 1] = '\0'; ++ ++ /* strip trailing newlines */ ++ s = overlay->path + strlen(overlay->path); ++ while (s > overlay->path && *--s == '\n') ++ *s = '\0'; ++ ++ pr_debug("%s: path is '%s'\n", __func__, overlay->path); ++ ++ err = request_firmware(&overlay->fw, overlay->path, NULL); ++ if (err != 0) ++ goto out_err; ++ ++ err = create_overlay(overlay, (void *)overlay->fw->data); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ ++ release_firmware(overlay->fw); ++ overlay->fw = NULL; ++ ++ overlay->path[0] = '\0'; ++ return err; ++} ++ ++static ssize_t cfs_overlay_item_status_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ return sprintf(page, "%s\n", ++ overlay->ov_id >= 0 ? "applied" : "unapplied"); ++} ++ ++CONFIGFS_ATTR(cfs_overlay_item_, path); ++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); ++ ++static struct configfs_attribute *cfs_overlay_attrs[] = { ++ &cfs_overlay_item_attr_path, ++ &cfs_overlay_item_attr_status, ++ NULL, ++}; ++ ++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, ++ void *buf, size_t max_count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ pr_debug("%s: buf=%p max_count=%u\n", __func__, ++ buf, max_count); ++ ++ if (overlay->dtbo == NULL) ++ return 0; ++ ++ /* copy if buffer provided */ ++ if (buf != NULL) { ++ /* the buffer must be large enough */ ++ if (overlay->dtbo_size > max_count) ++ return -ENOSPC; ++ ++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); ++ } ++ ++ return overlay->dtbo_size; ++} ++ ++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, ++ const void *buf, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy the contents */ ++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); ++ if (overlay->dtbo == NULL) ++ return -ENOMEM; ++ ++ overlay->dtbo_size = count; ++ ++ err = create_overlay(overlay, overlay->dtbo); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ kfree(overlay->dtbo); ++ overlay->dtbo = NULL; ++ overlay->dtbo_size = 0; ++ ++ return err; ++} ++ ++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); ++ ++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { ++ &cfs_overlay_item_attr_dtbo, ++ NULL, ++}; ++ ++static void cfs_overlay_release(struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ if (overlay->ov_id >= 0) ++ of_overlay_destroy(overlay->ov_id); ++ if (overlay->fw) ++ release_firmware(overlay->fw); ++ /* kfree with NULL is safe */ ++ kfree(overlay->dtbo); ++ kfree(overlay); ++} ++ ++static struct configfs_item_operations cfs_overlay_item_ops = { ++ .release = cfs_overlay_release, ++}; ++ ++static struct config_item_type cfs_overlay_type = { ++ .ct_item_ops = &cfs_overlay_item_ops, ++ .ct_attrs = cfs_overlay_attrs, ++ .ct_bin_attrs = cfs_overlay_bin_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *cfs_overlay_group_make_item( ++ struct config_group *group, const char *name) ++{ ++ struct cfs_overlay_item *overlay; ++ ++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); ++ if (!overlay) ++ return ERR_PTR(-ENOMEM); ++ overlay->ov_id = -1; ++ ++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); ++ return &overlay->item; ++} ++ ++static void cfs_overlay_group_drop_item(struct config_group *group, ++ struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ config_item_put(&overlay->item); ++} ++ ++static struct configfs_group_operations overlays_ops = { ++ .make_item = cfs_overlay_group_make_item, ++ .drop_item = cfs_overlay_group_drop_item, ++}; ++ ++static struct config_item_type overlays_type = { ++ .ct_group_ops = &overlays_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct configfs_group_operations of_cfs_ops = { ++ /* empty - we don't allow anything to be created */ ++}; ++ ++static struct config_item_type of_cfs_type = { ++ .ct_group_ops = &of_cfs_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group of_cfs_overlay_group; ++ ++struct config_group *of_cfs_def_groups[] = { ++ &of_cfs_overlay_group, ++ NULL ++}; ++ ++static struct configfs_subsystem of_cfs_subsys = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "device-tree", ++ .ci_type = &of_cfs_type, ++ }, ++ .default_groups = of_cfs_def_groups, ++ }, ++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), ++}; ++ ++static int __init of_cfs_init(void) ++{ ++ int ret; ++ ++ pr_info("%s\n", __func__); ++ ++ config_group_init(&of_cfs_subsys.su_group); ++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", ++ &overlays_type); ++ ++ ret = configfs_register_subsystem(&of_cfs_subsys); ++ if (ret != 0) { ++ pr_err("%s: failed to register subsys\n", __func__); ++ goto out; ++ } ++ pr_info("%s: OK\n", __func__); ++out: ++ return ret; ++} ++late_initcall(of_cfs_init); + +From 8ac9864a4bd3d7b096fc385db58d39b53da206f3 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 8 Mar 2016 09:49:16 +0000 -Subject: [PATCH 164/251] bcm2835-mmc: Only claim one DMA channel +Date: Fri, 13 Mar 2015 12:43:36 +0000 +Subject: [PATCH 088/114] Protect __release_resource against resources without + parents -With both MMC controllers enabled there are few DMA channels left. The -bcm2835-mmc driver only uses DMA in one direction at a time, so it -doesn't need to claim two channels. - -See: https://github.com/raspberrypi/linux/issues/1327 +Without this patch, removing a device tree overlay can crash here. Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +-- - drivers/mmc/host/bcm2835-mmc.c | 69 +++++++++++++++++++++++++---------- - 2 files changed, 51 insertions(+), 23 deletions(-) + kernel/resource.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4f833a9..e0be77a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -232,9 +232,8 @@ - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -+ dmas = <&dma 11>; -+ dma-names = "rx-tx"; - brcm,overclock-50 = <0>; - status = "disabled"; - }; -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 104f93e..ceb3793 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -108,8 +108,9 @@ struct bcm2835_host { - u32 shadow; +diff --git a/kernel/resource.c b/kernel/resource.c +index 9b5f044..f8a9af6 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -246,6 +246,12 @@ static int __release_resource(struct resource *old, bool release_child) + { + struct resource *tmp, **p, *chd; - /*DMA part*/ -- struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -- struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -+ struct dma_slave_config dma_cfg_rx; -+ struct dma_slave_config dma_cfg_tx; - struct dma_async_tx_descriptor *tx_desc; /* descriptor */ - - bool have_dma; -@@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(void *param) - - if (host->data && !(host->data->flags & MMC_DATA_WRITE)) { - /* otherwise handled in SDHCI IRQ */ -- dma_chan = host->dma_chan_rx; -+ dma_chan = host->dma_chan_rxtx; - dir_data = DMA_FROM_DEVICE; - - dma_unmap_sg(dma_chan->device->dev, -@@ -493,16 +494,21 @@ static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) - if (host->blocks == 0) - return; - -+ dma_chan = host->dma_chan_rxtx; - if (host->data->flags & MMC_DATA_READ) { -- dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; - } else { -- dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; - } - -+ /* The parameters have already been validated, so this will not fail */ -+ (void)dmaengine_slave_config(dma_chan, -+ (dir_data == DMA_FROM_DEVICE) ? -+ &host->dma_cfg_rx : -+ &host->dma_cfg_tx); -+ - BUG_ON(!dma_chan->device); - BUG_ON(!dma_chan->device->dev); - BUG_ON(!host->data->sg); -@@ -936,7 +942,7 @@ static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask) - if (host->data->flags & MMC_DATA_WRITE) { - /* IRQ handled here */ - -- dma_chan = host->dma_chan_tx; -+ dma_chan = host->dma_chan_rxtx; - dir_data = DMA_TO_DEVICE; - dma_unmap_sg(dma_chan->device->dev, - host->data->sg, host->data->sg_len, -@@ -1316,28 +1322,47 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; - #else -- if (IS_ERR_OR_NULL(host->dma_chan_tx) || -- IS_ERR_OR_NULL(host->dma_chan_rx)) { -- dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n", -+ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { -+ dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n", - DRIVER_NAME); - host->have_dma = false; - } else { -- dev_info(dev, "DMA channels allocated"); -- host->have_dma = true; -+ dev_info(dev, "DMA channel allocated"); - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.slave_id = 11; /* DREQ channel */ - -+ /* Validate the slave configurations */ -+ - cfg.direction = DMA_MEM_TO_DEV; - cfg.src_addr = 0; - cfg.dst_addr = host->bus_addr + SDHCI_BUFFER; -- ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); - -- cfg.direction = DMA_DEV_TO_MEM; -- cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -- cfg.dst_addr = 0; -- ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ -+ if (ret == 0) { -+ host->dma_cfg_tx = cfg; -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -+ cfg.dst_addr = 0; -+ -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ } -+ -+ if (ret == 0) { -+ host->dma_cfg_rx = cfg; -+ -+ host->use_dma = true; -+ } else { -+ pr_err("%s: unable to configure DMA channel. " -+ "Faling back to PIO\n", -+ mmc_hostname(mmc)); -+ dma_release_channel(host->dma_chan_rxtx); -+ host->dma_chan_rxtx = NULL; -+ host->use_dma = false; -+ } - } - #endif - mmc->max_segs = 128; -@@ -1416,16 +1441,20 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) - - #ifndef FORCE_PIO - if (node) { -- host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); -- host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); -+ host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx"); - } else { - dma_cap_mask_t mask; - - dma_cap_zero(mask); - /* we don't care about the channel, any would work */ - dma_cap_set(DMA_SLAVE, mask); -- host->dma_chan_tx = dma_request_channel(mask, NULL, NULL); -- host->dma_chan_rx = dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL); - } - #endif - clk = devm_clk_get(dev, NULL); ++ if (!old->parent) { ++ WARN(old->sibling, "sibling but no parent"); ++ if (old->sibling) ++ return -EINVAL; ++ return 0; ++ } + p = &old->parent->child; + for (;;) { + tmp = *p; -From ba461323859e90843ed2a65dd223a60244782814 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 8 Mar 2016 17:08:39 +0000 -Subject: [PATCH 165/251] config: rebuild with savedefconfig - ---- - arch/arm/configs/bcm2709_defconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6d6b519..116002b 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -593,7 +593,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y --CONFIG_HW_RANDOM_BCM2835=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1112,7 +1111,7 @@ CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m - CONFIG_IIO=m - CONFIG_IIO_BUFFER=y --CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m - CONFIG_DHT11=m - -From 226c823c6dde5546476a22be8d681712924ad6ef Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 8 Mar 2016 17:06:33 +0000 -Subject: [PATCH 166/251] config: Add module for mcp3422 ADC - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 116002b..7793baf 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1114,6 +1114,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m -+CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 1ca1695..f09be87 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1121,6 +1121,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m -+CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - -From f27ae7ba1432ab3604faaf8ca79ed31a5edc8d42 Mon Sep 17 00:00:00 2001 +From 91a49d58dc66d3523951fe8c810ce6cf224b0074 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 8 Mar 2016 16:18:57 +0000 -Subject: [PATCH 167/251] Pi3 DT: Add pull-ups on the UART RX lines +Date: Fri, 13 Mar 2015 20:00:21 +0000 +Subject: [PATCH 089/114] BCM270X_DT: Add a .dtbo target, use for overlays + +Change the filenames and extensions to keep the pre-DDT style of +overlay (-overlay.dtb) distinct from new ones that use a +different style of local fixups (.dtbo), and to match other +platforms. + +The RPi firmware uses the DDTK trailer atom to choose which type of +overlay to use for each kernel. Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++-- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) + arch/arm/boot/.gitignore | 2 +- + scripts/Makefile.dtbinst | 10 +++++++--- + scripts/Makefile.lib | 10 ++++++++++ + 3 files changed, 18 insertions(+), 4 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 36972d8..5a0c45a 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -53,13 +53,13 @@ - uart0_pins: uart0_pins { - brcm,pins = <32 33>; - brcm,function = <7>; /* alt3=UART0 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; +diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore +index 3c79f85..eaaeb17 100644 +--- a/arch/arm/boot/.gitignore ++++ b/arch/arm/boot/.gitignore +@@ -3,4 +3,4 @@ zImage + xipImage + bootpImage + uImage +-*.dtb ++*.dtb* +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index a1be75d..ad8dc1c 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -27,6 +27,7 @@ ifeq ("$(dtbinst-root)", "$(obj)") + endif - uart1_pins: uart1_pins { - brcm,pins = <14 15>; - brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; - }; + dtbinst-files := $(dtb-y) ++dtboinst-files := $(dtbo-y) + dtbinst-dirs := $(dts-dirs) -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index ae1292a..0b8f0ca 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -46,7 +46,7 @@ - uart1_pins: uart1_pins { - brcm,pins = <32 33>; - brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; - }; - }; + # Helper targets for Installing DTBs into the boot directory +@@ -35,15 +36,18 @@ quiet_cmd_dtb_install = INSTALL $< + + install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) + +-$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep ++$(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs): | __dtbs_install_prep + + $(dtbinst-files): %.dtb: $(obj)/%.dtb + $(call cmd,dtb_install,$(install-dir)) + ++$(dtboinst-files): %.dtbo: $(obj)/%.dtbo ++ $(call cmd,dtb_install,$(install-dir)) ++ + $(dtbinst-dirs): + $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(dtbinst-files) $(dtbinst-dirs) +-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) ++PHONY += $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) ++__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) + + .PHONY: $(PHONY) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index ddf83d0..c819ddc 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -306,6 +306,16 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(obj)/%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + ++quiet_cmd_dtco = DTCO $@ ++cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ ++ $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ ++ -i $(dir $<) $(DTC_FLAGS) \ ++ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ ++ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ++ ++$(obj)/%.dtbo: $(src)/%-overlay.dts FORCE ++ $(call if_changed_dep,dtco) ++ + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + + # Bzip2 -From e5b66ba646a96ad37ea4c7cc240c34e9d77f0eea Mon Sep 17 00:00:00 2001 +From 96fd3ebbca3c81575bf3dc7681c0f67243fc1af3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 29 May 2015 11:18:58 +0100 +Subject: [PATCH 090/114] scripts/knlinfo: Decode DDTK atom + +Show the DDTK atom as being a boolean. + +Signed-off-by: Phil Elwell +--- + scripts/knlinfo | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/scripts/knlinfo b/scripts/knlinfo +index b9ef124..263ec93 100755 +--- a/scripts/knlinfo ++++ b/scripts/knlinfo +@@ -16,6 +16,7 @@ my $trailer_magic = 'RPTL'; + + my %atom_formats = + ( ++ 'DDTK' => \&format_bool, + 'DTOK' => \&format_bool, + 'KVer' => \&format_string, + '270X' => \&format_bool, +@@ -148,7 +149,7 @@ sub format_atom + sub format_bool + { + my ($data) = @_; +- return unpack('V', $data) ? 'true' : 'false'; ++ return unpack('V', $data) ? 'y' : 'n'; + } + + sub format_int + +From 5ba639e7dfecaa2341b48645ea6297469cb644fd Mon Sep 17 00:00:00 2001 +From: Cheong2K +Date: Fri, 26 Feb 2016 18:20:10 +0800 +Subject: [PATCH 091/114] brcm: adds support for BCM43341 wifi + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 43fd3f4..c3c7c79 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -606,6 +606,7 @@ BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); + BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); ++BRCMF_FW_NVRAM_DEF(43341, "brcmfmac43341-sdio.bin", "brcmfmac43341-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); + BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt"); +@@ -622,6 +623,7 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), ++ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43341), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +index 699f2c2..15598b3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -35,6 +35,7 @@ + #define BRCM_CC_4330_CHIP_ID 0x4330 + #define BRCM_CC_4334_CHIP_ID 0x4334 + #define BRCM_CC_43340_CHIP_ID 43340 ++#define BRCM_CC_43341_CHIP_ID 43341 + #define BRCM_CC_43362_CHIP_ID 43362 + #define BRCM_CC_4335_CHIP_ID 0x4335 + #define BRCM_CC_4339_CHIP_ID 0x4339 + +From 469393b56eef50bc105c7508c4a35bc66cc120ce Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 9 Mar 2016 17:25:59 +0000 -Subject: [PATCH 168/251] brcmfmac: Disable power management +Subject: [PATCH 092/114] brcmfmac: Disable power management Disable wireless power saving in the brcmfmac WLAN driver. This is a temporary measure until the connectivity loss resulting from power @@ -149742,14 +128174,14 @@ saving is resolved. Signed-off-by: Phil Elwell --- - drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -index deb5f78..90f65d9 100644 ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -2567,6 +2567,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d5c2a27..5a08f59 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2623,6 +2623,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, * preference in cfg struct to apply this to * FW later while initializing the dongle */ @@ -149759,4523 +128191,148 @@ index deb5f78..90f65d9 100644 if (!check_vif_up(ifp->vif)) { -From 6be841fb1dc54f49488ac814034726a0eecb26c7 Mon Sep 17 00:00:00 2001 +From 8077a80f7213a87ae6ee2adc25799fec6e1bfe4d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 22 Jan 2016 13:06:39 -0800 +Subject: [PATCH 093/114] drm/vc4: Add a debugfs node for tracking execution + state. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.h | 1 + + drivers/gpu/drm/vc4/vc4_gem.c | 14 ++++++++++++++ + 3 files changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c +index d76ad10..a99aa86 100644 +--- a/drivers/gpu/drm/vc4/vc4_debugfs.c ++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c +@@ -17,6 +17,7 @@ + + static const struct drm_info_list vc4_debugfs_list[] = { + {"bo_stats", vc4_bo_stats_debugfs, 0}, ++ {"gem_exec", vc4_gem_exec_debugfs, 0}, + {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, + {"hvs_regs", vc4_hvs_debugfs_regs, 0}, + {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index fa2ad15..f092986 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -440,6 +440,7 @@ void vc4_job_handle_completed(struct vc4_dev *vc4); + int vc4_queue_seqno_cb(struct drm_device *dev, + struct vc4_seqno_cb *cb, uint64_t seqno, + void (*func)(struct vc4_seqno_cb *cb)); ++int vc4_gem_exec_debugfs(struct seq_file *m, void *arg); + + /* vc4_hdmi.c */ + extern struct platform_driver vc4_hdmi_driver; +diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c +index 8d4384f..aa4517c 100644 +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -32,6 +32,20 @@ + #include "vc4_regs.h" + #include "vc4_trace.h" + ++#ifdef CONFIG_DEBUG_FS ++int vc4_gem_exec_debugfs(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *)m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(dev); ++ ++ seq_printf(m, "Emitted seqno: 0x%016llx\n", vc4->emit_seqno); ++ seq_printf(m, "Finished seqno: 0x%016llx\n", vc4->finished_seqno); ++ ++ return 0; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ + static void + vc4_queue_hangcheck(struct drm_device *dev) + { + +From 3fc260b067c746366f51c43394ac398b3155b097 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 25 Jan 2016 13:03:33 -0800 +Subject: [PATCH 094/114] drm/vc4: Include vc4_drm.h in uapi in downstream + build. + +Signed-off-by: Eric Anholt +--- + include/uapi/drm/Kbuild | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild +index 9355dd8..68828bf 100644 +--- a/include/uapi/drm/Kbuild ++++ b/include/uapi/drm/Kbuild +@@ -15,6 +15,7 @@ header-y += radeon_drm.h + header-y += savage_drm.h + header-y += sis_drm.h + header-y += tegra_drm.h ++header-y += vc4_drm.h + header-y += via_drm.h + header-y += vmwgfx_drm.h + header-y += msm_drm.h + +From 05001f87c74655bc0b286e53494dfad5ac3bc5e7 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Wed, 9 Mar 2016 21:28:52 +0000 -Subject: [PATCH 169/251] BCM270X_DT: rpi-display overlay - add swapxy param +Date: Wed, 23 Mar 2016 17:22:10 +0000 +Subject: [PATCH 095/114] DT configfs: Fix build errors on other platforms Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/overlays/README | 5 +---- - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 1 + - 2 files changed, 2 insertions(+), 4 deletions(-) + drivers/of/configfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 6a7aa31..6fa5b80 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -644,14 +644,11 @@ Name: rpi-display - Info: RPi-Display - 2.8" Touch Display by Watterott - Load: dtoverlay=rpi-display,= - Params: speed Display SPI bus speed -- - rotate Display rotation {0,90,180,270} -- - fps Delay between frame updates -- - debug Debug output level {0-7} -- - xohms Touchpanel sensitivity (X-plate resistance) -+ swapxy Swap x and y axis +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +index 7b66deb..168b9d3 100644 +--- a/drivers/of/configfs.c ++++ b/drivers/of/configfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include "of_private.h" - Name: rpi-ft5406 -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -index a8fa974..ccb296e 100644 ---- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -78,5 +78,6 @@ - fps = <&rpidisplay>,"fps:0"; - debug = <&rpidisplay>,"debug:0"; - xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; - }; - }; +@@ -153,7 +154,7 @@ ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, + { + struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); + +- pr_debug("%s: buf=%p max_count=%u\n", __func__, ++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, + buf, max_count); + + if (overlay->dtbo == NULL) -From 0775a4eb95034a3460293cbd08bc7c6ebbe47a0f Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Fri, 11 Mar 2016 11:44:35 +0000 -Subject: [PATCH 170/251] Remove I2S config from bt_pins. - -Remove I2S config from bt_pins. Causes issues with clock alignment when I2S is -used by an external DAC via GPIO header. ---- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 +++--- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 5a0c45a..2cb7d43 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -45,9 +45,9 @@ - }; - - bt_pins: bt_pins { -- brcm,pins = <28 29 30 31 43>; -- brcm,function = <6 6 6 6 4>; /* alt2:PCM alt0:GPCLK2 */ -- brcm,pull = <0 0 0 0 0>; -+ brcm,pins = <43>; -+ brcm,function = <4>; /* alt0:GPCLK2 */ -+ brcm,pull = <0>; - }; - - uart0_pins: uart0_pins { -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index 0b8f0ca..f07afcb 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -29,7 +29,7 @@ - target = <&uart1>; - __overlay__ { - pinctrl-names = "default"; -- pinctrl-0 = <&uart1_pins>; -+ pinctrl-0 = <&uart1_pins &bt_pins>; - status = "okay"; - }; - }; - -From c80d4e337d289f911bc3d9c972cbcc85c0bf758c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 10 Aug 2015 09:44:59 +0100 -Subject: [PATCH 171/251] Revert "scripts/dtc: Add overlay support" - -This reverts commit fa6d1755c2fdd9451077d8248e3804f0619f19b9. ---- - scripts/dtc/checks.c | 119 +-- - scripts/dtc/dtc-lexer.l | 5 - - scripts/dtc/dtc-lexer.lex.c_shipped | 490 +++++---- - scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++------------------- - scripts/dtc/dtc-parser.tab.h_shipped | 107 +- - scripts/dtc/dtc-parser.y | 23 +- - scripts/dtc/dtc.c | 9 +- - scripts/dtc/dtc.h | 38 - - scripts/dtc/flattree.c | 141 +-- - scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1145 insertions(+), 1685 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index efd1bc6..e81a8c7 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -458,91 +458,21 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -- struct fixup *f, **fp; -- struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -- int has_phandle_refs; -- -- has_phandle_refs = 0; -- for_each_marker_of_type(m, REF_PHANDLE) { -- has_phandle_refs = 1; -- break; -- } -- -- if (!has_phandle_refs) -- return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (!refnode && !symbol_fixup_support) { -+ if (! refnode) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- if (!refnode) { -- /* allocate fixup entry */ -- fe = xmalloc(sizeof(*fe)); -- -- fe->node = node; -- fe->prop = prop; -- fe->offset = m->offset; -- fe->next = NULL; -- -- /* search for an already existing fixup */ -- for_each_fixup(dt, f) -- if (strcmp(f->ref, m->ref) == 0) -- break; -- -- /* no fixup found, add new */ -- if (f == NULL) { -- f = xmalloc(sizeof(*f)); -- f->ref = m->ref; -- f->entries = NULL; -- f->next = NULL; -- -- /* add it to the tree */ -- fp = &dt->fixups; -- while (*fp) -- fp = &(*fp)->next; -- *fp = f; -- } -- -- /* and now append fixup entry */ -- fep = &f->entries; -- while (*fep) -- fep = &(*fep)->next; -- *fep = fe; -- -- /* mark the entry as unresolved */ -- phandle = 0xdeadbeef; -- } else { -- phandle = get_node_phandle(dt, refnode); -- -- /* if it's a plugin, we need to record it */ -- if (symbol_fixup_support && dt->is_plugin) { -- -- /* allocate a new local fixup entry */ -- fe = xmalloc(sizeof(*fe)); -- -- fe->node = node; -- fe->prop = prop; -- fe->offset = m->offset; -- fe->next = NULL; -- -- /* append it to the local fixups */ -- fep = &dt->local_fixups; -- while (*fep) -- fep = &(*fep)->next; -- *fep = fe; -- } -- } -- -- *((cell_t *)(prop->val.val + m->offset)) = -- cpu_to_fdt32(phandle); -+ phandle = get_node_phandle(dt, refnode); -+ *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -@@ -722,45 +652,6 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - --static void check_auto_label_phandles(struct check *c, struct node *dt, -- struct node *node) --{ -- struct label *l; -- struct symbol *s, **sp; -- int has_label; -- -- if (!symbol_fixup_support) -- return; -- -- has_label = 0; -- for_each_label(node->labels, l) { -- has_label = 1; -- break; -- } -- -- if (!has_label) -- return; -- -- /* force allocation of a phandle for this node */ -- (void)get_node_phandle(dt, node); -- -- /* add the symbol */ -- for_each_label(node->labels, l) { -- -- s = xmalloc(sizeof(*s)); -- s->label = l; -- s->node = node; -- s->next = NULL; -- -- /* add it to the symbols list */ -- sp = &dt->symbols; -- while (*sp) -- sp = &((*sp)->next); -- *sp = s; -- } --} --NODE_WARNING(auto_label_phandles, NULL); -- - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -779,8 +670,6 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -- &auto_label_phandles, -- - &always_fail, - }; - -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index dd44ba2..0ee1caf 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -113,11 +113,6 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - --<*>"/plugin/" { -- DPRINT("Keyword: /plugin/\n"); -- return DT_PLUGIN; -- } -- - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 1518525..11cd78e 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -9,7 +9,7 @@ - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 - #define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 35 -+#define YY_FLEX_SUBMINOR_VERSION 39 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -162,7 +162,12 @@ typedef unsigned int flex_uint32_t; - typedef struct yy_buffer_state *YY_BUFFER_STATE; - #endif - --extern int yyleng; -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ -+extern yy_size_t yyleng; - - extern FILE *yyin, *yyout; - -@@ -171,6 +176,7 @@ extern FILE *yyin, *yyout; - #define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) -+ #define YY_LINENO_REWIND_TO(ptr) - - /* Return all but the first "n" matched characters back to the input stream. */ - #define yyless(n) \ -@@ -188,11 +194,6 @@ extern FILE *yyin, *yyout; - - #define unput(c) yyunput( c, (yytext_ptr) ) - --#ifndef YY_TYPEDEF_YY_SIZE_T --#define YY_TYPEDEF_YY_SIZE_T --typedef size_t yy_size_t; --#endif -- - #ifndef YY_STRUCT_YY_BUFFER_STATE - #define YY_STRUCT_YY_BUFFER_STATE - struct yy_buffer_state -@@ -210,7 +211,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- int yy_n_chars; -+ yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -280,8 +281,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static int yy_n_chars; /* number of characters read into yy_ch_buf */ --int yyleng; -+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -+yy_size_t yyleng; - - /* Points to current character in buffer. */ - static char *yy_c_buf_p = (char *) 0; -@@ -309,7 +310,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - - YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); - YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); - - void *yyalloc (yy_size_t ); - void *yyrealloc (void *,yy_size_t ); -@@ -341,7 +342,7 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap(n) 1 -+#define yywrap() 1 - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; -@@ -372,8 +373,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 31 --#define YY_END_OF_BUFFER 32 -+#define YY_NUM_RULES 30 -+#define YY_END_OF_BUFFER 31 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -381,26 +382,25 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[166] = -+static yyconst flex_int16_t yy_accept[159] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -- 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -- 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -- 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -- 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -- 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -- 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -- 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -- 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -- 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -- 0, 0, 0, 8, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -+ 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -+ 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -+ 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -+ 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -+ 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -+ 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -+ 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -+ 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -+ -+ 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -+ 5, 8, 0, 0, 0, 0, 7, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -- 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -- 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, -+ 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -+ 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -+ 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,165 +435,163 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[48] = -+static yyconst flex_int32_t yy_meta[47] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[180] = -+static yyconst flex_int16_t yy_base[173] = - { 0, -- 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -- 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -- 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -- 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -- 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -- 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -- 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -- 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -- 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -- 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -- -- 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -- 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -- 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -- 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -- 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -- 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -- 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -- 281, 288, 292, 300, 308, 312, 318, 326, 334 -+ 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -+ 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -+ 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -+ 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -+ 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -+ 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -+ 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -+ 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -+ 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -+ 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -+ -+ 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -+ 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -+ 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -+ 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -+ 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -+ 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -+ 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -+ 318, 326 - } ; - --static yyconst flex_int16_t yy_def[180] = -+static yyconst flex_int16_t yy_def[173] = - { 0, -- 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -- 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -- 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -- 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -- 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -- 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -- 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -- 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -- -- 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -- 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -- 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -- 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165 -+ 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -+ 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -+ 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -+ 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -+ 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -+ 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -+ 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ -+ 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -+ 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -+ 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158 - } ; - --static yyconst flex_int16_t yy_nxt[449] = -+static yyconst flex_int16_t yy_nxt[438] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -- 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -- 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -- 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -- 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -- 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -- 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -- 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -- 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -- 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -- 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -- 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -- 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -- 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -- 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -- -- 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -- 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -- 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -- 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -- 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -- 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -- 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -- 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -- 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -- 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -- -- 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -- 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -- 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -- 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -- 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -- 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -- 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -- 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -- 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -- 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -- -- 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165 -+ 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -+ 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -+ 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -+ 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -+ 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -+ 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -+ 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -+ 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -+ 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -+ 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -+ 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -+ 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -+ 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -+ 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -+ 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -+ -+ 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -+ 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -+ 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -+ 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -+ 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -+ 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -+ 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -+ 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -+ 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -+ 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -+ -+ 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -+ 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -+ 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -+ 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -+ 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -+ 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -+ 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -+ 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -+ 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -+ 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158 - } ; - --static yyconst flex_int16_t yy_chk[449] = -+static yyconst flex_int16_t yy_chk[438] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -- 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -- 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -+ 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -+ 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -- 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -- 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -- 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -- 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -- 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -- 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -- 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -- 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -- -- 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -- 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -- 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -- 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -- 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -- 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -- 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -- 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -- 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -- 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -- -- 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -- 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -- 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -- 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -- 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -- 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -- 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -- 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -- 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, -+ 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -+ 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -+ 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -+ 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -+ 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -+ 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -+ 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -+ 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -+ 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -+ -+ 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -+ 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -+ 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -+ 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -+ 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -+ 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -+ 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -+ 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -+ 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -+ 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -+ -+ 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -+ 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -+ 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -+ 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -+ 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -+ 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -+ 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -+ 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165 -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -664,7 +662,7 @@ static int dts_version = 1; - static void push_input_file(const char *filename); - static bool pop_input_file(void); - static void lexical_error(const char *fmt, ...); --#line 668 "dtc-lexer.lex.c" -+#line 666 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -706,7 +704,7 @@ FILE *yyget_out (void ); - - void yyset_out (FILE * out_str ); - --int yyget_leng (void ); -+yy_size_t yyget_leng (void ); - - char *yyget_text (void ); - -@@ -855,10 +853,6 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - --#line 68 "dtc-lexer.l" -- --#line 861 "dtc-lexer.lex.c" -- - if ( !(yy_init) ) - { - (yy_init) = 1; -@@ -885,6 +879,11 @@ YY_DECL - yy_load_buffer_state( ); - } - -+ { -+#line 68 "dtc-lexer.l" -+ -+#line 886 "dtc-lexer.lex.c" -+ - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); -@@ -902,7 +901,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; -+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -911,13 +910,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 165 ); -+ while ( yy_current_state != 158 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -1008,31 +1007,23 @@ case 5: - YY_RULE_SETUP - #line 116 "dtc-lexer.l" - { -- DPRINT("Keyword: /plugin/\n"); -- return DT_PLUGIN; -- } -- YY_BREAK --case 6: --YY_RULE_SETUP --#line 121 "dtc-lexer.l" --{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 7: -+case 6: - YY_RULE_SETUP --#line 127 "dtc-lexer.l" -+#line 122 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 8: -+case 7: - YY_RULE_SETUP --#line 133 "dtc-lexer.l" -+#line 128 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1040,9 +1031,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 9: -+case 8: - YY_RULE_SETUP --#line 140 "dtc-lexer.l" -+#line 135 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1050,9 +1041,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 10: -+case 9: - YY_RULE_SETUP --#line 147 "dtc-lexer.l" -+#line 142 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1060,9 +1051,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 11: -+case 10: - YY_RULE_SETUP --#line 154 "dtc-lexer.l" -+#line 149 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1082,10 +1073,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 12: --/* rule 12 can match eol */ -+case 11: -+/* rule 11 can match eol */ - YY_RULE_SETUP --#line 173 "dtc-lexer.l" -+#line 168 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1107,18 +1098,18 @@ YY_RULE_SETUP - return DT_CHAR_LITERAL; - } - YY_BREAK --case 13: -+case 12: - YY_RULE_SETUP --#line 194 "dtc-lexer.l" -+#line 189 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 14: -+case 13: - YY_RULE_SETUP --#line 200 "dtc-lexer.l" -+#line 195 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1126,27 +1117,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 15: -+case 14: - YY_RULE_SETUP --#line 207 "dtc-lexer.l" -+#line 202 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 16: -+case 15: - YY_RULE_SETUP --#line 213 "dtc-lexer.l" -+#line 208 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 17: -+case 16: - YY_RULE_SETUP --#line 219 "dtc-lexer.l" -+#line 214 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1155,75 +1146,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 18: -+case 17: - YY_RULE_SETUP --#line 227 "dtc-lexer.l" -+#line 222 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 19: --/* rule 19 can match eol */ -+case 18: -+/* rule 18 can match eol */ - YY_RULE_SETUP --#line 232 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - /* eat whitespace */ - YY_BREAK --case 20: --/* rule 20 can match eol */ -+case 19: -+/* rule 19 can match eol */ - YY_RULE_SETUP --#line 233 "dtc-lexer.l" -+#line 228 "dtc-lexer.l" - /* eat C-style comments */ - YY_BREAK --case 21: --/* rule 21 can match eol */ -+case 20: -+/* rule 20 can match eol */ - YY_RULE_SETUP --#line 234 "dtc-lexer.l" -+#line 229 "dtc-lexer.l" - /* eat C++-style comments */ - YY_BREAK --case 22: -+case 21: - YY_RULE_SETUP --#line 236 "dtc-lexer.l" -+#line 231 "dtc-lexer.l" - { return DT_LSHIFT; }; - YY_BREAK --case 23: -+case 22: - YY_RULE_SETUP --#line 237 "dtc-lexer.l" -+#line 232 "dtc-lexer.l" - { return DT_RSHIFT; }; - YY_BREAK --case 24: -+case 23: - YY_RULE_SETUP --#line 238 "dtc-lexer.l" -+#line 233 "dtc-lexer.l" - { return DT_LE; }; - YY_BREAK --case 25: -+case 24: - YY_RULE_SETUP --#line 239 "dtc-lexer.l" -+#line 234 "dtc-lexer.l" - { return DT_GE; }; - YY_BREAK --case 26: -+case 25: - YY_RULE_SETUP --#line 240 "dtc-lexer.l" -+#line 235 "dtc-lexer.l" - { return DT_EQ; }; - YY_BREAK --case 27: -+case 26: - YY_RULE_SETUP --#line 241 "dtc-lexer.l" -+#line 236 "dtc-lexer.l" - { return DT_NE; }; - YY_BREAK --case 28: -+case 27: - YY_RULE_SETUP --#line 242 "dtc-lexer.l" -+#line 237 "dtc-lexer.l" - { return DT_AND; }; - YY_BREAK --case 29: -+case 28: - YY_RULE_SETUP --#line 243 "dtc-lexer.l" -+#line 238 "dtc-lexer.l" - { return DT_OR; }; - YY_BREAK --case 30: -+case 29: - YY_RULE_SETUP --#line 245 "dtc-lexer.l" -+#line 240 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1239,12 +1230,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 31: -+case 30: - YY_RULE_SETUP --#line 260 "dtc-lexer.l" -+#line 255 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1248 "dtc-lexer.lex.c" -+#line 1239 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1374,6 +1365,7 @@ ECHO; - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -+ } /* end of user's declarations */ - } /* end of yylex */ - - /* yy_get_next_buffer - try to read in a new buffer -@@ -1429,21 +1421,21 @@ static int yy_get_next_buffer (void) - - else - { -- int num_to_read = -+ yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { -- int new_size = b->yy_buf_size * 2; -+ yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1474,7 +1466,7 @@ static int yy_get_next_buffer (void) - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -- (yy_n_chars), (size_t) num_to_read ); -+ (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } -@@ -1536,7 +1528,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1564,13 +1556,13 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 165); -+ yy_is_jam = (yy_current_state == 158); - -- return yy_is_jam ? 0 : yy_current_state; -+ return yy_is_jam ? 0 : yy_current_state; - } - - #ifndef YY_NO_INPUT -@@ -1597,7 +1589,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- int offset = (yy_c_buf_p) - (yytext_ptr); -+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1871,7 +1863,7 @@ void yypop_buffer_state (void) - */ - static void yyensure_buffer_stack (void) - { -- int num_to_alloc; -+ yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - -@@ -1968,12 +1960,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- int i; -+ yy_size_t i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; -@@ -2055,7 +2047,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --int yyget_leng (void) -+yy_size_t yyget_leng (void) - { - return yyleng; - } -@@ -2203,7 +2195,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 260 "dtc-lexer.l" -+#line 254 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 2c1784e..116458c 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.5. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "2.5" -+#define YYBISON_VERSION "3.0.2" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -58,18 +58,13 @@ - /* Pull parsers. */ - #define YYPULL 1 - --/* Using locations. */ --#define YYLSP_NEEDED 1 - - - - /* Copy the first part of user declarations. */ -- --/* Line 268 of yacc.c */ --#line 20 "dtc-parser.y" -+#line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include --#include - - #include "dtc.h" - #include "srcpos.h" -@@ -85,14 +80,15 @@ extern void yyerror(char const *s); - extern struct boot_info *the_boot_info; - extern bool treesource_error; - -+#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ - --/* Line 268 of yacc.c */ --#line 91 "dtc-parser.tab.c" -- --/* Enabling traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif -+# ifndef YY_NULLPTR -+# if defined __cplusplus && 201103L <= __cplusplus -+# define YY_NULLPTR nullptr -+# else -+# define YY_NULLPTR 0 -+# endif -+# endif - - /* Enabling verbose error messages. */ - #ifdef YYERROR_VERBOSE -@@ -102,51 +98,53 @@ extern bool treesource_error; - # define YYERROR_VERBOSE 0 - #endif - --/* Enabling the token table. */ --#ifndef YYTOKEN_TABLE --# define YYTOKEN_TABLE 0 -+/* In a future release of Bison, this section will be replaced -+ by #include "dtc-parser.tab.h". */ -+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -+/* Debug traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+#if YYDEBUG -+extern int yydebug; - #endif - -- --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_PLUGIN = 259, -- DT_MEMRESERVE = 260, -- DT_LSHIFT = 261, -- DT_RSHIFT = 262, -- DT_LE = 263, -- DT_GE = 264, -- DT_EQ = 265, -- DT_NE = 266, -- DT_AND = 267, -- DT_OR = 268, -- DT_BITS = 269, -- DT_DEL_PROP = 270, -- DT_DEL_NODE = 271, -- DT_PROPNODENAME = 272, -- DT_LITERAL = 273, -- DT_CHAR_LITERAL = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_LSHIFT = 260, -+ DT_RSHIFT = 261, -+ DT_LE = 262, -+ DT_GE = 263, -+ DT_EQ = 264, -+ DT_NE = 265, -+ DT_AND = 266, -+ DT_OR = 267, -+ DT_BITS = 268, -+ DT_DEL_PROP = 269, -+ DT_DEL_NODE = 270, -+ DT_PROPNODENAME = 271, -+ DT_LITERAL = 272, -+ DT_CHAR_LITERAL = 273, -+ DT_BYTE = 274, -+ DT_STRING = 275, -+ DT_LABEL = 276, -+ DT_REF = 277, -+ DT_INCBIN = 278 -+ }; - #endif - -- -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { -- --/* Line 293 of yacc.c */ --#line 39 "dtc-parser.y" -+#line 38 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; -@@ -164,37 +162,37 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; - -- -- --/* Line 293 of yacc.c */ --#line 173 "dtc-parser.tab.c" --} YYSTYPE; -+#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - -+/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --} YYLTYPE; --# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+}; - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - - --/* Copy the second part of user declarations. */ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; -+int yyparse (void); - -+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ - --/* Line 343 of yacc.c */ --#line 198 "dtc-parser.tab.c" -+/* Copy the second part of user declarations. */ -+ -+#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -208,11 +206,8 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#elif (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --typedef signed char yytype_int8; - #else --typedef short int yytype_int8; -+typedef signed char yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -232,8 +227,7 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# elif ! defined YYSIZE_T - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -247,38 +241,67 @@ typedef short int yytype_int16; - # if defined YYENABLE_NLS && YYENABLE_NLS - # if ENABLE_NLS - # include /* INFRINGES ON USER NAME SPACE */ --# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# define YY_(Msgid) dgettext ("bison-runtime", Msgid) - # endif - # endif - # ifndef YY_ --# define YY_(msgid) msgid -+# define YY_(Msgid) Msgid -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE -+# if (defined __GNUC__ \ -+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -+# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -+# else -+# define YY_ATTRIBUTE(Spec) /* empty */ -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE_PURE -+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -+#endif -+ -+#ifndef YY_ATTRIBUTE_UNUSED -+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -+#endif -+ -+#if !defined _Noreturn \ -+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -+# if defined _MSC_VER && 1200 <= _MSC_VER -+# define _Noreturn __declspec (noreturn) -+# else -+# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) - # endif - #endif - - /* Suppress unused-variable warnings by "using" E. */ - #if ! defined lint || defined __GNUC__ --# define YYUSE(e) ((void) (e)) -+# define YYUSE(E) ((void) (E)) - #else --# define YYUSE(e) /* empty */ -+# define YYUSE(E) /* empty */ - #endif - --/* Identity function, used to suppress warnings about constant conditions. */ --#ifndef lint --# define YYID(n) (n) --#else --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static int --YYID (int yyi) -+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -+/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -+ _Pragma ("GCC diagnostic push") \ -+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -+ _Pragma ("GCC diagnostic pop") - #else --static int --YYID (yyi) -- int yyi; -+# define YY_INITIAL_VALUE(Value) Value - #endif --{ -- return yyi; --} -+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END - #endif -+#ifndef YY_INITIAL_VALUE -+# define YY_INITIAL_VALUE(Value) /* Nothing. */ -+#endif -+ - - #if ! defined yyoverflow || YYERROR_VERBOSE - -@@ -297,9 +320,9 @@ YYID (yyi) - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS - # include /* INFRINGES ON USER NAME SPACE */ -+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 - # endif -@@ -309,8 +332,8 @@ YYID (yyi) - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's `empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+ /* Pacify GCC's 'empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -326,7 +349,7 @@ YYID (yyi) - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -334,15 +357,13 @@ YYID (yyi) - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined malloc && ! defined EXIT_SUCCESS - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined free && ! defined EXIT_SUCCESS - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -352,8 +373,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc -@@ -379,35 +400,35 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (YYID (0)) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) - - #endif - - #if defined YYCOPY_NEEDED && YYCOPY_NEEDED --/* Copy COUNT objects from FROM to TO. The source and destination do -+/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ - # ifndef YYCOPY - # if defined __GNUC__ && 1 < __GNUC__ --# define YYCOPY(To, From, Count) \ -- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# define YYCOPY(Dst, Src, Count) \ -+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) - # else --# define YYCOPY(To, From, Count) \ -- do \ -- { \ -- YYSIZE_T yyi; \ -- for (yyi = 0; yyi < (Count); yyi++) \ -- (To)[yyi] = (From)[yyi]; \ -- } \ -- while (YYID (0)) -+# define YYCOPY(Dst, Src, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (Dst)[yyi] = (Src)[yyi]; \ -+ } \ -+ while (0) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -418,37 +439,39 @@ union yyalloc - #define YYLAST 136 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 48 -+#define YYNTOKENS 47 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 29 -+#define YYNNTS 28 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 82 --/* YYNRULES -- Number of states. */ --#define YYNSTATES 147 -+#define YYNRULES 80 -+/* YYNSTATES -- Number of states. */ -+#define YYNSTATES 144 - --/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -+ by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 279 -+#define YYMAXUTOK 278 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -+ as returned by yylex, without out-of-bounds checking. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -- 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -- 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -+ 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -+ 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, -+ 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, -+ 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -463,335 +486,292 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23 - }; - - #if YYDEBUG --/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -- YYRHS. */ --static const yytype_uint16 yyprhs[] = --{ -- 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, -- 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, -- 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, -- 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, -- 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, -- 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, -- 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, -- 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, -- 262, 265, 269 --}; -- --/* YYRHS -- A `-1'-separated list of the rules' RHS. */ --static const yytype_int8 yyrhs[] = --{ -- 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, -- 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, -- 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, -- 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, -- -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, -- 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, -- -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, -- -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, -- 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, -- 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, -- 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, -- 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, -- -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, -- -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, -- 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, -- -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, -- 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, -- -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, -- -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, -- -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, -- 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, -- -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, -- -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, -- -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, -- 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, -- 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, -- 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, -- 76, -1 --}; -- --/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -- 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, -- 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, -- 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, -- 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, -- 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, -- 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, -- 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, -- 474, 478, 482 -+ 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -+ 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -+ 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -+ 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -+ 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -+ 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -+ 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -+ 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -+ 465 - }; - #endif - --#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+#if YYDEBUG || YYERROR_VERBOSE || 0 - /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -- "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -- "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -- "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -- "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -- "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -- "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -- "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -- "integer_prim", "integer_expr", "integer_trinary", "integer_or", -- "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -- "integer_eq", "integer_rela", "integer_shift", "integer_add", -- "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 -+ "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -+ "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -+ "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -+ "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -+ "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -+ "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -+ "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -+ "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -+ "integer_expr", "integer_trinary", "integer_or", "integer_and", -+ "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -+ "integer_rela", "integer_shift", "integer_add", "integer_mul", -+ "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -- token YYLEX-NUM. */ -+/* YYTOKNUM[NUM] -- (External) token number corresponding to the -+ (internal) symbol number NUM (which must be that of a token). */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -- 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -- 94, 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -+ 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -+ 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = --{ -- 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -- 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, -- 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, -- 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, -- 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, -- 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, -- 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, -- 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, -- 76, 76, 76 --}; -+#define YYPACT_NINF -81 - --/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+#define yypact_value_is_default(Yystate) \ -+ (!!((Yystate) == (-81))) -+ -+#define YYTABLE_NINF -1 -+ -+#define yytable_value_is_error(Yytable_value) \ -+ 0 -+ -+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+static const yytype_int8 yypact[] = - { -- 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -- 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, -- 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, -- 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, -- 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, -- 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, -- 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, -- 2, 3, 2 -+ 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -+ -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -+ -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -+ 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -+ 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -+ -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -+ 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -+ 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -+ 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -+ 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -+ -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -+ -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -+ -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -+ 74, 25, 75, -81 - }; - --/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE doesn't specify something else to do. Zero -- means the default is an error. */ -+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE does not specify something else to do. Zero -+ means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -- 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, -- 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, -- 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, -- 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, -+ 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -+ 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -+ 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -+ 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -+ 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, -- 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, -- 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, -- 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, -- 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, -- 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, -- 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, -- 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, -- 23, 0, 26, 0, 0, 0, 25 -+ 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -+ 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -+ 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -+ 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -+ 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -+ 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -+ 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -+ 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -+ 0, 0, 0, 23 - }; - --/* YYDEFGOTO[NTERM-NUM]. */ --static const yytype_int16 yydefgoto[] = -+ /* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, -- 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, -- 31, 32, 33, 34, 35, 36, 131, 97, 98 -+ -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -+ -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -+ 37, 27, 34, 38, -14, -81, 22, 24 - }; - --/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --#define YYPACT_NINF -84 --static const yytype_int8 yypact[] = -+ /* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int16 yydefgoto[] = - { -- 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, -- 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, -- -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, -- 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, -- 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, -- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -- -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, -- 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, -- 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, -- -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, -- -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, -- -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, -- -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, -- 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, -- -84, 24, -84, 77, 24, 80, -84 -+ -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -+ 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -+ 29, 30, 31, 32, 33, 128, 94, 95 - }; - --/* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule whose -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+static const yytype_uint8 yytable[] = - { -- -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, -- -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, -- 82, 29, 18, 25, 26, -17, -84, 20, 28 -+ 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -+ 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -+ 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -+ 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -+ 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -+ 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -+ 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -+ 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -+ 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -+ 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -+ 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -+ 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -+ 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -+ 0, 0, 75, 140, 0, 0, 142 - }; - --/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule which -- number is the opposite. If YYTABLE_NINF, syntax error. */ --#define YYTABLE_NINF -1 --static const yytype_uint8 yytable[] = -+static const yytype_int16 yycheck[] = - { -- 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, -- 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, -- 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, -- 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, -- 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, -- 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, -- 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, -- 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, -- 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, -- 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, -- 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, -- 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, -- 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 143, 0, 78, 145 -+ 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -+ 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -+ 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -+ 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -+ 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -+ 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -+ 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -+ 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -+ 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -+ 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -+ 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -+ 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -+ 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -+ -1, -1, 50, 138, -1, -1, 141 - }; - --#define yypact_value_is_default(yystate) \ -- ((yystate) == (-84)) -- --#define yytable_value_is_error(yytable_value) \ -- YYID (0) -+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -+ 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -+ 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -+ 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -+ 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -+ 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -+ 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -+ 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -+ 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -+ 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -+ 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -+ 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -+ 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -+ 58, 33, 58, 34 -+}; - --static const yytype_int16 yycheck[] = -+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, -- 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, -- 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, -- 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, -- 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, -- 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, -- 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, -- 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, -- 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, -- 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, -- 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, -- 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, -- 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, 141, -1, 53, 144 -+ 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -+ 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -+ 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -+ 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -+ 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -+ 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -+ 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -+ 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -+ 74 - }; - --/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -- 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -- 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -- 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -- 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, -- 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, -- 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, -- 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, -- 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, -- 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, -- 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, -- 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, -- 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, -- 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, -- 32, 34, 35, 60, 34, 60, 35 -+ 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -+ 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -+ 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -+ 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -+ 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -+ 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -+ 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -+ 2 - }; - --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -- --/* Like YYERROR except do call yyerror. This remains here temporarily -- to ease the transition to the new meaning of YYERROR, for GCC. -- Once GCC version 2 has supplanted version 1, this can go. However, -- YYFAIL appears to be in use. Nevertheless, it is formally deprecated -- in Bison 2.4.2's NEWS entry, where a plan to phase it out is -- discussed. */ -- --#define YYFAIL goto yyerrlab --#if defined YYFAIL -- /* This is here to suppress warnings from the GCC cpp's -- -Wunused-macros. Normally we don't worry about that warning, but -- some users do, and we want to make it easy for users to remove -- YYFAIL uses, which will produce warnings from Bison 2.5. */ --#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ - - #define YYRECOVERING() (!!yyerrstatus) - --#define YYBACKUP(Token, Value) \ --do \ -- if (yychar == YYEMPTY && yylen == 1) \ -- { \ -- yychar = (Token); \ -- yylval = (Value); \ -- YYPOPSTACK (1); \ -- goto yybackup; \ -- } \ -- else \ -- { \ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ YYPOPSTACK (yylen); \ -+ yystate = *yyssp; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (YYID (0)) -- -+ YYERROR; \ -+ } \ -+while (0) - --#define YYTERROR 1 --#define YYERRCODE 256 -+/* Error token number */ -+#define YYTERROR 1 -+#define YYERRCODE 256 - - - /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - --#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - #ifndef YYLLOC_DEFAULT --# define YYLLOC_DEFAULT(Current, Rhs, N) \ -- do \ -- if (YYID (N)) \ -- { \ -- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -- } \ -- else \ -- { \ -- (Current).first_line = (Current).last_line = \ -- YYRHSLOC (Rhs, 0).last_line; \ -- (Current).first_column = (Current).last_column = \ -- YYRHSLOC (Rhs, 0).last_column; \ -- } \ -- while (YYID (0)) -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) - #endif - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+ -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ - - /* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know -@@ -799,82 +779,73 @@ while (YYID (0)) - - #ifndef YY_LOCATION_PRINT - # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL --# define YY_LOCATION_PRINT(File, Loc) \ -- fprintf (File, "%d.%d-%d.%d", \ -- (Loc).first_line, (Loc).first_column, \ -- (Loc).last_line, (Loc).last_column) --# else --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) --# endif --#endif -- - --/* YYLEX -- calling `yylex' with the right arguments. */ -+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - --#ifdef YYLEX_PARAM --# define YYLEX yylex (YYLEX_PARAM) --#else --# define YYLEX yylex () --#endif -+YY_ATTRIBUTE_UNUSED -+static unsigned -+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -+{ -+ unsigned res = 0; -+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -+ if (0 <= yylocp->first_line) -+ { -+ res += YYFPRINTF (yyo, "%d", yylocp->first_line); -+ if (0 <= yylocp->first_column) -+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -+ } -+ if (0 <= yylocp->last_line) -+ { -+ if (yylocp->first_line < yylocp->last_line) -+ { -+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -+ if (0 <= end_col) -+ res += YYFPRINTF (yyo, ".%d", end_col); -+ } -+ else if (0 <= end_col && yylocp->first_column < end_col) -+ res += YYFPRINTF (yyo, "-%d", end_col); -+ } -+ return res; -+ } - --/* Enable debugging if requested. */ --#if YYDEBUG -+# define YY_LOCATION_PRINT(File, Loc) \ -+ yy_location_print_ (File, &(Loc)) - --# ifndef YYFPRINTF --# include /* INFRINGES ON USER NAME SPACE */ --# define YYFPRINTF fprintf -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) - # endif -+#endif - --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (YYID (0)) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value, Location); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (YYID (0)) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) - - --/*--------------------------------. --| Print this symbol on YYOUTPUT. | --`--------------------------------*/ -+/*----------------------------------------. -+| Print this symbol's value on YYOUTPUT. | -+`----------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) --#else --static void --yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -- YYLTYPE const * const yylocationp; --#endif - { -+ FILE *yyo = yyoutput; -+ YYUSE (yyo); -+ YYUSE (yylocationp); - if (!yyvaluep) - return; -- YYUSE (yylocationp); - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); --# else -- YYUSE (yyoutput); - # endif -- switch (yytype) -- { -- default: -- break; -- } -+ YYUSE (yytype); - } - - -@@ -882,23 +853,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) --#else --static void --yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -- YYLTYPE const * const yylocationp; --#endif - { -- if (yytype < YYNTOKENS) -- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -- else -- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ YYFPRINTF (yyoutput, "%s %s (", -+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); -@@ -911,16 +870,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) - | TOP (included). | - `------------------------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) --#else --static void --yy_stack_print (yybottom, yytop) -- yytype_int16 *yybottom; -- yytype_int16 *yytop; --#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -931,50 +882,42 @@ yy_stack_print (yybottom, yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (YYID (0)) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) --#else - static void --yy_reduce_print (yyvsp, yylsp, yyrule) -- YYSTYPE *yyvsp; -- YYLTYPE *yylsp; -- int yyrule; --#endif -+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) - { -+ unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -- unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- , &(yylsp[(yyi + 1) - (yynrhs)]) ); -+ yy_symbol_print (stderr, -+ yystos[yyssp[yyi + 1 - yynrhs]], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyvsp, yylsp, Rule); \ --} while (YYID (0)) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ -+} while (0) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -988,7 +931,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -1011,15 +954,8 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) --#else --static YYSIZE_T --yystrlen (yystr) -- const char *yystr; --#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -1035,16 +971,8 @@ yystrlen (yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) --#else --static char * --yystpcpy (yydest, yysrc) -- char *yydest; -- const char *yysrc; --#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1074,27 +1002,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1117,12 +1045,11 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; -- YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = 0; -+ const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1130,10 +1057,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -- - Assume YYFAIL is not used. It's too flawed to consider. See -- -- for details. YYERROR is fine as it does not invoke this -- function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1182,11 +1105,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - break; - } - yyarg[yycount++] = yytname[yyx]; -- yysize1 = yysize + yytnamerr (0, yytname[yyx]); -- if (! (yysize <= yysize1 -- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -+ { -+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); -+ if (! (yysize <= yysize1 -+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } - } - } - } -@@ -1206,10 +1131,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - # undef YYCASE_ - } - -- yysize1 = yysize + yystrlen (yyformat); -- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -+ { -+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat); -+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } - - if (*yymsg_alloc < yysize) - { -@@ -1246,50 +1173,21 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) --#else --static void --yydestruct (yymsg, yytype, yyvaluep, yylocationp) -- const char *yymsg; -- int yytype; -- YYSTYPE *yyvaluep; -- YYLTYPE *yylocationp; --#endif - { - YYUSE (yyvaluep); - YYUSE (yylocationp); -- - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -- switch (yytype) -- { -- -- default: -- break; -- } -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+ YYUSE (yytype); -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - } - - --/* Prevent warnings from -Wmissing-prototypes. */ --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); --#endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus --int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - - /* The lookahead symbol. */ -@@ -1297,10 +1195,12 @@ int yychar; - - /* The semantic value of the lookahead symbol. */ - YYSTYPE yylval; -- - /* Location data for the lookahead symbol. */ --YYLTYPE yylloc; -- -+YYLTYPE yylloc -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ = { 1, 1, 1, 1 } -+# endif -+; - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1309,38 +1209,19 @@ int yynerrs; - | yyparse. | - `----------*/ - --#ifdef YYPARSE_PARAM --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --int --yyparse (void *YYPARSE_PARAM) --#else --int --yyparse (YYPARSE_PARAM) -- void *YYPARSE_PARAM; --#endif --#else /* ! YYPARSE_PARAM */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) --#else --int --yyparse () -- --#endif --#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- `yyss': related to states. -- `yyvs': related to semantic values. -- `yyls': related to locations. -+ 'yyss': related to states. -+ 'yyvs': related to semantic values. -+ 'yyls': related to locations. - -- Refer to the stacks thru separate pointers, to allow yyoverflow -+ Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ -@@ -1366,7 +1247,7 @@ yyparse () - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ -- int yytoken; -+ int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -@@ -1385,10 +1266,9 @@ yyparse () - Keep to zero when no symbol should be popped. */ - int yylen = 0; - -- yytoken = 0; -- yyss = yyssa; -- yyvs = yyvsa; -- yyls = yylsa; -+ yyssp = yyss = yyssa; -+ yyvsp = yyvs = yyvsa; -+ yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1397,21 +1277,7 @@ yyparse () - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -- -- /* Initialize stack pointers. -- Waste one element of value and location stack -- so that they stay on the same level as the state stack. -- The wasted elements are never initialized. */ -- yyssp = yyss; -- yyvsp = yyvs; -- yylsp = yyls; -- --#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -- /* Initialize the default location before parsing starts. */ -- yylloc.first_line = yylloc.last_line = 1; -- yylloc.first_column = yylloc.last_column = 1; --#endif -- -+ yylsp[0] = yylloc; - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1432,26 +1298,26 @@ yyparse () - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- YYLTYPE *yyls1 = yyls; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yyls1, yysize * sizeof (*yylsp), -- &yystacksize); -- -- yyls = yyls1; -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1459,23 +1325,23 @@ yyparse () - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -- YYSTACK_RELOCATE (yyls_alloc, yyls); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ -@@ -1485,10 +1351,10 @@ yyparse () - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1517,7 +1383,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = YYLEX; -+ yychar = yylex (); - } - - if (yychar <= YYEOF) -@@ -1557,7 +1423,9 @@ yybackup: - yychar = YYEMPTY; - - yystate = yyn; -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - -@@ -1580,7 +1448,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- `$$ = $1'. -+ '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1595,322 +1463,273 @@ yyreduce: - switch (yyn) - { - case 2: -- --/* Line 1806 of yacc.c */ --#line 109 "dtc-parser.y" -+#line 105 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); -- (yyvsp[(5) - (5)].node)->is_root = 1; -- the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), -- guess_boot_cpuid((yyvsp[(5) - (5)].node))); -+ the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } -+#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: -- --/* Line 1806 of yacc.c */ --#line 119 "dtc-parser.y" -+#line 113 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.is_plugin) = 0; -+ (yyval.re) = NULL; - } -+#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: -- --/* Line 1806 of yacc.c */ --#line 123 "dtc-parser.y" -+#line 117 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.is_plugin) = 1; -+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } -+#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: -- --/* Line 1806 of yacc.c */ --#line 130 "dtc-parser.y" -+#line 124 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } -+#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: -- --/* Line 1806 of yacc.c */ --#line 134 "dtc-parser.y" -+#line 128 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -+ (yyval.re) = (yyvsp[0].re); - } -+#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: -- --/* Line 1806 of yacc.c */ --#line 141 "dtc-parser.y" -+#line 136 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); -+ (yyval.node) = name_node((yyvsp[0].node), ""); - } -+#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: -- --/* Line 1806 of yacc.c */ --#line 145 "dtc-parser.y" -+#line 140 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.re) = (yyvsp[(2) - (2)].re); -+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } -+#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: -- --/* Line 1806 of yacc.c */ --#line 153 "dtc-parser.y" -+#line 145 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ -+ add_label(&target->labels, (yyvsp[-2].labelref)); -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: -- --/* Line 1806 of yacc.c */ --#line 157 "dtc-parser.y" -+#line 156 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); -+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-2].node); - } -+#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: -- --/* Line 1806 of yacc.c */ --#line 162 "dtc-parser.y" -+#line 166 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -- add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); - if (target) -- merge_nodes(target, (yyvsp[(4) - (4)].node)); -+ delete_node(target); - else -- ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: -- --/* Line 1806 of yacc.c */ --#line 173 "dtc-parser.y" -+#line 181 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -- -- if (target) -- merge_nodes(target, (yyvsp[(3) - (3)].node)); -- else -- ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); -- (yyval.node) = (yyvsp[(1) - (3)].node); -+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } -+#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: -- --/* Line 1806 of yacc.c */ --#line 183 "dtc-parser.y" -+#line 188 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -- -- if (target) -- delete_node(target); -- else -- ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -- -- -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ (yyval.proplist) = NULL; - } -+#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: -- --/* Line 1806 of yacc.c */ --#line 198 "dtc-parser.y" -+#line 192 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); -+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } -+#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: -- --/* Line 1806 of yacc.c */ --#line 205 "dtc-parser.y" -+#line 199 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = NULL; -+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } -+#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: -- --/* Line 1806 of yacc.c */ --#line 209 "dtc-parser.y" -+#line 203 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); -+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } -+#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: -- --/* Line 1806 of yacc.c */ --#line 216 "dtc-parser.y" -+#line 207 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); -+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } -+#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: -- --/* Line 1806 of yacc.c */ --#line 220 "dtc-parser.y" -+#line 211 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); -+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -+ (yyval.prop) = (yyvsp[0].prop); - } -+#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: -- --/* Line 1806 of yacc.c */ --#line 224 "dtc-parser.y" -+#line 219 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); -+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } -+#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: -- --/* Line 1806 of yacc.c */ --#line 228 "dtc-parser.y" -+#line 223 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.prop) = (yyvsp[(2) - (2)].prop); -+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } -+#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: -- --/* Line 1806 of yacc.c */ --#line 236 "dtc-parser.y" -+#line 227 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); -+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } -+#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: -- --/* Line 1806 of yacc.c */ --#line 240 "dtc-parser.y" -+#line 231 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } -+#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 23: -- --/* Line 1806 of yacc.c */ --#line 244 "dtc-parser.y" -+#line 235 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -- } -- break; -- -- case 24: -- --/* Line 1806 of yacc.c */ --#line 248 "dtc-parser.y" -- { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -- } -- break; -- -- case 25: -- --/* Line 1806 of yacc.c */ --#line 252 "dtc-parser.y" -- { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; - -- if ((yyvsp[(6) - (9)].integer) != 0) -- if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) -+ if ((yyvsp[-3].integer) != 0) -+ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, -+ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, - strerror(errno)); - -- d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); -+ d = data_copy_file(f, (yyvsp[-1].integer)); - -- (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); -+ (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } -+#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: -- --/* Line 1806 of yacc.c */ --#line 268 "dtc-parser.y" -+ case 24: -+#line 251 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); -+ (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } -+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: -- --/* Line 1806 of yacc.c */ --#line 278 "dtc-parser.y" -+ case 25: -+#line 261 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: -- --/* Line 1806 of yacc.c */ --#line 285 "dtc-parser.y" -+ case 26: -+#line 268 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: -- --/* Line 1806 of yacc.c */ --#line 289 "dtc-parser.y" -+ case 27: -+#line 272 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = (yyvsp[(1) - (2)].data); -+ (yyval.data) = (yyvsp[-1].data); - } -+#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: -- --/* Line 1806 of yacc.c */ --#line 293 "dtc-parser.y" -+ case 28: -+#line 276 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: -- --/* Line 1806 of yacc.c */ --#line 300 "dtc-parser.y" -+ case 29: -+#line 283 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - -- bits = (yyvsp[(2) - (3)].integer); -+ bits = (yyvsp[-1].integer); - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { -- ERROR(&(yylsp[(2) - (3)]), "Array elements must be" -+ ERROR(&(yylsp[-1]), "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } -@@ -1918,25 +1737,23 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } -+#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: -- --/* Line 1806 of yacc.c */ --#line 316 "dtc-parser.y" -+ case 30: -+#line 299 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } -+#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: -- --/* Line 1806 of yacc.c */ --#line 321 "dtc-parser.y" -+ case 31: -+#line 304 "dtc-parser.y" /* yacc.c:1646 */ - { -- if ((yyvsp[(1) - (2)].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; -+ if ((yyvsp[-1].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1945,293 +1762,258 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -- ERROR(&(yylsp[(2) - (2)]), "Value out of range for" -- " %d-bit array element", (yyvsp[(1) - (2)].array).bits); -+ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[0]), "Value out of range for" -+ " %d-bit array element", (yyvsp[-1].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } -+#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 34: -- --/* Line 1806 of yacc.c */ --#line 340 "dtc-parser.y" -+ case 32: -+#line 323 "dtc-parser.y" /* yacc.c:1646 */ - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -- if ((yyvsp[(1) - (2)].array).bits == 32) -- (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, -+ if ((yyvsp[-1].array).bits == 32) -+ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, - REF_PHANDLE, -- (yyvsp[(2) - (2)].labelref)); -+ (yyvsp[0].labelref)); - else -- ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " -+ ERROR(&(yylsp[0]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } -+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 35: -- --/* Line 1806 of yacc.c */ --#line 354 "dtc-parser.y" -+ case 33: -+#line 337 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } -+#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 38: -- --/* Line 1806 of yacc.c */ --#line 363 "dtc-parser.y" -+ case 36: -+#line 346 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = (yyvsp[(2) - (3)].integer); -+ (yyval.integer) = (yyvsp[-1].integer); - } -+#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 41: -+ case 39: -+#line 357 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } -+#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 374 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } -+ case 41: -+#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } -+#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 43: -- --/* Line 1806 of yacc.c */ --#line 379 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } -+#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } -+#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 45: -- --/* Line 1806 of yacc.c */ --#line 384 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } -+#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } -+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 47: -- --/* Line 1806 of yacc.c */ --#line 389 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } -+#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } -+#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 49: -- --/* Line 1806 of yacc.c */ --#line 394 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } -+#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } -+#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 51: -- --/* Line 1806 of yacc.c */ --#line 399 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } -+#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } -+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 53: -- --/* Line 1806 of yacc.c */ --#line 404 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } -+ case 52: -+#line 388 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } -+#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 54: -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } -+#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 405 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } -+ case 55: -+#line 394 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } -+#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 56: -- --/* Line 1806 of yacc.c */ --#line 410 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } -+#line 395 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } -+#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 57: -- --/* Line 1806 of yacc.c */ --#line 411 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } -+#line 396 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } -+#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 58: -- --/* Line 1806 of yacc.c */ --#line 412 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } -+#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } -+#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 59: -- --/* Line 1806 of yacc.c */ --#line 413 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -- break; -- -- case 60: -- --/* Line 1806 of yacc.c */ --#line 417 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } -+#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } -+#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 61: -- --/* Line 1806 of yacc.c */ --#line 418 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } -+#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -+#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 63: -- --/* Line 1806 of yacc.c */ --#line 423 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } -+ case 62: -+#line 407 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } -+#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 64: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } -+#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 424 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } -+ case 65: -+#line 413 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } -+#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 66: -- --/* Line 1806 of yacc.c */ --#line 429 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } -+#line 414 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } -+#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 67: -- --/* Line 1806 of yacc.c */ --#line 430 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } -+ case 69: -+#line 420 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = -(yyvsp[0].integer); } -+#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 68: -- --/* Line 1806 of yacc.c */ --#line 431 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } -+ case 70: -+#line 421 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = ~(yyvsp[0].integer); } -+#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 71: -- --/* Line 1806 of yacc.c */ --#line 437 "dtc-parser.y" -- { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } -+#line 422 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = !(yyvsp[0].integer); } -+#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 72: -- --/* Line 1806 of yacc.c */ --#line 438 "dtc-parser.y" -- { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = empty_data; -+ } -+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 73: -- --/* Line 1806 of yacc.c */ --#line 439 "dtc-parser.y" -- { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } -+#line 431 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); -+ } -+#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 74: -- --/* Line 1806 of yacc.c */ --#line 444 "dtc-parser.y" -+#line 435 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = empty_data; -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: -- --/* Line 1806 of yacc.c */ --#line 448 "dtc-parser.y" -+#line 442 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); -+ (yyval.nodelist) = NULL; - } -+#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: -- --/* Line 1806 of yacc.c */ --#line 452 "dtc-parser.y" -+#line 446 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } -+#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: -- --/* Line 1806 of yacc.c */ --#line 459 "dtc-parser.y" -+#line 450 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = NULL; -+ ERROR(&(yylsp[0]), "Properties must precede subnodes"); -+ YYERROR; - } -+#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: -- --/* Line 1806 of yacc.c */ --#line 463 "dtc-parser.y" -+#line 458 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); -+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } -+#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: -- --/* Line 1806 of yacc.c */ --#line 467 "dtc-parser.y" -+#line 462 "dtc-parser.y" /* yacc.c:1646 */ - { -- ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); -- YYERROR; -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } -+#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 80: -- --/* Line 1806 of yacc.c */ --#line 475 "dtc-parser.y" -+#line 466 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); -+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[0].node); - } -+#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 81: - --/* Line 1806 of yacc.c */ --#line 479 "dtc-parser.y" -- { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -- } -- break; -- -- case 82: -- --/* Line 1806 of yacc.c */ --#line 483 "dtc-parser.y" -- { -- add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.node) = (yyvsp[(2) - (2)].node); -- } -- break; -- -- -- --/* Line 1806 of yacc.c */ --#line 2235 "dtc-parser.tab.c" -+#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2254,7 +2036,7 @@ yyreduce: - *++yyvsp = yyval; - *++yylsp = yyloc; - -- /* Now `shift' the result of the reduction. Determine what state -+ /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2269,9 +2051,9 @@ yyreduce: - goto yynewstate; - - --/*------------------------------------. --| yyerrlab -- here on detecting error | --`------------------------------------*/ -+/*--------------------------------------. -+| yyerrlab -- here on detecting error. | -+`--------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2322,20 +2104,20 @@ yyerrlab: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval, &yylloc); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2355,7 +2137,7 @@ yyerrorlab: - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2368,35 +2150,37 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -+ YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp, yylsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of -@@ -2425,7 +2209,7 @@ yyabortlab: - yyresult = 1; - goto yyreturn; - --#if !defined(yyoverflow) || YYERROR_VERBOSE -+#if !defined yyoverflow || YYERROR_VERBOSE - /*-------------------------------------------------. - | yyexhaustedlab -- memory exhaustion comes here. | - `-------------------------------------------------*/ -@@ -2444,14 +2228,14 @@ yyreturn: - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp, yylsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2462,18 +2246,12 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- /* Make sure YYID is used. */ -- return YYID (yyresult); -+ return yyresult; - } -- -- -- --/* Line 2067 of yacc.c */ --#line 489 "dtc-parser.y" -+#line 472 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) - { - ERROR(&yylloc, "%s", s); - } -- -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 0b22bbb..30867c6 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.5. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,50 +26,55 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -+/* Debug traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+#if YYDEBUG -+extern int yydebug; -+#endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_PLUGIN = 259, -- DT_MEMRESERVE = 260, -- DT_LSHIFT = 261, -- DT_RSHIFT = 262, -- DT_LE = 263, -- DT_GE = 264, -- DT_EQ = 265, -- DT_NE = 266, -- DT_AND = 267, -- DT_OR = 268, -- DT_BITS = 269, -- DT_DEL_PROP = 270, -- DT_DEL_NODE = 271, -- DT_PROPNODENAME = 272, -- DT_LITERAL = 273, -- DT_CHAR_LITERAL = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_LSHIFT = 260, -+ DT_RSHIFT = 261, -+ DT_LE = 262, -+ DT_GE = 263, -+ DT_EQ = 264, -+ DT_NE = 265, -+ DT_AND = 266, -+ DT_OR = 267, -+ DT_BITS = 268, -+ DT_DEL_PROP = 269, -+ DT_DEL_NODE = 270, -+ DT_PROPNODENAME = 271, -+ DT_LITERAL = 272, -+ DT_CHAR_LITERAL = 273, -+ DT_BYTE = 274, -+ DT_STRING = 275, -+ DT_LABEL = 276, -+ DT_REF = 277, -+ DT_INCBIN = 278 -+ }; - #endif - -- -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { -- --/* Line 2068 of yacc.c */ --#line 39 "dtc-parser.y" -+#line 38 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; -@@ -87,32 +92,30 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; -- -- - --/* Line 2068 of yacc.c */ --#line 96 "dtc-parser.tab.h" --} YYSTYPE; -+#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- -+/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --} YYLTYPE; --# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+}; - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - -+ -+extern YYSTYPE yylval; - extern YYLTYPE yylloc; -+int yyparse (void); - -+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 56b9c15..5a897e3 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,7 +19,6 @@ - */ - %{ - #include --#include - - #include "dtc.h" - #include "srcpos.h" -@@ -53,11 +52,9 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; - } - - %token DT_V1 --%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -74,7 +71,6 @@ extern bool treesource_error; - - %type propdata - %type propdataprefix --%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -105,23 +101,10 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' plugindecl memreserves devicetree -+ DT_V1 ';' memreserves devicetree - { -- $5->is_plugin = $3; -- $5->is_root = 1; -- the_boot_info = build_boot_info($4, $5, -- guess_boot_cpuid($5)); -- } -- ; -- --plugindecl: -- /* empty */ -- { -- $$ = 0; -- } -- | DT_PLUGIN ';' -- { -- $$ = 1; -+ the_boot_info = build_boot_info($3, $4, -+ guess_boot_cpuid($4)); - } - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 0cbb14c..8c4add6 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,7 +29,6 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ --int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -52,7 +51,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -70,7 +69,6 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -- {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -101,7 +99,6 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -- "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -189,9 +186,7 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- case '@': -- symbol_fixup_support = 1; -- break; -+ - case 'h': - usage(NULL); - default: -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index fe45748..56212c8 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -54,7 +54,6 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ --extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -133,25 +132,6 @@ struct label { - struct label *next; - }; - --struct fixup_entry { -- int offset; -- struct node *node; -- struct property *prop; -- struct fixup_entry *next; --}; -- --struct fixup { -- char *ref; -- struct fixup_entry *entries; -- struct fixup *next; --}; -- --struct symbol { -- struct label *label; -- struct node *node; -- struct symbol *next; --}; -- - struct property { - bool deleted; - char *name; -@@ -178,12 +158,6 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -- -- int is_root; -- int is_plugin; -- struct fixup *fixups; -- struct symbol *symbols; -- struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -207,18 +181,6 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - --#define for_each_fixup(n, f) \ -- for ((f) = (n)->fixups; (f); (f) = (f)->next) -- --#define for_each_fixup_entry(f, fe) \ -- for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -- --#define for_each_symbol(n, s) \ -- for ((s) = (n)->symbols; (s); (s) = (s)->next) -- --#define for_each_local_fixup_entry(n, fe) \ -- for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -- - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index f439b40..bd99fa2 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -262,12 +262,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - struct property *prop; - struct node *child; - bool seen_name_prop = false; -- struct symbol *sym; -- struct fixup *f; -- struct fixup_entry *fe; -- char *name, *s; -- const char *fullpath; -- int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -282,6 +276,8 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -+ int nameoff; -+ - if (streq(prop->name, "name")) - seen_name_prop = true; - -@@ -314,139 +310,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -- if (!symbol_fixup_support) -- goto no_symbols; -- -- /* add the symbol nodes (if any) */ -- if (tree->symbols) { -- -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__symbols__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- for_each_symbol(tree, sym) { -- -- vallen = strlen(sym->node->fullpath); -- -- nameoff = stringtable_insert(strbuf, sym->label->label); -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, sym->node->fullpath, -- strlen(sym->node->fullpath)); -- emit->align(etarget, sizeof(cell_t)); -- } -- -- emit->endnode(etarget, NULL); -- } -- -- /* add the fixup nodes */ -- if (tree->fixups) { -- -- /* emit the external fixups */ -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__fixups__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- for_each_fixup(tree, f) { -- -- namesz = 0; -- for_each_fixup_entry(f, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- namesz += strlen(fullpath) + 1; -- namesz += strlen(fe->prop->name) + 1; -- namesz += 32; /* space for : + '\0' */ -- } -- -- name = xmalloc(namesz); -- -- s = name; -- for_each_fixup_entry(f, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- snprintf(s, name + namesz - s, "%s:%s:%d", -- fullpath, -- fe->prop->name, fe->offset); -- s += strlen(s) + 1; -- } -- -- nameoff = stringtable_insert(strbuf, f->ref); -- vallen = s - name - 1; -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, name, vallen); -- emit->align(etarget, sizeof(cell_t)); -- -- free(name); -- } -- -- emit->endnode(etarget, tree->labels); -- } -- -- /* add the local fixup property */ -- if (tree->local_fixups) { -- -- /* emit the external fixups */ -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__local_fixups__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- namesz = 0; -- for_each_local_fixup_entry(tree, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- namesz += strlen(fullpath) + 1; -- namesz += strlen(fe->prop->name) + 1; -- namesz += 32; /* space for : + '\0' */ -- } -- -- name = xmalloc(namesz); -- -- s = name; -- for_each_local_fixup_entry(tree, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- snprintf(s, name + namesz - s, "%s:%s:%d", -- fullpath, fe->prop->name, -- fe->offset); -- s += strlen(s) + 1; -- } -- -- nameoff = stringtable_insert(strbuf, "fixup"); -- vallen = s - name - 1; -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, name, vallen); -- emit->align(etarget, sizeof(cell_t)); -- -- free(name); -- -- emit->endnode(etarget, tree->labels); -- } -- --no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 86b7338..5b8c7d5 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" -+#define DTC_VERSION "DTC 1.4.1-g9d3649bd" - -From 4db35c3559c7b70c617593f51cdde1e6a9f75376 Mon Sep 17 00:00:00 2001 +From 440679f12679191111976b233adfeec72263860e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 10 Aug 2015 09:49:15 +0100 -Subject: [PATCH 172/251] scripts/dtc: Update to upstream version 1.4.1 +Subject: [PATCH 096/114] scripts/dtc: Update to upstream version 1.4.1 Includes the new localfixups format. Signed-off-by: Phil Elwell --- - scripts/dtc/checks.c | 105 ++++- + scripts/dtc/checks.c | 105 +++++- scripts/dtc/dtc-lexer.l | 5 + - scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++++++++++------------ - scripts/dtc/dtc-parser.tab.c_shipped | 722 ++++++++++++++++++----------------- + scripts/dtc/dtc-lexer.lex.c_shipped | 537 +++++++++++++------------- + scripts/dtc/dtc-parser.tab.c_shipped | 714 ++++++++++++++++++----------------- scripts/dtc/dtc-parser.tab.h_shipped | 46 +-- scripts/dtc/dtc-parser.y | 22 +- scripts/dtc/dtc.c | 9 +- scripts/dtc/dtc.h | 40 ++ scripts/dtc/flattree.c | 202 ++++++++++ scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1021 insertions(+), 622 deletions(-) + 10 files changed, 1028 insertions(+), 654 deletions(-) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index e81a8c7..540a3ea 100644 +index 0c03ac9..b369c5e 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -458,6 +458,8 @@ static void fixup_phandle_references(struct check *c, struct node *dt, @@ -154415,10 +128472,10 @@ index e81a8c7..540a3ea 100644 }; diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 0ee1caf..dd44ba2 100644 +index 790fbf6..40bbc87 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l -@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); +@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...); return DT_V1; } @@ -154431,7 +128488,7 @@ index 0ee1caf..dd44ba2 100644 DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 11cd78e..1518525 100644 +index ba525c2..1518525 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped @@ -9,7 +9,7 @@ @@ -154941,10 +128998,85 @@ index 11cd78e..1518525 100644 yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); -@@ -1007,23 +1008,31 @@ case 5: +@@ -951,39 +952,31 @@ case 2: YY_RULE_SETUP - #line 116 "dtc-lexer.l" + #line 75 "dtc-lexer.l" { +- char *line, *fnstart, *fnend; +- struct data fn; ++ char *line, *tmp, *fn; + /* skip text before line # */ + line = yytext; + while (!isdigit((unsigned char)*line)) + line++; +- +- /* regexp ensures that first and list " +- * in the whole yytext are those at +- * beginning and end of the filename string */ +- fnstart = memchr(yytext, '"', yyleng); +- for (fnend = yytext + yyleng - 1; +- *fnend != '"'; fnend--) +- ; +- assert(fnstart && fnend && (fnend > fnstart)); +- +- fn = data_copy_escape_string(fnstart + 1, +- fnend - fnstart - 1); +- +- /* Don't allow nuls in filenames */ +- if (memchr(fn.val, '\0', fn.len - 1)) +- lexical_error("nul in line number directive"); +- ++ /* skip digits in line # */ ++ tmp = line; ++ while (!isspace((unsigned char)*tmp)) ++ tmp++; ++ /* "NULL"-terminate line # */ ++ *tmp = '\0'; ++ /* start of filename */ ++ fn = strchr(tmp + 1, '"') + 1; ++ /* strip trailing " from filename */ ++ tmp = strchr(fn, '"'); ++ *tmp = 0; + /* -1 since #line is the number of the next line */ +- srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); +- data_free(fn); ++ srcpos_set_line(xstrdup(fn), atoi(line) - 1); + } + YY_BREAK + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(BYTESTRING): + case YY_STATE_EOF(PROPNODENAME): + case YY_STATE_EOF(V1): +-#line 104 "dtc-lexer.l" ++#line 96 "dtc-lexer.l" + { + if (!pop_input_file()) { + yyterminate(); +@@ -993,7 +986,7 @@ case YY_STATE_EOF(V1): + case 3: + /* rule 3 can match eol */ + YY_RULE_SETUP +-#line 110 "dtc-lexer.l" ++#line 102 "dtc-lexer.l" + { + DPRINT("String: %s\n", yytext); + yylval.data = data_copy_escape_string(yytext+1, +@@ -1003,7 +996,7 @@ YY_RULE_SETUP + YY_BREAK + case 4: + YY_RULE_SETUP +-#line 117 "dtc-lexer.l" ++#line 109 "dtc-lexer.l" + { + DPRINT("Keyword: /dts-v1/\n"); + dts_version = 1; +@@ -1013,25 +1006,33 @@ YY_RULE_SETUP + YY_BREAK + case 5: + YY_RULE_SETUP +-#line 124 "dtc-lexer.l" ++#line 116 "dtc-lexer.l" ++{ + DPRINT("Keyword: /plugin/\n"); + return DT_PLUGIN; + } @@ -154952,7 +129084,7 @@ index 11cd78e..1518525 100644 +case 6: +YY_RULE_SETUP +#line 121 "dtc-lexer.l" -+{ + { DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; @@ -154961,7 +129093,7 @@ index 11cd78e..1518525 100644 -case 6: +case 7: YY_RULE_SETUP --#line 122 "dtc-lexer.l" +-#line 130 "dtc-lexer.l" +#line 127 "dtc-lexer.l" { DPRINT("Keyword: /bits/\n"); @@ -154972,48 +129104,60 @@ index 11cd78e..1518525 100644 -case 7: +case 8: YY_RULE_SETUP --#line 128 "dtc-lexer.l" +-#line 136 "dtc-lexer.l" +#line 133 "dtc-lexer.l" { DPRINT("Keyword: /delete-property/\n"); DPRINT("\n"); -@@ -1031,9 +1040,9 @@ YY_RULE_SETUP +@@ -1039,9 +1040,9 @@ YY_RULE_SETUP return DT_DEL_PROP; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP --#line 135 "dtc-lexer.l" +-#line 143 "dtc-lexer.l" +#line 140 "dtc-lexer.l" { DPRINT("Keyword: /delete-node/\n"); DPRINT("\n"); -@@ -1041,9 +1050,9 @@ YY_RULE_SETUP +@@ -1049,9 +1050,9 @@ YY_RULE_SETUP return DT_DEL_NODE; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP --#line 142 "dtc-lexer.l" +-#line 150 "dtc-lexer.l" +#line 147 "dtc-lexer.l" { DPRINT("Label: %s\n", yytext); yylval.labelref = xstrdup(yytext); -@@ -1051,9 +1060,9 @@ YY_RULE_SETUP +@@ -1059,9 +1060,9 @@ YY_RULE_SETUP return DT_LABEL; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP --#line 149 "dtc-lexer.l" +-#line 157 "dtc-lexer.l" +#line 154 "dtc-lexer.l" { char *e; DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1073,10 +1082,10 @@ YY_RULE_SETUP +@@ -1069,10 +1070,7 @@ YY_RULE_SETUP + errno = 0; + yylval.integer = strtoull(yytext, &e, 0); + +- if (*e && e[strspn(e, "UL")]) { +- lexical_error("Bad integer literal '%s'", +- yytext); +- } ++ assert(!(*e) || !e[strspn(e, "UL")]); + + if (errno == ERANGE) + lexical_error("Integer literal '%s' out of range", +@@ -1084,10 +1082,10 @@ YY_RULE_SETUP return DT_LITERAL; } YY_BREAK @@ -155022,19 +129166,19 @@ index 11cd78e..1518525 100644 +case 12: +/* rule 12 can match eol */ YY_RULE_SETUP --#line 168 "dtc-lexer.l" +-#line 179 "dtc-lexer.l" +#line 173 "dtc-lexer.l" { struct data d; DPRINT("Character literal: %s\n", yytext); -@@ -1098,18 +1107,18 @@ YY_RULE_SETUP +@@ -1109,18 +1107,18 @@ YY_RULE_SETUP return DT_CHAR_LITERAL; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP --#line 189 "dtc-lexer.l" +-#line 200 "dtc-lexer.l" +#line 194 "dtc-lexer.l" { /* label reference */ DPRINT("Ref: %s\n", yytext+1); @@ -155045,19 +129189,19 @@ index 11cd78e..1518525 100644 -case 13: +case 14: YY_RULE_SETUP --#line 195 "dtc-lexer.l" +-#line 206 "dtc-lexer.l" +#line 200 "dtc-lexer.l" { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); -@@ -1117,27 +1126,27 @@ YY_RULE_SETUP +@@ -1128,27 +1126,27 @@ YY_RULE_SETUP return DT_REF; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP --#line 202 "dtc-lexer.l" +-#line 213 "dtc-lexer.l" +#line 207 "dtc-lexer.l" { yylval.byte = strtol(yytext, NULL, 16); @@ -155068,7 +129212,7 @@ index 11cd78e..1518525 100644 -case 15: +case 16: YY_RULE_SETUP --#line 208 "dtc-lexer.l" +-#line 219 "dtc-lexer.l" +#line 213 "dtc-lexer.l" { DPRINT("/BYTESTRING\n"); @@ -155079,19 +129223,19 @@ index 11cd78e..1518525 100644 -case 16: +case 17: YY_RULE_SETUP --#line 214 "dtc-lexer.l" +-#line 225 "dtc-lexer.l" +#line 219 "dtc-lexer.l" { DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1146,75 +1155,75 @@ YY_RULE_SETUP +@@ -1157,75 +1155,75 @@ YY_RULE_SETUP return DT_PROPNODENAME; } YY_BREAK -case 17: +case 18: YY_RULE_SETUP --#line 222 "dtc-lexer.l" +-#line 233 "dtc-lexer.l" +#line 227 "dtc-lexer.l" { DPRINT("Binary Include\n"); @@ -155101,13 +129245,13 @@ index 11cd78e..1518525 100644 -case 18: -/* rule 18 can match eol */ -YY_RULE_SETUP --#line 227 "dtc-lexer.l" +-#line 238 "dtc-lexer.l" -/* eat whitespace */ - YY_BREAK case 19: /* rule 19 can match eol */ YY_RULE_SETUP --#line 228 "dtc-lexer.l" +-#line 239 "dtc-lexer.l" -/* eat C-style comments */ +#line 232 "dtc-lexer.l" +/* eat whitespace */ @@ -155115,7 +129259,7 @@ index 11cd78e..1518525 100644 case 20: /* rule 20 can match eol */ YY_RULE_SETUP --#line 229 "dtc-lexer.l" +-#line 240 "dtc-lexer.l" -/* eat C++-style comments */ +#line 233 "dtc-lexer.l" +/* eat C-style comments */ @@ -155123,63 +129267,63 @@ index 11cd78e..1518525 100644 case 21: +/* rule 21 can match eol */ YY_RULE_SETUP --#line 231 "dtc-lexer.l" +-#line 242 "dtc-lexer.l" -{ return DT_LSHIFT; }; +#line 234 "dtc-lexer.l" +/* eat C++-style comments */ YY_BREAK case 22: YY_RULE_SETUP --#line 232 "dtc-lexer.l" +-#line 243 "dtc-lexer.l" -{ return DT_RSHIFT; }; +#line 236 "dtc-lexer.l" +{ return DT_LSHIFT; }; YY_BREAK case 23: YY_RULE_SETUP --#line 233 "dtc-lexer.l" +-#line 244 "dtc-lexer.l" -{ return DT_LE; }; +#line 237 "dtc-lexer.l" +{ return DT_RSHIFT; }; YY_BREAK case 24: YY_RULE_SETUP --#line 234 "dtc-lexer.l" +-#line 245 "dtc-lexer.l" -{ return DT_GE; }; +#line 238 "dtc-lexer.l" +{ return DT_LE; }; YY_BREAK case 25: YY_RULE_SETUP --#line 235 "dtc-lexer.l" +-#line 246 "dtc-lexer.l" -{ return DT_EQ; }; +#line 239 "dtc-lexer.l" +{ return DT_GE; }; YY_BREAK case 26: YY_RULE_SETUP --#line 236 "dtc-lexer.l" +-#line 247 "dtc-lexer.l" -{ return DT_NE; }; +#line 240 "dtc-lexer.l" +{ return DT_EQ; }; YY_BREAK case 27: YY_RULE_SETUP --#line 237 "dtc-lexer.l" +-#line 248 "dtc-lexer.l" -{ return DT_AND; }; +#line 241 "dtc-lexer.l" +{ return DT_NE; }; YY_BREAK case 28: YY_RULE_SETUP --#line 238 "dtc-lexer.l" +-#line 249 "dtc-lexer.l" -{ return DT_OR; }; +#line 242 "dtc-lexer.l" +{ return DT_AND; }; YY_BREAK case 29: YY_RULE_SETUP --#line 240 "dtc-lexer.l" +-#line 251 "dtc-lexer.l" +#line 243 "dtc-lexer.l" +{ return DT_OR; }; + YY_BREAK @@ -155189,23 +129333,23 @@ index 11cd78e..1518525 100644 { DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); -@@ -1230,12 +1239,12 @@ YY_RULE_SETUP +@@ -1241,12 +1239,12 @@ YY_RULE_SETUP return yytext[0]; } YY_BREAK -case 30: +case 31: YY_RULE_SETUP --#line 255 "dtc-lexer.l" +-#line 266 "dtc-lexer.l" +#line 260 "dtc-lexer.l" ECHO; YY_BREAK --#line 1239 "dtc-lexer.lex.c" +-#line 1250 "dtc-lexer.lex.c" +#line 1248 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { -@@ -1365,7 +1374,6 @@ ECHO; +@@ -1376,7 +1374,6 @@ ECHO; "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ @@ -155213,7 +129357,7 @@ index 11cd78e..1518525 100644 } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer -@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) +@@ -1432,21 +1429,21 @@ static int yy_get_next_buffer (void) else { @@ -155238,7 +129382,7 @@ index 11cd78e..1518525 100644 if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; -@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) +@@ -1477,7 +1474,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), @@ -155247,7 +129391,7 @@ index 11cd78e..1518525 100644 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } -@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) +@@ -1539,7 +1536,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; @@ -155256,7 +129400,7 @@ index 11cd78e..1518525 100644 yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) +@@ -1567,13 +1564,13 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; @@ -155273,7 +129417,7 @@ index 11cd78e..1518525 100644 } #ifndef YY_NO_INPUT -@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) +@@ -1600,7 +1597,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ @@ -155282,7 +129426,7 @@ index 11cd78e..1518525 100644 ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) -@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) +@@ -1874,7 +1871,7 @@ void yypop_buffer_state (void) */ static void yyensure_buffer_stack (void) { @@ -155291,7 +129435,7 @@ index 11cd78e..1518525 100644 if (!(yy_buffer_stack)) { -@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +@@ -1971,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ @@ -155306,7 +129450,7 @@ index 11cd78e..1518525 100644 /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; -@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) +@@ -2058,7 +2055,7 @@ FILE *yyget_out (void) /** Get the length of the current token. * */ @@ -155315,17 +129459,17 @@ index 11cd78e..1518525 100644 { return yyleng; } -@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) +@@ -2206,7 +2203,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" --#line 254 "dtc-lexer.l" +-#line 265 "dtc-lexer.l" +#line 260 "dtc-lexer.l" diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 116458c..844c462 100644 +index 31cec50..844c462 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped @@ -65,6 +65,7 @@ @@ -155487,9 +129631,9 @@ index 116458c..844c462 100644 - 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, - 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, - 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -- 465 +- 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, +- 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, +- 481 + 0, 108, 108, 118, 121, 129, 132, 139, 143, 151, + 155, 160, 171, 181, 196, 204, 207, 214, 218, 222, + 226, 234, 238, 242, 246, 250, 266, 276, 284, 287, @@ -156188,7 +130332,7 @@ index 116458c..844c462 100644 { uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); -@@ -1787,233 +1807,233 @@ yyreduce: +@@ -1787,247 +1807,233 @@ yyreduce: (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); } @@ -156372,166 +130516,161 @@ index 116458c..844c462 100644 break; - case 65: --#line 413 "dtc-parser.y" /* yacc.c:1646 */ +-#line 414 "dtc-parser.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); +- } else { +- ERROR(&(yyloc), "Division by zero"); +- (yyval.integer) = 0; +- } +- } +-#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ + case 67: +#line 429 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } --#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } +#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 66: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ +-#line 423 "dtc-parser.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); +- } else { +- ERROR(&(yyloc), "Division by zero"); +- (yyval.integer) = 0; +- } +- } +-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ + case 68: +#line 430 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } --#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } +#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 69: --#line 420 "dtc-parser.y" /* yacc.c:1646 */ + case 71: -+#line 436 "dtc-parser.y" /* yacc.c:1646 */ + #line 436 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = -(yyvsp[0].integer); } --#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 70: --#line 421 "dtc-parser.y" /* yacc.c:1646 */ + case 72: -+#line 437 "dtc-parser.y" /* yacc.c:1646 */ + #line 437 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 71: --#line 422 "dtc-parser.y" /* yacc.c:1646 */ + case 73: -+#line 438 "dtc-parser.y" /* yacc.c:1646 */ + #line 438 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = !(yyvsp[0].integer); } --#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 72: --#line 427 "dtc-parser.y" /* yacc.c:1646 */ + case 74: -+#line 443 "dtc-parser.y" /* yacc.c:1646 */ + #line 443 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = empty_data; } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 73: --#line 431 "dtc-parser.y" /* yacc.c:1646 */ + case 75: -+#line 447 "dtc-parser.y" /* yacc.c:1646 */ + #line 447 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); } --#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1975 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 74: --#line 435 "dtc-parser.y" /* yacc.c:1646 */ + case 76: -+#line 451 "dtc-parser.y" /* yacc.c:1646 */ + #line 451 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); } --#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 75: --#line 442 "dtc-parser.y" /* yacc.c:1646 */ + case 77: -+#line 458 "dtc-parser.y" /* yacc.c:1646 */ + #line 458 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.nodelist) = NULL; } --#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 76: --#line 446 "dtc-parser.y" /* yacc.c:1646 */ + case 78: -+#line 462 "dtc-parser.y" /* yacc.c:1646 */ + #line 462 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); } --#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 77: --#line 450 "dtc-parser.y" /* yacc.c:1646 */ + case 79: -+#line 466 "dtc-parser.y" /* yacc.c:1646 */ + #line 466 "dtc-parser.y" /* yacc.c:1646 */ { ERROR(&(yylsp[0]), "Properties must precede subnodes"); YYERROR; } --#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2008 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 78: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ + case 80: -+#line 474 "dtc-parser.y" /* yacc.c:1646 */ + #line 474 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); } --#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2016 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 79: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ + case 81: -+#line 478 "dtc-parser.y" /* yacc.c:1646 */ + #line 478 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); } --#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2024 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 80: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ + case 82: -+#line 482 "dtc-parser.y" /* yacc.c:1646 */ + #line 482 "dtc-parser.y" /* yacc.c:1646 */ { add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); (yyval.node) = (yyvsp[0].node); } --#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2033 "dtc-parser.tab.c" /* yacc.c:1646 */ break; --#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2037 "dtc-parser.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires -@@ -2248,7 +2268,7 @@ yyreturn: - #endif - return yyresult; - } --#line 472 "dtc-parser.y" /* yacc.c:1906 */ -+#line 488 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped index 30867c6..276d078 100644 --- a/scripts/dtc/dtc-parser.tab.h_shipped @@ -156605,7 +130744,7 @@ index 30867c6..276d078 100644 # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 5a897e3..d23927d 100644 +index 000873f..bd67bac 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -19,6 +19,7 @@ @@ -156663,10 +130802,10 @@ index 5a897e3..d23927d 100644 ; diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 8c4add6..91e91e7 100644 +index 5fa23c4..1f8c285 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ +@@ -31,6 +31,7 @@ int reservenum; /* Number of memory reservation slots */ int minsize; /* Minimum blob size */ int padsize; /* Additional padding to blob */ int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ @@ -156674,7 +130813,7 @@ index 8c4add6..91e91e7 100644 static void fill_fullpaths(struct node *tree, const char *prefix) { -@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) +@@ -53,7 +54,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) #define FDT_VERSION(version) _FDT_VERSION(version) #define _FDT_VERSION(version) #version static const char usage_synopsis[] = "dtc [options] "; @@ -156683,7 +130822,7 @@ index 8c4add6..91e91e7 100644 static struct option const usage_long_opts[] = { {"quiet", no_argument, NULL, 'q'}, {"in-format", a_argument, NULL, 'I'}, -@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { +@@ -71,6 +72,7 @@ static struct option const usage_long_opts[] = { {"phandle", a_argument, NULL, 'H'}, {"warning", a_argument, NULL, 'W'}, {"error", a_argument, NULL, 'E'}, @@ -156691,7 +130830,7 @@ index 8c4add6..91e91e7 100644 {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {NULL, no_argument, NULL, 0x0}, -@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { +@@ -101,6 +103,7 @@ static const char * const usage_opts_help[] = { "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", "\n\tEnable/disable warnings (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")", @@ -156699,7 +130838,7 @@ index 8c4add6..91e91e7 100644 "\n\tPrint this help and exit", "\n\tPrint version and exit", NULL, -@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) +@@ -233,7 +236,9 @@ int main(int argc, char *argv[]) case 'E': parse_checks_option(false, true, optarg); break; @@ -157003,5678 +131142,346 @@ index bd99fa2..2385137 100644 } diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 5b8c7d5..2595dfd 100644 +index 11d93e6..2595dfd 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd" +-#define DTC_VERSION "DTC 1.4.1-gb06e55c8" +#define DTC_VERSION "DTC 1.4.1-g25efc119" -From 04317cda235aa8627422fd132fe4bbb19036f4a5 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou -Date: Thu, 22 Oct 2015 23:30:04 +0300 -Subject: [PATCH 173/251] configfs: implement binary attributes - -ConfigFS lacked binary attributes up until now. This patch -introduces support for binary attributes in a somewhat similar -manner of sysfs binary attributes albeit with changes that -fit the configfs usage model. - -Problems that configfs binary attributes fix are everything that -requires a binary blob as part of the configuration of a resource, -such as bitstream loading for FPGAs, DTBs for dynamically created -devices etc. - -Look at Documentation/filesystems/configfs/configfs.txt for internals -and howto use them. - -This patch is against linux-next as of today that contains -Christoph's configfs rework. - -Signed-off-by: Pantelis Antoniou -[hch: folded a fix from Geert Uytterhoeven ] -[hch: a few tiny updates based on review feedback] -Signed-off-by: Christoph Hellwig ---- - Documentation/filesystems/configfs/configfs.txt | 57 +++++- - fs/configfs/configfs_internal.h | 14 +- - fs/configfs/dir.c | 18 +- - fs/configfs/file.c | 255 +++++++++++++++++++++++- - fs/configfs/inode.c | 2 +- - include/linux/configfs.h | 50 +++++ - 6 files changed, 374 insertions(+), 22 deletions(-) - -diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt -index af68efd..e5fe521 100644 ---- a/Documentation/filesystems/configfs/configfs.txt -+++ b/Documentation/filesystems/configfs/configfs.txt -@@ -51,15 +51,27 @@ configfs tree is always there, whether mounted on /config or not. - An item is created via mkdir(2). The item's attributes will also - appear at this time. readdir(3) can determine what the attributes are, - read(2) can query their default values, and write(2) can store new --values. Like sysfs, attributes should be ASCII text files, preferably --with only one value per file. The same efficiency caveats from sysfs --apply. Don't mix more than one attribute in one attribute file. -- --Like sysfs, configfs expects write(2) to store the entire buffer at --once. When writing to configfs attributes, userspace processes should --first read the entire file, modify the portions they wish to change, and --then write the entire buffer back. Attribute files have a maximum size --of one page (PAGE_SIZE, 4096 on i386). -+values. Don't mix more than one attribute in one attribute file. -+ -+There are two types of configfs attributes: -+ -+* Normal attributes, which similar to sysfs attributes, are small ASCII text -+files, with a maximum size of one page (PAGE_SIZE, 4096 on i386). Preferably -+only one value per file should be used, and the same caveats from sysfs apply. -+Configfs expects write(2) to store the entire buffer at once. When writing to -+normal configfs attributes, userspace processes should first read the entire -+file, modify the portions they wish to change, and then write the entire -+buffer back. -+ -+* Binary attributes, which are somewhat similar to sysfs binary attributes, -+but with a few slight changes to semantics. The PAGE_SIZE limitation does not -+apply, but the whole binary item must fit in single kernel vmalloc'ed buffer. -+The write(2) calls from user space are buffered, and the attributes' -+write_bin_attribute method will be invoked on the final close, therefore it is -+imperative for user-space to check the return code of close(2) in order to -+verify that the operation finished successfully. -+To avoid a malicious user OOMing the kernel, there's a per-binary attribute -+maximum buffer value. - - When an item needs to be destroyed, remove it with rmdir(2). An - item cannot be destroyed if any other item has a link to it (via -@@ -171,6 +183,7 @@ among other things. For that, it needs a type. - struct configfs_item_operations *ct_item_ops; - struct configfs_group_operations *ct_group_ops; - struct configfs_attribute **ct_attrs; -+ struct configfs_bin_attribute **ct_bin_attrs; - }; - - The most basic function of a config_item_type is to define what -@@ -201,6 +214,32 @@ be called whenever userspace asks for a read(2) on the attribute. If an - attribute is writable and provides a ->store method, that method will be - be called whenever userspace asks for a write(2) on the attribute. - -+[struct configfs_bin_attribute] -+ -+ struct configfs_attribute { -+ struct configfs_attribute cb_attr; -+ void *cb_private; -+ size_t cb_max_size; -+ }; -+ -+The binary attribute is used when the one needs to use binary blob to -+appear as the contents of a file in the item's configfs directory. -+To do so add the binary attribute to the NULL-terminated array -+config_item_type->ct_bin_attrs, and the item appears in configfs, the -+attribute file will appear with the configfs_bin_attribute->cb_attr.ca_name -+filename. configfs_bin_attribute->cb_attr.ca_mode specifies the file -+permissions. -+The cb_private member is provided for use by the driver, while the -+cb_max_size member specifies the maximum amount of vmalloc buffer -+to be used. -+ -+If binary attribute is readable and the config_item provides a -+ct_item_ops->read_bin_attribute() method, that method will be called -+whenever userspace asks for a read(2) on the attribute. The converse -+will happen for write(2). The reads/writes are bufferred so only a -+single read/write will occur; the attributes' need not concern itself -+with it. -+ - [struct config_group] - - A config_item cannot live in a vacuum. The only way one can be created -diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h -index b65d1ef..ccc31fa 100644 ---- a/fs/configfs/configfs_internal.h -+++ b/fs/configfs/configfs_internal.h -@@ -53,13 +53,14 @@ struct configfs_dirent { - #define CONFIGFS_ROOT 0x0001 - #define CONFIGFS_DIR 0x0002 - #define CONFIGFS_ITEM_ATTR 0x0004 -+#define CONFIGFS_ITEM_BIN_ATTR 0x0008 - #define CONFIGFS_ITEM_LINK 0x0020 - #define CONFIGFS_USET_DIR 0x0040 - #define CONFIGFS_USET_DEFAULT 0x0080 - #define CONFIGFS_USET_DROPPING 0x0100 - #define CONFIGFS_USET_IN_MKDIR 0x0200 - #define CONFIGFS_USET_CREATING 0x0400 --#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) -+#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR) - - extern struct mutex configfs_symlink_mutex; - extern spinlock_t configfs_dirent_lock; -@@ -72,6 +73,8 @@ extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, - extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *)); - - extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); -+extern int configfs_create_bin_file(struct config_item *, -+ const struct configfs_bin_attribute *); - extern int configfs_make_dirent(struct configfs_dirent *, - struct dentry *, void *, umode_t, int); - extern int configfs_dirent_is_ready(struct configfs_dirent *); -@@ -88,7 +91,7 @@ extern void configfs_release_fs(void); - extern struct rw_semaphore configfs_rename_sem; - extern const struct file_operations configfs_dir_operations; - extern const struct file_operations configfs_file_operations; --extern const struct file_operations bin_fops; -+extern const struct file_operations configfs_bin_file_operations; - extern const struct inode_operations configfs_dir_inode_operations; - extern const struct inode_operations configfs_root_inode_operations; - extern const struct inode_operations configfs_symlink_inode_operations; -@@ -119,6 +122,13 @@ static inline struct configfs_attribute * to_attr(struct dentry * dentry) - return ((struct configfs_attribute *) sd->s_element); - } - -+static inline struct configfs_bin_attribute *to_bin_attr(struct dentry *dentry) -+{ -+ struct configfs_attribute *attr = to_attr(dentry); -+ -+ return container_of(attr, struct configfs_bin_attribute, cb_attr); -+} -+ - static inline struct config_item *configfs_get_config_item(struct dentry *dentry) - { - struct config_item * item = NULL; -diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c -index a7a1b21..7ae97e8 100644 ---- a/fs/configfs/dir.c -+++ b/fs/configfs/dir.c -@@ -255,6 +255,12 @@ static void configfs_init_file(struct inode * inode) - inode->i_fop = &configfs_file_operations; - } - -+static void configfs_init_bin_file(struct inode *inode) -+{ -+ inode->i_size = 0; -+ inode->i_fop = &configfs_bin_file_operations; -+} -+ - static void init_symlink(struct inode * inode) - { - inode->i_op = &configfs_symlink_inode_operations; -@@ -423,7 +429,9 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den - spin_unlock(&configfs_dirent_lock); - - error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, -- configfs_init_file); -+ (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ? -+ configfs_init_bin_file : -+ configfs_init_file); - if (error) { - configfs_put(sd); - return error; -@@ -583,6 +591,7 @@ static int populate_attrs(struct config_item *item) - { - struct config_item_type *t = item->ci_type; - struct configfs_attribute *attr; -+ struct configfs_bin_attribute *bin_attr; - int error = 0; - int i; - -@@ -594,6 +603,13 @@ static int populate_attrs(struct config_item *item) - break; - } - } -+ if (t->ct_bin_attrs) { -+ for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) { -+ error = configfs_create_bin_file(item, bin_attr); -+ if (error) -+ break; -+ } -+ } - - if (error) - detach_attrs(item); -diff --git a/fs/configfs/file.c b/fs/configfs/file.c -index d39099e..3687187 100644 ---- a/fs/configfs/file.c -+++ b/fs/configfs/file.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -48,6 +49,10 @@ struct configfs_buffer { - struct configfs_item_operations * ops; - struct mutex mutex; - int needs_read_fill; -+ bool read_in_progress; -+ bool write_in_progress; -+ char *bin_buffer; -+ int bin_buffer_size; - }; - - -@@ -123,6 +128,87 @@ out: - return retval; - } - -+/** -+ * configfs_read_bin_file - read a binary attribute. -+ * @file: file pointer. -+ * @buf: buffer to fill. -+ * @count: number of bytes to read. -+ * @ppos: starting offset in file. -+ * -+ * Userspace wants to read a binary attribute file. The attribute -+ * descriptor is in the file's ->d_fsdata. The target item is in the -+ * directory's ->d_fsdata. -+ * -+ * We check whether we need to refill the buffer. If so we will -+ * call the attributes' attr->read() twice. The first time we -+ * will pass a NULL as a buffer pointer, which the attributes' method -+ * will use to return the size of the buffer required. If no error -+ * occurs we will allocate the buffer using vmalloc and call -+ * attr->read() again passing that buffer as an argument. -+ * Then we just copy to user-space using simple_read_from_buffer. -+ */ -+ -+static ssize_t -+configfs_read_bin_file(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct configfs_buffer *buffer = file->private_data; -+ struct dentry *dentry = file->f_path.dentry; -+ struct config_item *item = to_item(dentry->d_parent); -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ ssize_t retval = 0; -+ ssize_t len = min_t(size_t, count, PAGE_SIZE); -+ -+ mutex_lock(&buffer->mutex); -+ -+ /* we don't support switching read/write modes */ -+ if (buffer->write_in_progress) { -+ retval = -ETXTBSY; -+ goto out; -+ } -+ buffer->read_in_progress = 1; -+ -+ if (buffer->needs_read_fill) { -+ /* perform first read with buf == NULL to get extent */ -+ len = bin_attr->read(item, NULL, 0); -+ if (len <= 0) { -+ retval = len; -+ goto out; -+ } -+ -+ /* do not exceed the maximum value */ -+ if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) { -+ retval = -EFBIG; -+ goto out; -+ } -+ -+ buffer->bin_buffer = vmalloc(len); -+ if (buffer->bin_buffer == NULL) { -+ retval = -ENOMEM; -+ goto out; -+ } -+ buffer->bin_buffer_size = len; -+ -+ /* perform second read to fill buffer */ -+ len = bin_attr->read(item, buffer->bin_buffer, len); -+ if (len < 0) { -+ retval = len; -+ vfree(buffer->bin_buffer); -+ buffer->bin_buffer_size = 0; -+ buffer->bin_buffer = NULL; -+ goto out; -+ } -+ -+ buffer->needs_read_fill = 0; -+ } -+ -+ retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+out: -+ mutex_unlock(&buffer->mutex); -+ return retval; -+} -+ - - /** - * fill_write_buffer - copy buffer from userspace. -@@ -209,10 +295,80 @@ configfs_write_file(struct file *file, const char __user *buf, size_t count, lof - return len; - } - --static int check_perm(struct inode * inode, struct file * file) -+/** -+ * configfs_write_bin_file - write a binary attribute. -+ * @file: file pointer -+ * @buf: data to write -+ * @count: number of bytes -+ * @ppos: starting offset -+ * -+ * Writing to a binary attribute file is similar to a normal read. -+ * We buffer the consecutive writes (binary attribute files do not -+ * support lseek) in a continuously growing buffer, but we don't -+ * commit until the close of the file. -+ */ -+ -+static ssize_t -+configfs_write_bin_file(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct configfs_buffer *buffer = file->private_data; -+ struct dentry *dentry = file->f_path.dentry; -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ void *tbuf = NULL; -+ ssize_t len; -+ -+ mutex_lock(&buffer->mutex); -+ -+ /* we don't support switching read/write modes */ -+ if (buffer->read_in_progress) { -+ len = -ETXTBSY; -+ goto out; -+ } -+ buffer->write_in_progress = 1; -+ -+ /* buffer grows? */ -+ if (*ppos + count > buffer->bin_buffer_size) { -+ -+ if (bin_attr->cb_max_size && -+ *ppos + count > bin_attr->cb_max_size) { -+ len = -EFBIG; -+ } -+ -+ tbuf = vmalloc(*ppos + count); -+ if (tbuf == NULL) { -+ len = -ENOMEM; -+ goto out; -+ } -+ -+ /* copy old contents */ -+ if (buffer->bin_buffer) { -+ memcpy(tbuf, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+ vfree(buffer->bin_buffer); -+ } -+ -+ /* clear the new area */ -+ memset(tbuf + buffer->bin_buffer_size, 0, -+ *ppos + count - buffer->bin_buffer_size); -+ buffer->bin_buffer = tbuf; -+ buffer->bin_buffer_size = *ppos + count; -+ } -+ -+ len = simple_write_to_buffer(buffer->bin_buffer, -+ buffer->bin_buffer_size, ppos, buf, count); -+ if (len > 0) -+ *ppos += len; -+out: -+ mutex_unlock(&buffer->mutex); -+ return len; -+} -+ -+static int check_perm(struct inode * inode, struct file * file, int type) - { - struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); - struct configfs_attribute * attr = to_attr(file->f_path.dentry); -+ struct configfs_bin_attribute *bin_attr = NULL; - struct configfs_buffer * buffer; - struct configfs_item_operations * ops = NULL; - int error = 0; -@@ -220,6 +376,9 @@ static int check_perm(struct inode * inode, struct file * file) - if (!item || !attr) - goto Einval; - -+ if (type & CONFIGFS_ITEM_BIN_ATTR) -+ bin_attr = to_bin_attr(file->f_path.dentry); -+ - /* Grab the module reference for this attribute if we have one */ - if (!try_module_get(attr->ca_owner)) { - error = -ENODEV; -@@ -236,9 +395,14 @@ static int check_perm(struct inode * inode, struct file * file) - * and we must have a store method. - */ - if (file->f_mode & FMODE_WRITE) { -- if (!(inode->i_mode & S_IWUGO) || !attr->store) -+ if (!(inode->i_mode & S_IWUGO)) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_ATTR) && !attr->store) - goto Eaccess; - -+ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write) -+ goto Eaccess; - } - - /* File needs read support. -@@ -246,7 +410,13 @@ static int check_perm(struct inode * inode, struct file * file) - * must be a show method for it. - */ - if (file->f_mode & FMODE_READ) { -- if (!(inode->i_mode & S_IRUGO) || !attr->show) -+ if (!(inode->i_mode & S_IRUGO)) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_ATTR) && !attr->show) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read) - goto Eaccess; - } - -@@ -260,6 +430,8 @@ static int check_perm(struct inode * inode, struct file * file) - } - mutex_init(&buffer->mutex); - buffer->needs_read_fill = 1; -+ buffer->read_in_progress = 0; -+ buffer->write_in_progress = 0; - buffer->ops = ops; - file->private_data = buffer; - goto Done; -@@ -277,12 +449,7 @@ static int check_perm(struct inode * inode, struct file * file) - return error; - } - --static int configfs_open_file(struct inode * inode, struct file * filp) --{ -- return check_perm(inode,filp); --} -- --static int configfs_release(struct inode * inode, struct file * filp) -+static int configfs_release(struct inode *inode, struct file *filp) - { - struct config_item * item = to_item(filp->f_path.dentry->d_parent); - struct configfs_attribute * attr = to_attr(filp->f_path.dentry); -@@ -303,6 +470,47 @@ static int configfs_release(struct inode * inode, struct file * filp) - return 0; - } - -+static int configfs_open_file(struct inode *inode, struct file *filp) -+{ -+ return check_perm(inode, filp, CONFIGFS_ITEM_ATTR); -+} -+ -+static int configfs_open_bin_file(struct inode *inode, struct file *filp) -+{ -+ return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR); -+} -+ -+static int configfs_release_bin_file(struct inode *inode, struct file *filp) -+{ -+ struct configfs_buffer *buffer = filp->private_data; -+ struct dentry *dentry = filp->f_path.dentry; -+ struct config_item *item = to_item(dentry->d_parent); -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ ssize_t len = 0; -+ int ret; -+ -+ buffer->read_in_progress = 0; -+ -+ if (buffer->write_in_progress) { -+ buffer->write_in_progress = 0; -+ -+ len = bin_attr->write(item, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+ -+ /* vfree on NULL is safe */ -+ vfree(buffer->bin_buffer); -+ buffer->bin_buffer = NULL; -+ buffer->bin_buffer_size = 0; -+ buffer->needs_read_fill = 1; -+ } -+ -+ ret = configfs_release(inode, filp); -+ if (len < 0) -+ return len; -+ return ret; -+} -+ -+ - const struct file_operations configfs_file_operations = { - .read = configfs_read_file, - .write = configfs_write_file, -@@ -311,6 +519,14 @@ const struct file_operations configfs_file_operations = { - .release = configfs_release, - }; - -+const struct file_operations configfs_bin_file_operations = { -+ .read = configfs_read_bin_file, -+ .write = configfs_write_bin_file, -+ .llseek = NULL, /* bin file is not seekable */ -+ .open = configfs_open_bin_file, -+ .release = configfs_release_bin_file, -+}; -+ - /** - * configfs_create_file - create an attribute file for an item. - * @item: item we're creating for. -@@ -332,3 +548,24 @@ int configfs_create_file(struct config_item * item, const struct configfs_attrib - return error; - } - -+/** -+ * configfs_create_bin_file - create a binary attribute file for an item. -+ * @item: item we're creating for. -+ * @attr: atrribute descriptor. -+ */ -+ -+int configfs_create_bin_file(struct config_item *item, -+ const struct configfs_bin_attribute *bin_attr) -+{ -+ struct dentry *dir = item->ci_dentry; -+ struct configfs_dirent *parent_sd = dir->d_fsdata; -+ umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG; -+ int error = 0; -+ -+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL); -+ error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode, -+ CONFIGFS_ITEM_BIN_ATTR); -+ mutex_unlock(&dir->d_inode->i_mutex); -+ -+ return error; -+} -diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c -index eae8757..0cc810e 100644 ---- a/fs/configfs/inode.c -+++ b/fs/configfs/inode.c -@@ -218,7 +218,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd) - if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) - return sd->s_dentry->d_name.name; - -- if (sd->s_type & CONFIGFS_ITEM_ATTR) { -+ if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) { - attr = sd->s_element; - return attr->ca_name; - } -diff --git a/include/linux/configfs.h b/include/linux/configfs.h -index 758a029..f7300d0 100644 ---- a/include/linux/configfs.h -+++ b/include/linux/configfs.h -@@ -51,6 +51,7 @@ struct module; - struct configfs_item_operations; - struct configfs_group_operations; - struct configfs_attribute; -+struct configfs_bin_attribute; - struct configfs_subsystem; - - struct config_item { -@@ -84,6 +85,7 @@ struct config_item_type { - struct configfs_item_operations *ct_item_ops; - struct configfs_group_operations *ct_group_ops; - struct configfs_attribute **ct_attrs; -+ struct configfs_bin_attribute **ct_bin_attrs; - }; - - /** -@@ -154,6 +156,54 @@ static struct configfs_attribute _pfx##attr_##_name = { \ - .store = _pfx##_name##_store, \ - } - -+struct file; -+struct vm_area_struct; -+ -+struct configfs_bin_attribute { -+ struct configfs_attribute cb_attr; /* std. attribute */ -+ void *cb_private; /* for user */ -+ size_t cb_max_size; /* max core size */ -+ ssize_t (*read)(struct config_item *, void *, size_t); -+ ssize_t (*write)(struct config_item *, const void *, size_t); -+}; -+ -+#define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_bin_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO | S_IWUSR, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .read = _pfx##_name##_read, \ -+ .write = _pfx##_name##_write, \ -+} -+ -+#define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .read = _pfx##_name##_read, \ -+} -+ -+#define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IWUSR, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .write = _pfx##_name##_write, \ -+} -+ - /* - * If allow_link() exists, the item can symlink(2) out to other - * items. If the item is a group, it may support mkdir(2). - -From 15c5929aef0ebd49a3afc31a307b0fa3e24a2923 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou -Date: Wed, 3 Dec 2014 13:23:28 +0200 -Subject: [PATCH 174/251] OF: DT-Overlay configfs interface - -This is a port of Pantelis Antoniou's v3 port that makes use of the -new upstreamed configfs support for binary attributes. - -Original commit message: - -Add a runtime interface to using configfs for generic device tree overlay -usage. With it its possible to use device tree overlays without having -to use a per-platform overlay manager. - -Please see Documentation/devicetree/configfs-overlays.txt for more info. - -Changes since v2: -- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) -- Created a documentation entry -- Slight rewording in Kconfig - -Changes since v1: -- of_resolve() -> of_resolve_phandles(). - -Originally-signed-off-by: Pantelis Antoniou -Signed-off-by: Phil Elwell ---- - Documentation/devicetree/configfs-overlays.txt | 31 +++ - drivers/of/Kconfig | 7 + - drivers/of/Makefile | 1 + - drivers/of/configfs.c | 314 +++++++++++++++++++++++++ - 4 files changed, 353 insertions(+) - create mode 100644 Documentation/devicetree/configfs-overlays.txt - create mode 100644 drivers/of/configfs.c - -diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt -new file mode 100644 -index 0000000..5fa43e0 ---- /dev/null -+++ b/Documentation/devicetree/configfs-overlays.txt -@@ -0,0 +1,31 @@ -+Howto use the configfs overlay interface. -+ -+A device-tree configfs entry is created in /config/device-tree/overlays -+and and it is manipulated using standard file system I/O. -+Note that this is a debug level interface, for use by developers and -+not necessarily something accessed by normal users due to the -+security implications of having direct access to the kernel's device tree. -+ -+* To create an overlay you mkdir the directory: -+ -+ # mkdir /config/device-tree/overlays/foo -+ -+* Either you echo the overlay firmware file to the path property file. -+ -+ # echo foo.dtbo >/config/device-tree/overlays/foo/path -+ -+* Or you cat the contents of the overlay to the dtbo file -+ -+ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo -+ -+The overlay file will be applied, and devices will be created/destroyed -+as required. -+ -+To remove it simply rmdir the directory. -+ -+ # rmdir /config/device-tree/overlays/foo -+ -+The rationalle of the dual interface (firmware & direct copy) is that each is -+better suited to different use patterns. The firmware interface is what's -+intended to be used by hardware managers in the kernel, while the copy interface -+make sense for developers (since it avoids problems with namespaces). -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index e2a4841..7e5e6c4 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -112,4 +112,11 @@ config OF_OVERLAY - While this option is selected automatically when needed, you can - enable it manually to improve device tree unit test coverage. - -+config OF_CONFIGFS -+ bool "Device Tree Overlay ConfigFS interface" -+ select CONFIGFS_FS -+ select OF_OVERLAY -+ help -+ Enable a simple user-space driven DT overlay interface. -+ - endif # OF -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index 156c072..46c8f57 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,4 +1,5 @@ - obj-y = base.o device.o platform.o -+obj-$(CONFIG_OF_CONFIGFS) += configfs.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o - obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o -diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c -new file mode 100644 -index 0000000..7b66deb ---- /dev/null -+++ b/drivers/of/configfs.c -@@ -0,0 +1,314 @@ -+/* -+ * Configfs entries for device-tree -+ * -+ * Copyright (C) 2013 - Pantelis Antoniou -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "of_private.h" -+ -+struct cfs_overlay_item { -+ struct config_item item; -+ -+ char path[PATH_MAX]; -+ -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int ov_id; -+ -+ void *dtbo; -+ int dtbo_size; -+}; -+ -+static int create_overlay(struct cfs_overlay_item *overlay, void *blob) -+{ -+ int err; -+ -+ /* unflatten the tree */ -+ of_fdt_unflatten_tree(blob, &overlay->overlay); -+ if (overlay->overlay == NULL) { -+ pr_err("%s: failed to unflatten tree\n", __func__); -+ err = -EINVAL; -+ goto out_err; -+ } -+ pr_debug("%s: unflattened OK\n", __func__); -+ -+ /* mark it as detached */ -+ of_node_set_flag(overlay->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(overlay->overlay); -+ if (err != 0) { -+ pr_err("%s: Failed to resolve tree\n", __func__); -+ goto out_err; -+ } -+ pr_debug("%s: resolved OK\n", __func__); -+ -+ err = of_overlay_create(overlay->overlay); -+ if (err < 0) { -+ pr_err("%s: Failed to create overlay (err=%d)\n", -+ __func__, err); -+ goto out_err; -+ } -+ overlay->ov_id = err; -+ -+out_err: -+ return err; -+} -+ -+static inline struct cfs_overlay_item *to_cfs_overlay_item( -+ struct config_item *item) -+{ -+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; -+} -+ -+static ssize_t cfs_overlay_item_path_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ return sprintf(page, "%s\n", overlay->path); -+} -+ -+static ssize_t cfs_overlay_item_path_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ const char *p = page; -+ char *s; -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); -+ overlay->path[sizeof(overlay->path) - 1] = '\0'; -+ -+ /* strip trailing newlines */ -+ s = overlay->path + strlen(overlay->path); -+ while (s > overlay->path && *--s == '\n') -+ *s = '\0'; -+ -+ pr_debug("%s: path is '%s'\n", __func__, overlay->path); -+ -+ err = request_firmware(&overlay->fw, overlay->path, NULL); -+ if (err != 0) -+ goto out_err; -+ -+ err = create_overlay(overlay, (void *)overlay->fw->data); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ -+ release_firmware(overlay->fw); -+ overlay->fw = NULL; -+ -+ overlay->path[0] = '\0'; -+ return err; -+} -+ -+static ssize_t cfs_overlay_item_status_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ return sprintf(page, "%s\n", -+ overlay->ov_id >= 0 ? "applied" : "unapplied"); -+} -+ -+CONFIGFS_ATTR(cfs_overlay_item_, path); -+CONFIGFS_ATTR_RO(cfs_overlay_item_, status); -+ -+static struct configfs_attribute *cfs_overlay_attrs[] = { -+ &cfs_overlay_item_attr_path, -+ &cfs_overlay_item_attr_status, -+ NULL, -+}; -+ -+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, -+ void *buf, size_t max_count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ pr_debug("%s: buf=%p max_count=%u\n", __func__, -+ buf, max_count); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ /* copy if buffer provided */ -+ if (buf != NULL) { -+ /* the buffer must be large enough */ -+ if (overlay->dtbo_size > max_count) -+ return -ENOSPC; -+ -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ } -+ -+ return overlay->dtbo_size; -+} -+ -+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, -+ const void *buf, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy the contents */ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) -+ return -ENOMEM; -+ -+ overlay->dtbo_size = count; -+ -+ err = create_overlay(overlay, overlay->dtbo); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ return err; -+} -+ -+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); -+ -+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { -+ &cfs_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+static void cfs_overlay_release(struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ if (overlay->ov_id >= 0) -+ of_overlay_destroy(overlay->ov_id); -+ if (overlay->fw) -+ release_firmware(overlay->fw); -+ /* kfree with NULL is safe */ -+ kfree(overlay->dtbo); -+ kfree(overlay); -+} -+ -+static struct configfs_item_operations cfs_overlay_item_ops = { -+ .release = cfs_overlay_release, -+}; -+ -+static struct config_item_type cfs_overlay_type = { -+ .ct_item_ops = &cfs_overlay_item_ops, -+ .ct_attrs = cfs_overlay_attrs, -+ .ct_bin_attrs = cfs_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *cfs_overlay_group_make_item( -+ struct config_group *group, const char *name) -+{ -+ struct cfs_overlay_item *overlay; -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->ov_id = -1; -+ -+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); -+ return &overlay->item; -+} -+ -+static void cfs_overlay_group_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ config_item_put(&overlay->item); -+} -+ -+static struct configfs_group_operations overlays_ops = { -+ .make_item = cfs_overlay_group_make_item, -+ .drop_item = cfs_overlay_group_drop_item, -+}; -+ -+static struct config_item_type overlays_type = { -+ .ct_group_ops = &overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_group_operations of_cfs_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type of_cfs_type = { -+ .ct_group_ops = &of_cfs_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group of_cfs_overlay_group; -+ -+struct config_group *of_cfs_def_groups[] = { -+ &of_cfs_overlay_group, -+ NULL -+}; -+ -+static struct configfs_subsystem of_cfs_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &of_cfs_type, -+ }, -+ .default_groups = of_cfs_def_groups, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), -+}; -+ -+static int __init of_cfs_init(void) -+{ -+ int ret; -+ -+ pr_info("%s\n", __func__); -+ -+ config_group_init(&of_cfs_subsys.su_group); -+ config_group_init_type_name(&of_cfs_overlay_group, "overlays", -+ &overlays_type); -+ -+ ret = configfs_register_subsystem(&of_cfs_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto out; -+ } -+ pr_info("%s: OK\n", __func__); -+out: -+ return ret; -+} -+late_initcall(of_cfs_init); - -From ee377daa5f1e9811fa04bbf254f4930ed5c7c9c5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 13 Mar 2015 12:43:36 +0000 -Subject: [PATCH 175/251] Protect __release_resource against resources without - parents - -Without this patch, removing a device tree overlay can crash here. - -Signed-off-by: Phil Elwell ---- - kernel/resource.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/kernel/resource.c b/kernel/resource.c -index 249b1eb..eb973a5 100644 ---- a/kernel/resource.c -+++ b/kernel/resource.c -@@ -237,6 +237,12 @@ static int __release_resource(struct resource *old) - { - struct resource *tmp, **p; - -+ if (!old->parent) { -+ WARN(old->sibling, "sibling but no parent"); -+ if (old->sibling) -+ return -EINVAL; -+ return 0; -+ } - p = &old->parent->child; - for (;;) { - tmp = *p; - -From fa4cb194572f56c3ab11913af77d31084b8f40e5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 13 Mar 2015 20:00:21 +0000 -Subject: [PATCH 176/251] BCM270X_DT: Add a .dtbo target, use for overlays - -Change the filenames and extensions to keep the pre-DDT style of -overlay (-overlay.dtb) distinct from new ones that use a -different style of local fixups (.dtbo), and to match other -platforms. - -The RPi firmware uses the DDTK trailer atom to choose which type of -overlay to use for each kernel. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/.gitignore | 2 +- - arch/arm/boot/dts/overlays/Makefile | 135 +++++++++++++++++------------------- - scripts/Makefile.lib | 10 +++ - 3 files changed, 76 insertions(+), 71 deletions(-) - -diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore -index 3c79f85..eaaeb17 100644 ---- a/arch/arm/boot/.gitignore -+++ b/arch/arm/boot/.gitignore -@@ -3,4 +3,4 @@ zImage - xipImage - bootpImage - uImage --*.dtb -+*.dtb* -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 687cc7c..d81fa09 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -12,78 +12,73 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif - --dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dwc2-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dwc-otg-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c0-bcm2708-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c1-bcm2708-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-backlight-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-1cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-2cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-3cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-1cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-2cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-3cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += vc4-kms-v3d-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += enc28j60.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += gpio-ir.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += gpio-poweroff.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dacplus.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += lirc-rpi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += piscreen2r.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pitft28-capacitive.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-display.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-ft5406.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-proto.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-sense.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdhost.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdtweak.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi-dev.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi-nand.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-1cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-2cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-3cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-1cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-2cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-3cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi-gpio35-39.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += tinylcd35.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += uart1.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo - - targets += dtbs dtbs_install --targets += $(dtb-y) -+targets += $(dtbo-y) - - endif - --always := $(dtb-y) --clean-files := *.dtb -- --# Enable fixups to support overlays on BCM2708 platforms --ifeq ($(RPI_DT_OVERLAYS),y) -- DTC_FLAGS ?= -@ --endif -+always := $(dtbo-y) -+clean-files := *.dtbo -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 79e8661..7209d62 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -292,6 +292,16 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(obj)/%.dtb: $(src)/%.dts FORCE - $(call if_changed_dep,dtc) - -+quiet_cmd_dtco = DTCO $@ -+cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -+ $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ -+ -i $(dir $<) $(DTC_FLAGS) \ -+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ -+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -+ -+$(obj)/%.dtbo: $(src)/%-overlay.dts FORCE -+ $(call if_changed_dep,dtco) -+ - dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) - - # Bzip2 - -From 3c760a6a8f336bfb891214091b71bc3408c93b6f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 11:18:58 +0100 -Subject: [PATCH 177/251] scripts/knlinfo: Decode DDTK atom - -Show the DDTK atom as being a boolean. - -Signed-off-by: Phil Elwell ---- - scripts/knlinfo | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/scripts/knlinfo b/scripts/knlinfo -index b9ef124..263ec93 100755 ---- a/scripts/knlinfo -+++ b/scripts/knlinfo -@@ -16,6 +16,7 @@ my $trailer_magic = 'RPTL'; - - my %atom_formats = - ( -+ 'DDTK' => \&format_bool, - 'DTOK' => \&format_bool, - 'KVer' => \&format_string, - '270X' => \&format_bool, -@@ -148,7 +149,7 @@ sub format_atom - sub format_bool - { - my ($data) = @_; -- return unpack('V', $data) ? 'true' : 'false'; -+ return unpack('V', $data) ? 'y' : 'n'; - } - - sub format_int - -From 2db1009fef8b23bac3b3ae61dd1382bffb0827b1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 11:48:59 +0100 -Subject: [PATCH 178/251] Enable Dynamic Device Tree for bcmrpi_defconfig and - bcm2709_defconfig - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7793baf..0fff5a3 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -403,6 +403,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m -+CONFIG_OF_CONFIGFS=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1161,7 +1162,6 @@ CONFIG_NTFS_FS=m - CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f09be87..2db41e6 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -396,6 +396,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m -+CONFIG_OF_OVERLAY=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - -From efe315038fd3581998bf6c93f432ac6cf85bb53f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sun, 13 Mar 2016 16:14:44 +0000 -Subject: [PATCH 179/251] SQUASH: Add CONFIG_OF_CONFIGFS to bcmrpi_defconfig - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcmrpi_defconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 2db41e6..74149cf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -396,7 +396,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m --CONFIG_OF_OVERLAY=y -+CONFIG_OF_CONFIGFS=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1169,7 +1169,6 @@ CONFIG_NTFS_FS=m - CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m - -From 558d3a84b6363b021f77f138615cbf7b72c6f38c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 14 Mar 2016 16:56:54 +0000 -Subject: [PATCH 180/251] dts, kbuild: dtbs_install installs .dtbo files too - -Signed-off-by: Phil Elwell ---- - scripts/Makefile.dtbinst | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst -index 1c15717..43647b3 100644 ---- a/scripts/Makefile.dtbinst -+++ b/scripts/Makefile.dtbinst -@@ -29,6 +29,7 @@ ifeq ("$(dtbinst-root)", "$(obj)") - endif - - dtbinst-files := $(dtb-y) -+dtboinst-files := $(dtbo-y) - dtbinst-dirs := $(dts-dirs) - - # Helper targets for Installing DTBs into the boot directory -@@ -37,15 +38,18 @@ quiet_cmd_dtb_install = INSTALL $< - - install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) - --$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep -+$(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs): | __dtbs_install_prep - - $(dtbinst-files): %.dtb: $(obj)/%.dtb - $(call cmd,dtb_install,$(install-dir)) - -+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo -+ $(call cmd,dtb_install,$(install-dir)) -+ - $(dtbinst-dirs): - $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ - --PHONY += $(dtbinst-files) $(dtbinst-dirs) --__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) -+PHONY += $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) -+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) - - .PHONY: $(PHONY) - -From 3df4e691dcda317e661b026201c28db902be6830 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 14:10:29 +0000 -Subject: [PATCH 181/251] bcm2835-sdhost: Workaround for "slow" sectors - -Some cards have been seen to cause timeouts after certain sectors are -read. This workaround enforces a minimum delay between the stop after -reading one of those sectors and a subsequent data command. - -Using CMD23 (SET_BLOCK_COUNT) avoids this problem, so good cards will -not be penalised by this workaround. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 50 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 46 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 4cc4272..f43aae0 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -202,9 +202,12 @@ struct bcm2835_host { - int max_delay; /* maximum length of time spent waiting */ - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+ u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+ -+ u32 sectors; /* Cached card size in sectors */ - }; - - #if ENABLE_LOG -@@ -425,6 +428,7 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - bcm2835_sdhost_set_power(host, true); - mdelay(10); - host->clock = 0; -+ host->sectors = 0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); -@@ -880,6 +884,24 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ if (!host->sectors && host->mmc->card) { -+ struct mmc_card *card = host->mmc->card; -+ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -+ /* -+ * The EXT_CSD sector count is in number of 512 byte -+ * sectors. -+ */ -+ host->sectors = card->ext_csd.sectors; -+ } else { -+ /* -+ * The CSD capacity field is in units of read_blkbits. -+ * set_capacity takes units of 512 bytes. -+ */ -+ host->sectors = card->csd.capacity << -+ (card->csd.read_blkbits - 9); -+ } -+ } -+ - if (!host->dma_desc) { - /* Use PIO */ - int flags = SG_MITER_ATOMIC; -@@ -989,7 +1011,7 @@ bool bcm2835_sdhost_send_command(struct bcm2835_host *host, - - if (cmd->data) { - log_event("CMDD", cmd->data->blocks, cmd->data->blksz); -- if (host->delay_after_stop) { -+ if (host->delay_after_this_stop) { - struct timeval now; - int time_since_stop; - do_gettimeofday(&now); -@@ -998,12 +1020,32 @@ bool bcm2835_sdhost_send_command(struct bcm2835_host *host, - /* Possibly less than one second */ - time_since_stop = time_since_stop * 1000000 + - (now.tv_usec - host->stop_time.tv_usec); -- if (time_since_stop < host->delay_after_stop) -- udelay(host->delay_after_stop - -+ if (time_since_stop < -+ host->delay_after_this_stop) -+ udelay(host->delay_after_this_stop - - time_since_stop); - } - } - -+ host->delay_after_this_stop = host->delay_after_stop; -+ if ((cmd->data->flags & MMC_DATA_READ) && !host->use_sbc) { -+ /* See if read crosses one of the hazardous sectors */ -+ u32 first_blk, last_blk; -+ -+ /* Intentionally include the following sector because -+ without CMD23/SBC the read may run on. */ -+ first_blk = host->mrq->cmd->arg; -+ last_blk = first_blk + cmd->data->blocks; -+ -+ if (((last_blk >= (host->sectors - 64)) && -+ (first_blk <= (host->sectors - 64))) || -+ ((last_blk >= (host->sectors - 32)) && -+ (first_blk <= (host->sectors - 32)))) { -+ host->delay_after_this_stop = -+ max(250u, host->delay_after_stop); -+ } -+ } -+ - if (cmd->data->flags & MMC_DATA_WRITE) - sdcmd |= SDCMD_WRITE_CMD; - if (cmd->data->flags & MMC_DATA_READ) -@@ -1078,7 +1120,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - if (!host->use_busy) - bcm2835_sdhost_finish_command(host, NULL); - -- if (host->delay_after_stop) -+ if (host->delay_after_this_stop) - do_gettimeofday(&host->stop_time); - } - } else { - -From 16f0b8c220be3459c873578037994693c7e025d1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 15:49:16 +0000 -Subject: [PATCH 182/251] BCM270X_DT: Add labels to spidev nodes - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++-- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++-- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 4 ++-- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++-- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++-- - 5 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index d2d6fa0..00ea1b2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index d033ee4..2f8a718 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 8bcafb4..954896e 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -42,7 +42,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -50,7 +50,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index aca253f..66523d6 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 2cb7d43..1ce4ea2 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -110,7 +110,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -118,7 +118,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; - -From 320ed2194edfdcd5fcc93772a353b7480fd4aa5a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 16:27:26 +0000 -Subject: [PATCH 183/251] BCM270X_DT: Use spidev labels in overlays - ---- - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 11 +++++---- - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 11 +++++---- - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 22 ++++++++++------- - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 16 ++++++++----- - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 16 ++++++++----- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 22 ++++++++++------- - .../dts/overlays/pitft28-capacitive-overlay.dts | 17 +++++++------ - .../dts/overlays/pitft28-resistive-overlay.dts | 24 ++++++++++++------- - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 28 +++++++++++++--------- - 14 files changed, 174 insertions(+), 103 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -index 6a92cd1..edf2dc9 100644 ---- a/arch/arm/boot/dts/overlays/ads7846-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - ads7846_pins: ads7846_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index eab4052..880c753 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -14,10 +14,6 @@ - - status = "okay"; - -- spidev@0{ -- status = "disabled"; -- }; -- - lowpan0: at86rf233@0 { - compatible = "atmel,at86rf233"; - reg = <0>; -@@ -32,6 +28,13 @@ - }; - - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - lowpan0_pins: lowpan0_pins { -diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -index 8fae869..db8a8fe 100644 ---- a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -+++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -14,10 +14,6 @@ - - status = "okay"; - -- spidev@0{ -- status = "disabled"; -- }; -- - eth1: enc28j60@0{ - compatible = "microchip,enc28j60"; - reg = <0>; /* CE0 */ -@@ -32,6 +28,13 @@ - }; - - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - eth1_pins: eth1_pins { -diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -index 3cd3083..ac0f3c2 100644 ---- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - hy28a_pins: hy28a_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -index f774c4a..8018aeb 100644 ---- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - hy28b_pins: hy28b_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -index 398d59c..c96cdae 100755 ---- a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -12,14 +12,18 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- spidev@0{ -- status = "disabled"; -- }; - }; - }; - -- /* the interrupt pin of the can-controller */ - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - can0_pins: can0_pins { -@@ -30,7 +34,7 @@ - }; - - /* the clock/oscillator of the can-controller */ -- fragment@2 { -+ fragment@3 { - target-path = "/clocks"; - __overlay__ { - /* external oscillator of mcp2515 on SPI0.0 */ -@@ -43,7 +47,7 @@ - }; - - /* the spi config of the can-controller itself binding everything together */ -- fragment@3 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -index 6bef9ae..67bd0d9 100644 ---- a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -12,14 +12,18 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- spidev@1{ -- status = "disabled"; -- }; - }; - }; - -- /* the interrupt pin of the can-controller */ - fragment@1 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - can1_pins: can1_pins { -@@ -30,7 +34,7 @@ - }; - - /* the clock/oscillator of the can-controller */ -- fragment@2 { -+ fragment@3 { - target-path = "/clocks"; - __overlay__ { - /* external oscillator of mcp2515 on spi0.1 */ -@@ -43,7 +47,7 @@ - }; - - /* the spi config of the can-controller itself binding everything together */ -- fragment@3 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index 9242a6e..2c29aae 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - mz61581_pins: mz61581_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index ba4ad33..40a1f29 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - piscreen_pins: piscreen_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -index 7c018e0..9c0bed8 100644 ---- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - piscreen2_pins: piscreen2_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -index 48920e9..5c07526 100644 ---- a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -@@ -13,14 +13,17 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; - }; - }; - -- fragment@1 { -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - pitft_pins: pitft_pins { -@@ -31,7 +34,7 @@ - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -55,7 +58,7 @@ - }; - }; - -- fragment@3 { -+ fragment@4 { - target = <&i2c1>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -index d506eae..ed2afc2 100644 ---- a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - pitft_pins: pitft_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -95,7 +101,7 @@ - }; - }; - -- fragment@3 { -+ fragment@5 { - target-path = "/soc"; - __overlay__ { - backlight { -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -index ccb296e..d7e72ee 100644 ---- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - rpi_display_pins: rpi_display_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -index f7102c8..33c0651 100644 ---- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -30,18 +30,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - tinylcd35_pins: tinylcd35_pins { -@@ -60,7 +66,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -124,7 +130,7 @@ - - /* RTC */ - -- fragment@3 { -+ fragment@5 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -138,7 +144,7 @@ - }; - }; - -- fragment@4 { -+ fragment@6 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -156,7 +162,7 @@ - * Values for input event code is found under the - * 'Keys and buttons' heading in include/uapi/linux/input.h - */ -- fragment@5 { -+ fragment@7 { - target-path = "/soc"; - __overlay__ { - keypad: keypad { - -From 19da6ff34954c7a0c2aecef0451463522ea24ca1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 16:41:37 +0000 -Subject: [PATCH 184/251] BCM270X_DT: Build and document the wittypi overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++++++ - arch/arm/boot/dts/overlays/wittypi-overlay.dts | 2 +- - 3 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d81fa09..4f3ca9c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -74,6 +74,7 @@ dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo - dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo - dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += wittypi.dtbo - - targets += dtbs dtbs_install - targets += $(dtbo-y) -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 6fa5b80..d939739 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -920,6 +920,14 @@ Params: gpiopin GPIO for I/O (default "4") - extpullup GPIO for external pullup (default "5") - - -+Name: wittypi -+Info: Configures the wittypi RTC module. -+Load: dtoverlay=wittypi,= -+Params: led_gpio GPIO for LED (default "17") -+ led_trigger Choose which activity the LED tracks (default -+ "default-on") -+ -+ - Troubleshooting - =============== - -diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -index be5987d..8498134 100644 ---- a/arch/arm/boot/dts/overlays/wittypi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -@@ -37,7 +37,7 @@ - }; - - __overrides__ { -- led_gpio = <&wittypi_led>,"gpios:4"; -+ led_gpio = <&wittypi_led>,"gpios:4"; - led_trigger = <&wittypi_led>,"linux,default-trigger"; - }; - - -From e45f33c187edcda0e4affe6930068deadebf8b6c Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Tue, 15 Mar 2016 21:13:39 +0100 -Subject: [PATCH 185/251] scripts/dtc: Fix UMR causing corrupt dtbo overlay - files - -struct fixup_entry is allocated from the heap but it's member -local_fixup_generated was never initialized. This lead to -corrupted dtbo files. - -Fix this by initializing local_fixup_generated to false. - -Signed-off-by: Matthias Reichl ---- - scripts/dtc/checks.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 540a3ea..2b3b3a7 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -523,6 +523,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - fe->prop = prop; - fe->offset = m->offset; - fe->next = NULL; -+ fe->local_fixup_generated = false; - - /* append it to the local fixups */ - fep = &dt->local_fixups; - -From e45af7e57db63c4bd5d0ad7fe400cfdd36df42d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 16 Mar 2016 08:35:06 +0000 -Subject: [PATCH 186/251] BCM270X_DT: Add dtparam for uart1 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 + - arch/arm/boot/dts/overlays/README | 3 +++ - 6 files changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 00ea1b2..0e9a22d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -120,6 +120,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 2f8a718..a60342c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -114,6 +114,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 954896e..cd0e1ac 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -89,6 +89,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 66523d6..9176d57 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -120,6 +120,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 1ce4ea2..d2d39c6 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -171,6 +171,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d939739..4ce7921 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -124,6 +124,9 @@ Params: - - uart0 Set to "off" to disable uart0 (default "on") - -+ uart1 Set to "on" or "off" to enable or disable uart1 -+ (default varies) -+ - watchdog Set to "on" to enable the hardware watchdog - (default "off") - - -From 3f7271f5e6747663f2db11f01721ee60961e0178 Mon Sep 17 00:00:00 2001 -From: Przemek Rudy -Date: Fri, 11 Mar 2016 22:41:26 +0100 -Subject: [PATCH 187/251] dwc-overlay: Use label so overrides can apply. - ---- - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -index 90c9811..527abc9 100644 ---- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -8,7 +8,7 @@ - target = <&usb>; - #address-cells = <1>; - #size-cells = <1>; -- __overlay__ { -+ dwc2_usb: __overlay__ { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -@@ -21,9 +21,9 @@ - }; - - __overrides__ { -- dr_mode = <&usb>, "dr_mode"; -- g-np-tx-fifo-size = <&usb>,"g-np-tx-fifo-size:0"; -- g-rx-fifo-size = <&usb>,"g-rx-fifo-size:0"; -- g-tx-fifo-size = <&usb>,"g-tx-fifo-size:0"; -+ dr_mode = <&dwc2_usb>, "dr_mode"; -+ g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; -+ g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; -+ g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; - }; - }; - -From 5b7b03b9220d45e9fa99c2f9c73a08792cc4684b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 22 Jan 2016 13:06:39 -0800 -Subject: [PATCH 188/251] drm/vc4: Add a debugfs node for tracking execution - state. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + - drivers/gpu/drm/vc4/vc4_drv.h | 1 + - drivers/gpu/drm/vc4/vc4_gem.c | 14 ++++++++++++++ - 3 files changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c -index d76ad10..a99aa86 100644 ---- a/drivers/gpu/drm/vc4/vc4_debugfs.c -+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c -@@ -17,6 +17,7 @@ - - static const struct drm_info_list vc4_debugfs_list[] = { - {"bo_stats", vc4_bo_stats_debugfs, 0}, -+ {"gem_exec", vc4_gem_exec_debugfs, 0}, - {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, - {"hvs_regs", vc4_hvs_debugfs_regs, 0}, - {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index ed93fa7..aa0d00e 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -403,6 +403,7 @@ void vc4_job_handle_completed(struct vc4_dev *vc4); - int vc4_queue_seqno_cb(struct drm_device *dev, - struct vc4_seqno_cb *cb, uint64_t seqno, - void (*func)(struct vc4_seqno_cb *cb)); -+int vc4_gem_exec_debugfs(struct seq_file *m, void *arg); - - /* vc4_hdmi.c */ - extern struct platform_driver vc4_hdmi_driver; -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 39f29e7..1243f4e 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -31,6 +31,20 @@ - #include "vc4_regs.h" - #include "vc4_trace.h" - -+#ifdef CONFIG_DEBUG_FS -+int vc4_gem_exec_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *)m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ seq_printf(m, "Emitted seqno: 0x%016llx\n", vc4->emit_seqno); -+ seq_printf(m, "Finished seqno: 0x%016llx\n", vc4->finished_seqno); -+ -+ return 0; -+} -+#endif /* CONFIG_DEBUG_FS */ -+ - static void - vc4_queue_hangcheck(struct drm_device *dev) - { - -From 04fb589070fd36693251a40ceb61743bb3a0c2c6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:03:33 -0800 -Subject: [PATCH 189/251] drm/vc4: Include vc4_drm.h in uapi in downstream - build. - -Signed-off-by: Eric Anholt ---- - include/uapi/drm/Kbuild | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild -index 38d4370..23381b5 100644 ---- a/include/uapi/drm/Kbuild -+++ b/include/uapi/drm/Kbuild -@@ -14,6 +14,7 @@ header-y += radeon_drm.h - header-y += savage_drm.h - header-y += sis_drm.h - header-y += tegra_drm.h -+header-y += vc4_drm.h - header-y += via_drm.h - header-y += vmwgfx_drm.h - header-y += msm_drm.h - -From 3472309b991f5f8c75a655d2f077a1eb632af3cf Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:05:00 -0800 -Subject: [PATCH 190/251] drm/vc4: Validate that WAIT_BO padding is cleared. - -This is ABI future-proofing if we ever want to extend the pad to mean -something. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 1243f4e..849d374 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -761,6 +761,9 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_gem_object *gem_obj; - struct vc4_bo *bo; - -+ if (args->pad != 0) -+ return -EINVAL; -+ - gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); - -From fc63883845d0d69d746b00a54d8cf2aaf2db30a5 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:52:41 -0800 -Subject: [PATCH 191/251] drm/vc4: Fix the clear color for the first tile - rendered. - -Apparently in hardware (as opposed to simulation), the clear colors -need to be uploaded before the render config, otherwise they won't -take effect. Fixes igt's vc4_wait_bo/used-bo-* subtests. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_render_cl.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 8a2a312..dea97f4 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -321,15 +321,6 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, - &exec->unref_list); - -- rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -- rcl_u32(setup, -- (setup->color_write ? (setup->color_write->paddr + -- args->color_write.offset) : -- 0)); -- rcl_u16(setup, args->width); -- rcl_u16(setup, args->height); -- rcl_u16(setup, args->color_write.bits); -- - /* The tile buffer gets cleared when the previous tile is stored. If - * the clear values changed between frames, then the tile buffer has - * stale clear values in it, so we have to do a store in None mode (no -@@ -349,6 +340,15 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - rcl_u32(setup, 0); /* no address, since we're in None mode */ - } - -+ rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -+ rcl_u32(setup, -+ (setup->color_write ? (setup->color_write->paddr + -+ args->color_write.offset) : -+ 0)); -+ rcl_u16(setup, args->width); -+ rcl_u16(setup, args->height); -+ rcl_u16(setup, args->color_write.bits); -+ - for (y = min_y_tile; y <= max_y_tile; y++) { - for (x = min_x_tile; x <= max_x_tile; x++) { - bool first = (x == min_x_tile && y == min_y_tile); - -From 6128659e9deeb8f7b15a0e8bb9e4e974afe39064 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:13:12 -0800 -Subject: [PATCH 192/251] drm/vc4: Return an ERR_PTR from BO creation instead - of NULL. - -Fixes igt vc4_create_bo/create-bo-0 by returning -EINVAL from the -ioctl instead of -ENOMEM. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 23 +++++++++++++---------- - drivers/gpu/drm/vc4/vc4_gem.c | 4 ++-- - drivers/gpu/drm/vc4/vc4_irq.c | 2 +- - drivers/gpu/drm/vc4/vc4_render_cl.c | 4 ++-- - drivers/gpu/drm/vc4/vc4_validate.c | 4 ++-- - 5 files changed, 20 insertions(+), 17 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index 6247ff8..8477579 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -213,10 +213,10 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, - size_t size = roundup(unaligned_size, PAGE_SIZE); - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_gem_cma_object *cma_obj; -- int pass; -+ int pass, ret; - - if (size == 0) -- return NULL; -+ return ERR_PTR(-EINVAL); - - /* First, try to get a vc4_bo from the kernel BO cache. */ - if (from_cache) { -@@ -247,14 +247,17 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, - * unreferenced BOs to the cache, and then - * free the cache. - */ -- vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, true); -+ ret = vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, -+ true); -+ if (ret) -+ return ERR_PTR(ret); - vc4_job_handle_completed(vc4); - vc4_bo_cache_purge(dev); - break; - case 3: - DRM_ERROR("Failed to allocate from CMA:\n"); - vc4_bo_stats_dump(vc4); -- return NULL; -+ return ERR_PTR(-ENOMEM); - } - } - -@@ -276,8 +279,8 @@ int vc4_dumb_create(struct drm_file *file_priv, - args->size = args->pitch * args->height; - - bo = vc4_bo_create(dev, args->size, false); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); -@@ -460,8 +463,8 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, - * get zeroed, and that might leak data between users. - */ - bo = vc4_bo_create(dev, args->size, false); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); -@@ -513,8 +516,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - } - - bo = vc4_bo_create(dev, args->size, true); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = copy_from_user(bo->base.vaddr, - (void __user *)(uintptr_t)args->data, -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 849d374..f8c003a 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -593,9 +593,9 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - } - - bo = vc4_bo_create(dev, exec_size, true); -- if (!bo) { -+ if (IS_ERR(bo)) { - DRM_ERROR("Couldn't allocate BO for binning\n"); -- ret = PTR_ERR(exec->exec_bo); -+ ret = PTR_ERR(bo); - goto fail; - } - exec->exec_bo = &bo->base; -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -index b68060e..78a2135 100644 ---- a/drivers/gpu/drm/vc4/vc4_irq.c -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -57,7 +57,7 @@ vc4_overflow_mem_work(struct work_struct *work) - struct vc4_bo *bo; - - bo = vc4_bo_create(dev, 256 * 1024, true); -- if (!bo) { -+ if (IS_ERR(bo)) { - DRM_ERROR("Couldn't allocate binner overflow mem\n"); - return; - } -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index dea97f4..0f12418 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -316,8 +316,8 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - size += xtiles * ytiles * loop_body_size; - - setup->rcl = &vc4_bo_create(dev, size, true)->base; -- if (!setup->rcl) -- return -ENOMEM; -+ if (IS_ERR(setup->rcl)) -+ return PTR_ERR(setup->rcl); - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, - &exec->unref_list); - -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index 0fb5b99..8396960 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -401,8 +401,8 @@ validate_tile_binning_config(VALIDATE_ARGS) - tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size, - true); - exec->tile_bo = &tile_bo->base; -- if (!exec->tile_bo) -- return -ENOMEM; -+ if (IS_ERR(exec->tile_bo)) -+ return PTR_ERR(exec->tile_bo); - list_add_tail(&tile_bo->unref_head, &exec->unref_list); - - /* tile alloc address. */ - -From e62f39b87fb3577d0c154ee50459a8d0b83865ca Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:32:41 -0800 -Subject: [PATCH 193/251] drm/vc4: Fix -ERESTARTSYS error return from BO waits. - -This caused the wait ioctls to claim that waiting had completed when -we actually got interrupted by a signal before it was done. Fixes -broken rendering throttling that produced serious lag in X window -dragging. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index f8c003a..dc3044d 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -352,12 +352,10 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, - finish_wait(&vc4->job_wait_queue, &wait); - trace_vc4_wait_for_seqno_end(dev, seqno); - -- if (ret && ret != -ERESTARTSYS) { -+ if (ret && ret != -ERESTARTSYS) - DRM_ERROR("timeout waiting for render thread idle\n"); -- return ret; -- } - -- return 0; -+ return ret; - } - - static void - -From 7942d03413ee330d2fb041dc62dabc8ce738cc0c Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:33:50 -0800 -Subject: [PATCH 194/251] drm/vc4: Drop error message on seqno wait timeouts. - -These ioctls end up getting exposed to userspace, and having normal -user requests print DRM errors is obviously wrong. The message was -originally to give us some idea of what happened when a hang occurred, -but we have a DRM_INFO from reset for that. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index dc3044d..a6fa63f 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -352,9 +352,6 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, - finish_wait(&vc4->job_wait_queue, &wait); - trace_vc4_wait_for_seqno_end(dev, seqno); - -- if (ret && ret != -ERESTARTSYS) -- DRM_ERROR("timeout waiting for render thread idle\n"); -- - return ret; - } - - -From 9ceac017a764704d9919a494590e8fea0e458adc Mon Sep 17 00:00:00 2001 -From: campag -Date: Wed, 24 Feb 2016 16:45:42 +0000 -Subject: [PATCH 195/251] BCM270X_DT: Add 1-bit SDIO using minimal pins... - -... for that mode: GPIOs 22-25. ---- - arch/arm/boot/dts/overlays/README | 21 ++++++++++++++ - arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts | 36 ++++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4ce7921..7118510 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -709,6 +709,27 @@ Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - bus_width Set the SDIO host bus width (default 4 bits) - - -+Name: sdio-1bit -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -+ and enables 1-bit SDIO via GPIOs 22-25. -+Load: dtoverlay=sdio-1bit,= -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) -+ -+ - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver - Load: dtoverlay=sdtweak,= -diff --git a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts -new file mode 100644 -index 0000000..46d4538 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts -@@ -0,0 +1,36 @@ -+/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ -+ -+/include/ "sdhost-overlay.dts" -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@3 { -+ target = <&mmc>; -+ sdio_mmc: __overlay__ { -+ compatible = "brcm,bcm2835-mmc"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ bus-width = <1>; -+ brcm,overclock-50 = <0>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ sdio_pins: sdio_pins { -+ brcm,pins = <22 23 24 25>; -+ brcm,function = <7 7 7 7>; /* ALT3 = SD1 */ -+ brcm,pull = <0 2 2 2>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ poll_once = <&sdio_mmc>,"non-removable?"; -+ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; -+ }; -+}; - -From 6dd9dc84456f9341739f6c6d2c7d5b1f08d5c8fe Mon Sep 17 00:00:00 2001 -From: Cheong2K -Date: Fri, 26 Feb 2016 18:20:10 +0800 -Subject: [PATCH 196/251] brcm: adds support for BCM43341 wifi - ---- - drivers/net/wireless/brcm80211/brcmfmac/sdio.c | 5 +++++ - drivers/net/wireless/brcm80211/include/brcm_hw_ids.h | 1 + - 2 files changed, 6 insertions(+) - -diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -index 7e74ac3..818f756 100644 ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -613,6 +613,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { - #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" - #define BCM43340_FIRMWARE_NAME "brcm/brcmfmac43340-sdio.bin" - #define BCM43340_NVRAM_NAME "brcm/brcmfmac43340-sdio.txt" -+#define BCM43341_FIRMWARE_NAME "brcm/brcmfmac43341-sdio.bin" -+#define BCM43341_NVRAM_NAME "brcm/brcmfmac43341-sdio.txt" - #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" - #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" - #define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" -@@ -642,6 +644,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4334_NVRAM_NAME); - MODULE_FIRMWARE(BCM43340_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM43340_NVRAM_NAME); -+MODULE_FIRMWARE(BCM43341_FIRMWARE_NAME); -+MODULE_FIRMWARE(BCM43341_NVRAM_NAME); - MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4335_NVRAM_NAME); - MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); -@@ -679,6 +683,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { - { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, - { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, - { BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43340) }, -+ { BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43341) }, - { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, - { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, -diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -index aa06ea2..f3ae83d 100644 ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -34,6 +34,7 @@ - #define BRCM_CC_4330_CHIP_ID 0x4330 - #define BRCM_CC_4334_CHIP_ID 0x4334 - #define BRCM_CC_43340_CHIP_ID 43340 -+#define BRCM_CC_43341_CHIP_ID 43341 - #define BRCM_CC_43362_CHIP_ID 43362 - #define BRCM_CC_4335_CHIP_ID 0x4335 - #define BRCM_CC_4339_CHIP_ID 0x4339 - -From 0702cbfdf586a8c1b67d28cdfc84a0623c8b12f1 Mon Sep 17 00:00:00 2001 -From: Michael Heimpold -Date: Fri, 29 Jan 2016 12:00:37 +0100 -Subject: [PATCH 197/251] Add overlay and enable support for QCA7000 board - -This adds a device tree overlay for the QCA7000 which can be used -when attaching an I2SE's PLC Stamp micro EVK to the Raspberry Pi. - -This Evaluation Board embeds a QCA7000 chip, a Homeplug Green PHY -powerline chip from Qualcomm/Atheros for the Internet of Things. - -This patch also enables the required QCA7000 driver module -in the default configurations. - -Signed-off-by: Stefan Wahren -Signed-off-by: Michael Heimpold ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - arch/arm/boot/dts/overlays/qca7000-overlay.dts | 52 ++++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 63 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/qca7000-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4f3ca9c..f4ae95a 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -48,6 +48,7 @@ dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += qca7000.dtbo - dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo - dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo - dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7118510..2a354b3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -625,6 +625,14 @@ Params: pin Output pin (default 18) - see table - clock PWM clock frequency (informational) - - -+Name: qca7000 -+Info: I2SE's Evaluation Board for PLC Stamp micro -+Load: dtoverlay=qca7000,= -+Params: int_pin GPIO pin for interrupt signal (default 23) -+ -+ speed SPI bus speed (default 12 MHz) -+ -+ - Name: raspidac3 - Info: Configures the RaspiDAV Rev.3x audio card - Load: dtoverlay=raspidac3 -diff --git a/arch/arm/boot/dts/overlays/qca7000-overlay.dts b/arch/arm/boot/dts/overlays/qca7000-overlay.dts -new file mode 100644 -index 0000000..b4e6013 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts -@@ -0,0 +1,52 @@ -+// Overlay for the Qualcomm Atheros QCA7000 on I2SE's PLC Stamp micro EVK -+// Visit: https://www.i2se.com/product/plc-stamp-micro-evk for details -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0 { -+ status = "disabled"; -+ }; -+ -+ eth1: qca7000@0 { -+ compatible = "qca,qca7000"; -+ reg = <0>; /* CE0 */ -+ pinctrl-names = "default"; -+ pinctrl-0 = <ð1_pins>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 0x1>; /* rising edge */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ eth1_pins: eth1_pins { -+ brcm,pins = <23>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ int_pin = <ð1>, "interrupts:0", -+ <ð1_pins>, "brcm,pins:0"; -+ speed = <ð1>, "spi-max-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 0fff5a3..b63632d 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -446,6 +446,7 @@ CONFIG_NETCONSOLE=m - CONFIG_TUN=m - CONFIG_VETH=m - CONFIG_ENC28J60=m -+CONFIG_QCA7000=m - CONFIG_MDIO_BITBANG=m - CONFIG_PPP=m - CONFIG_PPP_BSDCOMP=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 74149cf..e720c74 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -439,6 +439,7 @@ CONFIG_NETCONSOLE=m - CONFIG_TUN=m - CONFIG_VETH=m - CONFIG_ENC28J60=m -+CONFIG_QCA7000=m - CONFIG_MDIO_BITBANG=m - CONFIG_PPP=m - CONFIG_PPP_BSDCOMP=m - -From 5fbc1847fdefcf563be0c51ffc07de6666036ba6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 9 Mar 2016 13:28:24 +0000 -Subject: [PATCH 198/251] serial: Take care starting a hung-up tty's port - -tty_port_hangup sets a port's tty field to NULL (holding the port lock), -but uart_tx_stopped, called from __uart_start (with the port lock), -uses the tty field without checking for NULL. - -Change uart_tx_stopped to treat a NULL tty field as another stopped -indication. - -Signed-off-by: Phil Elwell ---- - include/linux/serial_core.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h -index 297d4fa..00ce6c6 100644 ---- a/include/linux/serial_core.h -+++ b/include/linux/serial_core.h -@@ -397,7 +397,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); - static inline int uart_tx_stopped(struct uart_port *port) - { - struct tty_struct *tty = port->state->port.tty; -- if (tty->stopped || port->hw_stopped) -+ if (!tty || tty->stopped || port->hw_stopped) - return 1; - return 0; - } - -From b8127d80609179210ae5ceea4929391991dbce9a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Mar 2016 10:16:16 +0000 -Subject: [PATCH 199/251] pi3-miniuart-bt-overlay: Correct and clarify info - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 6 ++++-- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 6 ++++-- - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 2a354b3..b674394 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -511,8 +511,10 @@ Name: pi3-miniuart-bt - Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore - UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum - usable baudrate. -- N.B. It is also necessary to edit /lib/systemd/system/hciuart.server -- and replace ttyAMA0 with ttyS0. -+ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service -+ and replace ttyAMA0 with ttyS0, unless you have a system with udev rules -+ that create /dev/serial0 and /dev/serial1, in which case use -+ /dev/serial1 instead because it will always be correct. - Load: dtoverlay=pi3-miniuart-bt - Params: - -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index f07afcb..38ed33b 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -5,8 +5,10 @@ - UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum - usable baudrate. - -- It is also necessary to edit /lib/systemd/system/hciuart.server and -- replace ttyAMA0 with ttyS0. -+ It is also necessary to edit /lib/systemd/system/hciuart.service and -+ replace ttyAMA0 with ttyS0, unless you have a system with udev rules -+ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 -+ instead because it will always be correct. - - If cmdline.txt uses the alias serial0 to refer to the user-accessable port - then the firmware will replace with the appropriate port whether or not - -From ee65eba2fa76dc0ca35f2c74ec655f89d9d33b13 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Mar 2016 10:41:56 +0000 -Subject: [PATCH 200/251] pwm overlays: Params must have in-overlay targets - ---- - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 9 ++++++++- - arch/arm/boot/dts/overlays/pwm-overlay.dts | 9 ++++++++- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -index 957e1a4..18e4e4f 100644 ---- a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -36,11 +36,18 @@ N.B.: - }; - }; - -+ fragment@2 { -+ target = <&clk_pwm>; -+ frag2: __overlay__ { -+ clock-frequency = <100000000>; -+ }; -+ }; -+ - __overrides__ { - pin = <&pwm_pins>,"brcm,pins:0"; - pin2 = <&pwm_pins>,"brcm,pins:4"; - func = <&pwm_pins>,"brcm,function:0"; - func2 = <&pwm_pins>,"brcm,function:4"; -- clock = <&clk_pwm>,"clock-frequency:0"; -+ clock = <&frag2>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts -index ddd67ff..bf030a6 100644 ---- a/arch/arm/boot/dts/overlays/pwm-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -34,9 +34,16 @@ N.B.: - }; - }; - -+ fragment@2 { -+ target = <&clk_pwm>; -+ frag2: __overlay__ { -+ clock-frequency = <100000000>; -+ }; -+ }; -+ - __overrides__ { - pin = <&pwm_pins>,"brcm,pins:0"; - func = <&pwm_pins>,"brcm,function:0"; -- clock = <&clk_pwm>,"clock-frequency:0"; -+ clock = <&frag2>,"clock-frequency:0"; - }; - }; - -From 62279457d4e5c3a132a0c8fe60c0d9c51c3edd9d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 18 Mar 2016 13:06:29 +0000 -Subject: [PATCH 201/251] BCM270X_DT: Switch Compute Module to MMC - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index e09e499..90e330d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -8,9 +8,9 @@ - }; - - &gpio { -- sdhost_pins: sdhost_pins { -+ mmc_pins: mmc_pins { - brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <7>; /* alt3 */ - }; - }; - -@@ -22,12 +22,14 @@ - }; - }; - --&sdhost { -+ -+&mmc { - pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -- bus-width = <4>; -+ pinctrl-0 = <&mmc_pins>; - non-removable; -+ bus-width = <4>; - status = "okay"; -+ brcm,overclock-50 = <0>; - }; - - &fb { -@@ -45,9 +47,6 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -- sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -- sd_force_pio = <&sdhost>,"brcm,force-pio?"; -- sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -- sd_debug = <&sdhost>,"brcm,debug"; -+ sd_overclock = <&mmc>,"brcm,overclock-50:0"; - }; - }; - -From 82ecf79397939c59b5b50cd683b823e1233568f7 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Fri, 18 Mar 2016 17:38:37 +0000 -Subject: [PATCH 202/251] dwc_otg: Don't free qh align buffers in atomic - context - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -index acd0dd7..3b2a607 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -56,6 +56,9 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) - { - dwc_otg_qtd_t *qtd, *qtd_tmp; - dwc_irqflags_t flags; -+ uint32_t buf_size = 0; -+ uint8_t *align_buf_virt = NULL; -+ dwc_dma_t align_buf_dma; - - /* Free each QTD in the QTD list */ - DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); -@@ -67,17 +70,19 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) - if (hcd->core_if->dma_desc_enable) { - dwc_otg_hcd_qh_free_ddma(hcd, qh); - } else if (qh->dw_align_buf) { -- uint32_t buf_size; - if (qh->ep_type == UE_ISOCHRONOUS) { - buf_size = 4096; - } else { - buf_size = hcd->core_if->core_params->max_transfer_size; - } -- DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma); -+ align_buf_virt = qh->dw_align_buf; -+ align_buf_dma = qh->dw_align_buf_dma; - } - - DWC_FREE(qh); - DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); -+ if (align_buf_virt) -+ DWC_DMA_FREE(buf_size, align_buf_virt, align_buf_dma); - return; - } - - -From 6e02745d8e2fc480d3442e6adaf4547e100611b5 Mon Sep 17 00:00:00 2001 +From a4862ba9bf7e56d3c2e8556c19eda52fc0f6b9c4 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Mon, 21 Mar 2016 15:38:38 +0000 -Subject: [PATCH 203/251] dwc_otg: Enable the hack for Split Interrupt - transactions by default +Date: Thu, 31 Mar 2016 16:49:52 +0100 +Subject: [PATCH 097/114] config: Enabled IPV6_SUBTREES -dwc_otg.fiq_fsm_mask=0xF has long been a suggestion for users with audio stutters or other USB bandwidth issues. -So far we are aware of many success stories but no failure caused by this setting. -Make it a default to learn more. - -See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=70437 - -Signed-off-by: popcornmix --- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 177745a..2536c11 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -106,6 +106,7 @@ CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m + CONFIG_IPV6_TUNNEL=m + CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IPV6_MROUTE=y + CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y + CONFIG_IPV6_PIMSM_V2=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0b87299..bfb6936 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -73,6 +73,7 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IP_ROUTE_MULTIPATH=y + CONFIG_IP_ROUTE_VERBOSE=y + CONFIG_IP_PNP=y + +From 042c70e53211e4062dff7ddf59a7b360b5370736 Mon Sep 17 00:00:00 2001 +From: Slawomir Stepien +Date: Sun, 3 Apr 2016 13:11:58 +0200 +Subject: [PATCH 098/114] [media]: bcm2835-camera: fix compilation error + +There is an error when compiling rpi-4.6.y branch: + CC [M] drivers/media/platform/bcm2835/bcm2835-camera.o +drivers/media/platform/bcm2835/bcm2835-camera.c:639:17: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] + .queue_setup = queue_setup, + ^ +drivers/media/platform/bcm2835/bcm2835-camera.c:639:17: note: (near initialization for 'bm2835_mmal_video_qops.queue_setup') + +The const void *parg in setup_queue callback is not needed since commit: +df9ecb0cad14b952a2865f8b3af86b2bbadfab45. +This commit removes it. + +Signed-off-by: Slawomir Stepien +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index 95edadf..cb060a7 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -247,7 +247,7 @@ bool fiq_fsm_enable = true; - //Bulk split-transaction NAK holdoff in microframes - uint16_t nak_holdoff = 8; +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index fbf89a2..fd20d1e 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -236,7 +236,7 @@ static struct mmal_fmt *get_format(struct v4l2_format *f) + Videobuf queue operations + ------------------------------------------------------------------*/ --unsigned short fiq_fsm_mask = 0x07; -+unsigned short fiq_fsm_mask = 0x0F; - - /** - * This function shows the Driver Version. +-static int queue_setup(struct vb2_queue *vq, const void *parg, ++static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], void *alloc_ctxs[]) + { -From 6a2fc8f71762aab14aee7311f8b7cd94aa316773 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 19 Mar 2016 16:51:37 +0000 -Subject: [PATCH 204/251] BCM270X_DT: Remove explicit claiming of UART pins +From 7eb6433554a5b01c7aded991216424b7c3a0561c Mon Sep 17 00:00:00 2001 +From: Slawomir Stepien +Date: Sun, 3 Apr 2016 18:59:57 +0200 +Subject: [PATCH 099/114] DT configfs: fix build error -It is convenient to be able to map a different function to the UART -pins (e.g. DPI for vga666) without having to disable the UART first. +There is an error when compiling rpi-4.6.y branch: + CC drivers/of/configfs.o +drivers/of/configfs.c:291:21: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] + .default_groups = of_cfs_def_groups, + ^ +drivers/of/configfs.c:291:21: note: (near initialization for 'of_cfs_subsys.su_group.default_groups.next') -Signed-off-by: Phil Elwell +The .default_groups is linked list since commit +1ae1602de028acaa42a0f6ff18d19756f8e825c6. +This commit uses configfs_add_default_group to fix this problem. + +Signed-off-by: Slawomir Stepien --- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 +++--- - .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 10 ++++----- - .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 25 +++++++++++----------- - 3 files changed, 20 insertions(+), 21 deletions(-) + drivers/of/configfs.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index d2d39c6..adba682 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -57,9 +57,9 @@ - }; +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +index 168b9d3..68f889d 100644 +--- a/drivers/of/configfs.c ++++ b/drivers/of/configfs.c +@@ -277,18 +277,12 @@ static struct config_item_type of_cfs_type = { - uart1_pins: uart1_pins { -- brcm,pins = <14 15>; -- brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 2>; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; + struct config_group of_cfs_overlay_group; -diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -index 05403e2..68f6069 100644 ---- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -28,13 +28,11 @@ - }; - - fragment@2 { -- target = <&gpio>; -+ target = <&uart0_pins>; - __overlay__ { -- uart0_pins: uart0_pins { -- brcm,pins = <14 15>; -- brcm,function = <4>; /* alt0 */ -- brcm,pull = <0 2>; -- }; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; - -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index 38ed33b..17d04cf 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -37,23 +37,24 @@ - }; - - fragment@2 { -- target = <&gpio>; -+ target = <&uart0_pins>; - __overlay__ { -- uart0_pins: uart0_pins { -- brcm,pins = <14 15>; -- brcm,function = <4>; /* alt0 */ -- brcm,pull = <0 2>; -- }; +-struct config_group *of_cfs_def_groups[] = { +- &of_cfs_overlay_group, +- NULL +-}; - -- uart1_pins: uart1_pins { -- brcm,pins = <32 33>; -- brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 2>; -- }; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; + static struct configfs_subsystem of_cfs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "device-tree", + .ci_type = &of_cfs_type, + }, +- .default_groups = of_cfs_def_groups, + }, + .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), + }; +@@ -302,6 +296,8 @@ static int __init of_cfs_init(void) + config_group_init(&of_cfs_subsys.su_group); + config_group_init_type_name(&of_cfs_overlay_group, "overlays", + &overlays_type); ++ configfs_add_default_group(&of_cfs_overlay_group, ++ &of_cfs_subsys.su_group); - fragment@3 { -+ target = <&uart1_pins>; -+ __overlay__ { -+ brcm,pins = <32 33>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ -+ fragment@4 { - target-path = "/aliases"; - __overlay__ { - serial0 = "/soc/uart@7e201000"; + ret = configfs_register_subsystem(&of_cfs_subsys); + if (ret != 0) { -From 403390e94d98b9f7b6f41397b04b2f29900cdcb0 Mon Sep 17 00:00:00 2001 -From: Rodrigo Freire -Date: Tue, 22 Mar 2016 12:40:33 -0300 -Subject: [PATCH 205/251] lirc_rpi: Lower IR reception error to debug +From 851b603db5ec7c276c4219ac92c0b085abb90f00 Mon Sep 17 00:00:00 2001 +From: dienet +Date: Wed, 13 Apr 2016 19:07:46 +0200 +Subject: [PATCH 100/114] vchiq_arm: do not use page_cache_release(page) macro + (#1403) -Lowers a IR reception error condition message to KERNEL_DEBUG +This macro is gone since 1fa64f198b9f8d6ec0f7aec7c18dc94684391140. + +Signed-off-by: Slawomir Stepien --- - drivers/staging/media/lirc/lirc_rpi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index cd09c99..0624439 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -271,7 +271,7 @@ static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) - data = PULSE_MASK; /* really long time */ - if (!(signal^sense)) { - /* sanity check */ -- printk(KERN_WARNING LIRC_DRIVER_NAME -+ printk(KERN_DEBUG LIRC_DRIVER_NAME - ": AIEEEE: %d %d %lx %lx %lx %lx\n", - signal, sense, tv.tv_sec, lasttv.tv_sec, - tv.tv_usec, lasttv.tv_usec); - -From 0fb8769fe60a8bba6f871ff6d91a04fb7950b67d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 14:16:25 +0000 -Subject: [PATCH 206/251] vchiq_arm: Access the dequeue_pending flag locked - -Reading through this code looking for another problem (now found in userland) -the use of dequeue_pending outside a lock didn't seem safe. - -Signed-off-by: Phil Elwell ---- - .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 4 ++-- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index c29040f..705c055 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -439,7 +439,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, + while (actual_pages > 0) + { + actual_pages--; +- page_cache_release(pages[actual_pages]); ++ put_page(pages[actual_pages]); + } + kfree(pagelist); + if (actual_pages == 0) +@@ -578,7 +578,7 @@ free_pagelist(PAGELIST_T *pagelist, int actual) + offset = 0; + set_page_dirty(pg); + } +- page_cache_release(pg); ++ put_page(pg); + } + } + diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index e11c0e0..71883e5 100644 +index a5cc385..dd62676 100644 --- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -279,6 +279,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - USER_SERVICE_T *user_service; - VCHIQ_SERVICE_T *service; - VCHIQ_INSTANCE_T instance; -+ int skip_completion = 0; +@@ -1520,7 +1520,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) + kunmap(page); + + for (page_idx = 0; page_idx < num_pages; page_idx++) +- page_cache_release(pages[page_idx]); ++ put_page(pages[page_idx]); + + kfree(pages); + } + +From ba7d03eecfa21c6dc350b236beaad715acac723f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 18 Apr 2016 23:00:31 +0100 +Subject: [PATCH 101/114] vchiq: Upate to match get_user_pages prototype + +--- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 3 +-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index 705c055..4cb5bff 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -420,7 +420,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, + *need_release = 0; /* do not try and release vmalloc pages */ + } else { + down_read(&task->mm->mmap_sem); +- actual_pages = get_user_pages(task, task->mm, ++ actual_pages = get_user_pages( + (unsigned long)buf & ~(PAGE_SIZE - 1), + num_pages, + (type == PAGELIST_READ) /*Write */ , +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +index dd62676..a76060c 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -1480,8 +1480,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) + } + + down_read(¤t->mm->mmap_sem); +- rc = get_user_pages(current, /* task */ +- current->mm, /* mm */ ++ rc = get_user_pages( + (unsigned long)virt_addr, /* start */ + num_pages, /* len */ + 0, /* write */ + +From 0ae92b6f6101216e8f6aa5d68b9adad458e91ae7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 21 Apr 2016 13:49:32 +0100 +Subject: [PATCH 102/114] vchiq_arm: Add completion records under the mutex + +An issue was observed when flushing openmax components +which generate a large number of messages returning +buffers to host. + +We occasionally found a duplicate message from 16 +messages prior, resulting in a buffer returned twice. + +While only one thread adds completions, without the +mutex you don't get the protection of the automatic +memory barrier you get with synchronisation objects. + +Signed-off-by: Phil Elwell +--- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +index a76060c..51e6018 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + VCHIQ_COMPLETION_DATA_T *completion; DEBUG_INITIALISE(g_state.local) - DEBUG_TRACE(SERVICE_CALLBACK_LINE); -@@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - user_service->msg_queue[user_service->msg_insert & - (MSG_QUEUE_SIZE - 1)] = header; - user_service->msg_insert++; -- spin_unlock(&msg_queue_spinlock); -- -- up(&user_service->insert_event); - - /* If there is a thread waiting in DEQUEUE_MESSAGE, or if - ** there is a MESSAGE_AVAILABLE in the completion queue then -@@ -356,13 +354,22 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - if (((user_service->message_available_pos - - instance->completion_remove) >= 0) || - user_service->dequeue_pending) { -- DEBUG_TRACE(SERVICE_CALLBACK_LINE); - user_service->dequeue_pending = 0; -- return VCHIQ_SUCCESS; -+ skip_completion = 1; - } - -+ spin_unlock(&msg_queue_spinlock); ++ mutex_lock(&instance->completion_mutex); + -+ up(&user_service->insert_event); + while (instance->completion_insert == + (instance->completion_remove + MAX_COMPLETIONS)) { + /* Out of space - wait for the client */ +@@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + vchiq_log_trace(vchiq_arm_log_level, + "add_completion - completion queue full"); + DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); + - header = NULL; - } ++ mutex_unlock(&instance->completion_mutex); + if (down_interruptible(&instance->remove_event) != 0) { + vchiq_log_info(vchiq_arm_log_level, + "service_callback interrupted"); + return VCHIQ_RETRY; +- } else if (instance->closing) { ++ } + -+ if (skip_completion) { -+ DEBUG_TRACE(SERVICE_CALLBACK_LINE); -+ return VCHIQ_SUCCESS; -+ } -+ - DEBUG_TRACE(SERVICE_CALLBACK_LINE); - - return add_completion(instance, reason, header, user_service, - -From 797c1c2110ba155df9fbdb44a7c052f7beeb0a50 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 15:57:14 +0000 -Subject: [PATCH 207/251] BCM270X_DT: Add pi3-act-led overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 19 +++++++++++++++ - arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 27 ++++++++++++++++++++++ - 3 files changed, 47 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f4ae95a..4c3db73 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-act-led.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo - dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b674394..9b49868 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -136,12 +136,14 @@ Params: - - act_led_activelow Set to "on" to invert the sense of the LED - (default "off") -+ N.B. For Pi3 see pi3-act-led overlay. - - act_led_gpio Set which GPIO to use for the activity LED - (in case you want to connect it to an external - device) - (default "16" on a non-Plus board, "47" on a - Plus or Pi 2) -+ N.B. For Pi3 see pi3-act-led overlay. - - pwr_led_trigger - pwr_led_activelow -@@ -499,6 +501,23 @@ Params: speed Display SPI bus speed - [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] - - -+Name: pi3-act-led -+Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -+ from the VPU. There is a special driver for this with a separate DT -+ node, which has the unfortunate consequence of breaking the -+ act_led_gpio and act_led_activelow dtparams. -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+Load: dtoverlay=pi3-act-led,= -+Params: activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ REQUIRED -+ -+ - Name: pi3-disable-bt - Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 - N.B. To disable the systemd service that initialises the modem so it -diff --git a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -new file mode 100644 -index 0000000..14a59dc ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -+ from the VPU. There is a special driver for this with a separate DT node, -+ which has the unfortunate consequence of breaking the act_led_gpio and -+ act_led_activelow dtparams. -+ -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+*/ -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&act_led>; -+ frag0: __overlay__ { -+ gpios = <&gpio 0 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio = <&frag0>,"gpios:4"; -+ activelow = <&frag0>,"gpios:8"; -+ }; -+}; - -From 6de376456d86ba0211a2e8c10cf50fda9f3b6e20 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 20:53:47 +0000 -Subject: [PATCH 208/251] vchiq_arm: Service callbacks must not fail - -Service callbacks are not allowed to return an error. The internal callback -that delivers events and messages to user tasks does not enqueue them if -the service is closing, but this is not an error and should not be -reported as such. - -Signed-off-by: Phil Elwell ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 71883e5..a5cc385 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -224,7 +224,7 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - } else if (instance->closing) { ++ mutex_lock(&instance->completion_mutex); ++ if (instance->closing) { ++ mutex_unlock(&instance->completion_mutex); vchiq_log_info(vchiq_arm_log_level, "service_callback closing"); -- return VCHIQ_ERROR; -+ return VCHIQ_SUCCESS; - } - DEBUG_TRACE(SERVICE_CALLBACK_LINE); - } - -From 4793b34f7a3f71b1acfcd769b8d25fdcbb01b2cd Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Thu, 17 Mar 2016 18:16:16 +0000 -Subject: [PATCH 209/251] Add configs and overlay for PCA9548 I2C mux - -Adds kernel configs for I2C muxes and a dt overlay for PCA9548 -that adds the 8 muxed I2C buses and mux device. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++ - .../boot/dts/overlays/i2c-mux-pca9548a-overlay.dts | 67 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - 5 files changed, 78 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4c3db73..7c4fc30 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9b49868..a9b1ff5 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -360,6 +360,12 @@ Params: i2c_gpio_sda GPIO used for I2C data (default "23") - (default "2" = ~100kHz) + return VCHIQ_SUCCESS; +@@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + if (reason == VCHIQ_MESSAGE_AVAILABLE) + user_service->message_available_pos = + instance->completion_insert; ++ + instance->completion_insert++; ++ mutex_unlock(&instance->completion_mutex); ++ + up(&instance->insert_event); -+Name: i2c-mux-pca9548a -+Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm -+Load: dtoverlay=i2c-mux-pca9548a,= -+Params: addr I2C address of PCA9548A (default 0x70) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= -diff --git a/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts -new file mode 100644 -index 0000000..1729fd6 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts -@@ -0,0 +1,67 @@ -+// Definitions for NXP PCA9548A I2C mux on ARM I2C bus. -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ i2cmux: mux@70 { -+ compatible = "nxp,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ }; -+ }; -+ }; -+ }; -+ __overrides__ { -+ addr = <&i2cmux>,"reg:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index b63632d..2c8e4b7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -600,6 +600,8 @@ CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m -+CONFIG_I2C_MUX=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e720c74..f6e2d84 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -593,6 +593,8 @@ CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m -+CONFIG_I2C_MUX=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m + return VCHIQ_SUCCESS; -From 77700bbcd5dc6285892ea67acba46e45c3341b66 Mon Sep 17 00:00:00 2001 -From: Nicolas Boullis -Date: Wed, 23 Mar 2016 23:40:15 +0100 -Subject: [PATCH 210/251] BCM270X_DT: Add DS1339 to i2c-rtc overlay - ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 8 ++++++++ - 2 files changed, 12 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index a9b1ff5..e88e7c8 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -371,6 +371,8 @@ Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= - Params: ds1307 Select the DS1307 device - -+ ds1339 Select the DS1339 device -+ - ds3231 Select the DS3231 device - - mcp7941x Select the MCP7941x device -@@ -381,6 +383,8 @@ Params: ds1307 Select the DS1307 device - - pcf8563 Select the PCF8563 device - -+ trickle-resistor-ohms Resistor value for trickle charge (DS1339-only) -+ - - Name: i2c0-bcm2708 - Info: Enable the i2c_bcm2708 driver for the i2c0 bus -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index fed4bd8..eecec16 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -17,6 +17,12 @@ - reg = <0x68>; - status = "disable"; - }; -+ ds1339: ds1339@68 { -+ compatible = "dallas,ds1339"; -+ trickle-resistor-ohms = <0>; -+ reg = <0x68>; -+ status = "disable"; -+ }; - mcp7941x: mcp7941x@6f { - compatible = "microchip,mcp7941x"; - reg = <0x6f>; -@@ -46,10 +52,12 @@ - }; - __overrides__ { - ds1307 = <&ds1307>,"status"; -+ ds1339 = <&ds1339>,"status"; - ds3231 = <&ds3231>,"status"; - mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - pcf8563 = <&pcf8563>,"status"; -+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0"; - }; - }; - -From c17b3228544635d56826292c0989d2e944917148 Mon Sep 17 00:00:00 2001 +From b203738cc5b4bd877e5f1db0d3e745b5865507aa Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 29 Mar 2016 15:32:30 +0100 -Subject: [PATCH 211/251] copy_from_user: CPU_SW_DOMAIN_PAN compatibility +Date: Thu, 21 Apr 2016 15:44:14 +0100 +Subject: [PATCH 103/114] bcm2835-i2s: Reduce the TX DREQ threshold -The downstream copy_from_user acceleration must also play nice with -CONFIG_CPU_SW_DOMAIN_PAN. +TX FIFO overrun is thought to be the cause of channel swapping, so +reducing the DREQ threshold seems reasonable and appears to be +effective. -See: https://github.com/raspberrypi/linux/issues/1381 +See: https://github.com/raspberrypi/linux/issues/1417 Signed-off-by: Phil Elwell --- - arch/arm/lib/uaccess_with_memcpy.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) + sound/soc/bcm/bcm2835-i2s.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) -diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index c29df92..6681df5 100644 ---- a/arch/arm/lib/uaccess_with_memcpy.c -+++ b/arch/arm/lib/uaccess_with_memcpy.c -@@ -186,6 +186,7 @@ out: - unsigned long noinline - __copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) - { -+ unsigned long ua_flags; - int atomic; +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index c7f3fc7..8064e3f 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -403,15 +403,22 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { -@@ -217,7 +218,9 @@ __copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) - if (tocopy > n) - tocopy = n; + /* Setup the DMA parameters */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, +- BCM2835_I2S_RXTHR(1) +- | BCM2835_I2S_TXTHR(1) +- | BCM2835_I2S_DMAEN, 0xffffffff); ++ BCM2835_I2S_RXTHR(3) ++ | BCM2835_I2S_TXTHR(3) ++ | BCM2835_I2S_DMAEN, ++ BCM2835_I2S_RXTHR(1) ++ | BCM2835_I2S_TXTHR(1) ++ | BCM2835_I2S_DMAEN); -+ ua_flags = uaccess_save_and_enable(); - memcpy(to, (const void *)from, tocopy); -+ uaccess_restore(ua_flags); - to += tocopy; - from += tocopy; - n -= tocopy; -@@ -261,9 +264,14 @@ arm_copy_from_user(void *to, const void __user *from, unsigned long n) - * With frame pointer disabled, tail call optimization kicks in - * as well making this test almost invisible. - */ -- if (n < COPY_FROM_USER_THRESHOLD) -- return __copy_from_user_std(to, from, n); -- return __copy_from_user_memcpy(to, from, n); -+ if (n < COPY_TO_USER_THRESHOLD) { -+ unsigned long ua_flags = uaccess_save_and_enable(); -+ n = __copy_from_user_std(to, from, n); -+ uaccess_restore(ua_flags); -+ } else { -+ n = __copy_from_user_memcpy(to, from, n); -+ } -+ return n; - } - - static unsigned long noinline + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, +- BCM2835_I2S_TX_PANIC(0x10) +- | BCM2835_I2S_RX_PANIC(0x30) +- | BCM2835_I2S_TX(0x30) +- | BCM2835_I2S_RX(0x20), 0xffffffff); ++ BCM2835_I2S_TX_PANIC(0x7f) ++ | BCM2835_I2S_RX_PANIC(0x7f) ++ | BCM2835_I2S_TX(0x7f) ++ | BCM2835_I2S_RX(0x7f), ++ BCM2835_I2S_TX_PANIC(0x10) ++ | BCM2835_I2S_RX_PANIC(0x30) ++ | BCM2835_I2S_TX(0x20) ++ | BCM2835_I2S_RX(0x20)); + + /* Clear FIFOs */ + bcm2835_i2s_clear_fifos(dev, true, true); -From 6abb732a5e79d2ab8384b6b70fd17e5347f59d0e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 16:33:09 +0100 -Subject: [PATCH 212/251] bcm2835-sdhost: Adjust to core clock changes - -The SDHOST block uses the core clock, so previously it has been -necessary to prevent the core clock from changing in order to maintain -performance and prevent accidental SD bus overclocking. - -With this patch the sdhost driver is notified of clock changes, allowing -it to delay them while an SD access is outstanding and to delay new SD -accesses while the clock is changing. This feature is disabled in the -case where the core frequency can never change. - -Now that the driver copes with changes to the core clock, it is safe -to disable the io_is_busy feature of the on-demand governor. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/Kconfig | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++++++++++++++++++++++++++++------ - 2 files changed, 119 insertions(+), 22 deletions(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index d509d10..98a7fa5 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -36,6 +36,7 @@ config MMC_BCM2835_PIO_DMA_BARRIER - config MMC_BCM2835_SDHOST - tristate "Support for the SDHost controller on BCM2708/9" - depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ depends on RASPBERRYPI_FIRMWARE - help - This selects the SDHost controller on BCM2835/6. - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index f43aae0..1deecef 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -50,6 +50,10 @@ - #include - #include - #include -+#include -+#include -+#include -+ - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -136,6 +140,8 @@ - - #define MHZ 1000000 - -+#define RPI_FIRMWARE_CLOCK_CORE 4 -+ - - struct bcm2835_host { - spinlock_t lock; -@@ -151,7 +157,9 @@ struct bcm2835_host { - - bool slow_card; /* Force 11-bit divisor */ - -- unsigned int max_clk; /* Max possible freq */ -+ unsigned int max_clk; /* Max src clock freq */ -+ unsigned int min_clk; /* Min src clock freq */ -+ unsigned int cur_clk; /* Current src clock freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -183,6 +191,7 @@ struct bcm2835_host { - unsigned int use_sbc:1; /* Send CMD23 */ - - unsigned int debug:1; /* Enable debug output */ -+ unsigned int variable_clock:1; /* The core clock may change */ - - /*DMA part*/ - struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -@@ -208,6 +217,9 @@ struct bcm2835_host { - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -+ -+ struct notifier_block cpufreq_nb; /* The cpufreq callback list item */ -+ struct semaphore cpufreq_semaphore; /* Interlock between SD activity and cpufreq changes */ - }; - - #if ENABLE_LOG -@@ -227,6 +239,10 @@ static u32 sdhost_log_idx; - static spinlock_t log_lock; - static void __iomem *timer_base; - -+static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -+ unsigned long action, void *data); -+static unsigned int get_core_clock(unsigned int mode); -+ - #define LOG_ENTRIES (256*1) - #define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) - -@@ -448,20 +464,14 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - --static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -+static void bcm2835_sdhost_init(struct bcm2835_host *host) - { -- pr_debug("bcm2835_sdhost_init(%d)\n", soft); -+ pr_debug("bcm2835_sdhost_init()\n"); - - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - - bcm2835_sdhost_reset_internal(host); -- -- if (soft) { -- /* force clock reconfiguration */ -- host->clock = 0; -- bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -- } - } - - static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) -@@ -1499,10 +1509,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ -- unsigned int input_clock = clock; -+ unsigned int clock = host->clock; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1543,17 +1553,17 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - return; - } - -- div = host->max_clk / clock; -+ div = host->cur_clk / clock; - if (div < 2) - div = 2; -- if ((host->max_clk / div) > clock) -+ if ((host->cur_clk / div) > clock) - div++; - div -= 2; - - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- clock = host->max_clk / (div + 2); -+ clock = host->cur_clk / (div + 2); - host->mmc->actual_clock = clock; - - /* Calibrate some delays */ -@@ -1561,7 +1571,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->ns_per_fifo_word = (1000000000/clock) * - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); - -- if (clock > input_clock) { -+ if (clock > host->clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ - host->overclock_50 = (clock/MHZ); -@@ -1587,9 +1597,9 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) -- pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), input_clock, -- host->max_clk, host->cdiv, host->mmc->actual_clock); -+ pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->cur_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1638,6 +1648,13 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - (mrq->data->blocks > host->pio_limit)) - bcm2835_sdhost_prepare_dma(host, mrq->data); - -+ if (host->variable_clock && -+ (down_killable(&host->cpufreq_semaphore) != 0)) { -+ mrq->cmd->error = -EINTR; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1687,6 +1704,52 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - spin_unlock_irqrestore(&host->lock, flags); - } - -+static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -+ unsigned long action, void *data) -+{ -+ struct cpufreq_freqs *freq = data; -+ struct bcm2835_host *host; -+ -+ host = container_of(nb, struct bcm2835_host, cpufreq_nb); -+ -+ if (freq->cpu == 0) { -+ switch (action) { -+ case CPUFREQ_PRECHANGE: -+ if (down_killable(&host->cpufreq_semaphore) != 0) -+ return NOTIFY_BAD; -+ break; -+ case CPUFREQ_POSTCHANGE: -+ if (freq->new > freq->old) -+ host->cur_clk = host->max_clk; -+ else -+ host->cur_clk = host->min_clk; -+ bcm2835_sdhost_set_clock(host); -+ up(&host->cpufreq_semaphore); -+ break; -+ default: -+ break; -+ } -+ } -+ return NOTIFY_OK; -+} -+ -+static unsigned int get_core_clock(unsigned int mode) -+{ -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; -+ -+ packet.id = RPI_FIRMWARE_CLOCK_CORE; -+ ret = rpi_firmware_property(fw, mode, &packet, sizeof(packet)); -+ if (ret) -+ return 0; -+ -+ return packet.val; -+} -+ - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { - -@@ -1700,13 +1763,16 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -+ if (ios->clock && !host->cur_clk) -+ host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ - spin_lock_irqsave(&host->lock, flags); - - log_event("IOS<", ios->clock, 0); - - if (!ios->clock || ios->clock != host->clock) { -- bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -+ bcm2835_sdhost_set_clock(host); - } - - /* set bus width */ -@@ -1795,7 +1861,7 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); -- bcm2835_sdhost_set_clock(host,50*MHZ); -+ bcm2835_sdhost_set_clock(host); - mrq->cmd->error = -EILSEQ; - mrq->cmd->retries = 1; - } -@@ -1813,6 +1879,9 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - spin_unlock_irqrestore(&host->lock, flags); - -+ if (host->variable_clock) -+ up(&host->cpufreq_semaphore); -+ - if (terminate_chan) - { - int err = dmaengine_terminate_all(terminate_chan); -@@ -1915,10 +1984,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - -- bcm2835_sdhost_init(host, 0); -+ bcm2835_sdhost_init(host); - - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -- mmc_hostname(mmc), host); -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -1953,6 +2022,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -+ unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2062,6 +2132,28 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - if (ret) - goto err; - -+ /* Query the core clock frequencies */ -+ host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); -+ if (max_clk != host->max_clk) { -+ pr_warn("%s: Expected max clock %d, found %d\n", -+ mmc_hostname(mmc), host->max_clk, max_clk); -+ host->max_clk = max_clk; -+ } -+ -+ if (host->min_clk != host->max_clk) { -+ host->cpufreq_nb.notifier_call = -+ bcm2835_sdhost_cpufreq_callback; -+ sema_init(&host->cpufreq_semaphore, 1); -+ cpufreq_register_notifier(&host->cpufreq_nb, -+ CPUFREQ_TRANSITION_NOTIFIER); -+ host->variable_clock = 1; -+ host->cur_clk = 0; /* Get this later */ -+ } else { -+ host->variable_clock = 0; -+ host->cur_clk = host->max_clk; -+ } -+ - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); -@@ -2081,6 +2173,10 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - - pr_debug("bcm2835_sdhost_remove\n"); - -+ if (host->variable_clock) -+ cpufreq_unregister_notifier(&host->cpufreq_nb, -+ CPUFREQ_TRANSITION_NOTIFIER); -+ - mmc_remove_host(host->mmc); - - bcm2835_sdhost_set_power(host, false); - -From 788985576c5b7f413466d4ea5e1b9c471ff2b7fc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 17:07:15 +0100 -Subject: [PATCH 213/251] BCM270X_DT: Document hazards of sdhost overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index e88e7c8..337be4a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -712,7 +712,11 @@ Params: - - - Name: sdhost --Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock. -+ N.B. This overlay is designed for situations where the mmc driver is -+ the default, so it disables the other (mmc) interface - this will kill -+ WiFi on a Pi3. If this isn't what you want, either use the sdtweak -+ overlay or the new sd_* dtparams of the base DTBs. - Load: dtoverlay=sdhost,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -@@ -771,6 +775,8 @@ Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver -+ N.B. This functionality is now available via the sd_* dtparams in the -+ base DTB. - Load: dtoverlay=sdtweak,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz - -From 58fb42a1ecf4bec15d3236183955f4b54f199e75 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 17:23:15 +0100 -Subject: [PATCH 214/251] cpufreq: Temporarily ignore io_is_busy=1 - -To speed testing of the new sdhost driver that adapts to changes in -core_freq, hack the on-demand governor to treat io_is_busy=1 as -io_is_busy=0. The io_is_busy feature can still be forced using -io_is_busy=2. - -Signed-off-by: Phil Elwell ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 03ac6ce..99a9610 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- od_tuners->io_is_busy = !!input; -+ // XXX temporary hack -+ if (input > 1) -+ input = 1; -+ else -+ input = 0; -+ od_tuners->io_is_busy = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From 8bf41d1b2f41d6af2c196497168d3cc8f97a0071 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 20:18:38 +0100 -Subject: [PATCH 215/251] Revert "cpufreq: Temporarily ignore io_is_busy=1" - -This reverts commit 2af1218a8a0220fec526f64d03977b8451afb4c8. ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 99a9610..03ac6ce 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,12 +307,7 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- // XXX temporary hack -- if (input > 1) -- input = 1; -- else -- input = 0; -- od_tuners->io_is_busy = input; -+ od_tuners->io_is_busy = !!input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From f9634b17e0d05988abbe329efd4b9eee59aadb0c Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Thu, 7 Jan 2016 15:50:22 +0100 -Subject: [PATCH 216/251] net, sched: add skb_at_tc_ingress helper - -Add a skb_at_tc_ingress() as this will be needed elsewhere as well and -can hide the ugly ifdef. - -Signed-off-by: Daniel Borkmann -Acked-by: Alexei Starovoitov -Signed-off-by: David S. Miller ---- - include/net/sch_generic.h | 9 +++++++++ - net/sched/cls_bpf.c | 6 +----- - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h -index b2a8e63..636a362 100644 ---- a/include/net/sch_generic.h -+++ b/include/net/sch_generic.h -@@ -407,6 +407,15 @@ bool tcf_destroy(struct tcf_proto *tp, bool force); - void tcf_destroy_chain(struct tcf_proto __rcu **fl); - int skb_do_redirect(struct sk_buff *); - -+static inline bool skb_at_tc_ingress(const struct sk_buff *skb) -+{ -+#ifdef CONFIG_NET_CLS_ACT -+ return G_TC_AT(skb->tc_verd) & AT_INGRESS; -+#else -+ return false; -+#endif -+} -+ - /* Reset all TX qdiscs greater then index of a device. */ - static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) - { -diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c -index 5faaa54..b3c8bb4 100644 ---- a/net/sched/cls_bpf.c -+++ b/net/sched/cls_bpf.c -@@ -79,12 +79,8 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp, - struct tcf_result *res) - { - struct cls_bpf_head *head = rcu_dereference_bh(tp->root); -+ bool at_ingress = skb_at_tc_ingress(skb); - struct cls_bpf_prog *prog; --#ifdef CONFIG_NET_CLS_ACT -- bool at_ingress = G_TC_AT(skb->tc_verd) & AT_INGRESS; --#else -- bool at_ingress = false; --#endif - int ret = -1; - - if (unlikely(!skb_mac_header_was_set(skb))) - -From de42773e4545e48e35472cdf01f1bcb7af1f27cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Linus=20L=C3=BCssing?= -Date: Wed, 24 Feb 2016 04:21:42 +0100 -Subject: [PATCH 217/251] net: fix bridge multicast packet checksum validation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We need to update the skb->csum after pulling the skb, otherwise -an unnecessary checksum (re)computation can ocure for IGMP/MLD packets -in the bridge code. Additionally this fixes the following splats for -network devices / bridge ports with support for and enabled RX checksum -offloading: - -[...] -[ 43.986968] eth0: hw csum failure -[ 43.990344] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.4.0 #2 -[ 43.996193] Hardware name: BCM2709 -[ 43.999647] [<800204e0>] (unwind_backtrace) from [<8001cf14>] (show_stack+0x10/0x14) -[ 44.007432] [<8001cf14>] (show_stack) from [<801ab614>] (dump_stack+0x80/0x90) -[ 44.014695] [<801ab614>] (dump_stack) from [<802e4548>] (__skb_checksum_complete+0x6c/0xac) -[ 44.023090] [<802e4548>] (__skb_checksum_complete) from [<803a055c>] (ipv6_mc_validate_checksum+0x104/0x178) -[ 44.032959] [<803a055c>] (ipv6_mc_validate_checksum) from [<802e111c>] (skb_checksum_trimmed+0x130/0x188) -[ 44.042565] [<802e111c>] (skb_checksum_trimmed) from [<803a06e8>] (ipv6_mc_check_mld+0x118/0x338) -[ 44.051501] [<803a06e8>] (ipv6_mc_check_mld) from [<803b2c98>] (br_multicast_rcv+0x5dc/0xd00) -[ 44.060077] [<803b2c98>] (br_multicast_rcv) from [<803aa510>] (br_handle_frame_finish+0xac/0x51c) -[...] - -Fixes: 9afd85c9e455 ("net: Export IGMP/MLD message validation code") -Reported-by: Álvaro Fernández Rojas -Signed-off-by: Linus Lüssing -Signed-off-by: David S. Miller ---- - net/core/skbuff.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 5bf88f5..8616d11 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -2948,6 +2948,24 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page, - EXPORT_SYMBOL_GPL(skb_append_pagefrags); - - /** -+ * skb_push_rcsum - push skb and update receive checksum -+ * @skb: buffer to update -+ * @len: length of data pulled -+ * -+ * This function performs an skb_push on the packet and updates -+ * the CHECKSUM_COMPLETE checksum. It should be used on -+ * receive path processing instead of skb_push unless you know -+ * that the checksum difference is zero (e.g., a valid IP header) -+ * or you are setting ip_summed to CHECKSUM_NONE. -+ */ -+static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len) -+{ -+ skb_push(skb, len); -+ skb_postpush_rcsum(skb, skb->data, len); -+ return skb->data; -+} -+ -+/** - * skb_pull_rcsum - pull skb and update receive checksum - * @skb: buffer to update - * @len: length of data pulled -@@ -4084,9 +4102,9 @@ struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb, - if (!pskb_may_pull(skb_chk, offset)) - goto err; - -- __skb_pull(skb_chk, offset); -+ skb_pull_rcsum(skb_chk, offset); - ret = skb_chkf(skb_chk); -- __skb_push(skb_chk, offset); -+ skb_push_rcsum(skb_chk, offset); - - if (ret) - goto err; - -From 2c0f60ed53c5a180397b2b740bbf796e09471012 Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Thu, 7 Jan 2016 15:50:23 +0100 -Subject: [PATCH 218/251] bpf: add skb_postpush_rcsum and fix dev_forward_skb - occasions - -Add a small helper skb_postpush_rcsum() and fix up redirect locations -that need CHECKSUM_COMPLETE fixups on ingress. dev_forward_skb() expects -a proper csum that covers also Ethernet header, f.e. since 2c26d34bbcc0 -("net/core: Handle csum for CHECKSUM_COMPLETE VXLAN forwarding"), we -also do skb_postpull_rcsum() after pulling Ethernet header off via -eth_type_trans(). - -When using eBPF in a netns setup f.e. with vxlan in collect metadata mode, -I can trigger the following csum issue with an IPv6 setup: - - [ 505.144065] dummy1: hw csum failure - [...] - [ 505.144108] Call Trace: - [ 505.144112] [] dump_stack+0x44/0x5c - [ 505.144134] [] netdev_rx_csum_fault+0x3a/0x40 - [ 505.144142] [] __skb_checksum_complete+0xcf/0xe0 - [ 505.144149] [] nf_ip6_checksum+0xb2/0x120 - [ 505.144161] [] icmpv6_error+0x17e/0x328 [nf_conntrack_ipv6] - [ 505.144170] [] ? ip6t_do_table+0x2fa/0x645 [ip6_tables] - [ 505.144177] [] ? ipv6_get_l4proto+0x65/0xd0 [nf_conntrack_ipv6] - [ 505.144189] [] nf_conntrack_in+0xc2/0x5a0 [nf_conntrack] - [ 505.144196] [] ipv6_conntrack_in+0x1c/0x20 [nf_conntrack_ipv6] - [ 505.144204] [] nf_iterate+0x5d/0x70 - [ 505.144210] [] nf_hook_slow+0x66/0xc0 - [ 505.144218] [] ipv6_rcv+0x3f2/0x4f0 - [ 505.144225] [] ? ip6_make_skb+0x1b0/0x1b0 - [ 505.144232] [] __netif_receive_skb_core+0x36b/0x9a0 - [ 505.144239] [] ? __netif_receive_skb+0x18/0x60 - [ 505.144245] [] __netif_receive_skb+0x18/0x60 - [ 505.144252] [] process_backlog+0x9f/0x140 - [ 505.144259] [] net_rx_action+0x145/0x320 - [...] - -What happens is that on ingress, we push Ethernet header back in, either -from cls_bpf or right before skb_do_redirect(), but without updating csum. -The "hw csum failure" can be fixed by using the new skb_postpush_rcsum() -helper for the dev_forward_skb() case to correct the csum diff again. - -Thanks to Hannes Frederic Sowa for the csum_partial() idea! - -Fixes: 3896d655f4d4 ("bpf: introduce bpf_clone_redirect() helper") -Fixes: 27b29f63058d ("bpf: add bpf_redirect() helper") -Signed-off-by: Daniel Borkmann -Acked-by: Alexei Starovoitov -Signed-off-by: David S. Miller ---- - include/linux/skbuff.h | 17 +++++++++++++++++ - net/core/filter.c | 17 +++++++++++++---- - 2 files changed, 30 insertions(+), 4 deletions(-) - -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 75f136a..d84c593 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2724,6 +2724,23 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb, - - unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); - -+static inline void skb_postpush_rcsum(struct sk_buff *skb, -+ const void *start, unsigned int len) -+{ -+ /* For performing the reverse operation to skb_postpull_rcsum(), -+ * we can instead of ... -+ * -+ * skb->csum = csum_add(skb->csum, csum_partial(start, len, 0)); -+ * -+ * ... just use this equivalent version here to save a few -+ * instructions. Feeding csum of 0 in csum_partial() and later -+ * on adding skb->csum is equivalent to feed skb->csum in the -+ * first place. -+ */ -+ if (skb->ip_summed == CHECKSUM_COMPLETE) -+ skb->csum = csum_partial(start, len, skb->csum); -+} -+ - /** - * pskb_trim_rcsum - trim received skb and update checksum - * @skb: buffer to trim -diff --git a/net/core/filter.c b/net/core/filter.c -index 37157c4..6e337ea 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1288,8 +1288,9 @@ static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) - /* skb_store_bits cannot return -EFAULT here */ - skb_store_bits(skb, offset, ptr, len); - -- if (BPF_RECOMPUTE_CSUM(flags) && skb->ip_summed == CHECKSUM_COMPLETE) -- skb->csum = csum_add(skb->csum, csum_partial(ptr, len, 0)); -+ if (BPF_RECOMPUTE_CSUM(flags)) -+ skb_postpush_rcsum(skb, ptr, len); -+ - return 0; - } - -@@ -1415,8 +1416,12 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5) - if (unlikely(!skb2)) - return -ENOMEM; - -- if (BPF_IS_REDIRECT_INGRESS(flags)) -+ if (BPF_IS_REDIRECT_INGRESS(flags)) { -+ if (skb_at_tc_ingress(skb2)) -+ skb_postpush_rcsum(skb2, skb_mac_header(skb2), -+ skb2->mac_len); - return dev_forward_skb(dev, skb2); -+ } - - skb2->dev = dev; - skb_sender_cpu_clear(skb2); -@@ -1459,8 +1464,12 @@ int skb_do_redirect(struct sk_buff *skb) - return -EINVAL; - } - -- if (BPF_IS_REDIRECT_INGRESS(ri->flags)) -+ if (BPF_IS_REDIRECT_INGRESS(ri->flags)) { -+ if (skb_at_tc_ingress(skb)) -+ skb_postpush_rcsum(skb, skb_mac_header(skb), -+ skb->mac_len); - return dev_forward_skb(dev, skb); -+ } - - skb->dev = dev; - skb_sender_cpu_clear(skb); - -From 67ba5d253f79ddbf1c28d7e3cb48efd0b845f87c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 31 Mar 2016 15:44:53 +0100 -Subject: [PATCH 219/251] bcm2835-sdhost: Precalc divisors and overclocks - -Recalculating the clock divisors when the core clock changes is wasteful -and makes it harder to manage the overclock settings. Instead, -precalculate them and only report significant changes. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++++++++---------------- - 1 file changed, 88 insertions(+), 64 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 1deecef..cc18ec8 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -154,12 +154,15 @@ struct bcm2835_host { - u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ -+ int clocks[2]; - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max src clock freq */ -- unsigned int min_clk; /* Min src clock freq */ -- unsigned int cur_clk; /* Current src clock freq */ -+ unsigned int src_clks[2]; /* Min/max src clock freqs */ -+ unsigned int cur_clk_idx; /* Index of current clock */ -+ unsigned int next_clk_idx; /* Next clock index */ -+ unsigned int cdivs[2]; - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -213,7 +216,7 @@ struct bcm2835_host { - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 overclock; /* Current frequency if overclocked, else zero */ -+ u32 prev_overclock_50; - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -@@ -1509,10 +1512,35 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - -+static void bcm2835_sdhost_select_clock(struct bcm2835_host *host, int idx) -+{ -+ unsigned int clock = host->clocks[idx]; -+ unsigned int cdiv = host->cdivs[idx]; -+ -+ host->mmc->actual_clock = clock; -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ -+ host->cdiv = cdiv; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, clock/2, SDTOUT); -+ -+ host->cur_clk_idx = host->next_clk_idx = idx; -+ -+ if (host->debug) -+ pr_info("%s: clock=%d -> src_clk=%d, cdiv=%x (actual %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->src_clks[idx], host->cdiv, -+ host->mmc->actual_clock); -+} -+ - void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ - unsigned int clock = host->clock; -+ int clk_idx; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1553,53 +1581,45 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- div = host->cur_clk / clock; -- if (div < 2) -- div = 2; -- if ((host->cur_clk / div) > clock) -- div++; -- div -= 2; -- -- if (div > SDCDIV_MAX_CDIV) -- div = SDCDIV_MAX_CDIV; -- -- clock = host->cur_clk / (div + 2); -- host->mmc->actual_clock = clock; -- -- /* Calibrate some delays */ -- -- host->ns_per_fifo_word = (1000000000/clock) * -- ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -- -- if (clock > host->clock) { -- /* Save the closest value, to make it easier -- to reduce in the event of error */ -- host->overclock_50 = (clock/MHZ); -- -- if (clock != host->overclock) { -- pr_warn("%s: overclocking to %dHz\n", -- mmc_hostname(host->mmc), clock); -- host->overclock = clock; -- } -- } -- else if (host->overclock) -+ /* Calculate the clock divisors */ -+ for (clk_idx = 0; clk_idx <= host->variable_clock; clk_idx++) - { -- host->overclock = 0; -- if (clock == 50 * MHZ) -- pr_warn("%s: cancelling overclock\n", -- mmc_hostname(host->mmc)); -+ unsigned int cur_clk = host->src_clks[clk_idx]; -+ unsigned int actual_clock; -+ -+ div = cur_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((cur_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ actual_clock = cur_clk / (div + 2); -+ -+ host->cdivs[clk_idx] = div; -+ host->clocks[clk_idx] = actual_clock; -+ -+ if (host->overclock_50 != host->prev_overclock_50) { -+ const char *clk_name = ""; -+ if (host->variable_clock) -+ clk_name = clk_idx ? " (turbo)" : " (normal)"; -+ if (actual_clock > host->clock) -+ pr_info("%s: overclocking to %dHz%s\n", -+ mmc_hostname(host->mmc), -+ actual_clock, clk_name); -+ else if ((host->overclock_50 < 50) && (clk_idx == 0)) -+ pr_info("%s: cancelling overclock%s\n", -+ mmc_hostname(host->mmc), -+ host->variable_clock ? "s" : ""); -+ } - } - -- host->cdiv = div; -- bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -- -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ if (host->clock == 50*MHZ) -+ host->prev_overclock_50 = host->overclock_50; - -- if (host->debug) -- pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->cur_clk, host->cdiv, host->mmc->actual_clock); -+ bcm2835_sdhost_select_clock(host, host->cur_clk_idx); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1657,6 +1677,9 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - - spin_lock_irqsave(&host->lock, flags); - -+ if (host->next_clk_idx != host->cur_clk_idx) -+ bcm2835_sdhost_select_clock(host, host->next_clk_idx); -+ - WARN_ON(host->mrq != NULL); - host->mrq = mrq; - -@@ -1719,11 +1742,7 @@ static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, - return NOTIFY_BAD; - break; - case CPUFREQ_POSTCHANGE: -- if (freq->new > freq->old) -- host->cur_clk = host->max_clk; -- else -- host->cur_clk = host->min_clk; -- bcm2835_sdhost_set_clock(host); -+ host->next_clk_idx = (freq->new > freq->old); - up(&host->cpufreq_semaphore); - break; - default: -@@ -1763,8 +1782,11 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && !host->cur_clk) -- host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ if (ios->clock && (host->cur_clk_idx == -1)) { -+ unsigned int cur_clk = -+ get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ host->cur_clk_idx = (cur_clk == host->src_clks[0]) ? 0 : 1; -+ } - - spin_lock_irqsave(&host->lock, flags); - -@@ -1854,11 +1876,12 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (host->overclock) { -+ if (host->clock > 50*MHZ) { - if ((mrq->cmd && mrq->cmd->error) || - (mrq->data && mrq->data->error) || - (mrq->stop && mrq->stop->error)) { -- host->overclock_50--; -+ host->overclock_50 = (host->clock/MHZ) - 1; -+ - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_set_clock(host); -@@ -2022,7 +2045,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk; -+ unsigned int max_clk, min_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2128,12 +2151,8 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - else - mmc->caps |= MMC_CAP_4_BIT_DATA; - -- ret = bcm2835_sdhost_add_host(host); -- if (ret) -- goto err; -- - /* Query the core clock frequencies */ -- host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); - max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - if (max_clk != host->max_clk) { - pr_warn("%s: Expected max clock %d, found %d\n", -@@ -2141,19 +2160,24 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->max_clk = max_clk; - } - -- if (host->min_clk != host->max_clk) { -+ host->src_clks[0] = min_clk; -+ host->cur_clk_idx = -1; -+ if (max_clk != min_clk) { -+ host->src_clks[1] = max_clk; - host->cpufreq_nb.notifier_call = - bcm2835_sdhost_cpufreq_callback; - sema_init(&host->cpufreq_semaphore, 1); - cpufreq_register_notifier(&host->cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - host->variable_clock = 1; -- host->cur_clk = 0; /* Get this later */ - } else { - host->variable_clock = 0; -- host->cur_clk = host->max_clk; - } - -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); - -From 7a21e0c9d567d27b000ef8350ee503776720852d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Apr 2016 12:35:32 +0100 -Subject: [PATCH 220/251] Revert "bcm2835-sdhost: Precalc divisors and - overclocks" - -This reverts commit 20260462773366a5734e5268dae0a4c179a21a2d. ---- - drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++---------------------- - 1 file changed, 64 insertions(+), 88 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index cc18ec8..1deecef 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -154,15 +154,12 @@ struct bcm2835_host { - u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ -- int clocks[2]; - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max src clock freq */ -- unsigned int src_clks[2]; /* Min/max src clock freqs */ -- unsigned int cur_clk_idx; /* Index of current clock */ -- unsigned int next_clk_idx; /* Next clock index */ -- unsigned int cdivs[2]; -+ unsigned int min_clk; /* Min src clock freq */ -+ unsigned int cur_clk; /* Current src clock freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -216,7 +213,7 @@ struct bcm2835_host { - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 prev_overclock_50; -+ u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -@@ -1512,35 +1509,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --static void bcm2835_sdhost_select_clock(struct bcm2835_host *host, int idx) --{ -- unsigned int clock = host->clocks[idx]; -- unsigned int cdiv = host->cdivs[idx]; -- -- host->mmc->actual_clock = clock; -- host->ns_per_fifo_word = (1000000000/clock) * -- ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -- -- host->cdiv = cdiv; -- bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -- -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, clock/2, SDTOUT); -- -- host->cur_clk_idx = host->next_clk_idx = idx; -- -- if (host->debug) -- pr_info("%s: clock=%d -> src_clk=%d, cdiv=%x (actual %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->src_clks[idx], host->cdiv, -- host->mmc->actual_clock); --} -- - void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ - unsigned int clock = host->clock; -- int clk_idx; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1581,45 +1553,53 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- /* Calculate the clock divisors */ -- for (clk_idx = 0; clk_idx <= host->variable_clock; clk_idx++) -- { -- unsigned int cur_clk = host->src_clks[clk_idx]; -- unsigned int actual_clock; -- -- div = cur_clk / clock; -- if (div < 2) -- div = 2; -- if ((cur_clk / div) > clock) -- div++; -- div -= 2; -- -- if (div > SDCDIV_MAX_CDIV) -- div = SDCDIV_MAX_CDIV; -- actual_clock = cur_clk / (div + 2); -- -- host->cdivs[clk_idx] = div; -- host->clocks[clk_idx] = actual_clock; -- -- if (host->overclock_50 != host->prev_overclock_50) { -- const char *clk_name = ""; -- if (host->variable_clock) -- clk_name = clk_idx ? " (turbo)" : " (normal)"; -- if (actual_clock > host->clock) -- pr_info("%s: overclocking to %dHz%s\n", -- mmc_hostname(host->mmc), -- actual_clock, clk_name); -- else if ((host->overclock_50 < 50) && (clk_idx == 0)) -- pr_info("%s: cancelling overclock%s\n", -- mmc_hostname(host->mmc), -- host->variable_clock ? "s" : ""); -+ div = host->cur_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((host->cur_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ -+ clock = host->cur_clk / (div + 2); -+ host->mmc->actual_clock = clock; -+ -+ /* Calibrate some delays */ -+ -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ -+ if (clock > host->clock) { -+ /* Save the closest value, to make it easier -+ to reduce in the event of error */ -+ host->overclock_50 = (clock/MHZ); -+ -+ if (clock != host->overclock) { -+ pr_warn("%s: overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->overclock = clock; - } - } -+ else if (host->overclock) -+ { -+ host->overclock = 0; -+ if (clock == 50 * MHZ) -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); -+ } -+ -+ host->cdiv = div; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- if (host->clock == 50*MHZ) -- host->prev_overclock_50 = host->overclock_50; -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - -- bcm2835_sdhost_select_clock(host, host->cur_clk_idx); -+ if (host->debug) -+ pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->cur_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1677,9 +1657,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - - spin_lock_irqsave(&host->lock, flags); - -- if (host->next_clk_idx != host->cur_clk_idx) -- bcm2835_sdhost_select_clock(host, host->next_clk_idx); -- - WARN_ON(host->mrq != NULL); - host->mrq = mrq; - -@@ -1742,7 +1719,11 @@ static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, - return NOTIFY_BAD; - break; - case CPUFREQ_POSTCHANGE: -- host->next_clk_idx = (freq->new > freq->old); -+ if (freq->new > freq->old) -+ host->cur_clk = host->max_clk; -+ else -+ host->cur_clk = host->min_clk; -+ bcm2835_sdhost_set_clock(host); - up(&host->cpufreq_semaphore); - break; - default: -@@ -1782,11 +1763,8 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && (host->cur_clk_idx == -1)) { -- unsigned int cur_clk = -- get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -- host->cur_clk_idx = (cur_clk == host->src_clks[0]) ? 0 : 1; -- } -+ if (ios->clock && !host->cur_clk) -+ host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1876,12 +1854,11 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (host->clock > 50*MHZ) { -+ if (host->overclock) { - if ((mrq->cmd && mrq->cmd->error) || - (mrq->data && mrq->data->error) || - (mrq->stop && mrq->stop->error)) { -- host->overclock_50 = (host->clock/MHZ) - 1; -- -+ host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_set_clock(host); -@@ -2045,7 +2022,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk, min_clk; -+ unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2151,8 +2128,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - else - mmc->caps |= MMC_CAP_4_BIT_DATA; - -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ - /* Query the core clock frequencies */ -- min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); - max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - if (max_clk != host->max_clk) { - pr_warn("%s: Expected max clock %d, found %d\n", -@@ -2160,24 +2141,19 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->max_clk = max_clk; - } - -- host->src_clks[0] = min_clk; -- host->cur_clk_idx = -1; -- if (max_clk != min_clk) { -- host->src_clks[1] = max_clk; -+ if (host->min_clk != host->max_clk) { - host->cpufreq_nb.notifier_call = - bcm2835_sdhost_cpufreq_callback; - sema_init(&host->cpufreq_semaphore, 1); - cpufreq_register_notifier(&host->cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - host->variable_clock = 1; -+ host->cur_clk = 0; /* Get this later */ - } else { - host->variable_clock = 0; -+ host->cur_clk = host->max_clk; - } - -- ret = bcm2835_sdhost_add_host(host); -- if (ret) -- goto err; -- - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); - -From a44f96721ff123198ef527c1471425cc5e2ee1b1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Apr 2016 12:35:51 +0100 -Subject: [PATCH 221/251] Revert "bcm2835-sdhost: Adjust to core clock changes" - -This reverts commit 4b89d07fd299a0f4e25321920cb74416ba2e638e. ---- - drivers/mmc/host/Kconfig | 1 - - drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++-------------------------------- - 2 files changed, 22 insertions(+), 119 deletions(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 98a7fa5..d509d10 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -36,7 +36,6 @@ config MMC_BCM2835_PIO_DMA_BARRIER - config MMC_BCM2835_SDHOST - tristate "Support for the SDHost controller on BCM2708/9" - depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -- depends on RASPBERRYPI_FIRMWARE - help - This selects the SDHost controller on BCM2835/6. - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 1deecef..f43aae0 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -50,10 +50,6 @@ - #include - #include - #include --#include --#include --#include -- - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -140,8 +136,6 @@ - - #define MHZ 1000000 - --#define RPI_FIRMWARE_CLOCK_CORE 4 -- - - struct bcm2835_host { - spinlock_t lock; -@@ -157,9 +151,7 @@ struct bcm2835_host { - - bool slow_card; /* Force 11-bit divisor */ - -- unsigned int max_clk; /* Max src clock freq */ -- unsigned int min_clk; /* Min src clock freq */ -- unsigned int cur_clk; /* Current src clock freq */ -+ unsigned int max_clk; /* Max possible freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -191,7 +183,6 @@ struct bcm2835_host { - unsigned int use_sbc:1; /* Send CMD23 */ - - unsigned int debug:1; /* Enable debug output */ -- unsigned int variable_clock:1; /* The core clock may change */ - - /*DMA part*/ - struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -@@ -217,9 +208,6 @@ struct bcm2835_host { - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -- -- struct notifier_block cpufreq_nb; /* The cpufreq callback list item */ -- struct semaphore cpufreq_semaphore; /* Interlock between SD activity and cpufreq changes */ - }; - - #if ENABLE_LOG -@@ -239,10 +227,6 @@ static u32 sdhost_log_idx; - static spinlock_t log_lock; - static void __iomem *timer_base; - --static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -- unsigned long action, void *data); --static unsigned int get_core_clock(unsigned int mode); -- - #define LOG_ENTRIES (256*1) - #define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) - -@@ -464,14 +448,20 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - --static void bcm2835_sdhost_init(struct bcm2835_host *host) -+static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - { -- pr_debug("bcm2835_sdhost_init()\n"); -+ pr_debug("bcm2835_sdhost_init(%d)\n", soft); - - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - - bcm2835_sdhost_reset_internal(host); -+ -+ if (soft) { -+ /* force clock reconfiguration */ -+ host->clock = 0; -+ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -+ } - } - - static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) -@@ -1509,10 +1499,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --void bcm2835_sdhost_set_clock(struct bcm2835_host *host) -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -- unsigned int clock = host->clock; -+ unsigned int input_clock = clock; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1553,17 +1543,17 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- div = host->cur_clk / clock; -+ div = host->max_clk / clock; - if (div < 2) - div = 2; -- if ((host->cur_clk / div) > clock) -+ if ((host->max_clk / div) > clock) - div++; - div -= 2; - - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- clock = host->cur_clk / (div + 2); -+ clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - - /* Calibrate some delays */ -@@ -1571,7 +1561,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - host->ns_per_fifo_word = (1000000000/clock) * - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); - -- if (clock > host->clock) { -+ if (clock > input_clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ - host->overclock_50 = (clock/MHZ); -@@ -1597,9 +1587,9 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) -- pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->cur_clk, host->cdiv, host->mmc->actual_clock); -+ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), input_clock, -+ host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1648,13 +1638,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - (mrq->data->blocks > host->pio_limit)) - bcm2835_sdhost_prepare_dma(host, mrq->data); - -- if (host->variable_clock && -- (down_killable(&host->cpufreq_semaphore) != 0)) { -- mrq->cmd->error = -EINTR; -- mmc_request_done(mmc, mrq); -- return; -- } -- - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1704,52 +1687,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - spin_unlock_irqrestore(&host->lock, flags); - } - --static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -- unsigned long action, void *data) --{ -- struct cpufreq_freqs *freq = data; -- struct bcm2835_host *host; -- -- host = container_of(nb, struct bcm2835_host, cpufreq_nb); -- -- if (freq->cpu == 0) { -- switch (action) { -- case CPUFREQ_PRECHANGE: -- if (down_killable(&host->cpufreq_semaphore) != 0) -- return NOTIFY_BAD; -- break; -- case CPUFREQ_POSTCHANGE: -- if (freq->new > freq->old) -- host->cur_clk = host->max_clk; -- else -- host->cur_clk = host->min_clk; -- bcm2835_sdhost_set_clock(host); -- up(&host->cpufreq_semaphore); -- break; -- default: -- break; -- } -- } -- return NOTIFY_OK; --} -- --static unsigned int get_core_clock(unsigned int mode) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- struct { -- u32 id; -- u32 val; -- } packet; -- int ret; -- -- packet.id = RPI_FIRMWARE_CLOCK_CORE; -- ret = rpi_firmware_property(fw, mode, &packet, sizeof(packet)); -- if (ret) -- return 0; -- -- return packet.val; --} -- - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { - -@@ -1763,16 +1700,13 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && !host->cur_clk) -- host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -- - spin_lock_irqsave(&host->lock, flags); - - log_event("IOS<", ios->clock, 0); - - if (!ios->clock || ios->clock != host->clock) { -+ bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -- bcm2835_sdhost_set_clock(host); - } - - /* set bus width */ -@@ -1861,7 +1795,7 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); -- bcm2835_sdhost_set_clock(host); -+ bcm2835_sdhost_set_clock(host,50*MHZ); - mrq->cmd->error = -EILSEQ; - mrq->cmd->retries = 1; - } -@@ -1879,9 +1813,6 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - spin_unlock_irqrestore(&host->lock, flags); - -- if (host->variable_clock) -- up(&host->cpufreq_semaphore); -- - if (terminate_chan) - { - int err = dmaengine_terminate_all(terminate_chan); -@@ -1984,10 +1915,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - -- bcm2835_sdhost_init(host); -+ bcm2835_sdhost_init(host, 0); - - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -- mmc_hostname(mmc), host); -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -2022,7 +1953,6 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2132,28 +2062,6 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - if (ret) - goto err; - -- /* Query the core clock frequencies */ -- host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -- max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); -- if (max_clk != host->max_clk) { -- pr_warn("%s: Expected max clock %d, found %d\n", -- mmc_hostname(mmc), host->max_clk, max_clk); -- host->max_clk = max_clk; -- } -- -- if (host->min_clk != host->max_clk) { -- host->cpufreq_nb.notifier_call = -- bcm2835_sdhost_cpufreq_callback; -- sema_init(&host->cpufreq_semaphore, 1); -- cpufreq_register_notifier(&host->cpufreq_nb, -- CPUFREQ_TRANSITION_NOTIFIER); -- host->variable_clock = 1; -- host->cur_clk = 0; /* Get this later */ -- } else { -- host->variable_clock = 0; -- host->cur_clk = host->max_clk; -- } -- - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); -@@ -2173,10 +2081,6 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - - pr_debug("bcm2835_sdhost_remove\n"); - -- if (host->variable_clock) -- cpufreq_unregister_notifier(&host->cpufreq_nb, -- CPUFREQ_TRANSITION_NOTIFIER); -- - mmc_remove_host(host->mmc); - - bcm2835_sdhost_set_power(host, false); - -From 99a50a0418f27f7b894ee9668b2ed02b435c9113 Mon Sep 17 00:00:00 2001 +From 3c3beab16b1e6d776d25d1867516bcaa298e58a3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 4 Apr 2016 16:03:18 +0100 -Subject: [PATCH 222/251] bcm2835-sdhost: Firmware manages the clock divisor +Subject: [PATCH 104/114] bcm2835-sdhost: Firmware manages the clock divisor The bcm2835-sdhost driver hands control of the CDIV clock divisor register to matching firmware, allowing it to adjust to a changing @@ -162688,9 +131495,8 @@ lower) than "normal" mode. Signed-off-by: Phil Elwell --- - drivers/mmc/host/bcm2835-sdhost.c | 120 ++++++++++++++++++----------- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 74 insertions(+), 47 deletions(-) + drivers/mmc/host/bcm2835-sdhost.c | 120 +++++++++++++++++++++++--------------- + 1 file changed, 73 insertions(+), 47 deletions(-) diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c index f43aae0..54087b2 100644 @@ -162887,1067 +131693,11 @@ index f43aae0..54087b2 100644 ret = bcm2835_sdhost_add_host(host); if (ret) goto err; -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index c844968..e312e9c 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -79,6 +79,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, - RPI_FIRMWARE_SET_TURBO = 0x00038009, - RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, -+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, - - /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -From 3a3bd335bf71e17af13de24423c806f9a26480b7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 4 Apr 2016 19:52:27 +0100 -Subject: [PATCH 223/251] Revert "Revert "cpufreq: Temporarily ignore - io_is_busy=1"" - -This reverts commit c353af0f83220068c10f6593b1767576b9b6cc18. ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 03ac6ce..99a9610 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- od_tuners->io_is_busy = !!input; -+ // XXX temporary hack -+ if (input > 1) -+ input = 1; -+ else -+ input = 0; -+ od_tuners->io_is_busy = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From 82caca6544d42613722befb52dd121bd9c7d8159 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 31 Mar 2016 16:49:52 +0100 -Subject: [PATCH 224/251] config: Enabled IPV6_SUBTREES - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 2c8e4b7..d509168 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -106,6 +106,7 @@ CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - CONFIG_IPV6_TUNNEL=m - CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IPV6_MROUTE=y - CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y - CONFIG_IPV6_PIMSM_V2=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f6e2d84..060ec5f 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -73,6 +73,7 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IP_ROUTE_MULTIPATH=y - CONFIG_IP_ROUTE_VERBOSE=y - CONFIG_IP_PNP=y - -From 67cf7c950c17a731c934a3b30b474cb8886744c5 Mon Sep 17 00:00:00 2001 -From: Sam Nazarko -Date: Fri, 1 Apr 2016 17:27:21 +0100 -Subject: [PATCH 225/251] add smsc95xx packetsize module_param - -Signed-off-by: Sam Nazarko ---- - drivers/net/usb/smsc95xx.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index a61bd08..3c23b11 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -83,6 +83,10 @@ static char *macaddr = ":"; - module_param(macaddr, charp, 0); - MODULE_PARM_DESC(macaddr, "MAC address"); - -+static int packetsize = 0; -+module_param(packetsize, int, 0644); -+MODULE_PARM_DESC(packetsize, "Override the RX URB packet size"); -+ - static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, - u32 *data, int in_pm) - { -@@ -1006,13 +1010,13 @@ static int smsc95xx_reset(struct usbnet *dev) - - if (!turbo_mode) { - burst_cap = 0; -- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE; - } else if (dev->udev->speed == USB_SPEED_HIGH) { -- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; -- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE; -+ burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE; - } else { -- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; -- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE; -+ burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE; - } - - netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", - -From fd1df6d4b4d6ebf352da378dcca5965297b242ec Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 5 Apr 2016 19:40:12 +0100 -Subject: [PATCH 226/251] reboot: Use power off rather than busy spinning when - halt is requested - ---- - arch/arm/kernel/reboot.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c -index 3826935..2cd6af2 100644 ---- a/arch/arm/kernel/reboot.c -+++ b/arch/arm/kernel/reboot.c -@@ -102,11 +102,7 @@ void machine_shutdown(void) - */ - void machine_halt(void) - { -- local_irq_disable(); -- smp_send_stop(); -- -- local_irq_disable(); -- while (1); -+ machine_power_off(); - } - - /* - -From d1766b543e9362da3ed16d5b03828a67214e7476 Mon Sep 17 00:00:00 2001 -From: HiassofT -Date: Wed, 6 Apr 2016 21:45:01 +0200 -Subject: [PATCH 227/251] Revert "bcm2835-dma: Fix dreq not set for slave - transfers" - -This reverts commit 8ad957e866a1fe1450f663f2b00a57d7de44904c. - - - -DMA channels are set in devicetree, thus dreq will be set, - -and this commit is no longer needed. - - - -Signed-off-by: Matthias Reichl ---- - drivers/dma/bcm2835-dma.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c -index 985019b..d26b6bd 100644 ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -679,8 +679,6 @@ static int bcm2835_dma_slave_config(struct dma_chan *chan, - } - - c->cfg = *cfg; -- if (!c->dreq) -- c->dreq = cfg->slave_id; - - return 0; - } - -From 68172482aa367aa118a7a46537206c817669b10c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Fri, 1 Apr 2016 15:28:46 +0100 -Subject: [PATCH 228/251] RPi config: Add CONFIG_PWM_PCA9685 for NXP PCA9685 - driver over I2C - -Includes DT overlay to configure it. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 +++++ - .../boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts | 26 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 35 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 7c4fc30..239c6a1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -30,6 +30,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-pwm-pca9685a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 337be4a..9df71a4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -366,6 +366,12 @@ Load: dtoverlay=i2c-mux-pca9548a,= - Params: addr I2C address of PCA9548A (default 0x70) - - -+Name: i2c-pwm-pca9685a -+Info: Adds support for an NXP PCA9685A I2C PWM controller on i2c_arm -+Load: dtoverlay=i2c-pwm-pca9685a,= -+Params: addr I2C address of PCA9685A (default 0x40) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= -diff --git a/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -new file mode 100644 -index 0000000..d1ffd23 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -@@ -0,0 +1,26 @@ -+// Definitions for NXP PCA9685A I2C PWM controller on ARM I2C bus. -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pca: pca@40 { -+ compatible = "nxp,pca9685"; -+ #pwm-cells = <2>; -+ reg = <0x40>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ addr = <&pca>,"reg:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d509168..299d7be 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1122,6 +1122,7 @@ CONFIG_MCP320X=m - CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 060ec5f..acda16b 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1129,6 +1129,7 @@ CONFIG_MCP320X=m - CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - -From 3d3c095375d6ac4508dc49a80d615b1fd56eb12a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 8 Apr 2016 17:43:27 +0100 -Subject: [PATCH 229/251] BCM270X_DT: Don't generate "linux,phandle" props - -The EPAPR standard says to use "phandle" properties to store phandles, -rather than the deprecated "linux,phandle" version. By default, dtc -generates both, but adding "-H epapr" causes it to only generate -"phandle"s, saving some space and clutter. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 2 +- - scripts/Makefile.lib | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index fdc450f..49badba 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -813,5 +813,5 @@ clean-files := *.dtb - - # Enable fixups to support overlays on BCM2708 platforms - ifeq ($(RPI_DT_OVERLAYS),y) -- DTC_FLAGS ?= -@ -+ DTC_FLAGS ?= -@ -H epapr - endif -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 7209d62..3079c4f 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -294,7 +294,7 @@ $(obj)/%.dtb: $(src)/%.dts FORCE - - quiet_cmd_dtco = DTCO $@ - cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -- $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ -+ $(objtree)/scripts/dtc/dtc -@ -H epapr -O dtb -o $@ -b 0 \ - -i $(dir $<) $(DTC_FLAGS) \ - -d $(depfile).dtc.tmp $(dtc-tmp) ; \ - cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) - -From 5cec9f4a5fb37bc1041c351ab309001c4f9f9d1d Mon Sep 17 00:00:00 2001 -From: 6by9 <6by9@users.noreply.github.com> -Date: Fri, 8 Apr 2016 18:15:43 +0100 -Subject: [PATCH 230/251] V4L2 driver updates (#1393) - -* BCM2835-V4L2: Correct ISO control and add V4L2_CID_ISO_SENSITIVITY_AUTO - -https://github.com/raspberrypi/linux/issues/1251 - -V4L2_CID_ISO_SENSITIVITY was not advertising ISO*1000 as it should. -V4L2_CID_ISO_SENSITIVITY_AUTO was not implemented, so was taking -V4L2_CID_ISO_SENSITIVITY as 0 for auto mode. -Still accepts 0 for auto, but also abides by the new parameter. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add a video_nr parameter. - -Adds a kernel parameter "video_nr" to specify the preferred -/dev/videoX device node. -https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=136120&p=905545 - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add support for multiple cameras - -Ask GPU on load how many cameras have been detected, and -enumerate that number of devices. -Only applicable on the Compute Module as no other device -exposes multiple CSI2 interfaces. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add control of the overlay location and alpha. - -Actually do something useful in vidioc_s_fmt_vid_overlay and -vidioc_try_fmt_vid_overlay, rather than effectively having -read-only fields. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: V4L2-Compliance failure fix - -VIDIOC_TRY_FMT was failing due to bytesperline not -being set correctly by default. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Make all module parameters static - -Clean up to correct variable scope - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 372 +++++++++++++++-------- - drivers/media/platform/bcm2835/bcm2835-camera.h | 19 +- - drivers/media/platform/bcm2835/controls.c | 31 +- - drivers/media/platform/bcm2835/mmal-parameters.h | 33 ++ - 4 files changed, 320 insertions(+), 135 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index 98a892e..0e6c9b4 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -45,6 +45,8 @@ - #define MAX_VIDEO_MODE_WIDTH 1280 - #define MAX_VIDEO_MODE_HEIGHT 720 - -+#define MAX_BCM2835_CAMERAS 2 -+ - MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture"); - MODULE_AUTHOR("Vincent Sanders"); - MODULE_LICENSE("GPL"); -@@ -54,8 +56,13 @@ int bcm2835_v4l2_debug; - module_param_named(debug, bcm2835_v4l2_debug, int, 0644); - MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2"); - --int max_video_width = MAX_VIDEO_MODE_WIDTH; --int max_video_height = MAX_VIDEO_MODE_HEIGHT; -+#define UNSET (-1) -+static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET }; -+module_param_array(video_nr, int, NULL, 0644); -+MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect"); -+ -+static int max_video_width = MAX_VIDEO_MODE_WIDTH; -+static int max_video_height = MAX_VIDEO_MODE_HEIGHT; - module_param(max_video_width, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - MODULE_PARM_DESC(max_video_width, "Threshold for video mode"); - module_param(max_video_height, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -@@ -70,11 +77,12 @@ MODULE_PARM_DESC(max_video_height, "Threshold for video mode"); - * our function table list (actually switch to an alternate set, but same - * result). - */ --int gst_v4l2src_is_broken = 0; -+static int gst_v4l2src_is_broken; - module_param(gst_v4l2src_is_broken, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - MODULE_PARM_DESC(gst_v4l2src_is_broken, "If non-zero, enable workaround for Gstreamer"); - --static struct bm2835_mmal_dev *gdev; /* global device data */ -+/* global device data array */ -+static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS]; - - #define FPS_MIN 1 - #define FPS_MAX 90 -@@ -413,6 +421,17 @@ static int enable_camera(struct bm2835_mmal_dev *dev) - { - int ret; - if (!dev->camera_use_count) { -+ ret = vchiq_mmal_port_parameter_set( -+ dev->instance, -+ &dev->component[MMAL_COMPONENT_CAMERA]->control, -+ MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num, -+ sizeof(dev->camera_num)); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, -+ "Failed setting camera num, ret %d\n", ret); -+ return -EINVAL; -+ } -+ - ret = vchiq_mmal_component_enable( - dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); -@@ -647,6 +666,30 @@ static struct vb2_ops bm2835_mmal_video_qops = { - IOCTL operations - ------------------------------------------------------------------*/ - -+static int set_overlay_params(struct bm2835_mmal_dev *dev, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ struct mmal_parameter_displayregion prev_config = { -+ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA | -+ MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN, -+ .layer = PREVIEW_LAYER, -+ .alpha = dev->overlay.global_alpha, -+ .fullscreen = 0, -+ .dest_rect = { -+ .x = dev->overlay.w.left, -+ .y = dev->overlay.w.top, -+ .width = dev->overlay.w.width, -+ .height = dev->overlay.w.height, -+ }, -+ }; -+ ret = vchiq_mmal_port_parameter_set(dev->instance, port, -+ MMAL_PARAMETER_DISPLAYREGION, -+ &prev_config, sizeof(prev_config)); -+ -+ return ret; -+} -+ - /* overlay ioctl */ - static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -@@ -678,10 +721,31 @@ static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, - static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) - { -- /* Only support one format so get the current one. */ -- vidioc_g_fmt_vid_overlay(file, priv, f); -+ struct bm2835_mmal_dev *dev = video_drvdata(file); - -- /* todo: allow the size and/or offset to be changed. */ -+ f->fmt.win.field = V4L2_FIELD_NONE; -+ f->fmt.win.chromakey = 0; -+ f->fmt.win.clips = NULL; -+ f->fmt.win.clipcount = 0; -+ f->fmt.win.bitmap = NULL; -+ -+ v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, MAX_WIDTH, 1, -+ &f->fmt.win.w.height, MIN_HEIGHT, MAX_HEIGHT, -+ 1, 0); -+ v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, MAX_WIDTH, 1, -+ &f->fmt.win.w.top, MIN_HEIGHT, MAX_HEIGHT, -+ 1, 0); -+ -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "Overlay: Now w/h %dx%d l/t %dx%d\n", -+ f->fmt.win.w.width, f->fmt.win.w.height, -+ f->fmt.win.w.left, f->fmt.win.w.top); -+ -+ v4l2_dump_win_format(1, -+ bcm2835_v4l2_debug, -+ &dev->v4l2_dev, -+ &f->fmt.win, -+ __func__); - return 0; - } - -@@ -693,8 +757,11 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, - vidioc_try_fmt_vid_overlay(file, priv, f); - - dev->overlay = f->fmt.win; -+ if (dev->component[MMAL_COMPONENT_PREVIEW]->enabled) { -+ set_overlay_params(dev, -+ &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); -+ } - -- /* todo: program the preview port parameters */ - return 0; - } - -@@ -704,20 +771,6 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) - struct bm2835_mmal_dev *dev = video_drvdata(file); - struct vchiq_mmal_port *src; - struct vchiq_mmal_port *dst; -- struct mmal_parameter_displayregion prev_config = { -- .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA | -- MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN, -- .layer = PREVIEW_LAYER, -- .alpha = 255, -- .fullscreen = 0, -- .dest_rect = { -- .x = dev->overlay.w.left, -- .y = dev->overlay.w.top, -- .width = dev->overlay.w.width, -- .height = dev->overlay.w.height, -- }, -- }; -- - if ((on && dev->component[MMAL_COMPONENT_PREVIEW]->enabled) || - (!on && !dev->component[MMAL_COMPONENT_PREVIEW]->enabled)) - return 0; /* already in requested state */ -@@ -749,9 +802,7 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) - if (ret < 0) - goto error; - -- ret = vchiq_mmal_port_parameter_set(dev->instance, dst, -- MMAL_PARAMETER_DISPLAYREGION, -- &prev_config, sizeof(prev_config)); -+ ret = set_overlay_params(dev, dst); - if (ret < 0) - goto error; - -@@ -782,6 +833,9 @@ static int vidioc_g_fbuf(struct file *file, void *fh, - struct vchiq_mmal_port *preview_port = - &dev->component[MMAL_COMPONENT_CAMERA]-> - output[MMAL_CAMERA_PORT_PREVIEW]; -+ -+ a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | -+ V4L2_FBUF_CAP_GLOBAL_ALPHA; - a->flags = V4L2_FBUF_FLAG_OVERLAY; - a->fmt.width = preview_port->es.video.width; - a->fmt.height = preview_port->es.video.height; -@@ -1445,6 +1499,34 @@ static struct video_device vdev_template = { - .release = video_device_release_empty, - }; - -+static int get_num_cameras(struct vchiq_mmal_instance *instance) -+{ -+ int ret; -+ struct vchiq_mmal_component *cam_info_component; -+ struct mmal_parameter_camera_info_t cam_info = {0}; -+ int param_size = sizeof(cam_info); -+ -+ /* create a camera_info component */ -+ ret = vchiq_mmal_component_init(instance, "camera_info", -+ &cam_info_component); -+ if (ret < 0) -+ /* Unusual failure - let's guess one camera. */ -+ return 1; -+ -+ if (vchiq_mmal_port_parameter_get(instance, -+ &cam_info_component->control, -+ MMAL_PARAMETER_CAMERA_INFO, -+ &cam_info, -+ ¶m_size)) { -+ pr_info("Failed to get camera info\n"); -+ } -+ -+ vchiq_mmal_component_finalise(instance, -+ cam_info_component); -+ -+ return cam_info.num_cameras; -+} -+ - static int set_camera_parameters(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *camera) - { -@@ -1685,7 +1767,9 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev, - /* video device needs to be able to access instance data */ - video_set_drvdata(vfd, dev); - -- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); -+ ret = video_register_device(vfd, -+ VFL_TYPE_GRABBER, -+ video_nr[dev->camera_num]); - if (ret < 0) - return ret; - -@@ -1696,10 +1780,52 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev, - return 0; - } - -+void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev) -+{ -+ if (!dev) -+ return; -+ -+ v4l2_info(&dev->v4l2_dev, "unregistering %s\n", -+ video_device_node_name(&dev->vdev)); -+ -+ video_unregister_device(&dev->vdev); -+ -+ if (dev->capture.encode_component) { -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "mmal_exit - disconnect tunnel\n"); -+ vchiq_mmal_port_connect_tunnel(dev->instance, -+ dev->capture.camera_port, NULL); -+ vchiq_mmal_component_disable(dev->instance, -+ dev->capture.encode_component); -+ } -+ vchiq_mmal_component_disable(dev->instance, -+ dev->component[MMAL_COMPONENT_CAMERA]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev-> -+ component[MMAL_COMPONENT_VIDEO_ENCODE]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev-> -+ component[MMAL_COMPONENT_IMAGE_ENCODE]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev->component[MMAL_COMPONENT_PREVIEW]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev->component[MMAL_COMPONENT_CAMERA]); -+ -+ v4l2_ctrl_handler_free(&dev->ctrl_handler); -+ -+ v4l2_device_unregister(&dev->v4l2_dev); -+ -+ kfree(dev); -+} -+ - static struct v4l2_format default_v4l2_format = { - .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG, - .fmt.pix.width = 1024, -- .fmt.pix.bytesperline = 1024, -+ .fmt.pix.bytesperline = 0, - .fmt.pix.height = 768, - .fmt.pix.sizeimage = 1024*768, - }; -@@ -1709,76 +1835,93 @@ static int __init bm2835_mmal_init(void) - int ret; - struct bm2835_mmal_dev *dev; - struct vb2_queue *q; -+ int camera; -+ unsigned int num_cameras; -+ struct vchiq_mmal_instance *instance; - -- dev = kzalloc(sizeof(*gdev), GFP_KERNEL); -- if (!dev) -- return -ENOMEM; -- -- /* setup device defaults */ -- dev->overlay.w.left = 150; -- dev->overlay.w.top = 50; -- dev->overlay.w.width = 1024; -- dev->overlay.w.height = 768; -- dev->overlay.clipcount = 0; -- dev->overlay.field = V4L2_FIELD_NONE; -- -- dev->capture.fmt = &formats[3]; /* JPEG */ -- -- /* v4l device registration */ -- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), -- "%s", BM2835_MMAL_MODULE_NAME); -- ret = v4l2_device_register(NULL, &dev->v4l2_dev); -- if (ret) -- goto free_dev; -- -- /* setup v4l controls */ -- ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); -+ ret = vchiq_mmal_init(&instance); - if (ret < 0) -- goto unreg_dev; -- dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; -+ return ret; - -- /* mmal init */ -- ret = mmal_init(dev); -- if (ret < 0) -- goto unreg_dev; -- -- /* initialize queue */ -- q = &dev->capture.vb_vidq; -- memset(q, 0, sizeof(*q)); -- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; -- q->drv_priv = dev; -- q->buf_struct_size = sizeof(struct mmal_buffer); -- q->ops = &bm2835_mmal_video_qops; -- q->mem_ops = &vb2_vmalloc_memops; -- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -- ret = vb2_queue_init(q); -- if (ret < 0) -- goto unreg_dev; -+ num_cameras = get_num_cameras(instance); -+ if (num_cameras > MAX_BCM2835_CAMERAS) -+ num_cameras = MAX_BCM2835_CAMERAS; - -- /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */ -- mutex_init(&dev->mutex); -+ for (camera = 0; camera < num_cameras; camera++) { -+ dev = kzalloc(sizeof(struct bm2835_mmal_dev), GFP_KERNEL); -+ if (!dev) -+ return -ENOMEM; - -- /* initialise video devices */ -- ret = bm2835_mmal_init_device(dev, &dev->vdev); -- if (ret < 0) -- goto unreg_dev; -+ dev->camera_num = camera; - -- /* Really want to call vidioc_s_fmt_vid_cap with the default -- * format, but currently the APIs don't join up. -- */ -- ret = mmal_setup_components(dev, &default_v4l2_format); -- if (ret < 0) { -- v4l2_err(&dev->v4l2_dev, -- "%s: could not setup components\n", __func__); -- goto unreg_dev; -- } -+ /* setup device defaults */ -+ dev->overlay.w.left = 150; -+ dev->overlay.w.top = 50; -+ dev->overlay.w.width = 1024; -+ dev->overlay.w.height = 768; -+ dev->overlay.clipcount = 0; -+ dev->overlay.field = V4L2_FIELD_NONE; -+ dev->overlay.global_alpha = 255; - -- v4l2_info(&dev->v4l2_dev, -- "Broadcom 2835 MMAL video capture ver %s loaded.\n", -- BM2835_MMAL_VERSION); -+ dev->capture.fmt = &formats[3]; /* JPEG */ -+ -+ /* v4l device registration */ -+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), -+ "%s", BM2835_MMAL_MODULE_NAME); -+ ret = v4l2_device_register(NULL, &dev->v4l2_dev); -+ if (ret) -+ goto free_dev; -+ -+ /* setup v4l controls */ -+ ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); -+ if (ret < 0) -+ goto unreg_dev; -+ dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; -+ -+ /* mmal init */ -+ dev->instance = instance; -+ ret = mmal_init(dev); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* initialize queue */ -+ q = &dev->capture.vb_vidq; -+ memset(q, 0, sizeof(*q)); -+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; -+ q->drv_priv = dev; -+ q->buf_struct_size = sizeof(struct mmal_buffer); -+ q->ops = &bm2835_mmal_video_qops; -+ q->mem_ops = &vb2_vmalloc_memops; -+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -+ ret = vb2_queue_init(q); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */ -+ mutex_init(&dev->mutex); -+ -+ /* initialise video devices */ -+ ret = bm2835_mmal_init_device(dev, &dev->vdev); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* Really want to call vidioc_s_fmt_vid_cap with the default -+ * format, but currently the APIs don't join up. -+ */ -+ ret = mmal_setup_components(dev, &default_v4l2_format); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, -+ "%s: could not setup components\n", __func__); -+ goto unreg_dev; -+ } - -- gdev = dev; -+ v4l2_info(&dev->v4l2_dev, -+ "Broadcom 2835 MMAL video capture ver %s loaded.\n", -+ BM2835_MMAL_VERSION); -+ -+ gdev[camera] = dev; -+ } - return 0; - - unreg_dev: -@@ -1788,8 +1931,11 @@ unreg_dev: - free_dev: - kfree(dev); - -- v4l2_err(&dev->v4l2_dev, -- "%s: error %d while loading driver\n", -+ for ( ; camera > 0; camera--) { -+ bcm2835_cleanup_instance(gdev[camera]); -+ gdev[camera] = NULL; -+ } -+ pr_info("%s: error %d while loading driver\n", - BM2835_MMAL_MODULE_NAME, ret); - - return ret; -@@ -1797,46 +1943,14 @@ free_dev: - - static void __exit bm2835_mmal_exit(void) - { -- if (!gdev) -- return; -- -- v4l2_info(&gdev->v4l2_dev, "unregistering %s\n", -- video_device_node_name(&gdev->vdev)); -+ int camera; -+ struct vchiq_mmal_instance *instance = gdev[0]->instance; - -- video_unregister_device(&gdev->vdev); -- -- if (gdev->capture.encode_component) { -- v4l2_dbg(1, bcm2835_v4l2_debug, &gdev->v4l2_dev, -- "mmal_exit - disconnect tunnel\n"); -- vchiq_mmal_port_connect_tunnel(gdev->instance, -- gdev->capture.camera_port, NULL); -- vchiq_mmal_component_disable(gdev->instance, -- gdev->capture.encode_component); -+ for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) { -+ bcm2835_cleanup_instance(gdev[camera]); -+ gdev[camera] = NULL; - } -- vchiq_mmal_component_disable(gdev->instance, -- gdev->component[MMAL_COMPONENT_CAMERA]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev-> -- component[MMAL_COMPONENT_VIDEO_ENCODE]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev-> -- component[MMAL_COMPONENT_IMAGE_ENCODE]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev->component[MMAL_COMPONENT_PREVIEW]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev->component[MMAL_COMPONENT_CAMERA]); -- -- vchiq_mmal_finalise(gdev->instance); -- -- v4l2_ctrl_handler_free(&gdev->ctrl_handler); -- -- v4l2_device_unregister(&gdev->v4l2_dev); -- -- kfree(gdev); -+ vchiq_mmal_finalise(instance); - } - - module_init(bm2835_mmal_init); -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h -index 7fe9f65..202906b 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.h -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.h -@@ -15,7 +15,7 @@ - * core driver device - */ - --#define V4L2_CTRL_COUNT 28 /* number of v4l controls */ -+#define V4L2_CTRL_COUNT 29 /* number of v4l controls */ - - enum { - MMAL_COMPONENT_CAMERA = 0, -@@ -58,6 +58,8 @@ struct bm2835_mmal_dev { - enum mmal_parameter_exposuremeteringmode metering_mode; - unsigned int manual_shutter_speed; - bool exp_auto_priority; -+ bool manual_iso_enabled; -+ uint32_t iso; - - /* allocated mmal instance and components */ - struct vchiq_mmal_instance *instance; -@@ -104,6 +106,8 @@ struct bm2835_mmal_dev { - - } capture; - -+ unsigned int camera_num; -+ - }; - - int bm2835_mmal_init_controls( -@@ -124,3 +128,16 @@ int set_framerate_params(struct bm2835_mmal_dev *dev); - (pix_fmt)->pixelformat, (pix_fmt)->bytesperline, \ - (pix_fmt)->sizeimage, (pix_fmt)->colorspace, (pix_fmt)->priv); \ - } -+#define v4l2_dump_win_format(level, debug, dev, win_fmt, desc) \ -+{ \ -+ v4l2_dbg(level, debug, dev, \ -+"%s: w %u h %u l %u t %u field %u chromakey %06X clip %p " \ -+"clipcount %u bitmap %p\n", \ -+ desc == NULL ? "" : desc, \ -+ (win_fmt)->w.width, (win_fmt)->w.height, \ -+ (win_fmt)->w.left, (win_fmt)->w.top, \ -+ (win_fmt)->field, \ -+ (win_fmt)->chromakey, \ -+ (win_fmt)->clips, (win_fmt)->clipcount, \ -+ (win_fmt)->bitmap); \ -+} -diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c -index f9f903f..fe61330 100644 ---- a/drivers/media/platform/bcm2835/controls.c -+++ b/drivers/media/platform/bcm2835/controls.c -@@ -49,10 +49,13 @@ static const s64 ev_bias_qmenu[] = { - 4000 - }; - --/* Supported ISO values -+/* Supported ISO values (*1000) - * ISOO = auto ISO - */ - static const s64 iso_qmenu[] = { -+ 0, 100000, 200000, 400000, 800000, -+}; -+static const uint32_t iso_values[] = { - 0, 100, 200, 400, 800, - }; - -@@ -201,7 +204,7 @@ static int ctrl_set_value(struct bm2835_mmal_dev *dev, - &u32_value, sizeof(u32_value)); - } - --static int ctrl_set_value_menu(struct bm2835_mmal_dev *dev, -+static int ctrl_set_iso(struct bm2835_mmal_dev *dev, - struct v4l2_ctrl *ctrl, - const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) - { -@@ -211,12 +214,23 @@ static int ctrl_set_value_menu(struct bm2835_mmal_dev *dev, - if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min) - return 1; - -+ if (ctrl->id == V4L2_CID_ISO_SENSITIVITY) -+ dev->iso = iso_values[ctrl->val]; -+ else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO) -+ dev->manual_iso_enabled = -+ (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL ? -+ true : -+ false); -+ - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; - -- u32_value = mmal_ctrl->imenu[ctrl->val]; -+ if (dev->manual_iso_enabled) -+ u32_value = dev->iso; -+ else -+ u32_value = 0; - - return vchiq_mmal_port_parameter_set(dev->instance, control, -- mmal_ctrl->mmal_id, -+ MMAL_PARAMETER_ISO, - &u32_value, sizeof(u32_value)); - } - -@@ -956,7 +970,14 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { - V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU, - 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu, - MMAL_PARAMETER_ISO, -- &ctrl_set_value_menu, -+ &ctrl_set_iso, -+ false -+ }, -+ { -+ V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, -+ 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, -+ MMAL_PARAMETER_ISO, -+ &ctrl_set_iso, - false - }, - { -diff --git a/drivers/media/platform/bcm2835/mmal-parameters.h b/drivers/media/platform/bcm2835/mmal-parameters.h -index aa0fd18..f6abb5c 100644 ---- a/drivers/media/platform/bcm2835/mmal-parameters.h -+++ b/drivers/media/platform/bcm2835/mmal-parameters.h -@@ -654,3 +654,36 @@ struct mmal_parameter_imagefx_parameters { - u32 num_effect_params; - u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; - }; -+ -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 -+ -+struct mmal_parameter_camera_info_camera_t { -+ u32 port_id; -+ u32 max_width; -+ u32 max_height; -+ u32 lens_present; -+ u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; -+}; -+ -+enum mmal_parameter_camera_info_flash_type_t { -+ /* Make values explicit to ensure they match values in config ini */ -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF -+}; -+ -+struct mmal_parameter_camera_info_flash_t { -+ enum mmal_parameter_camera_info_flash_type_t flash_type; -+}; -+ -+struct mmal_parameter_camera_info_t { -+ u32 num_cameras; -+ u32 num_flashes; -+ struct mmal_parameter_camera_info_camera_t -+ cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; -+ struct mmal_parameter_camera_info_flash_t -+ flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; -+}; - -From 4366809281c7cf500e97f9a113cb1234d273aed3 Mon Sep 17 00:00:00 2001 +From 60b77dc3f91119ad7cb3a2ae39797754575bc275 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 Apr 2016 12:50:58 +0100 -Subject: [PATCH 231/251] bcm2835-sdhost: Reset the clock in task context +Subject: [PATCH 105/114] bcm2835-sdhost: Reset the clock in task context Since reprogramming the clock can now involve a round-trip to the firmware it must not be done at atomic context, and a tasklet @@ -164054,1273 +131804,55 @@ index 54087b2..a57faed 100644 host->pio_limit = 1; host->max_delay = 1; /* Warn if over 1ms */ -From 37e270746e49ee6bf0e7a8404503e67364519ce2 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 7 Apr 2016 12:44:24 +0100 -Subject: [PATCH 232/251] config: Enable CONFIG_IPV6_ROUTER_PREF for networks - with multiple routers +From c439a5c39d8d64ddd8d835cac6b42550811d3581 Mon Sep 17 00:00:00 2001 +From: Sam Nazarko +Date: Fri, 1 Apr 2016 17:27:21 +0100 +Subject: [PATCH 106/114] add smsc95xx packetsize module_param +Signed-off-by: Sam Nazarko --- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + drivers/net/usb/smsc95xx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 299d7be..7bfc073 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -101,6 +101,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index acda16b..59026b3 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -95,6 +95,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - -From aa9f1aedb9a495b6688cc30a17a0b01c3ab03f8c Mon Sep 17 00:00:00 2001 -From: jochenberger -Date: Thu, 7 Apr 2016 21:38:46 +0200 -Subject: [PATCH 233/251] Enable hid-betopff module - -Add force feedback support for Betop based devices -https://github.com/raspberrypi/linux/blob/rpi-4.1.y/drivers/hid/hid-betopff.c ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7bfc073..31e3ac5 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -867,6 +867,7 @@ CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m - CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m - CONFIG_HID_CHERRY=m - CONFIG_HID_CHICONY=m - CONFIG_HID_CYPRESS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 59026b3..ac9287f 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -859,6 +859,7 @@ CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m - CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m - CONFIG_HID_CHERRY=m - CONFIG_HID_CHICONY=m - CONFIG_HID_CYPRESS=m - -From 51edceabf0a57229b0ccb3742640aefe4fcb161d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 12 Apr 2016 12:45:16 +0100 -Subject: [PATCH 234/251] config: Make IPV6 a module and regenerate with - defconfig - ---- - arch/arm/configs/bcm2709_defconfig | 4 ++-- - arch/arm/configs/bcmrpi_defconfig | 6 +++--- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 31e3ac5..5a8ab1e 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -101,6 +101,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6=m - CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m -@@ -600,10 +601,9 @@ CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m --CONFIG_I2C_MUX=m --CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index ac9287f..852751e 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -73,7 +73,6 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y --CONFIG_IPV6_SUBTREES=y - CONFIG_IP_ROUTE_MULTIPATH=y - CONFIG_IP_ROUTE_VERBOSE=y - CONFIG_IP_PNP=y -@@ -95,12 +94,14 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6=m - CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - CONFIG_IPV6_TUNNEL=m - CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IPV6_MROUTE=y - CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y - CONFIG_IPV6_PIMSM_V2=y -@@ -593,10 +594,9 @@ CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m --CONFIG_I2C_MUX=m --CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m - -From 037a9e0fd0cb7eeb947bb4dbff674833419dd7f7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 5 Apr 2016 13:01:54 +0100 -Subject: [PATCH 235/251] BCM270X_DT: Add dpi24 overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 +++++++ - arch/arm/boot/dts/overlays/dpi24-overlay.dts | 31 ++++++++++++++++++++++++++++ - 3 files changed, 40 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/dpi24-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 239c6a1..688ba0b 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,7 @@ endif - dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9df71a4..1438908 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -213,6 +213,14 @@ Params: gpiopin GPIO connected to the sensor's DATA output. - (default 4) +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index a61bd08..3c23b11 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -83,6 +83,10 @@ static char *macaddr = ":"; + module_param(macaddr, charp, 0); + MODULE_PARM_DESC(macaddr, "MAC address"); - -+Name: dpi24 -+Info: Overlay for a generic 24-bit DPI display -+ This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output -+ 2-3 seconds after the kernel has started. -+Load: dtoverlay=dpi24 -+Params: ++static int packetsize = 0; ++module_param(packetsize, int, 0644); ++MODULE_PARM_DESC(packetsize, "Override the RX URB packet size"); + -+ - Name: dwc-otg - Info: Selects the dwc_otg USB controller driver which has fiq support. This - is the default on all except the Pi Zero which defaults to dwc2. -diff --git a/arch/arm/boot/dts/overlays/dpi24-overlay.dts b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -new file mode 100644 -index 0000000..e4dbe40 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -@@ -0,0 +1,31 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ // There is no DPI driver module, but we need a platform device -+ // node (that doesn't already use pinctrl) to hang the pinctrl -+ // reference on - leds will do -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dpi24_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ dpi24_pins: dpi24_pins { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15 16 17 18 19 20 -+ 21 22 23 24 25 26 27>; -+ brcm,function = <6>; /* alt2 */ -+ brcm,pull = <0>; /* no pull */ -+ }; -+ }; -+ }; -+}; - -From 8e95bfba2bfc4186ee007176c9d2f7c42c369312 Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Thu, 14 Apr 2016 00:57:33 +0100 -Subject: [PATCH 236/251] Modify IQAudIO DAC+ ASoC driver to set card/dai - config from dt - -Add the ability to set the card name, dai name and dai stream name, from -dt config. - -Signed-off-by: DigitalDreamtime ---- - sound/soc/bcm/iqaudio-dac.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index a5eaa9e..b6b6dcf 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -61,8 +61,6 @@ static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { - - static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) { -- .name = "IQaudIO DAC", -- .stream_name = "IQaudIO DAC HiFi", - .cpu_dai_name = "bcm2708-i2s.0", - .codec_dai_name = "pcm512x-hifi", - .platform_name = "bcm2708-i2s.0", -@@ -76,7 +74,6 @@ static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { +@@ -1006,13 +1010,13 @@ static int smsc95xx_reset(struct usbnet *dev) - /* audio machine driver */ - static struct snd_soc_card snd_rpi_iqaudio_dac = { -- .name = "IQaudIODAC", - .owner = THIS_MODULE, - .dai_link = snd_rpi_iqaudio_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), -@@ -90,6 +87,7 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - - if (pdev->dev.of_node) { - struct device_node *i2s_node; -+ struct snd_soc_card *card = &snd_rpi_iqaudio_dac; - struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; - i2s_node = of_parse_phandle(pdev->dev.of_node, - "i2s-controller", 0); -@@ -103,6 +101,15 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - - digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, - "iqaudio,24db_digital_gain"); -+ if (of_property_read_string(pdev->dev.of_node, "card_name", -+ &card->name)) -+ card->name = "IQaudIODAC"; -+ if (of_property_read_string(pdev->dev.of_node, "dai_name", -+ &dai->name)) -+ dai->name = "IQaudIO DAC"; -+ if (of_property_read_string(pdev->dev.of_node, "dai_stream_name", -+ &dai->stream_name)) -+ dai->stream_name = "IQaudIO DAC HiFi"; + if (!turbo_mode) { + burst_cap = 0; +- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE; + } else if (dev->udev->speed == USB_SPEED_HIGH) { +- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; +- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE; ++ burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE; + } else { +- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; +- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE; ++ burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE; } - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); + netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", -From 7ea9f79b042605984245d4a0387f0e667fdc947c Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Thu, 14 Apr 2016 01:00:58 +0100 -Subject: [PATCH 237/251] Add support for the Digital Dreamtime Akkordion music - player. - -Support the Digital Dreamtime Akkordion using the OEM IQAudIO DAC+ or -DACZero modules. Set ALSA card name, ("Akkordion"), from dt config. - -Signed-off-by: DigitalDreamtime ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 20 ++++++++++ - .../dts/overlays/akkordion-iqdacplus-overlay.dts | 46 ++++++++++++++++++++++ - 3 files changed, 67 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 688ba0b..6bd6048 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1438908..5d0887f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -186,6 +186,26 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: akkordion-iqdacplus -+Info: Configures the Digital Dreamtime Akkordion Music Player (based on the -+ OEM IQAudIO DAC+ or DAC Zero module). -+Load: dtoverlay=akkordion-iqdacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ dtoverlay=akkordion-iqdacplus,24db_digital_gain -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ - Name: at86rf233 - Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, - connected to spi0.0 -diff --git a/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -new file mode 100644 -index 0000000..47c7664 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -@@ -0,0 +1,46 @@ -+// Definitions for Digital Dreamtime Akkordion using IQaudIO DAC+ or DACZero -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ frag0: __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ card_name = "Akkordion"; -+ dai_name = "IQaudIO DAC"; -+ dai_stream_name = "IQaudIO DAC HiFi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; -+ }; -+}; - -From 2544f9707d98c5d4251e0d6792a5a40016adedcb Mon Sep 17 00:00:00 2001 -From: Aaron Shaw -Date: Thu, 7 Apr 2016 21:26:21 +0100 -Subject: [PATCH 238/251] Add Support for BoomBerry Audio boards - ---- - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/README | 26 +++ - .../boot/dts/overlays/boomberry-dac-overlay.dts | 43 +++++ - .../boot/dts/overlays/boomberry-digi-overlay.dts | 39 ++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - sound/soc/bcm/Kconfig | 14 ++ - sound/soc/bcm/Makefile | 4 + - sound/soc/bcm/boomberry-dac.c | 163 ++++++++++++++++ - sound/soc/bcm/boomberry-digi.c | 215 +++++++++++++++++++++ - 10 files changed, 510 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts - create mode 100644 sound/soc/bcm/boomberry-dac.c - create mode 100644 sound/soc/bcm/boomberry-digi.c - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 6bd6048..4842dc1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,8 @@ dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo - dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += boomberry-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += boomberry-digi.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 5d0887f..eb5fc04 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -225,6 +225,32 @@ Load: dtoverlay=bmp085_i2c-sensor - Params: - - -+Name: boomberry-dac -+Info: Configures the BoomBerry DAC HAT, Amp HAT, DAC Zero and Amp Zero audio -+ cards -+Load: dtoverlay=boomberry-dac,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=boomberry-dac,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24dB_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ -+Name: boomberry-digi -+Info: Configures the BoomBerry Digi HAT and Digi Zero audio cards -+Load: dtoverlay=boomberry-digi -+Params: -+ -+ - Name: dht11 - Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors - Also sometimes found with the part number(s) AM230x. -diff --git a/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts -new file mode 100644 -index 0000000..0f7c9b0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts -@@ -0,0 +1,43 @@ -+// Definitions for BoomBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ frag0: __overlay__ { -+ compatible = "boomberry,boomberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"boomberry,24db_digital_gain?"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts -new file mode 100644 -index 0000000..a86e1d0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for BoomBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "boomberry,boomberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5a8ab1e..84ec380 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -853,6 +853,8 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SNG_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 852751e..603ba04 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -845,6 +845,8 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 1a3f826..3383381 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -50,6 +50,20 @@ config SND_BCM2708_SOC_RPI_PROTO - help - Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). - -+config SND_BCM2708_SOC_BOOMBERRY_DAC -+ tristate "Support for BoomBerry DAC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_PCM512x -+ help -+ Say Y or M if you want to add support for BoomBerry DAC. -+ -+config SND_BCM2708_SOC_BOOMBERRY_DIGI -+ tristate "Support for BoomBerry Digi" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_WM8804 -+ help -+ Say Y or M if you want to add support for BoomBerry Digi. -+ - config SND_BCM2708_SOC_IQAUDIO_DAC - tristate "Support for IQaudIO-DAC" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index b21e11e..b04b0d2 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -8,6 +8,8 @@ snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-hifiberry-amp-objs := hifiberry_amp.o -+snd-soc-boomberry-dac-objs := boomberry-dac.o -+snd-soc-boomberry-digi-objs := boomberry-digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-rpi-proto-objs := rpi-proto.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o -@@ -17,6 +19,8 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o -+obj-$(CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC) += snd-soc-boomberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI) += snd-soc-boomberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/boomberry-dac.c b/sound/soc/bcm/boomberry-dac.c -new file mode 100644 -index 0000000..08845ad ---- /dev/null -+++ b/sound/soc/bcm/boomberry-dac.c -@@ -0,0 +1,163 @@ -+/* -+ * ASoC Driver for BoomBerry DAC Raspberry Pi HAT Sound Card -+ * -+ * Author: Milan Neskovic -+ * Copyright 2016 -+ * based on code by Daniel Matuschek -+ * based on code by Florian Meier -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/pcm512x.h" -+ -+static bool digital_gain_0db_limit = true; -+ -+static int snd_rpi_boomberry_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } -+ -+ return 0; -+} -+ -+static int snd_rpi_boomberry_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ /*return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);*/ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+static int snd_rpi_boomberry_dac_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static void snd_rpi_boomberry_dac_shutdown(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_boomberry_dac_ops = { -+ .hw_params = snd_rpi_boomberry_dac_hw_params, -+ .startup = snd_rpi_boomberry_dac_startup, -+ .shutdown = snd_rpi_boomberry_dac_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_boomberry_dac_dai[] = { -+{ -+ .name = "BoomBerry DAC", -+ .stream_name = "BoomBerry DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004d", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_boomberry_dac_ops, -+ .init = snd_rpi_boomberry_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_boomberry_dac = { -+ .name = "snd_rpi_boomberry_dac", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_boomberry_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_boomberry_dac_dai), -+}; -+ -+static int snd_rpi_boomberry_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_boomberry_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_boomberry_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ -+ digital_gain_0db_limit = !of_property_read_bool( -+ pdev->dev.of_node, "boomberry,24db_digital_gain"); -+ } -+ -+ ret = snd_soc_register_card(&snd_rpi_boomberry_dac); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_boomberry_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_boomberry_dac); -+} -+ -+static const struct of_device_id snd_rpi_boomberry_dac_of_match[] = { -+ { .compatible = "boomberry,boomberry-dac", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_boomberry_dac_of_match); -+ -+static struct platform_driver snd_rpi_boomberry_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-boomberry-dac", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_boomberry_dac_of_match, -+ }, -+ .probe = snd_rpi_boomberry_dac_probe, -+ .remove = snd_rpi_boomberry_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_boomberry_dac_driver); -+ -+MODULE_AUTHOR("Milan Neskovic "); -+MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI DAC HAT Sound Card"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/bcm/boomberry-digi.c b/sound/soc/bcm/boomberry-digi.c -new file mode 100644 -index 0000000..3d5b5ff ---- /dev/null -+++ b/sound/soc/bcm/boomberry-digi.c -@@ -0,0 +1,215 @@ -+/* -+ * ASoC Driver for BoomBerry Raspberry Pi Digi HAT Sound Card -+ * -+ * Author: Milan Neskovic -+ * Copyright 2016 -+ * based on code by Daniel Matuschek -+ * based on code by Florian Meier -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/wm8804.h" -+ -+static int snd_rpi_boomberry_digi_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ /* enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ return 0; -+} -+ -+static int snd_rpi_boomberry_digi_startup(struct snd_pcm_substream *substream) { -+ /* turn on digital output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); -+ return 0; -+} -+ -+static void snd_rpi_boomberry_digi_shutdown(struct snd_pcm_substream *substream) { -+ /* turn off output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); -+} -+ -+static int snd_rpi_boomberry_digi_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ int sysclk = 27000000; /* This is fixed on this board */ -+ -+ long mclk_freq=0; -+ int mclk_div=1; -+ int sampling_freq=1; -+ -+ int ret; -+ -+ int samplerate = params_rate(params); -+ -+ if (samplerate<=96000) { -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ } else { -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ } -+ -+ switch (samplerate) { -+ case 32000: -+ sampling_freq=0x03; -+ break; -+ case 44100: -+ sampling_freq=0x00; -+ break; -+ case 48000: -+ sampling_freq=0x02; -+ break; -+ case 88200: -+ sampling_freq=0x08; -+ break; -+ case 96000: -+ sampling_freq=0x0a; -+ break; -+ case 176400: -+ sampling_freq=0x0c; -+ break; -+ case 192000: -+ sampling_freq=0x0e; -+ break; -+ default: -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", -+ samplerate); -+ } -+ -+ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -+ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); -+ -+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, -+ sysclk, SND_SOC_CLOCK_OUT); -+ if (ret < 0) { -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK: %d\n", ret); -+ return ret; -+ } -+ -+ /* Enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ /* Power on */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); -+ -+ /* set sampling frequency status bits */ -+ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_boomberry_digi_ops = { -+ .hw_params = snd_rpi_boomberry_digi_hw_params, -+ .startup = snd_rpi_boomberry_digi_startup, -+ .shutdown = snd_rpi_boomberry_digi_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_boomberry_digi_dai[] = { -+{ -+ .name = "BoomBerry Digi", -+ .stream_name = "BoomBerry Digi HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "wm8804-spdif", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "wm8804.1-003b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &snd_rpi_boomberry_digi_ops, -+ .init = snd_rpi_boomberry_digi_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_boomberry_digi = { -+ .name = "snd_rpi_boomberry_digi", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_boomberry_digi_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_boomberry_digi_dai), -+}; -+ -+static int snd_rpi_boomberry_digi_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_boomberry_digi.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_boomberry_digi_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ -+ ret = snd_soc_register_card(&snd_rpi_boomberry_digi); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_boomberry_digi_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_boomberry_digi); -+} -+ -+static const struct of_device_id snd_rpi_boomberry_digi_of_match[] = { -+ { .compatible = "boomberry,boomberry-digi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_boomberry_digi_of_match); -+ -+static struct platform_driver snd_rpi_boomberry_digi_driver = { -+ .driver = { -+ .name = "snd-rpi-boomberry-digi", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_boomberry_digi_of_match, -+ }, -+ .probe = snd_rpi_boomberry_digi_probe, -+ .remove = snd_rpi_boomberry_digi_remove, -+}; -+ -+module_platform_driver(snd_rpi_boomberry_digi_driver); -+ -+MODULE_AUTHOR("Milan Neskovic "); -+MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI Digi HAT Sound Card"); -+MODULE_LICENSE("GPL v2"); - -From e3ea2e74ce1c734d3bbfd1270e8934cb3de80431 Mon Sep 17 00:00:00 2001 -From: Aaron Shaw -Date: Fri, 8 Apr 2016 00:06:00 +0100 -Subject: [PATCH 239/251] Add support for mcp7940x family of RTC - ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 6 ++++++ - 2 files changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index eb5fc04..6a62e6f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -435,6 +435,8 @@ Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device - -+ mcp7940x Select the MCP7940x device -+ - mcp7941x Select the MCP7941x device - - pcf2127 Select the PCF2127 device -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index eecec16..4065647 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -23,6 +23,11 @@ - reg = <0x68>; - status = "disable"; - }; -+ mcp7940x: mcp7940x@6f { -+ compatible = "microchip,mcp7940x"; -+ reg = <0x6f>; -+ status = "disable"; -+ }; - mcp7941x: mcp7941x@6f { - compatible = "microchip,mcp7941x"; - reg = <0x6f>; -@@ -54,6 +59,7 @@ - ds1307 = <&ds1307>,"status"; - ds1339 = <&ds1339>,"status"; - ds3231 = <&ds3231>,"status"; -+ mcp7940x = <&mcp7940x>,"status"; - mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - -From a10d74e309c02ad451678e59c320d62208944605 Mon Sep 17 00:00:00 2001 -From: Jeremy McDermond -Date: Thu, 14 Apr 2016 09:39:20 -0700 -Subject: [PATCH 240/251] bcm2709_defconfig: Fix typo on BoomBerry - configuration directive - -The BoomBerry configuration directive in bcm2709_defconfig has a typo. ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 84ec380..7353332 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -854,7 +854,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SNG_BCM2708_SOC_BOOMBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - -From eb62c144a47bbc7d0015d65629fad05884aa654b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 15 Apr 2016 10:48:39 +0100 -Subject: [PATCH 241/251] boomberry-dac: Adjust for ALSA API change - -As of 4.4, snd_soc_limit_volume now takes a struct snd_soc_card * -rather than a struct snd_soc_codec *. - -Signed-off-by: Phil Elwell ---- - sound/soc/bcm/boomberry-dac.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/sound/soc/bcm/boomberry-dac.c b/sound/soc/bcm/boomberry-dac.c -index 08845ad..8d39de2 100644 ---- a/sound/soc/bcm/boomberry-dac.c -+++ b/sound/soc/bcm/boomberry-dac.c -@@ -40,9 +40,8 @@ static int snd_rpi_boomberry_dac_init(struct snd_soc_pcm_runtime *rtd) - { - int ret; - struct snd_soc_card *card = rtd->card; -- struct snd_soc_codec *codec = rtd->codec; - -- ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); - if (ret < 0) - dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); - } - -From d113d5842f6896cdcdd7c7c2e5733fe0ed0a5b06 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Sun, 17 Apr 2016 04:44:47 -0700 -Subject: [PATCH 242/251] vmcs: Remove unused sm_cache_map_vector definition - (#1411) - -The code using it also ifdef'ed with 0, anyyd gcc 6 -complains - -error: 'sm_cache_map_vector' defined but not used - -The code using it also ifdef'ed out - -Signed-off-by: Khem Raj ---- - drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 5d16e35..1db6716 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -197,12 +197,14 @@ struct SM_STATE_T { - static struct SM_STATE_T *sm_state; - static int sm_inited; - -+#if 0 - static const char *const sm_cache_map_vector[] = { - "(null)", - "host", - "videocore", - "host+videocore", - }; -+#endif - - /* ---- Private Function Prototypes -------------------------------------- */ - - -From 8842f5b24445286359d13b8f85230384a361f26b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 Apr 2016 11:56:53 +0100 -Subject: [PATCH 243/251] scripts/mkknlimg: Append a trailer for all input - -Now that the firmware assumes an unsigned kernel is DT-capable, it is -helpful to be able to mark a kernel as being non-DT-capable. - -Signed-off-by: Phil Elwell ---- - scripts/mkknlimg | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index 005f404..78c5845 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -98,7 +98,7 @@ my $append_trailer; - my $trailer; - my $kver = '?'; - --$append_trailer = $dtok; -+$append_trailer = 1; - - if ($res) - { -@@ -108,7 +108,6 @@ if ($res) - - if ($flags & FLAG_PI) - { -- $append_trailer = 1; - $dtok ||= ($flags & FLAG_DTOK) != 0; - $is_270x ||= ($flags & FLAG_270X) != 0; - $is_283x ||= ($flags & FLAG_283X) != 0; -@@ -116,18 +115,18 @@ if ($res) - } - else - { -- print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); -+ print ("* This doesn't look like a Raspberry Pi kernel.\n"); - } - } - elsif (!$dtok) - { -- print ("* Is this a valid kernel? In pass-through mode.\n"); -+ print ("* Is this a valid kernel?\n"); - } - - if ($append_trailer) - { - printf("DT: %s\n", $dtok ? "y" : "n"); -- printf("DDT: %s\n", $ddtk ? "y" : "n") if ($ddtk); -+ printf("DDT: %s\n", $ddtk ? "y" : "n"); - printf("270x: %s\n", $is_270x ? "y" : "n"); - printf("283x: %s\n", $is_283x ? "y" : "n"); - -@@ -136,7 +135,7 @@ if ($append_trailer) - push @atoms, [ $trailer_magic, pack('V', 0) ]; - push @atoms, [ 'KVer', $kver ]; - push @atoms, [ 'DTOK', pack('V', $dtok) ]; -- push @atoms, [ 'DDTK', pack('V', $ddtk) ] if ($ddtk); -+ push @atoms, [ 'DDTK', pack('V', $ddtk) ]; - push @atoms, [ '270X', pack('V', $is_270x) ]; - push @atoms, [ '283X', pack('V', $is_283x) ]; - push @atoms, [ '283x', pack('V', $is_283x && !$is_270x) ]; - -From 4713de1914febfd095de6c68d7152c10ba60a475 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Apr 2016 13:55:29 +0100 -Subject: [PATCH 244/251] scripts/dtc: Only emit local fixups for overlays - -Signed-off-by: Phil Elwell ---- - scripts/dtc/checks.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 2b3b3a7..fedfa79 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -514,7 +514,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - } - - /* if it's a local reference, we need to record it */ -- if (symbol_fixup_support) { -+ if (symbol_fixup_support && dt->is_plugin) { - - /* allocate a new local fixup entry */ - fe = xmalloc(sizeof(*fe)); - -From 8f691a8d8e5dd4a0e48f3fcc766936215a0efb27 Mon Sep 17 00:00:00 2001 +From 1d3ef6f3ee8e621efbfcf2147d80aba94ed50a12 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 19 Apr 2016 12:57:52 +0100 -Subject: [PATCH 245/251] bcm2835_thermal: Don't report unsupported trip type +Subject: [PATCH 107/114] bcm2835_thermal: Don't report unsupported trip type --- drivers/thermal/bcm2835-thermal.c | 34 +--------------------------------- @@ -165389,316 +131921,301 @@ index 08d8dc7..c63fb9f 100644 if (IS_ERR(tz)) { dev_err(&pdev->dev, "Failed to register the thermal device\n"); -From f92bda16cd790cb612920ed266d19c6ae2620c22 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:08:35 +0200 -Subject: [PATCH 246/251] bcm2835: do not require substream for accessing chmap - ctl +From c1e63a730e6d4ec6d212d39f37a425fc4bbcd7a0 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Sun, 17 Apr 2016 04:44:47 -0700 +Subject: [PATCH 108/114] vmcs: Remove unused sm_cache_map_vector definition + (#1411) -Fixes alsasctl store/restore operation. +The code using it also ifdef'ed with 0, anyyd gcc 6 +complains + +error: 'sm_cache_map_vector' defined but not used + +The code using it also ifdef'ed out + +Signed-off-by: Khem Raj --- - sound/arm/bcm2835-ctl.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) + drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 ++ + 1 file changed, 2 insertions(+) -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index e930718..8b855f9 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -489,8 +489,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, +diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c +index 5d16e35..1db6716 100644 +--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c ++++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c +@@ -197,12 +197,14 @@ struct SM_STATE_T { + static struct SM_STATE_T *sm_state; + static int sm_inited; + ++#if 0 + static const char *const sm_cache_map_vector[] = { + "(null)", + "host", + "videocore", + "host+videocore", + }; ++#endif + + /* ---- Private Function Prototypes -------------------------------------- */ + + +From 150f46922b0f2da460cc2cd447c6c039285dce27 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 5 Apr 2016 13:01:54 +0100 +Subject: [PATCH 109/114] BCM270X_DT: Add dpi24 overlay + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 +++++++ + arch/arm/boot/dts/overlays/dpi24-overlay.dts | 31 ++++++++++++++++++++++++++++ + 3 files changed, 40 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/dpi24-overlay.dts + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 7c4fc30..e6daef5 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -15,6 +15,7 @@ endif + dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo + dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo + dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index e88e7c8..5f8e4fd 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -213,6 +213,14 @@ Params: gpiopin GPIO connected to the sensor's DATA output. + (default 4) + + ++Name: dpi24 ++Info: Overlay for a generic 24-bit DPI display ++ This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output ++ 2-3 seconds after the kernel has started. ++Load: dtoverlay=dpi24 ++Params: ++ ++ + Name: dwc-otg + Info: Selects the dwc_otg USB controller driver which has fiq support. This + is the default on all except the Pi Zero which defaults to dwc2. +diff --git a/arch/arm/boot/dts/overlays/dpi24-overlay.dts b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +new file mode 100644 +index 0000000..e4dbe40 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +@@ -0,0 +1,31 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ // There is no DPI driver module, but we need a platform device ++ // node (that doesn't already use pinctrl) to hang the pinctrl ++ // reference on - leds will do ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dpi24_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ dpi24_pins: dpi24_pins { ++ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 ++ 12 13 14 15 16 17 18 19 20 ++ 21 22 23 24 25 26 27>; ++ brcm,function = <6>; /* alt2 */ ++ brcm,pull = <0>; /* no pull */ ++ }; ++ }; ++ }; ++}; + +From 21f5b65c2dfc30fd3c75bb9ad242eed0c5f3a5d8 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 5 Apr 2016 19:40:12 +0100 +Subject: [PATCH 110/114] reboot: Use power off rather than busy spinning when + halt is requested + +--- + arch/arm/kernel/reboot.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c +index 71a2ff9..812c15e 100644 +--- a/arch/arm/kernel/reboot.c ++++ b/arch/arm/kernel/reboot.c +@@ -102,11 +102,7 @@ void machine_shutdown(void) + */ + void machine_halt(void) { - struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); - bcm2835_chip_t *chip = info->private_data; -- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -- struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - struct cea_channel_speaker_allocation *ch = NULL; - int res = 0; - int cur = 0; -@@ -499,11 +497,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - -- if (!substream || !substream->runtime) { -- res = -ENODEV; -- goto unlock; -- } +- local_irq_disable(); +- smp_send_stop(); - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { - if (channel_allocations[i].ca_index == chip->cea_chmap) - ch = &channel_allocations[i]; -@@ -521,7 +514,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - while (cur < 8) - ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; - --unlock: - mutex_unlock(&chip->audio_mutex); - return res; +- local_irq_disable(); +- while (1); ++ machine_power_off(); } -@@ -541,7 +533,7 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - return -EINTR; - - if (!substream || !substream->runtime) { -- res = -ENODEV; -+ /* ignore and return success for the sake of alsactl */ - goto unlock; - } + /* -From 2c9ca7ae6ac79df824b94224936d378d725b7bb7 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:29:41 +0200 -Subject: [PATCH 247/251] bcm2835: add fallback channel layouts if channel map - API is not used - -Should be more useful than just forcing stereo. - -We can't match the exact legacy ALSA channel layouts, so this is a -"best effort" hack. - -I'm not sure what happens if the application requests channel counts -that are not power-of-2s. The channel map API hopefully forces -applications which use the channel map API to request the correct -count by adding padding channels, but the bare API enforces -nothing. Possibly this could be added to rate_hw_constraint_channels -at a later point. ---- - sound/arm/bcm2835-vchiq.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 8ecd2d7..9371073 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -598,7 +598,16 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - if (alsa_stream->chip->cea_chmap >= 0) { - chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; - } else { -- chmap_value = 0; /* force stereo */ -+ /* fallback layouts for applications which do not use chmap API */ -+ chmap_value = 0x00; -+ switch (channels) { -+ case 3: chmap_value = 0x01; break; -+ case 4: chmap_value = 0x03; break; -+ case 5: chmap_value = 0x07; break; -+ case 6: chmap_value = 0x0b; break; -+ case 7: chmap_value = 0x0f; break; -+ case 8: chmap_value = 0x13; break; -+ } - for (i = 0; i < 8; i++) - alsa_stream->chip->map_channels[i] = i; - } - -From a9670f6cc4cd89aa953d6240b037ebfa161e552b Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:38:03 +0200 -Subject: [PATCH 248/251] bcm2835: log which channel map is set - ---- - sound/arm/bcm2835-vchiq.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 9371073..876986d 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -596,8 +596,11 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - instance->result = -1; - - if (alsa_stream->chip->cea_chmap >= 0) { -+ LOG_INFO("Using application requested channel map: %d\n", -+ alsa_stream->chip->cea_chmap); - chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; - } else { -+ LOG_INFO("Using fallback channel map.\n"); - /* fallback layouts for applications which do not use chmap API */ - chmap_value = 0x00; - switch (channels) { -@@ -614,6 +617,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - for (i = 0; i < 8; i++) - chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); - -+ LOG_INFO("Requesting AUDS channel map: 0x%lx\n", (long)chmap_value); -+ - m.type = VC_AUDIO_MSG_TYPE_CONFIG; - m.u.config.channels = channels; - m.u.config.samplerate = samplerate; - -From 9135f5620348b62310684d40896ae21d993a563d Mon Sep 17 00:00:00 2001 +From 7e5b50942960069881572b173d745c22958e9d69 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Thu, 21 Apr 2016 13:49:32 +0100 -Subject: [PATCH 249/251] vchiq_arm: Add completion records under the mutex +Date: Wed, 30 Mar 2016 17:23:15 +0100 +Subject: [PATCH 111/114] cpufreq: Temporarily ignore io_is_busy=1 -An issue was observed when flushing openmax components -which generate a large number of messages returning -buffers to host. - -We occasionally found a duplicate message from 16 -messages prior, resulting in a buffer returned twice. - -While only one thread adds completions, without the -mutex you don't get the protection of the automatic -memory barrier you get with synchronisation objects. +To speed testing of the new sdhost driver that adapts to changes in +core_freq, hack the on-demand governor to treat io_is_busy=1 as +io_is_busy=0. The io_is_busy feature can still be forced using +io_is_busy=2. Signed-off-by: Phil Elwell --- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) + drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index a5cc385..4886236 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - VCHIQ_COMPLETION_DATA_T *completion; - DEBUG_INITIALISE(g_state.local) +diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c +index acd8027..72c5a4c 100644 +--- a/drivers/cpufreq/cpufreq_ondemand.c ++++ b/drivers/cpufreq/cpufreq_ondemand.c +@@ -216,7 +216,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, + ret = sscanf(buf, "%u", &input); + if (ret != 1) + return -EINVAL; +- dbs_data->io_is_busy = !!input; ++ // XXX temporary hack ++ if (input > 1) ++ input = 1; ++ else ++ input = 0; ++ dbs_data->io_is_busy = input; -+ mutex_lock(&instance->completion_mutex); -+ - while (instance->completion_insert == - (instance->completion_remove + MAX_COMPLETIONS)) { - /* Out of space - wait for the client */ -@@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - vchiq_log_trace(vchiq_arm_log_level, - "add_completion - completion queue full"); - DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); -+ -+ mutex_unlock(&instance->completion_mutex); - if (down_interruptible(&instance->remove_event) != 0) { - vchiq_log_info(vchiq_arm_log_level, - "service_callback interrupted"); - return VCHIQ_RETRY; -- } else if (instance->closing) { -+ } -+ -+ mutex_lock(&instance->completion_mutex); -+ if (instance->closing) { -+ mutex_unlock(&instance->completion_mutex); - vchiq_log_info(vchiq_arm_log_level, - "service_callback closing"); - return VCHIQ_SUCCESS; -@@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - if (reason == VCHIQ_MESSAGE_AVAILABLE) - user_service->message_available_pos = - instance->completion_insert; -+ - instance->completion_insert++; - -+ mutex_unlock(&instance->completion_mutex); -+ - up(&instance->insert_event); - - return VCHIQ_SUCCESS; + /* we need to re-evaluate prev_cpu_idle */ + gov_update_cpu_data(dbs_data); -From 14ba3016c66394dca226fc4fd66b2fd2e677497c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 Apr 2016 16:07:15 +0100 -Subject: [PATCH 250/251] config: Add DRM_UDL module +From 5852c38e95e3f81ba96c4aa8014f9267700ce90f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 21 Apr 2016 20:24:17 +0100 +Subject: [PATCH 112/114] config: Make IPV6 a module and regenerate with + defconfig -See: https://github.com/raspberrypi/linux/issues/1422 - -Signed-off-by: Phil Elwell --- - arch/arm/configs/bcm2709_defconfig | 5 +++-- - arch/arm/configs/bcmrpi_defconfig | 5 +++-- - 2 files changed, 6 insertions(+), 4 deletions(-) + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm/configs/bcmrpi_defconfig | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7353332..7788ecb 100644 +index 2536c11..d930029 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -814,6 +814,7 @@ CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_DRM=m -+CONFIG_DRM_UDL=m - CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -@@ -853,10 +854,10 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_ADAU1701=m +@@ -4,7 +4,6 @@ CONFIG_LOCALVERSION="-v7" + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y + CONFIG_POSIX_MQUEUE=y +-CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y +@@ -101,6 +100,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m + CONFIG_INET_XFRM_MODE_TUNNEL=m + CONFIG_INET_XFRM_MODE_BEET=m + CONFIG_INET_DIAG=m ++CONFIG_IPV6=m + CONFIG_INET6_AH=m + CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 603ba04..5b8b19a 100644 +index bfb6936..4cfb186 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -806,6 +806,7 @@ CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_DRM=m -+CONFIG_DRM_UDL=m - CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -@@ -845,10 +846,10 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_ADAU1701=m +@@ -3,7 +3,6 @@ CONFIG_PHYS_OFFSET=0 + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y + CONFIG_POSIX_MQUEUE=y +-CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y +@@ -73,7 +72,6 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IPV6_SUBTREES=y + CONFIG_IP_ROUTE_MULTIPATH=y + CONFIG_IP_ROUTE_VERBOSE=y + CONFIG_IP_PNP=y +@@ -94,11 +92,13 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m + CONFIG_INET_XFRM_MODE_TUNNEL=m + CONFIG_INET_XFRM_MODE_BEET=m + CONFIG_INET_DIAG=m ++CONFIG_IPV6=m + CONFIG_INET6_AH=m + CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m + CONFIG_IPV6_TUNNEL=m + CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IPV6_MROUTE=y + CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y + CONFIG_IPV6_PIMSM_V2=y -From a114d1bd49a30b9b3aa31d4b18069986e0335e12 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 Apr 2016 15:44:14 +0100 -Subject: [PATCH 251/251] bcm2835-i2s: Reduce the TX DREQ threshold +From c7bb9cf080179e9abd76a48c2cb517369590780c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 21 Apr 2016 20:31:55 +0100 +Subject: [PATCH 113/114] firmware: Add RPI_FIRMWARE_SET_SDHOST_CLOCK -TX FIFO overrun is thought to be the cause of channel swapping, so -reducing the DREQ threshold seems reasonable and appears to be -effective. - -See: https://github.com/raspberrypi/linux/issues/1417 - -Signed-off-by: Phil Elwell --- - sound/soc/bcm/bcm2835-i2s.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 1 file changed, 1 insertion(+) -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 04c1d13..aedb01f 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -555,15 +555,22 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 73e4956..227a107 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -81,6 +81,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, ++ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, - /* Setup the DMA parameters */ - regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, -- BCM2835_I2S_RXTHR(1) -- | BCM2835_I2S_TXTHR(1) -- | BCM2835_I2S_DMAEN, 0xffffffff); -+ BCM2835_I2S_RXTHR(3) -+ | BCM2835_I2S_TXTHR(3) -+ | BCM2835_I2S_DMAEN, -+ BCM2835_I2S_RXTHR(1) -+ | BCM2835_I2S_TXTHR(1) -+ | BCM2835_I2S_DMAEN); - - regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, -- BCM2835_I2S_TX_PANIC(0x10) -- | BCM2835_I2S_RX_PANIC(0x30) -- | BCM2835_I2S_TX(0x30) -- | BCM2835_I2S_RX(0x20), 0xffffffff); -+ BCM2835_I2S_TX_PANIC(0x7f) -+ | BCM2835_I2S_RX_PANIC(0x7f) -+ | BCM2835_I2S_TX(0x7f) -+ | BCM2835_I2S_RX(0x7f), -+ BCM2835_I2S_TX_PANIC(0x10) -+ | BCM2835_I2S_RX_PANIC(0x30) -+ | BCM2835_I2S_TX(0x20) -+ | BCM2835_I2S_RX(0x20)); - - /* Clear FIFOs */ - bcm2835_i2s_clear_fifos(dev, true, true); + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, + +From 815cdfe7c75dbdbf13fc3d5b629ed0a68c895ef4 Mon Sep 17 00:00:00 2001 +From: dienet +Date: Fri, 22 Apr 2016 21:58:41 +0200 +Subject: [PATCH 114/114] fbdev: bcm2708_fb: remove unused variable and + duplicated comment (#1426) + +The yres varialbe is not used anywhere in this function. Also this comment looks +to be duplicated. Remove them. + +Signed-off-by: Slawomir Stepien +--- + drivers/video/fbdev/bcm2708_fb.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c +index a20539a..cae5aab 100644 +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -218,9 +218,6 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) + { + /* info input, var output */ +- int yres; +- +- /* info input, var output */ + print_debug("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, diff --git a/projects/RPi2/patches/linux/linux-01-RPi_support.patch b/projects/RPi2/patches/linux/linux-01-RPi_support.patch index fce60a62ce..ac6f79e6d1 100644 --- a/projects/RPi2/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi2/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ -From 3cc8c1beb520133149f9cb5d394cbc1c8bbb01b0 Mon Sep 17 00:00:00 2001 +From e25d546f3718eac8527f09bba58083d175247f19 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 001/251] smsx95xx: fix crimes against truesize +Subject: [PATCH 001/114] smsx95xx: fix crimes against truesize smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. @@ -9,44 +9,56 @@ This patch stops smsc95xx from changing truesize. Signed-off-by: Steve Glendinning --- - drivers/net/usb/smsc95xx.c | 2 -- - 1 file changed, 2 deletions(-) - mode change 100644 => 100755 drivers/net/usb/smsc95xx.c + drivers/net/usb/smsc95xx.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100644 -new mode 100755 -index 66b3ab9..b544181 +index 66b3ab9..ea2dbe5 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -1785,7 +1785,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +@@ -74,6 +74,10 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + ++static bool truesize_mode = false; ++module_param(truesize_mode, bool, 0644); ++MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); ++ + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +@@ -1785,7 +1789,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(skb); skb_trim(skb, skb->len - 4); /* remove fcs */ - skb->truesize = size + sizeof(struct sk_buff); ++ if (truesize_mode) ++ skb->truesize = size + sizeof(struct sk_buff); return 1; } -@@ -1803,7 +1802,6 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +@@ -1803,7 +1808,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(ax_skb); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ - ax_skb->truesize = size + sizeof(struct sk_buff); ++ if (truesize_mode) ++ ax_skb->truesize = size + sizeof(struct sk_buff); usbnet_skb_return(dev, ax_skb); } -From d41a067375e9d557ee14ad6ecefbc559b724087c Mon Sep 17 00:00:00 2001 +From 607cb751d33b6af0d182a82a96eb14e4ff7c2ed7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 002/251] smsc95xx: Disable turbo mode by default +Subject: [PATCH 002/114] smsc95xx: Disable turbo mode by default --- drivers/net/usb/smsc95xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index b544181..9c0da18 100755 +index ea2dbe5..714cfe0 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -70,7 +70,7 @@ struct smsc95xx_priv { @@ -59,10 +71,41 @@ index b544181..9c0da18 100755 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); -From 52a67e5a346e7dfcd6af9115800108d6c9fca84e Mon Sep 17 00:00:00 2001 +From 1f222ae94cf97c02532c10a907fba8a7e1d57f08 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 9 Mar 2016 13:28:24 +0000 +Subject: [PATCH 003/114] serial: Take care starting a hung-up tty's port + +tty_port_hangup sets a port's tty field to NULL (holding the port lock), +but uart_tx_stopped, called from __uart_start (with the port lock), +uses the tty field without checking for NULL. + +Change uart_tx_stopped to treat a NULL tty field as another stopped +indication. + +Signed-off-by: Phil Elwell +--- + include/linux/serial_core.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index cbfcf38..96bc15a 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -403,7 +403,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); + static inline int uart_tx_stopped(struct uart_port *port) + { + struct tty_struct *tty = port->state->port.tty; +- if (tty->stopped || port->hw_stopped) ++ if (!tty || tty->stopped || port->hw_stopped) + return 1; + return 0; + } + +From dc048b33ed7346ea328d4e513f10549f37d98fb7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 003/251] vmstat: Workaround for issue where dirty page count +Subject: [PATCH 004/114] vmstat: Workaround for issue where dirty page count goes negative See: @@ -73,10 +116,10 @@ http://www.spinics.net/lists/linux-mm/msg72236.html 1 file changed, 4 insertions(+) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 3e5d907..2539068 100644 +index 73fae8c..5dd1278 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h -@@ -219,7 +219,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) +@@ -220,7 +220,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) { atomic_long_dec(&zone->vm_stat[item]); @@ -89,16 +132,43 @@ index 3e5d907..2539068 100644 static inline void __inc_zone_page_state(struct page *page, -From 5956e14120ab88b53fe2f68f7de6c197eae4a811 Mon Sep 17 00:00:00 2001 +From 39ff92a84c78a9a9732ac7f72de3691a1462060d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 18 Dec 2014 16:07:15 -0800 +Subject: [PATCH 005/114] mm: Remove the PFN busy warning + +See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is +expected sometimes when using CMA. However, that commit still spams +my kernel log with these warnings. + +Signed-off-by: Eric Anholt +--- + mm/page_alloc.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 59de90d..a7b5691 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -7101,8 +7101,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, + + /* Make sure the range is really isolated. */ + if (test_pages_isolated(outer_start, end, false)) { +- pr_info("%s: [%lx, %lx) PFNs busy\n", +- __func__, outer_start, end); + ret = -EBUSY; + goto done; + } + +From c9a338a0415713d87a65f1df36e158c496f88fd1 Mon Sep 17 00:00:00 2001 From: Robert Tiemann Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 004/251] BCM2835_DT: Fix I2S register map +Subject: [PATCH 006/114] BCM2835_DT: Fix I2S register map --- Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 4 ++-- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++-- - 3 files changed, 6 insertions(+), 6 deletions(-) + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt index 1396078..2db8294 100644 @@ -130,26 +200,11 @@ index 65783de..a89fe42 100644 dmas = <&dma 2>, <&dma 3>; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index aef64de..864a3ef 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -120,8 +120,8 @@ - - i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -+ reg = <0x7e203000 0x24>, -+ <0x7e101098 0x08>; - - dmas = <&dma 2>, - <&dma 3>; -From bd8d0148b99e3281aaa294257961377c93a9381d Mon Sep 17 00:00:00 2001 +From aca2671953e17069ad8f56e130163101381fc736 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 4 Dec 2015 17:41:50 +0000 -Subject: [PATCH 005/251] irq-bcm2836: Prevent spurious interrupts, and trap +Subject: [PATCH 007/114] irq-bcm2836: Prevent spurious interrupts, and trap them early The old arch-specific IRQ macros included a dsb to ensure the @@ -160,30 +215,26 @@ precaution to avoid spurious interrupts. Spurious interrupts are still possible for other reasons, though, so trap them early. --- - drivers/irqchip/irq-bcm2836.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + drivers/irqchip/irq-bcm2836.c | 1 + + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c -index f687082..4cd8ebe 100644 +index b6e950d..bbb92c2 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c -@@ -170,9 +170,10 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) +@@ -175,6 +175,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) u32 ipi = ffs(mbox_val) - 1; writel(1 << ipi, mailbox0); + dsb(); handle_IPI(ipi, regs); #endif -- } else { -+ } else if (stat) { - u32 hwirq = ffs(stat) - 1; - - handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); + } else if (stat) { -From 2311742728ef10f5d7ed17debc4065e90cb25c7e Mon Sep 17 00:00:00 2001 +From d1d05c91acf24e5222af4522c7c2c9d615ab68cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 12 Jun 2015 19:01:05 +0200 -Subject: [PATCH 006/251] irqchip: bcm2835: Add FIQ support +Subject: [PATCH 008/114] irqchip: bcm2835: Add FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -201,12 +252,12 @@ Acked-by: Stephen Warren 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig -index 8c53c55..c943747 100644 +index 7ef1214..b1a5a7b 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig -@@ -128,6 +128,7 @@ config ARCH_BCM2835 - select ARM_ERRATA_411920 +@@ -143,6 +143,7 @@ config ARCH_BCM2835 select ARM_TIMER_SP804 + select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select CLKSRC_OF + select FIQ select PINCTRL @@ -312,10 +363,10 @@ index bf9cc5f..3f601f9 100644 } -From 60f12c460c71c04609a23be23df6eb986481c365 Mon Sep 17 00:00:00 2001 +From bdf258bc4df61515e3de2a4caa597ccc96b519ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 23 Oct 2015 16:26:55 +0200 -Subject: [PATCH 007/251] irqchip: irq-bcm2835: Add 2836 FIQ support +Subject: [PATCH 009/114] irqchip: irq-bcm2835: Add 2836 FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -411,17 +462,41 @@ index 3f601f9..20deb28 100644 for (b = 0; b < NR_BANKS; b++) { for (i = 0; i < bank_irqs[b]; i++) { -From 8de2ecc5c42ae0a909fbc23da58ef2fa552d4c5b Mon Sep 17 00:00:00 2001 +From e623ec6ba4ad40fa1863a573ec86e71c3efa1955 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 14 Jul 2015 10:26:09 +0100 +Subject: [PATCH 010/114] spidev: Add "spidev" compatible string to silence + warning + +See: https://github.com/raspberrypi/linux/issues/1054 +--- + drivers/spi/spidev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index e3c19f3..f4963e3 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -695,6 +695,7 @@ static struct class *spidev_class; + static const struct of_device_id spidev_dt_ids[] = { + { .compatible = "rohm,dh2228fv" }, + { .compatible = "lineartechnology,ltc2488" }, ++ { .compatible = "spidev" }, + {}, + }; + MODULE_DEVICE_TABLE(of, spidev_dt_ids); + +From 27fe80aa5b09a161ff66c1d6e5588a41e7d19225 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 008/251] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 011/114] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index 3912646..b51a59c 100644 +index 2f4f5ee..edc1355 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -509,6 +509,8 @@ static void __init serial8250_isa_init_ports(void) @@ -434,10 +509,10 @@ index 3912646..b51a59c 100644 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From 2567dee80cdc0654788137d07308fa428d3dc8fb Mon Sep 17 00:00:00 2001 +From 46789d89b66ad2a8bb68da0ddeb16665dffe5f5a Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 009/251] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 012/114] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -446,7 +521,7 @@ Signed-off-by: Noralf Tronnes 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 17dd8fe..613be28 100644 +index 08b1d93..0a23c81 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -373,7 +373,7 @@ static struct gpio_chip bcm2835_gpio_chip = { @@ -459,10 +534,10 @@ index 17dd8fe..613be28 100644 .can_sleep = false, }; -From f23532983c575cac8b55c4bceb1e45a1439f7e0e Mon Sep 17 00:00:00 2001 +From bcb2842b04e0e339a863fd5cc5f760d1c84e10ca Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 010/251] pinctrl-bcm2835: Fix interrupt handling for GPIOs +Subject: [PATCH 013/114] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has @@ -483,7 +558,7 @@ the pins are often used for I2S instead. 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index 613be28..a06cf9e 100644 +index 0a23c81..b793bbd 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ @@ -608,10 +683,10 @@ index 613be28..a06cf9e 100644 }, }; -From fe30b946aef6315884bd029f889f6eb3692705e5 Mon Sep 17 00:00:00 2001 +From 4bcd8fc5cde916b2bd2807045d65cdcf9372ef53 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 011/251] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 014/114] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -625,7 +700,7 @@ interface, is unlikely to be a problem. 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -index a06cf9e..32f779e 100644 +index b793bbd..8683a1b 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -1029,6 +1029,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) @@ -638,10 +713,10 @@ index a06cf9e..32f779e 100644 pc->irq_data[i].irqgroup = i; -From cc544ca7cb8b033c7bf3d884277f32887a1417a7 Mon Sep 17 00:00:00 2001 +From 6ccfd268fe86872db44f61ba61d4dbac59c57186 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 012/251] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 015/114] spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the @@ -658,7 +733,7 @@ Signed-off-by: Phil Elwell 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index cf04960..a2b1f45 100644 +index f35cc10..5dfe20f 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -688,6 +688,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) @@ -722,10 +797,10 @@ index cf04960..a2b1f45 100644 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From 8cf07dd13a251b72f28805060d58b942b582feef Mon Sep 17 00:00:00 2001 +From 91bab1f8dcc81e282512c8f808b8d9ca2f7975b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 013/251] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 016/114] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -750,7 +825,7 @@ Signed-off-by: Noralf Trønnes 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 0f7b9ea..1e6f1cf 100644 +index 834d676..3b68a8d 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -17,12 +17,16 @@ @@ -783,78 +858,10 @@ index 0f7b9ea..1e6f1cf 100644 static const char * const bcm2835_compat[] = { -From 902ceaaea891e7883c141d45e52dde7d859e2324 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 16:44:05 +0200 -Subject: [PATCH 014/251] bcm2835-i2s: get base address for DMA from devicetree - -Code copied from spi-bcm2835. Get physical address from devicetree -instead of using hardcoded constant. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 8c435be..0bc4f47 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -158,10 +159,6 @@ static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { - #define BCM2835_I2S_INT_RXR BIT(1) - #define BCM2835_I2S_INT_TXW BIT(0) - --/* I2S DMA interface */ --/* FIXME: Needs IOMMU support */ --#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) -- - /* General device struct */ - struct bcm2835_i2s_dev { - struct device *dev; -@@ -791,6 +788,15 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - int ret; - struct regmap *regmap[2]; - struct resource *mem[2]; -+ const __be32 *addr; -+ dma_addr_t dma_reg_base; -+ -+ addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); -+ if (!addr) { -+ dev_err(&pdev->dev, "could not get DMA-register address\n"); -+ return -ENODEV; -+ } -+ dma_reg_base = be32_to_cpup(addr); - - /* Request both ioareas */ - for (i = 0; i <= 1; i++) { -@@ -817,12 +823,10 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - - /* Set the DMA address */ - dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = -- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG -- + BCM2835_VCMMU_SHIFT; -+ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - - dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = -- (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG -- + BCM2835_VCMMU_SHIFT; -+ dma_reg_base + BCM2835_I2S_FIFO_A_REG; - - /* Set the bus width */ - dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = - -From c89c8dc0cde738e6d2a5d07dbfd2aaa72f4a07d0 Mon Sep 17 00:00:00 2001 +From 9b4fc474912bed145c59cc8dcb76a48006cb46ea Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:21:16 +0200 -Subject: [PATCH 015/251] bcm2835-i2s: add 24bit support, update bclk_ratio to +Subject: [PATCH 017/114] bcm2835-i2s: add 24bit support, update bclk_ratio to more correct values Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -882,32 +889,24 @@ https://github.com/raspberrypi/linux/issues/681 Signed-off-by: Matthias Reichl --- - sound/soc/bcm/bcm2835-i2s.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) + sound/soc/bcm/bcm2835-i2s.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 0bc4f47..cf60390 100644 +index 1c1f221..d2663e7 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -340,11 +340,15 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - switch (params_format(params)) { +@@ -259,6 +259,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S16_LE: data_length = 16; -- bclk_ratio = 40; -+ bclk_ratio = 50; -+ break; + break; + case SNDRV_PCM_FORMAT_S24_LE: + data_length = 24; -+ bclk_ratio = 50; - break; ++ break; case SNDRV_PCM_FORMAT_S32_LE: data_length = 32; -- bclk_ratio = 80; -+ bclk_ratio = 100; break; - default: - return -EINVAL; -@@ -420,7 +424,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, +@@ -279,7 +282,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* Setup the frame format */ format = BCM2835_I2S_CHEN; @@ -916,7 +915,7 @@ index 0bc4f47..cf60390 100644 format |= BCM2835_I2S_CHWEX; format |= BCM2835_I2S_CHWID((data_length-8)&0xf); -@@ -711,6 +715,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { +@@ -570,6 +573,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE @@ -924,7 +923,7 @@ index 0bc4f47..cf60390 100644 | SNDRV_PCM_FMTBIT_S32_LE }, .capture = { -@@ -718,6 +723,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { +@@ -577,6 +581,7 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE @@ -933,107 +932,10 @@ index 0bc4f47..cf60390 100644 }, .ops = &bcm2835_i2s_dai_ops, -From da23963f1f4c8999ec76bb99234aec3864b0e56f Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 15:25:51 +0200 -Subject: [PATCH 016/251] bcm2835-i2s: setup clock only if CPU is clock master - -Code ported from bcm2708-i2s driver in Raspberry Pi tree. - -RPi commit c14827ecdaa36607f6110f9ce8df96e698672191 ("bcm2708: Allow -option card devices to be configured via DT") - -Original work by Zoltan Szenczi, committed to RPi tree by -Phil Elwell. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 28 +++++++++++++++++++--------- - 1 file changed, 19 insertions(+), 9 deletions(-) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index cf60390..4ac4e92 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -411,15 +411,25 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - divf = dividend & BCM2835_CLK_DIVF_MASK; - } - -- /* Set clock divider */ -- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD -- | BCM2835_CLK_DIVI(divi) -- | BCM2835_CLK_DIVF(divf)); -- -- /* Setup clock, but don't start it yet */ -- regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD -- | BCM2835_CLK_MASH(mash) -- | BCM2835_CLK_SRC(clk_src)); -+ /* Clock should only be set up here if CPU is clock master */ -+ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ case SND_SOC_DAIFMT_CBS_CFM: -+ /* Set clock divider */ -+ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, -+ BCM2835_CLK_PASSWD -+ | BCM2835_CLK_DIVI(divi) -+ | BCM2835_CLK_DIVF(divf)); -+ -+ /* Setup clock, but don't start it yet */ -+ regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, -+ BCM2835_CLK_PASSWD -+ | BCM2835_CLK_MASH(mash) -+ | BCM2835_CLK_SRC(clk_src)); -+ break; -+ default: -+ break; -+ } - - /* Setup the frame format */ - format = BCM2835_I2S_CHEN; - -From 611d61511eefc080a178187b36c9d86aec9bb8b0 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 11 Oct 2015 15:49:51 +0200 -Subject: [PATCH 017/251] bcm2835-i2s: Eliminate debugfs directory error - -Code ported from bcm2708-i2s driver in Raspberry Pi tree. - -RPi commit fd7d7a3dbe9262d16971ef81c234ed28c6499dd7 ("bcm2708: -Eliminate i2s debugfs directory error") - -Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') -to avoid the name clash when registering debugfs entries. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/bcm2835-i2s.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 4ac4e92..aab3df9 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -782,6 +782,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { - .precious_reg = bcm2835_i2s_precious_reg, - .volatile_reg = bcm2835_i2s_volatile_reg, - .cache_type = REGCACHE_RBTREE, -+ .name = "i2s", - }, - { - .reg_bits = 32, -@@ -790,6 +791,7 @@ static const struct regmap_config bcm2835_regmap_config[] = { - .max_register = BCM2835_CLK_PCMDIV_REG, - .volatile_reg = bcm2835_clk_volatile_reg, - .cache_type = REGCACHE_RBTREE, -+ .name = "clk", - }, - }; - - -From bb6885bf7549495ca00d9a839954dcd35c4b9e61 Mon Sep 17 00:00:00 2001 +From ad1d838172d12324cf8029f18a445ed35d895a6a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:35:20 +0200 -Subject: [PATCH 018/251] bcm2835-i2s: Register PCM device +Subject: [PATCH 018/114] bcm2835-i2s: Register PCM device Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -1055,10 +957,10 @@ Signed-off-by: Matthias Reichl 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index aab3df9..0e5c787 100644 +index d2663e7..3a8468d 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -799,6 +799,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { +@@ -625,6 +625,25 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { .name = "bcm2835-i2s-comp", }; @@ -1084,7 +986,7 @@ index aab3df9..0e5c787 100644 static int bcm2835_i2s_probe(struct platform_device *pdev) { struct bcm2835_i2s_dev *dev; -@@ -870,7 +889,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) +@@ -697,7 +716,9 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) return ret; } @@ -1096,10 +998,10 @@ index aab3df9..0e5c787 100644 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); return ret; -From 7eced106f678f81b479e3f4fcc0de5b0c8e1dbd9 Mon Sep 17 00:00:00 2001 +From 724a0c2c6cac52d4ea41db9d5c45fea6e1a3d34d Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 15:55:21 +0200 -Subject: [PATCH 019/251] bcm2835-i2s: Enable MMAP support via a DT property +Subject: [PATCH 019/114] bcm2835-i2s: Enable MMAP support via a DT property Code ported from bcm2708-i2s driver in Raspberry Pi tree. @@ -1118,10 +1020,10 @@ Signed-off-by: Matthias Reichl 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 0e5c787..04c1d13 100644 +index 3a8468d..c7f3fc7 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -799,7 +799,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { +@@ -625,7 +625,7 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { .name = "bcm2835-i2s-comp", }; @@ -1130,23 +1032,23 @@ index 0e5c787..04c1d13 100644 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX, .formats = SNDRV_PCM_FMTBIT_S16_LE | -@@ -835,6 +835,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) - } - dma_reg_base = be32_to_cpup(addr); +@@ -653,6 +653,11 @@ static int bcm2835_i2s_probe(struct platform_device *pdev) + const __be32 *addr; + dma_addr_t dma_base; + if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) + bcm2835_pcm_hardware.info |= + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID; + - /* Request both ioareas */ - for (i = 0; i <= 1; i++) { - void __iomem *base; + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), + GFP_KERNEL); + if (!dev) -From 6de25eb4521167e2d9d5a9c777333cec1542192f Mon Sep 17 00:00:00 2001 +From 3c8b0d34e47e2b73f9f67ee92013abf7c873cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Thu, 9 Apr 2015 12:34:11 +0200 -Subject: [PATCH 020/251] dmaengine: bcm2835: Add slave dma support +Subject: [PATCH 020/114] dmaengine: bcm2835: Add slave dma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1466,10 +1368,10 @@ index 996c4b0..b278c66 100644 +MODULE_AUTHOR("Gellert Weisz "); MODULE_LICENSE("GPL v2"); -From 6090e63c27886fcd841ba451d8646c093a179b8d Mon Sep 17 00:00:00 2001 +From 21af238b62b6bf7ee2091692c8d88689299743b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 3 Oct 2015 15:58:59 +0200 -Subject: [PATCH 021/251] dmaengine: bcm2835: set residue_granularity field +Subject: [PATCH 021/114] dmaengine: bcm2835: set residue_granularity field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1498,10 +1400,10 @@ index b278c66..696fb30 100644 INIT_LIST_HEAD(&od->ddev.channels); spin_lock_init(&od->lock); -From ea0d9861bde9e049f8d5e43ae89dcf7844cb5e8d Mon Sep 17 00:00:00 2001 +From 7f42da09fd073abe725120c913ee14a5e9651f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 3 Oct 2015 22:22:55 +0200 -Subject: [PATCH 022/251] dmaengine: bcm2835: Load driver early and support +Subject: [PATCH 022/114] dmaengine: bcm2835: Load driver early and support legacy API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -1519,7 +1421,7 @@ Signed-off-by: Noralf Trønnes 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index e6cd1a3..060306e 100644 +index d96d87c..4d0425c 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -108,7 +108,7 @@ config COH901318 @@ -1601,10 +1503,10 @@ index 696fb30..5db0a95 100644 MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); -From 8947371bab57f6f0adb8c9519ceeba017fa5fc6a Mon Sep 17 00:00:00 2001 +From f5754ddf7a7c2406cc893b2bd890f0f91b321ae5 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sat, 10 Oct 2015 12:29:18 +0200 -Subject: [PATCH 023/251] bcm2835-dma: Fix dreq not set for slave transfers +Subject: [PATCH 023/114] bcm2835-dma: Fix dreq not set for slave transfers Set dreq to slave_id if it is not set like in bcm2708-dmaengine. --- @@ -1625,10 +1527,10 @@ index 5db0a95..fe1fd60 100644 return 0; } -From 22399cbc5ece0905650012b73e51a366d1c754e6 Mon Sep 17 00:00:00 2001 +From 994a4cb73ee2a4f781959989cfeb9e90fddc508a Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 11 Oct 2015 12:28:30 +0200 -Subject: [PATCH 024/251] bcm2835-dma: Limit cyclic transfers on lite channels +Subject: [PATCH 024/114] bcm2835-dma: Limit cyclic transfers on lite channels to 32k Transfers larger than 32k cause repeated clicking with I2S soundcards. @@ -1665,10 +1567,98 @@ index fe1fd60..0adc347 100644 max_size = MAX_NORMAL_TRANSFER; period_len = min(period_len, max_size); -From 1e8033be36dd0c3b000c014245cc45f94118faa0 Mon Sep 17 00:00:00 2001 +From ea1c91a95f363d023dc256319c80a7e75e94ef74 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 16 Nov 2015 14:05:35 +0000 +Subject: [PATCH 025/114] bcm2835-dma: Fix up convert to DMA pool + +--- + drivers/dma/bcm2835-dma.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c +index 0adc347..985019b 100644 +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -488,6 +488,17 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( + c->cyclic = true; + + return vchan_tx_prep(&c->vc, &d->vd, flags); ++error_cb: ++ i--; ++ for (; i >= 0; i--) { ++ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; ++ ++ dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr); ++ } ++ ++ kfree(d->cb_list); ++ kfree(d); ++ return NULL; + } + + static struct dma_async_tx_descriptor * +@@ -534,6 +545,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + if (!d) + return NULL; + ++ d->c = c; + d->dir = direction; + + if (c->ch >= 8) /* LITE channel */ +@@ -553,15 +565,21 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + d->frames += len / max_size + 1; + } + +- /* Allocate memory for control blocks */ +- d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); +- d->control_block_base = dma_zalloc_coherent(chan->device->dev, +- d->control_block_size, &d->control_block_base_phys, +- GFP_NOWAIT); +- if (!d->control_block_base) { ++ d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL); ++ if (!d->cb_list) { + kfree(d); + return NULL; + } ++ /* Allocate memory for control blocks */ ++ for (i = 0; i < d->frames; i++) { ++ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; ++ ++ cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC, ++ &cb_entry->paddr); ++ ++ if (!cb_entry->cb) ++ goto error_cb; ++ } + + /* + * Iterate over all SG entries, create a control block +@@ -578,7 +596,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + + for (j = 0; j < len; j += max_size) { + struct bcm2835_dma_cb *control_block = +- &d->control_block_base[i + split_cnt]; ++ d->cb_list[i + split_cnt].cb; + + /* Setup addresses */ + if (d->dir == DMA_DEV_TO_MEM) { +@@ -620,9 +638,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, + if (i < sg_len - 1 || len - j > max_size) { + /* Next block is the next frame. */ + control_block->next = +- d->control_block_base_phys + +- sizeof(struct bcm2835_dma_cb) * +- (i + split_cnt + 1); ++ d->cb_list[i + split_cnt + 1].paddr; + } else { + /* Next block is empty. */ + control_block->next = 0; + +From 0060f36936def46e53a173f34d0b2ab8862be1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 15 Aug 2015 20:50:02 +0200 -Subject: [PATCH 025/251] bcm2835: Add support for uart1 +Subject: [PATCH 026/114] bcm2835: Add support for uart1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1682,7 +1672,7 @@ Signed-off-by: Noralf Trønnes 1 file changed, 25 insertions(+) diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c -index 1e6f1cf..ea36eec 100644 +index 3b68a8d..e72e522 100644 --- a/arch/arm/mach-bcm/board_bcm2835.c +++ b/arch/arm/mach-bcm/board_bcm2835.c @@ -22,6 +22,29 @@ @@ -1725,21 +1715,17 @@ index 1e6f1cf..ea36eec 100644 static const char * const bcm2835_compat[] = { -From d97842cc1aac3d0ff132500fad402068743d08df Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 26 Jun 2015 14:21:20 +0200 -Subject: [PATCH 026/251] firmware: bcm2835: Add missing property tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +From 139492dfc48f7e8ff2a26902178ef76ae790c7e3 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 25 Jan 2016 17:25:12 +0000 +Subject: [PATCH 027/114] firmware: Updated mailbox header -Signed-off-by: Noralf Trønnes --- - include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++++ - 1 file changed, 8 insertions(+) + include/soc/bcm2835/raspberrypi-firmware.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index c07d74a..525816d 100644 +index 3fb3571..73e4956 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -63,6 +63,7 @@ enum rpi_firmware_property_tag { @@ -1750,28 +1736,30 @@ index c07d74a..525816d 100644 RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, -@@ -72,10 +73,12 @@ enum rpi_firmware_property_tag { +@@ -72,11 +73,13 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, + RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, + RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -@@ -89,6 +92,7 @@ enum rpi_firmware_property_tag { +@@ -91,6 +94,8 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -@@ -98,6 +102,7 @@ enum rpi_firmware_property_tag { +@@ -100,6 +105,7 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, @@ -1779,21 +1767,22 @@ index c07d74a..525816d 100644 RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, -@@ -106,6 +111,9 @@ enum rpi_firmware_property_tag { +@@ -108,6 +114,10 @@ enum rpi_firmware_property_tag { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, + + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, -From f01f5606b8fe5e7ea7d70f4f2e0e7435040cabaa Mon Sep 17 00:00:00 2001 +From 43e70c9b87a98c3a6c2f6ca82e1b1ea4eeffca78 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 027/251] Main bcm2708/bcm2709 linux port +Subject: [PATCH 028/114] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1831,14 +1820,13 @@ Signed-off-by: Noralf Trønnes arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 ++ arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 ++ arch/arm/mach-bcm2709/vc_mem.c | 431 +++++++++++++++++++++++ - arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-v6.S | 15 +- - arch/arm/mm/proc-v7.S | 1 + arch/arm/tools/mach-types | 2 + drivers/clocksource/Makefile | 2 +- drivers/irqchip/Makefile | 3 + + drivers/irqchip/irq-bcm2835.c | 3 +- include/linux/mmc/host.h | 1 + - 37 files changed, 2147 insertions(+), 5 deletions(-) + 36 files changed, 2147 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -1866,11 +1854,11 @@ Signed-off-by: Noralf Trønnes create mode 100644 arch/arm/mach-bcm2709/vc_mem.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 34e1569..8f06ea8 100644 +index cdfa6c2..aad7157 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -317,6 +317,52 @@ choice - default ARCH_VERSATILE if !MMU +@@ -322,6 +322,52 @@ choice + default ARM_SINGLE_ARMV7M if !MMU default ARCH_MULTIPLATFORM if MMU +config ARCH_BCM2708 @@ -1922,7 +1910,7 @@ index 34e1569..8f06ea8 100644 config ARCH_MULTIPLATFORM bool "Allow multiple platforms to be selected" depends on MMU -@@ -808,6 +854,9 @@ config ARCH_VIRT +@@ -721,6 +767,9 @@ config ARCH_VIRT # Kconfigs may be included either alphabetically (according to the # plat- suffix) or along side the corresponding mach-* source. # @@ -1933,10 +1921,10 @@ index 34e1569..8f06ea8 100644 source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index ddbb361..340b759 100644 +index 1098e91..e119675 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1240,6 +1240,14 @@ choice +@@ -1302,6 +1302,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -1952,18 +1940,18 @@ index ddbb361..340b759 100644 config DEBUG_EXYNOS_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 2c2b28e..a2e7cf7 100644 +index 8c3ce2a..c4d7d10 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -154,6 +154,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -153,6 +153,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_BCM2708) += bcm2708 +machine-$(CONFIG_ARCH_BCM2709) += bcm2709 machine-$(CONFIG_ARCH_ALPINE) += alpine + machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 - machine-$(CONFIG_ARCH_AXXIA) += axxia diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04286fd..ed82628 100644 --- a/arch/arm/kernel/head.S @@ -4203,19 +4191,6 @@ index 0000000..d2adfd1 +module_param(phys_addr, uint, 0644); +module_param(mem_size, uint, 0644); +module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 4121886..253bed8 100644 ---- a/arch/arm/mm/Kconfig -+++ b/arch/arm/mm/Kconfig -@@ -358,7 +358,7 @@ config CPU_PJ4B - - # ARMv6 - config CPU_V6 -- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) -+ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) - select CPU_32v6 - select CPU_ABRT_EV6 - select CPU_CACHE_V6 diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 06d890a..30d96e8 100644 --- a/arch/arm/mm/proc-v6.S @@ -4243,18 +4218,6 @@ index 06d890a..30d96e8 100644 ret lr ENTRY(cpu_v6_dcache_clean_area) -diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 8e1ea43..be40ccb 100644 ---- a/arch/arm/mm/proc-v7.S -+++ b/arch/arm/mm/proc-v7.S -@@ -480,6 +480,7 @@ __errata_finish: - orr r0, r0, r6 @ set them - THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions - ret lr @ return to head.S:__ret -+ .space 256 - ENDPROC(__v7_setup) - - .align 2 diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 2ed1b8a..b52d949 100644 --- a/arch/arm/tools/mach-types @@ -4269,7 +4232,7 @@ index 2ed1b8a..b52d949 100644 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile -index 56bd16e..c2ac46d 100644 +index dc2b899..c38fb1a 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -19,7 +19,7 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o @@ -4282,11 +4245,11 @@ index 56bd16e..c2ac46d 100644 obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile -index 177f78f..6a9e2d0 100644 +index b03cfcb..70cad6b 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile -@@ -2,6 +2,9 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o - +@@ -5,6 +5,9 @@ obj-$(CONFIG_ATH79) += irq-ath79-cpu.o + obj-$(CONFIG_ATH79) += irq-ath79-misc.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o +obj-$(CONFIG_ARCH_BCM2708) += irq-bcm2835.o @@ -4295,37 +4258,59 @@ index 177f78f..6a9e2d0 100644 obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o +diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c +index 20deb28..c02bf8a 100644 +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -82,6 +82,7 @@ + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 + #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) ++#undef FIQ_START + #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) + + static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; +@@ -256,7 +257,7 @@ static int __init armctrl_of_init(struct device_node *node, + MAKE_HWIRQ(b, i) + NUMBER_IRQS); + BUG_ON(irq <= 0); + irq_set_chip(irq, &armctrl_chip); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ irq_set_probe(irq); + } + } + init_FIQ(FIQ_START); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index 8673ffe..ad22ebb 100644 +index 8dd4d29..f7fe8bd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -289,6 +289,7 @@ struct mmc_host { - #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) +@@ -291,6 +291,7 @@ struct mmc_host { #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ + #define MMC_CAP2_NO_SDIO (1 << 19) /* Do not send SDIO commands during initialization */ +#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ mmc_pm_flag_t pm_caps; /* supported pm features */ -From cc5bcfaa350113324f7433660c9a3dfc0229bcdd Mon Sep 17 00:00:00 2001 +From 49892df19a70edbe8a089d8c7048c9234f30d9d3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 11 Nov 2015 21:01:15 +0000 -Subject: [PATCH 028/251] squash: include ARCH_BCM2708 / ARCH_BCM2709 +Subject: [PATCH 029/114] squash: include ARCH_BCM2708 / ARCH_BCM2709 --- drivers/char/hw_random/Kconfig | 2 +- + drivers/clk/bcm/Makefile | 4 ++-- drivers/mailbox/Kconfig | 2 +- drivers/mailbox/bcm2835-mailbox.c | 18 ++++++++++++++++-- drivers/pinctrl/Makefile | 1 + drivers/pwm/Kconfig | 2 +- - drivers/spi/Kconfig | 2 +- + drivers/spi/Kconfig | 4 ++-- drivers/watchdog/Kconfig | 2 +- sound/soc/bcm/Kconfig | 2 +- - 8 files changed, 23 insertions(+), 8 deletions(-) + 9 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index dbf2271..e11e3f2 100644 +index 67ee8b0..b3ca2ee 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX @@ -4337,11 +4322,26 @@ index dbf2271..e11e3f2 100644 default HW_RANDOM ---help--- This driver provides kernel-side support for the Random Number +diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile +index 1d79bd2..fcf1bb5 100644 +--- a/drivers/clk/bcm/Makefile ++++ b/drivers/clk/bcm/Makefile +@@ -4,8 +4,8 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o + obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o + obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o +-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o +-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o ++obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835-aux.o + obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o + obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o + obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 546d05f..5a045c9 100644 +index 5305923..3de0dcb 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig -@@ -65,7 +65,7 @@ config ALTERA_MBOX +@@ -74,7 +74,7 @@ config ALTERA_MBOX config BCM2835_MBOX tristate "BCM2835 Mailbox" @@ -4400,19 +4400,19 @@ index cfb4b44..d9c6c21 100644 MODULE_AUTHOR("Lubomir Rintel "); MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 738cb49..4fd086f 100644 +index e4bc115..d996fe7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o +@@ -35,6 +35,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o +obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += bcm/ obj-$(CONFIG_ARCH_BCM) += bcm/ - obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ obj-y += freescale/ diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig -index 2f4641a..d5c1a5d 100644 +index c182efc..fe0f845 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -85,7 +85,7 @@ config PWM_BCM_KONA @@ -4425,23 +4425,32 @@ index 2f4641a..d5c1a5d 100644 PWM framework driver for BCM2835 controller (Raspberry Pi) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 8b9c2a3..e842e86 100644 +index 9d8c84b..2a27a37 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -78,7 +78,7 @@ config SPI_ATMEL +@@ -94,7 +94,7 @@ config SPI_AXI_SPI_ENGINE config SPI_BCM2835 tristate "BCM2835 SPI controller" depends on GPIOLIB - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on GPIOLIB help This selects a driver for the Broadcom BCM2835 SPI master. + +@@ -105,7 +105,7 @@ config SPI_BCM2835 + + config SPI_BCM2835AUX + tristate "BCM2835 SPI auxiliary controller" +- depends on (ARCH_BCM2835 && GPIOLIB) || COMPILE_TEST ++ depends on ((ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709) && GPIOLIB) || COMPILE_TEST + help + This selects a driver for the Broadcom BCM2835 SPI aux master. + diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 1c427be..3c03d17 100644 +index fb94765..8b2de7f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -1282,7 +1282,7 @@ config BCM63XX_WDT +@@ -1401,7 +1401,7 @@ config BCM63XX_WDT config BCM2835_WDT tristate "Broadcom BCM2835 hardware watchdog" @@ -4463,10 +4472,10 @@ index 6a834e1..c5070ae 100644 select REGMAP_MMIO help -From d23b18d79e915fa0a5820230ee7a35d682e7af42 Mon Sep 17 00:00:00 2001 +From e169f708f57c5898a4d4303dd6530b3af53b5866 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 029/251] Add dwc_otg driver +Subject: [PATCH 030/114] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -4929,6 +4938,35 @@ Also add error checking on the returned irq number. Signed-off-by: Noralf Trønnes dwc_otg: Remove duplicate gadget probe/unregister function + +dwc_otg: Properly set the HFIR + +Douglas Anderson reported: + +According to the most up to date version of the dwc2 databook, the FRINT +field of the HFIR register should be programmed to: +* 125 us * (PHY clock freq for HS) - 1 +* 1000 us * (PHY clock freq for FS/LS) - 1 + +This is opposed to older versions of the doc that claimed it should be: +* 125 us * (PHY clock freq for HS) +* 1000 us * (PHY clock freq for FS/LS) + +and reported lower timing jitter on a USB analyser + +dcw_otg: trim xfer length when buffer larger than allocated size is received + +dwc_otg: Don't free qh align buffers in atomic context + +dwc_otg: Enable the hack for Split Interrupt transactions by default + +dwc_otg.fiq_fsm_mask=0xF has long been a suggestion for users with audio stutters or other USB bandwidth issues. +So far we are aware of many success stories but no failure caused by this setting. +Make it a default to learn more. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=70437 + +Signed-off-by: popcornmix --- arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + @@ -4986,9 +5024,9 @@ dwc_otg: Remove duplicate gadget probe/unregister function drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 862 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2714 ++++++++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2727 ++++++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 1005 +++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 962 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 266 + @@ -5000,7 +5038,7 @@ dwc_otg: Remove duplicate gadget probe/unregister function drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 70 files changed, 59867 insertions(+), 16 deletions(-) + 70 files changed, 59885 insertions(+), 16 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -5107,7 +5145,7 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile -index d5c57f1..0e15a22 100644 +index dca7856..5c467de 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -7,6 +7,7 @@ @@ -5131,10 +5169,10 @@ index 358ca8d..abaac7c 100644 return i; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 2a27488..ae4dca1 100644 +index 38cc4ba..61b8bb5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4973,7 +4973,7 @@ static void port_event(struct usb_hub *hub, int port1) +@@ -5044,7 +5044,7 @@ static void port_event(struct usb_hub *hub, int port1) if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; @@ -9073,10 +9111,10 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 3bb0887..0905a86 100644 +index 3050b18..bbb5f3e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig -@@ -735,6 +735,19 @@ config USB_HWA_HCD +@@ -752,6 +752,19 @@ config USB_HWA_HCD To compile this driver a module, choose M here: the module will be called "hwa-hc". @@ -9097,18 +9135,18 @@ index 3bb0887..0905a86 100644 tristate "i.MX21 HCD support" depends on ARM && ARCH_MXC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index e7558ab..0bb50e6 100644 +index a9ddd3c..11d7761 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile -@@ -69,6 +69,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o +@@ -73,6 +73,8 @@ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o + +obj-$(CONFIG_USB_DWCOTG) += dwc_otg/ dwc_common_port/ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o - obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o - obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o + obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o + obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile new file mode 100644 index 0000000..f10d466 @@ -26083,7 +26121,7 @@ index 0000000..55fd337 +#endif /* (__DWC_OTG_CFI_H__) */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c new file mode 100644 -index 0000000..beaa8b3 +index 0000000..38abd0b --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c @@ -0,0 +1,7141 @@ @@ -29247,10 +29285,10 @@ index 0000000..beaa8b3 + clock = 48; + if (hprt0.b.prtspd == 0) + /* High speed case */ -+ return 125 * clock; ++ return 125 * clock - 1; + else + /* FS/LS case */ -+ return 1000 * clock; ++ return 1000 * clock - 1; +} + +/** @@ -37134,7 +37172,7 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..95edadf +index 0000000..cb060a7 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c @@ -0,0 +1,1757 @@ @@ -37387,7 +37425,7 @@ index 0000000..95edadf +//Bulk split-transaction NAK holdoff in microframes +uint16_t nak_holdoff = 8; + -+unsigned short fiq_fsm_mask = 0x07; ++unsigned short fiq_fsm_mask = 0x0F; + +/** + * This function shows the Driver Version. @@ -47504,10 +47542,10 @@ index 0000000..fb57db0 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c new file mode 100644 -index 0000000..8db3dfc +index 0000000..e6b38ac --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -0,0 +1,2714 @@ +@@ -0,0 +1,2727 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_intr.c $ + * $Revision: #89 $ @@ -48247,6 +48285,12 @@ index 0000000..8db3dfc + DWC_OTG_HC_XFER_COMPLETE, + &short_read); + ++ if (urb->actual_length + xfer_length > urb->length) { ++ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", ++ hc->dev_addr, __func__, __LINE__); ++ xfer_length = urb->length - urb->actual_length; ++ } ++ + /* non DWORD-aligned buffer case handling. */ + if (hc->align_buff && xfer_length && hc->ep_is_in) { + dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, @@ -48933,6 +48977,13 @@ index 0000000..8db3dfc +{ + uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, + halt_status, NULL); ++ ++ if (urb->actual_length + bytes_transferred > urb->length) { ++ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", ++ hc->dev_addr, __func__, __LINE__); ++ bytes_transferred = urb->length - urb->actual_length; ++ } ++ + /* non DWORD-aligned buffer case handling. */ + if (hc->align_buff && bytes_transferred && hc->ep_is_in) { + dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, @@ -51235,10 +51286,10 @@ index 0000000..2ceed42 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c new file mode 100644 -index 0000000..acd0dd7 +index 0000000..3b2a607 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -0,0 +1,957 @@ +@@ -0,0 +1,962 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_queue.c $ + * $Revision: #44 $ @@ -51297,6 +51348,9 @@ index 0000000..acd0dd7 +{ + dwc_otg_qtd_t *qtd, *qtd_tmp; + dwc_irqflags_t flags; ++ uint32_t buf_size = 0; ++ uint8_t *align_buf_virt = NULL; ++ dwc_dma_t align_buf_dma; + + /* Free each QTD in the QTD list */ + DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); @@ -51308,17 +51362,19 @@ index 0000000..acd0dd7 + if (hcd->core_if->dma_desc_enable) { + dwc_otg_hcd_qh_free_ddma(hcd, qh); + } else if (qh->dw_align_buf) { -+ uint32_t buf_size; + if (qh->ep_type == UE_ISOCHRONOUS) { + buf_size = 4096; + } else { + buf_size = hcd->core_if->core_params->max_transfer_size; + } -+ DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma); ++ align_buf_virt = qh->dw_align_buf; ++ align_buf_dma = qh->dw_align_buf_dma; + } + + DWC_FREE(qh); + DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); ++ if (align_buf_virt) ++ DWC_DMA_FREE(buf_size, align_buf_virt, align_buf_dma); + return; +} + @@ -65445,10 +65501,10 @@ index 0000000..cdc9963 +test_main(); +0; -From 09d89e5bb8c9adc39556accbf5bb118e1609fb80 Mon Sep 17 00:00:00 2001 +From ab5ddf2c310bafc8375a88ba494d5eba214abd7e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 030/251] bcm2708 framebuffer driver +Subject: [PATCH 031/114] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -65530,10 +65586,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 drivers/video/fbdev/bcm2708_fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index e6d16d6..0f33a78 100644 +index 983280e..ee72c3a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -224,6 +224,20 @@ config FB_TILEBLITTING +@@ -228,6 +228,20 @@ config FB_TILEBLITTING comment "Frame buffer hardware drivers" depends on FB @@ -65555,7 +65611,7 @@ index e6d16d6..0f33a78 100644 tristate "Aeroflex Gaisler framebuffer support" depends on FB && SPARC diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 50ed1b4..9b086ac 100644 +index 65fb150..df473d8 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o @@ -68910,10 +68966,10 @@ index 3c14e43..7626beb 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 185a83f51686987a770243702f0c54304c60cca2 Mon Sep 17 00:00:00 2001 +From b6332fb3df52fe7808c7de394a428252fc9749b4 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 031/251] dmaengine: Add support for BCM2708 +Subject: [PATCH 032/114] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -69070,10 +69126,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index 060306e..33e36b9 100644 +index 4d0425c..b7863f0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig -@@ -470,6 +470,10 @@ config TIMB_DMA +@@ -474,6 +474,10 @@ config TIMB_DMA help Enable support for the Timberdale FPGA DMA engine. @@ -69085,7 +69141,7 @@ index 060306e..33e36b9 100644 tristate "AM33xx CPPI41 DMA support" depends on ARCH_OMAP diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile -index ef9c099..e0cf5e6 100644 +index 6084127..8188c36 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o @@ -69533,10 +69589,10 @@ index 0000000..99cc7fd + +#endif /* _PLAT_BCM2708_DMA_H */ -From dd0f809dccd2522c01727b2822f484ce8e9ce23a Mon Sep 17 00:00:00 2001 +From eaa0834b46389ca5b48a699ca1fe40e164c0400b Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 032/251] MMC: added alternative MMC driver +Subject: [PATCH 033/114] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -69602,39 +69658,59 @@ In non-DT mode, don't add the device in the board file. Signed-off-by: Noralf Trønnes bcm2835-mmc: Don't overwrite MMC capabilities from DT + +bcm2835-mmc: Don't override bus width capabilities from devicetree + +Take out the force setting of the MMC_CAP_4_BIT_DATA host capability +so that the result read from devicetree via mmc_of_parse() is +preserved. + +bcm2835-mmc: Only claim one DMA channel + +With both MMC controllers enabled there are few DMA channels left. The +bcm2835-mmc driver only uses DMA in one direction at a time, so it +doesn't need to claim two channels. + +See: https://github.com/raspberrypi/linux/issues/1327 + +Signed-off-by: Phil Elwell --- - drivers/mmc/core/quirks.c | 6 + + drivers/mmc/core/quirks.c | 10 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1542 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 1578 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 1571 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 1611 insertions(+) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index fad660b..87ae2e9 100644 +index fad660b..b79fe14 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c -@@ -53,6 +53,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { +@@ -53,6 +53,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) { ++#ifdef CONFIG_MMC_BCM2835 + extern unsigned mmc_debug; ++#endif const struct mmc_fixup *f; u64 rev = cid_rev_card(card); -@@ -77,5 +78,10 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) +@@ -77,5 +80,12 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) f->vendor_fixup(card, f->data); } } + /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. + * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). + */ ++#ifdef CONFIG_MMC_BCM2835 + if (mmc_debug & (1<<13)) + card->quirks |= MMC_QUIRK_BLK_NO_CMD23; ++#endif } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 1dee533..9b72d2c 100644 +index 04feea8..e258577 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -69674,7 +69750,7 @@ index 1dee533..9b72d2c 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 3595f83..6cf6457 100644 +index af918d2..3ba94f0 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -69687,10 +69763,10 @@ index 3595f83..6cf6457 100644 obj-$(CONFIG_MMC_MTK) += mtk-sd.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..43aed6e +index 0000000..ceb3793 --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1542 @@ +@@ -0,0 +1,1571 @@ +/* + * BCM2835 MMC host driver. + * @@ -69801,8 +69877,9 @@ index 0000000..43aed6e + u32 shadow; + + /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ ++ struct dma_slave_config dma_cfg_rx; ++ struct dma_slave_config dma_cfg_tx; + struct dma_async_tx_descriptor *tx_desc; /* descriptor */ + + bool have_dma; @@ -70035,7 +70112,7 @@ index 0000000..43aed6e + + if (host->data && !(host->data->flags & MMC_DATA_WRITE)) { + /* otherwise handled in SDHCI IRQ */ -+ dma_chan = host->dma_chan_rx; ++ dma_chan = host->dma_chan_rxtx; + dir_data = DMA_FROM_DEVICE; + + dma_unmap_sg(dma_chan->device->dev, @@ -70186,16 +70263,21 @@ index 0000000..43aed6e + if (host->blocks == 0) + return; + ++ dma_chan = host->dma_chan_rxtx; + if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { -+ dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } + ++ /* The parameters have already been validated, so this will not fail */ ++ (void)dmaengine_slave_config(dma_chan, ++ (dir_data == DMA_FROM_DEVICE) ? ++ &host->dma_cfg_rx : ++ &host->dma_cfg_tx); ++ + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); + BUG_ON(!host->data->sg); @@ -70629,7 +70711,7 @@ index 0000000..43aed6e + if (host->data->flags & MMC_DATA_WRITE) { + /* IRQ handled here */ + -+ dma_chan = host->dma_chan_tx; ++ dma_chan = host->dma_chan_rxtx; + dir_data = DMA_TO_DEVICE; + dma_unmap_sg(dma_chan->device->dev, + host->data->sg, host->data->sg_len, @@ -70998,7 +71080,7 @@ index 0000000..43aed6e + /* host controller capabilities */ + mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | + MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; ++ MMC_CAP_MMC_HIGHSPEED; + + mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; + @@ -71009,28 +71091,47 @@ index 0000000..43aed6e + dev_info(dev, "Forcing PIO mode\n"); + host->have_dma = false; +#else -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n", ++ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { ++ dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n", + DRIVER_NAME); + host->have_dma = false; + } else { -+ dev_info(dev, "DMA channels allocated"); -+ host->have_dma = true; ++ dev_info(dev, "DMA channel allocated"); + + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.slave_id = 11; /* DREQ channel */ + ++ /* Validate the slave configurations */ ++ + cfg.direction = DMA_MEM_TO_DEV; + cfg.src_addr = 0; + cfg.dst_addr = host->bus_addr + SDHCI_BUFFER; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); + -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ ++ if (ret == 0) { ++ host->dma_cfg_tx = cfg; ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; ++ cfg.dst_addr = 0; ++ ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ } ++ ++ if (ret == 0) { ++ host->dma_cfg_rx = cfg; ++ ++ host->use_dma = true; ++ } else { ++ pr_err("%s: unable to configure DMA channel. " ++ "Faling back to PIO\n", ++ mmc_hostname(mmc)); ++ dma_release_channel(host->dma_chan_rxtx); ++ host->dma_chan_rxtx = NULL; ++ host->use_dma = false; ++ } + } +#endif + mmc->max_segs = 128; @@ -71109,16 +71210,20 @@ index 0000000..43aed6e + +#ifndef FORCE_PIO + if (node) { -+ host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); ++ host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx"); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ + dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = dma_request_channel(mask, NULL, NULL); ++ host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL); + } +#endif + clk = devm_clk_get(dev, NULL); @@ -71234,10 +71339,10 @@ index 0000000..43aed6e +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From e15ccca87e0a679797cbcaf24bbf2304b1e8eba3 Mon Sep 17 00:00:00 2001 +From 4674c122d3fa842a1065f255b3e50f61683692a0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 033/251] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 034/114] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -71310,15 +71415,64 @@ The MMC card-discovery process generates timeouts. This is expected behaviour, so reporting it to the user serves no purpose. Suppress the reporting of timeout errors unless the debug flag is on. + +bcm2835-sdhost: Add workaround for odd behaviour on some cards + +For reasons not understood, the sdhost driver fails when reading +sectors very near the end of some SD cards. The problem could +be related to the similar issue that reading the final sector +of any card as part of a multiple read never completes, and the +workaround is an extension of the mechanism introduced to solve +that problem which ensures those sectors are always read singly. + +bcm2835-sdhost: Major revision + +This is a significant revision of the bcm2835-sdhost driver. It +improves on the original in a number of ways: + +1) Through the use of CMD23 for reads it appears to avoid problems + reading some sectors on certain high speed cards. +2) Better atomicity to prevent crashes. +3) Higher performance. +4) Activity logging included, for easier diagnosis in the event + of a problem. + +Signed-off-by: Phil Elwell + +bcm2835-sdhost: Restore ATOMIC flag to PIO sg mapping + +Allocation problems have been seen in a wireless driver, and +this is the only change which might have been responsible. + +SQUASH: bcm2835-sdhost: Only claim one DMA channel + +With both MMC controllers enabled there are few DMA channels left. The +bcm2835-sdhost driver only uses DMA in one direction at a time, so it +doesn't need to claim two channels. + +See: https://github.com/raspberrypi/linux/issues/1327 + +Signed-off-by: Phil Elwell + +bcm2835-sdhost: Workaround for "slow" sectors + +Some cards have been seen to cause timeouts after certain sectors are +read. This workaround enforces a minimum delay between the stop after +reading one of those sectors and a subsequent data command. + +Using CMD23 (SET_BLOCK_COUNT) avoids this problem, so good cards will +not be penalised by this workaround. + +Signed-off-by: Phil Elwell --- drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1907 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1918 insertions(+) + drivers/mmc/host/bcm2835-sdhost.c | 2121 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 2132 insertions(+) create mode 100644 drivers/mmc/host/bcm2835-sdhost.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 9b72d2c..d509d10 100644 +index e258577..4cdd8cd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER @@ -71339,7 +71493,7 @@ index 9b72d2c..d509d10 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 6cf6457..df27ae9 100644 +index 3ba94f0..8daaa94 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -71352,15 +71506,15 @@ index 6cf6457..df27ae9 100644 obj-$(CONFIG_MMC_AU1X) += au1xmmc.o diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c new file mode 100644 -index 0000000..da08998 +index 0000000..f43aae0 --- /dev/null +++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1907 @@ +@@ -0,0 +1,2121 @@ +/* + * BCM2835 SD host driver. + * + * Author: Phil Elwell -+ * Copyright 2015 ++ * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd. + * + * Based on + * mmc-bcm2835.c by Gellert Weisz @@ -71382,12 +71536,13 @@ index 0000000..da08998 + * along with this program. If not, see . + */ + -+#define SAFE_READ_THRESHOLD 4 -+#define SAFE_WRITE_THRESHOLD 4 -+#define ALLOW_DMA 1 -+#define ALLOW_CMD23 0 -+#define ALLOW_FAST 1 -+#define USE_BLOCK_IRQ 1 ++#define FIFO_READ_THRESHOLD 4 ++#define FIFO_WRITE_THRESHOLD 4 ++#define ALLOW_CMD23_READ 1 ++#define ALLOW_CMD23_WRITE 0 ++#define ENABLE_LOG 1 ++#define SDDATA_FIFO_PIO_BURST 8 ++#define CMD_DALLY_US 1 + +#include +#include @@ -71406,6 +71561,7 @@ index 0000000..da08998 +#include +#include +#include ++#include + +#define DRIVER_NAME "sdhost-bcm2835" + @@ -71468,6 +71624,28 @@ index 0000000..da08998 +#define SDEDM_READ_THRESHOLD_SHIFT 14 +#define SDEDM_THRESHOLD_MASK 0x1f + ++#define SDEDM_FSM_MASK 0xf ++#define SDEDM_FSM_IDENTMODE 0x0 ++#define SDEDM_FSM_DATAMODE 0x1 ++#define SDEDM_FSM_READDATA 0x2 ++#define SDEDM_FSM_WRITEDATA 0x3 ++#define SDEDM_FSM_READWAIT 0x4 ++#define SDEDM_FSM_READCRC 0x5 ++#define SDEDM_FSM_WRITECRC 0x6 ++#define SDEDM_FSM_WRITEWAIT1 0x7 ++#define SDEDM_FSM_POWERDOWN 0x8 ++#define SDEDM_FSM_POWERUP 0x9 ++#define SDEDM_FSM_WRITESTART1 0xa ++#define SDEDM_FSM_WRITESTART2 0xb ++#define SDEDM_FSM_GENPULSES 0xc ++#define SDEDM_FSM_WRITEWAIT2 0xd ++#define SDEDM_FSM_STARTPOWDOWN 0xf ++ ++#define SDDATA_FIFO_WORDS 16 ++ ++#define USE_CMD23_FLAGS ((ALLOW_CMD23_READ * MMC_DATA_READ) | \ ++ (ALLOW_CMD23_WRITE * MMC_DATA_WRITE)) ++ +#define MHZ 1000000 + + @@ -71489,15 +71667,17 @@ index 0000000..da08998 + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + -+ struct timer_list timer; /* Timer for timeouts */ ++ struct work_struct cmd_wait_wq; /* Workqueue function */ + -+ struct timer_list pio_timer; /* PIO error detection timer */ ++ struct timer_list timer; /* Timer for timeouts */ + + struct sg_mapping_iter sg_miter; /* SG state for PIO */ + unsigned int blocks; /* remaining PIO blocks */ + + int irq; /* Device IRQ */ + ++ u32 cmd_quick_poll_retries; ++ u32 ns_per_fifo_word; + + /* cached registers */ + u32 hcfg; @@ -71512,27 +71692,126 @@ index 0000000..da08998 + + unsigned int use_busy:1; /* Wait for busy interrupt */ + ++ unsigned int use_sbc:1; /* Send CMD23 */ ++ + unsigned int debug:1; /* Enable debug output */ + -+ u32 thread_isr; -+ + /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ ++ struct dma_chan *dma_chan; /* Channel in use */ ++ struct dma_slave_config dma_cfg_rx; ++ struct dma_slave_config dma_cfg_tx; ++ struct dma_async_tx_descriptor *dma_desc; ++ u32 dma_dir; ++ u32 drain_words; ++ struct page *drain_page; ++ u32 drain_offset; + + bool allow_dma; -+ bool have_dma; + bool use_dma; + /*end of DMA part*/ + + int max_delay; /* maximum length of time spent waiting */ + struct timeval stop_time; /* when the last stop was issued */ + u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ ++ u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ + u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ + u32 overclock; /* Current frequency if overclocked, else zero */ + u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ ++ ++ u32 sectors; /* Cached card size in sectors */ +}; + ++#if ENABLE_LOG ++ ++struct log_entry_struct { ++ char event[4]; ++ u32 timestamp; ++ u32 param1; ++ u32 param2; ++}; ++ ++typedef struct log_entry_struct LOG_ENTRY_T; ++ ++LOG_ENTRY_T *sdhost_log_buf; ++dma_addr_t sdhost_log_addr; ++static u32 sdhost_log_idx; ++static spinlock_t log_lock; ++static void __iomem *timer_base; ++ ++#define LOG_ENTRIES (256*1) ++#define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) ++ ++static void log_init(u32 bus_to_phys) ++{ ++ spin_lock_init(&log_lock); ++ sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, ++ GFP_KERNEL); ++ if (sdhost_log_buf) { ++ pr_info("sdhost: log_buf @ %p (%x)\n", ++ sdhost_log_buf, sdhost_log_addr); ++ timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); ++ if (!timer_base) ++ pr_err("sdhost: failed to remap timer\n"); ++ } ++ else ++ pr_err("sdhost: failed to allocate log buf\n"); ++} ++ ++static void log_event_impl(const char *event, u32 param1, u32 param2) ++{ ++ if (sdhost_log_buf) { ++ LOG_ENTRY_T *entry; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&log_lock, flags); ++ ++ entry = sdhost_log_buf + sdhost_log_idx; ++ memcpy(entry->event, event, 4); ++ entry->timestamp = (readl(timer_base + 4) & 0x3fffffff) + ++ (smp_processor_id()<<30); ++ entry->param1 = param1; ++ entry->param2 = param2; ++ sdhost_log_idx = (sdhost_log_idx + 1) % LOG_ENTRIES; ++ ++ spin_unlock_irqrestore(&log_lock, flags); ++ } ++} ++ ++static void log_dump(void) ++{ ++ if (sdhost_log_buf) { ++ LOG_ENTRY_T *entry; ++ unsigned long flags; ++ int idx; ++ ++ spin_lock_irqsave(&log_lock, flags); ++ ++ idx = sdhost_log_idx; ++ do { ++ entry = sdhost_log_buf + idx; ++ if (entry->event[0] != '\0') ++ pr_err("[%08x] %.4s %x %x\n", ++ entry->timestamp, ++ entry->event, ++ entry->param1, ++ entry->param2); ++ idx = (idx + 1) % LOG_ENTRIES; ++ } while (idx != sdhost_log_idx); ++ ++ spin_unlock_irqrestore(&log_lock, flags); ++ } ++} ++ ++#define log_event(event, param1, param2) log_event_impl(event, param1, param2) ++ ++#else ++ ++#define log_init(x) (void)0 ++#define log_event(event, param1, param2) (void)0 ++#define log_dump() (void)0 ++ ++#endif + +static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) +{ @@ -71554,7 +71833,7 @@ index 0000000..da08998 + const char *label) +{ + if (cmd) -+ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", ++ pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", + mmc_hostname(host->mmc), + (cmd == host->cmd) ? '>' : ' ', + label, cmd->opcode, cmd->arg, cmd->flags, @@ -71564,77 +71843,81 @@ index 0000000..da08998 + +static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) +{ -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ if (host->mrq) ++ { ++ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); ++ if (host->mrq->data) ++ pr_err("%s: data blocks %x blksz %x - err %d\n", ++ mmc_hostname(host->mmc), ++ host->mrq->data->blocks, ++ host->mrq->data->blksz, ++ host->mrq->data->error); ++ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); ++ } + -+ pr_info("%s: =========== REGISTER DUMP ===========\n", ++ pr_err("%s: =========== REGISTER DUMP ===========\n", + mmc_hostname(host->mmc)); + -+ pr_info("%s: SDCMD 0x%08x\n", ++ pr_err("%s: SDCMD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCMD)); -+ pr_info("%s: SDARG 0x%08x\n", ++ pr_err("%s: SDARG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDARG)); -+ pr_info("%s: SDTOUT 0x%08x\n", ++ pr_err("%s: SDTOUT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info("%s: SDCDIV 0x%08x\n", ++ pr_err("%s: SDCDIV 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info("%s: SDRSP0 0x%08x\n", ++ pr_err("%s: SDRSP0 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info("%s: SDRSP1 0x%08x\n", ++ pr_err("%s: SDRSP1 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info("%s: SDRSP2 0x%08x\n", ++ pr_err("%s: SDRSP2 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info("%s: SDRSP3 0x%08x\n", ++ pr_err("%s: SDRSP3 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info("%s: SDHSTS 0x%08x\n", ++ pr_err("%s: SDHSTS 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info("%s: SDVDD 0x%08x\n", ++ pr_err("%s: SDVDD 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDVDD)); -+ pr_info("%s: SDEDM 0x%08x\n", ++ pr_err("%s: SDEDM 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDEDM)); -+ pr_info("%s: SDHCFG 0x%08x\n", ++ pr_err("%s: SDHCFG 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info("%s: SDHBCT 0x%08x\n", ++ pr_err("%s: SDHBCT 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info("%s: SDHBLC 0x%08x\n", ++ pr_err("%s: SDHBLC 0x%08x\n", + mmc_hostname(host->mmc), + bcm2835_sdhost_read(host, SDHBLC)); + -+ pr_info("%s: ===========================================\n", ++ pr_err("%s: ===========================================\n", + mmc_hostname(host->mmc)); +} + -+ +static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) +{ + bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); +} + -+ +static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) +{ + u32 temp; + ++ if (host->debug) ++ pr_info("%s: reset\n", mmc_hostname(host->mmc)); ++ + bcm2835_sdhost_set_power(host, false); + + bcm2835_sdhost_write(host, 0, SDCMD); @@ -71650,26 +71933,25 @@ index 0000000..da08998 + temp = bcm2835_sdhost_read(host, SDEDM); + temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; ++ host->sectors = 0; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + bcm2835_sdhost_write(host, host->cdiv, SDCDIV); + mmiowb(); +} + -+ +static void bcm2835_sdhost_reset(struct mmc_host *mmc) +{ + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(mmc)); + spin_lock_irqsave(&host->lock, flags); ++ log_event("RST<", 0, 0); + + bcm2835_sdhost_reset_internal(host); + @@ -71694,82 +71976,48 @@ index 0000000..da08998 + } +} + -+static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+{ -+ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -+ -+ if (!write_complete) { -+ /* Request an IRQ for the last block */ -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -+ /* The write has now completed. Disable the interrupt -+ and clear the status flag */ -+ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -+ write_complete = true; -+ } -+ } -+ -+ return write_complete; -+} -+ -+static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) ++static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) +{ + int timediff; -+#ifdef DEBUG -+ static struct timeval start_time; -+ static int max_stall_time = 0; -+ static int total_stall_time = 0; -+ struct timeval before, after; ++ u32 alternate_idle; ++ u32 edm; + -+ do_gettimeofday(&before); -+ if (max_stall_time == 0) -+ start_time = before; -+#endif ++ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ? ++ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; ++ ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ ++ log_event("WTC<", edm, 0); + + timediff = 0; + + while (1) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm & 0xf) == 1) ++ u32 fsm = edm & SDEDM_FSM_MASK; ++ if ((fsm == SDEDM_FSM_IDENTMODE) || ++ (fsm == SDEDM_FSM_DATAMODE)) + break; -+ timediff++; -+ if (timediff > 5000000) { -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); ++ if (fsm == alternate_idle) { ++ bcm2835_sdhost_write(host, ++ edm | SDEDM_FORCE_DATA_MODE, ++ SDEDM); ++ break; ++ } + -+ pr_err(" wait_write_complete - still waiting after %dus\n", ++ timediff++; ++ if (timediff == 100000) { ++ pr_err("%s: wait_transfer_complete - still waiting after %d retries\n", ++ mmc_hostname(host->mmc), + timediff); -+#else -+ pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff); -+#endif ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; ++ host->mrq->data->error = -ETIMEDOUT; ++ log_event("WTC!", edm, 0); + return; + } ++ cpu_relax(); ++ edm = bcm2835_sdhost_read(host, SDEDM); + } -+ -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -+ -+ total_stall_time += timediff; -+ if (timediff > max_stall_time) -+ max_stall_time = timediff; -+ -+ if ((after.tv_sec - start_time.tv_sec) > 10) { -+ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -+ max_stall_time, total_stall_time); -+ start_time = after; -+ max_stall_time = 0; -+ total_stall_time = 0; -+ } -+#endif ++ log_event("WTC>", edm, 0); +} + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); @@ -71777,98 +72025,128 @@ index 0000000..da08998 +static void bcm2835_sdhost_dma_complete(void *param) +{ + struct bcm2835_host *host = param; -+ struct dma_chan *dma_chan; ++ struct mmc_data *data = host->data; + unsigned long flags; -+ u32 dir_data; + + spin_lock_irqsave(&host->lock, flags); ++ log_event("DMA<", (u32)host->data, bcm2835_sdhost_read(host, SDHSTS)); ++ log_event("DMA ", bcm2835_sdhost_read(host, SDCMD), ++ bcm2835_sdhost_read(host, SDEDM)); + -+ if (host->data) { -+ bool write_complete; -+ if (USE_BLOCK_IRQ) -+ write_complete = bcm2835_sdhost_is_write_complete(host); -+ else { -+ bcm2835_sdhost_wait_write_complete(host); -+ write_complete = true; -+ } -+ pr_debug("dma_complete() - write_complete=%d\n", -+ write_complete); ++ if (host->dma_chan) { ++ dma_unmap_sg(host->dma_chan->device->dev, ++ data->sg, data->sg_len, ++ host->dma_dir); + -+ if (write_complete || (host->data->flags & MMC_DATA_READ)) -+ { -+ if (write_complete) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ } else { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ } -+ -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } ++ host->dma_chan = NULL; + } + ++ if (host->drain_words) { ++ void *page; ++ u32 *buf; ++ ++ page = kmap_atomic(host->drain_page); ++ buf = page + host->drain_offset; ++ ++ while (host->drain_words) { ++ u32 edm = bcm2835_sdhost_read(host, SDEDM); ++ if ((edm >> 4) & 0x1f) ++ *(buf++) = bcm2835_sdhost_read(host, ++ SDDATA); ++ host->drain_words--; ++ } ++ ++ kunmap_atomic(page); ++ } ++ ++ bcm2835_sdhost_finish_data(host); ++ ++ log_event("DMA>", (u32)host->data, 0); + spin_unlock_irqrestore(&host->lock, flags); +} + -+static bool data_transfer_wait(struct bcm2835_host *host) -+{ -+ unsigned long timeout = 1000000; -+ while (timeout) -+ { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (sdhsts & SDHSTS_DATA_FLAG) { -+ bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); -+ break; -+ } -+ timeout--; -+ } -+ if (timeout == 0) { -+ pr_err("%s: Data %s timeout\n", -+ mmc_hostname(host->mmc), -+ (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return false; -+ } -+ return true; -+} -+ +static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len; + u32 *buf; ++ unsigned long wait_max; + + blksize = host->data->blksz; + ++ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); ++ + local_irq_save(flags); + + while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); ++ int copy_words; ++ u32 hsts = 0; ++ ++ if (!sg_miter_next(&host->sg_miter)) { ++ host->data->error = -EINVAL; ++ break; ++ } + + len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); ++ if (len % 4) { ++ host->data->error = -EINVAL; ++ break; ++ } + + blksize -= len; + host->sg_miter.consumed = len; + + buf = (u32 *)host->sg_miter.addr; + -+ while (len) { -+ if (!data_transfer_wait(host)) -+ break; ++ copy_words = len/4; + -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ len -= 4; ++ while (copy_words) { ++ int burst_words, words; ++ u32 edm; ++ ++ burst_words = SDDATA_FIFO_PIO_BURST; ++ if (burst_words > copy_words) ++ burst_words = copy_words; ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ words = ((edm >> 4) & 0x1f); ++ ++ if (words < burst_words) { ++ int fsm_state = (edm & SDEDM_FSM_MASK); ++ if ((fsm_state != SDEDM_FSM_READDATA) && ++ (fsm_state != SDEDM_FSM_READWAIT) && ++ (fsm_state != SDEDM_FSM_READCRC)) { ++ hsts = bcm2835_sdhost_read(host, ++ SDHSTS); ++ pr_err("%s: fsm %x, hsts %x\n", ++ mmc_hostname(host->mmc), ++ fsm_state, hsts); ++ if (hsts & SDHSTS_ERROR_MASK) ++ break; ++ } ++ ++ if (time_after(jiffies, wait_max)) { ++ pr_err("%s: PIO read timeout - EDM %x\n", ++ mmc_hostname(host->mmc), ++ edm); ++ hsts = SDHSTS_REW_TIME_OUT; ++ break; ++ } ++ ndelay((burst_words - words) * ++ host->ns_per_fifo_word); ++ continue; ++ } else if (words > copy_words) { ++ words = copy_words; ++ } ++ ++ copy_words -= words; ++ ++ while (words) { ++ *(buf++) = bcm2835_sdhost_read(host, SDDATA); ++ words--; ++ } + } + -+ if (host->data->error) ++ if (hsts & SDHSTS_ERROR_MASK) + break; + } + @@ -71882,32 +72160,83 @@ index 0000000..da08998 + unsigned long flags; + size_t blksize, len; + u32 *buf; ++ unsigned long wait_max; + + blksize = host->data->blksz; + ++ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); ++ + local_irq_save(flags); + + while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); ++ int copy_words; ++ u32 hsts = 0; ++ ++ if (!sg_miter_next(&host->sg_miter)) { ++ host->data->error = -EINVAL; ++ break; ++ } + + len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); ++ if (len % 4) { ++ host->data->error = -EINVAL; ++ break; ++ } + + blksize -= len; + host->sg_miter.consumed = len; + -+ buf = host->sg_miter.addr; ++ buf = (u32 *)host->sg_miter.addr; + -+ while (len) { -+ if (!data_transfer_wait(host)) -+ break; ++ copy_words = len/4; + -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ len -= 4; ++ while (copy_words) { ++ int burst_words, words; ++ u32 edm; ++ ++ burst_words = SDDATA_FIFO_PIO_BURST; ++ if (burst_words > copy_words) ++ burst_words = copy_words; ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f); ++ ++ if (words < burst_words) { ++ int fsm_state = (edm & SDEDM_FSM_MASK); ++ if ((fsm_state != SDEDM_FSM_WRITEDATA) && ++ (fsm_state != SDEDM_FSM_WRITESTART1) && ++ (fsm_state != SDEDM_FSM_WRITESTART2)) { ++ hsts = bcm2835_sdhost_read(host, ++ SDHSTS); ++ pr_err("%s: fsm %x, hsts %x\n", ++ mmc_hostname(host->mmc), ++ fsm_state, hsts); ++ if (hsts & SDHSTS_ERROR_MASK) ++ break; ++ } ++ ++ if (time_after(jiffies, wait_max)) { ++ pr_err("%s: PIO write timeout - EDM %x\n", ++ mmc_hostname(host->mmc), ++ edm); ++ hsts = SDHSTS_REW_TIME_OUT; ++ break; ++ } ++ ndelay((burst_words - words) * ++ host->ns_per_fifo_word); ++ continue; ++ } else if (words > copy_words) { ++ words = copy_words; ++ } ++ ++ copy_words -= words; ++ ++ while (words) { ++ bcm2835_sdhost_write(host, *(buf++), SDDATA); ++ words--; ++ } + } + -+ if (host->data->error) ++ if (hsts & SDHSTS_ERROR_MASK) + break; + } + @@ -71916,12 +72245,12 @@ index 0000000..da08998 + local_irq_restore(flags); +} + -+ +static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) +{ + u32 sdhsts; + bool is_read; + BUG_ON(!host->data); ++ log_event("XFP<", (u32)host->data, host->blocks); + + is_read = (host->data->flags & MMC_DATA_READ) != 0; + if (is_read) @@ -71945,65 +72274,99 @@ index 0000000..da08998 + is_read ? "read" : "write", + sdhsts); + host->data->error = -ETIMEDOUT; -+ } else if (!is_read && !host->data->error) { -+ /* Start a timer in case a transfer error occurs because -+ there is no error interrupt */ -+ mod_timer(&host->pio_timer, jiffies + host->pio_timeout); + } ++ log_event("XFP>", (u32)host->data, host->blocks); +} + -+ -+static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) ++static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, ++ struct mmc_data *data) +{ -+ u32 len, dir_data, dir_slave; ++ int len, dir_data, dir_slave; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *dma_chan; + -+ pr_debug("bcm2835_sdhost_transfer_dma()\n"); ++ log_event("PRD<", (u32)data, 0); ++ pr_debug("bcm2835_sdhost_prepare_dma()\n"); + -+ WARN_ON(!host->data); -+ -+ if (!host->data) -+ return; -+ -+ if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; ++ dma_chan = host->dma_chan_rxtx; ++ if (data->flags & MMC_DATA_READ) { + dir_data = DMA_FROM_DEVICE; + dir_slave = DMA_DEV_TO_MEM; + } else { -+ dma_chan = host->dma_chan_tx; + dir_data = DMA_TO_DEVICE; + dir_slave = DMA_MEM_TO_DEV; + } ++ log_event("PRD1", (u32)dma_chan, 0); + + BUG_ON(!dma_chan->device); + BUG_ON(!dma_chan->device->dev); -+ BUG_ON(!host->data->sg); ++ BUG_ON(!data->sg); + -+ len = dma_map_sg(dma_chan->device->dev, host->data->sg, -+ host->data->sg_len, dir_data); -+ if (len > 0) { -+ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, ++ /* The block doesn't manage the FIFO DREQs properly for multi-block ++ transfers, so don't attempt to DMA the final few words. ++ Unfortunately this requires the final sg entry to be trimmed. ++ N.B. This code demands that the overspill is contained in ++ a single sg entry. ++ */ ++ ++ host->drain_words = 0; ++ if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) { ++ struct scatterlist *sg; ++ u32 len; ++ int i; ++ ++ len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4, ++ (u32)data->blocks * data->blksz); ++ ++ for_each_sg(data->sg, sg, data->sg_len, i) { ++ if (sg_is_last(sg)) { ++ BUG_ON(sg->length < len); ++ sg->length -= len; ++ host->drain_page = (struct page *)sg->page_link; ++ host->drain_offset = sg->offset + sg->length; ++ } ++ } ++ host->drain_words = len/4; ++ } ++ ++ /* The parameters have already been validated, so this will not fail */ ++ (void)dmaengine_slave_config(dma_chan, ++ (dir_data == DMA_FROM_DEVICE) ? ++ &host->dma_cfg_rx : ++ &host->dma_cfg_tx); ++ ++ len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, ++ dir_data); ++ ++ log_event("PRD2", len, 0); ++ if (len > 0) ++ desc = dmaengine_prep_slave_sg(dma_chan, data->sg, + len, dir_slave, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ } else { -+ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -+ } ++ log_event("PRD3", (u32)desc, 0); ++ + if (desc) { + desc->callback = bcm2835_sdhost_dma_complete; + desc->callback_param = host; -+ dmaengine_submit(desc); -+ dma_async_issue_pending(dma_chan); ++ host->dma_desc = desc; ++ host->dma_chan = dma_chan; ++ host->dma_dir = dir_data; + } -+ ++ log_event("PDM>", (u32)data, 0); +} + ++static void bcm2835_sdhost_start_dma(struct bcm2835_host *host) ++{ ++ log_event("SDMA", (u32)host->data, (u32)host->dma_chan); ++ dmaengine_submit(host->dma_desc); ++ dma_async_issue_pending(host->dma_chan); ++} + +static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) +{ + u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | + SDHCFG_BUSY_IRPT_EN; -+ if (host->use_dma) ++ if (host->dma_desc) + host->hcfg = (host->hcfg & ~all_irqs) | + SDHCFG_BUSY_IRPT_EN; + else @@ -72014,13 +72377,13 @@ index 0000000..da08998 + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); +} + -+ +static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) +{ + struct mmc_data *data = cmd->data; + + WARN_ON(host->data); + ++ host->data = data; + if (!data) + return; + @@ -72029,16 +72392,32 @@ index 0000000..da08998 + BUG_ON(data->blksz > host->mmc->max_blk_size); + BUG_ON(data->blocks > 65535); + -+ host->data = data; + host->data_complete = 0; + host->flush_fifo = 0; + host->data->bytes_xfered = 0; + -+ host->use_dma = host->have_dma && (data->blocks > host->pio_limit); -+ if (!host->use_dma) { -+ int flags; ++ if (!host->sectors && host->mmc->card) { ++ struct mmc_card *card = host->mmc->card; ++ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { ++ /* ++ * The EXT_CSD sector count is in number of 512 byte ++ * sectors. ++ */ ++ host->sectors = card->ext_csd.sectors; ++ } else { ++ /* ++ * The CSD capacity field is in units of read_blkbits. ++ * set_capacity takes units of 512 bytes. ++ */ ++ host->sectors = card->csd.capacity << ++ (card->csd.read_blkbits - 9); ++ } ++ } ++ ++ if (!host->dma_desc) { ++ /* Use PIO */ ++ int flags = SG_MITER_ATOMIC; + -+ flags = SG_MITER_ATOMIC; + if (data->flags & MMC_DATA_READ) + flags |= SG_MITER_TO_SG; + else @@ -72050,19 +72429,20 @@ index 0000000..da08998 + bcm2835_sdhost_set_transfer_irqs(host); + + bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); ++ bcm2835_sdhost_write(host, data->blocks, SDHBLC); + + BUG_ON(!host->data); +} + -+ -+void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) ++bool bcm2835_sdhost_send_command(struct bcm2835_host *host, ++ struct mmc_command *cmd) +{ + u32 sdcmd, sdhsts; + unsigned long timeout; + int delay; + + WARN_ON(host->cmd); ++ log_event("CMD<", cmd->opcode, cmd->arg); + + if (cmd->data) + pr_debug("%s: send_command %d 0x%x " @@ -72085,9 +72465,9 @@ index 0000000..da08998 + pr_err("%s: previous command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); -+ cmd->error = -EIO; ++ cmd->error = -EILSEQ; + tasklet_schedule(&host->finish_tasklet); -+ return; ++ return false; + } + timeout--; + udelay(10); @@ -72115,23 +72495,24 @@ index 0000000..da08998 + if (sdhsts & SDHSTS_ERROR_MASK) + bcm2835_sdhost_write(host, sdhsts, SDHSTS); + -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + pr_err("%s: unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); -+ return; ++ return false; + } + ++ bcm2835_sdhost_prepare_data(host, cmd); ++ ++ bcm2835_sdhost_write(host, cmd->arg, SDARG); ++ + sdcmd = cmd->opcode & SDCMD_CMD_MASK; + -+ if (!(cmd->flags & MMC_RSP_PRESENT)) ++ host->use_busy = 0; ++ if (!(cmd->flags & MMC_RSP_PRESENT)) { + sdcmd |= SDCMD_NO_RESPONSE; -+ else { ++ } else { + if (cmd->flags & MMC_RSP_136) + sdcmd |= SDCMD_LONG_RESPONSE; + if (cmd->flags & MMC_RSP_BUSY) { @@ -72141,7 +72522,8 @@ index 0000000..da08998 + } + + if (cmd->data) { -+ if (host->delay_after_stop) { ++ log_event("CMDD", cmd->data->blocks, cmd->data->blksz); ++ if (host->delay_after_this_stop) { + struct timeval now; + int time_since_stop; + do_gettimeofday(&now); @@ -72150,12 +72532,32 @@ index 0000000..da08998 + /* Possibly less than one second */ + time_since_stop = time_since_stop * 1000000 + + (now.tv_usec - host->stop_time.tv_usec); -+ if (time_since_stop < host->delay_after_stop) -+ udelay(host->delay_after_stop - ++ if (time_since_stop < ++ host->delay_after_this_stop) ++ udelay(host->delay_after_this_stop - + time_since_stop); + } + } + ++ host->delay_after_this_stop = host->delay_after_stop; ++ if ((cmd->data->flags & MMC_DATA_READ) && !host->use_sbc) { ++ /* See if read crosses one of the hazardous sectors */ ++ u32 first_blk, last_blk; ++ ++ /* Intentionally include the following sector because ++ without CMD23/SBC the read may run on. */ ++ first_blk = host->mrq->cmd->arg; ++ last_blk = first_blk + cmd->data->blocks; ++ ++ if (((last_blk >= (host->sectors - 64)) && ++ (first_blk <= (host->sectors - 64))) || ++ ((last_blk >= (host->sectors - 32)) && ++ (first_blk <= (host->sectors - 32)))) { ++ host->delay_after_this_stop = ++ max(250u, host->delay_after_stop); ++ } ++ } ++ + if (cmd->data->flags & MMC_DATA_WRITE) + sdcmd |= SDCMD_WRITE_CMD; + if (cmd->data->flags & MMC_DATA_READ) @@ -72163,10 +72565,12 @@ index 0000000..da08998 + } + + bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); ++ ++ return true; +} + -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, ++ unsigned long *irq_flags); +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); + +static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) @@ -72176,6 +72580,7 @@ index 0000000..da08998 + data = host->data; + BUG_ON(!data); + ++ log_event("FDA<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_data(error %d, stop %d, sbc %d)\n", + data->error, data->stop ? 1 : 0, + host->mrq->sbc ? 1 : 0); @@ -72183,10 +72588,7 @@ index 0000000..da08998 + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); + -+ if (data->error) { -+ data->bytes_xfered = 0; -+ } else -+ data->bytes_xfered = data->blksz * data->blocks; ++ data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks); + + host->data_complete = 1; + @@ -72201,9 +72603,9 @@ index 0000000..da08998 + } + else + bcm2835_sdhost_transfer_complete(host); ++ log_event("FDA>", (u32)host->mrq, (u32)host->cmd); +} + -+ +static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) +{ + struct mmc_data *data; @@ -72215,6 +72617,7 @@ index 0000000..da08998 + data = host->data; + host->data = NULL; + ++ log_event("TCM<", (u32)data, data->error); + pr_debug("transfer_complete(error %d, stop %d)\n", + data->error, data->stop ? 1 : 0); + @@ -72223,88 +72626,114 @@ index 0000000..da08998 + * a) open-ended multiblock transfer (no CMD23) + * b) error in multiblock transfer + */ -+ if (data->stop && -+ (data->error || -+ !host->mrq->sbc)) { -+ host->flush_fifo = 1; -+ bcm2835_sdhost_send_command(host, data->stop); -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); ++ if (host->mrq->stop && (data->error || !host->use_sbc)) { ++ if (bcm2835_sdhost_send_command(host, host->mrq->stop)) { ++ /* No busy, so poll for completion */ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, NULL); ++ ++ if (host->delay_after_this_stop) ++ do_gettimeofday(&host->stop_time); ++ } + } else { ++ bcm2835_sdhost_wait_transfer_complete(host); + tasklet_schedule(&host->finish_tasklet); + } ++ log_event("TCM>", (u32)data, 0); +} + -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) ++/* If irq_flags is valid, the caller is in a thread context and is allowed ++ to sleep */ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, ++ unsigned long *irq_flags) +{ + u32 sdcmd; -+ unsigned long timeout; ++ u32 retries; +#ifdef DEBUG + struct timeval before, after; + int timediff = 0; +#endif + ++ log_event("FCM<", (u32)host->mrq, (u32)host->cmd); + pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); + + BUG_ON(!host->cmd || !host->mrq); + -+#ifdef DEBUG -+ do_gettimeofday(&before); -+#endif -+ /* Wait max 100 ms */ -+ timeout = 10000; ++ /* Poll quickly at first */ ++ ++ retries = host->cmd_quick_poll_retries; ++ if (!retries) { ++ /* Work out how many polls take 1us by timing 10us */ ++ struct timeval start, now; ++ int us_diff; ++ ++ retries = 1; ++ do { ++ int i; ++ ++ retries *= 2; ++ ++ do_gettimeofday(&start); ++ ++ for (i = 0; i < retries; i++) { ++ cpu_relax(); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ } ++ ++ do_gettimeofday(&now); ++ us_diff = (now.tv_sec - start.tv_sec) * 1000000 + ++ (now.tv_usec - start.tv_usec); ++ } while (us_diff < 10); ++ ++ host->cmd_quick_poll_retries = ((retries * us_diff + 9)*CMD_DALLY_US)/10 + 1; ++ retries = 1; // We've already waited long enough this time ++ } ++ ++ retries = host->cmd_quick_poll_retries; + for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ (sdcmd & SDCMD_NEW_FLAG) && timeout; -+ timeout--) { -+ if (host->flush_fifo) { -+ while (bcm2835_sdhost_read(host, SDHSTS) & -+ SDHSTS_DATA_FLAG) -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ udelay(10); ++ (sdcmd & SDCMD_NEW_FLAG) && !(sdcmd & SDCMD_FAIL_FLAG) && retries; ++ retries--) { ++ cpu_relax(); + sdcmd = bcm2835_sdhost_read(host, SDCMD); + } -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); + -+ pr_debug(" finish_command - waited %dus\n", timediff); -+#endif ++ if (!retries) { ++ unsigned long wait_max; + -+ if (timeout == 0) { ++ if (!irq_flags) { ++ /* Schedule the work */ ++ log_event("CWWQ", 0, 0); ++ schedule_work(&host->cmd_wait_wq); ++ return; ++ } ++ ++ /* Wait max 100 ms */ ++ wait_max = jiffies + msecs_to_jiffies(100); ++ while (time_before(jiffies, wait_max)) { ++ spin_unlock_irqrestore(&host->lock, *irq_flags); ++ usleep_range(1, 10); ++ spin_lock_irqsave(&host->lock, *irq_flags); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ if (!(sdcmd & SDCMD_NEW_FLAG) || ++ (sdcmd & SDCMD_FAIL_FLAG)) ++ break; ++ } ++ } ++ ++ /* Check for errors */ ++ if (sdcmd & SDCMD_NEW_FLAG) { + pr_err("%s: command never completed.\n", + mmc_hostname(host->mmc)); + bcm2835_sdhost_dumpregs(host); + host->cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; -+ } -+ -+ if (host->flush_fifo) { -+ for (timeout = 100; -+ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -+ timeout--) { -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ host->flush_fifo = 0; -+ if (timeout == 0) { -+ pr_err("%s: FIFO never drained.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ } -+ -+ /* Check for errors */ -+ if (sdcmd & SDCMD_FAIL_FLAG) -+ { ++ } else if (sdcmd & SDCMD_FAIL_FLAG) { + u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); + ++ /* Clear the errors */ ++ bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS); ++ + if (host->debug) + pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", + mmc_hostname(host->mmc), sdcmd, sdhsts, @@ -72327,7 +72756,7 @@ index 0000000..da08998 + mmc_hostname(host->mmc), + host->cmd->opcode); + bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; ++ host->cmd->error = -EILSEQ; + } + tasklet_schedule(&host->finish_tasklet); + return; @@ -72342,31 +72771,31 @@ index 0000000..da08998 + pr_debug("%s: finish_command %08x %08x %08x %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); ++ log_event("RSP ", host->cmd->resp[0], host->cmd->resp[1]); + } else { + host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); + pr_debug("%s: finish_command %08x\n", + mmc_hostname(host->mmc), + host->cmd->resp[0]); ++ log_event("RSP ", host->cmd->resp[0], 0); + } + } + -+ host->cmd->error = 0; -+ + if (host->cmd == host->mrq->sbc) { + /* Finished CMD23, now send actual command. */ + host->cmd = NULL; -+ bcm2835_sdhost_send_command(host, host->mrq->cmd); ++ if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) { ++ if (host->data && host->dma_desc) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_start_dma(host); + -+ if (host->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else if (host->cmd == host->mrq->stop) ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, NULL); ++ } ++ } else if (host->cmd == host->mrq->stop) { + /* Finished CMD12 */ + tasklet_schedule(&host->finish_tasklet); -+ else { ++ } else { + /* Processed actual command. */ + host->cmd = NULL; + if (!host->data) @@ -72374,6 +72803,7 @@ index 0000000..da08998 + else if (host->data_complete) + bcm2835_sdhost_transfer_complete(host); + } ++ log_event("FCM>", (u32)host->mrq, (u32)host->cmd); +} + +static void bcm2835_sdhost_timeout(unsigned long data) @@ -72384,10 +72814,12 @@ index 0000000..da08998 + host = (struct bcm2835_host *)data; + + spin_lock_irqsave(&host->lock, flags); ++ log_event("TIM<", 0, 0); + + if (host->mrq) { + pr_err("%s: timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); ++ log_dump(); + bcm2835_sdhost_dumpregs(host); + + if (host->data) { @@ -72408,74 +72840,15 @@ index 0000000..da08998 + spin_unlock_irqrestore(&host->lock, flags); +} + -+static void bcm2835_sdhost_pio_timeout(unsigned long data) ++static void bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) +{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ if (sdhsts & SDHSTS_REW_TIME_OUT) { -+ pr_err("%s: transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); -+ } else { -+ pr_err("%s: unexpected transfer timeout\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -+ SDHSTS); -+ -+ host->data->error = -ETIMEDOUT; -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) -+{ -+ if (enable) -+ host->hcfg |= SDHCFG_SDIO_IRPT_EN; -+ else -+ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); -+ spin_lock_irqsave(&host->lock, flags); -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -+ SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR); -+ ++ log_event("IRQB", (u32)host->cmd, intmask); + if (!host->cmd) { + pr_err("%s: got command busy interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return 0; ++ return; + } + + if (!host->use_busy) { @@ -72483,7 +72856,7 @@ index 0000000..da08998 + "though not expecting one.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return 0; ++ return; + } + host->use_busy = 0; + @@ -72506,28 +72879,23 @@ index 0000000..da08998 + } else if (intmask & SDHSTS_CMD_TIME_OUT) + host->cmd->error = -ETIMEDOUT; + ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); + } + else -+ bcm2835_sdhost_finish_command(host); -+ -+ return handled; ++ bcm2835_sdhost_finish_command(host, NULL); +} + -+static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) +{ -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); -+ + /* There are no dedicated data/space available interrupt + status bits, so it is necessary to use the single shared + data/space available FIFO status bits. It is therefore not + an error to get here when there is no data transfer in + progress. */ ++ log_event("IRQD", (u32)host->data, intmask); + if (!host->data) -+ return 0; ++ return; + + if (intmask & (SDHSTS_CRC16_ERROR | + SDHSTS_FIFO_ERROR | @@ -72538,46 +72906,37 @@ index 0000000..da08998 + else + host->data->error = -ETIMEDOUT; + -+ bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; ++ if (host->debug) { ++ log_dump(); ++ bcm2835_sdhost_dumpregs(host); ++ } + } + -+ /* Use the block interrupt for writes after the first block */ -+ if (host->data->flags & MMC_DATA_WRITE) { ++ if (host->data->error) { ++ bcm2835_sdhost_finish_data(host); ++ } else if (host->data->flags & MMC_DATA_WRITE) { ++ /* Use the block interrupt for writes after the first block */ + host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); + host->hcfg |= SDHCFG_BLOCK_IRPT_EN; + bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if (host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); ++ bcm2835_sdhost_transfer_pio(host); + } else { -+ if (!host->data->error) { -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; -+ } ++ bcm2835_sdhost_transfer_pio(host); ++ host->blocks--; + if ((host->blocks == 0) || host->data->error) + bcm2835_sdhost_finish_data(host); + } -+ -+ return handled; +} + -+static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) +{ -+ struct dma_chan *dma_chan; -+ u32 dir_data; -+ const u32 handled = (SDHSTS_REW_TIME_OUT | -+ SDHSTS_CRC16_ERROR | -+ SDHSTS_FIFO_ERROR); -+ ++ log_event("IRQK", (u32)host->data, intmask); + if (!host->data) { + pr_err("%s: got block interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + bcm2835_sdhost_dumpregs(host); -+ return handled; ++ return; + } + + if (intmask & (SDHSTS_CRC16_ERROR | @@ -72589,145 +72948,69 @@ index 0000000..da08998 + else + host->data->error = -ETIMEDOUT; + -+ if (host->debug) ++ if (host->debug) { ++ log_dump(); + bcm2835_sdhost_dumpregs(host); -+ tasklet_schedule(&host->finish_tasklet); -+ return handled; ++ } + } + -+ if (!host->use_dma) { ++ if (!host->dma_desc) { + BUG_ON(!host->blocks); -+ host->blocks--; -+ if ((host->blocks == 0) || host->data->error) { -+ /* Cancel the timer */ -+ del_timer(&host->pio_timer); -+ ++ if (host->data->error || (--host->blocks == 0)) { + bcm2835_sdhost_finish_data(host); + } else { + bcm2835_sdhost_transfer_pio(host); -+ -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); + } + } else if (host->data->flags & MMC_DATA_WRITE) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ + bcm2835_sdhost_finish_data(host); + } -+ -+ return handled; +} + -+ +static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) +{ + irqreturn_t result = IRQ_NONE; + struct bcm2835_host *host = dev_id; -+ u32 unexpected = 0, early = 0; -+ int loops = 0; ++ u32 intmask; + + spin_lock(&host->lock); + -+ for (loops = 0; loops < 1; loops++) { -+ u32 intmask, handled; ++ intmask = bcm2835_sdhost_read(host, SDHSTS); ++ log_event("IRQ<", intmask, 0); + -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ handled = intmask & (SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && -+ (loops == 0) && !host->data) { -+ pr_err("%s: sdhost_irq data interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), -+ (unsigned)intmask); -+ -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ if (!handled) -+ break; -+ -+ if (loops) -+ early |= handled; ++ bcm2835_sdhost_write(host, ++ SDHSTS_BUSY_IRPT | ++ SDHSTS_BLOCK_IRPT | ++ SDHSTS_SDIO_IRPT | ++ SDHSTS_DATA_FLAG, ++ SDHSTS); + ++ if (intmask & SDHSTS_BLOCK_IRPT) { ++ bcm2835_sdhost_block_irq(host, intmask); + result = IRQ_HANDLED; ++ } + -+ /* Clear all interrupts and notifications */ -+ bcm2835_sdhost_write(host, intmask, SDHSTS); ++ if (intmask & SDHSTS_BUSY_IRPT) { ++ bcm2835_sdhost_busy_irq(host, intmask); ++ result = IRQ_HANDLED; ++ } + -+ if (intmask & SDHSTS_BUSY_IRPT) -+ handled |= bcm2835_sdhost_busy_irq(host, intmask); -+ -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) -+ handled |= bcm2835_sdhost_data_irq(host, intmask); -+ -+ if (intmask & SDHSTS_BLOCK_IRPT) -+ handled |= bcm2835_sdhost_block_irq(host, intmask); -+ -+ if (intmask & SDHSTS_SDIO_IRPT) { -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -+ host->thread_isr |= SDHSTS_SDIO_IRPT; -+ result = IRQ_WAKE_THREAD; -+ } -+ -+ unexpected |= (intmask & ~handled); ++ /* There is no true data interrupt status bit, so it is ++ necessary to qualify the data flag with the interrupt ++ enable bit */ ++ if ((intmask & SDHSTS_DATA_FLAG) && ++ (host->hcfg & SDHCFG_DATA_IRPT_EN)) { ++ bcm2835_sdhost_data_irq(host, intmask); ++ result = IRQ_HANDLED; + } + + mmiowb(); + ++ log_event("IRQ>", bcm2835_sdhost_read(host, SDHSTS), 0); + spin_unlock(&host->lock); + -+ if (early) -+ pr_debug("%s: early %x (loops %d)\n", -+ mmc_hostname(host->mmc), early, loops); -+ -+ if (unexpected) { -+ pr_err("%s: unexpected interrupt 0x%08x.\n", -+ mmc_hostname(host->mmc), unexpected); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ + return result; +} + -+static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_host *host = dev_id; -+ unsigned long flags; -+ u32 isr; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ isr = host->thread_isr; -+ host->thread_isr = 0; -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (isr & SDHSTS_SDIO_IRPT) { -+ sdio_run_irqs(host->mmc); -+ -+/* Is this necessary? Why re-enable an interrupt which is enabled? -+ spin_lock_irqsave(&host->lock, flags); -+ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -+ spin_unlock_irqrestore(&host->lock, flags); -+*/ -+ } -+ -+ return isr ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+ -+ +void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) +{ + int div = 0; /* Initialized for compiler warning */ @@ -72737,9 +73020,8 @@ index 0000000..da08998 + pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); + + if ((host->overclock_50 > 50) && -+ (clock == 50*MHZ)) { ++ (clock == 50*MHZ)) + clock = host->overclock_50 * MHZ + (MHZ - 1); -+ } + + /* The SDCDIV register has 11 bits, and holds (div - 2). + But in data mode the max is 50MHz wihout a minimum, and only the @@ -72786,6 +73068,11 @@ index 0000000..da08998 + clock = host->max_clk / (div + 2); + host->mmc->actual_clock = clock; + ++ /* Calibrate some delays */ ++ ++ host->ns_per_fifo_word = (1000000000/clock) * ++ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); ++ + if (clock > input_clock) { + /* Save the closest value, to make it easier + to reduce in the event of error */ @@ -72821,6 +73108,7 @@ index 0000000..da08998 +{ + struct bcm2835_host *host; + unsigned long flags; ++ u32 edm, fsm; + + host = mmc_priv(mmc); + @@ -72841,6 +73129,8 @@ index 0000000..da08998 + } + + /* Reset the error statuses in case this is a retry */ ++ if (mrq->sbc) ++ mrq->sbc->error = 0; + if (mrq->cmd) + mrq->cmd->error = 0; + if (mrq->data) @@ -72856,29 +73146,59 @@ index 0000000..da08998 + return; + } + ++ if (host->use_dma && mrq->data && ++ (mrq->data->blocks > host->pio_limit)) ++ bcm2835_sdhost_prepare_dma(host, mrq->data); ++ + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); -+ + host->mrq = mrq; + -+ if (mrq->sbc) -+ bcm2835_sdhost_send_command(host, mrq->sbc); -+ else -+ bcm2835_sdhost_send_command(host, mrq->cmd); ++ edm = bcm2835_sdhost_read(host, SDEDM); ++ fsm = edm & SDEDM_FSM_MASK; + ++ log_event("REQ<", (u32)mrq, edm); ++ if ((fsm != SDEDM_FSM_IDENTMODE) && ++ (fsm != SDEDM_FSM_DATAMODE)) { ++ pr_err("%s: previous command (%d) not complete (EDM %x)\n", ++ mmc_hostname(host->mmc), ++ bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, ++ edm); ++ log_event("REQ!", (u32)mrq, edm); ++ log_dump(); ++ bcm2835_sdhost_dumpregs(host); ++ mrq->cmd->error = -EILSEQ; ++ tasklet_schedule(&host->finish_tasklet); ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ host->use_sbc = !!mrq->sbc && ++ (host->mrq->data->flags & USE_CMD23_FLAGS); ++ if (host->use_sbc) { ++ if (bcm2835_sdhost_send_command(host, mrq->sbc)) { ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, &flags); ++ } ++ } else if (bcm2835_sdhost_send_command(host, mrq->cmd)) { ++ if (host->data && host->dma_desc) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_start_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host, &flags); ++ } ++ ++ log_event("CMD ", (u32)mrq->cmd->opcode, ++ mrq->data ? (u32)mrq->data->blksz : 0); + mmiowb(); ++ ++ log_event("REQ>", (u32)mrq, 0); + spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (!mrq->sbc && mrq->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); +} + -+ +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + @@ -72894,6 +73214,8 @@ index 0000000..da08998 + + spin_lock_irqsave(&host->lock, flags); + ++ log_event("IOS<", ios->clock, 0); ++ + if (!ios->clock || ios->clock != host->clock) { + bcm2835_sdhost_set_clock(host, ios->clock); + host->clock = ios->clock; @@ -72916,44 +73238,53 @@ index 0000000..da08998 + spin_unlock_irqrestore(&host->lock, flags); +} + -+static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -+ unsigned int direction, -+ u32 blk_pos, int blk_size) -+{ -+ /* There is a bug in the host controller hardware that makes -+ reading the final sector of the card as part of a multiple read -+ problematic. Detect that case and shorten the read accordingly. -+ */ -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ -+ return blk_size; -+} -+ -+ +static struct mmc_host_ops bcm2835_sdhost_ops = { + .request = bcm2835_sdhost_request, + .set_ios = bcm2835_sdhost_set_ios, -+ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, + .hw_reset = bcm2835_sdhost_reset, -+ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, +}; + ++static void bcm2835_sdhost_cmd_wait_work(struct work_struct *work) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = container_of(work, struct bcm2835_host, cmd_wait_wq); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ log_event("CWK<", (u32)host->cmd, (u32)host->mrq); ++ ++ /* ++ * If this tasklet gets rescheduled while running, it will ++ * be run again afterwards but without any active request. ++ */ ++ if (!host->mrq) { ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ bcm2835_sdhost_finish_command(host, &flags); ++ ++ mmiowb(); ++ ++ log_event("CWK>", (u32)host->cmd, 0); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} + +static void bcm2835_sdhost_tasklet_finish(unsigned long param) +{ + struct bcm2835_host *host; + unsigned long flags; + struct mmc_request *mrq; ++ struct dma_chan *terminate_chan = NULL; + + host = (struct bcm2835_host *)param; + + spin_lock_irqsave(&host->lock, flags); + ++ log_event("TSK<", (u32)host->mrq, 0); + /* + * If this tasklet gets rescheduled while running, it will + * be run again afterwards but without any active request. @@ -72988,12 +73319,24 @@ index 0000000..da08998 + + mmiowb(); + ++ host->dma_desc = NULL; ++ terminate_chan = host->dma_chan; ++ host->dma_chan = NULL; ++ + spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (terminate_chan) ++ { ++ int err = dmaengine_terminate_all(terminate_chan); ++ if (err) ++ pr_err("%s: failed to terminate DMA (%d)\n", ++ mmc_hostname(host->mmc), err); ++ } ++ + mmc_request_done(host->mmc, mrq); ++ log_event("TSK>", (u32)mrq, 0); +} + -+ -+ +int bcm2835_sdhost_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc; @@ -73014,39 +73357,57 @@ index 0000000..da08998 + mmc->f_max, mmc->f_min, mmc->max_busy_timeout); + + /* host controller capabilities */ -+ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | ++ mmc->caps |= + MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | + MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | -+ (ALLOW_CMD23 * MMC_CAP_CMD23); ++ ((ALLOW_CMD23_READ|ALLOW_CMD23_WRITE) * MMC_CAP_CMD23); + + spin_lock_init(&host->lock); + + if (host->allow_dma) { -+ if (IS_ERR_OR_NULL(host->dma_chan_tx) || -+ IS_ERR_OR_NULL(host->dma_chan_rx)) { -+ pr_err("%s: unable to initialise DMA channels. " ++ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { ++ pr_err("%s: unable to initialise DMA channel. " + "Falling back to PIO\n", + mmc_hostname(mmc)); -+ host->have_dma = false; ++ host->use_dma = false; + } else { -+ host->have_dma = true; -+ + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + cfg.slave_id = 13; /* DREQ channel */ + ++ /* Validate the slave configurations */ ++ + cfg.direction = DMA_MEM_TO_DEV; + cfg.src_addr = 0; + cfg.dst_addr = host->bus_addr + SDDATA; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); + -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDDATA; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ ++ if (ret == 0) { ++ host->dma_cfg_tx = cfg; ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->bus_addr + SDDATA; ++ cfg.dst_addr = 0; ++ ++ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); ++ } ++ ++ if (ret == 0) { ++ host->dma_cfg_rx = cfg; ++ ++ host->use_dma = true; ++ } else { ++ pr_err("%s: unable to configure DMA channel. " ++ "Falling back to PIO\n", ++ mmc_hostname(mmc)); ++ dma_release_channel(host->dma_chan_rxtx); ++ host->dma_chan_rxtx = NULL; ++ host->use_dma = false; ++ } + } + } else { -+ host->have_dma = false; ++ host->use_dma = false; + } + + mmc->max_segs = 128; @@ -73061,16 +73422,15 @@ index 0000000..da08998 + tasklet_init(&host->finish_tasklet, + bcm2835_sdhost_tasklet_finish, (unsigned long)host); + ++ INIT_WORK(&host->cmd_wait_wq, bcm2835_sdhost_cmd_wait_work); ++ + setup_timer(&host->timer, bcm2835_sdhost_timeout, + (unsigned long)host); + -+ setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ (unsigned long)host); -+ + bcm2835_sdhost_init(host, 0); -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -+ bcm2835_sdhost_thread_irq, -+ IRQF_SHARED, mmc_hostname(mmc), host); ++ ++ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, ++ mmc_hostname(mmc), host); + if (ret) { + pr_err("%s: failed to request IRQ %d: %d\n", + mmc_hostname(mmc), host->irq, ret); @@ -73081,11 +73441,11 @@ index 0000000..da08998 + mmc_add_host(mmc); + + pio_limit_string[0] = '\0'; -+ if (host->have_dma && (host->pio_limit > 0)) ++ if (host->use_dma && (host->pio_limit > 0)) + sprintf(pio_limit_string, " (>%d)", host->pio_limit); + pr_info("%s: %s loaded - DMA %s%s\n", + mmc_hostname(mmc), DRIVER_NAME, -+ host->have_dma ? "enabled" : "disabled", ++ host->use_dma ? "enabled" : "disabled", + pio_limit_string); + + return 0; @@ -73115,8 +73475,11 @@ index 0000000..da08998 + mmc->ops = &bcm2835_sdhost_ops; + host = mmc_priv(mmc); + host->mmc = mmc; ++ host->cmd_quick_poll_retries = 0; + host->pio_timeout = msecs_to_jiffies(500); ++ host->pio_limit = 1; + host->max_delay = 1; /* Warn if over 1ms */ ++ host->allow_dma = 1; + spin_lock_init(&host->lock); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -73132,13 +73495,12 @@ index 0000000..da08998 + return -ENODEV; + } + host->bus_addr = be32_to_cpup(addr); ++ log_init(iomem->start - host->bus_addr); + pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", + (unsigned long)host->ioaddr, + (unsigned long)iomem->start, + (unsigned long)host->bus_addr); + -+ host->allow_dma = ALLOW_DMA; -+ + if (node) { + /* Read any custom properties */ + of_property_read_u32(node, @@ -73150,26 +73512,35 @@ index 0000000..da08998 + of_property_read_u32(node, + "brcm,pio-limit", + &host->pio_limit); -+ host->allow_dma = ALLOW_DMA && ++ host->allow_dma = + !of_property_read_bool(node, "brcm,force-pio"); + host->debug = of_property_read_bool(node, "brcm,debug"); + } + ++ host->dma_chan = NULL; ++ host->dma_desc = NULL; ++ ++ /* Formally recognise the other way of disabling DMA */ ++ if (host->pio_limit == 0x7fffffff) ++ host->allow_dma = false; ++ + if (host->allow_dma) { + if (node) { -+ host->dma_chan_tx = -+ dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = -+ dma_request_slave_channel(dev, "rx"); ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx-tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "tx"); ++ if (!host->dma_chan_rxtx) ++ host->dma_chan_rxtx = ++ dma_request_slave_channel(dev, "rx"); + } else { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + /* we don't care about the channel, any would work */ + dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = -+ dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = ++ host->dma_chan_rxtx = + dma_request_channel(mask, NULL, NULL); + } + } @@ -73239,15 +73610,12 @@ index 0000000..da08998 + return 0; +} + -+ +static const struct of_device_id bcm2835_sdhost_match[] = { + { .compatible = "brcm,bcm2835-sdhost" }, + { } +}; +MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); + -+ -+ +static struct platform_driver bcm2835_sdhost_driver = { + .probe = bcm2835_sdhost_probe, + .remove = bcm2835_sdhost_remove, @@ -73264,10 +73632,10 @@ index 0000000..da08998 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From a5a139f18bcc782f2cc3a1de66c936ce2dbb6ffb Mon Sep 17 00:00:00 2001 +From e3dd7794f6746e34aef2cff941ab2a79f3942099 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 034/251] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 035/114] cma: Add vc_cma driver to enable use of CMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -73299,7 +73667,7 @@ Signed-off-by: Noralf Trønnes create mode 100644 include/linux/broadcom/vc_cma.h diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index a043107..2ba2d82 100644 +index 3ec0766..aec9337 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -4,6 +4,8 @@ @@ -74610,10 +74978,10 @@ index 0000000..be2819d + +#endif /* VC_CMA_H */ -From 79708ff24769bfa53cc800dd05f951340829cc5d Mon Sep 17 00:00:00 2001 +From 00dc76905d2070f2f9080fcf0c93a0d94b0826bc Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 035/251] bcm2708: alsa sound driver +Subject: [PATCH 036/114] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -74668,7 +75036,7 @@ Signed-off-by: Noralf Trønnes create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index e040621..7746e5d 100644 +index e040621..7746e5d2 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig @@ -40,5 +40,13 @@ config SND_PXA2XX_AC97 @@ -76500,7 +76868,7 @@ index 0000000..3de3094 +MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c new file mode 100644 -index 0000000..6b545e7 +index 0000000..7a2ed78 --- /dev/null +++ b/sound/arm/bcm2835.c @@ -0,0 +1,511 @@ @@ -76609,7 +76977,7 @@ index 0000000..6b545e7 + numchans); + } + -+ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); ++ err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); + if (err) { + dev_err(dev, "Failed to create soundcard structure\n"); + return err; @@ -76689,7 +77057,7 @@ index 0000000..6b545e7 + if (dev > 0) + goto add_register_map; + -+ err = snd_card_new(NULL, index[dev], id[dev], THIS_MODULE, 0, &g_card); ++ err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE, 0, &g_card); + if (err < 0) + goto out; + @@ -77311,10 +77679,10 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From 522686ae5036c50971853fee0fdb371ed8309222 Mon Sep 17 00:00:00 2001 +From d5ba929f0e3f3ea5bce2e0f10a33492c20a2fd2d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 036/251] bcm2708 vchiq driver +Subject: [PATCH 037/114] bcm2708 vchiq driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -77484,6 +77852,26 @@ vchiq_arm: Sort out the vmalloc case See: https://github.com/raspberrypi/linux/issues/1055 vchiq: hack: Add include depecated dma include file + +vchiq_arm: Tweak the logging output + +Signed-off-by: Phil Elwell + +vchiq_arm: Access the dequeue_pending flag locked + +Reading through this code looking for another problem (now found in userland) +the use of dequeue_pending outside a lock didn't seem safe. + +Signed-off-by: Phil Elwell + +vchiq_arm: Service callbacks must not fail + +Service callbacks are not allowed to return an error. The internal callback +that delivers events and messages to user tasks does not enqueue them if +the service is closing, but this is not an error and should not be +reported as such. + +Signed-off-by: Phil Elwell --- arch/arm/mach-bcm2708/include/mach/platform.h | 2 + arch/arm/mach-bcm2709/include/mach/platform.h | 2 + @@ -77501,13 +77889,13 @@ vchiq: hack: Add include depecated dma include file .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + .../interface/vchiq_arm/vchiq_2835_arm.c | 586 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2903 +++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2910 +++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + .../interface/vchiq_arm/vchiq_connected.c | 120 + .../interface/vchiq_arm/vchiq_connected.h | 50 + - .../vc04_services/interface/vchiq_arm/vchiq_core.c | 3934 ++++++++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_core.c | 3929 ++++++++++++++++++++ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 712 ++++ .../interface/vchiq_arm/vchiq_debugfs.c | 383 ++ .../interface/vchiq_arm/vchiq_debugfs.h | 52 + @@ -77522,7 +77910,7 @@ vchiq: hack: Add include depecated dma include file .../vc04_services/interface/vchiq_arm/vchiq_util.c | 156 + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 82 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 37 files changed, 12819 insertions(+) + 37 files changed, 12821 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -77584,10 +77972,10 @@ index 311b9f2..9a638f5 100644 /* * Watchdog diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 22892c7..b859ce0 100644 +index a216b46..90af750 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -533,6 +533,7 @@ source "drivers/misc/lis3lv02d/Kconfig" +@@ -812,6 +812,7 @@ source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" source "drivers/misc/vmw_vmci/Kconfig" @@ -77596,7 +77984,7 @@ index 22892c7..b859ce0 100644 source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 537d7f3..ac24d77 100644 +index b2fb6dbf..1a58cf7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_INTEL_MEI) += mei/ @@ -79794,10 +80182,10 @@ index 0000000..c29040f +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..e11c0e0 +index 0000000..a5cc385 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2903 @@ +@@ -0,0 +1,2910 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -80024,7 +80412,7 @@ index 0000000..e11c0e0 + } else if (instance->closing) { + vchiq_log_info(vchiq_arm_log_level, + "service_callback closing"); -+ return VCHIQ_ERROR; ++ return VCHIQ_SUCCESS; + } + DEBUG_TRACE(SERVICE_CALLBACK_LINE); + } @@ -80079,6 +80467,7 @@ index 0000000..e11c0e0 + USER_SERVICE_T *user_service; + VCHIQ_SERVICE_T *service; + VCHIQ_INSTANCE_T instance; ++ int skip_completion = 0; + DEBUG_INITIALISE(g_state.local) + + DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -80145,9 +80534,6 @@ index 0000000..e11c0e0 + user_service->msg_queue[user_service->msg_insert & + (MSG_QUEUE_SIZE - 1)] = header; + user_service->msg_insert++; -+ spin_unlock(&msg_queue_spinlock); -+ -+ up(&user_service->insert_event); + + /* If there is a thread waiting in DEQUEUE_MESSAGE, or if + ** there is a MESSAGE_AVAILABLE in the completion queue then @@ -80156,13 +80542,22 @@ index 0000000..e11c0e0 + if (((user_service->message_available_pos - + instance->completion_remove) >= 0) || + user_service->dequeue_pending) { -+ DEBUG_TRACE(SERVICE_CALLBACK_LINE); + user_service->dequeue_pending = 0; -+ return VCHIQ_SUCCESS; ++ skip_completion = 1; + } + ++ spin_unlock(&msg_queue_spinlock); ++ ++ up(&user_service->insert_event); ++ + header = NULL; + } ++ ++ if (skip_completion) { ++ DEBUG_TRACE(SERVICE_CALLBACK_LINE); ++ return VCHIQ_SUCCESS; ++ } ++ + DEBUG_TRACE(SERVICE_CALLBACK_LINE); + + return add_completion(instance, reason, header, user_service, @@ -83229,10 +83624,10 @@ index 0000000..863b3e3 +#endif /* VCHIQ_CONNECTED_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c new file mode 100644 -index 0000000..2c98da4 +index 0000000..160db24 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -0,0 +1,3934 @@ +@@ -0,0 +1,3929 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -84126,16 +84521,14 @@ index 0000000..2c98da4 + error_count); + return VCHIQ_ERROR; + } -+ if (i == 0) { -+ if (SRVTRACE_ENABLED(service, -+ VCHIQ_LOG_INFO)) -+ vchiq_log_dump_mem("Sent", 0, -+ header->data + pos, -+ min(64u, -+ elements[0].size)); -+ } + } + ++ if (SRVTRACE_ENABLED(service, ++ VCHIQ_LOG_INFO)) ++ vchiq_log_dump_mem("Sent", 0, ++ header->data, ++ min(16, pos)); ++ + spin_lock("a_spinlock); + service_quota->message_use_count++; + @@ -84274,16 +84667,13 @@ index 0000000..2c98da4 + error_count); + return VCHIQ_ERROR; + } -+ if (i == 0) { -+ if (vchiq_sync_log_level >= -+ VCHIQ_LOG_TRACE) -+ vchiq_log_dump_mem("Sent Sync", -+ 0, header->data + pos, -+ min(64u, -+ elements[0].size)); -+ } + } + ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("Sent Sync", ++ 0, header->data, ++ min(16, pos)); ++ + VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); + } else { @@ -84955,7 +85345,7 @@ index 0000000..2c98da4 + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, -+ min(64, size)); ++ min(16, size)); + } + + if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) @@ -85422,7 +85812,7 @@ index 0000000..2c98da4 + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, -+ min(64, size)); ++ min(16, size)); + } + + switch (type) { @@ -90619,10 +91009,10 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From a4ad9bf42376a39e5314f41ecd1ea8fbafb4ca46 Mon Sep 17 00:00:00 2001 +From 62b4dcdac24e9da625a03d47365898e1c57ae1d5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 16:07:06 +0100 -Subject: [PATCH 037/251] vc_mem: Add vc_mem driver +Subject: [PATCH 038/114] vc_mem: Add vc_mem driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -91627,10 +92017,10 @@ index 0000000..20a4753 + +#endif /* _VC_MEM_H */ -From c18ab896c13c1824cdc4c8c544f2576e778d4595 Mon Sep 17 00:00:00 2001 +From 5e3c755951a4886d0e8a7673dabfabd6f0e0a11a Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 038/251] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 039/114] vcsm: VideoCore shared memory service for BCM2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -96046,10 +96436,10 @@ index 0000000..334f36d + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ -From d778ec78cbc50597690495a4767dad44d9329547 Mon Sep 17 00:00:00 2001 +From c3063fdb979a493f5d9bec3535410b807465f82f Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 039/251] Add /dev/gpiomem device for rootless user GPIO access +Subject: [PATCH 040/114] Add /dev/gpiomem device for rootless user GPIO access Signed-off-by: Luke Wren @@ -96360,10 +96750,10 @@ index 0000000..911f5b7 +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); -From 684fa35717d47554b4e019f45e513b58823b50dc Mon Sep 17 00:00:00 2001 +From 51660273781e15d356a98ffdc38671cdde96cf78 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 040/251] Add SMI driver +Subject: [PATCH 041/114] Add SMI driver Signed-off-by: Luke Wren --- @@ -96895,7 +97285,7 @@ index 0000000..d6efd92 + "Character device driver for BCM2835's secondary memory interface"); +MODULE_AUTHOR("Luke Wren "); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index b859ce0..b978ba9 100644 +index 90af750..7011b2d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D @@ -96914,7 +97304,7 @@ index b859ce0..b978ba9 100644 tristate "Analog Devices Digital Potentiometers" depends on (I2C || SPI) && SYSFS diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index ac24d77..1acff5b 100644 +index 1a58cf7..28989fa 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o @@ -98314,18 +98704,18 @@ index 0000000..ee3a75e + +#endif /* BCM2835_SMI_H */ -From d6893b8f68df96a0dd728a1ea8518af748d3de55 Mon Sep 17 00:00:00 2001 +From 4fcf517853295325de2791f6ec1a647c1ec88a53 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 041/251] Add SMI NAND driver +Subject: [PATCH 042/114] Add SMI NAND driver Signed-off-by: Luke Wren --- .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++ drivers/mtd/nand/Kconfig | 7 + drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++ - 4 files changed, 318 insertions(+) + drivers/mtd/nand/bcm2835_smi_nand.c | 267 +++++++++++++++++++++ + 4 files changed, 317 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c @@ -98379,7 +98769,7 @@ index 0000000..159544d +}; \ No newline at end of file diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 2896640..56ff00b 100644 +index f05e0e9..8c69541 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -41,6 +41,13 @@ config MTD_SM_COMMON @@ -98397,7 +98787,7 @@ index 2896640..56ff00b 100644 tristate diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 2c7f014..30e22f0 100644 +index f553353..ea8d647 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o @@ -98410,10 +98800,10 @@ index 2c7f014..30e22f0 100644 obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o diff --git a/drivers/mtd/nand/bcm2835_smi_nand.c b/drivers/mtd/nand/bcm2835_smi_nand.c new file mode 100644 -index 0000000..b747326 +index 0000000..02adda6 --- /dev/null +++ b/drivers/mtd/nand/bcm2835_smi_nand.c -@@ -0,0 +1,268 @@ +@@ -0,0 +1,267 @@ +/** + * NAND flash driver for Broadcom Secondary Memory Interface + * @@ -98606,7 +98996,6 @@ index 0000000..b747326 + mtd->owner = THIS_MODULE; + mtd->dev.parent = dev; + mtd->name = DRIVER_NAME; -+ ppdata.of_node = node; + + /* 20 us command delay time... */ + this->chip_delay = 20; @@ -98683,10 +99072,10 @@ index 0000000..b747326 + ("Driver for NAND chips using Broadcom Secondary Memory Interface"); +MODULE_AUTHOR("Luke Wren "); -From 90d547aa8fc1259726f56f404af4ecf9dff6ba0e Mon Sep 17 00:00:00 2001 +From 370d2f9b37ffe70748bbec0a41c59fc1a0f29fb6 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 042/251] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 043/114] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -98771,7 +99160,7 @@ index 5430adf..9e53cd0 100644 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c new file mode 100644 -index 0000000..cd09c99 +index 0000000..0624439 --- /dev/null +++ b/drivers/staging/media/lirc/lirc_rpi.c @@ -0,0 +1,730 @@ @@ -99048,7 +99437,7 @@ index 0000000..cd09c99 + data = PULSE_MASK; /* really long time */ + if (!(signal^sense)) { + /* sanity check */ -+ printk(KERN_WARNING LIRC_DRIVER_NAME ++ printk(KERN_DEBUG LIRC_DRIVER_NAME + ": AIEEEE: %d %d %lx %lx %lx %lx\n", + signal, sense, tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); @@ -99535,10 +99924,10 @@ index 0000000..fb69624 + +#endif -From c220c109c1a18cf786523a205b85a4ebca638624 Mon Sep 17 00:00:00 2001 +From ad8d0254434814507570bf2f39b74e65f041a58c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 043/251] Add cpufreq driver +Subject: [PATCH 044/114] Add cpufreq driver Signed-off-by: popcornmix --- @@ -99549,12 +99938,12 @@ Signed-off-by: popcornmix create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index b1f8a73..930b3ef 100644 +index 14b1f93..c6e8bd5 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -217,6 +217,15 @@ config ARM_SPEAR_CPUFREQ - help - This adds the CPUFreq driver support for SPEAr SOCs. +@@ -229,6 +229,15 @@ config ARM_STI_CPUFREQ + this config option if you wish to add CPUFreq support for STi based + SoCs. +config ARM_BCM2835_CPUFREQ + depends on RASPBERRYPI_FIRMWARE @@ -99569,13 +99958,13 @@ index b1f8a73..930b3ef 100644 bool "Tegra20 CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index c0af1a1..f6a753a 100644 +index 9e63fb1..9e55083 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -73,6 +73,7 @@ obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o - obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o +@@ -74,6 +74,7 @@ obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o + obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o +obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o @@ -99800,10 +100189,10 @@ index 0000000..3eb9e93 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From 1184f7bb9072fe8b453e3c9a71938a16943a708f Mon Sep 17 00:00:00 2001 +From 58567c0d357f8c1311e43791effa972482306217 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 044/251] Added hwmon/thermal driver for reporting core +Subject: [PATCH 045/114] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -99824,10 +100213,10 @@ Signed-off-by: Noralf Trønnes create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index 8cc4ac6..b273311 100644 +index c37eedc..0705996 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -285,6 +285,13 @@ config INTEL_POWERCLAMP +@@ -292,6 +292,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. @@ -99842,7 +100231,7 @@ index 8cc4ac6..b273311 100644 tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index cfae6a6..b0e336f 100644 +index 8e9cbc3..497014c 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o @@ -100001,10 +100390,10 @@ index 0000000..08d8dc7 +MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); +MODULE_LICENSE("GPL"); -From 418bd7563b83b568046489b0f4b8c67391d31445 Mon Sep 17 00:00:00 2001 +From a61b0d97dc8cd059cb38e51fd0854e6cabec3967 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 045/251] Add Chris Boot's i2c driver +Subject: [PATCH 046/114] Add Chris Boot's i2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100085,15 +100474,17 @@ validity of the chip_select value. i2c-bcm2708: Remove non-DT support Signed-off-by: Noralf Trønnes + +Set the BSC_CLKT clock streching timeout to 35ms as per SMBus specs. --- drivers/i2c/busses/Kconfig | 21 +- drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 493 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 515 insertions(+), 1 deletion(-) + drivers/i2c/busses/i2c-bcm2708.c | 508 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 drivers/i2c/busses/i2c-bcm2708.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 7b0aa82..effadb0 100644 +index faa8e68..2bd4f7f 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" @@ -100146,10 +100537,10 @@ index 37f2819..e309579 100644 diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c new file mode 100644 -index 0000000..85f411c +index 0000000..c9b8e5c --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,493 @@ +@@ -0,0 +1,508 @@ +/* + * Driver for Broadcom BCM2708 BSC Controllers + * @@ -100223,7 +100614,7 @@ index 0000000..85f411c + +#define DRV_NAME "bcm2708_i2c" + -+static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; ++static unsigned int baudrate; +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(baudrate, "The I2C baudrate"); + @@ -100239,6 +100630,7 @@ index 0000000..85f411c + int irq; + struct clk *clk; + u32 cdiv; ++ u32 clk_tout; + + struct completion done; + @@ -100278,7 +100670,7 @@ index 0000000..85f411c + +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) +{ -+ u32 cdiv, s; ++ u32 cdiv, s, clk_tout; + u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; + int wait_loops = I2C_WAIT_LOOP_COUNT; + @@ -100286,12 +100678,14 @@ index 0000000..85f411c + * Use the value that we cached in the probe. + */ + cdiv = bi->cdiv; ++ clk_tout = bi->clk_tout; + + if (bi->msg->flags & I2C_M_RD) + c |= BSC_C_INTR | BSC_C_READ; + else + c |= BSC_C_INTT; + ++ bcm2708_wr(bi, BSC_CLKT, clk_tout); + bcm2708_wr(bi, BSC_DIV, cdiv); + bcm2708_wr(bi, BSC_A, bi->msg->addr); + bcm2708_wr(bi, BSC_DLEN, bi->msg->len); @@ -100464,7 +100858,10 @@ index 0000000..85f411c + struct bcm2708_i2c *bi; + struct i2c_adapter *adap; + unsigned long bus_hz; -+ u32 cdiv; ++ u32 cdiv, clk_tout; ++ u32 baud; ++ ++ baud = CONFIG_I2C_BCM2708_BAUDRATE; + + if (pdev->dev.of_node) { + u32 bus_clk_rate; @@ -100475,12 +100872,15 @@ index 0000000..85f411c + } + if (!of_property_read_u32(pdev->dev.of_node, + "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; ++ baud = bus_clk_rate; + else + dev_warn(&pdev->dev, + "Could not read clock-frequency property\n"); + } + ++ if (baudrate) ++ baud = baudrate; ++ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "could not get IO memory\n"); @@ -100564,15 +100964,21 @@ index 0000000..85f411c + } + + bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; ++ cdiv = bus_hz / baud; + if (cdiv > 0xffff) { + cdiv = 0xffff; -+ baudrate = bus_hz / cdiv; ++ baud = bus_hz / cdiv; + } ++ ++ clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs. ++ if (clk_tout > 0xffff) ++ clk_tout = 0xffff; ++ + bi->cdiv = cdiv; ++ bi->clk_tout = clk_tout; + + dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -+ pdev->id, (unsigned long)regs->start, irq, baudrate); ++ pdev->id, (unsigned long)regs->start, irq, baud); + + return 0; + @@ -100644,10 +101050,10 @@ index 0000000..85f411c +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From 3c15dbca1ea1cf9b6843cb55e2fd01d4701ef874 Mon Sep 17 00:00:00 2001 +From ee6a578174b8f43710c3d897c1b3c74d31b99466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:27:06 +0200 -Subject: [PATCH 046/251] char: broadcom: Add vcio module +Subject: [PATCH 047/114] char: broadcom: Add vcio module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100873,10 +101279,10 @@ index 0000000..c19bc20 +MODULE_DESCRIPTION("Mailbox userspace access"); +MODULE_LICENSE("GPL"); -From 8481c7c7094e5395ab47c8ecc6c7c12d654baf5a Mon Sep 17 00:00:00 2001 +From 44bce7a87a61fc4a18a9b65c9dc1ecfcdc53351d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:25:01 +0200 -Subject: [PATCH 047/251] firmware: bcm2835: Support ARCH_BCM270x +Subject: [PATCH 048/114] firmware: bcm2835: Support ARCH_BCM270x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -100982,10 +101388,10 @@ index dd506cd..b980d53 100644 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -From 7e74c5de1a6c613a28ee5a5cc871661ceadd0fcd Mon Sep 17 00:00:00 2001 +From 9c0359b11195a31b974f7b893d9f7c0088816c8c Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 048/251] bcm2835: add v4l2 camera device +Subject: [PATCH 049/114] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -101262,13 +101668,19 @@ are now returned as they are being flushed on stop_streaming. squash: Fixup bcm2835-camera for changes in kernel 4.4 api + +v4l2: Fix up driver to upstream timestamp changes + +bcm2835-camera: fix a bug in computation of frame timestamp + +Fixes #1318 --- Documentation/video4linux/bcm2835-v4l2.txt | 60 + drivers/media/platform/Kconfig | 2 + drivers/media/platform/Makefile | 2 + drivers/media/platform/bcm2835/Kconfig | 25 + drivers/media/platform/bcm2835/Makefile | 5 + - drivers/media/platform/bcm2835/bcm2835-camera.c | 1844 +++++++++++++++++++++ + drivers/media/platform/bcm2835/bcm2835-camera.c | 1845 +++++++++++++++++++++ drivers/media/platform/bcm2835/bcm2835-camera.h | 126 ++ drivers/media/platform/bcm2835/controls.c | 1324 +++++++++++++++ drivers/media/platform/bcm2835/mmal-common.h | 53 + @@ -101280,7 +101692,7 @@ squash: Fixup bcm2835-camera for changes in kernel 4.4 api drivers/media/platform/bcm2835/mmal-parameters.h | 656 ++++++++ drivers/media/platform/bcm2835/mmal-vchiq.c | 1916 ++++++++++++++++++++++ drivers/media/platform/bcm2835/mmal-vchiq.h | 178 ++ - 17 files changed, 6960 insertions(+) + 17 files changed, 6961 insertions(+) create mode 100644 Documentation/video4linux/bcm2835-v4l2.txt create mode 100644 drivers/media/platform/bcm2835/Kconfig create mode 100644 drivers/media/platform/bcm2835/Makefile @@ -101364,7 +101776,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index ccbc974..63c9715 100644 +index 201f5c2..b798ab8 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -101377,7 +101789,7 @@ index ccbc974..63c9715 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index efa0295..8c0b3b5 100644 +index bbb7bd1..6fe5b3f 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -101386,9 +101798,9 @@ index efa0295..8c0b3b5 100644 +obj-$(CONFIG_VIDEO_BCM2835) += bcm2835/ + - obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o + obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig new file mode 100644 index 0000000..99a5cbc @@ -101433,10 +101845,10 @@ index 0000000..f17c79c +ccflags-$(CONFIG_VIDEO_BCM2835) += -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c new file mode 100644 -index 0000000..e83334c +index 0000000..fbf89a2 --- /dev/null +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -0,0 +1,1844 @@ +@@ -0,0 +1,1845 @@ +/* + * Broadcom BM2835 V4L2 driver + * @@ -101791,6 +102203,7 @@ index 0000000..e83334c + if (dev->capture.frame_count) { + if (dev->capture.vc_start_timestamp != -1 && + pts != 0) { ++ struct timeval timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; + u32 div = 0; @@ -101798,16 +102211,15 @@ index 0000000..e83334c + + div = + div_u64_rem(runtime_us, USEC_PER_SEC, &rem); -+ buf->vb.timestamp.tv_sec = -+ dev->capture.kernel_start_ts.tv_sec - 1 + -+ div; -+ buf->vb.timestamp.tv_usec = ++ timestamp.tv_sec = ++ dev->capture.kernel_start_ts.tv_sec + div; ++ timestamp.tv_usec = + dev->capture.kernel_start_ts.tv_usec + rem; + -+ if (buf->vb.timestamp.tv_usec >= ++ if (timestamp.tv_usec >= + USEC_PER_SEC) { -+ buf->vb.timestamp.tv_sec++; -+ buf->vb.timestamp.tv_usec -= ++ timestamp.tv_sec++; ++ timestamp.tv_usec -= + USEC_PER_SEC; + } + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, @@ -101818,11 +102230,12 @@ index 0000000..e83334c + (int)dev->capture.kernel_start_ts. + tv_usec, + dev->capture.vc_start_timestamp, pts, -+ (int)buf->vb.timestamp.tv_sec, -+ (int)buf->vb.timestamp. -+ tv_usec); ++ (int)timestamp.tv_sec, ++ (int)timestamp.tv_usec); ++ buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + ++ timestamp.tv_usec * 1000ULL; + } else { -+ v4l2_get_timestamp(&buf->vb.timestamp); ++ buf->vb.vb2_buf.timestamp = ktime_get_ns(); + } + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); @@ -106265,7 +106678,7 @@ index 0000000..aa0fd18 +}; diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c new file mode 100644 -index 0000000..7813225 +index 0000000..78132254 --- /dev/null +++ b/drivers/media/platform/bcm2835/mmal-vchiq.c @@ -0,0 +1,1916 @@ @@ -108370,10 +108783,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 2a1cb83a705ce839581fbabeb9a8db3dad478ccf Mon Sep 17 00:00:00 2001 +From 9889d89cb74b96f8bbaff5a7c451e262af26fbb9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 049/251] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 050/114] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -108838,20 +109251,20 @@ index 0000000..3998d43 + return (($val eq 'y') || ($val eq '1')); +} -From 3c9e2867950ad9a36623e07c2d1641445bab50dd Mon Sep 17 00:00:00 2001 +From c962a4d9204d97b1b62ab32f274c22bac54ad8d5 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 050/251] fdt: Add support for the CONFIG_CMDLINE_EXTEND option +Subject: [PATCH 051/114] fdt: Add support for the CONFIG_CMDLINE_EXTEND option --- drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 655f79d..fdc4501 100644 +index 3349d2a..1e26605 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c -@@ -954,19 +954,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, +@@ -960,19 +960,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, /* Retrieve command line */ p = of_get_flat_dt_prop(node, "bootargs", &l); @@ -108896,10 +109309,10 @@ index 655f79d..fdc4501 100644 pr_debug("Command line is: %s\n", (char*)data); -From 336ecbfbddc122378578b727f46bfe71858aaa05 Mon Sep 17 00:00:00 2001 +From 829ab8a2cb98b039ceba5b4407522442ef629ba0 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 051/251] BCM2708: Add core Device Tree support +Subject: [PATCH 052/114] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -108965,62 +109378,89 @@ squash: Add cprman to dt BCM270X_DT: Use clk_core for I2C interfaces --- - arch/arm/boot/dts/Makefile | 30 + - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 145 +++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 135 +++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 102 ++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 40 ++ - arch/arm/boot/dts/bcm2708.dtsi | 40 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 347 +++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 145 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 102 ++++ - arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 +++ - arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + - arch/arm/boot/dts/overlays/Makefile | 69 +++ - arch/arm/boot/dts/overlays/README | 648 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 +++ - .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + - arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 ++ - .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 ++ - .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ - .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 +++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 55 ++ - arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + - arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 69 +++ - arch/arm/boot/dts/overlays/mmc-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 111 ++++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 +++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 ++++ - arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 46 ++ - arch/arm/boot/dts/overlays/pwm-overlay.dts | 42 ++ - arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++ - arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 +++ - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + - arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 29 + - arch/arm/boot/dts/overlays/sdio-overlay.dts | 32 + - arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + - arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 +++ - arch/arm/boot/dts/overlays/smi-overlay.dts | 37 ++ - .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++ - arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 ++ - arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ - .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - 55 files changed, 4203 insertions(+) + arch/arm/boot/dts/Makefile | 31 + + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 150 +++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 140 +++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 102 ++ + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 52 + + arch/arm/boot/dts/bcm2708.dtsi | 40 + + arch/arm/boot/dts/bcm2708_common.dtsi | 379 ++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 150 +++ + arch/arm/boot/dts/bcm2709.dtsi | 102 ++ + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 197 ++++ + arch/arm/boot/dts/bcm2710.dtsi | 102 ++ + arch/arm/boot/dts/bcm2835-rpi-cm.dts | 93 ++ + arch/arm/boot/dts/bcm2835-rpi-cm.dtsi | 30 + + arch/arm/boot/dts/overlays/Makefile | 88 ++ + arch/arm/boot/dts/overlays/README | 1014 ++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 89 ++ + arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 57 ++ + .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 + + arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 20 + + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 29 + + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 53 + + arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 45 + + .../boot/dts/overlays/gpio-poweroff-overlay.dts | 34 + + .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 + + .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 + + .../dts/overlays/hifiberry-dacplus-overlay.dts | 54 ++ + .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 + + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 93 ++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 148 +++ + arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 28 + + .../boot/dts/overlays/i2c-mux-pca9548a-overlay.dts | 67 ++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 63 ++ + .../arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 36 + + .../arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 37 + + arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 + + .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 43 + + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 ++ + .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 73 ++ + .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 73 ++ + arch/arm/boot/dts/overlays/mmc-overlay.dts | 38 + + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 117 +++ + arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 27 + + .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 46 + + .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 64 ++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 102 ++ + arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 106 ++ + .../dts/overlays/pitft28-capacitive-overlay.dts | 91 ++ + .../dts/overlays/pitft28-resistive-overlay.dts | 121 +++ + arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 + + arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 53 + + arch/arm/boot/dts/overlays/pwm-overlay.dts | 49 + + arch/arm/boot/dts/overlays/qca7000-overlay.dts | 52 + + arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 + + .../boot/dts/overlays/rpi-backlight-overlay.dts | 21 + + arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 + + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 89 ++ + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 17 + + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 + + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 47 + + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 32 + + arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts | 36 + + arch/arm/boot/dts/overlays/sdio-overlay.dts | 36 + + arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 23 + + arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 + + arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/smi-overlay.dts | 37 + + .../boot/dts/overlays/spi-gpio35-39-overlay.dts | 31 + + arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 57 ++ + arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 81 ++ + arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 57 ++ + arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 69 ++ + arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 81 ++ + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 222 +++++ + arch/arm/boot/dts/overlays/uart1-overlay.dts | 38 + + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 95 ++ + arch/arm/boot/dts/overlays/vga666-overlay.dts | 30 + + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 + + .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 + + arch/arm/boot/dts/overlays/wittypi-overlay.dts | 44 + + 82 files changed, 6392 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -109029,14 +109469,20 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b.dts + create mode 100644 arch/arm/boot/dts/bcm2710.dtsi create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dts create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm.dtsi create mode 100644 arch/arm/boot/dts/overlays/Makefile create mode 100644 arch/arm/boot/dts/overlays/README create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dwc-otg-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dwc2-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts @@ -109044,7 +109490,11 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts @@ -109053,34 +109503,51 @@ BCM270X_DT: Use clk_core for I2C interfaces create mode 100644 arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/pwm-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/qca7000-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/rpi-sense-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/uart1-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/vga666-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/wittypi-overlay.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 30bbc37..d583e67 100644 +index 95c1923..a4db123 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,25 @@ +@@ -1,5 +1,26 @@ ifeq ($(CONFIG_OF),y) +dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-b.dtb @@ -109088,6 +109555,7 @@ index 30bbc37..d583e67 100644 +dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-cm.dtb +dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb +dtb-$(CONFIG_ARCH_BCM2709) += bcm2709-rpi-2-b.dtb ++dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb + +# Raspberry Pi +ifeq ($(CONFIG_ARCH_BCM2708),y) @@ -109105,8 +109573,8 @@ index 30bbc37..d583e67 100644 + dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb - dtb-$(CONFIG_MACH_ASM9260) += \ -@@ -777,10 +797,20 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + dtb-$(CONFIG_MACH_ARTPEC6) += \ +@@ -839,10 +860,20 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb @@ -109129,10 +109597,10 @@ index 30bbc37..d583e67 100644 +endif diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts new file mode 100644 -index 0000000..2e4df17 +index 0000000..0e9a22d --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,145 @@ +@@ -0,0 +1,150 @@ +/dts-v1/; + +#include "bcm2708.dtsi" @@ -109194,7 +109662,7 @@ index 0000000..2e4df17 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109202,7 +109670,7 @@ index 0000000..2e4df17 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109255,6 +109723,7 @@ index 0000000..2e4df17 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109276,14 +109745,18 @@ index 0000000..2e4df17 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts new file mode 100644 -index 0000000..0445b46 +index 0000000..a60342c --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,135 @@ +@@ -0,0 +1,140 @@ +/dts-v1/; + +#include "bcm2708.dtsi" @@ -109345,7 +109818,7 @@ index 0000000..0445b46 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109353,7 +109826,7 @@ index 0000000..0445b46 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109400,6 +109873,7 @@ index 0000000..0445b46 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109417,11 +109891,15 @@ index 0000000..0445b46 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts new file mode 100755 -index 0000000..87c1a54 +index 0000000..cd0e1ac --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts @@ -0,0 +1,102 @@ @@ -109469,7 +109947,7 @@ index 0000000..87c1a54 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -109477,7 +109955,7 @@ index 0000000..87c1a54 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -109516,6 +109994,7 @@ index 0000000..87c1a54 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -109524,15 +110003,14 @@ index 0000000..87c1a54 + i2c0_baudrate = <&i2c0>,"clock-frequency:0"; + i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi new file mode 100644 -index 0000000..3c8bdde +index 0000000..90e330d --- /dev/null +++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,40 @@ +@@ -0,0 +1,52 @@ +#include "bcm2708.dtsi" + +&gpio { @@ -109542,6 +110020,13 @@ index 0000000..3c8bdde + }; +}; + ++&gpio { ++ mmc_pins: mmc_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <7>; /* alt3 */ ++ }; ++}; ++ +&leds { + act_led: act { + label = "led0"; @@ -109550,12 +110035,14 @@ index 0000000..3c8bdde + }; +}; + -+&sdhost { ++ ++&mmc { + pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ bus-width = <4>; ++ pinctrl-0 = <&mmc_pins>; + non-removable; ++ bus-width = <4>; + status = "okay"; ++ brcm,overclock-50 = <0>; +}; + +&fb { @@ -109564,6 +110051,8 @@ index 0000000..3c8bdde + +/ { + __overrides__ { ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; @@ -109571,6 +110060,7 @@ index 0000000..3c8bdde + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&mmc>,"brcm,overclock-50:0"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi @@ -109621,10 +110111,11 @@ index 0000000..f5a44cd +}; diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi new file mode 100644 -index 0000000..75fb4ce +index 0000000..e0be77a --- /dev/null +++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,347 @@ +@@ -0,0 +1,379 @@ ++#include +#include "skeleton.dtsi" + +/ { @@ -109632,6 +110123,7 @@ index 0000000..75fb4ce + + aliases { + audio = &audio; ++ aux = &aux; + sound = &sound; + soc = &soc; + dma = &dma; @@ -109646,6 +110138,8 @@ index 0000000..75fb4ce + spi0 = &spi0; + i2c0 = &i2c0; + uart1 = &uart1; ++ spi1 = &spi1; ++ spi2 = &spi2; + mmc = &mmc; + i2c1 = &i2c1; + i2c2 = &i2c2; @@ -109759,9 +110253,9 @@ index 0000000..75fb4ce + reg = <0x7e202000 0x100>; + interrupts = <2 24>; + clocks = <&clk_core>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; ++ dmas = <&dma 13>; ++ dma-names = "rx-tx"; ++ brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; + status = "disabled"; + }; @@ -109812,6 +110306,14 @@ index 0000000..75fb4ce + status = "disabled"; + }; + ++ aux: aux@0x7e215004 { ++ compatible = "brcm,bcm2835-aux"; ++ #clock-cells = <1>; ++ reg = <0x7e215000 0x8>; ++ clocks = <&clk_core>; ++ status = "disabled"; ++ }; ++ + uart1: uart@7e215040 { + compatible = "brcm,bcm2835-aux-uart", "ns16550"; + reg = <0x7e215040 0x40>; @@ -109820,16 +110322,36 @@ index 0000000..75fb4ce + reg-shift = <2>; + no-loopback-test; + status = "disabled"; -+ }; ++ }; ++ ++ spi1: spi@7e215080 { ++ compatible = "brcm,bcm2835-aux-spi"; ++ reg = <0x7e215080 0x40>, <0x7e215000 0x8>; ++ interrupts = <1 29>; ++ clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi2: spi@7e2150C0 { ++ compatible = "brcm,bcm2835-aux-spi"; ++ reg = <0x7e2150C0 0x40>, <0x7e215000 0x8>; ++ interrupts = <1 29>; ++ clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; + + mmc: mmc@7e300000 { + compatible = "brcm,bcm2835-mmc"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; ++ dmas = <&dma 11>; ++ dma-names = "rx-tx"; ++ brcm,overclock-50 = <0>; + status = "disabled"; + }; + @@ -109974,10 +110496,10 @@ index 0000000..75fb4ce +}; diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..5206ba2 +index 0000000..9176d57 --- /dev/null +++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,145 @@ +@@ -0,0 +1,150 @@ +/dts-v1/; + +#include "bcm2709.dtsi" @@ -110039,7 +110561,7 @@ index 0000000..5206ba2 + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; + cs-gpios = <&gpio 8 1>, <&gpio 7 1>; + -+ spidev@0{ ++ spidev0: spidev@0{ + compatible = "spidev"; + reg = <0>; /* CE0 */ + #address-cells = <1>; @@ -110047,7 +110569,7 @@ index 0000000..5206ba2 + spi-max-frequency = <500000>; + }; + -+ spidev@1{ ++ spidev1: spidev@1{ + compatible = "spidev"; + reg = <1>; /* CE1 */ + #address-cells = <1>; @@ -110100,6 +110622,7 @@ index 0000000..5206ba2 + __overrides__ { + uart0 = <&uart0>,"status"; + uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; @@ -110121,6 +110644,10 @@ index 0000000..5206ba2 + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi @@ -110231,6 +110758,317 @@ index 0000000..a8cfd7c + interrupt-parent = <&local_intc>; + interrupts = <8>; +}; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +new file mode 100644 +index 0000000..adba682 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -0,0 +1,197 @@ ++/dts-v1/; ++ ++#include "bcm2710.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2710","brcm,bcm2709"; ++ model = "Raspberry Pi 3 Model B"; ++}; ++ ++&gpio { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <7>; // alt3 = SD1 ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = <43>; ++ brcm,function = <4>; /* alt0:GPCLK2 */ ++ brcm,pull = <0>; ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <32 33>; ++ brcm,function = <7>; /* alt3=UART0 */ ++ brcm,pull = <0 2>; ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++}; ++ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <4>; ++ status = "okay"; ++ brcm,overclock-50 = <0>; ++}; ++ ++&soc { ++ virtgpio: virtgpio { ++ compatible = "brcm,bcm2835-virtgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&random { ++ status = "okay"; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&virtgpio 0 0>; ++ }; ++}; ++ ++/ { ++ chosen { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ uart1 = <&uart1>,"status"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ core_freq = <&clk_core>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi +new file mode 100644 +index 0000000..1a48686 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -0,0 +1,102 @@ ++#include "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2710","brcm,bcm2709"; ++ model = "BCM2710"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x3f000000 0x01000000>, ++ <0x40000000 0x40000000 0x00040000>; ++ ++ 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>; ++ }; ++ ++ gpiomem { ++ compatible = "brcm,bcm2835-gpiomem"; ++ reg = <0x7e200000 0x1000>; ++ status = "okay"; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ clock-frequency = <19200000>; ++ interrupt-parent = <&local_intc>; ++ interrupts = <0>, // PHYS_SECURE_PPI ++ <1>, // PHYS_NONSECURE_PPI ++ <3>, // VIRT_PPI ++ <2>; // HYP_PPI ++ always-on; ++ }; ++ ++ syscon@40000000 { ++ compatible = "brcm,bcm2836-arm-local", "syscon"; ++ reg = <0x40000000 0x100>; ++ }; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ v7_cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x000>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x001>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x002>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x003>; ++ clock-frequency = <800000000>; ++ }; ++ }; ++ ++ __overrides__ { ++ arm_freq = <&v7_cpu0>, "clock-frequency:0", ++ <&v7_cpu1>, "clock-frequency:0", ++ <&v7_cpu2>, "clock-frequency:0", ++ <&v7_cpu3>, "clock-frequency:0"; ++ }; ++}; ++ ++&watchdog { ++ status = "okay"; ++}; ++ ++&intc { ++ compatible = "brcm,bcm2836-armctrl-ic"; ++ interrupt-parent = <&local_intc>; ++ interrupts = <8>; ++}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm.dts b/arch/arm/boot/dts/bcm2835-rpi-cm.dts new file mode 100644 index 0000000..c6e6860 @@ -110368,10 +111206,10 @@ index 0000000..9c4000f +}; diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile new file mode 100644 -index 0000000..d8c2771 +index 0000000..7c4fc30 --- /dev/null +++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,69 @@ +@@ -0,0 +1,88 @@ +ifeq ($(CONFIG_OF),y) + +# Overlays for the Raspberry Pi platform @@ -110386,67 +111224,86 @@ index 0000000..d8c2771 + RPI_DT_OVERLAYS=y +endif + -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb ++dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += enc28j60.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += gpio-ir.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += gpio-poweroff.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dacplus.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += lirc-rpi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-act-led.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += piscreen2r.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pitft28-capacitive.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += qca7000.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-display.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-ft5406.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-proto.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += rpi-sense.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdhost.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += sdtweak.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi-dev.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi-nand.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += smi.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-1cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-2cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi1-3cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-1cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-2cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi2-3cs.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += spi-gpio35-39.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += tinylcd35.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += uart1.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += wittypi.dtbo + +targets += dtbs dtbs_install -+targets += $(dtb-y) ++targets += $(dtbo-y) + +endif + -+always := $(dtb-y) -+clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif ++always := $(dtbo-y) ++clean-files := *.dtbo diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README new file mode 100644 -index 0000000..268d400 +index 0000000..e88e7c8 --- /dev/null +++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,648 @@ +@@ -0,0 +1,1014 @@ +Introduction +============ + @@ -110502,8 +111359,8 @@ index 0000000..268d400 +Using Overlays +============== + -+Overlays are loaded using the "dtoverlay" directive. As an example, consider the -+popular lirc-rpi module, the Linux Infrared Remote Control driver. In the ++Overlays are loaded using the "dtoverlay" directive. As an example, consider ++the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the +pre-DT world this would be loaded from /etc/modules, with an explicit +"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, +this becomes a line in config.txt: @@ -110518,71 +111375,87 @@ index 0000000..268d400 + +Parameters always have default values, although in some cases (e.g. "w1-gpio") +it is necessary to provided multiple overlays in order to get the desired -+behaviour. See the list of overlays below for a description of the parameters and their defaults. ++behaviour. See the list of overlays below for a description of the parameters ++and their defaults. + +The Overlay and Parameter Reference +=================================== + -+N.B. When editing this file, please preserve the indentation levels to make it simple to parse -+programmatically. NO HARD TABS. ++N.B. When editing this file, please preserve the indentation levels to make it ++simple to parse programmatically. NO HARD TABS. + + +Name: +Info: Configures the base Raspberry Pi hardware +Load: +Params: -+ audio Set to "on" to enable the onboard ALSA audio -+ interface (default "off") ++ audio Set to "on" to enable the onboard ALSA audio ++ interface (default "off") + -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") ++ i2c_arm Set to "on" to enable the ARM's i2c interface ++ (default "off") + -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") ++ i2c_vc Set to "on" to enable the i2c interface ++ usually reserved for the VideoCore processor ++ (default "off") + -+ i2c An alias for i2c_arm ++ i2c An alias for i2c_arm + -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") ++ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface ++ (default "100000") + -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") ++ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface ++ (default "100000") + -+ i2c_baudrate An alias for i2c_arm_baudrate ++ i2c_baudrate An alias for i2c_arm_baudrate + -+ i2s Set to "on" to enable the i2s interface -+ (default "off") ++ i2s Set to "on" to enable the i2s interface ++ (default "off") + -+ spi Set to "on" to enable the spi interfaces -+ (default "off") ++ spi Set to "on" to enable the spi interfaces ++ (default "off") + -+ random Set to "on" to enable the hardware random -+ number generator (default "on") ++ random Set to "on" to enable the hardware random ++ number generator (default "on") + -+ uart0 Set to "off" to disable uart0 (default "on") ++ sd_overclock Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ watchdog Set to "on" to enable the hardware watchdog -+ (default "off") ++ sd_force_pio Disable DMA support for SD driver (default off) + -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") ++ sd_pio_limit Number of blocks above which to use DMA for ++ SD card (default 1) + -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") ++ sd_debug Enable debug output from SD driver (default off) + -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) ++ uart0 Set to "off" to disable uart0 (default "on") ++ ++ uart1 Set to "on" or "off" to enable or disable uart1 ++ (default varies) ++ ++ watchdog Set to "on" to enable the hardware watchdog ++ (default "off") ++ ++ act_led_trigger Choose which activity the LED tracks. ++ Use "heartbeat" for a nice load indicator. ++ (default "mmc") ++ ++ act_led_activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ N.B. For Pi3 see pi3-act-led overlay. ++ ++ act_led_gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ (default "16" on a non-Plus board, "47" on a ++ Plus or Pi 2) ++ N.B. For Pi3 see pi3-act-led overlay. + + pwr_led_trigger + pwr_led_activelow + pwr_led_gpio -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. ++ As for act_led_*, but using the PWR LED. ++ Not available on Model A/B boards. + + N.B. It is recommended to only enable those interfaces that are needed. + Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc @@ -110597,19 +111470,19 @@ index 0000000..268d400 +Name: ads7846 +Info: ADS7846 Touch controller +Load: dtoverlay=ads7846,= -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) ++Params: cs SPI bus Chip Select (default 1) ++ speed SPI bus speed (default 2MHz, max 3.25MHz) ++ penirq GPIO used for PENIRQ. REQUIRED ++ penirq_pull Set GPIO pull (default 0=none, 2=pullup) ++ swapxy Swap x and y axis ++ xmin Minimum value on the X axis (default 0) ++ ymin Minimum value on the Y axis (default 0) ++ xmax Maximum value on the X axis (default 4095) ++ ymax Maximum value on the Y axis (default 4095) ++ pmin Minimum reported pressure value (default 0) ++ pmax Maximum reported pressure value (default 65535) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ (default 400) + + penirq is required and usually xohms (60-100) has to be set as well. + Apart from that, pmax (255) and swapxy are also common. @@ -110619,6 +111492,18 @@ index 0000000..268d400 + www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt + + ++Name: at86rf233 ++Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, ++ connected to spi0.0 ++Load: dtoverlay=at86rf233,= ++Params: interrupt GPIO used for INT (default 23) ++ reset GPIO used for Reset (default 24) ++ sleep GPIO used for Sleep (default 25) ++ speed SPI bus speed in Hz (default 3000000) ++ trim Fine tuning of the internal capacitance ++ arrays (0=+0pF, 15=+4.5pF, default 15) ++ ++ +Name: bmp085_i2c-sensor +Info: Configures the BMP085/BMP180 digital barometric pressure and temperature + sensors from Bosch Sensortec @@ -110630,8 +111515,29 @@ index 0000000..268d400 +Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors + Also sometimes found with the part number(s) AM230x. +Load: dtoverlay=dht11,= -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) ++Params: gpiopin GPIO connected to the sensor's DATA output. ++ (default 4) ++ ++ ++Name: dwc-otg ++Info: Selects the dwc_otg USB controller driver which has fiq support. This ++ is the default on all except the Pi Zero which defaults to dwc2. ++Load: dtoverlay=dwc-otg ++Params: ++ ++ ++Name: dwc2 ++Info: Selects the dwc2 USB controller driver ++Load: dtoverlay=dwc2,= ++Params: dr_mode Dual role mode: "host", "peripheral" or "otg" ++ ++ g-rx-fifo-size Size of rx fifo size in gadget mode ++ ++ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget ++ mode ++ ++ g-tx-fifo-size Size of periodic tx fifo per endpoint ++ (except ep0) in gadget mode + + +[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] @@ -110640,22 +111546,38 @@ index 0000000..268d400 +Name: enc28j60 +Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) +Load: dtoverlay=enc28j60,= -+Params: int_pin GPIO used for INT (default 25) ++Params: int_pin GPIO used for INT (default 25) + -+ speed SPI bus speed (default 12000000) ++ speed SPI bus speed (default 12000000) ++ ++ ++Name: gpio-ir ++Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- ++ based gpio_ir_recv driver maps received keys directly to a ++ /dev/input/event* device, all decoding is done by the kernel - LIRC is ++ not required! The key mapping and other decoding parameters can be ++ configured by "ir-keytable" tool. ++Load: dtoverlay=gpio-ir,= ++Params: gpio_pin Input pin number. Default is 18. ++ ++ gpio_pull Desired pull-up/down state (off, down, up) ++ Default is "down". ++ ++ rc-map-name Default rc keymap (can also be changed by ++ ir-keytable), defaults to "rc-rc6-mce" + + +Name: gpio-poweroff +Info: Drives a GPIO high or low on reboot +Load: dtoverlay=gpio-poweroff,= -+Params: gpiopin GPIO for signalling (default 26) ++Params: gpiopin GPIO for signalling (default 26) + -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. ++ active_low Set if the power control device requires a ++ high->low transition to trigger a power-down. ++ Note that this will require the support of a ++ custom dt-blob.bin to prevent a power-down ++ during the boot process, and that a reboot ++ will also cause the pin to go low. + + +Name: hifiberry-amp @@ -110672,8 +111594,21 @@ index 0000000..268d400 + +Name: hifiberry-dacplus +Info: Configures the HifiBerry DAC+ audio card -+Load: dtoverlay=hifiberry-dacplus -+Params: ++Load: dtoverlay=hifiberry-dacplus,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24dB_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) + + +Name: hifiberry-digi @@ -110686,54 +111621,91 @@ index 0000000..268d400 +Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28a,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + -+ resetgpio GPIO used to reset controller ++ resetgpio GPIO used to reset controller + -+ ledgpio GPIO used to control backlight ++ ledgpio GPIO used to control backlight + + +Name: hy28b +Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics + Default values match Texy's display shield +Load: dtoverlay=hy28b,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + -+ resetgpio GPIO used to reset controller ++ resetgpio GPIO used to reset controller + -+ ledgpio GPIO used to control backlight ++ ledgpio GPIO used to control backlight ++ ++ ++Name: i2c-gpio ++Info: Adds support for software i2c controller on gpio pins ++Load: dtoverlay=i2c-gpio,= ++Params: i2c_gpio_sda GPIO used for I2C data (default "23") ++ ++ i2c_gpio_scl GPIO used for I2C clock (default "24") ++ ++ i2c_gpio_delay_us Clock delay in microseconds ++ (default "2" = ~100kHz) ++ ++ ++Name: i2c-mux-pca9548a ++Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm ++Load: dtoverlay=i2c-mux-pca9548a,= ++Params: addr I2C address of PCA9548A (default 0x70) + + +Name: i2c-rtc +Info: Adds support for a number of I2C Real Time Clock devices -+Load: dtoverlay=i2c-rtc, -+Params: ds1307 Select the DS1307 device ++Load: dtoverlay=i2c-rtc,= ++Params: ds1307 Select the DS1307 device + -+ ds3231 Select the DS3231 device ++ ds1339 Select the DS1339 device + -+ mcp7941x Select the MCP7941x device ++ ds3231 Select the DS3231 device + -+ pcf2127 Select the PCF2127 device ++ mcp7941x Select the MCP7941x device + -+ pcf8523 Select the PCF8523 device ++ pcf2127 Select the PCF2127 device + -+ pcf8563 Select the PCF8563 device ++ pcf8523 Select the PCF8523 device ++ ++ pcf8563 Select the PCF8563 device ++ ++ trickle-resistor-ohms Resistor value for trickle charge (DS1339-only) ++ ++ ++Name: i2c0-bcm2708 ++Info: Enable the i2c_bcm2708 driver for the i2c0 bus ++Load: dtoverlay=i2c0-bcm2708,= ++Params: sda0_pin GPIO pin for SDA0 (0, 28 [or 44] - default 0) ++ scl0_pin GPIO pin for SCL0 (1, 29 [or 45] - default 1) ++ ++ ++Name: i2c1-bcm2708 ++Info: Enable the i2c_bcm2708 driver for the i2c1 bus ++Load: dtoverlay=i2c1-bcm2708,= ++Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) ++ scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) ++ pin_func Alternative pin function (4 (alt0), 6 (alt2) - ++ default 4) + + +Name: i2s-mmap @@ -110750,78 +111722,90 @@ index 0000000..268d400 + +Name: iqaudio-dacplus +Info: Configures the IQaudio DAC+ audio card -+Load: dtoverlay=iqaudio-dacplus -+Params: ++Load: dtoverlay=iqaudio-dacplus,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=iqaudio-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24db_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) + + +Name: lirc-rpi +Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) + Consult the module documentation for more details. -+Load: dtoverlay=lirc-rpi,=,... -+Params: gpio_out_pin GPIO for output (default "17") ++Load: dtoverlay=lirc-rpi,= ++Params: gpio_out_pin GPIO for output (default "17") + -+ gpio_in_pin GPIO for input (default "18") ++ gpio_in_pin GPIO for input (default "18") + -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") ++ gpio_in_pull Pull up/down/off on the input pin ++ (default "down") + -+ sense Override the IR receive auto-detection logic: -+ "0" = force active-high -+ "1" = force active-low -+ "-1" = use auto-detection -+ (default "-1") ++ sense Override the IR receive auto-detection logic: ++ "0" = force active-high ++ "1" = force active-low ++ "-1" = use auto-detection ++ (default "-1") + -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") ++ softcarrier Turn the software carrier "on" or "off" ++ (default "on") + -+ invert "on" = invert the output pin (default "off") ++ invert "on" = invert the output pin (default "off") + -+ debug "on" = enable additional debug messages -+ (default "off") ++ debug "on" = enable additional debug messages ++ (default "off") + + +Name: mcp2515-can0 +Info: Configures the MCP2515 CAN controller on spi0.0 +Load: dtoverlay=mcp2515-can0,= -+Params: oscillator Clock frequency for the CAN controller (Hz) ++Params: oscillator Clock frequency for the CAN controller (Hz) + -+ spimaxfrequency Maximum SPI frequence (Hz) ++ spimaxfrequency Maximum SPI frequence (Hz) + -+ interrupt GPIO for interrupt signal ++ interrupt GPIO for interrupt signal + + +Name: mcp2515-can1 +Info: Configures the MCP2515 CAN controller on spi0.1 +Load: dtoverlay=mcp2515-can1,= -+Params: oscillator Clock frequency for the CAN controller (Hz) ++Params: oscillator Clock frequency for the CAN controller (Hz) + -+ spimaxfrequency Maximum SPI frequence (Hz) ++ spimaxfrequency Maximum SPI frequence (Hz) + -+ interrupt GPIO for interrupt signal ++ interrupt GPIO for interrupt signal + + +Name: mmc +Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock +Load: dtoverlay=mmc,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz + + +Name: mz61581 +Info: MZ61581 display by Tontec +Load: dtoverlay=mz61581,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ txbuflen Transmit buffer length (default 32768) ++ txbuflen Transmit buffer length (default 32768) + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) + + +[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] @@ -110833,36 +111817,109 @@ index 0000000..268d400 +[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] + + ++Name: pi3-act-led ++Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed ++ from the VPU. There is a special driver for this with a separate DT ++ node, which has the unfortunate consequence of breaking the ++ act_led_gpio and act_led_activelow dtparams. ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++Load: dtoverlay=pi3-act-led,= ++Params: activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ ++ gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ REQUIRED ++ ++ ++Name: pi3-disable-bt ++Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 ++ N.B. To disable the systemd service that initialises the modem so it ++ doesn't use the UART, use 'sudo systemctl disable hciuart'. ++Load: dtoverlay=pi3-disable-bt ++Params: ++ ++ ++Name: pi3-miniuart-bt ++Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore ++ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum ++ usable baudrate. ++ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service ++ and replace ttyAMA0 with ttyS0, unless you have a system with udev rules ++ that create /dev/serial0 and /dev/serial1, in which case use ++ /dev/serial1 instead because it will always be correct. ++Load: dtoverlay=pi3-miniuart-bt ++Params: ++ ++ +Name: piscreen +Info: PiScreen display by OzzMaker.com +Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ xohms Touchpanel sensitivity (X-plate resistance) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: piscreen2r ++Info: PiScreen 2 with resistive TP display by OzzMaker.com ++Load: dtoverlay=piscreen2r,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: pitft28-capacitive ++Info: Adafruit PiTFT 2.8" capacitive touch screen ++Load: dtoverlay=pitft28-capacitive,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ touch-sizex Touchscreen size x (default 240) ++ ++ touch-sizey Touchscreen size y (default 320) ++ ++ touch-invx Touchscreen inverted x axis ++ ++ touch-invy Touchscreen inverted y axis ++ ++ touch-swapxy Touchscreen swapped x y axis + + +Name: pitft28-resistive +Info: Adafruit PiTFT 2.8" resistive touch screen +Load: dtoverlay=pitft28-resistive,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + + +Name: pps-gpio +Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). +Load: dtoverlay=pps-gpio,= -+Params: gpiopin Input GPIO (default "18") ++Params: gpiopin Input GPIO (default "18") + + +Name: pwm @@ -110879,9 +111936,9 @@ index 0000000..268d400 + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm,= -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) ++Params: pin Output pin (default 18) - see table ++ func Pin function (default 2 = Alt5) - see above ++ clock PWM clock frequency (informational) + + +Name: pwm-2chan @@ -110898,11 +111955,19 @@ index 0000000..268d400 + 4) Currently the clock must have been enabled and configured + by other means. +Load: dtoverlay=pwm-2chan,= -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) ++Params: pin Output pin (default 18) - see table ++ pin2 Output pin for other channel (default 19) ++ func Pin function (default 2 = Alt5) - see above ++ func2 Function for pin2 (default 2 = Alt5) ++ clock PWM clock frequency (informational) ++ ++ ++Name: qca7000 ++Info: I2SE's Evaluation Board for PLC Stamp micro ++Load: dtoverlay=qca7000,= ++Params: int_pin GPIO pin for interrupt signal (default 23) ++ ++ speed SPI bus speed (default 12 MHz) + + +Name: raspidac3 @@ -110911,6 +111976,12 @@ index 0000000..268d400 +Params: + + ++Name: rpi-backlight ++Info: Raspberry Pi official display backlight driver ++Load: dtoverlay=rpi-backlight ++Params: ++ ++ +Name: rpi-dac +Info: Configures the RPi DAC audio card +Load: dtoverlay=rpi-dac @@ -110920,15 +111991,12 @@ index 0000000..268d400 +Name: rpi-display +Info: RPi-Display - 2.8" Touch Display by Watterott +Load: dtoverlay=rpi-display,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) ++Params: speed Display SPI bus speed ++ rotate Display rotation {0,90,180,270} ++ fps Delay between frame updates ++ debug Debug output level {0-7} ++ xohms Touchpanel sensitivity (X-plate resistance) ++ swapxy Swap x and y axis + + +Name: rpi-ft5406 @@ -110952,33 +112020,73 @@ index 0000000..268d400 +Name: sdhost +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock +Load: dtoverlay=sdhost,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ force_pio Disable DMA support (default off) ++ force_pio Disable DMA support (default off) + -+ pio_limit Number of blocks above which to use DMA -+ (default 1) ++ pio_limit Number of blocks above which to use DMA ++ (default 1) + -+ debug Enable debug output (default off) ++ debug Enable debug output (default off) + + +Name: sdio +Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, + and enables SDIO via GPIOs 22-27. +Load: dtoverlay=sdio,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz ++Params: overclock_50 SD Clock (in MHz) to use when the MMC framework ++ requests 50MHz + -+ force_pio Disable DMA support (default off) ++ sdio_overclock SDIO Clock (in MHz) to use when the MMC ++ framework requests 50MHz + -+ pio_limit Number of blocks above which to use DMA -+ (default 1) ++ force_pio Disable DMA support (default off) + -+ debug Enable debug output (default off) ++ pio_limit Number of blocks above which to use DMA ++ (default 1) + -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) ++ debug Enable debug output (default off) ++ ++ poll_once Disable SDIO-device polling every second ++ (default on: polling once at boot-time) ++ ++ bus_width Set the SDIO host bus width (default 4 bits) ++ ++ ++Name: sdio-1bit ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, ++ and enables 1-bit SDIO via GPIOs 22-25. ++Load: dtoverlay=sdio-1bit,= ++Params: overclock_50 SD Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ sdio_overclock SDIO Clock (in MHz) to use when the MMC ++ framework requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) ++ ++ poll_once Disable SDIO-device polling every second ++ (default on: polling once at boot-time) ++ ++ ++Name: sdtweak ++Info: Tunes the bcm2835-sdhost SD/MMC driver ++Load: dtoverlay=sdtweak,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ ++ force_pio Disable DMA support (default off) ++ ++ pio_limit Number of blocks above which to use DMA ++ (default 1) ++ ++ debug Enable debug output (default off) + + +Name: smi @@ -111005,29 +112113,128 @@ index 0000000..268d400 +Params: + + ++Name: spi1-1cs ++Info: Enables spi1 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi1-2cs ++Info: Enables spi1 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.1 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi1-3cs ++Info: Enables spi1 with three chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi1 is only accessible on devices with a 40pin header, eg: ++ A+, B+, Zero and PI2 B; as well as the Compute Module. ++Load: dtoverlay=spi1-3cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). ++ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). ++ cs2_pin GPIO pin for CS2 (default 16 - BCM SPI1_CE2). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.1 (default ++ is 'okay' or enabled). ++ cs2_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev1.2 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-1cs ++Info: Enables spi2 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-2cs ++Info: Enables spi2 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.1 (default ++ is 'okay' or enabled). ++ ++ ++Name: spi2-3cs ++Info: Enables spi2 with three chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++ N.B.: spi2 is only accessible with the Compute Module. ++Load: dtoverlay=spi2-3cs,= ++Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). ++ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). ++ cs2_pin GPIO pin for CS2 (default 45 - BCM SPI2_CE2). ++ cs0_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.0 (default ++ is 'okay' or enabled). ++ cs1_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.1 (default ++ is 'okay' or enabled). ++ cs2_spidev Set to 'disabled' to stop the creation of a ++ userspace device node /dev/spidev2.2 (default ++ is 'okay' or enabled). ++ ++ +Name: tinylcd35 +Info: 3.5" Color TFT Display by www.tinylcd.com + Options: Touch, RTC, keypad +Load: dtoverlay=tinylcd35,= -+Params: speed Display SPI bus speed ++Params: speed Display SPI bus speed + -+ rotate Display rotation {0,90,180,270} ++ rotate Display rotation {0,90,180,270} + -+ fps Delay between frame updates ++ fps Delay between frame updates + -+ debug Debug output level {0-7} ++ debug Debug output level {0-7} + -+ touch Enable touch panel ++ touch Enable touch panel + -+ touchgpio Touch controller IRQ GPIO ++ touchgpio Touch controller IRQ GPIO + -+ xohms Touchpanel: Resistance of X-plate in ohms ++ xohms Touchpanel: Resistance of X-plate in ohms + -+ rtc-pcf PCF8563 Real Time Clock ++ rtc-pcf PCF8563 Real Time Clock + -+ rtc-ds DS1307 Real Time Clock ++ rtc-ds DS1307 Real Time Clock + -+ keypad Enable keypad ++ keypad Enable keypad + + Examples: + Display with touchpanel, PCF8563 RTC and keypad: @@ -111039,9 +112246,17 @@ index 0000000..268d400 +Name: uart1 +Info: Enable uart1 in place of uart0 +Load: dtoverlay=uart1,= -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) ++Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) + -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) ++ ++ ++Name: vc4-kms-v3d ++Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. Running startx or ++ booting to GUI while this overlay is in use will cause interesting ++ lockups. ++Load: dtoverlay=vc4-kms-v3d ++Params: + + +Name: vga666 @@ -111056,22 +112271,30 @@ index 0000000..268d400 +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *don't* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio,= -+Params: gpiopin GPIO for I/O (default "4") ++Params: gpiopin GPIO for I/O (default "4") + -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature + + +Name: w1-gpio-pullup +Info: Configures the w1-gpio Onewire interface module. + Use this overlay if you *do* need a GPIO to drive an external pullup. +Load: dtoverlay=w1-gpio-pullup,= -+Params: gpiopin GPIO for I/O (default "4") ++Params: gpiopin GPIO for I/O (default "4") + -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature + -+ extpullup GPIO for external pullup (default "5") ++ extpullup GPIO for external pullup (default "5") ++ ++ ++Name: wittypi ++Info: Configures the wittypi RTC module. ++Load: dtoverlay=wittypi,= ++Params: led_gpio GPIO for LED (default "17") ++ led_trigger Choose which activity the LED tracks (default ++ "default-on") + + +Troubleshooting @@ -111097,10 +112320,10 @@ index 0000000..268d400 +http://www.raspberrypi.org/documentation/configuration/device-tree.md diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts new file mode 100644 -index 0000000..6a92cd1 +index 0000000..edf2dc9 --- /dev/null +++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -0,0 +1,83 @@ +@@ -0,0 +1,89 @@ +/* + * Generic Device Tree overlay for the ADS7846 touch controller + * @@ -111116,18 +112339,24 @@ index 0000000..6a92cd1 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + ads7846_pins: ads7846_pins { @@ -111138,7 +112367,7 @@ index 0000000..6a92cd1 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111184,6 +112413,69 @@ index 0000000..6a92cd1 + xohms = <&ads7846>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts +new file mode 100644 +index 0000000..880c753 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ lowpan0: at86rf233@0 { ++ compatible = "atmel,at86rf233"; ++ reg = <0>; ++ interrupt-parent = <&gpio>; ++ interrupts = <23 4>; /* active high */ ++ reset-gpio = <&gpio 24 1>; ++ sleep-gpio = <&gpio 25 1>; ++ spi-max-frequency = <3000000>; ++ xtal-trim = /bits/ 8 <0xf>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ lowpan0_pins: lowpan0_pins { ++ brcm,pins = <23 24 25>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ interrupt = <&lowpan0>, "interrupts:0", ++ <&lowpan0_pins>, "brcm,pins:0"; ++ reset = <&lowpan0>, "reset-gpio:4", ++ <&lowpan0_pins>, "brcm,pins:4"; ++ sleep = <&lowpan0>, "sleep-gpio:4", ++ <&lowpan0_pins>, "brcm,pins:8"; ++ speed = <&lowpan0>, "spi-max-frequency:0"; ++ trim = <&lowpan0>, "xtal-trim.0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts new file mode 100644 index 0000000..782b171 @@ -111258,12 +112550,73 @@ index 0000000..9bf67fd + <&dht11>,"gpios:4"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +new file mode 100644 +index 0000000..fc48bd1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&usb>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ __overlay__ { ++ compatible = "brcm,bcm2708-usb"; ++ reg = <0x7e980000 0x10000>, ++ <0x7e006000 0x1000>; ++ interrupts = <2 0>, ++ <1 9>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +new file mode 100644 +index 0000000..527abc9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&usb>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ dwc2_usb: __overlay__ { ++ compatible = "brcm,bcm2835-usb"; ++ reg = <0x7e980000 0x10000>; ++ interrupts = <1 9>; ++ dr_mode = "otg"; ++ g-np-tx-fifo-size = <32>; ++ g-rx-fifo-size = <256>; ++ g-tx-fifo-size = <256 128 128 64 64 64 32>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ dr_mode = <&dwc2_usb>, "dr_mode"; ++ g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; ++ g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; ++ g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts new file mode 100644 -index 0000000..8fae869 +index 0000000..db8a8fe --- /dev/null +++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -0,0 +1,50 @@ +@@ -0,0 +1,53 @@ +// Overlay for the Microchip ENC28J60 Ethernet Controller +/dts-v1/; +/plugin/; @@ -111280,10 +112633,6 @@ index 0000000..8fae869 + + status = "okay"; + -+ spidev@0{ -+ status = "disabled"; -+ }; -+ + eth1: enc28j60@0{ + compatible = "microchip,enc28j60"; + reg = <0>; /* CE0 */ @@ -111298,6 +112647,13 @@ index 0000000..8fae869 + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + eth1_pins: eth1_pins { @@ -111314,6 +112670,57 @@ index 0000000..8fae869 + speed = <ð1>, "spi-max-frequency:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +new file mode 100644 +index 0000000..a2d6bc7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +@@ -0,0 +1,45 @@ ++// Definitions for ir-gpio module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ gpio_ir: ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ ++ // pin number, high or low ++ gpios = <&gpio 18 1>; ++ ++ // parameter for keymap name ++ linux,rc-map-name = "rc-rc6-mce"; ++ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ gpio_ir_pins: gpio_ir_pins { ++ brcm,pins = <18>; // pin 18 ++ brcm,function = <0>; // in ++ brcm,pull = <1>; // down ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ // parameters ++ gpio_pin = <&gpio_ir>,"gpios:4", ++ <&gpio_ir_pins>,"brcm,pins:0", ++ <&gpio_ir_pins>,"brcm,pull:0"; // pin number ++ gpio_pull = <&gpio_ir_pins>,"brcm,pull:0"; // pull-up/down state ++ ++ rc-map-name = <&gpio_ir>,"linux,rc-map-name"; // default rc map ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts new file mode 100644 index 0000000..ff8cb36 @@ -111441,10 +112848,10 @@ index 0000000..5e7633a +}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts new file mode 100644 -index 0000000..deb9c62 +index 0000000..42a0194 --- /dev/null +++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,54 @@ +// Definitions for HiFiBerry DAC+ +/dts-v1/; +/plugin/; @@ -111453,22 +112860,32 @@ index 0000000..deb9c62 + compatible = "brcm,bcm2708"; + + fragment@0 { -+ target = <&sound>; ++ target-path = "/clocks"; + __overlay__ { ++ dacpro_osc: dacpro_osc { ++ compatible = "hifiberry,dacpro-clk"; ++ #clock-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&sound>; ++ frag1: __overlay__ { + compatible = "hifiberry,hifiberry-dacplus"; + i2s-controller = <&i2s>; + status = "okay"; + }; + }; + -+ fragment@1 { ++ fragment@2 { + target = <&i2s>; + __overlay__ { + status = "okay"; + }; + }; + -+ fragment@2 { ++ fragment@3 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -111479,10 +112896,15 @@ index 0000000..deb9c62 + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; ++ clocks = <&dacpro_osc>; + status = "okay"; + }; + }; + }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag1>,"hifiberry,24db_digital_gain?"; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts new file mode 100644 @@ -111531,10 +112953,10 @@ index 0000000..d0e0d8a +}; diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts new file mode 100644 -index 0000000..3cd3083 +index 0000000..ac0f3c2 --- /dev/null +++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -0,0 +1,87 @@ +@@ -0,0 +1,93 @@ +/* + * Device Tree overlay for HY28A display + * @@ -111550,18 +112972,24 @@ index 0000000..3cd3083 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + hy28a_pins: hy28a_pins { @@ -111571,7 +112999,7 @@ index 0000000..3cd3083 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111624,10 +113052,10 @@ index 0000000..3cd3083 +}; diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts new file mode 100644 -index 0000000..f774c4a +index 0000000..8018aeb --- /dev/null +++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -0,0 +1,142 @@ +@@ -0,0 +1,148 @@ +/* + * Device Tree overlay for HY28b display shield by Texy + * @@ -111643,18 +113071,24 @@ index 0000000..f774c4a + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + hy28b_pins: hy28b_pins { @@ -111664,7 +113098,7 @@ index 0000000..f774c4a + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -111770,12 +113204,119 @@ index 0000000..f774c4a + <&hy28b_pins>, "brcm,pins:2"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +new file mode 100644 +index 0000000..2a2dc98 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +@@ -0,0 +1,28 @@ ++// Overlay for i2c_gpio bitbanging host bus. ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ i2c_gpio: i2c@0 { ++ compatible = "i2c-gpio"; ++ gpios = <&gpio 23 0 /* sda */ ++ &gpio 24 0 /* scl */ ++ >; ++ i2c-gpio,delay-us = <2>; /* ~100 kHz */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; ++ i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; ++ i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; ++ }; ++}; ++ +diff --git a/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts +new file mode 100644 +index 0000000..1729fd6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts +@@ -0,0 +1,67 @@ ++// Definitions for NXP PCA9548A I2C mux on ARM I2C bus. ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ i2cmux: mux@70 { ++ compatible = "nxp,pca9548"; ++ reg = <0x70>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ i2c@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ }; ++ i2c@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <1>; ++ }; ++ i2c@2 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <2>; ++ }; ++ i2c@3 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <3>; ++ }; ++ i2c@4 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <4>; ++ }; ++ i2c@5 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <5>; ++ }; ++ i2c@6 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <6>; ++ }; ++ i2c@7 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <7>; ++ }; ++ }; ++ }; ++ }; ++ __overrides__ { ++ addr = <&i2cmux>,"reg:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts new file mode 100644 -index 0000000..fed4bd8 +index 0000000..eecec16 --- /dev/null +++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,55 @@ +@@ -0,0 +1,63 @@ +// Definitions for several I2C based Real Time Clocks +/dts-v1/; +/plugin/; @@ -111795,6 +113336,12 @@ index 0000000..fed4bd8 + reg = <0x68>; + status = "disable"; + }; ++ ds1339: ds1339@68 { ++ compatible = "dallas,ds1339"; ++ trickle-resistor-ohms = <0>; ++ reg = <0x68>; ++ status = "disable"; ++ }; + mcp7941x: mcp7941x@6f { + compatible = "microchip,mcp7941x"; + reg = <0x6f>; @@ -111824,13 +113371,100 @@ index 0000000..fed4bd8 + }; + __overrides__ { + ds1307 = <&ds1307>,"status"; ++ ds1339 = <&ds1339>,"status"; + ds3231 = <&ds3231>,"status"; + mcp7941x = <&mcp7941x>,"status"; + pcf2127 = <&pcf2127>,"status"; + pcf8523 = <&pcf8523>,"status"; + pcf8563 = <&pcf8563>,"status"; ++ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +new file mode 100644 +index 0000000..5c0e55b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +@@ -0,0 +1,36 @@ ++/* ++ * Device tree overlay for i2c_bcm2708, i2c0 bus ++ * ++ * Compile: ++ * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c0>; ++ __overlay__ { ++ pinctrl-0 = <&i2c0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ sda0_pin = <&i2c0_pins>,"brcm,pins:0"; ++ scl0_pin = <&i2c0_pins>,"brcm,pins:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +new file mode 100644 +index 0000000..e303b9c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +@@ -0,0 +1,37 @@ ++/* ++ * Device tree overlay for i2c_bcm2708, i2c1 bus ++ * ++ * Compile: ++ * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ sda1_pin = <&i2c1_pins>,"brcm,pins:0"; ++ scl1_pin = <&i2c1_pins>,"brcm,pins:4"; ++ pin_func = <&i2c1_pins>,"brcm,function:0"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts new file mode 100644 index 0000000..a11160a @@ -111897,10 +113531,10 @@ index 0000000..ea8173e +}; diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts new file mode 100644 -index 0000000..735d8ab +index 0000000..e0aaf8f --- /dev/null +++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,43 @@ +// Definitions for IQaudIO DAC+ +/dts-v1/; +/plugin/; @@ -111910,7 +113544,7 @@ index 0000000..735d8ab + + fragment@0 { + target = <&sound>; -+ __overlay__ { ++ frag0: __overlay__ { + compatible = "iqaudio,iqaudio-dac"; + i2s-controller = <&i2s>; + status = "okay"; @@ -111939,6 +113573,10 @@ index 0000000..735d8ab + }; + }; + }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; ++ }; +}; diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts new file mode 100644 @@ -112005,10 +113643,10 @@ index 0000000..7d5d82b +}; diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts new file mode 100755 -index 0000000..398d59c +index 0000000..c96cdae --- /dev/null +++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -0,0 +1,69 @@ +@@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can0 on spi0.0 + */ @@ -112023,14 +113661,18 @@ index 0000000..398d59c + target = <&spi0>; + __overlay__ { + status = "okay"; -+ spidev@0{ -+ status = "disabled"; -+ }; + }; + }; + -+ /* the interrupt pin of the can-controller */ + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + can0_pins: can0_pins { @@ -112041,7 +113683,7 @@ index 0000000..398d59c + }; + + /* the clock/oscillator of the can-controller */ -+ fragment@2 { ++ fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on SPI0.0 */ @@ -112054,7 +113696,7 @@ index 0000000..398d59c + }; + + /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112080,10 +113722,10 @@ index 0000000..398d59c +}; diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts new file mode 100644 -index 0000000..6bef9ae +index 0000000..67bd0d9 --- /dev/null +++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -0,0 +1,69 @@ +@@ -0,0 +1,73 @@ +/* + * Device tree overlay for mcp251x/can1 on spi0.1 edited by petit_miner + */ @@ -112098,14 +113740,18 @@ index 0000000..6bef9ae + target = <&spi0>; + __overlay__ { + status = "okay"; -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + -+ /* the interrupt pin of the can-controller */ + fragment@1 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + can1_pins: can1_pins { @@ -112116,7 +113762,7 @@ index 0000000..6bef9ae + }; + + /* the clock/oscillator of the can-controller */ -+ fragment@2 { ++ fragment@3 { + target-path = "/clocks"; + __overlay__ { + /* external oscillator of mcp2515 on spi0.1 */ @@ -112129,7 +113775,7 @@ index 0000000..6bef9ae + }; + + /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112155,10 +113801,10 @@ index 0000000..6bef9ae +}; diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts new file mode 100644 -index 0000000..00a22be +index 0000000..d32b02c --- /dev/null +++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -0,0 +1,39 @@ +@@ -0,0 +1,38 @@ +/dts-v1/; +/plugin/; + @@ -112195,15 +113841,14 @@ index 0000000..00a22be + + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts new file mode 100644 -index 0000000..9242a6e +index 0000000..2c29aae --- /dev/null +++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,111 @@ +@@ -0,0 +1,117 @@ +/* + * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec + * @@ -112219,18 +113864,24 @@ index 0000000..9242a6e + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + mz61581_pins: mz61581_pins { @@ -112240,7 +113891,7 @@ index 0000000..9242a6e + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112315,12 +113966,167 @@ index 0000000..9242a6e + xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +new file mode 100644 +index 0000000..14a59dc +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed ++ from the VPU. There is a special driver for this with a separate DT node, ++ which has the unfortunate consequence of breaking the act_led_gpio and ++ act_led_activelow dtparams. ++ ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&act_led>; ++ frag0: __overlay__ { ++ gpios = <&gpio 0 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ gpio = <&frag0>,"gpios:4"; ++ activelow = <&frag0>,"gpios:8"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +new file mode 100644 +index 0000000..68f6069 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +@@ -0,0 +1,46 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. ++ To disable the systemd service that initialises the modem so it doesn't use ++ the UART: ++ ++ sudo systemctl disable hciuart ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/uart@7e201000"; ++ serial1 = "/soc/uart@7e215040"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +new file mode 100644 +index 0000000..17d04cf +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +@@ -0,0 +1,64 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore ++ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum ++ usable baudrate. ++ ++ It is also necessary to edit /lib/systemd/system/hciuart.service and ++ replace ttyAMA0 with ttyS0, unless you have a system with udev rules ++ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 ++ instead because it will always be correct. ++ ++ If cmdline.txt uses the alias serial0 to refer to the user-accessable port ++ then the firmware will replace with the appropriate port whether or not ++ this overlay is used. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins &bt_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&uart1_pins>; ++ __overlay__ { ++ brcm,pins = <32 33>; ++ brcm,function = <2>; /* alt5=UART1 */ ++ brcm,pull = <0 2>; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/uart@7e201000"; ++ serial1 = "/soc/uart@7e215040"; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts new file mode 100644 -index 0000000..ba4ad33 +index 0000000..40a1f29 --- /dev/null +++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -0,0 +1,96 @@ +@@ -0,0 +1,102 @@ +/* + * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker + * @@ -112336,18 +114142,24 @@ index 0000000..ba4ad33 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + piscreen_pins: piscreen_pins { @@ -112357,7 +114169,7 @@ index 0000000..ba4ad33 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112417,12 +114229,221 @@ index 0000000..ba4ad33 + xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +new file mode 100644 +index 0000000..9c0bed8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +@@ -0,0 +1,106 @@ ++ /* ++ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&gpio>; ++ __overlay__ { ++ piscreen2_pins: piscreen2_pins { ++ brcm,pins = <17 25 24 22>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ piscreen2: piscreen2@0{ ++ compatible = "ilitek,ili9486"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&piscreen2_pins>; ++ bgr; ++ spi-max-frequency = <64000000>; ++ rotate = <90>; ++ fps = <30>; ++ buswidth = <8>; ++ regwidth = <16>; ++ txbuflen = <32768>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 22 1>; ++ debug = <0>; ++ ++ init = <0x10000b0 0x00 ++ 0x1000011 ++ 0x20000ff ++ 0x100003a 0x55 ++ 0x1000036 0x28 ++ 0x10000c0 0x11 0x09 ++ 0x10000c1 0x41 ++ 0x10000c5 0x00 0x00 0x00 0x00 ++ 0x10000b6 0x00 0x02 ++ 0x10000f7 0xa9 0x51 0x2c 0x2 ++ 0x10000be 0x00 0x04 ++ 0x10000e9 0x00 ++ 0x1000011 ++ 0x1000029>; ++ ++ }; ++ ++ piscreen2_ts: piscreen2-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,swap-xy; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&piscreen2>,"spi-max-frequency:0"; ++ rotate = <&piscreen2>,"rotate:0"; ++ fps = <&piscreen2>,"fps:0"; ++ debug = <&piscreen2>,"debug:0"; ++ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; ++ +diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts +new file mode 100644 +index 0000000..5c07526 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts +@@ -0,0 +1,91 @@ ++/* ++ * Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ pitft_pins: pitft_pins { ++ brcm,pins = <24 25>; ++ brcm,function = <0 1>; /* in out */ ++ brcm,pull = <2 0>; /* pullup none */ ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pitft: pitft@0{ ++ compatible = "ilitek,ili9340"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pitft_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <90>; ++ fps = <25>; ++ bgr; ++ buswidth = <8>; ++ dc-gpios = <&gpio 25 0>; ++ debug = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c1>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ft6236: ft6236@38 { ++ compatible = "focaltech,ft6236"; ++ reg = <0x38>; ++ ++ interrupt-parent = <&gpio>; ++ interrupts = <24 2>; ++ touchscreen-size-x = <240>; ++ touchscreen-size-y = <320>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&pitft>,"spi-max-frequency:0"; ++ rotate = <&pitft>,"rotate:0"; ++ fps = <&pitft>,"fps:0"; ++ debug = <&pitft>,"debug:0"; ++ touch-sizex = <&ft6236>,"touchscreen-size-x?"; ++ touch-sizey = <&ft6236>,"touchscreen-size-y?"; ++ touch-invx = <&ft6236>,"touchscreen-inverted-x?"; ++ touch-invy = <&ft6236>,"touchscreen-inverted-y?"; ++ touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts new file mode 100644 -index 0000000..d506eae +index 0000000..ed2afc2 --- /dev/null +++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ +@@ -0,0 +1,121 @@ +/* + * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen + * @@ -112438,18 +114459,24 @@ index 0000000..d506eae + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + pitft_pins: pitft_pins { @@ -112460,7 +114487,7 @@ index 0000000..d506eae + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112520,7 +114547,7 @@ index 0000000..d506eae + }; + }; + -+ fragment@3 { ++ fragment@5 { + target-path = "/soc"; + __overlay__ { + backlight { @@ -112580,10 +114607,10 @@ index 0000000..40bf0e1 +}; diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts new file mode 100644 -index 0000000..957e1a4 +index 0000000..18e4e4f --- /dev/null +++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -0,0 +1,46 @@ +@@ -0,0 +1,53 @@ +/dts-v1/; +/plugin/; + @@ -112622,20 +114649,27 @@ index 0000000..957e1a4 + }; + }; + ++ fragment@2 { ++ target = <&clk_pwm>; ++ frag2: __overlay__ { ++ clock-frequency = <100000000>; ++ }; ++ }; ++ + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + pin2 = <&pwm_pins>,"brcm,pins:4"; + func = <&pwm_pins>,"brcm,function:0"; + func2 = <&pwm_pins>,"brcm,function:4"; -+ clock = <&clk_pwm>,"clock-frequency:0"; ++ clock = <&frag2>,"clock-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts new file mode 100644 -index 0000000..ddd67ff +index 0000000..bf030a6 --- /dev/null +++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -0,0 +1,42 @@ +@@ -0,0 +1,49 @@ +/dts-v1/; +/plugin/; + @@ -112672,10 +114706,75 @@ index 0000000..ddd67ff + }; + }; + ++ fragment@2 { ++ target = <&clk_pwm>; ++ frag2: __overlay__ { ++ clock-frequency = <100000000>; ++ }; ++ }; ++ + __overrides__ { + pin = <&pwm_pins>,"brcm,pins:0"; + func = <&pwm_pins>,"brcm,function:0"; -+ clock = <&clk_pwm>,"clock-frequency:0"; ++ clock = <&frag2>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/qca7000-overlay.dts b/arch/arm/boot/dts/overlays/qca7000-overlay.dts +new file mode 100644 +index 0000000..b4e6013 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts +@@ -0,0 +1,52 @@ ++// Overlay for the Qualcomm Atheros QCA7000 on I2SE's PLC Stamp micro EVK ++// Visit: https://www.i2se.com/product/plc-stamp-micro-evk for details ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ spidev@0 { ++ status = "disabled"; ++ }; ++ ++ eth1: qca7000@0 { ++ compatible = "qca,qca7000"; ++ reg = <0>; /* CE0 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð1_pins>; ++ interrupt-parent = <&gpio>; ++ interrupts = <23 0x1>; /* rising edge */ ++ spi-max-frequency = <12000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ eth1_pins: eth1_pins { ++ brcm,pins = <23>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ int_pin = <ð1>, "interrupts:0", ++ <ð1_pins>, "brcm,pins:0"; ++ speed = <ð1>, "spi-max-frequency:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/raspidac3-overlay.dts b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts @@ -112729,6 +114828,33 @@ index 0000000..1bd8054 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts +new file mode 100644 +index 0000000..c021d02 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts +@@ -0,0 +1,21 @@ ++/* ++ * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display ++ * backlight controller ++ */ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ rpi_backlight: rpi_backlight { ++ compatible = "raspberrypi,rpi-backlight"; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts new file mode 100644 index 0000000..7fc6ac9 @@ -112771,10 +114897,10 @@ index 0000000..7fc6ac9 +}; diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts new file mode 100644 -index 0000000..a8fa974 +index 0000000..d7e72ee --- /dev/null +++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -0,0 +1,82 @@ +@@ -0,0 +1,89 @@ +/* + * Device Tree overlay for rpi-display by Watterott + * @@ -112790,18 +114916,24 @@ index 0000000..a8fa974 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + rpi_display_pins: rpi_display_pins { @@ -112812,7 +114944,7 @@ index 0000000..a8fa974 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -112855,6 +114987,7 @@ index 0000000..a8fa974 + fps = <&rpidisplay>,"fps:0"; + debug = <&rpidisplay>,"debug:0"; + xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; ++ swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts @@ -112980,45 +115113,90 @@ index 0000000..2715324 +}; diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts new file mode 100644 -index 0000000..85f0725 +index 0000000..a431177 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,29 @@ +@@ -0,0 +1,32 @@ +/dts-v1/; +/plugin/; + ++/* Provide backwards compatible aliases for the old sdhost dtparams. */ ++ +/{ + compatible = "brcm,bcm2708"; + + fragment@0 { ++ target = <&sdhost>; ++ frag0: __overlay__ { ++ brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; ++ brcm,debug-flags = <0>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { + target = <&mmc>; + __overlay__ { + status = "disabled"; + }; + }; + -+ fragment@1 { -+ target = <&sdhost>; -+ frag1: __overlay__ { ++ __overrides__ { ++ overclock_50 = <&frag0>,"brcm,overclock-50:0"; ++ force_pio = <&frag0>,"brcm,force-pio?"; ++ pio_limit = <&frag0>,"brcm,pio-limit:0"; ++ debug = <&frag0>,"brcm,debug?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts +new file mode 100644 +index 0000000..46d4538 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts +@@ -0,0 +1,36 @@ ++/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ ++ ++/include/ "sdhost-overlay.dts" ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@3 { ++ target = <&mmc>; ++ sdio_mmc: __overlay__ { ++ compatible = "brcm,bcm2835-mmc"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <1>; + brcm,overclock-50 = <0>; -+ brcm,pio-limit = <1>; + status = "okay"; + }; + }; + ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ sdio_pins: sdio_pins { ++ brcm,pins = <22 23 24 25>; ++ brcm,function = <7 7 7 7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2>; ++ }; ++ }; ++ }; ++ + __overrides__ { -+ overclock_50 = <&frag1>,"brcm,overclock-50:0"; -+ force_pio = <&frag1>,"brcm,force-pio?"; -+ pio_limit = <&frag1>,"brcm,pio-limit:0"; -+ debug = <&frag1>,"brcm,debug?"; ++ poll_once = <&sdio_mmc>,"non-removable?"; ++ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts new file mode 100644 -index 0000000..afc8742 +index 0000000..398bd81 --- /dev/null +++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -0,0 +1,32 @@ +@@ -0,0 +1,36 @@ +/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ + +/include/ "sdhost-overlay.dts" @@ -113032,6 +115210,8 @@ index 0000000..afc8742 + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + non-removable; ++ bus-width = <4>; ++ brcm,overclock-50 = <0>; + status = "okay"; + }; + }; @@ -113049,6 +115229,37 @@ index 0000000..afc8742 + + __overrides__ { + poll_once = <&sdio_mmc>,"non-removable?"; ++ bus_width = <&sdio_mmc>,"bus-width:0"; ++ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts +new file mode 100644 +index 0000000..e4a4677 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Provide backwards compatible aliases for the old sdhost dtparams. */ ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sdhost>; ++ frag0: __overlay__ { ++ brcm,overclock-50 = <0>; ++ brcm,pio-limit = <1>; ++ }; ++ }; ++ ++ __overrides__ { ++ overclock_50 = <&frag0>,"brcm,overclock-50:0"; ++ force_pio = <&frag0>,"brcm,force-pio?"; ++ pio_limit = <&frag0>,"brcm,pio-limit:0"; ++ debug = <&frag0>,"brcm,debug?"; + }; +}; diff --git a/arch/arm/boot/dts/overlays/smi-dev-overlay.dts b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts @@ -113230,12 +115441,462 @@ index 0000000..9648063 + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts +new file mode 100644 +index 0000000..71c2439 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts +new file mode 100644 +index 0000000..2ae0885 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts +@@ -0,0 +1,69 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18 17>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>, <&gpio 17 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ cs1_spidev = <&spidev1_1>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts +new file mode 100644 +index 0000000..8f79044 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts +@@ -0,0 +1,81 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18 17 16>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>, <&gpio 17 1>, <&gpio 16 1>; ++ status = "okay"; ++ ++ spidev1_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev1_2: spidev@2 { ++ compatible = "spidev"; ++ reg = <2>; /* CE2 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs2_pin = <&spi1_cs_pins>,"brcm,pins:8", ++ <&frag1>,"cs-gpios:28"; ++ cs0_spidev = <&spidev1_0>,"status"; ++ cs1_spidev = <&spidev1_1>,"status"; ++ cs2_spidev = <&spidev1_2>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts +new file mode 100644 +index 0000000..6f57bc7 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts +new file mode 100644 +index 0000000..d090631 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts +@@ -0,0 +1,69 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43 44>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>, <&gpio 44 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ cs1_spidev = <&spidev2_1>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts +new file mode 100644 +index 0000000..e258672 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts +@@ -0,0 +1,81 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi2_pins: spi2_pins { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ }; ++ ++ spi2_cs_pins: spi2_cs_pins { ++ brcm,pins = <43 44 45>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; ++ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; ++ status = "okay"; ++ ++ spidev2_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ ++ spidev2_2: spidev@2 { ++ compatible = "spidev"; ++ reg = <2>; /* CE2 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs2_pin = <&spi2_cs_pins>,"brcm,pins:8", ++ <&frag1>,"cs-gpios:28"; ++ cs0_spidev = <&spidev2_0>,"status"; ++ cs1_spidev = <&spidev2_1>,"status"; ++ cs2_spidev = <&spidev2_2>,"status"; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts new file mode 100644 -index 0000000..f7102c8 +index 0000000..33c0651 --- /dev/null +++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ +@@ -0,0 +1,222 @@ +/* + * tinylcd35-overlay.dts + * @@ -113268,18 +115929,24 @@ index 0000000..f7102c8 + target = <&spi0>; + __overlay__ { + status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; + }; + }; + + fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&gpio>; + __overlay__ { + tinylcd35_pins: tinylcd35_pins { @@ -113298,7 +115965,7 @@ index 0000000..f7102c8 + }; + }; + -+ fragment@2 { ++ fragment@4 { + target = <&spi0>; + __overlay__ { + /* needed to avoid dtc warning */ @@ -113362,7 +116029,7 @@ index 0000000..f7102c8 + + /* RTC */ + -+ fragment@3 { ++ fragment@5 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -113376,7 +116043,7 @@ index 0000000..f7102c8 + }; + }; + -+ fragment@4 { ++ fragment@6 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; @@ -113394,7 +116061,7 @@ index 0000000..f7102c8 + * Values for input event code is found under the + * 'Keys and buttons' heading in include/uapi/linux/input.h + */ -+ fragment@5 { ++ fragment@7 { + target-path = "/soc"; + __overlay__ { + keypad: keypad { @@ -113496,6 +116163,107 @@ index 0000000..fa73e1f + rxd1_pin = <&uart1_pins>,"brcm,pins:4"; + }; +}; +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +new file mode 100644 +index 0000000..da37483 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -0,0 +1,95 @@ ++/* ++ * vc4-kms-v3d-overlay.dts ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++#include "dt-bindings/clock/bcm2835.h" ++#include "dt-bindings/gpio/gpio.h" ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&cprman>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&fb>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pixelvalve@7e206000 { ++ compatible = "brcm,bcm2835-pixelvalve0"; ++ reg = <0x7e206000 0x100>; ++ interrupts = <2 13>; /* pwa0 */ ++ }; ++ ++ pixelvalve@7e207000 { ++ compatible = "brcm,bcm2835-pixelvalve1"; ++ reg = <0x7e207000 0x100>; ++ interrupts = <2 14>; /* pwa1 */ ++ }; ++ ++ hvs@7e400000 { ++ compatible = "brcm,bcm2835-hvs"; ++ reg = <0x7e400000 0x6000>; ++ interrupts = <2 1>; ++ }; ++ ++ pixelvalve@7e807000 { ++ compatible = "brcm,bcm2835-pixelvalve2"; ++ reg = <0x7e807000 0x100>; ++ interrupts = <2 10>; /* pixelvalve */ ++ }; ++ ++ hdmi@7e902000 { ++ compatible = "brcm,bcm2835-hdmi"; ++ reg = <0x7e902000 0x600>, ++ <0x7e808000 0x100>; ++ interrupts = <2 8>, <2 9>; ++ ddc = <&i2c2>; ++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; ++ clocks = <&cprman BCM2835_PLLH_PIX>, ++ <&cprman BCM2835_CLOCK_HSM>; ++ clock-names = "pixel", "hdmi"; ++ }; ++ ++ v3d@7ec00000 { ++ compatible = "brcm,vc4-v3d"; ++ reg = <0x7ec00000 0x1000>; ++ interrupts = <1 10>; ++ }; ++ ++ gpu@7e4c0000 { ++ compatible = "brcm,bcm2835-vc4"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/chosen"; ++ __overlay__ { ++ bootargs = "cma=256M@512M"; ++ }; ++ }; ++}; diff --git a/arch/arm/boot/dts/overlays/vga666-overlay.dts b/arch/arm/boot/dts/overlays/vga666-overlay.dts new file mode 100644 index 0000000..7fcab96 @@ -113624,532 +116392,61 @@ index 0000000..66a98f6 + pullup = <&w1>,"rpi,parasitic-power:0"; + }; +}; - -From 83d747d78be86190ad18c8c49e0d5518ac6bf83b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 15 Aug 2015 20:47:07 +0200 -Subject: [PATCH 052/251] bcm2835: Match with BCM2708 Device Trees -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 132 ++++++++++++++++++--- - arch/arm/boot/dts/bcm2835-rpi-b.dts | 115 ++++++++++++++++-- - arch/arm/boot/dts/bcm2835.dtsi | 195 +++---------------------------- - 3 files changed, 237 insertions(+), 205 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index 668442b..17e2443 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -1,30 +1,128 @@ - /dts-v1/; --#include "bcm2835-rpi.dtsi" -+#include "bcm2835.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; - }; --}; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -+ i2s_pins: i2s { - brcm,pins = <18 19 20 21>; -- brcm,function = ; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; +diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts +new file mode 100644 +index 0000000..8498134 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts +@@ -0,0 +1,44 @@ ++/* ++ * Device Tree overlay for Witty Pi extension board by UUGear ++ * ++ */ + -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+ -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; -+ }; -+}; ++/dts-v1/; ++/plugin/; + +/ { ++ ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ compatible = "gpio-leds"; ++ wittypi_led: wittypi_led { ++ label = "wittypi_led"; ++ linux,default-trigger = "default-on"; ++ gpios = <&gpio 17 0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtc: ds1337@68 { ++ compatible = "dallas,ds1337"; ++ reg = <0x68>; ++ wakeup-source; ++ }; ++ }; ++ }; ++ + __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index ff6b2d1..221d252 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -1,17 +1,118 @@ - /dts-v1/; --#include "bcm2835-rpi.dtsi" -+#include "bcm2835.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; -+}; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ ++ led_gpio = <&wittypi_led>,"gpios:4"; ++ led_trigger = <&wittypi_led>,"linux,default-trigger"; + }; + -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = <6>; /* alt2 */ - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &alt3>; -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 16 1>; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1_clkrate = <&uart1>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; -+ }; - }; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 864a3ef..3256bff 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -1,206 +1,39 @@ --#include --#include --#include "skeleton.dtsi" -+#include "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2835"; - model = "BCM2835"; -- interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - - soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -- ranges = <0x7e000000 0x20000000 0x02000000>; -+ ranges = <0x7e000000 0x20000000 0x01000000>; - 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 0x24>, -- <0x7e101098 0x08>; -- -- 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>; -+ aux_enable: aux_enable@0x7e215004 { -+ compatible = "bcrm,bcm2835-aux-enable"; -+ reg = <0x7e215004 0x04>; - }; -- - }; - }; -+ -+&intc { -+ compatible = "brcm,bcm2835-armctrl-ic"; -+}; -+ -+&watchdog { -+ status = "okay"; +}; -From 1b4ab4d431eed3ced1dfdcb4ac14ce3937b74244 Mon Sep 17 00:00:00 2001 +From 2984afc661362f0232f374a91edc59a2cafcc302 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 053/251] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 053/114] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -114164,7 +116461,7 @@ Signed-off-by: Siarhei Siamashka 2 files changed, 35 insertions(+) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index 0705d88..771992a 100644 +index 4e73b6f..d3a8cc3 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) @@ -114242,10 +116539,10 @@ index fb795c3..fa72af0 100644 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ -From 25f558f2cb3b7c357c2b3fff66afca442b8462f9 Mon Sep 17 00:00:00 2001 +From f125245cdc2f65f3f085c9146bc3ce5b373b9def Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 054/251] Speed up console framebuffer imageblit function +Subject: [PATCH 054/114] Speed up console framebuffer imageblit function Especially on platforms with a slower CPU but a relatively high framebuffer fill bandwidth, like current ARM devices, the existing @@ -114454,10 +116751,10 @@ index a2bb276..436494f 100644 start_index, pitch_index); } else -From 0490dab9480fa92983af098b472d6a6e6e573e29 Mon Sep 17 00:00:00 2001 +From c158f1cc55e3166d2eac6a0c7e06bd93d6c4c244 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 055/251] Allow mac address to be set in smsc95xx +Subject: [PATCH 055/114] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -114465,7 +116762,7 @@ Signed-off-by: popcornmix 1 file changed, 56 insertions(+) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 9c0da18..3244a90 100755 +index 714cfe0..08ced57 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -59,6 +59,7 @@ @@ -114476,9 +116773,9 @@ index 9c0da18..3244a90 100755 struct smsc95xx_priv { u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); +@@ -78,6 +79,10 @@ static bool truesize_mode = false; + module_param(truesize_mode, bool, 0644); + MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); +static char *macaddr = ":"; +module_param(macaddr, charp, 0); @@ -114487,7 +116784,7 @@ index 9c0da18..3244a90 100755 static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data, int in_pm) { -@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +@@ -767,8 +772,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } @@ -114548,10 +116845,10 @@ index 9c0da18..3244a90 100755 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -From 5f3d302d1cd2e2684c1a4a21953c4677809a2f87 Mon Sep 17 00:00:00 2001 +From 7dc5a6f1fb813263ee414e2d7898d3e03d79edd8 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 056/251] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 056/114] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -114801,32 +117098,32 @@ index d58594a..feae942 100644 unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From bc26cb5ca41caddb82d291450e32b27e56d9b87f Mon Sep 17 00:00:00 2001 +From 79e36090cb7c4f81295a6764dcb5879f30d0ddb4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 057/251] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 057/114] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- - kernel/cgroup.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) + kernel/cgroup.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index dc94f8b..3dda8a8 100644 +index 671dc05..fbbf2e6 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5302,7 +5302,7 @@ int __init cgroup_init_early(void) +@@ -5521,7 +5521,7 @@ int __init cgroup_init_early(void) return 0; } --static unsigned long cgroup_disable_mask __initdata; -+static unsigned long cgroup_disable_mask __initdata = 1<<0; +-static u16 cgroup_disable_mask __initdata; ++static u16 cgroup_disable_mask __initdata = 1<<0; /** * cgroup_init - cgroup initialization -@@ -5798,6 +5798,27 @@ static int __init cgroup_disable(char *str) +@@ -6051,6 +6051,28 @@ static int __init cgroup_no_v1(char *str) } - __setup("cgroup_disable=", cgroup_disable); + __setup("cgroup_no_v1=", cgroup_no_v1); +static int __init cgroup_enable(char *str) +{ @@ -114842,6 +117139,7 @@ index dc94f8b..3dda8a8 100644 + if (strcmp(token, ss->name) && + strcmp(token, ss->legacy_name)) + continue; ++ + cgroup_disable_mask &= ~(1 << i); + } + } @@ -114853,10 +117151,10 @@ index dc94f8b..3dda8a8 100644 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry * @dentry: directory dentry of interest -From 22689d60a6ca6191119ef7ab70c5b23991a41e16 Mon Sep 17 00:00:00 2001 +From a46b0a5f799ac1798512ee52f694802873027e6a Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 058/251] ASoC: Add support for PCM5102A codec +Subject: [PATCH 058/114] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. @@ -114870,20 +117168,20 @@ Signed-off-by: Florian Meier create mode 100644 sound/soc/codecs/pcm5102a.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index cfdafc4..bd38590 100644 +index 649e92a..ba4aad4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -89,6 +89,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C +@@ -100,6 +100,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_RT298 if I2C + select SND_SOC_RT5514 if I2C + select SND_SOC_RT5616 if I2C + select SND_SOC_PCM5102A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -549,6 +550,10 @@ config SND_SOC_RT298 - tristate - depends on I2C +@@ -630,6 +631,10 @@ config SND_SOC_RT5514 + config SND_SOC_RT5616 + tristate "Realtek RT5616 CODEC" +config SND_SOC_PCM5102A + tristate @@ -114893,21 +117191,21 @@ index cfdafc4..bd38590 100644 tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index f632fc4..7ba76ba 100644 +index 185a712..7522017 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -85,6 +85,7 @@ snd-soc-rl6231-objs := rl6231.o - snd-soc-rl6347a-objs := rl6347a.o - snd-soc-rt286-objs := rt286.o +@@ -98,6 +98,7 @@ snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o + snd-soc-rt5514-objs := rt5514.o + snd-soc-rt5616-objs := rt5616.o +snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o snd-soc-rt5645-objs := rt5645.o -@@ -280,6 +281,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o +@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o + obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o + obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o +obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o @@ -114989,10 +117287,10 @@ index 0000000..7c6598e +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 26aeeecaac62fdee4bff333a743680693009f15a Mon Sep 17 00:00:00 2001 +From 49142e5a7faec4059b97245bb91b5b4c5ab243e6 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 059/251] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 059/114] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -115002,8 +117300,8 @@ Signed-off-by: Florian Meier --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 4 ++ - sound/soc/bcm/hifiberry_dac.c | 122 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 133 insertions(+) + sound/soc/bcm/hifiberry_dac.c | 123 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 134 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_dac.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115035,10 +117333,10 @@ index bc816b7..b877d38 100644 +obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c new file mode 100644 -index 0000000..3ab0f47 +index 0000000..29ecc08 --- /dev/null +++ b/sound/soc/bcm/hifiberry_dac.c -@@ -0,0 +1,122 @@ +@@ -0,0 +1,123 @@ +/* + * ASoC Driver for HifiBerry DAC + * @@ -115104,6 +117402,7 @@ index 0000000..3ab0f47 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_dac = { + .name = "snd_rpi_hifiberry_dac", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), +}; @@ -115162,19 +117461,19 @@ index 0000000..3ab0f47 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From 5bf2d31cda2340e5d7d73c35ea876225d2f8e9a1 Mon Sep 17 00:00:00 2001 +From a2bfef45c070bc2ac4990f930c03f6bf71c80eb3 Mon Sep 17 00:00:00 2001 From: Florian Meier -Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 060/251] ASoC: Add support for Rpi-DAC +Date: Mon, 25 Jan 2016 15:48:59 +0000 +Subject: [PATCH 060/114] ASoC: Add support for Rpi-DAC --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 118 ++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/rpi-dac.c | 119 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/Kconfig | 9 ++++ sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 69 ++++++++++++++++++++++++++ - 6 files changed, 207 insertions(+) + sound/soc/codecs/pcm1794a.c | 69 +++++++++++++++++++++++++ + 6 files changed, 208 insertions(+) create mode 100644 sound/soc/bcm/rpi-dac.c create mode 100644 sound/soc/codecs/pcm1794a.c @@ -115207,10 +117506,10 @@ index b877d38..99c96b4 100644 +obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c new file mode 100644 -index 0000000..d5fac1b +index 0000000..59dc89e --- /dev/null +++ b/sound/soc/bcm/rpi-dac.c -@@ -0,0 +1,118 @@ +@@ -0,0 +1,119 @@ +/* + * ASoC Driver for RPi-DAC. + * @@ -115273,6 +117572,7 @@ index 0000000..d5fac1b +/* audio machine driver */ +static struct snd_soc_card snd_rpi_rpi_dac = { + .name = "snd_rpi_rpi_dac", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_rpi_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), +}; @@ -115330,20 +117630,20 @@ index 0000000..d5fac1b +MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index bd38590..b63f2fb 100644 +index ba4aad4..214af16 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -90,6 +90,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_RT286 if I2C - select SND_SOC_RT298 if I2C +@@ -101,6 +101,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_RT5514 if I2C + select SND_SOC_RT5616 if I2C select SND_SOC_PCM5102A if I2C + select SND_SOC_PCM1794A if I2C select SND_SOC_RT5631 if I2C select SND_SOC_RT5640 if I2C select SND_SOC_RT5645 if I2C -@@ -550,6 +551,14 @@ config SND_SOC_RT298 - tristate - depends on I2C +@@ -631,6 +632,14 @@ config SND_SOC_RT5514 + config SND_SOC_RT5616 + tristate "Realtek RT5616 CODEC" +config SND_SOC_RT298 + tristate @@ -115357,21 +117657,21 @@ index bd38590..b63f2fb 100644 tristate depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 7ba76ba..2147436 100644 +index 7522017..b87e845 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -85,6 +85,7 @@ snd-soc-rl6231-objs := rl6231.o - snd-soc-rl6347a-objs := rl6347a.o - snd-soc-rt286-objs := rt286.o +@@ -98,6 +98,7 @@ snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o + snd-soc-rt5514-objs := rt5514.o + snd-soc-rt5616-objs := rt5616.o +snd-soc-pcm1794a-objs := pcm1794a.o snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-rt5631-objs := rt5631.o snd-soc-rt5640-objs := rt5640.o -@@ -281,6 +282,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o +@@ -308,6 +309,7 @@ obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o + obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o + obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o +obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o @@ -115452,10 +117752,10 @@ index 0000000..afe1b41 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 2b8d51c50a053f52a94bf0965ad472d7e411a737 Mon Sep 17 00:00:00 2001 +From 6328cc72836700f65568fd7b69e5cc81eb5aecb8 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 061/251] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 061/114] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -115495,10 +117795,10 @@ index 8d91470..5795fb1 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -From ef7ccc94b42ad0827735d8fadac43b23548a0b35 Mon Sep 17 00:00:00 2001 +From 6c0cc4423bccc53163746eb1ff6d4a44d1358b76 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 062/251] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 062/114] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -115519,8 +117819,8 @@ adds the sample rate bits in the SPDIF status block. --- sound/soc/bcm/Kconfig | 7 ++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_digi.c | 223 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 232 insertions(+) + sound/soc/bcm/hifiberry_digi.c | 224 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 233 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_digi.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115557,10 +117857,10 @@ index 99c96b4..4d53c58 100644 obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c new file mode 100644 -index 0000000..80732b8 +index 0000000..9840e15 --- /dev/null +++ b/sound/soc/bcm/hifiberry_digi.c -@@ -0,0 +1,223 @@ +@@ -0,0 +1,224 @@ +/* + * ASoC Driver for HifiBerry Digi + * @@ -115727,6 +118027,7 @@ index 0000000..80732b8 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_digi = { + .name = "snd_rpi_hifiberry_digi", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_digi_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), +}; @@ -115785,10 +118086,10 @@ index 0000000..80732b8 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From 9871f390c47d90a75d21d20be88e88aa49536fd5 Mon Sep 17 00:00:00 2001 +From 6e7576347357e152cab8a18b678fe679ec81b68f Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 063/251] ASoC: wm8804: Set idle_bias_off to false Idle bias +Subject: [PATCH 063/114] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -115810,10 +118111,10 @@ index 5795fb1..c846716 100644 .dapm_widgets = wm8804_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), -From bad079610353ec3b8632ca9109da462435b41ba3 Mon Sep 17 00:00:00 2001 +From f03a1430b5f631cfac3bf79d7b0266d628627a39 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 064/251] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 064/114] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -115821,11 +118122,17 @@ The main volume control in the PCM512x DAC has a range up to +24dB. This is dangerously loud and can potentially cause massive clipping in the output stages. Therefore this sets a sensible limit of 0dB for this control. + +Allow up to 24dB digital gain to be applied when using IQAudIO DAC+ + +24db_digital_gain DT param can be used to specify that PCM512x +codec "Digital" volume control should not be limited to 0dB gain, +and if specified will allow the full 24dB gain. --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/iqaudio-dac.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 141 insertions(+) + sound/soc/bcm/iqaudio-dac.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 150 insertions(+) create mode 100644 sound/soc/bcm/iqaudio-dac.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -115859,10 +118166,10 @@ index 4d53c58..08e4dc5 100644 +obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c new file mode 100644 -index 0000000..37038d4 +index 0000000..a5eaa9e --- /dev/null +++ b/sound/soc/bcm/iqaudio-dac.c -@@ -0,0 +1,132 @@ +@@ -0,0 +1,141 @@ +/* + * ASoC Driver for IQaudIO DAC + * @@ -115888,14 +118195,19 @@ index 0000000..37038d4 +#include +#include + ++static bool digital_gain_0db_limit = true; ++ +static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) +{ -+ int ret; -+ struct snd_soc_card *card = rtd->card; ++ if (digital_gain_0db_limit) ++ { ++ int ret; ++ struct snd_soc_card *card = rtd->card; + -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } + + return 0; +} @@ -115937,6 +118249,7 @@ index 0000000..37038d4 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_iqaudio_dac = { + .name = "IQaudIODAC", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_iqaudio_dac_dai, + .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), +}; @@ -115959,6 +118272,9 @@ index 0000000..37038d4 + dai->platform_name = NULL; + dai->platform_of_node = i2s_node; + } ++ ++ digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, ++ "iqaudio,24db_digital_gain"); + } + + ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); @@ -115996,10 +118312,10 @@ index 0000000..37038d4 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From a5a08b66a1ac4a02bc9aaac168e363dd45f28087 Mon Sep 17 00:00:00 2001 +From 8ca6dfd134bd0117e548b050e0af99bd09f1fd92 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 065/251] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 065/114] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -116007,7 +118323,7 @@ Reduces overhead when using X 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index 5dd426f..9ae0cd5 100644 +index ae83af6..4a7af9d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -49,7 +49,7 @@ @@ -116019,7 +118335,7 @@ index 5dd426f..9ae0cd5 100644 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1091,8 +1091,12 @@ static int usbhid_start(struct hid_device *hid) +@@ -1083,8 +1083,12 @@ static int usbhid_start(struct hid_device *hid) } /* Change the polling interval of mice. */ @@ -116035,20 +118351,214 @@ index 5dd426f..9ae0cd5 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From 6181933c3fb422cf92cf1f2720064e48d1f93955 Mon Sep 17 00:00:00 2001 +From 84f1f5340ba06631612745253d8989998e324f5a Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 066/251] Added support for HiFiBerry DAC+ +Subject: [PATCH 066/114] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. + +Add support for the HiFiBerry DAC+ Pro. + +The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. + +An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. + +Limit PCM512x "Digital" gain to 0dB by default with HiFiBerry DAC+ + +24db_digital_gain DT param can be used to specify that PCM512x +codec "Digital" volume control should not be limited to 0dB gain, +and if specified will allow the full 24dB gain. --- - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_dacplus.c | 141 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 150 insertions(+) + drivers/clk/Makefile | 1 + + drivers/clk/clk-hifiberry-dacpro.c | 160 +++++++++++++++++ + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplus.c | 352 +++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/pcm512x.c | 3 +- + 6 files changed, 524 insertions(+), 1 deletion(-) + create mode 100644 drivers/clk/clk-hifiberry-dacpro.c create mode 100644 sound/soc/bcm/hifiberry_dacplus.c +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 46869d6..a202e6f 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o + obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o + obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o + obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o + obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o + obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o + obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o +diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c +new file mode 100644 +index 0000000..3e35d45 +--- /dev/null ++++ b/drivers/clk/clk-hifiberry-dacpro.c +@@ -0,0 +1,160 @@ ++/* ++ * Clock Driver for HiFiBerry DAC Pro ++ * ++ * Author: Stuart MacLean ++ * Copyright 2015 ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++/** ++ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro ++ * @hw: clk_hw for the common clk framework ++ * @mode: 0 => CLK44EN, 1 => CLK48EN ++ */ ++struct clk_hifiberry_hw { ++ struct clk_hw hw; ++ uint8_t mode; ++}; ++ ++#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) ++ ++static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { ++ { .compatible = "hifiberry,dacpro-clk",}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); ++ ++static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : ++ CLK_48EN_RATE; ++} ++ ++static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, ++ unsigned long rate, unsigned long *parent_rate) ++{ ++ long actual_rate; ++ ++ if (rate <= CLK_44EN_RATE) { ++ actual_rate = (long)CLK_44EN_RATE; ++ } else if (rate >= CLK_48EN_RATE) { ++ actual_rate = (long)CLK_48EN_RATE; ++ } else { ++ long diff44Rate = (long)(rate - CLK_44EN_RATE); ++ long diff48Rate = (long)(CLK_48EN_RATE - rate); ++ ++ if (diff44Rate < diff48Rate) ++ actual_rate = (long)CLK_44EN_RATE; ++ else ++ actual_rate = (long)CLK_48EN_RATE; ++ } ++ return actual_rate; ++} ++ ++ ++static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, ++ unsigned long rate, unsigned long parent_rate) ++{ ++ unsigned long actual_rate; ++ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); ++ ++ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, ++ &parent_rate); ++ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; ++ return 0; ++} ++ ++ ++const struct clk_ops clk_hifiberry_dacpro_rate_ops = { ++ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, ++ .round_rate = clk_hifiberry_dacpro_round_rate, ++ .set_rate = clk_hifiberry_dacpro_set_rate, ++}; ++ ++static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) ++{ ++ int ret; ++ struct clk_hifiberry_hw *proclk; ++ struct clk *clk; ++ struct device *dev; ++ struct clk_init_data init; ++ ++ dev = &pdev->dev; ++ ++ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); ++ if (!proclk) ++ return -ENOMEM; ++ ++ init.name = "clk-hifiberry-dacpro"; ++ init.ops = &clk_hifiberry_dacpro_rate_ops; ++ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; ++ init.parent_names = NULL; ++ init.num_parents = 0; ++ ++ proclk->mode = 0; ++ proclk->hw.init = &init; ++ ++ clk = devm_clk_register(dev, &proclk->hw); ++ if (!IS_ERR(clk)) { ++ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, ++ clk); ++ } else { ++ dev_err(dev, "Fail to register clock driver\n"); ++ kfree(proclk); ++ ret = PTR_ERR(clk); ++ } ++ return ret; ++} ++ ++static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) ++{ ++ of_clk_del_provider(pdev->dev.of_node); ++ return 0; ++} ++ ++static struct platform_driver clk_hifiberry_dacpro_driver = { ++ .probe = clk_hifiberry_dacpro_probe, ++ .remove = clk_hifiberry_dacpro_remove, ++ .driver = { ++ .name = "clk-hifiberry-dacpro", ++ .of_match_table = clk_hifiberry_dacpro_dt_ids, ++ }, ++}; ++ ++static int __init clk_hifiberry_dacpro_init(void) ++{ ++ return platform_driver_register(&clk_hifiberry_dacpro_driver); ++} ++core_initcall(clk_hifiberry_dacpro_init); ++ ++static void __exit clk_hifiberry_dacpro_exit(void) ++{ ++ platform_driver_unregister(&clk_hifiberry_dacpro_driver); ++} ++module_exit(clk_hifiberry_dacpro_exit); ++ ++MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:clk-hifiberry-dacpro"); diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig index 38dcdd9..8c338b5 100644 --- a/sound/soc/bcm/Kconfig @@ -116087,15 +118597,15 @@ index 08e4dc5..a29538e 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c new file mode 100644 -index 0000000..11e4f39 +index 0000000..03d8d2a --- /dev/null +++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -0,0 +1,141 @@ +@@ -0,0 +1,352 @@ +/* -+ * ASoC Driver for HiFiBerry DAC+ ++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro + * -+ * Author: Daniel Matuschek -+ * Copyright 2014 ++ * Author: Daniel Matuschek, Stuart MacLean ++ * Copyright 2014-2015 + * based on code by Florian Meier + * + * This program is free software; you can redistribute it and/or @@ -116110,6 +118620,13 @@ index 0000000..11e4f39 + +#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include +#include @@ -116119,34 +118636,233 @@ index 0000000..11e4f39 + +#include "../codecs/pcm512x.h" + ++#define HIFIBERRY_DACPRO_NOCLOCK 0 ++#define HIFIBERRY_DACPRO_CLK44EN 1 ++#define HIFIBERRY_DACPRO_CLK48EN 2 ++ ++struct pcm512x_priv { ++ struct regmap *regmap; ++ struct clk *sclk; ++}; ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++static bool snd_rpi_hifiberry_is_dacpro; ++static bool digital_gain_0db_limit = true; ++ ++static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, ++ int clk_id) ++{ ++ switch (clk_id) { ++ case HIFIBERRY_DACPRO_NOCLOCK: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); ++ break; ++ case HIFIBERRY_DACPRO_CLK44EN: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); ++ break; ++ case HIFIBERRY_DACPRO_CLK48EN: ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); ++ break; ++ } ++} ++ ++static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) ++{ ++ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) ++{ ++ int sck; ++ ++ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); ++ return (!(sck & 0x40)); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( ++ struct snd_soc_codec *codec) ++{ ++ msleep(2); ++ return snd_rpi_hifiberry_dacplus_is_sclk(codec); ++} ++ ++static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) ++{ ++ bool isClk44EN, isClk48En, isNoClk; ++ ++ snd_rpi_hifiberry_dacplus_clk_gpio(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); ++ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); ++ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); ++ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); ++ ++ return (isClk44EN && isClk48En && !isNoClk); ++} ++ ++static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) ++{ ++ int type; ++ ++ switch (sample_rate) { ++ case 11025: ++ case 22050: ++ case 44100: ++ case 88200: ++ case 176400: ++ type = HIFIBERRY_DACPRO_CLK44EN; ++ break; ++ default: ++ type = HIFIBERRY_DACPRO_CLK48EN; ++ break; ++ } ++ return type; ++} ++ ++static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, ++ int sample_rate) ++{ ++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); ++ ++ if (!IS_ERR(pcm512x->sclk)) { ++ int ctype; ++ ++ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); ++ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) ++ ? CLK_44EN_RATE : CLK_48EN_RATE); ++ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); ++ } ++} ++ +static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; ++ struct pcm512x_priv *priv; ++ ++ snd_rpi_hifiberry_is_dacpro ++ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_dai_link *dai = rtd->dai_link; ++ ++ dai->name = "HiFiBerry DAC+ Pro"; ++ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; ++ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBM_CFM; ++ ++ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); ++ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); ++ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); ++ } else { ++ priv = snd_soc_codec_get_drvdata(codec); ++ priv->sclk = ERR_PTR(-ENOENT); ++ } ++ + snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ ++ if (digital_gain_0db_limit) ++ { ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } ++ + return 0; +} + -+static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) ++static int snd_rpi_hifiberry_dacplus_update_rate_den( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); ++ struct snd_ratnum *rats_no_pll; ++ unsigned int num = 0, den = 0; ++ int err; ++ ++ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); ++ if (!rats_no_pll) ++ return -ENOMEM; ++ ++ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; ++ rats_no_pll->den_min = 1; ++ rats_no_pll->den_max = 128; ++ rats_no_pll->den_step = 1; ++ ++ err = snd_interval_ratnum(hw_param_interval(params, ++ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); ++ if (err >= 0 && den) { ++ params->rate_num = num; ++ params->rate_den = den; ++ } ++ ++ devm_kfree(rtd->dev, rats_no_pll); + return 0; +} + -+static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { ++static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( ++ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) ++{ ++ int bratio = snd_pcm_format_physical_width(params_format(params)) ++ * params_channels(params); ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); ++} ++ ++static int snd_rpi_hifiberry_dacplus_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ int ret; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_rpi_hifiberry_dacplus_set_sclk(codec, ++ params_rate(params)); ++ ++ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, ++ params); ++ if (!ret) ++ ret = snd_rpi_hifiberry_dacplus_update_rate_den( ++ substream, params); ++ } else { ++ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++ } ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dacplus_startup( ++ struct snd_pcm_substream *substream) ++{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); ++ ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplus_shutdown( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); +} + +/* machine stream operations */ @@ -116174,6 +118890,7 @@ index 0000000..11e4f39 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_hifiberry_dacplus = { + .name = "snd_rpi_hifiberry_dacplus", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_dacplus_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), +}; @@ -116183,19 +118900,23 @@ index 0000000..11e4f39 + int ret = 0; + + snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ + if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; + -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } ++ dai = &snd_rpi_hifiberry_dacplus_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ ++ digital_gain_0db_limit = !of_property_read_bool( ++ pdev->dev.of_node, "hifiberry,24db_digital_gain"); + } + + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); @@ -116232,11 +118953,25 @@ index 0000000..11e4f39 +MODULE_AUTHOR("Daniel Matuschek "); +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c +index 047c489..090fe0e 100644 +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -854,7 +854,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, + int fssp; + int gpio; + +- lrclk_div = snd_soc_params_to_frame_size(params); ++ lrclk_div = snd_pcm_format_physical_width(params_format(params)) ++ * params_channels(params); + if (lrclk_div == 0) { + dev_err(dev, "No LRCLK?\n"); + return -EINVAL; -From 2804c1880d7b34b85e35eaa503fee6d648c243de Mon Sep 17 00:00:00 2001 +From 85af785da011ab32246855f5d2bbb57354e66feb Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 067/251] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 067/114] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. @@ -116254,12 +118989,12 @@ Some code to load the driver based on device-tree-overlays was missing. This is --- sound/soc/bcm/Kconfig | 7 + sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_amp.c | 127 +++++++++++++++ + sound/soc/bcm/hifiberry_amp.c | 128 +++++++++++++++ sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/tas5713.h | 210 ++++++++++++++++++++++++ - 7 files changed, 721 insertions(+) + 7 files changed, 722 insertions(+) create mode 100644 sound/soc/bcm/hifiberry_amp.c create mode 100644 sound/soc/codecs/tas5713.c create mode 100644 sound/soc/codecs/tas5713.h @@ -116302,10 +119037,10 @@ index a29538e..30db495 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c new file mode 100644 -index 0000000..5903915 +index 0000000..0bb12e4 --- /dev/null +++ b/sound/soc/bcm/hifiberry_amp.c -@@ -0,0 +1,127 @@ +@@ -0,0 +1,128 @@ +/* + * ASoC Driver for HifiBerry AMP + * @@ -116369,6 +119104,7 @@ index 0000000..5903915 + +static struct snd_soc_card snd_rpi_hifiberry_amp = { + .name = "snd_rpi_hifiberry_amp", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_hifiberry_amp_dai, + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), +}; @@ -116434,10 +119170,10 @@ index 0000000..5903915 +MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index b63f2fb..fe32cca 100644 +index 214af16..06be5a2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig -@@ -117,6 +117,7 @@ config SND_SOC_ALL_CODECS +@@ -129,6 +129,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TFA9879 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER @@ -116445,7 +119181,7 @@ index b63f2fb..fe32cca 100644 select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC31XX if I2C select SND_SOC_TLV320AIC32X4 if I2C -@@ -674,6 +675,9 @@ config SND_SOC_TFA9879 +@@ -758,6 +759,9 @@ config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C @@ -116456,10 +119192,10 @@ index b63f2fb..fe32cca 100644 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 2147436..dbb213d 100644 +index b87e845..9974a13 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile -@@ -118,6 +118,7 @@ snd-soc-sti-sas-objs := sti-sas.o +@@ -132,6 +132,7 @@ snd-soc-sti-sas-objs := sti-sas.o snd-soc-tas5086-objs := tas5086.o snd-soc-tas571x-objs := tas571x.o snd-soc-tfa9879-objs := tfa9879.o @@ -116467,7 +119203,7 @@ index 2147436..dbb213d 100644 snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -312,6 +313,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o +@@ -340,6 +341,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o @@ -117067,10 +119803,10 @@ index 0000000..8f019e0 + +#endif /* _TAS5713_H */ -From cb468b5a1270e4819be26c8cacfd0cb6c70be776 Mon Sep 17 00:00:00 2001 +From f8bae62b0dd99d5820498f1e20e77d366af8dcfe Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 068/251] Update ds1307 driver for device-tree support +Subject: [PATCH 068/114] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -117078,10 +119814,10 @@ Signed-off-by: Ryan Coe 1 file changed, 8 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index aa705bb..1cb13fe 100644 +index b2156ee..4ba33ee 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c -@@ -1207,6 +1207,14 @@ static int ds1307_remove(struct i2c_client *client) +@@ -1605,6 +1605,14 @@ static int ds1307_remove(struct i2c_client *client) return 0; } @@ -117097,10 +119833,10 @@ index aa705bb..1cb13fe 100644 .driver = { .name = "rtc-ds1307", -From e545dfb5383a8d5d775818282c7f95ae7a2e1f72 Mon Sep 17 00:00:00 2001 +From 095e4b2962f86a593d2ee02655e5a4ad03701fba Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 069/251] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 069/114] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support @@ -117130,35 +119866,28 @@ See: https://github.com/raspberrypi/linux/issues/1064 create mode 100644 drivers/leds/trigger/ledtrig-input.c diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 5db4515..685a8b5 100644 +index 61143f5..e98df59 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c -@@ -42,6 +42,13 @@ static void gpio_led_work(struct work_struct *work) - led_dat->platform_gpio_blink_set(led_dat->gpiod, - led_dat->new_level, NULL, NULL); +@@ -46,8 +46,15 @@ static void gpio_led_set(struct led_classdev *led_cdev, + led_dat->platform_gpio_blink_set(led_dat->gpiod, level, + NULL, NULL); led_dat->blinking = 0; + } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { + gpiod_direction_input(led_dat->gpiod); + led_dat->cdev.flags &= ~SET_GPIO_INPUT; -+ } -+ else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { -+ gpiod_direction_output(led_dat->gpiod, led_dat->new_level); ++ } else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { ++ gpiod_direction_output(led_dat->gpiod, level); + led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; - } else - gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level); - } -@@ -62,7 +69,8 @@ static void gpio_led_set(struct led_classdev *led_cdev, - * seem to have a reliable way to know if we're already in one; so - * let's just assume the worst. - */ -- if (led_dat->can_sleep) { -+ if (led_dat->can_sleep || -+ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) { - led_dat->new_level = level; - schedule_work(&led_dat->work); } else { -@@ -75,6 +83,13 @@ static void gpio_led_set(struct led_classdev *led_cdev, - } +- if (led_dat->can_sleep) ++ if (led_dat->can_sleep || ++ (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) + gpiod_set_value_cansleep(led_dat->gpiod, level); + else + gpiod_set_value(led_dat->gpiod, level); +@@ -61,6 +68,13 @@ static int gpio_led_set_blocking(struct led_classdev *led_cdev, + return 0; } +static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) @@ -117171,10 +119900,11 @@ index 5db4515..685a8b5 100644 static int gpio_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { -@@ -131,6 +146,7 @@ static int create_gpio_led(const struct gpio_led *template, +@@ -120,6 +134,8 @@ static int create_gpio_led(const struct gpio_led *template, + led_dat->platform_gpio_blink_set = blink_set; led_dat->cdev.blink_set = gpio_blink_set; } - led_dat->cdev.brightness_set = gpio_led_set; ++ led_dat->cdev.brightness_set = gpio_led_set; + led_dat->cdev.brightness_get = gpio_led_get; if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) state = !!gpiod_get_value_cansleep(led_dat->gpiod); @@ -117206,7 +119936,7 @@ index 1abf48d..c03afdc 100644 +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o diff --git a/drivers/leds/trigger/ledtrig-input.c b/drivers/leds/trigger/ledtrig-input.c new file mode 100644 -index 0000000..07d1219 +index 0000000..27f8ebe --- /dev/null +++ b/drivers/leds/trigger/ledtrig-input.c @@ -0,0 +1,54 @@ @@ -117233,13 +119963,13 @@ index 0000000..07d1219 +static void input_trig_activate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_INPUT; -+ led_set_brightness_async(led_cdev, 0); ++ led_set_brightness(led_cdev, 0); +} + +static void input_trig_deactivate(struct led_classdev *led_cdev) +{ + led_cdev->flags |= SET_GPIO_OUTPUT; -+ led_set_brightness_async(led_cdev, 0); ++ led_set_brightness(led_cdev, 0); +} + +static struct led_trigger input_led_trigger = { @@ -117265,24 +119995,24 @@ index 0000000..07d1219 +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); diff --git a/include/linux/leds.h b/include/linux/leds.h -index fa359c7..4b25a1a 100644 +index f203a8f..555cf15 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h -@@ -48,6 +48,9 @@ struct led_classdev { - #define SET_BRIGHTNESS_ASYNC (1 << 21) - #define SET_BRIGHTNESS_SYNC (1 << 22) +@@ -50,6 +50,9 @@ struct led_classdev { + #define LED_SYSFS_DISABLE (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) + #define LED_HW_PLUGGABLE (1 << 24) + /* Additions for Raspberry Pi PWR LED */ +#define SET_GPIO_INPUT (1 << 30) +#define SET_GPIO_OUTPUT (1 << 31) - /* Set LED brightness level */ - /* Must not sleep, use a workqueue if needed */ + /* Set LED brightness level + * Must not sleep. Use brightness_set_blocking for drivers -From f6d9d6ba910f1604a3d488091f052a57f14cd998 Mon Sep 17 00:00:00 2001 +From 1cfd22d5f3cbc9b1c6eadee234f07e9285ae46fe Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 070/251] enc28j60: Add device tree compatible string and an +Subject: [PATCH 070/114] enc28j60: Add device tree compatible string and an overlay --- @@ -117311,10 +120041,10 @@ index 86ea17e..a1b20c1 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From 68eb237af6a1c15b68fb1eff1596d152f06eeaa5 Mon Sep 17 00:00:00 2001 +From 28eeb1b06004f5a4e3e89f516e4678ca3c4c82d9 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 071/251] Add driver for rpi-proto +Subject: [PATCH 071/114] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -117329,8 +120059,8 @@ Signed-off-by: Waldemar Brodkorb --- sound/soc/bcm/Kconfig | 7 +++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 162 insertions(+) + sound/soc/bcm/rpi-proto.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 163 insertions(+) create mode 100644 sound/soc/bcm/rpi-proto.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -117371,10 +120101,10 @@ index 30db495..4f5ab1f 100644 obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o diff --git a/sound/soc/bcm/rpi-proto.c b/sound/soc/bcm/rpi-proto.c new file mode 100644 -index 0000000..c6e45a0 +index 0000000..9db678e --- /dev/null +++ b/sound/soc/bcm/rpi-proto.c -@@ -0,0 +1,153 @@ +@@ -0,0 +1,154 @@ +/* + * ASoC driver for PROTO AudioCODEC (with a WM8731) + * connected to a Raspberry Pi @@ -117468,6 +120198,7 @@ index 0000000..c6e45a0 +/* audio machine driver */ +static struct snd_soc_card snd_rpi_proto = { + .name = "snd_rpi_proto", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_proto_dai, + .num_links = ARRAY_SIZE(snd_rpi_proto_dai), +}; @@ -117529,24 +120260,24 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From d76384c130898ee68885a8cddfbe4686ad41aa0f Mon Sep 17 00:00:00 2001 +From 6f2334146dea18d259dba83c9f89b42caba6efab Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 072/251] config: Add default configs +Subject: [PATCH 072/114] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1254 +++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1265 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 2519 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1262 +++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1271 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 2533 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..16062bf +index 0000000..177745a --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1254 @@ +@@ -0,0 +1,1262 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -117564,12 +120295,12 @@ index 0000000..16062bf +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=m +CONFIG_IKCONFIG_PROC=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y @@ -117589,6 +120320,7 @@ index 0000000..16062bf +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_ARCH_BCM2709=y +# CONFIG_CACHE_L2X0 is not set ++# CONFIG_DEBUG_RODATA is not set +CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_VMSPLIT_2G=y @@ -117648,1260 +120380,6 @@ index 0000000..16062bf +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=m -+CONFIG_IRCOMM=m -+CONFIG_IRDA_ULTRA=y -+CONFIG_IRDA_CACHE_LAST_LSAP=y -+CONFIG_IRDA_FAST_RR=y -+CONFIG_IRTTY_SIR=m -+CONFIG_KINGSUN_DONGLE=m -+CONFIG_KSDAZZLE_DONGLE=m -+CONFIG_KS959_DONGLE=m -+CONFIG_USB_IRDA=m -+CONFIG_SIGMATEL_FIR=m -+CONFIG_MCS_FIR=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_UBI=m -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m -+CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m -+CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m -+CONFIG_USB_NET_SMSC95XX=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_FT6236=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM_VC_SM=y -+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=y -+CONFIG_RAW_DRIVER=y -+CONFIG_I2C=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_SPI=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y -+CONFIG_HWMON=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHTC1=m -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=m -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m -+CONFIG_FB=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_UDL=m -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_MIXER_OSS=m -+CONFIG_SND_PCM_OSS=m -+CONFIG_SND_SEQUENCER_OSS=y -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_BCM2835=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m -+CONFIG_SND_SOC_ADAU1701=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=y -+CONFIG_UHID=m -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m -+CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_LED=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m -+CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+CONFIG_LEDS_TRIGGER_ONESHOT=y -+CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y -+CONFIG_LEDS_TRIGGER_CPU=y -+CONFIG_LEDS_TRIGGER_GPIO=y -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m -+CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_RPI=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9163=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER=y -+CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_KFIFO_BUF=m -+CONFIG_MCP320X=m -+CONFIG_DHT11=m -+CONFIG_PWM_BCM2835=m -+CONFIG_RASPBERRYPI_FIRMWARE=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y -+CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_SMB2=y -+CONFIG_CIFS_FSCACHE=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+CONFIG_DLM=m -+CONFIG_PRINTK_TIME=y -+CONFIG_BOOT_PRINTK_DELAY=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_TIMER_STATS=y -+CONFIG_IRQSOFF_TRACER=y -+CONFIG_SCHED_TRACER=y -+CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set -+CONFIG_FUNCTION_PROFILER=y -+CONFIG_KGDB=y -+CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+CONFIG_CRYPTO_USER_API_SKCIPHER=m -+# CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_AES_ARM_BS=m -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -new file mode 100644 -index 0000000..1d1b799 ---- /dev/null -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1265 @@ -+# CONFIG_ARM_PATCH_PHYS_VIRT is not set -+CONFIG_PHYS_OFFSET=0 -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_FHANDLE=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y -+CONFIG_NAMESPACES=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_EMBEDDED=y -+# CONFIG_COMPAT_BRK is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y -+CONFIG_JUMP_LABEL=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y -+CONFIG_ARCH_BCM2708=y -+CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_UACCESS_WITH_MEMCPY=y -+CONFIG_SECCOMP=y -+# CONFIG_ATAGS is not set -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 -+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_VFP=y -+CONFIG_BINFMT_MISC=m -+# CONFIG_SUSPEND is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m @@ -119179,6 +120657,8 @@ index 0000000..1d1b799 +CONFIG_BT_6LOWPAN=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m @@ -119203,6 +120683,7 @@ index 0000000..1d1b799 +CONFIG_MTD_BLOCK=m +CONFIG_MTD_NAND=m +CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y +CONFIG_ZRAM=m +CONFIG_ZRAM_LZ4_COMPRESS=y +CONFIG_BLK_DEV_LOOP=y @@ -119245,6 +120726,7 @@ index 0000000..1d1b799 +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_ENC28J60=m ++CONFIG_QCA7000=m +CONFIG_MDIO_BITBANG=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m @@ -119296,31 +120778,29 @@ index 0000000..1d1b799 +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m +CONFIG_ATH9K=m +CONFIG_ATH9K_HTC=m +CONFIG_CARL9170=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_USB=m +CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m +CONFIG_B43=m +# CONFIG_B43_PHY_N is not set +CONFIG_B43LEGACY=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_USB=y +CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m @@ -119329,12 +120809,12 @@ index 0000000..1d1b799 +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m ++CONFIG_RTL8187=m +CONFIG_RTL8192CU=m ++CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_IEEE802154_AT86RF230=m +CONFIG_IEEE802154_MRF24J40=m @@ -119388,17 +120868,1280 @@ index 0000000..1d1b799 +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y +CONFIG_RAW_DRIVER=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_BCM2708=m ++CONFIG_I2C_GPIO=m +CONFIG_SPI=y +CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m ++CONFIG_SPI_SPIDEV=y ++CONFIG_PPS=m ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_BCM_VIRT=y ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2760=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_W1_SLAVE_BQ27000=m ++CONFIG_BATTERY_DS2760=m ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_HWMON=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHTC1=m ++CONFIG_THERMAL=y ++CONFIG_THERMAL_BCM2835=y ++CONFIG_WATCHDOG=y ++CONFIG_BCM2835_WDT=m ++CONFIG_UCB1400_CORE=m ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_LIRC=m ++CONFIG_RC_DEVICES=y ++CONFIG_RC_ATI_REMOTE=m ++CONFIG_IR_IMON=m ++CONFIG_IR_MCEUSB=m ++CONFIG_IR_REDRAT3=m ++CONFIG_IR_STREAMZAP=m ++CONFIG_IR_IGUANA=m ++CONFIG_IR_TTUSBIR=m ++CONFIG_RC_LOOPBACK=m ++CONFIG_IR_GPIO_CIR=m ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_STK1160_AC97=y ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_RC=y ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++CONFIG_DVB_USB=m ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_CXUSB=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_VP7045=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_FRIIO=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835=y ++CONFIG_VIDEO_BCM2835_MMAL=m ++CONFIG_RADIO_SI470X=y ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV7640=m ++CONFIG_VIDEO_MT9V011=m ++CONFIG_DRM=m ++CONFIG_DRM_VC4=m ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_UDL=m ++CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m ++CONFIG_BACKLIGHT_GPIO=m ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_MIXER_OSS=m ++CONFIG_SND_PCM_OSS=m ++CONFIG_SND_SEQUENCER_OSS=y ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_BCM2835=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_WM8804_I2C=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HIDRAW=y ++CONFIG_UHID=m ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_ELO=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_PRINTER=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_F81232=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SPI=m ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++CONFIG_LEDS_TRIGGER_GPIO=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_ISL12057=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2835=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m ++CONFIG_STAGING=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_R8723AU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_LIRC_STAGING=y ++CONFIG_LIRC_IMON=m ++CONFIG_LIRC_RPI=m ++CONFIG_LIRC_SASEM=m ++CONFIG_LIRC_SERIAL=m ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_ILI9163=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2835_MBOX=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=m ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_MCP320X=m ++CONFIG_MCP3422=m ++CONFIG_DHT11=m ++CONFIG_PWM_BCM2835=m ++CONFIG_RASPBERRYPI_FIRMWARE=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_QFMT_V1=m ++CONFIG_QFMT_V2=m ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_NTFS_RW=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_SMB2=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_DLM=m ++CONFIG_PRINTK_TIME=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_KPROBE_EVENT is not set ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_USER_API_SKCIPHER=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_AES_ARM_BS=m ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +new file mode 100644 +index 0000000..0b87299 +--- /dev/null ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -0,0 +1,1271 @@ ++# CONFIG_ARM_PATCH_PHYS_VIRT is not set ++CONFIG_PHYS_OFFSET=0 ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_FHANDLE=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_PREEMPT_VOLUNTARY=y ++CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y ++CONFIG_UACCESS_WITH_MEMCPY=y ++CONFIG_SECCOMP=y ++# CONFIG_ATAGS is not set ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=m ++CONFIG_CPU_FREQ_STAT_DETAILS=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++# CONFIG_SUSPEND is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_DIAG=m ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CT_PROTO_DCCP=m ++CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_IEEE802154=m ++CONFIG_IEEE802154_6LOWPAN=m ++CONFIG_MAC802154=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRNET=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_6LOWPAN=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_BT_WILINK=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y ++CONFIG_ZRAM=m ++CONFIG_ZRAM_LZ4_COMPRESS=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_MD_RAID0=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_ENC28J60=m ++CONFIG_QCA7000=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8187=m ++CONFIG_RTL8192CU=m ++CONFIG_USB_ZD1201=m ++CONFIG_ZD1211RW=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_IEEE802154_AT86RF230=m ++CONFIG_IEEE802154_MRF24J40=m ++CONFIG_IEEE802154_CC2520=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_RPISENSE=m ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_FT6236=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y ++CONFIG_DEVPTS_MULTIPLE_INSTANCES=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++CONFIG_RAW_DRIVER=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX_PCA954x=m ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_GPIO=m ++CONFIG_SPI=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m +CONFIG_SPI_SPIDEV=y +CONFIG_PPS=m +CONFIG_PPS_CLIENT_LDISC=m @@ -119604,12 +122347,15 @@ index 0000000..1d1b799 +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_MT9V011=m ++CONFIG_DRM=m ++CONFIG_DRM_VC4=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_UDL=m +CONFIG_FB_SSD1307=m +CONFIG_FB_RPISENSE=m +# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y @@ -119836,14 +122582,12 @@ index 0000000..1d1b799 +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_ISL12057=m +CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m @@ -119859,12 +122603,13 @@ index 0000000..1d1b799 +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_BCM2708=y @@ -119923,6 +122668,7 @@ index 0000000..1d1b799 +CONFIG_IIO_BUFFER_CB=m +CONFIG_IIO_KFIFO_BUF=m +CONFIG_MCP320X=m ++CONFIG_MCP3422=m +CONFIG_DHT11=m +CONFIG_PWM_BCM2835=m +CONFIG_RASPBERRYPI_FIRMWARE=y @@ -119969,7 +122715,6 @@ index 0000000..1d1b799 +CONFIG_NTFS_RW=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_CONFIGFS_FS=y +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m @@ -120073,1439 +122818,10 @@ index 0000000..1d1b799 +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 704b0ef1532a29776c5a9df0fe8d93eabdff6f4d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 073/251] bcm2835: bcm2835_defconfig -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some options in bcm2835_defconfig are now the default and -some have changed. Update to keep functionality. - -No longer available: SCSI_MULTI_LUN and RESOURCE_COUNTERS. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig enable MMC_BCM2835 - -Enable the downstream bcm2835-mmc driver and DMA support. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig enable BCM2708_MBOX - -Enable the mailbox driver. - -Signed-off-by: Noralf Trønnes - -bcm2835: bcm2835_defconfig use FB_BCM2708 - -Enable the bcm2708 framebuffer driver. -Disable the simple framebuffer driver, which matches the -device handed over by u-boot. - -Signed-off-by: Noralf Trønnes - -bcm2835: Merge bcm2835_defconfig with bcmrpi_defconfig - -These commands where used to make this commit: - -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_I2C_BCM2708 -CONFIG_SPI_BCM2708 -CONFIG_SND_BCM2708_SOC_I2S -CONFIG_USB_DWCOTG -CONFIG_LIRC_RPI -EOF - -grep -F -v -f filter merge.cfg > filtered.cfg - -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -ARCH=arm make oldconfig - -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -rm merge.cfg filter filtered.cfg added.cfg defconfig - -ARCH=arm make bcm2835_defconfig -ARCH=arm make oldconfig - -Signed-off-by: Noralf Trønnes - -configs: Incorporate v4.1 dependency changes - -Commit 78e9b7de78bb53e8bc7f4c4a60ebacb250c0c190 added a -dependency on TI_ST instead of selecting it, disabling: -CONFIG_BT_WILINK=m -CONFIG_RADIO_WL128X=m - -Commit 652ccae5cc4e1305fb0a4619947f9ee89d8c7f5a added a -depency on ARM_CRYPTO, disabling: -CONFIG_CRYPTO_SHA*_ARM*=m -CONFIG_CRYPTO_AES_ARM*=m - -Signed-off-by: Noralf Trønnes - -Conflicts: - arch/arm/configs/bcm2709_defconfig - -bcm2835: Sync bcm2835_defconfig with bcmrpi_defconfig - -These commands where used to make this commit: - -: Get changed and new config values from a merge -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -: Remove these options -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_SPI_BCM2708 -EOF - -: Apply filter -grep -F -v -f filter merge.cfg > filtered.cfg - -: Add these options -: watchdog contains the restart/poweroff code. -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_I2C_BCM2835=m -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -: Create new config -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -: Verify -ARCH=arm make oldconfig - -: Update bcm2835_defconfig -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -: Clean up -rm merge.cfg filter filtered.cfg added.cfg defconfig - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 1166 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1140 insertions(+), 26 deletions(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..fdb2e2a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,105 +1,1103 @@ - # CONFIG_LOCALVERSION_AUTO is not set - CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y - CONFIG_FHANDLE=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_BSD_PROCESS_ACCT=y - CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y - CONFIG_LOG_BUF_SHIFT=18 - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y --CONFIG_RESOURCE_COUNTERS=y -+CONFIG_MEMCG=y - CONFIG_CGROUP_PERF=y - CONFIG_CFS_BANDWIDTH=y - CONFIG_RT_GROUP_SCHED=y -+CONFIG_BLK_CGROUP=y - CONFIG_NAMESPACES=y - CONFIG_SCHED_AUTOGROUP=y --CONFIG_RELAY=y - CONFIG_BLK_DEV_INITRD=y --CONFIG_RD_BZIP2=y --CONFIG_RD_LZMA=y --CONFIG_RD_XZ=y --CONFIG_RD_LZO=y - CONFIG_CC_OPTIMIZE_FOR_SIZE=y --CONFIG_KALLSYMS_ALL=y - CONFIG_EMBEDDED=y - # CONFIG_COMPAT_BRK is not set - CONFIG_PROFILING=y --CONFIG_OPROFILE=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y - CONFIG_JUMP_LABEL=y -+CONFIG_CC_STACKPROTECTOR_REGULAR=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_ARCH_MULTI_V6=y - # CONFIG_ARCH_MULTI_V7 is not set - CONFIG_ARCH_BCM=y - CONFIG_ARCH_BCM2835=y --CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_PREEMPT=y - CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y - CONFIG_KSM=y - CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y --CONFIG_CC_STACKPROTECTOR=y -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 - CONFIG_KEXEC=y - CONFIG_CRASH_DUMP=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - CONFIG_VFP=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_BINFMT_MISC=m - # CONFIG_SUSPEND is not set - CONFIG_NET=y - CONFIG_PACKET=y - CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m - CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y - CONFIG_NETWORK_SECMARK=y - CONFIG_NETFILTER=y --CONFIG_CFG80211=y --CONFIG_MAC80211=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=m -+CONFIG_IRCOMM=m -+CONFIG_IRDA_ULTRA=y -+CONFIG_IRDA_CACHE_LAST_LSAP=y -+CONFIG_IRDA_FAST_RR=y -+CONFIG_IRTTY_SIR=m -+CONFIG_KINGSUN_DONGLE=m -+CONFIG_KSDAZZLE_DONGLE=m -+CONFIG_KS959_DONGLE=m -+CONFIG_USB_IRDA=m -+CONFIG_SIGMATEL_FIR=m -+CONFIG_MCS_FIR=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - # CONFIG_STANDALONE is not set -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_ZRAM=m -+CONFIG_ZRAM_LZ4_COMPRESS=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m - CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y --CONFIG_SCSI_MULTI_LUN=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m - CONFIG_SCSI_CONSTANTS=y - CONFIG_SCSI_SCAN_ASYNC=y -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m - CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m - CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m - CONFIG_USB_NET_SMSC95XX=y --CONFIG_ZD1211RW=y --CONFIG_INPUT_EVDEV=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_AT76C50X_USB=m -+CONFIG_USB_ZD1201=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_RTL8187=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_ATH_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_WL_MEDIATEK=y -+CONFIG_MT7601U=m -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM_VC_SM=y -+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m -+CONFIG_RAW_DRIVER=y - CONFIG_I2C=y --CONFIG_I2C_CHARDEV=y --CONFIG_I2C_BCM2835=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_I2C_BCM2835=m - CONFIG_SPI=y --CONFIG_SPI_BCM2835=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y - # CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=y -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y --CONFIG_FB_SIMPLE=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_MIXER_OSS=m -+CONFIG_SND_PCM_OSS=m -+CONFIG_SND_SEQUENCER_OSS=y -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_BCM2835=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=y -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y - CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m - CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_DWC2=y -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_LED=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m - CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y - CONFIG_LEDS_TRIGGER_CPU=y - CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y --CONFIG_LEDS_TRIGGER_TRANSIENT=y --CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y --CONFIG_USB_DWC2=y --CONFIG_USB_DWC2_HOST=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_RPI=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER=y -+CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_KFIFO_BUF=m -+CONFIG_DHT11=m -+CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y -@@ -107,18 +1105,110 @@ CONFIG_EXT3_FS=y - CONFIG_EXT3_FS_POSIX_ACL=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y - CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --# CONFIG_MISC_FILESYSTEMS is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y - CONFIG_NFS_FS=y --CONFIG_NFSD=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" - CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m - CONFIG_NLS_ASCII=y --CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m - CONFIG_NLS_UTF8=y -+CONFIG_DLM=m - CONFIG_PRINTK_TIME=y - CONFIG_BOOT_PRINTK_DELAY=y - CONFIG_DYNAMIC_DEBUG=y -@@ -128,14 +1218,38 @@ CONFIG_DEBUG_INFO=y - CONFIG_UNUSED_SYMBOLS=y - CONFIG_DEBUG_MEMORY_INIT=y - CONFIG_LOCKUP_DETECTOR=y -+CONFIG_TIMER_STATS=y -+# CONFIG_DEBUG_PREEMPT is not set -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y - CONFIG_SCHED_TRACER=y - CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set - CONFIG_FUNCTION_PROFILER=y - CONFIG_TEST_KSTRTOX=y - CONFIG_KGDB=y - CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y - CONFIG_STRICT_DEVMEM=y - CONFIG_DEBUG_LL=y - CONFIG_EARLY_PRINTK=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CRYPTD=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA512=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_HW is not set -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set - # CONFIG_XZ_DEC_ARMTHUMB is not set - -From e3d855ae8766391b2c35d6c61b852e79ca9f9047 Mon Sep 17 00:00:00 2001 +From a1e6971294e3e911c461f9aefdc7882a154a0a9d Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 074/251] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 073/114] rpi-ft5406: Add touchscreen driver for pi LCD display Fix driver detection failure Check that the buffer response is non-zero meaning the touchscreen was detected @@ -121518,10 +122834,10 @@ rpi-ft5406: Use firmware API create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index ae33da7..5935716 100644 +index 8ecdc38..1e4e7a0 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -608,6 +608,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -630,6 +630,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. @@ -121536,7 +122852,7 @@ index ae33da7..5935716 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index cbaa6ab..13ab8c0 100644 +index f42975e..92590b3 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o @@ -121800,10 +123116,10 @@ index 0000000..b27dbee +MODULE_DESCRIPTION("Touchscreen driver for memory based FT5406"); +MODULE_LICENSE("GPL"); -From 7298b88fd999f55dc6dde8cb6288562f68b05e56 Mon Sep 17 00:00:00 2001 +From 3442c1202309c020f8dd61c76574cf414240daed Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 075/251] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 074/114] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use @@ -121812,6 +123128,15 @@ optimised memcpy/memmove/memcmp/memset implementations. arch/arm: Add mmiocpy/set aliases for memcpy/set See: https://github.com/raspberrypi/linux/issues/1082 + +copy_from_user: CPU_SW_DOMAIN_PAN compatibility + +The downstream copy_from_user acceleration must also play nice with +CONFIG_CPU_SW_DOMAIN_PAN. + +See: https://github.com/raspberrypi/linux/issues/1381 + +Signed-off-by: Phil Elwell --- arch/arm/include/asm/string.h | 5 + arch/arm/include/asm/uaccess.h | 3 + @@ -121824,8 +123149,8 @@ See: https://github.com/raspberrypi/linux/issues/1082 arch/arm/lib/memcpymove.h | 506 +++++++++++++++++++++++++++++++++++++ arch/arm/lib/memmove_rpi.S | 61 +++++ arch/arm/lib/memset_rpi.S | 123 +++++++++ - arch/arm/lib/uaccess_with_memcpy.c | 112 +++++++- - 12 files changed, 1365 insertions(+), 6 deletions(-) + arch/arm/lib/uaccess_with_memcpy.c | 120 ++++++++- + 12 files changed, 1373 insertions(+), 6 deletions(-) create mode 100644 arch/arm/lib/arm-mem.h create mode 100644 arch/arm/lib/exports_rpi.c create mode 100644 arch/arm/lib/memcmp_rpi.S @@ -123191,7 +124516,7 @@ index 0000000..7067415 +ENDPROC(memset) +ENDPROC(mmioset) diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index 588bbc2..c29df92 100644 +index 6bd1089..cd17dd1 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -22,6 +22,14 @@ @@ -123209,7 +124534,7 @@ index 588bbc2..c29df92 100644 static int pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) { -@@ -85,7 +93,44 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) +@@ -84,7 +92,44 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) return 1; } @@ -123255,13 +124580,14 @@ index 588bbc2..c29df92 100644 __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) { unsigned long ua_flags; -@@ -138,6 +183,54 @@ out: +@@ -137,6 +182,57 @@ out: return n; } +unsigned long noinline +__copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) +{ ++ unsigned long ua_flags; + int atomic; + + if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { @@ -123293,7 +124619,9 @@ index 588bbc2..c29df92 100644 + if (tocopy > n) + tocopy = n; + ++ ua_flags = uaccess_save_and_enable(); + memcpy(to, (const void *)from, tocopy); ++ uaccess_restore(ua_flags); + to += tocopy; + from += tocopy; + n -= tocopy; @@ -123310,7 +124638,7 @@ index 588bbc2..c29df92 100644 unsigned long arm_copy_to_user(void __user *to, const void *from, unsigned long n) { -@@ -148,7 +241,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -147,7 +243,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) * With frame pointer disabled, tail call optimization kicks in * as well making this test almost invisible. */ @@ -123319,7 +124647,7 @@ index 588bbc2..c29df92 100644 unsigned long ua_flags = uaccess_save_and_enable(); n = __copy_to_user_std(to, from, n); uaccess_restore(ua_flags); -@@ -157,6 +250,21 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) +@@ -156,6 +252,26 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n) } return n; } @@ -123334,18 +124662,23 @@ index 588bbc2..c29df92 100644 + * With frame pointer disabled, tail call optimization kicks in + * as well making this test almost invisible. + */ -+ if (n < COPY_FROM_USER_THRESHOLD) -+ return __copy_from_user_std(to, from, n); -+ return __copy_from_user_memcpy(to, from, n); ++ if (n < COPY_TO_USER_THRESHOLD) { ++ unsigned long ua_flags = uaccess_save_and_enable(); ++ n = __copy_from_user_std(to, from, n); ++ uaccess_restore(ua_flags); ++ } else { ++ n = __copy_from_user_memcpy(to, from, n); ++ } ++ return n; +} static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From e8f27792e51eda819e6918697a67dc85a2d2fc13 Mon Sep 17 00:00:00 2001 +From 0813a534e8677a29f014d32722f373e42bf2aa93 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 076/251] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 075/114] gpio-poweroff: Allow it to work on Raspberry Pi The Raspberry Pi firmware manages the power-down and reboot process. To do this it installs a pm_power_off handler, causing @@ -123380,4442 +124713,10 @@ index be3d81f..a030ae9 100644 "%s: pm_power_off function already registered", __func__); -From e1cb11c1118f942ad55724ec8036065cbba41a62 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 077/251] spidev: Add "spidev" compatible string to silence - warning - -See: https://github.com/raspberrypi/linux/issues/1054 ---- - drivers/spi/spidev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index d0e7dfc..57b0760 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -695,6 +695,7 @@ static struct class *spidev_class; - static const struct of_device_id spidev_dt_ids[] = { - { .compatible = "rohm,dh2228fv" }, - { .compatible = "lineartechnology,ltc2488" }, -+ { .compatible = "spidev" }, - {}, - }; - MODULE_DEVICE_TABLE(of, spidev_dt_ids); - -From e74c88c3ce4685417d4a3aee8ce6cd22092c5315 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 17:00:18 +0100 -Subject: [PATCH 078/251] scripts/dtc: Add overlay support - ---- - scripts/dtc/checks.c | 119 ++- - scripts/dtc/dtc-lexer.l | 5 + - scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++----- - scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++++++--------------- - scripts/dtc/dtc-parser.tab.h_shipped | 107 +- - scripts/dtc/dtc-parser.y | 23 +- - scripts/dtc/dtc.c | 9 +- - scripts/dtc/dtc.h | 38 + - scripts/dtc/flattree.c | 141 ++- - scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1685 insertions(+), 1145 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index e81a8c7..efd1bc6 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -458,21 +458,91 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -+ struct fixup *f, **fp; -+ struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -+ int has_phandle_refs; -+ -+ has_phandle_refs = 0; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ has_phandle_refs = 1; -+ break; -+ } -+ -+ if (!has_phandle_refs) -+ return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -+ if (!refnode && !symbol_fixup_support) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); -+ if (!refnode) { -+ /* allocate fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* search for an already existing fixup */ -+ for_each_fixup(dt, f) -+ if (strcmp(f->ref, m->ref) == 0) -+ break; -+ -+ /* no fixup found, add new */ -+ if (f == NULL) { -+ f = xmalloc(sizeof(*f)); -+ f->ref = m->ref; -+ f->entries = NULL; -+ f->next = NULL; -+ -+ /* add it to the tree */ -+ fp = &dt->fixups; -+ while (*fp) -+ fp = &(*fp)->next; -+ *fp = f; -+ } -+ -+ /* and now append fixup entry */ -+ fep = &f->entries; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ -+ /* mark the entry as unresolved */ -+ phandle = 0xdeadbeef; -+ } else { -+ phandle = get_node_phandle(dt, refnode); -+ -+ /* if it's a plugin, we need to record it */ -+ if (symbol_fixup_support && dt->is_plugin) { -+ -+ /* allocate a new local fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* append it to the local fixups */ -+ fep = &dt->local_fixups; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ } -+ } -+ -+ *((cell_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(phandle); - } - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -@@ -652,6 +722,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - -+static void check_auto_label_phandles(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct label *l; -+ struct symbol *s, **sp; -+ int has_label; -+ -+ if (!symbol_fixup_support) -+ return; -+ -+ has_label = 0; -+ for_each_label(node->labels, l) { -+ has_label = 1; -+ break; -+ } -+ -+ if (!has_label) -+ return; -+ -+ /* force allocation of a phandle for this node */ -+ (void)get_node_phandle(dt, node); -+ -+ /* add the symbol */ -+ for_each_label(node->labels, l) { -+ -+ s = xmalloc(sizeof(*s)); -+ s->label = l; -+ s->node = node; -+ s->next = NULL; -+ -+ /* add it to the symbols list */ -+ sp = &dt->symbols; -+ while (*sp) -+ sp = &((*sp)->next); -+ *sp = s; -+ } -+} -+NODE_WARNING(auto_label_phandles, NULL); -+ - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -670,6 +779,8 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -+ &auto_label_phandles, -+ - &always_fail, - }; - -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 0ee1caf..dd44ba2 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 11cd78e..1518525 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -9,7 +9,7 @@ - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 - #define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 39 -+#define YY_FLEX_SUBMINOR_VERSION 35 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -162,12 +162,7 @@ typedef unsigned int flex_uint32_t; - typedef struct yy_buffer_state *YY_BUFFER_STATE; - #endif - --#ifndef YY_TYPEDEF_YY_SIZE_T --#define YY_TYPEDEF_YY_SIZE_T --typedef size_t yy_size_t; --#endif -- --extern yy_size_t yyleng; -+extern int yyleng; - - extern FILE *yyin, *yyout; - -@@ -176,7 +171,6 @@ extern FILE *yyin, *yyout; - #define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) -- #define YY_LINENO_REWIND_TO(ptr) - - /* Return all but the first "n" matched characters back to the input stream. */ - #define yyless(n) \ -@@ -194,6 +188,11 @@ extern FILE *yyin, *yyout; - - #define unput(c) yyunput( c, (yytext_ptr) ) - -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ - #ifndef YY_STRUCT_YY_BUFFER_STATE - #define YY_STRUCT_YY_BUFFER_STATE - struct yy_buffer_state -@@ -211,7 +210,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- yy_size_t yy_n_chars; -+ int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -281,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ --yy_size_t yyleng; -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ -+int yyleng; - - /* Points to current character in buffer. */ - static char *yy_c_buf_p = (char *) 0; -@@ -310,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - - YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); - YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - - void *yyalloc (yy_size_t ); - void *yyrealloc (void *,yy_size_t ); -@@ -342,7 +341,7 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap() 1 -+#define yywrap(n) 1 - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; -@@ -373,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -382,25 +381,26 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[159] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst flex_int32_t yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[173] = -+static yyconst flex_int16_t yy_base[180] = - { 0, -- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -- -- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -- 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[173] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[438] = -+static yyconst flex_int16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -- -- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -- -- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[438] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -- -- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -- -- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -662,7 +664,7 @@ static int dts_version = 1; - static void push_input_file(const char *filename); - static bool pop_input_file(void); - static void lexical_error(const char *fmt, ...); --#line 666 "dtc-lexer.lex.c" -+#line 668 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -704,7 +706,7 @@ FILE *yyget_out (void ); - - void yyset_out (FILE * out_str ); - --yy_size_t yyget_leng (void ); -+int yyget_leng (void ); - - char *yyget_text (void ); - -@@ -853,6 +855,10 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - -+#line 68 "dtc-lexer.l" -+ -+#line 861 "dtc-lexer.lex.c" -+ - if ( !(yy_init) ) - { - (yy_init) = 1; -@@ -879,11 +885,6 @@ YY_DECL - yy_load_buffer_state( ); - } - -- { --#line 68 "dtc-lexer.l" -- --#line 886 "dtc-lexer.lex.c" -- - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); -@@ -901,7 +902,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; -+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -910,13 +911,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 158 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -1007,23 +1008,31 @@ case 5: - YY_RULE_SETUP - #line 116 "dtc-lexer.l" - { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 121 "dtc-lexer.l" -+{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 122 "dtc-lexer.l" -+#line 127 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 128 "dtc-lexer.l" -+#line 133 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1031,9 +1040,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 135 "dtc-lexer.l" -+#line 140 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1041,9 +1050,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 142 "dtc-lexer.l" -+#line 147 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1051,9 +1060,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 149 "dtc-lexer.l" -+#line 154 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1073,10 +1082,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 168 "dtc-lexer.l" -+#line 173 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1098,18 +1107,18 @@ YY_RULE_SETUP - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 189 "dtc-lexer.l" -+#line 194 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 195 "dtc-lexer.l" -+#line 200 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1117,27 +1126,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 202 "dtc-lexer.l" -+#line 207 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 208 "dtc-lexer.l" -+#line 213 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 214 "dtc-lexer.l" -+#line 219 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1146,75 +1155,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 222 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 227 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 228 "dtc-lexer.l" --/* eat C-style comments */ -+#line 232 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 229 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 233 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 231 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 234 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 232 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 236 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 233 "dtc-lexer.l" --{ return DT_LE; }; -+#line 237 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 234 "dtc-lexer.l" --{ return DT_GE; }; -+#line 238 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 235 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 239 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 236 "dtc-lexer.l" --{ return DT_NE; }; -+#line 240 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 237 "dtc-lexer.l" --{ return DT_AND; }; -+#line 241 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 238 "dtc-lexer.l" --{ return DT_OR; }; -+#line 242 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 240 "dtc-lexer.l" -+#line 243 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 245 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1230,12 +1239,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 255 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1239 "dtc-lexer.lex.c" -+#line 1248 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1365,7 +1374,6 @@ ECHO; - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -- } /* end of user's declarations */ - } /* end of yylex */ - - /* yy_get_next_buffer - try to read in a new buffer -@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) - - else - { -- yy_size_t num_to_read = -+ int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { -- yy_size_t new_size = b->yy_buf_size * 2; -+ int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -- (yy_n_chars), num_to_read ); -+ (yy_n_chars), (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } -@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 158); -+ yy_is_jam = (yy_current_state == 165); - -- return yy_is_jam ? 0 : yy_current_state; -+ return yy_is_jam ? 0 : yy_current_state; - } - - #ifndef YY_NO_INPUT -@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); -+ int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) - */ - static void yyensure_buffer_stack (void) - { -- yy_size_t num_to_alloc; -+ int num_to_alloc; - - if (!(yy_buffer_stack)) { - -@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- yy_size_t i; -+ int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; -@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --yy_size_t yyget_leng (void) -+int yyget_leng (void) - { - return yyleng; - } -@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 254 "dtc-lexer.l" -+#line 260 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 116458c..2c1784e 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 2.5. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "3.0.2" -+#define YYBISON_VERSION "2.5" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -58,13 +58,18 @@ - /* Pull parsers. */ - #define YYPULL 1 - -+/* Using locations. */ -+#define YYLSP_NEEDED 1 - - - - /* Copy the first part of user declarations. */ --#line 20 "dtc-parser.y" /* yacc.c:339 */ -+ -+/* Line 268 of yacc.c */ -+#line 20 "dtc-parser.y" - - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -80,15 +85,14 @@ extern void yyerror(char const *s); - extern struct boot_info *the_boot_info; - extern bool treesource_error; - --#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ - --# ifndef YY_NULLPTR --# if defined __cplusplus && 201103L <= __cplusplus --# define YY_NULLPTR nullptr --# else --# define YY_NULLPTR 0 --# endif --# endif -+/* Line 268 of yacc.c */ -+#line 91 "dtc-parser.tab.c" -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif - - /* Enabling verbose error messages. */ - #ifdef YYERROR_VERBOSE -@@ -98,53 +102,51 @@ extern bool treesource_error; - # define YYERROR_VERBOSE 0 - #endif - --/* In a future release of Bison, this section will be replaced -- by #include "dtc-parser.tab.h". */ --#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED --# define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Debug traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif --#if YYDEBUG --extern int yydebug; -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 - #endif - --/* Token type. */ -+ -+/* Tokens. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- enum yytokentype -- { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -- }; -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - --/* Value type. */ -+ -+ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; --union YYSTYPE -+typedef union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:355 */ -+ -+/* Line 293 of yacc.c */ -+#line 39 "dtc-parser.y" - - char *propnodename; - char *labelref; -@@ -162,37 +164,37 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - --#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ --}; -+ -+ -+/* Line 293 of yacc.c */ -+#line 173 "dtc-parser.tab.c" -+} YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE YYLTYPE; --struct YYLTYPE -+typedef struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --}; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - - --extern YYSTYPE yylval; --extern YYLTYPE yylloc; --int yyparse (void); -- --#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -- - /* Copy the second part of user declarations. */ - --#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ -+ -+/* Line 343 of yacc.c */ -+#line 198 "dtc-parser.tab.c" - - #ifdef short - # undef short -@@ -206,8 +208,11 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#else -+#elif (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - typedef signed char yytype_int8; -+#else -+typedef short int yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -227,7 +232,8 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T -+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -241,68 +247,39 @@ typedef short int yytype_int16; - # if defined YYENABLE_NLS && YYENABLE_NLS - # if ENABLE_NLS - # include /* INFRINGES ON USER NAME SPACE */ --# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -+# define YY_(msgid) dgettext ("bison-runtime", msgid) - # endif - # endif - # ifndef YY_ --# define YY_(Msgid) Msgid --# endif --#endif -- --#ifndef YY_ATTRIBUTE --# if (defined __GNUC__ \ -- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C --# define YY_ATTRIBUTE(Spec) __attribute__(Spec) --# else --# define YY_ATTRIBUTE(Spec) /* empty */ --# endif --#endif -- --#ifndef YY_ATTRIBUTE_PURE --# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) --#endif -- --#ifndef YY_ATTRIBUTE_UNUSED --# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) --#endif -- --#if !defined _Noreturn \ -- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) --# if defined _MSC_VER && 1200 <= _MSC_VER --# define _Noreturn __declspec (noreturn) --# else --# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -+# define YY_(msgid) msgid - # endif - #endif - - /* Suppress unused-variable warnings by "using" E. */ - #if ! defined lint || defined __GNUC__ --# define YYUSE(E) ((void) (E)) -+# define YYUSE(e) ((void) (e)) - #else --# define YYUSE(E) /* empty */ -+# define YYUSE(e) /* empty */ - #endif - --#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ --/* Suppress an incorrect diagnostic about yylval being uninitialized. */ --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -- _Pragma ("GCC diagnostic push") \ -- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") --# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -- _Pragma ("GCC diagnostic pop") -+/* Identity function, used to suppress warnings about constant conditions. */ -+#ifndef lint -+# define YYID(n) (n) - #else --# define YY_INITIAL_VALUE(Value) Value --#endif --#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN --# define YY_IGNORE_MAYBE_UNINITIALIZED_END -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static int -+YYID (int yyi) -+#else -+static int -+YYID (yyi) -+ int yyi; - #endif --#ifndef YY_INITIAL_VALUE --# define YY_INITIAL_VALUE(Value) /* Nothing. */ -+{ -+ return yyi; -+} - #endif - -- - #if ! defined yyoverflow || YYERROR_VERBOSE - - /* The parser invokes alloca or malloc; define the necessary symbols. */ -@@ -320,9 +297,9 @@ typedef short int yytype_int16; - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - # include /* INFRINGES ON USER NAME SPACE */ -- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 - # endif -@@ -332,8 +309,8 @@ typedef short int yytype_int16; - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's 'empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -349,7 +326,7 @@ typedef short int yytype_int16; - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -357,13 +334,15 @@ typedef short int yytype_int16; - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS -+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS -+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -373,8 +352,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc -@@ -400,35 +379,35 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (0) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (YYID (0)) - - #endif - - #if defined YYCOPY_NEEDED && YYCOPY_NEEDED --/* Copy COUNT objects from SRC to DST. The source and destination do -+/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ - # ifndef YYCOPY - # if defined __GNUC__ && 1 < __GNUC__ --# define YYCOPY(Dst, Src, Count) \ -- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) - # else --# define YYCOPY(Dst, Src, Count) \ -- do \ -- { \ -- YYSIZE_T yyi; \ -- for (yyi = 0; yyi < (Count); yyi++) \ -- (Dst)[yyi] = (Src)[yyi]; \ -- } \ -- while (0) -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (YYID (0)) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -439,39 +418,37 @@ union yyalloc - #define YYLAST 136 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 47 -+#define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 29 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 80 --/* YYNSTATES -- Number of states. */ --#define YYNSTATES 144 -+#define YYNRULES 82 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 147 - --/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -- by yylex, with out-of-bounds checking. */ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 278 -+#define YYMAXUTOK 279 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -- as returned by yylex, without out-of-bounds checking. */ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, -+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, -+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -486,292 +463,335 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - }; - - #if YYDEBUG -- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const yytype_uint16 yyprhs[] = -+{ -+ 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, -+ 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, -+ 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, -+ 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, -+ 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, -+ 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, -+ 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, -+ 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, -+ 262, 265, 269 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yytype_int8 yyrhs[] = -+{ -+ 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, -+ 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, -+ 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, -+ 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, -+ -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, -+ 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, -+ -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, -+ -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, -+ 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, -+ 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, -+ 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, -+ 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, -+ -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, -+ -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, -+ 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, -+ -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, -+ 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, -+ -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, -+ -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, -+ -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, -+ 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, -+ -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, -+ -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, -+ -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, -+ 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, -+ 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, -+ 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, -+ 76, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -- 465 -+ 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -+ 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, -+ 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, -+ 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, -+ 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, -+ 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, -+ 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, -+ 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, -+ 474, 478, 482 - }; - #endif - --#if YYDEBUG || YYERROR_VERBOSE || 0 -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE - /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -+ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -+ "integer_prim", "integer_expr", "integer_trinary", "integer_or", -+ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -+ "integer_eq", "integer_rela", "integer_shift", "integer_add", -+ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[NUM] -- (External) token number corresponding to the -- (internal) symbol number NUM (which must be that of a token). */ -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -- 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -+ 94, 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --#define YYPACT_NINF -81 -- --#define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-81))) -- --#define YYTABLE_NINF -1 -- --#define yytable_value_is_error(Yytable_value) \ -- 0 -- -- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --static const yytype_int8 yypact[] = -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -- 74, 25, 75, -81 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, -+ 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, -+ 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, -+ 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, -+ 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, -+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, -+ 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, -+ 76, 76, 76 - }; - -- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE does not specify something else to do. Zero -- means the default is an error. */ --static const yytype_uint8 yydefact[] = -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -- 0, 0, 0, 23 -+ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -+ 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, -+ 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, -+ 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, -+ 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, -+ 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, -+ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, -+ 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, -+ 2, 3, 2 - }; - -- /* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const yytype_uint8 yydefact[] = - { -- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -- 37, 27, 34, 38, -14, -81, 22, 24 -+ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -+ 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, -+ 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, -+ 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, -+ 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, -+ 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, -+ 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, -+ 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, -+ 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, -+ 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, -+ 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, -+ 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, -+ 23, 0, 26, 0, 0, 0, 25 - }; - -- /* YYDEFGOTO[NTERM-NUM]. */ -+/* YYDEFGOTO[NTERM-NUM]. */ - static const yytype_int16 yydefgoto[] = - { -- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 128, 94, 95 -+ -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, -+ 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, -+ 31, 32, 33, 34, 35, 36, 131, 97, 98 - }; - -- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule whose -- number is the opposite. If YYTABLE_NINF, syntax error. */ --static const yytype_uint8 yytable[] = -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -84 -+static const yytype_int8 yypact[] = - { -- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -- 0, 0, 75, 140, 0, 0, 142 -+ 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, -+ 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, -+ -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, -+ 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, -+ 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, -+ 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, -+ 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, -+ -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, -+ -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, -+ -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, -+ -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, -+ 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, -+ -84, 24, -84, 77, 24, 80, -84 - }; - --static const yytype_int16 yycheck[] = -+/* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -- -1, -1, 50, 138, -1, -1, 141 -+ -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, -+ -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, -+ 82, 29, 18, 25, 26, -17, -84, 20, 28 - }; - -- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -1 -+static const yytype_uint8 yytable[] = - { -- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -- 58, 33, 58, 34 -+ 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, -+ 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, -+ 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, -+ 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, -+ 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, -+ 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, -+ 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, -+ 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, -+ 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, -+ 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, -+ 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, -+ 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, -+ 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 143, 0, 78, 145 - }; - -- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = -+#define yypact_value_is_default(yystate) \ -+ ((yystate) == (-84)) -+ -+#define yytable_value_is_error(yytable_value) \ -+ YYID (0) -+ -+static const yytype_int16 yycheck[] = - { -- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -- 74 -+ 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, -+ 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, -+ 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, -+ 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, -+ 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, -+ 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, -+ 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, -+ 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, -+ 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, -+ 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, -+ 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, -+ 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, -+ 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, -+ -1, -1, -1, 141, -1, 53, 144 - }; - -- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -- 2 -+ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -+ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -+ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -+ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -+ 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, -+ 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, -+ 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, -+ 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, -+ 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, -+ 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, -+ 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, -+ 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, -+ 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, -+ 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, -+ 32, 34, 35, 60, 34, 60, 35 - }; - -- --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. However, -+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated -+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is -+ discussed. */ -+ -+#define YYFAIL goto yyerrlab -+#if defined YYFAIL -+ /* This is here to suppress warnings from the GCC cpp's -+ -Wunused-macros. Normally we don't worry about that warning, but -+ some users do, and we want to make it easy for users to remove -+ YYFAIL uses, which will produce warnings from Bison 2.5. */ -+#endif - - #define YYRECOVERING() (!!yyerrstatus) - --#define YYBACKUP(Token, Value) \ --do \ -- if (yychar == YYEMPTY) \ -- { \ -- yychar = (Token); \ -- yylval = (Value); \ -- YYPOPSTACK (yylen); \ -- yystate = *yyssp; \ -- goto yybackup; \ -- } \ -- else \ -- { \ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ YYPOPSTACK (1); \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (0) -+ YYERROR; \ -+ } \ -+while (YYID (0)) -+ - --/* Error token number */ --#define YYTERROR 1 --#define YYERRCODE 256 -+#define YYTERROR 1 -+#define YYERRCODE 256 - - - /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - #ifndef YYLLOC_DEFAULT --# define YYLLOC_DEFAULT(Current, Rhs, N) \ -- do \ -- if (N) \ -- { \ -- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -- } \ -- else \ -- { \ -- (Current).first_line = (Current).last_line = \ -- YYRHSLOC (Rhs, 0).last_line; \ -- (Current).first_column = (Current).last_column = \ -- YYRHSLOC (Rhs, 0).last_column; \ -- } \ -- while (0) -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (YYID (N)) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (YYID (0)) - #endif - --#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -- -- --/* Enable debugging if requested. */ --#if YYDEBUG -- --# ifndef YYFPRINTF --# include /* INFRINGES ON USER NAME SPACE */ --# define YYFPRINTF fprintf --# endif -- --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (0) -- - - /* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know -@@ -779,73 +799,82 @@ do { \ - - #ifndef YY_LOCATION_PRINT - # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif - --/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - --YY_ATTRIBUTE_UNUSED --static unsigned --yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) --{ -- unsigned res = 0; -- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -- if (0 <= yylocp->first_line) -- { -- res += YYFPRINTF (yyo, "%d", yylocp->first_line); -- if (0 <= yylocp->first_column) -- res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -- } -- if (0 <= yylocp->last_line) -- { -- if (yylocp->first_line < yylocp->last_line) -- { -- res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -- if (0 <= end_col) -- res += YYFPRINTF (yyo, ".%d", end_col); -- } -- else if (0 <= end_col && yylocp->first_column < end_col) -- res += YYFPRINTF (yyo, "-%d", end_col); -- } -- return res; -- } -+/* YYLEX -- calling `yylex' with the right arguments. */ - --# define YY_LOCATION_PRINT(File, Loc) \ -- yy_location_print_ (File, &(Loc)) -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (YYLEX_PARAM) -+#else -+# define YYLEX yylex () -+#endif - --# else --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf - # endif --#endif - -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (YYID (0)) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value, Location); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (0) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (YYID (0)) - - --/*----------------------------------------. --| Print this symbol's value on YYOUTPUT. | --`----------------------------------------*/ -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ - -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif - { -- FILE *yyo = yyoutput; -- YYUSE (yyo); -- YYUSE (yylocationp); - if (!yyvaluep) - return; -+ YYUSE (yylocationp); - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# else -+ YYUSE (yyoutput); - # endif -- YYUSE (yytype); -+ switch (yytype) -+ { -+ default: -+ break; -+ } - } - - -@@ -853,11 +882,23 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif - { -- YYFPRINTF (yyoutput, "%s %s (", -- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); -@@ -870,8 +911,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL - | TOP (included). | - `------------------------------------------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -+#else -+static void -+yy_stack_print (yybottom, yytop) -+ yytype_int16 *yybottom; -+ yytype_int16 *yytop; -+#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -882,42 +931,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (0) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (YYID (0)) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -+#else - static void --yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -+yy_reduce_print (yyvsp, yylsp, yyrule) -+ YYSTYPE *yyvsp; -+ YYLTYPE *yylsp; -+ int yyrule; -+#endif - { -- unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -+ unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, -- yystos[yyssp[yyi + 1 - yynrhs]], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- , &(yylsp[(yyi + 1) - (yynrhs)]) ); -+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ --} while (0) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyvsp, yylsp, Rule); \ -+} while (YYID (0)) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -931,7 +988,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -954,8 +1011,15 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) -+#else -+static YYSIZE_T -+yystrlen (yystr) -+ const char *yystr; -+#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -971,8 +1035,16 @@ yystrlen (const char *yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) -+#else -+static char * -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1002,27 +1074,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1045,11 +1117,12 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); - YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = YY_NULLPTR; -+ const char *yyformat = 0; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1057,6 +1130,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -+ - Assume YYFAIL is not used. It's too flawed to consider. See -+ -+ for details. YYERROR is fine as it does not invoke this -+ function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1105,13 +1182,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - break; - } - yyarg[yycount++] = yytname[yyx]; -- { -- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); -- if (! (yysize <= yysize1 -- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -- } -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ if (! (yysize <= yysize1 -+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; - } - } - } -@@ -1131,12 +1206,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - # undef YYCASE_ - } - -- { -- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); -- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -- } -+ yysize1 = yysize + yystrlen (yyformat); -+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; - - if (*yymsg_alloc < yysize) - { -@@ -1173,21 +1246,50 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void - yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep, yylocationp) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+ YYLTYPE *yylocationp; -+#endif - { - YYUSE (yyvaluep); - YYUSE (yylocationp); -+ - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -- YYUSE (yytype); -- YY_IGNORE_MAYBE_UNINITIALIZED_END -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } - } - - -+/* Prevent warnings from -Wmissing-prototypes. */ -+#ifdef YYPARSE_PARAM -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void *YYPARSE_PARAM); -+#else -+int yyparse (); -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ - - - /* The lookahead symbol. */ -@@ -1195,12 +1297,10 @@ int yychar; - - /* The semantic value of the lookahead symbol. */ - YYSTYPE yylval; -+ - /* Location data for the lookahead symbol. */ --YYLTYPE yylloc --# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -- = { 1, 1, 1, 1 } --# endif --; -+YYLTYPE yylloc; -+ - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1209,19 +1309,38 @@ int yynerrs; - | yyparse. | - `----------*/ - -+#ifdef YYPARSE_PARAM -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void *YYPARSE_PARAM) -+#else -+int -+yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- 'yyss': related to states. -- 'yyvs': related to semantic values. -- 'yyls': related to locations. -+ `yyss': related to states. -+ `yyvs': related to semantic values. -+ `yyls': related to locations. - -- Refer to the stacks through separate pointers, to allow yyoverflow -+ Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ -@@ -1247,7 +1366,7 @@ yyparse (void) - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ -- int yytoken = 0; -+ int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -@@ -1266,9 +1385,10 @@ yyparse (void) - Keep to zero when no symbol should be popped. */ - int yylen = 0; - -- yyssp = yyss = yyssa; -- yyvsp = yyvs = yyvsa; -- yylsp = yyls = yylsa; -+ yytoken = 0; -+ yyss = yyssa; -+ yyvs = yyvsa; -+ yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1277,7 +1397,21 @@ yyparse (void) - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -- yylsp[0] = yylloc; -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ yylsp = yyls; -+ -+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ /* Initialize the default location before parsing starts. */ -+ yylloc.first_line = yylloc.last_line = 1; -+ yylloc.first_column = yylloc.last_column = 1; -+#endif -+ - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1298,26 +1432,26 @@ yyparse (void) - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- YYLTYPE *yyls1 = yyls; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yyls1, yysize * sizeof (*yylsp), -- &yystacksize); -- -- yyls = yyls1; -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1325,23 +1459,23 @@ yyparse (void) - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -- YYSTACK_RELOCATE (yyls_alloc, yyls); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ -@@ -1351,10 +1485,10 @@ yyparse (void) - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1383,7 +1517,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = yylex (); -+ yychar = YYLEX; - } - - if (yychar <= YYEOF) -@@ -1423,9 +1557,7 @@ yybackup: - yychar = YYEMPTY; - - yystate = yyn; -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -- YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - -@@ -1448,7 +1580,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- '$$ = $1'. -+ `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1463,273 +1595,322 @@ yyreduce: - switch (yyn) - { - case 2: --#line 105 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 109 "dtc-parser.y" - { -- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -- guess_boot_cpuid((yyvsp[0].node))); -+ (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); -+ (yyvsp[(5) - (5)].node)->is_root = 1; -+ the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), -+ guess_boot_cpuid((yyvsp[(5) - (5)].node))); - } --#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --#line 113 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 119 "dtc-parser.y" - { -- (yyval.re) = NULL; -+ (yyval.is_plugin) = 0; - } --#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --#line 117 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 123 "dtc-parser.y" - { -- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); -+ (yyval.is_plugin) = 1; - } --#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: --#line 124 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 130 "dtc-parser.y" - { -- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); -+ (yyval.re) = NULL; - } --#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: --#line 128 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 134 "dtc-parser.y" - { -- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -- (yyval.re) = (yyvsp[0].re); -+ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); - } --#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: --#line 136 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 141 "dtc-parser.y" - { -- (yyval.node) = name_node((yyvsp[0].node), ""); -+ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); - } --#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: --#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 145 "dtc-parser.y" - { -- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); -+ add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.re) = (yyvsp[(2) - (2)].re); - } --#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: --#line 145 "dtc-parser.y" /* yacc.c:1646 */ -- { -- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -- add_label(&target->labels, (yyvsp[-2].labelref)); -- if (target) -- merge_nodes(target, (yyvsp[0].node)); -- else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[-3].node); -+/* Line 1806 of yacc.c */ -+#line 153 "dtc-parser.y" -+ { -+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); - } --#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: --#line 156 "dtc-parser.y" /* yacc.c:1646 */ -- { -- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); - -- if (target) -- merge_nodes(target, (yyvsp[0].node)); -- else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[-2].node); -+/* Line 1806 of yacc.c */ -+#line 157 "dtc-parser.y" -+ { -+ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); - } --#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: --#line 166 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 162 "dtc-parser.y" - { -- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); - -+ add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); - if (target) -- delete_node(target); -+ merge_nodes(target, (yyvsp[(4) - (4)].node)); - else -- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -- -- -- (yyval.node) = (yyvsp[-3].node); -+ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -+ (yyval.node) = (yyvsp[(1) - (4)].node); - } --#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: --#line 181 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 173 "dtc-parser.y" - { -- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); -+ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[(3) - (3)].node)); -+ else -+ ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); -+ (yyval.node) = (yyvsp[(1) - (3)].node); - } --#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: --#line 188 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 183 "dtc-parser.y" - { -- (yyval.proplist) = NULL; -+ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -+ -+ if (target) -+ delete_node(target); -+ else -+ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[(1) - (4)].node); - } --#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: --#line 192 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 198 "dtc-parser.y" - { -- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); -+ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); - } --#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: --#line 199 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 205 "dtc-parser.y" - { -- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); -+ (yyval.proplist) = NULL; - } --#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: --#line 203 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 209 "dtc-parser.y" - { -- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); -+ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); - } --#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: --#line 207 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 216 "dtc-parser.y" - { -- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); -+ (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); - } --#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: --#line 211 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 220 "dtc-parser.y" - { -- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -- (yyval.prop) = (yyvsp[0].prop); -+ (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); - } --#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: --#line 219 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 224 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); -+ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); - } --#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: --#line 223 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 228 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); -+ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.prop) = (yyvsp[(2) - (2)].prop); - } --#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: --#line 227 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 236 "dtc-parser.y" - { -- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); -+ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); - } --#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: --#line 231 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 240 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); -+ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); - } --#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 23: --#line 235 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 244 "dtc-parser.y" - { -- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); -+ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ } -+ break; -+ -+ case 24: -+ -+/* Line 1806 of yacc.c */ -+#line 248 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -+ } -+ break; -+ -+ case 25: -+ -+/* Line 1806 of yacc.c */ -+#line 252 "dtc-parser.y" -+ { -+ FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); - struct data d; - -- if ((yyvsp[-3].integer) != 0) -- if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) -+ if ((yyvsp[(6) - (9)].integer) != 0) -+ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, -+ (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, - strerror(errno)); - -- d = data_copy_file(f, (yyvsp[-1].integer)); -+ d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); - -- (yyval.data) = data_merge((yyvsp[-8].data), d); -+ (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); - fclose(f); - } --#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --#line 251 "dtc-parser.y" /* yacc.c:1646 */ -+ case 26: -+ -+/* Line 1806 of yacc.c */ -+#line 268 "dtc-parser.y" - { -- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[-4].data), d); -+ (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); - fclose(f); - } --#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --#line 261 "dtc-parser.y" /* yacc.c:1646 */ -+ case 27: -+ -+/* Line 1806 of yacc.c */ -+#line 278 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --#line 268 "dtc-parser.y" /* yacc.c:1646 */ -+ case 28: -+ -+/* Line 1806 of yacc.c */ -+#line 285 "dtc-parser.y" - { - (yyval.data) = empty_data; - } --#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --#line 272 "dtc-parser.y" /* yacc.c:1646 */ -+ case 29: -+ -+/* Line 1806 of yacc.c */ -+#line 289 "dtc-parser.y" - { -- (yyval.data) = (yyvsp[-1].data); -+ (yyval.data) = (yyvsp[(1) - (2)].data); - } --#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --#line 276 "dtc-parser.y" /* yacc.c:1646 */ -+ case 30: -+ -+/* Line 1806 of yacc.c */ -+#line 293 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --#line 283 "dtc-parser.y" /* yacc.c:1646 */ -+ case 31: -+ -+/* Line 1806 of yacc.c */ -+#line 300 "dtc-parser.y" - { - unsigned long long bits; - -- bits = (yyvsp[-1].integer); -+ bits = (yyvsp[(2) - (3)].integer); - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { -- ERROR(&(yylsp[-1]), "Array elements must be" -+ ERROR(&(yylsp[(2) - (3)]), "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } -@@ -1737,23 +1918,25 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } --#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --#line 299 "dtc-parser.y" /* yacc.c:1646 */ -+ case 32: -+ -+/* Line 1806 of yacc.c */ -+#line 316 "dtc-parser.y" - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } --#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --#line 304 "dtc-parser.y" /* yacc.c:1646 */ -+ case 33: -+ -+/* Line 1806 of yacc.c */ -+#line 321 "dtc-parser.y" - { -- if ((yyvsp[-1].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; -+ if ((yyvsp[(1) - (2)].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1762,258 +1945,293 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -- ERROR(&(yylsp[0]), "Value out of range for" -- " %d-bit array element", (yyvsp[-1].array).bits); -+ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[(2) - (2)]), "Value out of range for" -+ " %d-bit array element", (yyvsp[(1) - (2)].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); - } --#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: --#line 323 "dtc-parser.y" /* yacc.c:1646 */ -+ case 34: -+ -+/* Line 1806 of yacc.c */ -+#line 340 "dtc-parser.y" - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); - -- if ((yyvsp[-1].array).bits == 32) -- (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, -+ if ((yyvsp[(1) - (2)].array).bits == 32) -+ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, - REF_PHANDLE, -- (yyvsp[0].labelref)); -+ (yyvsp[(2) - (2)].labelref)); - else -- ERROR(&(yylsp[0]), "References are only allowed in " -+ ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); - } --#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: --#line 337 "dtc-parser.y" /* yacc.c:1646 */ -+ case 35: -+ -+/* Line 1806 of yacc.c */ -+#line 354 "dtc-parser.y" - { -- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); -+ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 36: --#line 346 "dtc-parser.y" /* yacc.c:1646 */ -+ case 38: -+ -+/* Line 1806 of yacc.c */ -+#line 363 "dtc-parser.y" - { -- (yyval.integer) = (yyvsp[-1].integer); -+ (yyval.integer) = (yyvsp[(2) - (3)].integer); - } --#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; -- -- case 39: --#line 357 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } --#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 41: --#line 362 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } --#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 374 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } - break; - - case 43: --#line 367 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } --#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 379 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } - break; - - case 45: --#line 372 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } --#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 384 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } - break; - - case 47: --#line 377 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } --#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 389 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } - break; - - case 49: --#line 382 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } --#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 394 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } - break; - - case 51: --#line 387 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } --#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 399 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } - break; - -- case 52: --#line 388 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } --#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 53: -+ -+/* Line 1806 of yacc.c */ -+#line 404 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } - break; - - case 54: --#line 393 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } --#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; - -- case 55: --#line 394 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } --#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 405 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } - break; - - case 56: --#line 395 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } --#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 410 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } - break; - - case 57: --#line 396 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } --#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 411 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } - break; - - case 58: --#line 400 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } --#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 412 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } - break; - - case 59: --#line 401 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } --#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 413 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -+ break; -+ -+ case 60: -+ -+/* Line 1806 of yacc.c */ -+#line 417 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } - break; - - case 61: --#line 406 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } --#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 418 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } - break; - -- case 62: --#line 407 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } --#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 63: -+ -+/* Line 1806 of yacc.c */ -+#line 423 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } - break; - - case 64: --#line 412 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } --#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -- break; - -- case 65: --#line 413 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } --#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 424 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } - break; - - case 66: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } --#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 429 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } - break; - -- case 69: --#line 420 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = -(yyvsp[0].integer); } --#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 67: -+ -+/* Line 1806 of yacc.c */ -+#line 430 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } - break; - -- case 70: --#line 421 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ case 68: -+ -+/* Line 1806 of yacc.c */ -+#line 431 "dtc-parser.y" -+ { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } - break; - - case 71: --#line 422 "dtc-parser.y" /* yacc.c:1646 */ -- { (yyval.integer) = !(yyvsp[0].integer); } --#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 437 "dtc-parser.y" -+ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } - break; - - case 72: --#line 427 "dtc-parser.y" /* yacc.c:1646 */ -- { -- (yyval.data) = empty_data; -- } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 438 "dtc-parser.y" -+ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } - break; - - case 73: --#line 431 "dtc-parser.y" /* yacc.c:1646 */ -- { -- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); -- } --#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 439 "dtc-parser.y" -+ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } - break; - - case 74: --#line 435 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 444 "dtc-parser.y" - { -- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); -+ (yyval.data) = empty_data; - } --#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: --#line 442 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 448 "dtc-parser.y" - { -- (yyval.nodelist) = NULL; -+ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); - } --#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: --#line 446 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 452 "dtc-parser.y" - { -- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); - } --#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: --#line 450 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 459 "dtc-parser.y" - { -- ERROR(&(yylsp[0]), "Properties must precede subnodes"); -- YYERROR; -+ (yyval.nodelist) = NULL; - } --#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 463 "dtc-parser.y" - { -- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); -+ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); - } --#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 467 "dtc-parser.y" - { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); -+ ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); -+ YYERROR; - } --#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 80: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ -+ -+/* Line 1806 of yacc.c */ -+#line 475 "dtc-parser.y" - { -- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -- (yyval.node) = (yyvsp[0].node); -+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); - } --#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -+ case 81: - --#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ -+/* Line 1806 of yacc.c */ -+#line 479 "dtc-parser.y" -+ { -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -+ } -+ break; -+ -+ case 82: -+ -+/* Line 1806 of yacc.c */ -+#line 483 "dtc-parser.y" -+ { -+ add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -+ (yyval.node) = (yyvsp[(2) - (2)].node); -+ } -+ break; -+ -+ -+ -+/* Line 1806 of yacc.c */ -+#line 2235 "dtc-parser.tab.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2036,7 +2254,7 @@ yyreduce: - *++yyvsp = yyval; - *++yylsp = yyloc; - -- /* Now 'shift' the result of the reduction. Determine what state -+ /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2051,9 +2269,9 @@ yyreduce: - goto yynewstate; - - --/*--------------------------------------. --| yyerrlab -- here on detecting error. | --`--------------------------------------*/ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2104,20 +2322,20 @@ yyerrlab: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval, &yylloc); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2137,7 +2355,7 @@ yyerrorlab: - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; -- /* Do not reclaim the symbols of the rule whose action triggered -+ /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2150,37 +2368,35 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -+ YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp, yylsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - -- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -- YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of -@@ -2209,7 +2425,7 @@ yyabortlab: - yyresult = 1; - goto yyreturn; - --#if !defined yyoverflow || YYERROR_VERBOSE -+#if !defined(yyoverflow) || YYERROR_VERBOSE - /*-------------------------------------------------. - | yyexhaustedlab -- memory exhaustion comes here. | - `-------------------------------------------------*/ -@@ -2228,14 +2444,14 @@ yyreturn: - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule whose action triggered -+ /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp, yylsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2246,12 +2462,18 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- return yyresult; -+ /* Make sure YYID is used. */ -+ return YYID (yyresult); - } --#line 472 "dtc-parser.y" /* yacc.c:1906 */ -+ -+ -+ -+/* Line 2067 of yacc.c */ -+#line 489 "dtc-parser.y" - - - void yyerror(char const *s) - { - ERROR(&yylloc, "%s", s); - } -+ -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 30867c6..0b22bbb 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 2.5. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,55 +26,50 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - --#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED --# define YY_YY_DTC_PARSER_TAB_H_INCLUDED --/* Debug traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif --#if YYDEBUG --extern int yydebug; --#endif - --/* Token type. */ -+/* Tokens. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- enum yytokentype -- { -- DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -- }; -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 -+ }; - #endif - --/* Value type. */ -+ -+ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; --union YYSTYPE -+typedef union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:1909 */ -+ -+/* Line 2068 of yacc.c */ -+#line 39 "dtc-parser.y" - - char *propnodename; - char *labelref; -@@ -92,30 +87,32 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; -+ -+ - --#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ --}; -+/* Line 2068 of yacc.c */ -+#line 96 "dtc-parser.tab.h" -+} YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --/* Location type. */ -+extern YYSTYPE yylval; -+ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE YYLTYPE; --struct YYLTYPE -+typedef struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --}; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - -- --extern YYSTYPE yylval; - extern YYLTYPE yylloc; --int yyparse (void); - --#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 5a897e3..56b9c15 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,6 +19,7 @@ - */ - %{ - #include -+#include - - #include "dtc.h" - #include "srcpos.h" -@@ -52,9 +53,11 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ int is_plugin; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -71,6 +74,7 @@ extern bool treesource_error; - - %type propdata - %type propdataprefix -+%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -101,10 +105,23 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ DT_V1 ';' plugindecl memreserves devicetree - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ $5->is_plugin = $3; -+ $5->is_root = 1; -+ the_boot_info = build_boot_info($4, $5, -+ guess_boot_cpuid($5)); -+ } -+ ; -+ -+plugindecl: -+ /* empty */ -+ { -+ $$ = 0; -+ } -+ | DT_PLUGIN ';' -+ { -+ $$ = 1; - } - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 8c4add6..0cbb14c 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- -+ case '@': -+ symbol_fixup_support = 1; -+ break; - case 'h': - usage(NULL); - default: -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 56212c8..fe45748 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -132,6 +133,25 @@ struct label { - struct label *next; - }; - -+struct fixup_entry { -+ int offset; -+ struct node *node; -+ struct property *prop; -+ struct fixup_entry *next; -+}; -+ -+struct fixup { -+ char *ref; -+ struct fixup_entry *entries; -+ struct fixup *next; -+}; -+ -+struct symbol { -+ struct label *label; -+ struct node *node; -+ struct symbol *next; -+}; -+ - struct property { - bool deleted; - char *name; -@@ -158,6 +178,12 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ -+ int is_root; -+ int is_plugin; -+ struct fixup *fixups; -+ struct symbol *symbols; -+ struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -181,6 +207,18 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - -+#define for_each_fixup(n, f) \ -+ for ((f) = (n)->fixups; (f); (f) = (f)->next) -+ -+#define for_each_fixup_entry(f, fe) \ -+ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -+ -+#define for_each_symbol(n, s) \ -+ for ((s) = (n)->symbols; (s); (s) = (s)->next) -+ -+#define for_each_local_fixup_entry(n, fe) \ -+ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -+ - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index bd99fa2..f439b40 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -262,6 +262,12 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - struct property *prop; - struct node *child; - bool seen_name_prop = false; -+ struct symbol *sym; -+ struct fixup *f; -+ struct fixup_entry *fe; -+ char *name, *s; -+ const char *fullpath; -+ int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -276,8 +282,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -- int nameoff; -- - if (streq(prop->name, "name")) - seen_name_prop = true; - -@@ -310,6 +314,139 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -+ if (!symbol_fixup_support) -+ goto no_symbols; -+ -+ /* add the symbol nodes (if any) */ -+ if (tree->symbols) { -+ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__symbols__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_symbol(tree, sym) { -+ -+ vallen = strlen(sym->node->fullpath); -+ -+ nameoff = stringtable_insert(strbuf, sym->label->label); -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, sym->node->fullpath, -+ strlen(sym->node->fullpath)); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ emit->endnode(etarget, NULL); -+ } -+ -+ /* add the fixup nodes */ -+ if (tree->fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_fixup(tree, f) { -+ -+ namesz = 0; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, -+ fe->prop->name, fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, f->ref); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ } -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+ /* add the local fixup property */ -+ if (tree->local_fixups) { -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__local_fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ namesz = 0; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for : + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_local_fixup_entry(tree, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", -+ fullpath, fe->prop->name, -+ fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, "fixup"); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ -+ emit->endnode(etarget, tree->labels); -+ } -+ -+no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 5b8c7d5..86b7338 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd" -+#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" - -From 682bf3cce9aab7644697e66b2a3e3e9ae5ccdf1c Mon Sep 17 00:00:00 2001 +From 8fa5e143ce9adb6f48f952b89d71990b5a560ae1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 079/251] mfd: Add Raspberry Pi Sense HAT core driver +Subject: [PATCH 076/114] mfd: Add Raspberry Pi Sense HAT core driver --- drivers/input/joystick/Kconfig | 8 + @@ -128025,7 +124926,7 @@ index 0000000..6a41676 +MODULE_AUTHOR("Serge Schneider "); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 4d92df6..c5730dc 100644 +index eea61e3..d2c3b72 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -10,6 +10,14 @@ config MFD_CORE @@ -128044,10 +124945,10 @@ index 4d92df6..c5730dc 100644 tristate "AMD CS5535 and CS5536 southbridge core functions" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index a8b76b8..e6339d2 100644 +index 5eaa6465d..8dc2dde 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile -@@ -194,3 +194,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o +@@ -203,3 +203,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o @@ -128217,10 +125118,10 @@ index 0000000..eea9312 +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index 0f33a78..4caa417 100644 +index ee72c3a..5be1a31 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig -@@ -2506,3 +2506,16 @@ config FB_SM712 +@@ -2502,3 +2502,16 @@ config FB_SM712 This driver is also available as a module. The module will be called sm712fb. If you want to compile it as a module, say M here and read . @@ -128238,10 +125139,10 @@ index 0f33a78..4caa417 100644 + help + This is the framebuffer driver for the Raspberry Pi Sense HAT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile -index 9b086ac..7101277 100644 +index df473d8..474c567 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile -@@ -150,6 +150,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o +@@ -149,6 +149,7 @@ obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o obj-$(CONFIG_FB_MXS) += mxsfb.o obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o obj-$(CONFIG_FB_SIMPLE) += simplefb.o @@ -128681,10 +125582,10 @@ index 0000000..56196dc + +#endif -From 28fda0b00b2fe4e5a5151024124e57a3821c1ec4 Mon Sep 17 00:00:00 2001 +From 8b9a3c692dcb44ba033bb131b4873e035ce5ff76 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 080/251] RaspiDAC3 support +Subject: [PATCH 077/114] RaspiDAC3 support Signed-off-by: Jan Grulich @@ -128697,8 +125598,8 @@ Signed-off-by: Matthias Reichl --- sound/soc/bcm/Kconfig | 8 ++ sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/raspidac3.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 201 insertions(+) + sound/soc/bcm/raspidac3.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 202 insertions(+) create mode 100644 sound/soc/bcm/raspidac3.c diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig @@ -128736,10 +125637,10 @@ index 4f5ab1f..b21e11e 100644 +obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o diff --git a/sound/soc/bcm/raspidac3.c b/sound/soc/bcm/raspidac3.c new file mode 100644 -index 0000000..3cabf5b +index 0000000..e7422e2 --- /dev/null +++ b/sound/soc/bcm/raspidac3.c -@@ -0,0 +1,191 @@ +@@ -0,0 +1,192 @@ +/* + * ASoC Driver for RaspiDAC v3 + * @@ -128870,6 +125771,7 @@ index 0000000..3cabf5b +/* audio machine driver */ +static struct snd_soc_card snd_rpi_raspidac3 = { + .name = "RaspiDAC Rev.3x HiFi Audio Card", ++ .owner = THIS_MODULE, + .dai_link = snd_rpi_raspidac3_dai, + .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai), +}; @@ -128932,10 +125834,10 @@ index 0000000..3cabf5b +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 852162b9ea81d2a87bd17ad36b1e347dd02039e2 Mon Sep 17 00:00:00 2001 +From 0e83954993c856c53c4bccb3a1987bff50e58533 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:02:34 +0100 -Subject: [PATCH 081/251] tpa6130a2: Add headphone switch control +Subject: [PATCH 078/114] tpa6130a2: Add headphone switch control Signed-off-by: Jan Grulich --- @@ -129026,41 +125928,10 @@ index 11d85c5..3caaa17 100644 /* -From a75c4939c66e03c683d86b01d793d28c074818eb Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 28 Sep 2015 23:38:59 +0100 -Subject: [PATCH 082/251] irq-bcm2835: Fix building with 2708 - ---- - drivers/irqchip/irq-bcm2835.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c -index 20deb28..c02bf8a 100644 ---- a/drivers/irqchip/irq-bcm2835.c -+++ b/drivers/irqchip/irq-bcm2835.c -@@ -82,6 +82,7 @@ - #define NR_BANKS 3 - #define IRQS_PER_BANK 32 - #define NUMBER_IRQS MAKE_HWIRQ(NR_BANKS, 0) -+#undef FIQ_START - #define FIQ_START (NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0)) - - static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; -@@ -256,7 +257,7 @@ static int __init armctrl_of_init(struct device_node *node, - MAKE_HWIRQ(b, i) + NUMBER_IRQS); - BUG_ON(irq <= 0); - irq_set_chip(irq, &armctrl_chip); -- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); -+ irq_set_probe(irq); - } - } - init_FIQ(FIQ_START); - -From ef612ffab83e04751eca4f4d4a5017fecaab9cae Mon Sep 17 00:00:00 2001 +From 4e521b9a6f05e7f2b5ed358804ee6c36d1c23c4e Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 083/251] rpi_display: add backlight driver and overlay +Subject: [PATCH 079/114] rpi_display: add backlight driver and overlay Add a mailbox-driven backlight controller for the Raspberry Pi DSI touchscreen display. Requires updated GPU firmware to recognise the @@ -129068,99 +125939,12 @@ mailbox request. Signed-off-by: Gordon Hollingworth --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++ - .../boot/dts/overlays/rpi-backlight-overlay.dts | 21 ++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/video/backlight/Kconfig | 6 ++ - drivers/video/backlight/Makefile | 1 + - drivers/video/backlight/rpi_backlight.c | 119 +++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 9 files changed, 157 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts + drivers/video/backlight/Kconfig | 6 ++ + drivers/video/backlight/Makefile | 1 + + drivers/video/backlight/rpi_backlight.c | 119 ++++++++++++++++++++++++++++++++ + 3 files changed, 126 insertions(+) create mode 100644 drivers/video/backlight/rpi_backlight.c -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d8c2771..fb7ac49 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-backlight-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 268d400..d7f2979 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -462,6 +462,12 @@ Load: dtoverlay=raspidac3 - Params: - - -+Name: rpi-backlight -+Info: Raspberry Pi official display backlight driver -+Load: dtoverlay=rpi-backlight -+Params: -+ -+ - Name: rpi-dac - Info: Configures the RPi DAC audio card - Load: dtoverlay=rpi-dac -diff --git a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -new file mode 100644 -index 0000000..c021d02 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -@@ -0,0 +1,21 @@ -+/* -+ * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display -+ * backlight controller -+ */ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ rpi_backlight: rpi_backlight { -+ compatible = "raspberrypi,rpi-backlight"; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 16062bf..13999af 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -808,6 +808,7 @@ CONFIG_FB_UDL=m - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_LOGO=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 1d1b799..146add9 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -801,6 +801,7 @@ CONFIG_FB_UDL=m - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_LOGO=y diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 5ffa4b4..c3023ab 100644 --- a/drivers/video/backlight/Kconfig @@ -129315,111 +126099,11 @@ index 0000000..14a0d9b +MODULE_AUTHOR("Gordon Hollingworth "); +MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver"); +MODULE_LICENSE("GPL"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index 525816d..b011489 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -112,6 +112,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, - - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - -From 9e683aed13baf656729ca37b7efb70d595781f85 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Mon, 16 Nov 2015 14:05:35 +0000 -Subject: [PATCH 084/251] bcm2835-dma: Fix up convert to DMA pool - ---- - drivers/dma/bcm2835-dma.c | 36 ++++++++++++++++++++++++++---------- - 1 file changed, 26 insertions(+), 10 deletions(-) - -diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c -index 0adc347..985019b 100644 ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -488,6 +488,17 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic( - c->cyclic = true; - - return vchan_tx_prep(&c->vc, &d->vd, flags); -+error_cb: -+ i--; -+ for (; i >= 0; i--) { -+ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; -+ -+ dma_pool_free(c->cb_pool, cb_entry->cb, cb_entry->paddr); -+ } -+ -+ kfree(d->cb_list); -+ kfree(d); -+ return NULL; - } - - static struct dma_async_tx_descriptor * -@@ -534,6 +545,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - if (!d) - return NULL; - -+ d->c = c; - d->dir = direction; - - if (c->ch >= 8) /* LITE channel */ -@@ -553,15 +565,21 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - d->frames += len / max_size + 1; - } - -- /* Allocate memory for control blocks */ -- d->control_block_size = d->frames * sizeof(struct bcm2835_dma_cb); -- d->control_block_base = dma_zalloc_coherent(chan->device->dev, -- d->control_block_size, &d->control_block_base_phys, -- GFP_NOWAIT); -- if (!d->control_block_base) { -+ d->cb_list = kcalloc(d->frames, sizeof(*d->cb_list), GFP_KERNEL); -+ if (!d->cb_list) { - kfree(d); - return NULL; - } -+ /* Allocate memory for control blocks */ -+ for (i = 0; i < d->frames; i++) { -+ struct bcm2835_cb_entry *cb_entry = &d->cb_list[i]; -+ -+ cb_entry->cb = dma_pool_zalloc(c->cb_pool, GFP_ATOMIC, -+ &cb_entry->paddr); -+ -+ if (!cb_entry->cb) -+ goto error_cb; -+ } - - /* - * Iterate over all SG entries, create a control block -@@ -578,7 +596,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - - for (j = 0; j < len; j += max_size) { - struct bcm2835_dma_cb *control_block = -- &d->control_block_base[i + split_cnt]; -+ d->cb_list[i + split_cnt].cb; - - /* Setup addresses */ - if (d->dir == DMA_DEV_TO_MEM) { -@@ -620,9 +638,7 @@ bcm2835_dma_prep_slave_sg(struct dma_chan *chan, - if (i < sg_len - 1 || len - j > max_size) { - /* Next block is the next frame. */ - control_block->next = -- d->control_block_base_phys + -- sizeof(struct bcm2835_dma_cb) * -- (i + split_cnt + 1); -+ d->cb_list[i + split_cnt + 1].paddr; - } else { - /* Next block is empty. */ - control_block->next = 0; - -From 17d171c260c02491c27b1d89e84c09053f825ac2 Mon Sep 17 00:00:00 2001 +From 5ecd9e700a81663147a2457cef2a93fd5ae621cd Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 Nov 2015 11:38:59 +0000 -Subject: [PATCH 085/251] scripts: Multi-platform support for mkknlimg and +Subject: [PATCH 080/114] scripts: Multi-platform support for mkknlimg and knlinfo The firmware uses tags in the kernel trailer to choose which dtb file @@ -129668,17179 +126352,10 @@ index 3998d43..005f404 100755 - return (($val eq 'y') || ($val eq '1')); -} -From 3daa279385ccf4297bb8beb5b1f770ea535e7245 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 2 Mar 2015 13:01:12 -0800 -Subject: [PATCH 086/251] drm/vc4: Add suport for 3D rendering using the V3D - engine. - -This is a squash of the out-of-tree development series. Since that -series contained code from the first "get a demo triangle rendered -using a hacked up driver using binary shader code" to "plug the last -known security hole", it's hard to reconstruct a different series of -incremental development that's mergeable without security holes -throughout it. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/Makefile | 11 +- - drivers/gpu/drm/vc4/vc4_bo.c | 476 +++++++++++++- - drivers/gpu/drm/vc4/vc4_crtc.c | 98 ++- - drivers/gpu/drm/vc4/vc4_debugfs.c | 3 + - drivers/gpu/drm/vc4/vc4_drv.c | 45 +- - drivers/gpu/drm/vc4/vc4_drv.h | 317 ++++++++++ - drivers/gpu/drm/vc4/vc4_gem.c | 686 +++++++++++++++++++++ - drivers/gpu/drm/vc4/vc4_irq.c | 211 +++++++ - drivers/gpu/drm/vc4/vc4_kms.c | 148 ++++- - drivers/gpu/drm/vc4/vc4_packet.h | 384 ++++++++++++ - drivers/gpu/drm/vc4/vc4_plane.c | 40 ++ - drivers/gpu/drm/vc4/vc4_qpu_defines.h | 268 ++++++++ - drivers/gpu/drm/vc4/vc4_render_cl.c | 448 ++++++++++++++ - drivers/gpu/drm/vc4/vc4_trace.h | 63 ++ - drivers/gpu/drm/vc4/vc4_trace_points.c | 14 + - drivers/gpu/drm/vc4/vc4_v3d.c | 268 ++++++++ - drivers/gpu/drm/vc4/vc4_validate.c | 958 +++++++++++++++++++++++++++++ - drivers/gpu/drm/vc4/vc4_validate_shaders.c | 521 ++++++++++++++++ - include/uapi/drm/vc4_drm.h | 229 +++++++ - 19 files changed, 5173 insertions(+), 15 deletions(-) - create mode 100644 drivers/gpu/drm/vc4/vc4_gem.c - create mode 100644 drivers/gpu/drm/vc4/vc4_irq.c - create mode 100644 drivers/gpu/drm/vc4/vc4_packet.h - create mode 100644 drivers/gpu/drm/vc4/vc4_qpu_defines.h - create mode 100644 drivers/gpu/drm/vc4/vc4_render_cl.c - create mode 100644 drivers/gpu/drm/vc4/vc4_trace.h - create mode 100644 drivers/gpu/drm/vc4/vc4_trace_points.c - create mode 100644 drivers/gpu/drm/vc4/vc4_v3d.c - create mode 100644 drivers/gpu/drm/vc4/vc4_validate.c - create mode 100644 drivers/gpu/drm/vc4/vc4_validate_shaders.c - create mode 100644 include/uapi/drm/vc4_drm.h - -diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile -index 32b4f9c..4c6a99f 100644 ---- a/drivers/gpu/drm/vc4/Makefile -+++ b/drivers/gpu/drm/vc4/Makefile -@@ -8,10 +8,19 @@ vc4-y := \ - vc4_crtc.o \ - vc4_drv.o \ - vc4_kms.o \ -+ vc4_gem.o \ - vc4_hdmi.o \ - vc4_hvs.o \ -- vc4_plane.o -+ vc4_irq.o \ -+ vc4_plane.o \ -+ vc4_render_cl.o \ -+ vc4_trace_points.o \ -+ vc4_v3d.o \ -+ vc4_validate.o \ -+ vc4_validate_shaders.o - - vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o - - obj-$(CONFIG_DRM_VC4) += vc4.o -+ -+CFLAGS_vc4_trace_points.o := -I$(src) -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index ab9f510..bfa605f 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -15,16 +15,174 @@ - */ - - #include "vc4_drv.h" -+#include "uapi/drm/vc4_drm.h" - --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size) -+static void vc4_bo_stats_dump(struct vc4_dev *vc4) - { -+ DRM_INFO("num bos allocated: %d\n", -+ vc4->bo_stats.num_allocated); -+ DRM_INFO("size bos allocated: %dkb\n", -+ vc4->bo_stats.size_allocated / 1024); -+ DRM_INFO("num bos used: %d\n", -+ vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached); -+ DRM_INFO("size bos used: %dkb\n", -+ (vc4->bo_stats.size_allocated - -+ vc4->bo_stats.size_cached) / 1024); -+ DRM_INFO("num bos cached: %d\n", -+ vc4->bo_stats.num_cached); -+ DRM_INFO("size bos cached: %dkb\n", -+ vc4->bo_stats.size_cached / 1024); -+} -+ -+static uint32_t bo_page_index(size_t size) -+{ -+ return (size / PAGE_SIZE) - 1; -+} -+ -+/* Must be called with bo_lock held. */ -+static void vc4_bo_destroy(struct vc4_bo *bo) -+{ -+ struct drm_gem_object *obj = &bo->base.base; -+ struct vc4_dev *vc4 = to_vc4_dev(obj->dev); -+ -+ if (bo->validated_shader) { -+ kfree(bo->validated_shader->texture_samples); -+ kfree(bo->validated_shader); -+ bo->validated_shader = NULL; -+ } -+ -+ vc4->bo_stats.num_allocated--; -+ vc4->bo_stats.size_allocated -= obj->size; -+ drm_gem_cma_free_object(obj); -+} -+ -+/* Must be called with bo_lock held. */ -+static void vc4_bo_remove_from_cache(struct vc4_bo *bo) -+{ -+ struct drm_gem_object *obj = &bo->base.base; -+ struct vc4_dev *vc4 = to_vc4_dev(obj->dev); -+ -+ vc4->bo_stats.num_cached--; -+ vc4->bo_stats.size_cached -= obj->size; -+ -+ list_del(&bo->unref_head); -+ list_del(&bo->size_head); -+} -+ -+static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, -+ size_t size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t page_index = bo_page_index(size); -+ -+ if (vc4->bo_cache.size_list_size <= page_index) { -+ uint32_t new_size = max(vc4->bo_cache.size_list_size * 2, -+ page_index + 1); -+ struct list_head *new_list; -+ uint32_t i; -+ -+ new_list = kmalloc(new_size * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!new_list) -+ return NULL; -+ -+ /* Rebase the old cached BO lists to their new list -+ * head locations. -+ */ -+ for (i = 0; i < vc4->bo_cache.size_list_size; i++) { -+ struct list_head *old_list = &vc4->bo_cache.size_list[i]; -+ if (list_empty(old_list)) -+ INIT_LIST_HEAD(&new_list[i]); -+ else -+ list_replace(old_list, &new_list[i]); -+ } -+ /* And initialize the brand new BO list heads. */ -+ for (i = vc4->bo_cache.size_list_size; i < new_size; i++) -+ INIT_LIST_HEAD(&new_list[i]); -+ -+ kfree(vc4->bo_cache.size_list); -+ vc4->bo_cache.size_list = new_list; -+ vc4->bo_cache.size_list_size = new_size; -+ } -+ -+ return &vc4->bo_cache.size_list[page_index]; -+} -+ -+void vc4_bo_cache_purge(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ spin_lock(&vc4->bo_lock); -+ while (!list_empty(&vc4->bo_cache.time_list)) { -+ struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, -+ struct vc4_bo, unref_head); -+ vc4_bo_remove_from_cache(bo); -+ vc4_bo_destroy(bo); -+ } -+ spin_unlock(&vc4->bo_lock); -+} -+ -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t size = roundup(unaligned_size, PAGE_SIZE); -+ uint32_t page_index = bo_page_index(size); - struct drm_gem_cma_object *cma_obj; -+ int pass; - -- cma_obj = drm_gem_cma_create(dev, size); -- if (IS_ERR(cma_obj)) -+ if (size == 0) - return NULL; -- else -- return to_vc4_bo(&cma_obj->base); -+ -+ /* First, try to get a vc4_bo from the kernel BO cache. */ -+ spin_lock(&vc4->bo_lock); -+ if (page_index < vc4->bo_cache.size_list_size && -+ !list_empty(&vc4->bo_cache.size_list[page_index])) { -+ struct vc4_bo *bo = -+ list_first_entry(&vc4->bo_cache.size_list[page_index], -+ struct vc4_bo, size_head); -+ vc4_bo_remove_from_cache(bo); -+ spin_unlock(&vc4->bo_lock); -+ kref_init(&bo->base.base.refcount); -+ return bo; -+ } -+ spin_unlock(&vc4->bo_lock); -+ -+ /* Otherwise, make a new BO. */ -+ for (pass = 0; ; pass++) { -+ cma_obj = drm_gem_cma_create(dev, size); -+ if (!IS_ERR(cma_obj)) -+ break; -+ -+ switch (pass) { -+ case 0: -+ /* -+ * If we've run out of CMA memory, kill the cache of -+ * CMA allocations we've got laying around and try again. -+ */ -+ vc4_bo_cache_purge(dev); -+ break; -+ case 1: -+ /* -+ * Getting desperate, so try to wait for any -+ * previous rendering to finish, free its -+ * unreferenced BOs to the cache, and then -+ * free the cache. -+ */ -+ vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, true); -+ vc4_job_handle_completed(vc4); -+ vc4_bo_cache_purge(dev); -+ break; -+ case 3: -+ DRM_ERROR("Failed to allocate from CMA:\n"); -+ vc4_bo_stats_dump(vc4); -+ return NULL; -+ } -+ } -+ -+ vc4->bo_stats.num_allocated++; -+ vc4->bo_stats.size_allocated += size; -+ -+ return to_vc4_bo(&cma_obj->base); - } - - int vc4_dumb_create(struct drm_file *file_priv, -@@ -41,7 +199,7 @@ int vc4_dumb_create(struct drm_file *file_priv, - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; - -- bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE)); -+ bo = vc4_bo_create(dev, args->size); - if (!bo) - return -ENOMEM; - -@@ -50,3 +208,309 @@ int vc4_dumb_create(struct drm_file *file_priv, - - return ret; - } -+ -+static void -+vc4_bo_cache_free_old(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long expire_time = jiffies - msecs_to_jiffies(1000); -+ -+ spin_lock(&vc4->bo_lock); -+ while (!list_empty(&vc4->bo_cache.time_list)) { -+ struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, -+ struct vc4_bo, unref_head); -+ if (time_before(expire_time, bo->free_time)) { -+ mod_timer(&vc4->bo_cache.time_timer, -+ round_jiffies_up(jiffies + -+ msecs_to_jiffies(1000))); -+ spin_unlock(&vc4->bo_lock); -+ return; -+ } -+ -+ vc4_bo_remove_from_cache(bo); -+ vc4_bo_destroy(bo); -+ } -+ spin_unlock(&vc4->bo_lock); -+} -+ -+/* Called on the last userspace/kernel unreference of the BO. Returns -+ * it to the BO cache if possible, otherwise frees it. -+ * -+ * Note that this is called with the struct_mutex held. -+ */ -+void vc4_free_object(struct drm_gem_object *gem_bo) -+{ -+ struct drm_device *dev = gem_bo->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo *bo = to_vc4_bo(gem_bo); -+ struct list_head *cache_list; -+ -+ /* If the object references someone else's memory, we can't cache it. -+ */ -+ if (gem_bo->import_attach) { -+ vc4_bo_destroy(bo); -+ return; -+ } -+ -+ /* Don't cache if it was publicly named. */ -+ if (gem_bo->name) { -+ vc4_bo_destroy(bo); -+ return; -+ } -+ -+ spin_lock(&vc4->bo_lock); -+ cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); -+ if (!cache_list) { -+ vc4_bo_destroy(bo); -+ spin_unlock(&vc4->bo_lock); -+ return; -+ } -+ -+ if (bo->validated_shader) { -+ kfree(bo->validated_shader->texture_samples); -+ kfree(bo->validated_shader); -+ bo->validated_shader = NULL; -+ } -+ -+ bo->free_time = jiffies; -+ list_add(&bo->size_head, cache_list); -+ list_add(&bo->unref_head, &vc4->bo_cache.time_list); -+ -+ vc4->bo_stats.num_cached++; -+ vc4->bo_stats.size_cached += gem_bo->size; -+ spin_unlock(&vc4->bo_lock); -+ -+ vc4_bo_cache_free_old(dev); -+} -+ -+static void vc4_bo_cache_time_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, bo_cache.time_work); -+ struct drm_device *dev = vc4->dev; -+ -+ vc4_bo_cache_free_old(dev); -+} -+ -+static void vc4_bo_cache_time_timer(unsigned long data) -+{ -+ struct drm_device *dev = (struct drm_device *)data; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ schedule_work(&vc4->bo_cache.time_work); -+} -+ -+struct dma_buf * -+vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("Attempting to export shader BO\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_prime_export(dev, obj, flags); -+} -+ -+int -+vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_create_bo *args = data; -+ struct vc4_bo *bo = NULL; -+ int ret; -+ -+ bo = vc4_bo_create(dev, args->size); -+ if (!bo) -+ return -ENOMEM; -+ -+ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); -+ drm_gem_object_unreference_unlocked(&bo->base.base); -+ -+ return ret; -+} -+ -+int -+vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_create_shader_bo *args = data; -+ struct vc4_bo *bo = NULL; -+ int ret; -+ -+ if (args->size == 0) -+ return -EINVAL; -+ -+ if (args->size % sizeof(u64) != 0) -+ return -EINVAL; -+ -+ if (args->flags != 0) { -+ DRM_INFO("Unknown flags set: 0x%08x\n", args->flags); -+ return -EINVAL; -+ } -+ -+ if (args->pad != 0) { -+ DRM_INFO("Pad set: 0x%08x\n", args->pad); -+ return -EINVAL; -+ } -+ -+ bo = vc4_bo_create(dev, args->size); -+ if (!bo) -+ return -ENOMEM; -+ -+ ret = copy_from_user(bo->base.vaddr, -+ (void __user *)(uintptr_t)args->data, -+ args->size); -+ if (ret != 0) -+ goto fail; -+ -+ bo->validated_shader = vc4_validate_shader(&bo->base); -+ if (!bo->validated_shader) { -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ /* We have to create the handle after validation, to avoid -+ * races for users to do doing things like mmap the shader BO. -+ */ -+ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); -+ -+ fail: -+ drm_gem_object_unreference_unlocked(&bo->base.base); -+ -+ return ret; -+} -+ -+int -+vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_mmap_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ -+ /* The mmap offset was set up at BO allocation time. */ -+ args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -+ -+ drm_gem_object_unreference(gem_obj); -+ return 0; -+} -+ -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ int ret; -+ -+ ret = drm_gem_mmap(filp, vma); -+ if (ret) -+ return ret; -+ -+ gem_obj = vma->vm_private_data; -+ bo = to_vc4_bo(gem_obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -+ * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -+ * the whole buffer. -+ */ -+ vma->vm_flags &= ~VM_PFNMAP; -+ vma->vm_pgoff = 0; -+ -+ ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -+ bo->base.vaddr, bo->base.paddr, -+ vma->vm_end - vma->vm_start); -+ if (ret) -+ drm_gem_vm_close(vma); -+ -+ return ret; -+} -+ -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ return drm_gem_cma_prime_mmap(obj, vma); -+} -+ -+void *vc4_prime_vmap(struct drm_gem_object *obj) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_cma_prime_vmap(obj); -+} -+ -+void vc4_bo_cache_init(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ spin_lock_init(&vc4->bo_lock); -+ -+ INIT_LIST_HEAD(&vc4->bo_cache.time_list); -+ -+ INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); -+ setup_timer(&vc4->bo_cache.time_timer, -+ vc4_bo_cache_time_timer, -+ (unsigned long) dev); -+} -+ -+void vc4_bo_cache_destroy(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ del_timer(&vc4->bo_cache.time_timer); -+ cancel_work_sync(&vc4->bo_cache.time_work); -+ -+ vc4_bo_cache_purge(dev); -+ -+ if (vc4->bo_stats.num_allocated) { -+ DRM_ERROR("Destroying BO cache while BOs still allocated:\n"); -+ vc4_bo_stats_dump(vc4); -+ } -+} -+ -+#ifdef CONFIG_DEBUG_FS -+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo_stats stats; -+ -+ spin_lock(&vc4->bo_lock); -+ stats = vc4->bo_stats; -+ spin_unlock(&vc4->bo_lock); -+ -+ seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); -+ seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -+ seq_printf(m, "num bos used: %d\n", (stats.num_allocated - -+ stats.num_cached)); -+ seq_printf(m, "size bos used: %dkb\n", (stats.size_allocated - -+ stats.size_cached) / 1024); -+ seq_printf(m, "num bos cached: %d\n", stats.num_cached); -+ seq_printf(m, "size bos cached: %dkb\n", stats.size_cached / 1024); -+ -+ return 0; -+} -+#endif -diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c -index 265064c..3be2720 100644 ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -35,6 +35,7 @@ - #include "drm_atomic_helper.h" - #include "drm_crtc_helper.h" - #include "linux/clk.h" -+#include "drm_fb_cma_helper.h" - #include "linux/component.h" - #include "linux/of_device.h" - #include "vc4_drv.h" -@@ -476,10 +477,105 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) - return ret; - } - -+struct vc4_async_flip_state { -+ struct drm_crtc *crtc; -+ struct drm_framebuffer *fb; -+ struct drm_pending_vblank_event *event; -+ -+ struct vc4_seqno_cb cb; -+}; -+ -+/* Called when the V3D execution for the BO being flipped to is done, so that -+ * we can actually update the plane's address to point to it. -+ */ -+static void -+vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) -+{ -+ struct vc4_async_flip_state *flip_state = -+ container_of(cb, struct vc4_async_flip_state, cb); -+ struct drm_crtc *crtc = flip_state->crtc; -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_plane *plane = crtc->primary; -+ -+ vc4_plane_async_set_fb(plane, flip_state->fb); -+ if (flip_state->event) { -+ unsigned long flags; -+ spin_lock_irqsave(&dev->event_lock, flags); -+ drm_crtc_send_vblank_event(crtc, flip_state->event); -+ spin_unlock_irqrestore(&dev->event_lock, flags); -+ } -+ -+ drm_framebuffer_unreference(flip_state->fb); -+ kfree(flip_state); -+ -+ up(&vc4->async_modeset); -+} -+ -+/* Implements async (non-vblank-synced) page flips. -+ * -+ * The page flip ioctl needs to return immediately, so we grab the -+ * modeset semaphore on the pipe, and queue the address update for -+ * when V3D is done with the BO being flipped to. -+ */ -+static int vc4_async_page_flip(struct drm_crtc *crtc, -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) -+{ -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_plane *plane = crtc->primary; -+ int ret = 0; -+ struct vc4_async_flip_state *flip_state; -+ struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); -+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ -+ flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); -+ if (!flip_state) -+ return -ENOMEM; -+ -+ drm_framebuffer_reference(fb); -+ flip_state->fb = fb; -+ flip_state->crtc = crtc; -+ flip_state->event = event; -+ -+ /* Make sure all other async modesetes have landed. */ -+ ret = down_interruptible(&vc4->async_modeset); -+ if (ret) { -+ kfree(flip_state); -+ return ret; -+ } -+ -+ /* Immediately update the plane's legacy fb pointer, so that later -+ * modeset prep sees the state that will be present when the semaphore -+ * is released. -+ */ -+ drm_atomic_set_fb_for_plane(plane->state, fb); -+ plane->fb = fb; -+ -+ vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, -+ vc4_async_page_flip_complete); -+ -+ /* Driver takes ownership of state on successful async commit. */ -+ return 0; -+} -+ -+static int vc4_page_flip(struct drm_crtc *crtc, -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) -+{ -+ if (flags & DRM_MODE_PAGE_FLIP_ASYNC) -+ return vc4_async_page_flip(crtc, fb, event, flags); -+ else -+ return drm_atomic_helper_page_flip(crtc, fb, event, flags); -+} -+ - static const struct drm_crtc_funcs vc4_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, - .destroy = vc4_crtc_destroy, -- .page_flip = drm_atomic_helper_page_flip, -+ .page_flip = vc4_page_flip, - .set_property = NULL, - .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ - .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ -diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c -index 4297b0a..d76ad10 100644 ---- a/drivers/gpu/drm/vc4/vc4_debugfs.c -+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c -@@ -16,11 +16,14 @@ - #include "vc4_regs.h" - - static const struct drm_info_list vc4_debugfs_list[] = { -+ {"bo_stats", vc4_bo_stats_debugfs, 0}, - {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, - {"hvs_regs", vc4_hvs_debugfs_regs, 0}, - {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, - {"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1}, - {"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2}, -+ {"v3d_ident", vc4_v3d_debugfs_ident, 0}, -+ {"v3d_regs", vc4_v3d_debugfs_regs, 0}, - }; - - #define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list) -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index d5db9e0..3baf1fc 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -14,8 +14,10 @@ - #include - #include - #include -+#include - #include "drm_fb_cma_helper.h" - -+#include "uapi/drm/vc4_drm.h" - #include "vc4_drv.h" - #include "vc4_regs.h" - -@@ -63,7 +65,7 @@ static const struct file_operations vc4_drm_fops = { - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, -- .mmap = drm_gem_cma_mmap, -+ .mmap = vc4_mmap, - .poll = drm_poll, - .read = drm_read, - #ifdef CONFIG_COMPAT -@@ -73,16 +75,28 @@ static const struct file_operations vc4_drm_fops = { - }; - - static const struct drm_ioctl_desc vc4_drm_ioctls[] = { -+ DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), - }; - - static struct drm_driver vc4_drm_driver = { - .driver_features = (DRIVER_MODESET | - DRIVER_ATOMIC | - DRIVER_GEM | -+ DRIVER_HAVE_IRQ | - DRIVER_PRIME), - .lastclose = vc4_lastclose, - .preclose = vc4_drm_preclose, - -+ .irq_handler = vc4_irq, -+ .irq_preinstall = vc4_irq_preinstall, -+ .irq_postinstall = vc4_irq_postinstall, -+ .irq_uninstall = vc4_irq_uninstall, -+ - .enable_vblank = vc4_enable_vblank, - .disable_vblank = vc4_disable_vblank, - .get_vblank_counter = drm_vblank_count, -@@ -92,18 +106,18 @@ static struct drm_driver vc4_drm_driver = { - .debugfs_cleanup = vc4_debugfs_cleanup, - #endif - -- .gem_free_object = drm_gem_cma_free_object, -+ .gem_free_object = vc4_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_import = drm_gem_prime_import, -- .gem_prime_export = drm_gem_prime_export, -+ .gem_prime_export = vc4_prime_export, - .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, - .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, -- .gem_prime_vmap = drm_gem_cma_prime_vmap, -+ .gem_prime_vmap = vc4_prime_vmap, - .gem_prime_vunmap = drm_gem_cma_prime_vunmap, -- .gem_prime_mmap = drm_gem_cma_prime_mmap, -+ .gem_prime_mmap = vc4_prime_mmap, - - .dumb_create = vc4_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, -@@ -113,6 +127,8 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -+ .gem_obj_size = sizeof(struct vc4_bo), -+ - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, -@@ -153,6 +169,7 @@ static int vc4_drm_bind(struct device *dev) - struct drm_device *drm; - struct drm_connector *connector; - struct vc4_dev *vc4; -+ struct device_node *firmware_node; - int ret = 0; - - dev->coherent_dma_mask = DMA_BIT_MASK(32); -@@ -161,6 +178,14 @@ static int vc4_drm_bind(struct device *dev) - if (!vc4) - return -ENOMEM; - -+ firmware_node = of_parse_phandle(dev->of_node, "firmware", 0); -+ vc4->firmware = rpi_firmware_get(firmware_node); -+ if (!vc4->firmware) { -+ DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); -+ return -EPROBE_DEFER; -+ } -+ of_node_put(firmware_node); -+ - drm = drm_dev_alloc(&vc4_drm_driver, dev); - if (!drm) - return -ENOMEM; -@@ -170,13 +195,17 @@ static int vc4_drm_bind(struct device *dev) - - drm_dev_set_unique(drm, dev_name(dev)); - -+ vc4_bo_cache_init(drm); -+ - drm_mode_config_init(drm); - if (ret) - goto unref; - -+ vc4_gem_init(drm); -+ - ret = component_bind_all(dev, drm); - if (ret) -- goto unref; -+ goto gem_destroy; - - ret = drm_dev_register(drm, 0); - if (ret < 0) -@@ -200,8 +229,11 @@ unregister: - drm_dev_unregister(drm); - unbind_all: - component_unbind_all(dev, drm); -+gem_destroy: -+ vc4_gem_destroy(drm); - unref: - drm_dev_unref(drm); -+ vc4_bo_cache_destroy(drm); - return ret; - } - -@@ -228,6 +260,7 @@ static struct platform_driver *const component_drivers[] = { - &vc4_hdmi_driver, - &vc4_crtc_driver, - &vc4_hvs_driver, -+ &vc4_v3d_driver, - }; - - static int vc4_platform_drm_probe(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index fd8319f..8cc89d1 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -15,8 +15,85 @@ struct vc4_dev { - struct vc4_hdmi *hdmi; - struct vc4_hvs *hvs; - struct vc4_crtc *crtc[3]; -+ struct vc4_v3d *v3d; - - struct drm_fbdev_cma *fbdev; -+ struct rpi_firmware *firmware; -+ -+ /* The kernel-space BO cache. Tracks buffers that have been -+ * unreferenced by all other users (refcounts of 0!) but not -+ * yet freed, so we can do cheap allocations. -+ */ -+ struct vc4_bo_cache { -+ /* Array of list heads for entries in the BO cache, -+ * based on number of pages, so we can do O(1) lookups -+ * in the cache when allocating. -+ */ -+ struct list_head *size_list; -+ uint32_t size_list_size; -+ -+ /* List of all BOs in the cache, ordered by age, so we -+ * can do O(1) lookups when trying to free old -+ * buffers. -+ */ -+ struct list_head time_list; -+ struct work_struct time_work; -+ struct timer_list time_timer; -+ } bo_cache; -+ -+ struct vc4_bo_stats { -+ u32 num_allocated; -+ u32 size_allocated; -+ u32 num_cached; -+ u32 size_cached; -+ } bo_stats; -+ -+ /* Protects bo_cache and the BO stats. */ -+ spinlock_t bo_lock; -+ -+ /* Sequence number for the last job queued in job_list. -+ * Starts at 0 (no jobs emitted). -+ */ -+ uint64_t emit_seqno; -+ -+ /* Sequence number for the last completed job on the GPU. -+ * Starts at 0 (no jobs completed). -+ */ -+ uint64_t finished_seqno; -+ -+ /* List of all struct vc4_exec_info for jobs to be executed. -+ * The first job in the list is the one currently programmed -+ * into ct0ca/ct1ca for execution. -+ */ -+ struct list_head job_list; -+ /* List of the finished vc4_exec_infos waiting to be freed by -+ * job_done_work. -+ */ -+ struct list_head job_done_list; -+ spinlock_t job_lock; -+ wait_queue_head_t job_wait_queue; -+ struct work_struct job_done_work; -+ -+ /* List of struct vc4_seqno_cb for callbacks to be made from a -+ * workqueue when the given seqno is passed. -+ */ -+ struct list_head seqno_cb_list; -+ -+ /* The binner overflow memory that's currently set up in -+ * BPOA/BPOS registers. When overflow occurs and a new one is -+ * allocated, the previous one will be moved to -+ * vc4->current_exec's free list. -+ */ -+ struct vc4_bo *overflow_mem; -+ struct work_struct overflow_mem_work; -+ -+ struct { -+ uint32_t last_ct0ca, last_ct1ca; -+ struct timer_list timer; -+ struct work_struct reset_work; -+ } hangcheck; -+ -+ struct semaphore async_modeset; - }; - - static inline struct vc4_dev * -@@ -27,6 +104,25 @@ to_vc4_dev(struct drm_device *dev) - - struct vc4_bo { - struct drm_gem_cma_object base; -+ -+ /* seqno of the last job to render to this BO. */ -+ uint64_t seqno; -+ -+ /* List entry for the BO's position in either -+ * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list -+ */ -+ struct list_head unref_head; -+ -+ /* Time in jiffies when the BO was put in vc4->bo_cache. */ -+ unsigned long free_time; -+ -+ /* List entry for the BO's position in vc4_dev->bo_cache.size_list */ -+ struct list_head size_head; -+ -+ /* Struct for shader validation state, if created by -+ * DRM_IOCTL_VC4_CREATE_SHADER_BO. -+ */ -+ struct vc4_validated_shader_info *validated_shader; - }; - - static inline struct vc4_bo * -@@ -35,6 +131,17 @@ to_vc4_bo(struct drm_gem_object *bo) - return (struct vc4_bo *)bo; - } - -+struct vc4_seqno_cb { -+ struct work_struct work; -+ uint64_t seqno; -+ void (*func)(struct vc4_seqno_cb *cb); -+}; -+ -+struct vc4_v3d { -+ struct platform_device *pdev; -+ void __iomem *regs; -+}; -+ - struct vc4_hvs { - struct platform_device *pdev; - void __iomem *regs; -@@ -72,9 +179,151 @@ to_vc4_encoder(struct drm_encoder *encoder) - return container_of(encoder, struct vc4_encoder, base); - } - -+#define V3D_READ(offset) readl(vc4->v3d->regs + offset) -+#define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset) - #define HVS_READ(offset) readl(vc4->hvs->regs + offset) - #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) - -+enum vc4_bo_mode { -+ VC4_MODE_UNDECIDED, -+ VC4_MODE_RENDER, -+ VC4_MODE_SHADER, -+}; -+ -+struct vc4_bo_exec_state { -+ struct drm_gem_cma_object *bo; -+ enum vc4_bo_mode mode; -+}; -+ -+struct vc4_exec_info { -+ /* Sequence number for this bin/render job. */ -+ uint64_t seqno; -+ -+ /* Kernel-space copy of the ioctl arguments */ -+ struct drm_vc4_submit_cl *args; -+ -+ /* This is the array of BOs that were looked up at the start of exec. -+ * Command validation will use indices into this array. -+ */ -+ struct vc4_bo_exec_state *bo; -+ uint32_t bo_count; -+ -+ /* Pointers for our position in vc4->job_list */ -+ struct list_head head; -+ -+ /* List of other BOs used in the job that need to be released -+ * once the job is complete. -+ */ -+ struct list_head unref_list; -+ -+ /* Current unvalidated indices into @bo loaded by the non-hardware -+ * VC4_PACKET_GEM_HANDLES. -+ */ -+ uint32_t bo_index[2]; -+ -+ /* This is the BO where we store the validated command lists, shader -+ * records, and uniforms. -+ */ -+ struct drm_gem_cma_object *exec_bo; -+ -+ /** -+ * This tracks the per-shader-record state (packet 64) that -+ * determines the length of the shader record and the offset -+ * it's expected to be found at. It gets read in from the -+ * command lists. -+ */ -+ struct vc4_shader_state { -+ uint8_t packet; -+ uint32_t addr; -+ /* Maximum vertex index referenced by any primitive using this -+ * shader state. -+ */ -+ uint32_t max_index; -+ } *shader_state; -+ -+ /** How many shader states the user declared they were using. */ -+ uint32_t shader_state_size; -+ /** How many shader state records the validator has seen. */ -+ uint32_t shader_state_count; -+ -+ bool found_tile_binning_mode_config_packet; -+ bool found_start_tile_binning_packet; -+ bool found_increment_semaphore_packet; -+ uint8_t bin_tiles_x, bin_tiles_y; -+ struct drm_gem_cma_object *tile_bo; -+ uint32_t tile_alloc_offset; -+ -+ /** -+ * Computed addresses pointing into exec_bo where we start the -+ * bin thread (ct0) and render thread (ct1). -+ */ -+ uint32_t ct0ca, ct0ea; -+ uint32_t ct1ca, ct1ea; -+ -+ /* Pointers to the shader recs. These paddr gets incremented as CL -+ * packets are relocated in validate_gl_shader_state, and the vaddrs -+ * (u and v) get incremented and size decremented as the shader recs -+ * themselves are validated. -+ */ -+ void *shader_rec_u; -+ void *shader_rec_v; -+ uint32_t shader_rec_p; -+ uint32_t shader_rec_size; -+ -+ /* Pointers to the uniform data. These pointers are incremented, and -+ * size decremented, as each batch of uniforms is uploaded. -+ */ -+ void *uniforms_u; -+ void *uniforms_v; -+ uint32_t uniforms_p; -+ uint32_t uniforms_size; -+}; -+ -+static inline struct vc4_exec_info * -+vc4_first_job(struct vc4_dev *vc4) -+{ -+ if (list_empty(&vc4->job_list)) -+ return NULL; -+ return list_first_entry(&vc4->job_list, struct vc4_exec_info, head); -+} -+ -+/** -+ * struct vc4_texture_sample_info - saves the offsets into the UBO for texture -+ * setup parameters. -+ * -+ * This will be used at draw time to relocate the reference to the texture -+ * contents in p0, and validate that the offset combined with -+ * width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO. -+ * Note that the hardware treats unprovided config parameters as 0, so not all -+ * of them need to be set up for every texure sample, and we'll store ~0 as -+ * the offset to mark the unused ones. -+ * -+ * See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit -+ * Setup") for definitions of the texture parameters. -+ */ -+struct vc4_texture_sample_info { -+ bool is_direct; -+ uint32_t p_offset[4]; -+}; -+ -+/** -+ * struct vc4_validated_shader_info - information about validated shaders that -+ * needs to be used from command list validation. -+ * -+ * For a given shader, each time a shader state record references it, we need -+ * to verify that the shader doesn't read more uniforms than the shader state -+ * record's uniform BO pointer can provide, and we need to apply relocations -+ * and validate the shader state record's uniforms that define the texture -+ * samples. -+ */ -+struct vc4_validated_shader_info -+{ -+ uint32_t uniforms_size; -+ uint32_t uniforms_src_size; -+ uint32_t num_texture_samples; -+ struct vc4_texture_sample_info *texture_samples; -+}; -+ - /** - * _wait_for - magic (register) wait macro - * -@@ -111,6 +360,18 @@ int vc4_dumb_create(struct drm_file *file_priv, - struct drm_mode_create_dumb *args); - struct dma_buf *vc4_prime_export(struct drm_device *dev, - struct drm_gem_object *obj, int flags); -+int vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma); -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); -+void *vc4_prime_vmap(struct drm_gem_object *obj); -+void vc4_bo_cache_init(struct drm_device *dev); -+void vc4_bo_cache_destroy(struct drm_device *dev); -+int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); - - /* vc4_crtc.c */ - extern struct platform_driver vc4_crtc_driver; -@@ -126,10 +387,34 @@ void vc4_debugfs_cleanup(struct drm_minor *minor); - /* vc4_drv.c */ - void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); - -+/* vc4_gem.c */ -+void vc4_gem_init(struct drm_device *dev); -+void vc4_gem_destroy(struct drm_device *dev); -+int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+int vc4_wait_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); -+void vc4_submit_next_job(struct drm_device *dev); -+int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, -+ uint64_t timeout_ns, bool interruptible); -+void vc4_job_handle_completed(struct vc4_dev *vc4); -+int vc4_queue_seqno_cb(struct drm_device *dev, -+ struct vc4_seqno_cb *cb, uint64_t seqno, -+ void (*func)(struct vc4_seqno_cb *cb)); -+ - /* vc4_hdmi.c */ - extern struct platform_driver vc4_hdmi_driver; - int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused); - -+/* vc4_irq.c */ -+irqreturn_t vc4_irq(int irq, void *arg); -+void vc4_irq_preinstall(struct drm_device *dev); -+int vc4_irq_postinstall(struct drm_device *dev); -+void vc4_irq_uninstall(struct drm_device *dev); -+void vc4_irq_reset(struct drm_device *dev); -+ - /* vc4_hvs.c */ - extern struct platform_driver vc4_hvs_driver; - void vc4_hvs_dump_state(struct drm_device *dev); -@@ -143,3 +428,35 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, - enum drm_plane_type type); - u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); - u32 vc4_plane_dlist_size(struct drm_plane_state *state); -+void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb); -+ -+/* vc4_v3d.c */ -+extern struct platform_driver vc4_v3d_driver; -+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); -+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); -+int vc4_v3d_set_power(struct vc4_dev *vc4, bool on); -+ -+/* vc4_validate.c */ -+int -+vc4_validate_bin_cl(struct drm_device *dev, -+ void *validated, -+ void *unvalidated, -+ struct vc4_exec_info *exec); -+ -+int -+vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); -+ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -+ -+bool vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj); -+ -+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); -+ -+bool vc4_check_tex_size(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *fbo, -+ uint32_t offset, uint8_t tiling_format, -+ uint32_t width, uint32_t height, uint8_t cpp); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -new file mode 100644 -index 0000000..361390b ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -0,0 +1,686 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+#include "vc4_trace.h" -+ -+static void -+vc4_queue_hangcheck(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ mod_timer(&vc4->hangcheck.timer, -+ round_jiffies_up(jiffies + msecs_to_jiffies(100))); -+} -+ -+static void -+vc4_reset(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ DRM_INFO("Resetting GPU.\n"); -+ vc4_v3d_set_power(vc4, false); -+ vc4_v3d_set_power(vc4, true); -+ -+ vc4_irq_reset(dev); -+ -+ /* Rearm the hangcheck -- another job might have been waiting -+ * for our hung one to get kicked off, and vc4_irq_reset() -+ * would have started it. -+ */ -+ vc4_queue_hangcheck(dev); -+} -+ -+static void -+vc4_reset_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, hangcheck.reset_work); -+ -+ vc4_reset(vc4->dev); -+} -+ -+static void -+vc4_hangcheck_elapsed(unsigned long data) -+{ -+ struct drm_device *dev = (struct drm_device *)data; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t ct0ca, ct1ca; -+ -+ /* If idle, we can stop watching for hangs. */ -+ if (list_empty(&vc4->job_list)) -+ return; -+ -+ ct0ca = V3D_READ(V3D_CTNCA(0)); -+ ct1ca = V3D_READ(V3D_CTNCA(1)); -+ -+ /* If we've made any progress in execution, rearm the timer -+ * and wait. -+ */ -+ if (ct0ca != vc4->hangcheck.last_ct0ca || -+ ct1ca != vc4->hangcheck.last_ct1ca) { -+ vc4->hangcheck.last_ct0ca = ct0ca; -+ vc4->hangcheck.last_ct1ca = ct1ca; -+ vc4_queue_hangcheck(dev); -+ return; -+ } -+ -+ /* We've gone too long with no progress, reset. This has to -+ * be done from a work struct, since resetting can sleep and -+ * this timer hook isn't allowed to. -+ */ -+ schedule_work(&vc4->hangcheck.reset_work); -+} -+ -+static void -+submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Stop any existing thread and set state to "stopped at halt" */ -+ V3D_WRITE(V3D_CTNCS(thread), V3D_CTRUN); -+ barrier(); -+ -+ V3D_WRITE(V3D_CTNCA(thread), start); -+ barrier(); -+ -+ /* Set the end address of the control list. Writing this -+ * register is what starts the job. -+ */ -+ V3D_WRITE(V3D_CTNEA(thread), end); -+ barrier(); -+} -+ -+int -+vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, -+ bool interruptible) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret = 0; -+ unsigned long timeout_expire; -+ DEFINE_WAIT(wait); -+ -+ if (vc4->finished_seqno >= seqno) -+ return 0; -+ -+ if (timeout_ns == 0) -+ return -ETIME; -+ -+ timeout_expire = jiffies + nsecs_to_jiffies(timeout_ns); -+ -+ trace_vc4_wait_for_seqno_begin(dev, seqno, timeout_ns); -+ for (;;) { -+ prepare_to_wait(&vc4->job_wait_queue, &wait, -+ interruptible ? TASK_INTERRUPTIBLE : -+ TASK_UNINTERRUPTIBLE); -+ -+ if (interruptible && signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ -+ if (vc4->finished_seqno >= seqno) -+ break; -+ -+ if (timeout_ns != ~0ull) { -+ if (time_after_eq(jiffies, timeout_expire)) { -+ ret = -ETIME; -+ break; -+ } -+ schedule_timeout(timeout_expire - jiffies); -+ } else { -+ schedule(); -+ } -+ } -+ -+ finish_wait(&vc4->job_wait_queue, &wait); -+ trace_vc4_wait_for_seqno_end(dev, seqno); -+ -+ if (ret && ret != -ERESTARTSYS) { -+ DRM_ERROR("timeout waiting for render thread idle\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void -+vc4_flush_caches(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Flush the GPU L2 caches. These caches sit on top of system -+ * L3 (the 128kb or so shared with the CPU), and are -+ * non-allocating in the L3. -+ */ -+ V3D_WRITE(V3D_L2CACTL, -+ V3D_L2CACTL_L2CCLR); -+ -+ V3D_WRITE(V3D_SLCACTL, -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_T1CC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_T0CC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_UCC) | -+ VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); -+} -+ -+/* Sets the registers for the next job to be actually be executed in -+ * the hardware. -+ * -+ * The job_lock should be held during this. -+ */ -+void -+vc4_submit_next_job(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_exec_info *exec = vc4_first_job(vc4); -+ -+ if (!exec) -+ return; -+ -+ vc4_flush_caches(dev); -+ -+ /* Disable the binner's pre-loaded overflow memory address */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ if (exec->ct0ca != exec->ct0ea) -+ submit_cl(dev, 0, exec->ct0ca, exec->ct0ea); -+ submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); -+} -+ -+static void -+vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) -+{ -+ struct vc4_bo *bo; -+ unsigned i; -+ -+ for (i = 0; i < exec->bo_count; i++) { -+ bo = to_vc4_bo(&exec->bo[i].bo->base); -+ bo->seqno = seqno; -+ } -+ -+ list_for_each_entry(bo, &exec->unref_list, unref_head) { -+ bo->seqno = seqno; -+ } -+} -+ -+/* Queues a struct vc4_exec_info for execution. If no job is -+ * currently executing, then submits it. -+ * -+ * Unlike most GPUs, our hardware only handles one command list at a -+ * time. To queue multiple jobs at once, we'd need to edit the -+ * previous command list to have a jump to the new one at the end, and -+ * then bump the end address. That's a change for a later date, -+ * though. -+ */ -+static void -+vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint64_t seqno = ++vc4->emit_seqno; -+ unsigned long irqflags; -+ -+ exec->seqno = seqno; -+ vc4_update_bo_seqnos(exec, seqno); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ list_add_tail(&exec->head, &vc4->job_list); -+ -+ /* If no job was executing, kick ours off. Otherwise, it'll -+ * get started when the previous job's frame done interrupt -+ * occurs. -+ */ -+ if (vc4_first_job(vc4) == exec) { -+ vc4_submit_next_job(dev); -+ vc4_queue_hangcheck(dev); -+ } -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+} -+ -+/** -+ * Looks up a bunch of GEM handles for BOs and stores the array for -+ * use in the command validator that actually writes relocated -+ * addresses pointing to them. -+ */ -+static int -+vc4_cl_lookup_bos(struct drm_device *dev, -+ struct drm_file *file_priv, -+ struct vc4_exec_info *exec) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ uint32_t *handles; -+ int ret = 0; -+ int i; -+ -+ exec->bo_count = args->bo_handle_count; -+ -+ if (!exec->bo_count) { -+ /* See comment on bo_index for why we have to check -+ * this. -+ */ -+ DRM_ERROR("Rendering requires BOs to validate\n"); -+ return -EINVAL; -+ } -+ -+ exec->bo = kcalloc(exec->bo_count, sizeof(struct vc4_bo_exec_state), -+ GFP_KERNEL); -+ if (!exec->bo) { -+ DRM_ERROR("Failed to allocate validated BO pointers\n"); -+ return -ENOMEM; -+ } -+ -+ handles = drm_malloc_ab(exec->bo_count, sizeof(uint32_t)); -+ if (!handles) { -+ DRM_ERROR("Failed to allocate incoming GEM handles\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(handles, -+ (void __user *)(uintptr_t)args->bo_handles, -+ exec->bo_count * sizeof(uint32_t)); -+ if (ret) { -+ DRM_ERROR("Failed to copy in GEM handles\n"); -+ goto fail; -+ } -+ -+ spin_lock(&file_priv->table_lock); -+ for (i = 0; i < exec->bo_count; i++) { -+ struct drm_gem_object *bo = idr_find(&file_priv->object_idr, -+ handles[i]); -+ if (!bo) { -+ DRM_ERROR("Failed to look up GEM BO %d: %d\n", -+ i, handles[i]); -+ ret = -EINVAL; -+ spin_unlock(&file_priv->table_lock); -+ goto fail; -+ } -+ drm_gem_object_reference(bo); -+ exec->bo[i].bo = (struct drm_gem_cma_object *)bo; -+ } -+ spin_unlock(&file_priv->table_lock); -+ -+fail: -+ kfree(handles); -+ return 0; -+} -+ -+static int -+vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ void *temp = NULL; -+ void *bin; -+ int ret = 0; -+ uint32_t bin_offset = 0; -+ uint32_t shader_rec_offset = roundup(bin_offset + args->bin_cl_size, -+ 16); -+ uint32_t uniforms_offset = shader_rec_offset + args->shader_rec_size; -+ uint32_t exec_size = uniforms_offset + args->uniforms_size; -+ uint32_t temp_size = exec_size + (sizeof(struct vc4_shader_state) * -+ args->shader_rec_count); -+ struct vc4_bo *bo; -+ -+ if (uniforms_offset < shader_rec_offset || -+ exec_size < uniforms_offset || -+ args->shader_rec_count >= (UINT_MAX / -+ sizeof(struct vc4_shader_state)) || -+ temp_size < exec_size) { -+ DRM_ERROR("overflow in exec arguments\n"); -+ goto fail; -+ } -+ -+ /* Allocate space where we'll store the copied in user command lists -+ * and shader records. -+ * -+ * We don't just copy directly into the BOs because we need to -+ * read the contents back for validation, and I think the -+ * bo->vaddr is uncached access. -+ */ -+ temp = kmalloc(temp_size, GFP_KERNEL); -+ if (!temp) { -+ DRM_ERROR("Failed to allocate storage for copying " -+ "in bin/render CLs.\n"); -+ ret = -ENOMEM; -+ goto fail; -+ } -+ bin = temp + bin_offset; -+ exec->shader_rec_u = temp + shader_rec_offset; -+ exec->uniforms_u = temp + uniforms_offset; -+ exec->shader_state = temp + exec_size; -+ exec->shader_state_size = args->shader_rec_count; -+ -+ ret = copy_from_user(bin, -+ (void __user *)(uintptr_t)args->bin_cl, -+ args->bin_cl_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in bin cl\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(exec->shader_rec_u, -+ (void __user *)(uintptr_t)args->shader_rec, -+ args->shader_rec_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in shader recs\n"); -+ goto fail; -+ } -+ -+ ret = copy_from_user(exec->uniforms_u, -+ (void __user *)(uintptr_t)args->uniforms, -+ args->uniforms_size); -+ if (ret) { -+ DRM_ERROR("Failed to copy in uniforms cl\n"); -+ goto fail; -+ } -+ -+ bo = vc4_bo_create(dev, exec_size); -+ if (!bo) { -+ DRM_ERROR("Couldn't allocate BO for binning\n"); -+ ret = PTR_ERR(exec->exec_bo); -+ goto fail; -+ } -+ exec->exec_bo = &bo->base; -+ -+ list_add_tail(&to_vc4_bo(&exec->exec_bo->base)->unref_head, -+ &exec->unref_list); -+ -+ exec->ct0ca = exec->exec_bo->paddr + bin_offset; -+ -+ exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; -+ exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; -+ exec->shader_rec_size = args->shader_rec_size; -+ -+ exec->uniforms_v = exec->exec_bo->vaddr + uniforms_offset; -+ exec->uniforms_p = exec->exec_bo->paddr + uniforms_offset; -+ exec->uniforms_size = args->uniforms_size; -+ -+ ret = vc4_validate_bin_cl(dev, -+ exec->exec_bo->vaddr + bin_offset, -+ bin, -+ exec); -+ if (ret) -+ goto fail; -+ -+ ret = vc4_validate_shader_recs(dev, exec); -+ -+fail: -+ kfree(temp); -+ return ret; -+} -+ -+static void -+vc4_complete_exec(struct vc4_exec_info *exec) -+{ -+ unsigned i; -+ -+ if (exec->bo) { -+ for (i = 0; i < exec->bo_count; i++) -+ drm_gem_object_unreference(&exec->bo[i].bo->base); -+ kfree(exec->bo); -+ } -+ -+ while (!list_empty(&exec->unref_list)) { -+ struct vc4_bo *bo = list_first_entry(&exec->unref_list, -+ struct vc4_bo, unref_head); -+ list_del(&bo->unref_head); -+ drm_gem_object_unreference(&bo->base.base); -+ } -+ -+ kfree(exec); -+} -+ -+void -+vc4_job_handle_completed(struct vc4_dev *vc4) -+{ -+ unsigned long irqflags; -+ struct vc4_seqno_cb *cb, *cb_temp; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ while (!list_empty(&vc4->job_done_list)) { -+ struct vc4_exec_info *exec = -+ list_first_entry(&vc4->job_done_list, -+ struct vc4_exec_info, head); -+ list_del(&exec->head); -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ vc4_complete_exec(exec); -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ } -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ list_for_each_entry_safe(cb, cb_temp, &vc4->seqno_cb_list, work.entry) { -+ if (cb->seqno <= vc4->finished_seqno) { -+ list_del_init(&cb->work.entry); -+ schedule_work(&cb->work); -+ } -+ } -+} -+ -+static void vc4_seqno_cb_work(struct work_struct *work) -+{ -+ struct vc4_seqno_cb *cb = container_of(work, struct vc4_seqno_cb, work); -+ cb->func(cb); -+} -+ -+int vc4_queue_seqno_cb(struct drm_device *dev, -+ struct vc4_seqno_cb *cb, uint64_t seqno, -+ void (*func)(struct vc4_seqno_cb *cb)) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret = 0; -+ -+ cb->func = func; -+ INIT_WORK(&cb->work, vc4_seqno_cb_work); -+ -+ mutex_lock(&dev->struct_mutex); -+ if (seqno > vc4->finished_seqno) { -+ cb->seqno = seqno; -+ list_add_tail(&cb->work.entry, &vc4->seqno_cb_list); -+ } else { -+ schedule_work(&cb->work); -+ } -+ mutex_unlock(&dev->struct_mutex); -+ -+ return ret; -+} -+ -+/* Scheduled when any job has been completed, this walks the list of -+ * jobs that had completed and unrefs their BOs and frees their exec -+ * structs. -+ */ -+static void -+vc4_job_done_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, job_done_work); -+ struct drm_device *dev = vc4->dev; -+ -+ /* Need the struct lock for drm_gem_object_unreference(). */ -+ mutex_lock(&dev->struct_mutex); -+ vc4_job_handle_completed(vc4); -+ mutex_unlock(&dev->struct_mutex); -+} -+ -+static int -+vc4_wait_for_seqno_ioctl_helper(struct drm_device *dev, -+ uint64_t seqno, -+ uint64_t *timeout_ns) -+{ -+ unsigned long start = jiffies; -+ int ret = vc4_wait_for_seqno(dev, seqno, *timeout_ns, true); -+ -+ if ((ret == -EINTR || ret == -ERESTARTSYS) && *timeout_ns != ~0ull) { -+ uint64_t delta = jiffies_to_nsecs(jiffies - start); -+ if (*timeout_ns >= delta) -+ *timeout_ns -= delta; -+ } -+ -+ return ret; -+} -+ -+int -+vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_wait_seqno *args = data; -+ -+ return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, -+ &args->timeout_ns); -+} -+ -+int -+vc4_wait_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ int ret; -+ struct drm_vc4_wait_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ bo = to_vc4_bo(gem_obj); -+ -+ ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, &args->timeout_ns); -+ -+ drm_gem_object_unreference(gem_obj); -+ return ret; -+} -+ -+/** -+ * Submits a command list to the VC4. -+ * -+ * This is what is called batchbuffer emitting on other hardware. -+ */ -+int -+vc4_submit_cl_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_vc4_submit_cl *args = data; -+ struct vc4_exec_info *exec; -+ int ret; -+ -+ if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) { -+ DRM_ERROR("Unknown flags: 0x%02x\n", args->flags); -+ return -EINVAL; -+ } -+ -+ exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); -+ if (!exec) { -+ DRM_ERROR("malloc failure on exec struct\n"); -+ return -ENOMEM; -+ } -+ -+ exec->args = args; -+ INIT_LIST_HEAD(&exec->unref_list); -+ -+ mutex_lock(&dev->struct_mutex); -+ -+ ret = vc4_cl_lookup_bos(dev, file_priv, exec); -+ if (ret) -+ goto fail; -+ -+ if (exec->args->bin_cl_size != 0) { -+ ret = vc4_get_bcl(dev, exec); -+ if (ret) -+ goto fail; -+ } else { -+ exec->ct0ca = exec->ct0ea = 0; -+ } -+ -+ ret = vc4_get_rcl(dev, exec); -+ if (ret) -+ goto fail; -+ -+ /* Clear this out of the struct we'll be putting in the queue, -+ * since it's part of our stack. -+ */ -+ exec->args = NULL; -+ -+ vc4_queue_submit(dev, exec); -+ -+ /* Return the seqno for our job. */ -+ args->seqno = vc4->emit_seqno; -+ -+ mutex_unlock(&dev->struct_mutex); -+ -+ return 0; -+ -+fail: -+ vc4_complete_exec(exec); -+ -+ mutex_unlock(&dev->struct_mutex); -+ -+ return ret; -+} -+ -+void -+vc4_gem_init(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ INIT_LIST_HEAD(&vc4->job_list); -+ INIT_LIST_HEAD(&vc4->job_done_list); -+ INIT_LIST_HEAD(&vc4->seqno_cb_list); -+ spin_lock_init(&vc4->job_lock); -+ -+ INIT_WORK(&vc4->hangcheck.reset_work, vc4_reset_work); -+ setup_timer(&vc4->hangcheck.timer, -+ vc4_hangcheck_elapsed, -+ (unsigned long) dev); -+ -+ INIT_WORK(&vc4->job_done_work, vc4_job_done_work); -+} -+ -+void -+vc4_gem_destroy(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Waiting for exec to finish would need to be done before -+ * unregistering V3D. -+ */ -+ WARN_ON(vc4->emit_seqno != vc4->finished_seqno); -+ -+ /* V3D should already have disabled its interrupt and cleared -+ * the overflow allocation registers. Now free the object. -+ */ -+ if (vc4->overflow_mem) { -+ drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -+ vc4->overflow_mem = NULL; -+ } -+ -+ vc4_bo_cache_destroy(dev); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -new file mode 100644 -index 0000000..f29b796 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -0,0 +1,211 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** DOC: Interrupt management for the V3D engine. -+ * -+ * We have an interrupt status register (V3D_INTCTL) which reports -+ * interrupts, and where writing 1 bits clears those interrupts. -+ * There are also a pair of interrupt registers -+ * (V3D_INTENA/V3D_INTDIS) where writing a 1 to their bits enables or -+ * disables that specific interrupt, and 0s written are ignored -+ * (reading either one returns the set of enabled interrupts). -+ * -+ * When we take a render frame interrupt, we need to wake the -+ * processes waiting for some frame to be done, and get the next frame -+ * submitted ASAP (so the hardware doesn't sit idle when there's work -+ * to do). -+ * -+ * When we take the binner out of memory interrupt, we need to -+ * allocate some new memory and pass it to the binner so that the -+ * current job can make progress. -+ */ -+ -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+ -+#define V3D_DRIVER_IRQS (V3D_INT_OUTOMEM | \ -+ V3D_INT_FRDONE) -+ -+DECLARE_WAIT_QUEUE_HEAD(render_wait); -+ -+static void -+vc4_overflow_mem_work(struct work_struct *work) -+{ -+ struct vc4_dev *vc4 = -+ container_of(work, struct vc4_dev, overflow_mem_work); -+ struct drm_device *dev = vc4->dev; -+ struct vc4_bo *bo; -+ -+ bo = vc4_bo_create(dev, 256 * 1024); -+ if (!bo) { -+ DRM_ERROR("Couldn't allocate binner overflow mem\n"); -+ return; -+ } -+ -+ /* If there's a job executing currently, then our previous -+ * overflow allocation is getting used in that job and we need -+ * to queue it to be released when the job is done. But if no -+ * job is executing at all, then we can free the old overflow -+ * object direcctly. -+ * -+ * No lock necessary for this pointer since we're the only -+ * ones that update the pointer, and our workqueue won't -+ * reenter. -+ */ -+ if (vc4->overflow_mem) { -+ struct vc4_exec_info *current_exec; -+ unsigned long irqflags; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ current_exec = vc4_first_job(vc4); -+ if (current_exec) { -+ vc4->overflow_mem->seqno = vc4->finished_seqno + 1; -+ list_add_tail(&vc4->overflow_mem->unref_head, -+ ¤t_exec->unref_list); -+ vc4->overflow_mem = NULL; -+ } -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ } -+ -+ if (vc4->overflow_mem) { -+ drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -+ } -+ vc4->overflow_mem = bo; -+ -+ V3D_WRITE(V3D_BPOA, bo->base.paddr); -+ V3D_WRITE(V3D_BPOS, bo->base.base.size); -+ V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM); -+ V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM); -+} -+ -+static void -+vc4_irq_finish_job(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_exec_info *exec = vc4_first_job(vc4); -+ -+ if (!exec) -+ return; -+ -+ vc4->finished_seqno++; -+ list_move_tail(&exec->head, &vc4->job_done_list); -+ vc4_submit_next_job(dev); -+ -+ wake_up_all(&vc4->job_wait_queue); -+ schedule_work(&vc4->job_done_work); -+} -+ -+irqreturn_t -+vc4_irq(int irq, void *arg) -+{ -+ struct drm_device *dev = arg; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t intctl; -+ irqreturn_t status = IRQ_NONE; -+ -+ barrier(); -+ intctl = V3D_READ(V3D_INTCTL); -+ -+ /* Acknowledge the interrupts we're handling here. The render -+ * frame done interrupt will be cleared, while OUTOMEM will -+ * stay high until the underlying cause is cleared. -+ */ -+ V3D_WRITE(V3D_INTCTL, intctl); -+ -+ if (intctl & V3D_INT_OUTOMEM) { -+ /* Disable OUTOMEM until the work is done. */ -+ V3D_WRITE(V3D_INTDIS, V3D_INT_OUTOMEM); -+ schedule_work(&vc4->overflow_mem_work); -+ status = IRQ_HANDLED; -+ } -+ -+ if (intctl & V3D_INT_FRDONE) { -+ spin_lock(&vc4->job_lock); -+ vc4_irq_finish_job(dev); -+ spin_unlock(&vc4->job_lock); -+ status = IRQ_HANDLED; -+ } -+ -+ return status; -+} -+ -+void -+vc4_irq_preinstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ init_waitqueue_head(&vc4->job_wait_queue); -+ INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work); -+ -+ /* Clear any pending interrupts someone might have left around -+ * for us. -+ */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+} -+ -+int -+vc4_irq_postinstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Enable both the render done and out of memory interrupts. */ -+ V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); -+ -+ return 0; -+} -+ -+void -+vc4_irq_uninstall(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Disable sending interrupts for our driver's IRQs. */ -+ V3D_WRITE(V3D_INTDIS, V3D_DRIVER_IRQS); -+ -+ /* Clear any pending interrupts we might have left. */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+ -+ cancel_work_sync(&vc4->overflow_mem_work); -+} -+ -+/** Reinitializes interrupt registers when a GPU reset is performed. */ -+void vc4_irq_reset(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long irqflags; -+ -+ /* Acknowledge any stale IRQs. */ -+ V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS); -+ -+ /* -+ * Turn all our interrupts on. Binner out of memory is the -+ * only one we expect to trigger at this point, since we've -+ * just come from poweron and haven't supplied any overflow -+ * memory yet. -+ */ -+ V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ vc4_irq_finish_job(dev); -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index 2e5597d..c83287a 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -15,6 +15,7 @@ - */ - - #include "drm_crtc.h" -+#include "drm_atomic.h" - #include "drm_atomic_helper.h" - #include "drm_crtc_helper.h" - #include "drm_plane_helper.h" -@@ -29,10 +30,151 @@ static void vc4_output_poll_changed(struct drm_device *dev) - drm_fbdev_cma_hotplug_event(vc4->fbdev); - } - -+struct vc4_commit { -+ struct drm_device *dev; -+ struct drm_atomic_state *state; -+ struct vc4_seqno_cb cb; -+}; -+ -+static void -+vc4_atomic_complete_commit(struct vc4_commit *c) -+{ -+ struct drm_atomic_state *state = c->state; -+ struct drm_device *dev = state->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ drm_atomic_helper_commit_modeset_disables(dev, state); -+ -+ drm_atomic_helper_commit_planes(dev, state); -+ -+ drm_atomic_helper_commit_modeset_enables(dev, state); -+ -+ drm_atomic_helper_wait_for_vblanks(dev, state); -+ -+ drm_atomic_helper_cleanup_planes(dev, state); -+ -+ drm_atomic_state_free(state); -+ -+ up(&vc4->async_modeset); -+ -+ kfree(c); -+} -+ -+static void -+vc4_atomic_complete_commit_seqno_cb(struct vc4_seqno_cb *cb) -+{ -+ struct vc4_commit *c = container_of(cb, struct vc4_commit, cb); -+ -+ vc4_atomic_complete_commit(c); -+} -+ -+static struct vc4_commit *commit_init(struct drm_atomic_state *state) -+{ -+ struct vc4_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); -+ -+ if (!c) -+ return NULL; -+ c->dev = state->dev; -+ c->state = state; -+ -+ return c; -+} -+ -+/** -+ * vc4_atomic_commit - commit validated state object -+ * @dev: DRM device -+ * @state: the driver state object -+ * @async: asynchronous commit -+ * -+ * This function commits a with drm_atomic_helper_check() pre-validated state -+ * object. This can still fail when e.g. the framebuffer reservation fails. For -+ * now this doesn't implement asynchronous commits. -+ * -+ * RETURNS -+ * Zero for success or -errno. -+ */ -+static int vc4_atomic_commit(struct drm_device *dev, -+ struct drm_atomic_state *state, -+ bool async) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int ret; -+ int i; -+ uint64_t wait_seqno = 0; -+ struct vc4_commit *c; -+ -+ c = commit_init(state); -+ if (!c) -+ return -ENOMEM; -+ -+ /* Make sure that any outstanding modesets have finished. */ -+ ret = down_interruptible(&vc4->async_modeset); -+ if (ret) { -+ kfree(c); -+ return ret; -+ } -+ -+ ret = drm_atomic_helper_prepare_planes(dev, state); -+ if (ret) { -+ kfree(c); -+ up(&vc4->async_modeset); -+ return ret; -+ } -+ -+ for (i = 0; i < dev->mode_config.num_total_plane; i++) { -+ struct drm_plane *plane = state->planes[i]; -+ struct drm_plane_state *new_state = state->plane_states[i]; -+ -+ if (!plane) -+ continue; -+ -+ if ((plane->state->fb != new_state->fb) && new_state->fb) { -+ struct drm_gem_cma_object *cma_bo = -+ drm_fb_cma_get_gem_obj(new_state->fb, 0); -+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ wait_seqno = max(bo->seqno, wait_seqno); -+ } -+ } -+ -+ /* -+ * This is the point of no return - everything below never fails except -+ * when the hw goes bonghits. Which means we can commit the new state on -+ * the software side now. -+ */ -+ -+ drm_atomic_helper_swap_state(dev, state); -+ -+ /* -+ * Everything below can be run asynchronously without the need to grab -+ * any modeset locks at all under one condition: It must be guaranteed -+ * that the asynchronous work has either been cancelled (if the driver -+ * supports it, which at least requires that the framebuffers get -+ * cleaned up with drm_atomic_helper_cleanup_planes()) or completed -+ * before the new state gets committed on the software side with -+ * drm_atomic_helper_swap_state(). -+ * -+ * This scheme allows new atomic state updates to be prepared and -+ * checked in parallel to the asynchronous completion of the previous -+ * update. Which is important since compositors need to figure out the -+ * composition of the next frame right after having submitted the -+ * current layout. -+ */ -+ -+ if (async) { -+ vc4_queue_seqno_cb(dev, &c->cb, wait_seqno, -+ vc4_atomic_complete_commit_seqno_cb); -+ } else { -+ vc4_wait_for_seqno(dev, wait_seqno, ~0ull, false); -+ vc4_atomic_complete_commit(c); -+ } -+ -+ return 0; -+} -+ - static const struct drm_mode_config_funcs vc4_mode_funcs = { - .output_poll_changed = vc4_output_poll_changed, - .atomic_check = drm_atomic_helper_check, -- .atomic_commit = drm_atomic_helper_commit, -+ .atomic_commit = vc4_atomic_commit, - .fb_create = drm_fb_cma_create, - }; - -@@ -41,6 +183,8 @@ int vc4_kms_load(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret; - -+ sema_init(&vc4->async_modeset, 1); -+ - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret < 0) { - dev_err(dev->dev, "failed to initialize vblank\n"); -@@ -51,6 +195,8 @@ int vc4_kms_load(struct drm_device *dev) - dev->mode_config.max_height = 2048; - dev->mode_config.funcs = &vc4_mode_funcs; - dev->mode_config.preferred_depth = 24; -+ dev->mode_config.async_page_flip = true; -+ - dev->vblank_disable_allowed = true; - - drm_mode_config_reset(dev); -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -new file mode 100644 -index 0000000..9757bc8 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -0,0 +1,384 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef VC4_PACKET_H -+#define VC4_PACKET_H -+ -+#include "vc4_regs.h" /* for VC4_MASK, VC4_GET_FIELD, VC4_SET_FIELD */ -+ -+enum vc4_packet { -+ VC4_PACKET_HALT = 0, -+ VC4_PACKET_NOP = 1, -+ -+ VC4_PACKET_FLUSH = 4, -+ VC4_PACKET_FLUSH_ALL = 5, -+ VC4_PACKET_START_TILE_BINNING = 6, -+ VC4_PACKET_INCREMENT_SEMAPHORE = 7, -+ VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -+ -+ VC4_PACKET_BRANCH = 16, -+ VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -+ -+ VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -+ VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -+ VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -+ VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -+ VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -+ -+ VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -+ VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -+ -+ VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -+ VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -+ -+ VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -+ -+ VC4_PACKET_GL_SHADER_STATE = 64, -+ VC4_PACKET_NV_SHADER_STATE = 65, -+ VC4_PACKET_VG_SHADER_STATE = 66, -+ -+ VC4_PACKET_CONFIGURATION_BITS = 96, -+ VC4_PACKET_FLAT_SHADE_FLAGS = 97, -+ VC4_PACKET_POINT_SIZE = 98, -+ VC4_PACKET_LINE_WIDTH = 99, -+ VC4_PACKET_RHT_X_BOUNDARY = 100, -+ VC4_PACKET_DEPTH_OFFSET = 101, -+ VC4_PACKET_CLIP_WINDOW = 102, -+ VC4_PACKET_VIEWPORT_OFFSET = 103, -+ VC4_PACKET_Z_CLIPPING = 104, -+ VC4_PACKET_CLIPPER_XY_SCALING = 105, -+ VC4_PACKET_CLIPPER_Z_SCALING = 106, -+ -+ VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -+ VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -+ VC4_PACKET_CLEAR_COLORS = 114, -+ VC4_PACKET_TILE_COORDINATES = 115, -+ -+ /* Not an actual hardware packet -- this is what we use to put -+ * references to GEM bos in the command stream, since we need the u32 -+ * int the actual address packet in order to store the offset from the -+ * start of the BO. -+ */ -+ VC4_PACKET_GEM_HANDLES = 254, -+} __attribute__ ((__packed__)); -+ -+#define VC4_PACKET_HALT_SIZE 1 -+#define VC4_PACKET_NOP_SIZE 1 -+#define VC4_PACKET_FLUSH_SIZE 1 -+#define VC4_PACKET_FLUSH_ALL_SIZE 1 -+#define VC4_PACKET_START_TILE_BINNING_SIZE 1 -+#define VC4_PACKET_INCREMENT_SEMAPHORE_SIZE 1 -+#define VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE 1 -+#define VC4_PACKET_BRANCH_SIZE 5 -+#define VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE 5 -+#define VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE 1 -+#define VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF_SIZE 1 -+#define VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE 5 -+#define VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE 5 -+#define VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE 7 -+#define VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE 7 -+#define VC4_PACKET_GL_INDEXED_PRIMITIVE_SIZE 14 -+#define VC4_PACKET_GL_ARRAY_PRIMITIVE_SIZE 10 -+#define VC4_PACKET_COMPRESSED_PRIMITIVE_SIZE 1 -+#define VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE_SIZE 1 -+#define VC4_PACKET_PRIMITIVE_LIST_FORMAT_SIZE 2 -+#define VC4_PACKET_GL_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_NV_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_VG_SHADER_STATE_SIZE 5 -+#define VC4_PACKET_CONFIGURATION_BITS_SIZE 4 -+#define VC4_PACKET_FLAT_SHADE_FLAGS_SIZE 5 -+#define VC4_PACKET_POINT_SIZE_SIZE 5 -+#define VC4_PACKET_LINE_WIDTH_SIZE 5 -+#define VC4_PACKET_RHT_X_BOUNDARY_SIZE 3 -+#define VC4_PACKET_DEPTH_OFFSET_SIZE 5 -+#define VC4_PACKET_CLIP_WINDOW_SIZE 9 -+#define VC4_PACKET_VIEWPORT_OFFSET_SIZE 5 -+#define VC4_PACKET_Z_CLIPPING_SIZE 9 -+#define VC4_PACKET_CLIPPER_XY_SCALING_SIZE 9 -+#define VC4_PACKET_CLIPPER_Z_SCALING_SIZE 9 -+#define VC4_PACKET_TILE_BINNING_MODE_CONFIG_SIZE 16 -+#define VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE 11 -+#define VC4_PACKET_CLEAR_COLORS_SIZE 14 -+#define VC4_PACKET_TILE_COORDINATES_SIZE 3 -+#define VC4_PACKET_GEM_HANDLES_SIZE 9 -+ -+/** @{ -+ * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_TILE_RENDERING_MODE_CONFIG. -+*/ -+#define VC4_TILING_FORMAT_LINEAR 0 -+#define VC4_TILING_FORMAT_T 1 -+#define VC4_TILING_FORMAT_LT 2 -+/** @} */ -+ -+/** @{ -+ * -+ * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and -+ * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. -+ */ -+#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0) -+ -+/** @{ -+ * -+ * byte 2 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address) -+ */ -+ -+#define VC4_LOADSTORE_TILE_BUFFER_EOF (1 << 3) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS (1 << 1) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR (1 << 0) -+ -+/** @} */ -+ -+/** @{ -+ * -+ * byte 0-1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL -+ */ -+#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 15) -+#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR (1 << 14) -+#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR (1 << 13) -+#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP (1 << 12) -+ -+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK VC4_MASK(9, 8) -+#define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT 8 -+#define VC4_LOADSTORE_TILE_BUFFER_RGBA8888 0 -+#define VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER 1 -+#define VC4_LOADSTORE_TILE_BUFFER_BGR565 2 -+/** @} */ -+ -+/** @{ -+ * -+ * byte 0 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and -+ * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL -+ */ -+#define VC4_STORE_TILE_BUFFER_MODE_MASK VC4_MASK(7, 6) -+#define VC4_STORE_TILE_BUFFER_MODE_SHIFT 6 -+#define VC4_STORE_TILE_BUFFER_MODE_SAMPLE0 (0 << 6) -+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X4 (1 << 6) -+#define VC4_STORE_TILE_BUFFER_MODE_DECIMATE_X16 (2 << 6) -+ -+/** The values of the field are VC4_TILING_FORMAT_* */ -+#define VC4_LOADSTORE_TILE_BUFFER_TILING_MASK VC4_MASK(5, 4) -+#define VC4_LOADSTORE_TILE_BUFFER_TILING_SHIFT 4 -+ -+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK VC4_MASK(2, 0) -+#define VC4_LOADSTORE_TILE_BUFFER_BUFFER_SHIFT 0 -+#define VC4_LOADSTORE_TILE_BUFFER_NONE 0 -+#define VC4_LOADSTORE_TILE_BUFFER_COLOR 1 -+#define VC4_LOADSTORE_TILE_BUFFER_ZS 2 -+#define VC4_LOADSTORE_TILE_BUFFER_Z 3 -+#define VC4_LOADSTORE_TILE_BUFFER_VG_MASK 4 -+#define VC4_LOADSTORE_TILE_BUFFER_FULL 5 -+/** @} */ -+ -+#define VC4_INDEX_BUFFER_U8 (0 << 4) -+#define VC4_INDEX_BUFFER_U16 (1 << 4) -+ -+/* This flag is only present in NV shader state. */ -+#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS (1 << 3) -+#define VC4_SHADER_FLAG_ENABLE_CLIPPING (1 << 2) -+#define VC4_SHADER_FLAG_VS_POINT_SIZE (1 << 1) -+#define VC4_SHADER_FLAG_FS_SINGLE_THREAD (1 << 0) -+ -+/** @{ byte 2 of config bits. */ -+#define VC4_CONFIG_BITS_EARLY_Z_UPDATE (1 << 1) -+#define VC4_CONFIG_BITS_EARLY_Z (1 << 0) -+/** @} */ -+ -+/** @{ byte 1 of config bits. */ -+#define VC4_CONFIG_BITS_Z_UPDATE (1 << 7) -+/** same values in this 3-bit field as PIPE_FUNC_* */ -+#define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT 4 -+#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE (1 << 3) -+ -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO (0 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD (1 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR (2 << 1) -+#define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO (3 << 1) -+ -+#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT (1 << 0) -+/** @} */ -+ -+/** @{ byte 0 of config bits. */ -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_NONE (0 << 6) -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X (1 << 6) -+#define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X (2 << 6) -+ -+#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES (1 << 4) -+#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET (1 << 3) -+#define VC4_CONFIG_BITS_CW_PRIMITIVES (1 << 2) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK (1 << 1) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT (1 << 0) -+/** @} */ -+ -+/** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */ -+#define VC4_BIN_CONFIG_DB_NON_MS (1 << 7) -+ -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK VC4_MASK(6, 5) -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_SHIFT 5 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32 0 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_64 1 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128 2 -+#define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_256 3 -+ -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK VC4_MASK(4, 3) -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_SHIFT 3 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32 0 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_64 1 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128 2 -+#define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256 3 -+ -+#define VC4_BIN_CONFIG_AUTO_INIT_TSDA (1 << 2) -+#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT (1 << 1) -+#define VC4_BIN_CONFIG_MS_MODE_4X (1 << 0) -+/** @} */ -+ -+/** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */ -+#define VC4_RENDER_CONFIG_DB_NON_MS (1 << 12) -+#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11) -+#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G (1 << 10) -+#define VC4_RENDER_CONFIG_COVERAGE_MODE (1 << 9) -+#define VC4_RENDER_CONFIG_ENABLE_VG_MASK (1 << 8) -+ -+/** The values of the field are VC4_TILING_FORMAT_* */ -+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK VC4_MASK(7, 6) -+#define VC4_RENDER_CONFIG_MEMORY_FORMAT_SHIFT 6 -+ -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_1X (0 << 4) -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_4X (1 << 4) -+#define VC4_RENDER_CONFIG_DECIMATE_MODE_16X (2 << 4) -+ -+#define VC4_RENDER_CONFIG_FORMAT_MASK VC4_MASK(3, 2) -+#define VC4_RENDER_CONFIG_FORMAT_SHIFT 2 -+#define VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED 0 -+#define VC4_RENDER_CONFIG_FORMAT_RGBA8888 1 -+#define VC4_RENDER_CONFIG_FORMAT_BGR565 2 -+ -+#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT (1 << 1) -+#define VC4_RENDER_CONFIG_MS_MODE_4X (1 << 0) -+ -+#define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX (1 << 4) -+#define VC4_PRIMITIVE_LIST_FORMAT_32_XY (3 << 4) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_POINTS (0 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_LINES (1 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_TRIANGLES (2 << 0) -+#define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT (3 << 0) -+ -+enum vc4_texture_data_type { -+ VC4_TEXTURE_TYPE_RGBA8888 = 0, -+ VC4_TEXTURE_TYPE_RGBX8888 = 1, -+ VC4_TEXTURE_TYPE_RGBA4444 = 2, -+ VC4_TEXTURE_TYPE_RGBA5551 = 3, -+ VC4_TEXTURE_TYPE_RGB565 = 4, -+ VC4_TEXTURE_TYPE_LUMINANCE = 5, -+ VC4_TEXTURE_TYPE_ALPHA = 6, -+ VC4_TEXTURE_TYPE_LUMALPHA = 7, -+ VC4_TEXTURE_TYPE_ETC1 = 8, -+ VC4_TEXTURE_TYPE_S16F = 9, -+ VC4_TEXTURE_TYPE_S8 = 10, -+ VC4_TEXTURE_TYPE_S16 = 11, -+ VC4_TEXTURE_TYPE_BW1 = 12, -+ VC4_TEXTURE_TYPE_A4 = 13, -+ VC4_TEXTURE_TYPE_A1 = 14, -+ VC4_TEXTURE_TYPE_RGBA64 = 15, -+ VC4_TEXTURE_TYPE_RGBA32R = 16, -+ VC4_TEXTURE_TYPE_YUV422R = 17, -+}; -+ -+#define VC4_TEX_P0_OFFSET_MASK VC4_MASK(31, 12) -+#define VC4_TEX_P0_OFFSET_SHIFT 12 -+#define VC4_TEX_P0_CSWIZ_MASK VC4_MASK(11, 10) -+#define VC4_TEX_P0_CSWIZ_SHIFT 10 -+#define VC4_TEX_P0_CMMODE_MASK VC4_MASK(9, 9) -+#define VC4_TEX_P0_CMMODE_SHIFT 9 -+#define VC4_TEX_P0_FLIPY_MASK VC4_MASK(8, 8) -+#define VC4_TEX_P0_FLIPY_SHIFT 8 -+#define VC4_TEX_P0_TYPE_MASK VC4_MASK(7, 4) -+#define VC4_TEX_P0_TYPE_SHIFT 4 -+#define VC4_TEX_P0_MIPLVLS_MASK VC4_MASK(3, 0) -+#define VC4_TEX_P0_MIPLVLS_SHIFT 0 -+ -+#define VC4_TEX_P1_TYPE4_MASK VC4_MASK(31, 31) -+#define VC4_TEX_P1_TYPE4_SHIFT 31 -+#define VC4_TEX_P1_HEIGHT_MASK VC4_MASK(30, 20) -+#define VC4_TEX_P1_HEIGHT_SHIFT 20 -+#define VC4_TEX_P1_ETCFLIP_MASK VC4_MASK(19, 19) -+#define VC4_TEX_P1_ETCFLIP_SHIFT 19 -+#define VC4_TEX_P1_WIDTH_MASK VC4_MASK(18, 8) -+#define VC4_TEX_P1_WIDTH_SHIFT 8 -+ -+#define VC4_TEX_P1_MAGFILT_MASK VC4_MASK(7, 7) -+#define VC4_TEX_P1_MAGFILT_SHIFT 7 -+# define VC4_TEX_P1_MAGFILT_LINEAR 0 -+# define VC4_TEX_P1_MAGFILT_NEAREST 1 -+ -+#define VC4_TEX_P1_MINFILT_MASK VC4_MASK(6, 4) -+#define VC4_TEX_P1_MINFILT_SHIFT 4 -+# define VC4_TEX_P1_MINFILT_LINEAR 0 -+# define VC4_TEX_P1_MINFILT_NEAREST 1 -+# define VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR 2 -+# define VC4_TEX_P1_MINFILT_NEAR_MIP_LIN 3 -+# define VC4_TEX_P1_MINFILT_LIN_MIP_NEAR 4 -+# define VC4_TEX_P1_MINFILT_LIN_MIP_LIN 5 -+ -+#define VC4_TEX_P1_WRAP_T_MASK VC4_MASK(3, 2) -+#define VC4_TEX_P1_WRAP_T_SHIFT 2 -+#define VC4_TEX_P1_WRAP_S_MASK VC4_MASK(1, 0) -+#define VC4_TEX_P1_WRAP_S_SHIFT 0 -+# define VC4_TEX_P1_WRAP_REPEAT 0 -+# define VC4_TEX_P1_WRAP_CLAMP 1 -+# define VC4_TEX_P1_WRAP_MIRROR 2 -+# define VC4_TEX_P1_WRAP_BORDER 3 -+ -+#define VC4_TEX_P2_PTYPE_MASK VC4_MASK(31, 30) -+#define VC4_TEX_P2_PTYPE_SHIFT 30 -+# define VC4_TEX_P2_PTYPE_IGNORED 0 -+# define VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE 1 -+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS 2 -+# define VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS 3 -+ -+/* VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE bits */ -+#define VC4_TEX_P2_CMST_MASK VC4_MASK(29, 12) -+#define VC4_TEX_P2_CMST_SHIFT 12 -+#define VC4_TEX_P2_BSLOD_MASK VC4_MASK(0, 0) -+#define VC4_TEX_P2_BSLOD_SHIFT 0 -+ -+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_DIMENSIONS */ -+#define VC4_TEX_P2_CHEIGHT_MASK VC4_MASK(22, 12) -+#define VC4_TEX_P2_CHEIGHT_SHIFT 12 -+#define VC4_TEX_P2_CWIDTH_MASK VC4_MASK(10, 0) -+#define VC4_TEX_P2_CWIDTH_SHIFT 0 -+ -+/* VC4_TEX_P2_PTYPE_CHILD_IMAGE_OFFSETS */ -+#define VC4_TEX_P2_CYOFF_MASK VC4_MASK(22, 12) -+#define VC4_TEX_P2_CYOFF_SHIFT 12 -+#define VC4_TEX_P2_CXOFF_MASK VC4_MASK(10, 0) -+#define VC4_TEX_P2_CXOFF_SHIFT 0 -+ -+#endif /* VC4_PACKET_H */ -diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c -index 887f3ca..65e5455 100644 ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -29,6 +29,14 @@ struct vc4_plane_state { - u32 *dlist; - u32 dlist_size; /* Number of dwords in allocated for the display list */ - u32 dlist_count; /* Number of used dwords in the display list. */ -+ -+ /* Offset in the dlist to pointer word 0. */ -+ u32 pw0_offset; -+ -+ /* Offset where the plane's dlist was last stored in the -+ hardware at vc4_crtc_atomic_flush() time. -+ */ -+ u32 *hw_dlist; - }; - - static inline struct vc4_plane_state * -@@ -207,6 +215,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, - /* Position Word 3: Context. Written by the HVS. */ - vc4_dlist_write(vc4_state, 0xc0c0c0c0); - -+ vc4_state->pw0_offset = vc4_state->dlist_count; -+ - /* Pointer Word 0: RGB / Y Pointer */ - vc4_dlist_write(vc4_state, bo->paddr + offset); - -@@ -258,6 +268,8 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) - struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); - int i; - -+ vc4_state->hw_dlist = dlist; -+ - /* Can't memcpy_toio() because it needs to be 32-bit writes. */ - for (i = 0; i < vc4_state->dlist_count; i++) - writel(vc4_state->dlist[i], &dlist[i]); -@@ -272,6 +284,34 @@ u32 vc4_plane_dlist_size(struct drm_plane_state *state) - return vc4_state->dlist_count; - } - -+/* Updates the plane to immediately (well, once the FIFO needs -+ * refilling) scan out from at a new framebuffer. -+ */ -+void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) -+{ -+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); -+ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -+ uint32_t addr; -+ -+ /* We're skipping the address adjustment for negative origin, -+ * because this is only called on the primary plane. -+ */ -+ WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); -+ addr = bo->paddr + fb->offsets[0]; -+ -+ /* Write the new address into the hardware immediately. The -+ * scanout will start from this address as soon as the FIFO -+ * needs to refill with pixels. -+ */ -+ writel(addr, &vc4_state->hw_dlist[vc4_state->pw0_offset]); -+ -+ /* Also update the CPU-side dlist copy, so that any later -+ * atomic updates that don't do a new modeset on our plane -+ * also use our updated address. -+ */ -+ vc4_state->dlist[vc4_state->pw0_offset] = addr; -+} -+ - static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { - .prepare_fb = NULL, - .cleanup_fb = NULL, -diff --git a/drivers/gpu/drm/vc4/vc4_qpu_defines.h b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -new file mode 100644 -index 0000000..e47c994 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -@@ -0,0 +1,268 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef VC4_QPU_DEFINES_H -+#define VC4_QPU_DEFINES_H -+ -+enum qpu_op_add { -+ QPU_A_NOP, -+ QPU_A_FADD, -+ QPU_A_FSUB, -+ QPU_A_FMIN, -+ QPU_A_FMAX, -+ QPU_A_FMINABS, -+ QPU_A_FMAXABS, -+ QPU_A_FTOI, -+ QPU_A_ITOF, -+ QPU_A_ADD = 12, -+ QPU_A_SUB, -+ QPU_A_SHR, -+ QPU_A_ASR, -+ QPU_A_ROR, -+ QPU_A_SHL, -+ QPU_A_MIN, -+ QPU_A_MAX, -+ QPU_A_AND, -+ QPU_A_OR, -+ QPU_A_XOR, -+ QPU_A_NOT, -+ QPU_A_CLZ, -+ QPU_A_V8ADDS = 30, -+ QPU_A_V8SUBS = 31, -+}; -+ -+enum qpu_op_mul { -+ QPU_M_NOP, -+ QPU_M_FMUL, -+ QPU_M_MUL24, -+ QPU_M_V8MULD, -+ QPU_M_V8MIN, -+ QPU_M_V8MAX, -+ QPU_M_V8ADDS, -+ QPU_M_V8SUBS, -+}; -+ -+enum qpu_raddr { -+ QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_R_UNIF = 32, -+ QPU_R_VARY = 35, -+ QPU_R_ELEM_QPU = 38, -+ QPU_R_NOP, -+ QPU_R_XY_PIXEL_COORD = 41, -+ QPU_R_MS_REV_FLAGS = 41, -+ QPU_R_VPM = 48, -+ QPU_R_VPM_LD_BUSY, -+ QPU_R_VPM_LD_WAIT, -+ QPU_R_MUTEX_ACQUIRE, -+}; -+ -+enum qpu_waddr { -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_W_ACC0 = 32, /* aka r0 */ -+ QPU_W_ACC1, -+ QPU_W_ACC2, -+ QPU_W_ACC3, -+ QPU_W_TMU_NOSWAP, -+ QPU_W_ACC5, -+ QPU_W_HOST_INT, -+ QPU_W_NOP, -+ QPU_W_UNIFORMS_ADDRESS, -+ QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -+ QPU_W_MS_FLAGS = 42, -+ QPU_W_REV_FLAG = 42, -+ QPU_W_TLB_STENCIL_SETUP = 43, -+ QPU_W_TLB_Z, -+ QPU_W_TLB_COLOR_MS, -+ QPU_W_TLB_COLOR_ALL, -+ QPU_W_TLB_ALPHA_MASK, -+ QPU_W_VPM, -+ QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -+ QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -+ QPU_W_MUTEX_RELEASE, -+ QPU_W_SFU_RECIP, -+ QPU_W_SFU_RECIPSQRT, -+ QPU_W_SFU_EXP, -+ QPU_W_SFU_LOG, -+ QPU_W_TMU0_S, -+ QPU_W_TMU0_T, -+ QPU_W_TMU0_R, -+ QPU_W_TMU0_B, -+ QPU_W_TMU1_S, -+ QPU_W_TMU1_T, -+ QPU_W_TMU1_R, -+ QPU_W_TMU1_B, -+}; -+ -+enum qpu_sig_bits { -+ QPU_SIG_SW_BREAKPOINT, -+ QPU_SIG_NONE, -+ QPU_SIG_THREAD_SWITCH, -+ QPU_SIG_PROG_END, -+ QPU_SIG_WAIT_FOR_SCOREBOARD, -+ QPU_SIG_SCOREBOARD_UNLOCK, -+ QPU_SIG_LAST_THREAD_SWITCH, -+ QPU_SIG_COVERAGE_LOAD, -+ QPU_SIG_COLOR_LOAD, -+ QPU_SIG_COLOR_LOAD_END, -+ QPU_SIG_LOAD_TMU0, -+ QPU_SIG_LOAD_TMU1, -+ QPU_SIG_ALPHA_MASK_LOAD, -+ QPU_SIG_SMALL_IMM, -+ QPU_SIG_LOAD_IMM, -+ QPU_SIG_BRANCH -+}; -+ -+enum qpu_mux { -+ /* hardware mux values */ -+ QPU_MUX_R0, -+ QPU_MUX_R1, -+ QPU_MUX_R2, -+ QPU_MUX_R3, -+ QPU_MUX_R4, -+ QPU_MUX_R5, -+ QPU_MUX_A, -+ QPU_MUX_B, -+ -+ /* non-hardware mux values */ -+ QPU_MUX_IMM, -+}; -+ -+enum qpu_cond { -+ QPU_COND_NEVER, -+ QPU_COND_ALWAYS, -+ QPU_COND_ZS, -+ QPU_COND_ZC, -+ QPU_COND_NS, -+ QPU_COND_NC, -+ QPU_COND_CS, -+ QPU_COND_CC, -+}; -+ -+enum qpu_pack_mul { -+ QPU_PACK_MUL_NOP, -+ QPU_PACK_MUL_8888 = 3, /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_MUL_8A, -+ QPU_PACK_MUL_8B, -+ QPU_PACK_MUL_8C, -+ QPU_PACK_MUL_8D, -+}; -+ -+enum qpu_pack_a { -+ QPU_PACK_A_NOP, -+ /* convert to 16 bit float if float input, or to int16. */ -+ QPU_PACK_A_16A, -+ QPU_PACK_A_16B, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_A_8888, -+ /* Convert to 8-bit unsigned int. */ -+ QPU_PACK_A_8A, -+ QPU_PACK_A_8B, -+ QPU_PACK_A_8C, -+ QPU_PACK_A_8D, -+ -+ /* Saturating variants of the previous instructions. */ -+ QPU_PACK_A_32_SAT, /* int-only */ -+ QPU_PACK_A_16A_SAT, /* int or float */ -+ QPU_PACK_A_16B_SAT, -+ QPU_PACK_A_8888_SAT, -+ QPU_PACK_A_8A_SAT, -+ QPU_PACK_A_8B_SAT, -+ QPU_PACK_A_8C_SAT, -+ QPU_PACK_A_8D_SAT, -+}; -+ -+enum qpu_unpack_r4 { -+ QPU_UNPACK_R4_NOP, -+ QPU_UNPACK_R4_F16A_TO_F32, -+ QPU_UNPACK_R4_F16B_TO_F32, -+ QPU_UNPACK_R4_8D_REP, -+ QPU_UNPACK_R4_8A, -+ QPU_UNPACK_R4_8B, -+ QPU_UNPACK_R4_8C, -+ QPU_UNPACK_R4_8D, -+}; -+ -+#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low)) -+/* Using the GNU statement expression extension */ -+#define QPU_SET_FIELD(value, field) \ -+ ({ \ -+ uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \ -+ assert((fieldval & ~ field ## _MASK) == 0); \ -+ fieldval & field ## _MASK; \ -+ }) -+ -+#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) -+ -+#define QPU_SIG_SHIFT 60 -+#define QPU_SIG_MASK QPU_MASK(63, 60) -+ -+#define QPU_UNPACK_SHIFT 57 -+#define QPU_UNPACK_MASK QPU_MASK(59, 57) -+ -+/** -+ * If set, the pack field means PACK_MUL or R4 packing, instead of normal -+ * regfile a packing. -+ */ -+#define QPU_PM ((uint64_t)1 << 56) -+ -+#define QPU_PACK_SHIFT 52 -+#define QPU_PACK_MASK QPU_MASK(55, 52) -+ -+#define QPU_COND_ADD_SHIFT 49 -+#define QPU_COND_ADD_MASK QPU_MASK(51, 49) -+#define QPU_COND_MUL_SHIFT 46 -+#define QPU_COND_MUL_MASK QPU_MASK(48, 46) -+ -+#define QPU_SF ((uint64_t)1 << 45) -+ -+#define QPU_WADDR_ADD_SHIFT 38 -+#define QPU_WADDR_ADD_MASK QPU_MASK(43, 38) -+#define QPU_WADDR_MUL_SHIFT 32 -+#define QPU_WADDR_MUL_MASK QPU_MASK(37, 32) -+ -+#define QPU_OP_MUL_SHIFT 29 -+#define QPU_OP_MUL_MASK QPU_MASK(31, 29) -+ -+#define QPU_RADDR_A_SHIFT 18 -+#define QPU_RADDR_A_MASK QPU_MASK(23, 18) -+#define QPU_RADDR_B_SHIFT 12 -+#define QPU_RADDR_B_MASK QPU_MASK(17, 12) -+#define QPU_SMALL_IMM_SHIFT 12 -+#define QPU_SMALL_IMM_MASK QPU_MASK(17, 12) -+ -+#define QPU_ADD_A_SHIFT 9 -+#define QPU_ADD_A_MASK QPU_MASK(11, 9) -+#define QPU_ADD_B_SHIFT 6 -+#define QPU_ADD_B_MASK QPU_MASK(8, 6) -+#define QPU_MUL_A_SHIFT 3 -+#define QPU_MUL_A_MASK QPU_MASK(5, 3) -+#define QPU_MUL_B_SHIFT 0 -+#define QPU_MUL_B_MASK QPU_MASK(2, 0) -+ -+#define QPU_WS ((uint64_t)1 << 44) -+ -+#define QPU_OP_ADD_SHIFT 24 -+#define QPU_OP_ADD_MASK QPU_MASK(28, 24) -+ -+#endif /* VC4_QPU_DEFINES_H */ -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -new file mode 100644 -index 0000000..0ffac8d ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -0,0 +1,448 @@ -+/* -+ * Copyright © 2014-2015 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * DOC: Render command list generation -+ * -+ * In the VC4 driver, render command list generation is performed by the -+ * kernel instead of userspace. We do this because validating a -+ * user-submitted command list is hard to get right and has high CPU overhead, -+ * while the number of valid configurations for render command lists is -+ * actually fairly low. -+ */ -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_packet.h" -+ -+struct vc4_rcl_setup { -+ struct drm_gem_cma_object *color_read; -+ struct drm_gem_cma_object *color_ms_write; -+ struct drm_gem_cma_object *zs_read; -+ struct drm_gem_cma_object *zs_write; -+ -+ struct drm_gem_cma_object *rcl; -+ u32 next_offset; -+}; -+ -+static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) -+{ -+ *(u8 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 1; -+} -+ -+static inline void rcl_u16(struct vc4_rcl_setup *setup, u16 val) -+{ -+ *(u16 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 2; -+} -+ -+static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val) -+{ -+ *(u32 *)(setup->rcl->vaddr + setup->next_offset) = val; -+ setup->next_offset += 4; -+} -+ -+ -+/* -+ * Emits a no-op STORE_TILE_BUFFER_GENERAL. -+ * -+ * If we emit a PACKET_TILE_COORDINATES, it must be followed by a store of -+ * some sort before another load is triggered. -+ */ -+static void vc4_store_before_load(struct vc4_rcl_setup *setup) -+{ -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, -+ VC4_SET_FIELD(VC4_LOADSTORE_TILE_BUFFER_NONE, -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER) | -+ VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR | -+ VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR | -+ VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR); -+ rcl_u32(setup, 0); /* no address, since we're in None mode */ -+} -+ -+/* -+ * Emits a PACKET_TILE_COORDINATES if one isn't already pending. -+ * -+ * The tile coordinates packet triggers a pending load if there is one, are -+ * used for clipping during rendering, and determine where loads/stores happen -+ * relative to their base address. -+ */ -+static void vc4_tile_coordinates(struct vc4_rcl_setup *setup, -+ uint32_t x, uint32_t y) -+{ -+ rcl_u8(setup, VC4_PACKET_TILE_COORDINATES); -+ rcl_u8(setup, x); -+ rcl_u8(setup, y); -+} -+ -+static void emit_tile(struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup, -+ uint8_t x, uint8_t y, bool first, bool last) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ -+ /* Note that the load doesn't actually occur until the -+ * tile coords packet is processed, and only one load -+ * may be outstanding at a time. -+ */ -+ if (setup->color_read) { -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->color_read.bits); -+ rcl_u32(setup, -+ setup->color_read->paddr + args->color_read.offset); -+ } -+ -+ if (setup->zs_read) { -+ if (setup->color_read) { -+ /* Exec previous load. */ -+ vc4_tile_coordinates(setup, x, y); -+ vc4_store_before_load(setup); -+ } -+ -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_read.bits); -+ rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset); -+ } -+ -+ /* Clipping depends on tile coordinates having been -+ * emitted, so we always need one here. -+ */ -+ vc4_tile_coordinates(setup, x, y); -+ -+ /* Wait for the binner before jumping to the first -+ * tile's lists. -+ */ -+ if (first && has_bin) -+ rcl_u8(setup, VC4_PACKET_WAIT_ON_SEMAPHORE); -+ -+ if (has_bin) { -+ rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST); -+ rcl_u32(setup, (exec->tile_bo->paddr + -+ exec->tile_alloc_offset + -+ (y * exec->bin_tiles_x + x) * 32)); -+ } -+ -+ if (setup->zs_write) { -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_write.bits | -+ (setup->color_ms_write ? -+ VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0)); -+ rcl_u32(setup, -+ (setup->zs_write->paddr + args->zs_write.offset) | -+ ((last && !setup->color_ms_write) ? -+ VC4_LOADSTORE_TILE_BUFFER_EOF : 0)); -+ } -+ -+ if (setup->color_ms_write) { -+ if (setup->zs_write) { -+ /* Reset after previous store */ -+ vc4_tile_coordinates(setup, x, y); -+ } -+ -+ if (last) -+ rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF); -+ else -+ rcl_u8(setup, VC4_PACKET_STORE_MS_TILE_BUFFER); -+ } -+} -+ -+static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ uint8_t min_x_tile = args->min_x_tile; -+ uint8_t min_y_tile = args->min_y_tile; -+ uint8_t max_x_tile = args->max_x_tile; -+ uint8_t max_y_tile = args->max_y_tile; -+ uint8_t xtiles = max_x_tile - min_x_tile + 1; -+ uint8_t ytiles = max_y_tile - min_y_tile + 1; -+ uint8_t x, y; -+ uint32_t size, loop_body_size; -+ -+ size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE; -+ loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE; -+ -+ if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) { -+ size += VC4_PACKET_CLEAR_COLORS_SIZE + -+ VC4_PACKET_TILE_COORDINATES_SIZE + -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ -+ if (setup->color_read) { -+ loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE); -+ } -+ if (setup->zs_read) { -+ if (setup->color_read) { -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; -+ } -+ -+ if (has_bin) { -+ size += VC4_PACKET_WAIT_ON_SEMAPHORE_SIZE; -+ loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE; -+ } -+ -+ if (setup->zs_write) -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ if (setup->color_ms_write) { -+ if (setup->zs_write) -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE; -+ } -+ size += xtiles * ytiles * loop_body_size; -+ -+ setup->rcl = &vc4_bo_create(dev, size)->base; -+ if (!setup->rcl) -+ return -ENOMEM; -+ list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, -+ &exec->unref_list); -+ -+ rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -+ rcl_u32(setup, -+ (setup->color_ms_write ? -+ (setup->color_ms_write->paddr + -+ args->color_ms_write.offset) : -+ 0)); -+ rcl_u16(setup, args->width); -+ rcl_u16(setup, args->height); -+ rcl_u16(setup, args->color_ms_write.bits); -+ -+ /* The tile buffer gets cleared when the previous tile is stored. If -+ * the clear values changed between frames, then the tile buffer has -+ * stale clear values in it, so we have to do a store in None mode (no -+ * writes) so that we trigger the tile buffer clear. -+ */ -+ if (args->flags & VC4_SUBMIT_CL_USE_CLEAR_COLOR) { -+ rcl_u8(setup, VC4_PACKET_CLEAR_COLORS); -+ rcl_u32(setup, args->clear_color[0]); -+ rcl_u32(setup, args->clear_color[1]); -+ rcl_u32(setup, args->clear_z); -+ rcl_u8(setup, args->clear_s); -+ -+ vc4_tile_coordinates(setup, 0, 0); -+ -+ rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, VC4_LOADSTORE_TILE_BUFFER_NONE); -+ rcl_u32(setup, 0); /* no address, since we're in None mode */ -+ } -+ -+ for (y = min_y_tile; y <= max_y_tile; y++) { -+ for (x = min_x_tile; x <= max_x_tile; x++) { -+ bool first = (x == min_x_tile && y == min_y_tile); -+ bool last = (x == max_x_tile && y == max_y_tile); -+ emit_tile(exec, setup, x, y, first, last); -+ } -+ } -+ -+ BUG_ON(setup->next_offset != size); -+ exec->ct1ca = setup->rcl->paddr; -+ exec->ct1ea = setup->rcl->paddr + setup->next_offset; -+ -+ return 0; -+} -+ -+static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ uint8_t tiling = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_TILING); -+ uint8_t buffer = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER); -+ uint8_t format = VC4_GET_FIELD(surf->bits, -+ VC4_LOADSTORE_TILE_BUFFER_FORMAT); -+ int cpp; -+ -+ if (surf->pad != 0) { -+ DRM_ERROR("Padding unset\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ return -EINVAL; -+ -+ if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK | -+ VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK | -+ VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) { -+ DRM_ERROR("Unknown bits in load/store: 0x%04x\n", -+ surf->bits); -+ return -EINVAL; -+ } -+ -+ if (tiling > VC4_TILING_FORMAT_LT) { -+ DRM_ERROR("Bad tiling format\n"); -+ return -EINVAL; -+ } -+ -+ if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) { -+ if (format != 0) { -+ DRM_ERROR("No color format should be set for ZS\n"); -+ return -EINVAL; -+ } -+ cpp = 4; -+ } else if (buffer == VC4_LOADSTORE_TILE_BUFFER_COLOR) { -+ switch (format) { -+ case VC4_LOADSTORE_TILE_BUFFER_BGR565: -+ case VC4_LOADSTORE_TILE_BUFFER_BGR565_DITHER: -+ cpp = 2; -+ break; -+ case VC4_LOADSTORE_TILE_BUFFER_RGBA8888: -+ cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Bad tile buffer format\n"); -+ return -EINVAL; -+ } -+ } else { -+ DRM_ERROR("Bad load/store buffer %d.\n", buffer); -+ return -EINVAL; -+ } -+ -+ if (surf->offset & 0xf) { -+ DRM_ERROR("load/store buffer must be 16b aligned.\n"); -+ return -EINVAL; -+ } -+ -+ if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling, -+ exec->args->width, exec->args->height, cpp)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ uint8_t tiling = VC4_GET_FIELD(surf->bits, -+ VC4_RENDER_CONFIG_MEMORY_FORMAT); -+ uint8_t format = VC4_GET_FIELD(surf->bits, -+ VC4_RENDER_CONFIG_FORMAT); -+ int cpp; -+ -+ if (surf->pad != 0) { -+ DRM_ERROR("Padding unset\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK | -+ VC4_RENDER_CONFIG_FORMAT_MASK)) { -+ DRM_ERROR("Unknown bits in render config: 0x%04x\n", -+ surf->bits); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ return -EINVAL; -+ -+ if (tiling > VC4_TILING_FORMAT_LT) { -+ DRM_ERROR("Bad tiling format\n"); -+ return -EINVAL; -+ } -+ -+ switch (format) { -+ case VC4_RENDER_CONFIG_FORMAT_BGR565_DITHERED: -+ case VC4_RENDER_CONFIG_FORMAT_BGR565: -+ cpp = 2; -+ break; -+ case VC4_RENDER_CONFIG_FORMAT_RGBA8888: -+ cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Bad tile buffer format\n"); -+ return -EINVAL; -+ } -+ -+ if (!vc4_check_tex_size(exec, *obj, surf->offset, tiling, -+ exec->args->width, exec->args->height, cpp)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) -+{ -+ struct vc4_rcl_setup setup = {0}; -+ struct drm_vc4_submit_cl *args = exec->args; -+ bool has_bin = args->bin_cl_size != 0; -+ int ret; -+ -+ if (args->min_x_tile > args->max_x_tile || -+ args->min_y_tile > args->max_y_tile) { -+ DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n", -+ args->min_x_tile, args->min_y_tile, -+ args->max_x_tile, args->max_y_tile); -+ return -EINVAL; -+ } -+ -+ if (has_bin && -+ (args->max_x_tile > exec->bin_tiles_x || -+ args->max_y_tile > exec->bin_tiles_y)) { -+ DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n", -+ args->max_x_tile, args->max_y_tile, -+ exec->bin_tiles_x, exec->bin_tiles_y); -+ return -EINVAL; -+ } -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write, -+ &args->color_ms_write); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); -+ if (ret) -+ return ret; -+ -+ /* We shouldn't even have the job submitted to us if there's no -+ * surface to write out. -+ */ -+ if (!setup.color_ms_write && !setup.zs_write) { -+ DRM_ERROR("RCL requires color or Z/S write\n"); -+ return -EINVAL; -+ } -+ -+ return vc4_create_rcl_bo(dev, exec, &setup); -+} -diff --git a/drivers/gpu/drm/vc4/vc4_trace.h b/drivers/gpu/drm/vc4/vc4_trace.h -new file mode 100644 -index 0000000..ad7b1ea ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_trace.h -@@ -0,0 +1,63 @@ -+/* -+ * Copyright (C) 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. -+ */ -+ -+#if !defined(_VC4_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -+#define _VC4_TRACE_H_ -+ -+#include -+#include -+#include -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM vc4 -+#define TRACE_INCLUDE_FILE vc4_trace -+ -+TRACE_EVENT(vc4_wait_for_seqno_begin, -+ TP_PROTO(struct drm_device *dev, uint64_t seqno, uint64_t timeout), -+ TP_ARGS(dev, seqno, timeout), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ __field(u64, timeout) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ __entry->timeout = timeout; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu, timeout=%llu", -+ __entry->dev, __entry->seqno, __entry->timeout) -+); -+ -+TRACE_EVENT(vc4_wait_for_seqno_end, -+ TP_PROTO(struct drm_device *dev, uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, __entry->seqno) -+); -+ -+#endif /* _VC4_TRACE_H_ */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#include -diff --git a/drivers/gpu/drm/vc4/vc4_trace_points.c b/drivers/gpu/drm/vc4/vc4_trace_points.c -new file mode 100644 -index 0000000..e6278f2 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_trace_points.c -@@ -0,0 +1,14 @@ -+/* -+ * Copyright (C) 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 "vc4_drv.h" -+ -+#ifndef __CHECKER__ -+#define CREATE_TRACE_POINTS -+#include "vc4_trace.h" -+#endif -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -new file mode 100644 -index 0000000..b9cb7cf ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -0,0 +1,268 @@ -+/* -+ * Copyright (c) 2014 The Linux Foundation. All rights reserved. -+ * Copyright (C) 2013 Red Hat -+ * Author: Rob Clark -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include "linux/component.h" -+#include "soc/bcm2835/raspberrypi-firmware.h" -+#include "vc4_drv.h" -+#include "vc4_regs.h" -+ -+#ifdef CONFIG_DEBUG_FS -+#define REGDEF(reg) { reg, #reg } -+static const struct { -+ uint32_t reg; -+ const char *name; -+} vc4_reg_defs[] = { -+ REGDEF(V3D_IDENT0), -+ REGDEF(V3D_IDENT1), -+ REGDEF(V3D_IDENT2), -+ REGDEF(V3D_SCRATCH), -+ REGDEF(V3D_L2CACTL), -+ REGDEF(V3D_SLCACTL), -+ REGDEF(V3D_INTCTL), -+ REGDEF(V3D_INTENA), -+ REGDEF(V3D_INTDIS), -+ REGDEF(V3D_CT0CS), -+ REGDEF(V3D_CT1CS), -+ REGDEF(V3D_CT0EA), -+ REGDEF(V3D_CT1EA), -+ REGDEF(V3D_CT0CA), -+ REGDEF(V3D_CT1CA), -+ REGDEF(V3D_CT00RA0), -+ REGDEF(V3D_CT01RA0), -+ REGDEF(V3D_CT0LC), -+ REGDEF(V3D_CT1LC), -+ REGDEF(V3D_CT0PC), -+ REGDEF(V3D_CT1PC), -+ REGDEF(V3D_PCS), -+ REGDEF(V3D_BFC), -+ REGDEF(V3D_RFC), -+ REGDEF(V3D_BPCA), -+ REGDEF(V3D_BPCS), -+ REGDEF(V3D_BPOA), -+ REGDEF(V3D_BPOS), -+ REGDEF(V3D_BXCF), -+ REGDEF(V3D_SQRSV0), -+ REGDEF(V3D_SQRSV1), -+ REGDEF(V3D_SQCNTL), -+ REGDEF(V3D_SRQPC), -+ REGDEF(V3D_SRQUA), -+ REGDEF(V3D_SRQUL), -+ REGDEF(V3D_SRQCS), -+ REGDEF(V3D_VPACNTL), -+ REGDEF(V3D_VPMBASE), -+ REGDEF(V3D_PCTRC), -+ REGDEF(V3D_PCTRE), -+ REGDEF(V3D_PCTR0), -+ REGDEF(V3D_PCTRS0), -+ REGDEF(V3D_PCTR1), -+ REGDEF(V3D_PCTRS1), -+ REGDEF(V3D_PCTR2), -+ REGDEF(V3D_PCTRS2), -+ REGDEF(V3D_PCTR3), -+ REGDEF(V3D_PCTRS3), -+ REGDEF(V3D_PCTR4), -+ REGDEF(V3D_PCTRS4), -+ REGDEF(V3D_PCTR5), -+ REGDEF(V3D_PCTRS5), -+ REGDEF(V3D_PCTR6), -+ REGDEF(V3D_PCTRS6), -+ REGDEF(V3D_PCTR7), -+ REGDEF(V3D_PCTRS7), -+ REGDEF(V3D_PCTR8), -+ REGDEF(V3D_PCTRS8), -+ REGDEF(V3D_PCTR9), -+ REGDEF(V3D_PCTRS9), -+ REGDEF(V3D_PCTR10), -+ REGDEF(V3D_PCTRS10), -+ REGDEF(V3D_PCTR11), -+ REGDEF(V3D_PCTRS11), -+ REGDEF(V3D_PCTR12), -+ REGDEF(V3D_PCTRS12), -+ REGDEF(V3D_PCTR13), -+ REGDEF(V3D_PCTRS13), -+ REGDEF(V3D_PCTR14), -+ REGDEF(V3D_PCTRS14), -+ REGDEF(V3D_PCTR15), -+ REGDEF(V3D_PCTRS15), -+ REGDEF(V3D_BGE), -+ REGDEF(V3D_FDBGO), -+ REGDEF(V3D_FDBGB), -+ REGDEF(V3D_FDBGR), -+ REGDEF(V3D_FDBGS), -+ REGDEF(V3D_ERRSTAT), -+}; -+ -+int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(vc4_reg_defs); i++) { -+ seq_printf(m, "%s (0x%04x): 0x%08x\n", -+ vc4_reg_defs[i].name, vc4_reg_defs[i].reg, -+ V3D_READ(vc4_reg_defs[i].reg)); -+ } -+ -+ return 0; -+} -+ -+int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ uint32_t ident1 = V3D_READ(V3D_IDENT1); -+ uint32_t nslc = VC4_GET_FIELD(ident1, V3D_IDENT1_NSLC); -+ uint32_t tups = VC4_GET_FIELD(ident1, V3D_IDENT1_TUPS); -+ uint32_t qups = VC4_GET_FIELD(ident1, V3D_IDENT1_QUPS); -+ -+ seq_printf(m, "Revision: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); -+ seq_printf(m, "Slices: %d\n", nslc); -+ seq_printf(m, "TMUs: %d\n", nslc * tups); -+ seq_printf(m, "QPUs: %d\n", nslc * qups); -+ seq_printf(m, "Semaphores: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); -+ -+ return 0; -+} -+#endif /* CONFIG_DEBUG_FS */ -+ -+/* -+ * Asks the firmware to turn on power to the V3D engine. -+ * -+ * This may be doable with just the clocks interface, though this -+ * packet does some other register setup from the firmware, too. -+ */ -+int -+vc4_v3d_set_power(struct vc4_dev *vc4, bool on) -+{ -+ u32 packet = on; -+ -+ return rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_SET_ENABLE_QPU, -+ &packet, sizeof(packet)); -+} -+ -+static void vc4_v3d_init_hw(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ /* Take all the memory that would have been reserved for user -+ * QPU programs, since we don't have an interface for running -+ * them, anyway. -+ */ -+ V3D_WRITE(V3D_VPMBASE, 0); -+} -+ -+static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct drm_device *drm = dev_get_drvdata(master); -+ struct vc4_dev *vc4 = to_vc4_dev(drm); -+ struct vc4_v3d *v3d = NULL; -+ int ret; -+ -+ v3d = devm_kzalloc(&pdev->dev, sizeof(*v3d), GFP_KERNEL); -+ if (!v3d) -+ return -ENOMEM; -+ -+ v3d->pdev = pdev; -+ -+ v3d->regs = vc4_ioremap_regs(pdev, 0); -+ if (IS_ERR(v3d->regs)) -+ return PTR_ERR(v3d->regs); -+ -+ vc4->v3d = v3d; -+ -+ ret = vc4_v3d_set_power(vc4, true); -+ if (ret) -+ return ret; -+ -+ if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) { -+ DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n", -+ V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0); -+ return -EINVAL; -+ } -+ -+ /* Reset the binner overflow address/size at setup, to be sure -+ * we don't reuse an old one. -+ */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ vc4_v3d_init_hw(drm); -+ -+ ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); -+ if (ret) { -+ DRM_ERROR("Failed to install IRQ handler\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void vc4_v3d_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct drm_device *drm = dev_get_drvdata(master); -+ struct vc4_dev *vc4 = to_vc4_dev(drm); -+ -+ drm_irq_uninstall(drm); -+ -+ /* Disable the binner's overflow memory address, so the next -+ * driver probe (if any) doesn't try to reuse our old -+ * allocation. -+ */ -+ V3D_WRITE(V3D_BPOA, 0); -+ V3D_WRITE(V3D_BPOS, 0); -+ -+ vc4_v3d_set_power(vc4, false); -+ -+ vc4->v3d = NULL; -+} -+ -+static const struct component_ops vc4_v3d_ops = { -+ .bind = vc4_v3d_bind, -+ .unbind = vc4_v3d_unbind, -+}; -+ -+static int vc4_v3d_dev_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &vc4_v3d_ops); -+} -+ -+static int vc4_v3d_dev_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &vc4_v3d_ops); -+ return 0; -+} -+ -+static const struct of_device_id vc4_v3d_dt_match[] = { -+ { .compatible = "brcm,vc4-v3d" }, -+ {} -+}; -+ -+struct platform_driver vc4_v3d_driver = { -+ .probe = vc4_v3d_dev_probe, -+ .remove = vc4_v3d_dev_remove, -+ .driver = { -+ .name = "vc4_v3d", -+ .of_match_table = vc4_v3d_dt_match, -+ }, -+}; -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -new file mode 100644 -index 0000000..ff3b62f ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -0,0 +1,958 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * Command list validator for VC4. -+ * -+ * The VC4 has no IOMMU between it and system memory. So, a user with -+ * access to execute command lists could escalate privilege by -+ * overwriting system memory (drawing to it as a framebuffer) or -+ * reading system memory it shouldn't (reading it as a texture, or -+ * uniform data, or vertex data). -+ * -+ * This validates command lists to ensure that all accesses are within -+ * the bounds of the GEM objects referenced. It explicitly whitelists -+ * packets, and looks at the offsets in any address fields to make -+ * sure they're constrained within the BOs they reference. -+ * -+ * Note that because of the validation that's happening anyway, this -+ * is where GEM relocation processing happens. -+ */ -+ -+#include "uapi/drm/vc4_drm.h" -+#include "vc4_drv.h" -+#include "vc4_packet.h" -+ -+#define VALIDATE_ARGS \ -+ struct vc4_exec_info *exec, \ -+ void *validated, \ -+ void *untrusted -+ -+ -+/** Return the width in pixels of a 64-byte microtile. */ -+static uint32_t -+utile_width(int cpp) -+{ -+ switch (cpp) { -+ case 1: -+ case 2: -+ return 8; -+ case 4: -+ return 4; -+ case 8: -+ return 2; -+ default: -+ DRM_ERROR("unknown cpp: %d\n", cpp); -+ return 1; -+ } -+} -+ -+/** Return the height in pixels of a 64-byte microtile. */ -+static uint32_t -+utile_height(int cpp) -+{ -+ switch (cpp) { -+ case 1: -+ return 8; -+ case 2: -+ case 4: -+ case 8: -+ return 4; -+ default: -+ DRM_ERROR("unknown cpp: %d\n", cpp); -+ return 1; -+ } -+} -+ -+/** -+ * The texture unit decides what tiling format a particular miplevel is using -+ * this function, so we lay out our miptrees accordingly. -+ */ -+static bool -+size_is_lt(uint32_t width, uint32_t height, int cpp) -+{ -+ return (width <= 4 * utile_width(cpp) || -+ height <= 4 * utile_height(cpp)); -+} -+ -+bool -+vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj) -+{ -+ *obj = NULL; -+ -+ if (hindex >= exec->bo_count) { -+ DRM_ERROR("BO index %d greater than BO count %d\n", -+ hindex, exec->bo_count); -+ return false; -+ } -+ -+ if (exec->bo[hindex].mode != mode) { -+ if (exec->bo[hindex].mode == VC4_MODE_UNDECIDED) { -+ exec->bo[hindex].mode = mode; -+ } else { -+ DRM_ERROR("BO index %d reused with mode %d vs %d\n", -+ hindex, exec->bo[hindex].mode, mode); -+ return false; -+ } -+ } -+ -+ *obj = exec->bo[hindex].bo; -+ return true; -+} -+ -+static bool -+vc4_use_handle(struct vc4_exec_info *exec, -+ uint32_t gem_handles_packet_index, -+ enum vc4_bo_mode mode, -+ struct drm_gem_cma_object **obj) -+{ -+ return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index], -+ mode, obj); -+} -+ -+static uint32_t -+gl_shader_rec_size(uint32_t pointer_bits) -+{ -+ uint32_t attribute_count = pointer_bits & 7; -+ bool extended = pointer_bits & 8; -+ -+ if (attribute_count == 0) -+ attribute_count = 8; -+ -+ if (extended) -+ return 100 + attribute_count * 4; -+ else -+ return 36 + attribute_count * 8; -+} -+ -+bool -+vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, -+ uint32_t offset, uint8_t tiling_format, -+ uint32_t width, uint32_t height, uint8_t cpp) -+{ -+ uint32_t aligned_width, aligned_height, stride, size; -+ uint32_t utile_w = utile_width(cpp); -+ uint32_t utile_h = utile_height(cpp); -+ -+ /* The shaded vertex format stores signed 12.4 fixed point -+ * (-2048,2047) offsets from the viewport center, so we should -+ * never have a render target larger than 4096. The texture -+ * unit can only sample from 2048x2048, so it's even more -+ * restricted. This lets us avoid worrying about overflow in -+ * our math. -+ */ -+ if (width > 4096 || height > 4096) { -+ DRM_ERROR("Surface dimesions (%d,%d) too large", width, height); -+ return false; -+ } -+ -+ switch (tiling_format) { -+ case VC4_TILING_FORMAT_LINEAR: -+ aligned_width = round_up(width, utile_w); -+ aligned_height = height; -+ break; -+ case VC4_TILING_FORMAT_T: -+ aligned_width = round_up(width, utile_w * 8); -+ aligned_height = round_up(height, utile_h * 8); -+ break; -+ case VC4_TILING_FORMAT_LT: -+ aligned_width = round_up(width, utile_w); -+ aligned_height = round_up(height, utile_h); -+ break; -+ default: -+ DRM_ERROR("buffer tiling %d unsupported\n", tiling_format); -+ return false; -+ } -+ -+ stride = aligned_width * cpp; -+ size = stride * aligned_height; -+ -+ if (size + offset < size || -+ size + offset > fbo->base.size) { -+ DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %d)\n", -+ width, height, -+ aligned_width, aligned_height, -+ size, offset, fbo->base.size); -+ return false; -+ } -+ -+ return true; -+} -+ -+static int -+validate_flush_all(VALIDATE_ARGS) -+{ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("VC4_PACKET_FLUSH_ALL after " -+ "VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+validate_start_tile_binning(VALIDATE_ARGS) -+{ -+ if (exec->found_start_tile_binning_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n"); -+ return -EINVAL; -+ } -+ exec->found_start_tile_binning_packet = true; -+ -+ if (!exec->found_tile_binning_mode_config_packet) { -+ DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+validate_increment_semaphore(VALIDATE_ARGS) -+{ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ exec->found_increment_semaphore_packet = true; -+ -+ /* Once we've found the semaphore increment, there should be one FLUSH -+ * then the end of the command list. The FLUSH actually triggers the -+ * increment, so we only need to make sure there -+ */ -+ -+ return 0; -+} -+ -+static int -+validate_indexed_prim_list(VALIDATE_ARGS) -+{ -+ struct drm_gem_cma_object *ib; -+ uint32_t length = *(uint32_t *)(untrusted + 1); -+ uint32_t offset = *(uint32_t *)(untrusted + 5); -+ uint32_t max_index = *(uint32_t *)(untrusted + 9); -+ uint32_t index_size = (*(uint8_t *)(untrusted + 0) >> 4) ? 2 : 1; -+ struct vc4_shader_state *shader_state; -+ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ /* Check overflow condition */ -+ if (exec->shader_state_count == 0) { -+ DRM_ERROR("shader state must precede primitives\n"); -+ return -EINVAL; -+ } -+ shader_state = &exec->shader_state[exec->shader_state_count - 1]; -+ -+ if (max_index > shader_state->max_index) -+ shader_state->max_index = max_index; -+ -+ if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &ib)) -+ return -EINVAL; -+ -+ if (offset > ib->base.size || -+ (ib->base.size - offset) / index_size < length) { -+ DRM_ERROR("IB access overflow (%d + %d*%d > %d)\n", -+ offset, length, index_size, ib->base.size); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)(validated + 5) = ib->paddr + offset; -+ -+ return 0; -+} -+ -+static int -+validate_gl_array_primitive(VALIDATE_ARGS) -+{ -+ uint32_t length = *(uint32_t *)(untrusted + 1); -+ uint32_t base_index = *(uint32_t *)(untrusted + 5); -+ uint32_t max_index; -+ struct vc4_shader_state *shader_state; -+ -+ if (exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ /* Check overflow condition */ -+ if (exec->shader_state_count == 0) { -+ DRM_ERROR("shader state must precede primitives\n"); -+ return -EINVAL; -+ } -+ shader_state = &exec->shader_state[exec->shader_state_count - 1]; -+ -+ if (length + base_index < length) { -+ DRM_ERROR("primitive vertex count overflow\n"); -+ return -EINVAL; -+ } -+ max_index = length + base_index - 1; -+ -+ if (max_index > shader_state->max_index) -+ shader_state->max_index = max_index; -+ -+ return 0; -+} -+ -+static int -+validate_gl_shader_state(VALIDATE_ARGS) -+{ -+ uint32_t i = exec->shader_state_count++; -+ -+ if (i >= exec->shader_state_size) { -+ DRM_ERROR("More requests for shader states than declared\n"); -+ return -EINVAL; -+ } -+ -+ exec->shader_state[i].packet = VC4_PACKET_GL_SHADER_STATE; -+ exec->shader_state[i].addr = *(uint32_t *)untrusted; -+ exec->shader_state[i].max_index = 0; -+ -+ if (exec->shader_state[i].addr & ~0xf) { -+ DRM_ERROR("high bits set in GL shader rec reference\n"); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)validated = (exec->shader_rec_p + -+ exec->shader_state[i].addr); -+ -+ exec->shader_rec_p += -+ roundup(gl_shader_rec_size(exec->shader_state[i].addr), 16); -+ -+ return 0; -+} -+ -+static int -+validate_nv_shader_state(VALIDATE_ARGS) -+{ -+ uint32_t i = exec->shader_state_count++; -+ -+ if (i >= exec->shader_state_size) { -+ DRM_ERROR("More requests for shader states than declared\n"); -+ return -EINVAL; -+ } -+ -+ exec->shader_state[i].packet = VC4_PACKET_NV_SHADER_STATE; -+ exec->shader_state[i].addr = *(uint32_t *)untrusted; -+ -+ if (exec->shader_state[i].addr & 15) { -+ DRM_ERROR("NV shader state address 0x%08x misaligned\n", -+ exec->shader_state[i].addr); -+ return -EINVAL; -+ } -+ -+ *(uint32_t *)validated = (exec->shader_state[i].addr + -+ exec->shader_rec_p); -+ -+ return 0; -+} -+ -+static int -+validate_tile_binning_config(VALIDATE_ARGS) -+{ -+ struct drm_device *dev = exec->exec_bo->base.dev; -+ uint8_t flags; -+ uint32_t tile_state_size, tile_alloc_size; -+ uint32_t tile_count; -+ -+ if (exec->found_tile_binning_mode_config_packet) { -+ DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); -+ return -EINVAL; -+ } -+ exec->found_tile_binning_mode_config_packet = true; -+ -+ exec->bin_tiles_x = *(uint8_t *)(untrusted + 12); -+ exec->bin_tiles_y = *(uint8_t *)(untrusted + 13); -+ tile_count = exec->bin_tiles_x * exec->bin_tiles_y; -+ flags = *(uint8_t *)(untrusted + 14); -+ -+ if (exec->bin_tiles_x == 0 || -+ exec->bin_tiles_y == 0) { -+ DRM_ERROR("Tile binning config of %dx%d too small\n", -+ exec->bin_tiles_x, exec->bin_tiles_y); -+ return -EINVAL; -+ } -+ -+ if (flags & (VC4_BIN_CONFIG_DB_NON_MS | -+ VC4_BIN_CONFIG_TILE_BUFFER_64BIT | -+ VC4_BIN_CONFIG_MS_MODE_4X)) { -+ DRM_ERROR("unsupported bining config flags 0x%02x\n", flags); -+ return -EINVAL; -+ } -+ -+ /* The tile state data array is 48 bytes per tile, and we put it at -+ * the start of a BO containing both it and the tile alloc. -+ */ -+ tile_state_size = 48 * tile_count; -+ -+ /* Since the tile alloc array will follow us, align. */ -+ exec->tile_alloc_offset = roundup(tile_state_size, 4096); -+ -+ *(uint8_t *)(validated + 14) = -+ ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK | -+ VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK)) | -+ VC4_BIN_CONFIG_AUTO_INIT_TSDA | -+ VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32, -+ VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE) | -+ VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128, -+ VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE)); -+ -+ /* Initial block size. */ -+ tile_alloc_size = 32 * tile_count; -+ -+ /* -+ * The initial allocation gets rounded to the next 256 bytes before -+ * the hardware starts fulfilling further allocations. -+ */ -+ tile_alloc_size = roundup(tile_alloc_size, 256); -+ -+ /* Add space for the extra allocations. This is what gets used first, -+ * before overflow memory. It must have at least 4096 bytes, but we -+ * want to avoid overflow memory usage if possible. -+ */ -+ tile_alloc_size += 1024 * 1024; -+ -+ exec->tile_bo = &vc4_bo_create(dev, exec->tile_alloc_offset + -+ tile_alloc_size)->base; -+ if (!exec->tile_bo) -+ return -ENOMEM; -+ list_add_tail(&to_vc4_bo(&exec->tile_bo->base)->unref_head, -+ &exec->unref_list); -+ -+ /* tile alloc address. */ -+ *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + -+ exec->tile_alloc_offset); -+ /* tile alloc size. */ -+ *(uint32_t *)(validated + 4) = tile_alloc_size; -+ /* tile state address. */ -+ *(uint32_t *)(validated + 8) = exec->tile_bo->paddr; -+ -+ return 0; -+} -+ -+static int -+validate_gem_handles(VALIDATE_ARGS) -+{ -+ memcpy(exec->bo_index, untrusted, sizeof(exec->bo_index)); -+ return 0; -+} -+ -+#define VC4_DEFINE_PACKET(packet, name, func) \ -+ [packet] = { packet ## _SIZE, name, func } -+ -+static const struct cmd_info { -+ uint16_t len; -+ const char *name; -+ int (*func)(struct vc4_exec_info *exec, void *validated, -+ void *untrusted); -+} cmd_info[] = { -+ VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning), -+ VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive), -+ -+ /* This is only used by clipped primitives (packets 48 and 49), which -+ * we don't support parsing yet. -+ */ -+ VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state), -+ VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, "NV Shader State", validate_nv_shader_state), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL), -+ /* Note: The docs say this was also 105, but it was 106 in the -+ * initial userland code drop. -+ */ -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles), -+}; -+ -+int -+vc4_validate_bin_cl(struct drm_device *dev, -+ void *validated, -+ void *unvalidated, -+ struct vc4_exec_info *exec) -+{ -+ uint32_t len = exec->args->bin_cl_size; -+ uint32_t dst_offset = 0; -+ uint32_t src_offset = 0; -+ -+ while (src_offset < len) { -+ void *dst_pkt = validated + dst_offset; -+ void *src_pkt = unvalidated + src_offset; -+ u8 cmd = *(uint8_t *)src_pkt; -+ const struct cmd_info *info; -+ -+ if (cmd > ARRAY_SIZE(cmd_info)) { -+ DRM_ERROR("0x%08x: packet %d out of bounds\n", -+ src_offset, cmd); -+ return -EINVAL; -+ } -+ -+ info = &cmd_info[cmd]; -+ if (!info->name) { -+ DRM_ERROR("0x%08x: packet %d invalid\n", -+ src_offset, cmd); -+ return -EINVAL; -+ } -+ -+#if 0 -+ DRM_INFO("0x%08x: packet %d (%s) size %d processing...\n", -+ src_offset, cmd, info->name, info->len); -+#endif -+ -+ if (src_offset + info->len > len) { -+ DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x " -+ "exceeds bounds (0x%08x)\n", -+ src_offset, cmd, info->name, info->len, -+ src_offset + len); -+ return -EINVAL; -+ } -+ -+ if (cmd != VC4_PACKET_GEM_HANDLES) -+ memcpy(dst_pkt, src_pkt, info->len); -+ -+ if (info->func && info->func(exec, -+ dst_pkt + 1, -+ src_pkt + 1)) { -+ DRM_ERROR("0x%08x: packet %d (%s) failed to " -+ "validate\n", -+ src_offset, cmd, info->name); -+ return -EINVAL; -+ } -+ -+ src_offset += info->len; -+ /* GEM handle loading doesn't produce HW packets. */ -+ if (cmd != VC4_PACKET_GEM_HANDLES) -+ dst_offset += info->len; -+ -+ /* When the CL hits halt, it'll stop reading anything else. */ -+ if (cmd == VC4_PACKET_HALT) -+ break; -+ } -+ -+ exec->ct0ea = exec->ct0ca + dst_offset; -+ -+ if (!exec->found_start_tile_binning_packet) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n"); -+ return -EINVAL; -+ } -+ -+ if (!exec->found_increment_semaphore_packet) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static bool -+reloc_tex(struct vc4_exec_info *exec, -+ void *uniform_data_u, -+ struct vc4_texture_sample_info *sample, -+ uint32_t texture_handle_index) -+ -+{ -+ struct drm_gem_cma_object *tex; -+ uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); -+ uint32_t p1 = *(uint32_t *)(uniform_data_u + sample->p_offset[1]); -+ uint32_t p2 = (sample->p_offset[2] != ~0 ? -+ *(uint32_t *)(uniform_data_u + sample->p_offset[2]) : 0); -+ uint32_t p3 = (sample->p_offset[3] != ~0 ? -+ *(uint32_t *)(uniform_data_u + sample->p_offset[3]) : 0); -+ uint32_t *validated_p0 = exec->uniforms_v + sample->p_offset[0]; -+ uint32_t offset = p0 & VC4_TEX_P0_OFFSET_MASK; -+ uint32_t miplevels = VC4_GET_FIELD(p0, VC4_TEX_P0_MIPLVLS); -+ uint32_t width = VC4_GET_FIELD(p1, VC4_TEX_P1_WIDTH); -+ uint32_t height = VC4_GET_FIELD(p1, VC4_TEX_P1_HEIGHT); -+ uint32_t cpp, tiling_format, utile_w, utile_h; -+ uint32_t i; -+ uint32_t cube_map_stride = 0; -+ enum vc4_texture_data_type type; -+ -+ if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex)) -+ return false; -+ -+ if (sample->is_direct) { -+ uint32_t remaining_size = tex->base.size - p0; -+ if (p0 > tex->base.size - 4) { -+ DRM_ERROR("UBO offset greater than UBO size\n"); -+ goto fail; -+ } -+ if (p1 > remaining_size - 4) { -+ DRM_ERROR("UBO clamp would allow reads outside of UBO\n"); -+ goto fail; -+ } -+ *validated_p0 = tex->paddr + p0; -+ return true; -+ } -+ -+ if (width == 0) -+ width = 2048; -+ if (height == 0) -+ height = 2048; -+ -+ if (p0 & VC4_TEX_P0_CMMODE_MASK) { -+ if (VC4_GET_FIELD(p2, VC4_TEX_P2_PTYPE) == -+ VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) -+ cube_map_stride = p2 & VC4_TEX_P2_CMST_MASK; -+ if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) == -+ VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) { -+ if (cube_map_stride) { -+ DRM_ERROR("Cube map stride set twice\n"); -+ goto fail; -+ } -+ -+ cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK; -+ } -+ if (!cube_map_stride) { -+ DRM_ERROR("Cube map stride not set\n"); -+ goto fail; -+ } -+ } -+ -+ type = (VC4_GET_FIELD(p0, VC4_TEX_P0_TYPE) | -+ (VC4_GET_FIELD(p1, VC4_TEX_P1_TYPE4) << 4)); -+ -+ switch (type) { -+ case VC4_TEXTURE_TYPE_RGBA8888: -+ case VC4_TEXTURE_TYPE_RGBX8888: -+ case VC4_TEXTURE_TYPE_RGBA32R: -+ cpp = 4; -+ break; -+ case VC4_TEXTURE_TYPE_RGBA4444: -+ case VC4_TEXTURE_TYPE_RGBA5551: -+ case VC4_TEXTURE_TYPE_RGB565: -+ case VC4_TEXTURE_TYPE_LUMALPHA: -+ case VC4_TEXTURE_TYPE_S16F: -+ case VC4_TEXTURE_TYPE_S16: -+ cpp = 2; -+ break; -+ case VC4_TEXTURE_TYPE_LUMINANCE: -+ case VC4_TEXTURE_TYPE_ALPHA: -+ case VC4_TEXTURE_TYPE_S8: -+ cpp = 1; -+ break; -+ case VC4_TEXTURE_TYPE_ETC1: -+ case VC4_TEXTURE_TYPE_BW1: -+ case VC4_TEXTURE_TYPE_A4: -+ case VC4_TEXTURE_TYPE_A1: -+ case VC4_TEXTURE_TYPE_RGBA64: -+ case VC4_TEXTURE_TYPE_YUV422R: -+ default: -+ DRM_ERROR("Texture format %d unsupported\n", type); -+ goto fail; -+ } -+ utile_w = utile_width(cpp); -+ utile_h = utile_height(cpp); -+ -+ if (type == VC4_TEXTURE_TYPE_RGBA32R) { -+ tiling_format = VC4_TILING_FORMAT_LINEAR; -+ } else { -+ if (size_is_lt(width, height, cpp)) -+ tiling_format = VC4_TILING_FORMAT_LT; -+ else -+ tiling_format = VC4_TILING_FORMAT_T; -+ } -+ -+ if (!vc4_check_tex_size(exec, tex, offset + cube_map_stride * 5, -+ tiling_format, width, height, cpp)) { -+ goto fail; -+ } -+ -+ /* The mipmap levels are stored before the base of the texture. Make -+ * sure there is actually space in the BO. -+ */ -+ for (i = 1; i <= miplevels; i++) { -+ uint32_t level_width = max(width >> i, 1u); -+ uint32_t level_height = max(height >> i, 1u); -+ uint32_t aligned_width, aligned_height; -+ uint32_t level_size; -+ -+ /* Once the levels get small enough, they drop from T to LT. */ -+ if (tiling_format == VC4_TILING_FORMAT_T && -+ size_is_lt(level_width, level_height, cpp)) { -+ tiling_format = VC4_TILING_FORMAT_LT; -+ } -+ -+ switch (tiling_format) { -+ case VC4_TILING_FORMAT_T: -+ aligned_width = round_up(level_width, utile_w * 8); -+ aligned_height = round_up(level_height, utile_h * 8); -+ break; -+ case VC4_TILING_FORMAT_LT: -+ aligned_width = round_up(level_width, utile_w); -+ aligned_height = round_up(level_height, utile_h); -+ break; -+ default: -+ aligned_width = round_up(level_width, utile_w); -+ aligned_height = level_height; -+ break; -+ } -+ -+ level_size = aligned_width * cpp * aligned_height; -+ -+ if (offset < level_size) { -+ DRM_ERROR("Level %d (%dx%d -> %dx%d) size %db " -+ "overflowed buffer bounds (offset %d)\n", -+ i, level_width, level_height, -+ aligned_width, aligned_height, -+ level_size, offset); -+ goto fail; -+ } -+ -+ offset -= level_size; -+ } -+ -+ *validated_p0 = tex->paddr + p0; -+ -+ return true; -+ fail: -+ DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); -+ DRM_INFO("Texture p1 at %d: 0x%08x\n", sample->p_offset[1], p1); -+ DRM_INFO("Texture p2 at %d: 0x%08x\n", sample->p_offset[2], p2); -+ DRM_INFO("Texture p3 at %d: 0x%08x\n", sample->p_offset[3], p3); -+ return false; -+} -+ -+static int -+validate_shader_rec(struct drm_device *dev, -+ struct vc4_exec_info *exec, -+ struct vc4_shader_state *state) -+{ -+ uint32_t *src_handles; -+ void *pkt_u, *pkt_v; -+ enum shader_rec_reloc_type { -+ RELOC_CODE, -+ RELOC_VBO, -+ }; -+ struct shader_rec_reloc { -+ enum shader_rec_reloc_type type; -+ uint32_t offset; -+ }; -+ static const struct shader_rec_reloc gl_relocs[] = { -+ { RELOC_CODE, 4 }, /* fs */ -+ { RELOC_CODE, 16 }, /* vs */ -+ { RELOC_CODE, 28 }, /* cs */ -+ }; -+ static const struct shader_rec_reloc nv_relocs[] = { -+ { RELOC_CODE, 4 }, /* fs */ -+ { RELOC_VBO, 12 } -+ }; -+ const struct shader_rec_reloc *relocs; -+ struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; -+ uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; -+ int i; -+ struct vc4_validated_shader_info *validated_shader; -+ -+ if (state->packet == VC4_PACKET_NV_SHADER_STATE) { -+ relocs = nv_relocs; -+ nr_fixed_relocs = ARRAY_SIZE(nv_relocs); -+ -+ packet_size = 16; -+ } else { -+ relocs = gl_relocs; -+ nr_fixed_relocs = ARRAY_SIZE(gl_relocs); -+ -+ nr_attributes = state->addr & 0x7; -+ if (nr_attributes == 0) -+ nr_attributes = 8; -+ packet_size = gl_shader_rec_size(state->addr); -+ } -+ nr_relocs = nr_fixed_relocs + nr_attributes; -+ -+ if (nr_relocs * 4 > exec->shader_rec_size) { -+ DRM_ERROR("overflowed shader recs reading %d handles " -+ "from %d bytes left\n", -+ nr_relocs, exec->shader_rec_size); -+ return -EINVAL; -+ } -+ src_handles = exec->shader_rec_u; -+ exec->shader_rec_u += nr_relocs * 4; -+ exec->shader_rec_size -= nr_relocs * 4; -+ -+ if (packet_size > exec->shader_rec_size) { -+ DRM_ERROR("overflowed shader recs copying %db packet " -+ "from %d bytes left\n", -+ packet_size, exec->shader_rec_size); -+ return -EINVAL; -+ } -+ pkt_u = exec->shader_rec_u; -+ pkt_v = exec->shader_rec_v; -+ memcpy(pkt_v, pkt_u, packet_size); -+ exec->shader_rec_u += packet_size; -+ /* Shader recs have to be aligned to 16 bytes (due to the attribute -+ * flags being in the low bytes), so round the next validated shader -+ * rec address up. This should be safe, since we've got so many -+ * relocations in a shader rec packet. -+ */ -+ BUG_ON(roundup(packet_size, 16) - packet_size > nr_relocs * 4); -+ exec->shader_rec_v += roundup(packet_size, 16); -+ exec->shader_rec_size -= packet_size; -+ -+ for (i = 0; i < nr_relocs; i++) { -+ enum vc4_bo_mode mode; -+ -+ if (i < nr_fixed_relocs && relocs[i].type == RELOC_CODE) -+ mode = VC4_MODE_SHADER; -+ else -+ mode = VC4_MODE_RENDER; -+ -+ if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) { -+ return false; -+ } -+ } -+ -+ for (i = 0; i < nr_fixed_relocs; i++) { -+ uint32_t o = relocs[i].offset; -+ uint32_t src_offset = *(uint32_t *)(pkt_u + o); -+ uint32_t *texture_handles_u; -+ void *uniform_data_u; -+ uint32_t tex; -+ -+ *(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset; -+ -+ switch (relocs[i].type) { -+ case RELOC_CODE: -+ if (src_offset != 0) { -+ DRM_ERROR("Shaders must be at offset 0 of " -+ "the BO.\n"); -+ goto fail; -+ } -+ -+ validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -+ if (!validated_shader) -+ goto fail; -+ -+ if (validated_shader->uniforms_src_size > -+ exec->uniforms_size) { -+ DRM_ERROR("Uniforms src buffer overflow\n"); -+ goto fail; -+ } -+ -+ texture_handles_u = exec->uniforms_u; -+ uniform_data_u = (texture_handles_u + -+ validated_shader->num_texture_samples); -+ -+ memcpy(exec->uniforms_v, uniform_data_u, -+ validated_shader->uniforms_size); -+ -+ for (tex = 0; -+ tex < validated_shader->num_texture_samples; -+ tex++) { -+ if (!reloc_tex(exec, -+ uniform_data_u, -+ &validated_shader->texture_samples[tex], -+ texture_handles_u[tex])) { -+ goto fail; -+ } -+ } -+ -+ *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; -+ -+ exec->uniforms_u += validated_shader->uniforms_src_size; -+ exec->uniforms_v += validated_shader->uniforms_size; -+ exec->uniforms_p += validated_shader->uniforms_size; -+ -+ break; -+ -+ case RELOC_VBO: -+ break; -+ } -+ } -+ -+ for (i = 0; i < nr_attributes; i++) { -+ struct drm_gem_cma_object *vbo = bo[nr_fixed_relocs + i]; -+ uint32_t o = 36 + i * 8; -+ uint32_t offset = *(uint32_t *)(pkt_u + o + 0); -+ uint32_t attr_size = *(uint8_t *)(pkt_u + o + 4) + 1; -+ uint32_t stride = *(uint8_t *)(pkt_u + o + 5); -+ uint32_t max_index; -+ -+ if (state->addr & 0x8) -+ stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; -+ -+ if (vbo->base.size < offset || -+ vbo->base.size - offset < attr_size) { -+ DRM_ERROR("BO offset overflow (%d + %d > %d)\n", -+ offset, attr_size, vbo->base.size); -+ return -EINVAL; -+ } -+ -+ if (stride != 0) { -+ max_index = ((vbo->base.size - offset - attr_size) / -+ stride); -+ if (state->max_index > max_index) { -+ DRM_ERROR("primitives use index %d out of supplied %d\n", -+ state->max_index, max_index); -+ return -EINVAL; -+ } -+ } -+ -+ *(uint32_t *)(pkt_v + o) = vbo->paddr + offset; -+ } -+ -+ return 0; -+ -+fail: -+ return -EINVAL; -+} -+ -+int -+vc4_validate_shader_recs(struct drm_device *dev, -+ struct vc4_exec_info *exec) -+{ -+ uint32_t i; -+ int ret = 0; -+ -+ for (i = 0; i < exec->shader_state_count; i++) { -+ ret = validate_shader_rec(dev, exec, &exec->shader_state[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return ret; -+} -diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -new file mode 100644 -index 0000000..0aab9d7 ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -@@ -0,0 +1,521 @@ -+/* -+ * Copyright © 2014 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+/** -+ * DOC: Shader validator for VC4. -+ * -+ * The VC4 has no IOMMU between it and system memory. So, a user with access -+ * to execute shaders could escalate privilege by overwriting system memory -+ * (using the VPM write address register in the general-purpose DMA mode) or -+ * reading system memory it shouldn't (reading it as a texture, or uniform -+ * data, or vertex data). -+ * -+ * This walks over a shader starting from some offset within a BO, ensuring -+ * that its accesses are appropriately bounded, and recording how many texture -+ * accesses are made and where so that we can do relocations for them in the -+ * uniform stream. -+ * -+ * The kernel API has shaders stored in user-mapped BOs. The BOs will be -+ * forcibly unmapped from the process before validation, and any cache of -+ * validated state will be flushed if the mapping is faulted back in. -+ * -+ * Storing the shaders in BOs means that the validation process will be slow -+ * due to uncached reads, but since shaders are long-lived and shader BOs are -+ * never actually modified, this shouldn't be a problem. -+ */ -+ -+#include "vc4_drv.h" -+#include "vc4_qpu_defines.h" -+ -+struct vc4_shader_validation_state { -+ struct vc4_texture_sample_info tmu_setup[2]; -+ int tmu_write_count[2]; -+ -+ /* For registers that were last written to by a MIN instruction with -+ * one argument being a uniform, the address of the uniform. -+ * Otherwise, ~0. -+ * -+ * This is used for the validation of direct address memory reads. -+ */ -+ uint32_t live_min_clamp_offsets[32 + 32 + 4]; -+ bool live_max_clamp_regs[32 + 32 + 4]; -+}; -+ -+static uint32_t -+waddr_to_live_reg_index(uint32_t waddr, bool is_b) -+{ -+ if (waddr < 32) { -+ if (is_b) -+ return 32 + waddr; -+ else -+ return waddr; -+ } else if (waddr <= QPU_W_ACC3) { -+ -+ return 64 + waddr - QPU_W_ACC0; -+ } else { -+ return ~0; -+ } -+} -+ -+static uint32_t -+raddr_add_a_to_live_reg_index(uint64_t inst) -+{ -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ -+ if (add_a == QPU_MUX_A) { -+ return raddr_a; -+ } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) { -+ return 32 + raddr_b; -+ } else if (add_a <= QPU_MUX_R3) { -+ return 64 + add_a; -+ } else { -+ return ~0; -+ } -+} -+ -+static bool -+is_tmu_submit(uint32_t waddr) -+{ -+ return (waddr == QPU_W_TMU0_S || -+ waddr == QPU_W_TMU1_S); -+} -+ -+static bool -+is_tmu_write(uint32_t waddr) -+{ -+ return (waddr >= QPU_W_TMU0_S && -+ waddr <= QPU_W_TMU1_B); -+} -+ -+static bool -+record_validated_texture_sample(struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ int tmu) -+{ -+ uint32_t s = validated_shader->num_texture_samples; -+ int i; -+ struct vc4_texture_sample_info *temp_samples; -+ -+ temp_samples = krealloc(validated_shader->texture_samples, -+ (s + 1) * sizeof(*temp_samples), -+ GFP_KERNEL); -+ if (!temp_samples) -+ return false; -+ -+ memcpy(&temp_samples[s], -+ &validation_state->tmu_setup[tmu], -+ sizeof(*temp_samples)); -+ -+ validated_shader->num_texture_samples = s + 1; -+ validated_shader->texture_samples = temp_samples; -+ -+ for (i = 0; i < 4; i++) -+ validation_state->tmu_setup[tmu].p_offset[i] = ~0; -+ -+ return true; -+} -+ -+static bool -+check_tmu_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) -+{ -+ uint32_t waddr = (is_mul ? -+ QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -+ QPU_GET_FIELD(inst, QPU_WADDR_ADD)); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ int tmu = waddr > QPU_W_TMU0_B; -+ bool submit = is_tmu_submit(waddr); -+ bool is_direct = submit && validation_state->tmu_write_count[tmu] == 0; -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ if (is_direct) { -+ uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B); -+ uint32_t clamp_reg, clamp_offset; -+ -+ if (sig == QPU_SIG_SMALL_IMM) { -+ DRM_ERROR("direct TMU read used small immediate\n"); -+ return false; -+ } -+ -+ /* Make sure that this texture load is an add of the base -+ * address of the UBO to a clamped offset within the UBO. -+ */ -+ if (is_mul || -+ QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) { -+ DRM_ERROR("direct TMU load wasn't an add\n"); -+ return false; -+ } -+ -+ /* We assert that the the clamped address is the first -+ * argument, and the UBO base address is the second argument. -+ * This is arbitrary, but simpler than supporting flipping the -+ * two either way. -+ */ -+ clamp_reg = raddr_add_a_to_live_reg_index(inst); -+ if (clamp_reg == ~0) { -+ DRM_ERROR("direct TMU load wasn't clamped\n"); -+ return false; -+ } -+ -+ clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg]; -+ if (clamp_offset == ~0) { -+ DRM_ERROR("direct TMU load wasn't clamped\n"); -+ return false; -+ } -+ -+ /* Store the clamp value's offset in p1 (see reloc_tex() in -+ * vc4_validate.c). -+ */ -+ validation_state->tmu_setup[tmu].p_offset[1] = -+ clamp_offset; -+ -+ if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && -+ !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) { -+ DRM_ERROR("direct TMU load didn't add to a uniform\n"); -+ return false; -+ } -+ -+ validation_state->tmu_setup[tmu].is_direct = true; -+ } else { -+ if (raddr_a == QPU_R_UNIF || (sig != QPU_SIG_SMALL_IMM && -+ raddr_b == QPU_R_UNIF)) { -+ DRM_ERROR("uniform read in the same instruction as " -+ "texture setup.\n"); -+ return false; -+ } -+ } -+ -+ if (validation_state->tmu_write_count[tmu] >= 4) { -+ DRM_ERROR("TMU%d got too many parameters before dispatch\n", -+ tmu); -+ return false; -+ } -+ validation_state->tmu_setup[tmu].p_offset[validation_state->tmu_write_count[tmu]] = -+ validated_shader->uniforms_size; -+ validation_state->tmu_write_count[tmu]++; -+ /* Since direct uses a RADDR uniform reference, it will get counted in -+ * check_instruction_reads() -+ */ -+ if (!is_direct) -+ validated_shader->uniforms_size += 4; -+ -+ if (submit) { -+ if (!record_validated_texture_sample(validated_shader, -+ validation_state, tmu)) { -+ return false; -+ } -+ -+ validation_state->tmu_write_count[tmu] = 0; -+ } -+ -+ return true; -+} -+ -+static bool -+check_register_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) -+{ -+ uint32_t waddr = (is_mul ? -+ QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -+ QPU_GET_FIELD(inst, QPU_WADDR_ADD)); -+ -+ switch (waddr) { -+ case QPU_W_UNIFORMS_ADDRESS: -+ /* XXX: We'll probably need to support this for reladdr, but -+ * it's definitely a security-related one. -+ */ -+ DRM_ERROR("uniforms address load unsupported\n"); -+ return false; -+ -+ case QPU_W_TLB_COLOR_MS: -+ case QPU_W_TLB_COLOR_ALL: -+ case QPU_W_TLB_Z: -+ /* These only interact with the tile buffer, not main memory, -+ * so they're safe. -+ */ -+ return true; -+ -+ case QPU_W_TMU0_S: -+ case QPU_W_TMU0_T: -+ case QPU_W_TMU0_R: -+ case QPU_W_TMU0_B: -+ case QPU_W_TMU1_S: -+ case QPU_W_TMU1_T: -+ case QPU_W_TMU1_R: -+ case QPU_W_TMU1_B: -+ return check_tmu_write(inst, validated_shader, validation_state, -+ is_mul); -+ -+ case QPU_W_HOST_INT: -+ case QPU_W_TMU_NOSWAP: -+ case QPU_W_TLB_ALPHA_MASK: -+ case QPU_W_MUTEX_RELEASE: -+ /* XXX: I haven't thought about these, so don't support them -+ * for now. -+ */ -+ DRM_ERROR("Unsupported waddr %d\n", waddr); -+ return false; -+ -+ case QPU_W_VPM_ADDR: -+ DRM_ERROR("General VPM DMA unsupported\n"); -+ return false; -+ -+ case QPU_W_VPM: -+ case QPU_W_VPMVCD_SETUP: -+ /* We allow VPM setup in general, even including VPM DMA -+ * configuration setup, because the (unsafe) DMA can only be -+ * triggered by QPU_W_VPM_ADDR writes. -+ */ -+ return true; -+ -+ case QPU_W_TLB_STENCIL_SETUP: -+ return true; -+ } -+ -+ return true; -+} -+ -+static void -+track_live_clamps(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state) -+{ -+ uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD); -+ uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); -+ uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); -+ uint32_t cond_add = QPU_GET_FIELD(inst, QPU_COND_ADD); -+ uint32_t add_a = QPU_GET_FIELD(inst, QPU_ADD_A); -+ uint32_t add_b = QPU_GET_FIELD(inst, QPU_ADD_B); -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ bool ws = inst & QPU_WS; -+ uint32_t lri_add_a, lri_add, lri_mul; -+ bool add_a_is_min_0; -+ -+ /* Check whether OP_ADD's A argumennt comes from a live MAX(x, 0), -+ * before we clear previous live state. -+ */ -+ lri_add_a = raddr_add_a_to_live_reg_index(inst); -+ add_a_is_min_0 = (lri_add_a != ~0 && -+ validation_state->live_max_clamp_regs[lri_add_a]); -+ -+ /* Clear live state for registers written by our instruction. */ -+ lri_add = waddr_to_live_reg_index(waddr_add, ws); -+ lri_mul = waddr_to_live_reg_index(waddr_mul, !ws); -+ if (lri_mul != ~0) { -+ validation_state->live_max_clamp_regs[lri_mul] = false; -+ validation_state->live_min_clamp_offsets[lri_mul] = ~0; -+ } -+ if (lri_add != ~0) { -+ validation_state->live_max_clamp_regs[lri_add] = false; -+ validation_state->live_min_clamp_offsets[lri_add] = ~0; -+ } else { -+ /* Nothing further to do for live tracking, since only ADDs -+ * generate new live clamp registers. -+ */ -+ return; -+ } -+ -+ /* Now, handle remaining live clamp tracking for the ADD operation. */ -+ -+ if (cond_add != QPU_COND_ALWAYS) -+ return; -+ -+ if (op_add == QPU_A_MAX) { -+ /* Track live clamps of a value to a minimum of 0 (in either -+ * arg). -+ */ -+ if (sig != QPU_SIG_SMALL_IMM || raddr_b != 0 || -+ (add_a != QPU_MUX_B && add_b != QPU_MUX_B)) { -+ return; -+ } -+ -+ validation_state->live_max_clamp_regs[lri_add] = true; -+ } if (op_add == QPU_A_MIN) { -+ /* Track live clamps of a value clamped to a minimum of 0 and -+ * a maximum of some uniform's offset. -+ */ -+ if (!add_a_is_min_0) -+ return; -+ -+ if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) && -+ !(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF && -+ sig != QPU_SIG_SMALL_IMM)) { -+ return; -+ } -+ -+ validation_state->live_min_clamp_offsets[lri_add] = -+ validated_shader->uniforms_size; -+ } -+} -+ -+static bool -+check_instruction_writes(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state) -+{ -+ uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); -+ uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); -+ bool ok; -+ -+ if (is_tmu_write(waddr_add) && is_tmu_write(waddr_mul)) { -+ DRM_ERROR("ADD and MUL both set up textures\n"); -+ return false; -+ } -+ -+ ok = (check_register_write(inst, validated_shader, validation_state, false) && -+ check_register_write(inst, validated_shader, validation_state, true)); -+ -+ track_live_clamps(inst, validated_shader, validation_state); -+ -+ return ok; -+} -+ -+static bool -+check_instruction_reads(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader) -+{ -+ uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); -+ uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ if (raddr_a == QPU_R_UNIF || -+ (raddr_b == QPU_R_UNIF && sig != QPU_SIG_SMALL_IMM)) { -+ /* This can't overflow the uint32_t, because we're reading 8 -+ * bytes of instruction to increment by 4 here, so we'd -+ * already be OOM. -+ */ -+ validated_shader->uniforms_size += 4; -+ } -+ -+ return true; -+} -+ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj) -+{ -+ bool found_shader_end = false; -+ int shader_end_ip = 0; -+ uint32_t ip, max_ip; -+ uint64_t *shader; -+ struct vc4_validated_shader_info *validated_shader; -+ struct vc4_shader_validation_state validation_state; -+ int i; -+ -+ memset(&validation_state, 0, sizeof(validation_state)); -+ -+ for (i = 0; i < 8; i++) -+ validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0; -+ for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++) -+ validation_state.live_min_clamp_offsets[i] = ~0; -+ -+ shader = shader_obj->vaddr; -+ max_ip = shader_obj->base.size / sizeof(uint64_t); -+ -+ validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL); -+ if (!validated_shader) -+ return NULL; -+ -+ for (ip = 0; ip < max_ip; ip++) { -+ uint64_t inst = shader[ip]; -+ uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); -+ -+ switch (sig) { -+ case QPU_SIG_NONE: -+ case QPU_SIG_WAIT_FOR_SCOREBOARD: -+ case QPU_SIG_SCOREBOARD_UNLOCK: -+ case QPU_SIG_COLOR_LOAD: -+ case QPU_SIG_LOAD_TMU0: -+ case QPU_SIG_LOAD_TMU1: -+ case QPU_SIG_PROG_END: -+ case QPU_SIG_SMALL_IMM: -+ if (!check_instruction_writes(inst, validated_shader, -+ &validation_state)) { -+ DRM_ERROR("Bad write at ip %d\n", ip); -+ goto fail; -+ } -+ -+ if (!check_instruction_reads(inst, validated_shader)) -+ goto fail; -+ -+ if (sig == QPU_SIG_PROG_END) { -+ found_shader_end = true; -+ shader_end_ip = ip; -+ } -+ -+ break; -+ -+ case QPU_SIG_LOAD_IMM: -+ if (!check_instruction_writes(inst, validated_shader, -+ &validation_state)) { -+ DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); -+ goto fail; -+ } -+ break; -+ -+ default: -+ DRM_ERROR("Unsupported QPU signal %d at " -+ "instruction %d\n", sig, ip); -+ goto fail; -+ } -+ -+ /* There are two delay slots after program end is signaled -+ * that are still executed, then we're finished. -+ */ -+ if (found_shader_end && ip == shader_end_ip + 2) -+ break; -+ } -+ -+ if (ip == max_ip) { -+ DRM_ERROR("shader failed to terminate before " -+ "shader BO end at %d\n", -+ shader_obj->base.size); -+ goto fail; -+ } -+ -+ /* Again, no chance of integer overflow here because the worst case -+ * scenario is 8 bytes of uniforms plus handles per 8-byte -+ * instruction. -+ */ -+ validated_shader->uniforms_src_size = -+ (validated_shader->uniforms_size + -+ 4 * validated_shader->num_texture_samples); -+ -+ return validated_shader; -+ -+fail: -+ if (validated_shader) { -+ kfree(validated_shader->texture_samples); -+ kfree(validated_shader); -+ } -+ return NULL; -+} -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -new file mode 100644 -index 0000000..499daae ---- /dev/null -+++ b/include/uapi/drm/vc4_drm.h -@@ -0,0 +1,229 @@ -+/* -+ * Copyright © 2014-2015 Broadcom -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef _UAPI_VC4_DRM_H_ -+#define _UAPI_VC4_DRM_H_ -+ -+#include -+ -+#define DRM_VC4_SUBMIT_CL 0x00 -+#define DRM_VC4_WAIT_SEQNO 0x01 -+#define DRM_VC4_WAIT_BO 0x02 -+#define DRM_VC4_CREATE_BO 0x03 -+#define DRM_VC4_MMAP_BO 0x04 -+#define DRM_VC4_CREATE_SHADER_BO 0x05 -+ -+#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) -+#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -+#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) -+#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) -+#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) -+#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+ -+struct drm_vc4_submit_rcl_surface { -+ uint32_t hindex; /* Handle index, or ~0 if not present. */ -+ uint32_t offset; /* Offset to start of buffer. */ -+ /* -+ * Bits for either render config (color_ms_write) or load/store packet. -+ */ -+ uint16_t bits; -+ uint16_t pad; -+}; -+ -+/** -+ * struct drm_vc4_submit_cl - ioctl argument for submitting commands to the 3D -+ * engine. -+ * -+ * Drivers typically use GPU BOs to store batchbuffers / command lists and -+ * their associated state. However, because the VC4 lacks an MMU, we have to -+ * do validation of memory accesses by the GPU commands. If we were to store -+ * our commands in BOs, we'd need to do uncached readback from them to do the -+ * validation process, which is too expensive. Instead, userspace accumulates -+ * commands and associated state in plain memory, then the kernel copies the -+ * data to its own address space, and then validates and stores it in a GPU -+ * BO. -+ */ -+struct drm_vc4_submit_cl { -+ /* Pointer to the binner command list. -+ * -+ * This is the first set of commands executed, which runs the -+ * coordinate shader to determine where primitives land on the screen, -+ * then writes out the state updates and draw calls necessary per tile -+ * to the tile allocation BO. -+ */ -+ uint64_t bin_cl; -+ -+ /* Pointer to the shader records. -+ * -+ * Shader records are the structures read by the hardware that contain -+ * pointers to uniforms, shaders, and vertex attributes. The -+ * reference to the shader record has enough information to determine -+ * how many pointers are necessary (fixed number for shaders/uniforms, -+ * and an attribute count), so those BO indices into bo_handles are -+ * just stored as uint32_ts before each shader record passed in. -+ */ -+ uint64_t shader_rec; -+ -+ /* Pointer to uniform data and texture handles for the textures -+ * referenced by the shader. -+ * -+ * For each shader state record, there is a set of uniform data in the -+ * order referenced by the record (FS, VS, then CS). Each set of -+ * uniform data has a uint32_t index into bo_handles per texture -+ * sample operation, in the order the QPU_W_TMUn_S writes appear in -+ * the program. Following the texture BO handle indices is the actual -+ * uniform data. -+ * -+ * The individual uniform state blocks don't have sizes passed in, -+ * because the kernel has to determine the sizes anyway during shader -+ * code validation. -+ */ -+ uint64_t uniforms; -+ uint64_t bo_handles; -+ -+ /* Size in bytes of the binner command list. */ -+ uint32_t bin_cl_size; -+ /* Size in bytes of the set of shader records. */ -+ uint32_t shader_rec_size; -+ /* Number of shader records. -+ * -+ * This could just be computed from the contents of shader_records and -+ * the address bits of references to them from the bin CL, but it -+ * keeps the kernel from having to resize some allocations it makes. -+ */ -+ uint32_t shader_rec_count; -+ /* Size in bytes of the uniform state. */ -+ uint32_t uniforms_size; -+ -+ /* Number of BO handles passed in (size is that times 4). */ -+ uint32_t bo_handle_count; -+ -+ /* RCL setup: */ -+ uint16_t width; -+ uint16_t height; -+ uint8_t min_x_tile; -+ uint8_t min_y_tile; -+ uint8_t max_x_tile; -+ uint8_t max_y_tile; -+ struct drm_vc4_submit_rcl_surface color_read; -+ struct drm_vc4_submit_rcl_surface color_ms_write; -+ struct drm_vc4_submit_rcl_surface zs_read; -+ struct drm_vc4_submit_rcl_surface zs_write; -+ uint32_t clear_color[2]; -+ uint32_t clear_z; -+ uint8_t clear_s; -+ -+ uint32_t pad:24; -+ -+#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) -+ uint32_t flags; -+ -+ /* Returned value of the seqno of this render job (for the -+ * wait ioctl). -+ */ -+ uint64_t seqno; -+}; -+ -+/** -+ * struct drm_vc4_wait_seqno - ioctl argument for waiting for -+ * DRM_VC4_SUBMIT_CL completion using its returned seqno. -+ * -+ * timeout_ns is the timeout in nanoseconds, where "0" means "don't -+ * block, just return the status." -+ */ -+struct drm_vc4_wait_seqno { -+ uint64_t seqno; -+ uint64_t timeout_ns; -+}; -+ -+/** -+ * struct drm_vc4_wait_bo - ioctl argument for waiting for -+ * completion of the last DRM_VC4_SUBMIT_CL on a BO. -+ * -+ * This is useful for cases where multiple processes might be -+ * rendering to a BO and you want to wait for all rendering to be -+ * completed. -+ */ -+struct drm_vc4_wait_bo { -+ uint32_t handle; -+ uint32_t pad; -+ uint64_t timeout_ns; -+}; -+ -+/** -+ * struct drm_vc4_create_bo - ioctl argument for creating VC4 BOs. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_create_bo { -+ uint32_t size; -+ uint32_t flags; -+ /** Returned GEM handle for the BO. */ -+ uint32_t handle; -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_create_shader_bo - ioctl argument for creating VC4 -+ * shader BOs. -+ * -+ * Since allowing a shader to be overwritten while it's also being -+ * executed from would allow privlege escalation, shaders must be -+ * created using this ioctl, and they can't be mmapped later. -+ */ -+struct drm_vc4_create_shader_bo { -+ /* Size of the data argument. */ -+ uint32_t size; -+ /* Flags, currently must be 0. */ -+ uint32_t flags; -+ -+ /* Pointer to the data. */ -+ uint64_t data; -+ -+ /** Returned GEM handle for the BO. */ -+ uint32_t handle; -+ /* Pad, must be 0. */ -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -+ * -+ * This doesn't actually perform an mmap. Instead, it returns the -+ * offset you need to use in an mmap on the DRM device node. This -+ * means that tools like valgrind end up knowing about the mapped -+ * memory. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_mmap_bo { -+ /** Handle for the object being mapped. */ -+ uint32_t handle; -+ uint32_t flags; -+ /** offset into the drm node to use for subsequent mmap call. */ -+ uint64_t offset; -+}; -+ -+#endif /* _UAPI_VC4_DRM_H_ */ - -From 666602424fba993b28229ce2133ff8d2a16b248e Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 14 Oct 2015 11:32:14 -0700 -Subject: [PATCH 087/251] drm/vc4: Force HDMI to connected. - -For some reason on the downstream tree, the HPD GPIO isn't working. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c -index da9a36d..d15c529 100644 ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -164,6 +164,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) - struct drm_device *dev = connector->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - -+ return connector_status_connected; -+ - if (vc4->hdmi->hpd_gpio) { - if (gpio_get_value(vc4->hdmi->hpd_gpio)) - return connector_status_connected; - -From 83244506ffc629eb672d74f1e075d25188b4d081 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:23:18 -0700 -Subject: [PATCH 088/251] drm/vc4: bo cache locking fixes. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 32 ++++++++++++++++++-------------- - drivers/gpu/drm/vc4/vc4_drv.h | 2 +- - 2 files changed, 19 insertions(+), 15 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index bfa605f..af0fde6 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -112,14 +112,14 @@ void vc4_bo_cache_purge(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - } - - struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -@@ -134,18 +134,18 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - return NULL; - - /* First, try to get a vc4_bo from the kernel BO cache. */ -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - if (page_index < vc4->bo_cache.size_list_size && - !list_empty(&vc4->bo_cache.size_list[page_index])) { - struct vc4_bo *bo = - list_first_entry(&vc4->bo_cache.size_list[page_index], - struct vc4_bo, size_head); - vc4_bo_remove_from_cache(bo); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - kref_init(&bo->base.base.refcount); - return bo; - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - /* Otherwise, make a new BO. */ - for (pass = 0; ; pass++) { -@@ -215,7 +215,7 @@ vc4_bo_cache_free_old(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); -@@ -223,14 +223,14 @@ vc4_bo_cache_free_old(struct drm_device *dev) - mod_timer(&vc4->bo_cache.time_timer, - round_jiffies_up(jiffies + - msecs_to_jiffies(1000))); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - return; - } - - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - } - - /* Called on the last userspace/kernel unreference of the BO. Returns -@@ -248,21 +248,25 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - /* If the object references someone else's memory, we can't cache it. - */ - if (gem_bo->import_attach) { -+ mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -+ mutex_unlock(&vc4->bo_lock); - return; - } - - /* Don't cache if it was publicly named. */ - if (gem_bo->name) { -+ mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -+ mutex_unlock(&vc4->bo_lock); - return; - } - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); - if (!cache_list) { - vc4_bo_destroy(bo); -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - return; - } - -@@ -278,7 +282,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - - vc4->bo_stats.num_cached++; - vc4->bo_stats.size_cached += gem_bo->size; -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - vc4_bo_cache_free_old(dev); - } -@@ -465,7 +469,7 @@ void vc4_bo_cache_init(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- spin_lock_init(&vc4->bo_lock); -+ mutex_init(&vc4->bo_lock); - - INIT_LIST_HEAD(&vc4->bo_cache.time_list); - -@@ -498,9 +502,9 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_bo_stats stats; - -- spin_lock(&vc4->bo_lock); -+ mutex_lock(&vc4->bo_lock); - stats = vc4->bo_stats; -- spin_unlock(&vc4->bo_lock); -+ mutex_unlock(&vc4->bo_lock); - - seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); - seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 8cc89d1..c079b82 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -49,7 +49,7 @@ struct vc4_dev { - } bo_stats; - - /* Protects bo_cache and the BO stats. */ -- spinlock_t bo_lock; -+ struct mutex bo_lock; - - /* Sequence number for the last job queued in job_list. - * Starts at 0 (no jobs emitted). - -From 149b9d3feccb3fcc379d91cacc35fa8e6ce59dd1 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:29:41 -0700 -Subject: [PATCH 089/251] drm/vc4: bo cache locking cleanup. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index af0fde6..acd360c 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -215,7 +215,6 @@ vc4_bo_cache_free_old(struct drm_device *dev) - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); - -- mutex_lock(&vc4->bo_lock); - while (!list_empty(&vc4->bo_cache.time_list)) { - struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, - struct vc4_bo, unref_head); -@@ -223,14 +222,12 @@ vc4_bo_cache_free_old(struct drm_device *dev) - mod_timer(&vc4->bo_cache.time_timer, - round_jiffies_up(jiffies + - msecs_to_jiffies(1000))); -- mutex_unlock(&vc4->bo_lock); - return; - } - - vc4_bo_remove_from_cache(bo); - vc4_bo_destroy(bo); - } -- mutex_unlock(&vc4->bo_lock); - } - - /* Called on the last userspace/kernel unreference of the BO. Returns -@@ -245,29 +242,24 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - struct vc4_bo *bo = to_vc4_bo(gem_bo); - struct list_head *cache_list; - -+ mutex_lock(&vc4->bo_lock); - /* If the object references someone else's memory, we can't cache it. - */ - if (gem_bo->import_attach) { -- mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - - /* Don't cache if it was publicly named. */ - if (gem_bo->name) { -- mutex_lock(&vc4->bo_lock); - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - -- mutex_lock(&vc4->bo_lock); - cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); - if (!cache_list) { - vc4_bo_destroy(bo); -- mutex_unlock(&vc4->bo_lock); -- return; -+ goto out; - } - - if (bo->validated_shader) { -@@ -282,9 +274,11 @@ void vc4_free_object(struct drm_gem_object *gem_bo) - - vc4->bo_stats.num_cached++; - vc4->bo_stats.size_cached += gem_bo->size; -- mutex_unlock(&vc4->bo_lock); - - vc4_bo_cache_free_old(dev); -+ -+out: -+ mutex_unlock(&vc4->bo_lock); - } - - static void vc4_bo_cache_time_work(struct work_struct *work) -@@ -293,7 +287,9 @@ static void vc4_bo_cache_time_work(struct work_struct *work) - container_of(work, struct vc4_dev, bo_cache.time_work); - struct drm_device *dev = vc4->dev; - -+ mutex_lock(&vc4->bo_lock); - vc4_bo_cache_free_old(dev); -+ mutex_unlock(&vc4->bo_lock); - } - - static void vc4_bo_cache_time_timer(unsigned long data) - -From 7a42f6a5addb1961f016f14ef9010bdc19565a77 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:32:24 -0700 -Subject: [PATCH 090/251] drm/vc4: Use job_lock to protect seqno_cb_list. - -We're (mostly) not supposed to be using struct_mutex in drivers these -days. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 361390b..b1853b2 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -474,7 +474,6 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - vc4_complete_exec(exec); - spin_lock_irqsave(&vc4->job_lock, irqflags); - } -- spin_unlock_irqrestore(&vc4->job_lock, irqflags); - - list_for_each_entry_safe(cb, cb_temp, &vc4->seqno_cb_list, work.entry) { - if (cb->seqno <= vc4->finished_seqno) { -@@ -482,6 +481,8 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - schedule_work(&cb->work); - } - } -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); - } - - static void vc4_seqno_cb_work(struct work_struct *work) -@@ -496,18 +497,19 @@ int vc4_queue_seqno_cb(struct drm_device *dev, - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret = 0; -+ unsigned long irqflags; - - cb->func = func; - INIT_WORK(&cb->work, vc4_seqno_cb_work); - -- mutex_lock(&dev->struct_mutex); -+ spin_lock_irqsave(&vc4->job_lock, irqflags); - if (seqno > vc4->finished_seqno) { - cb->seqno = seqno; - list_add_tail(&cb->work.entry, &vc4->seqno_cb_list); - } else { - schedule_work(&cb->work); - } -- mutex_unlock(&dev->struct_mutex); -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); - - return ret; - } - -From bf31c306877aef83b109356b8471a69590d0a915 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:44:35 -0700 -Subject: [PATCH 091/251] drm/vc4: Drop struct_mutex around CL validation. - -We were using it so that we could make sure that shader validation -state didn't change while we were validating, but now shader -validation state is immutable. The bcl/rcl generation doesn't do any -other BO dereferencing, and seems to have no other global state -dependency not covered by job_lock / bo_lock. - -Fixes a lock order reversal between mmap_sem and struct_mutex. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index b1853b2..32f375a 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -244,13 +244,15 @@ static void - vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -- uint64_t seqno = ++vc4->emit_seqno; -+ uint64_t seqno; - unsigned long irqflags; - -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ -+ seqno = ++vc4->emit_seqno; - exec->seqno = seqno; - vc4_update_bo_seqnos(exec, seqno); - -- spin_lock_irqsave(&vc4->job_lock, irqflags); - list_add_tail(&exec->head, &vc4->job_list); - - /* If no job was executing, kick ours off. Otherwise, it'll -@@ -608,8 +610,6 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - exec->args = args; - INIT_LIST_HEAD(&exec->unref_list); - -- mutex_lock(&dev->struct_mutex); -- - ret = vc4_cl_lookup_bos(dev, file_priv, exec); - if (ret) - goto fail; -@@ -636,15 +636,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - /* Return the seqno for our job. */ - args->seqno = vc4->emit_seqno; - -- mutex_unlock(&dev->struct_mutex); -- - return 0; - - fail: - vc4_complete_exec(exec); - -- mutex_unlock(&dev->struct_mutex); -- - return ret; - } - - -From 90604ba9389fd34efcd5c4266fd9d4604f1543e4 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 19 Oct 2015 08:44:35 -0700 -Subject: [PATCH 092/251] drm/vc4: Drop struct_mutex around CL validation. - -We were using it so that we could make sure that shader validation -state didn't change while we were validating, but now shader -validation state is immutable. The bcl/rcl generation doesn't do any -other BO dereferencing, and seems to have no other global state -dependency not covered by job_lock / bo_lock. We only need to hold -struct_mutex for object unreferencing. - -Fixes a lock order reversal between mmap_sem and struct_mutex. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 32f375a..55551ea 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -439,10 +439,12 @@ fail: - } - - static void --vc4_complete_exec(struct vc4_exec_info *exec) -+vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) - { - unsigned i; - -+ /* Need the struct lock for drm_gem_object_unreference(). */ -+ mutex_lock(&dev->struct_mutex); - if (exec->bo) { - for (i = 0; i < exec->bo_count; i++) - drm_gem_object_unreference(&exec->bo[i].bo->base); -@@ -455,6 +457,7 @@ vc4_complete_exec(struct vc4_exec_info *exec) - list_del(&bo->unref_head); - drm_gem_object_unreference(&bo->base.base); - } -+ mutex_unlock(&dev->struct_mutex); - - kfree(exec); - } -@@ -473,7 +476,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - list_del(&exec->head); - - spin_unlock_irqrestore(&vc4->job_lock, irqflags); -- vc4_complete_exec(exec); -+ vc4_complete_exec(vc4->dev, exec); - spin_lock_irqsave(&vc4->job_lock, irqflags); - } - -@@ -525,12 +528,8 @@ vc4_job_done_work(struct work_struct *work) - { - struct vc4_dev *vc4 = - container_of(work, struct vc4_dev, job_done_work); -- struct drm_device *dev = vc4->dev; - -- /* Need the struct lock for drm_gem_object_unreference(). */ -- mutex_lock(&dev->struct_mutex); - vc4_job_handle_completed(vc4); -- mutex_unlock(&dev->struct_mutex); - } - - static int -@@ -639,7 +638,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - return 0; - - fail: -- vc4_complete_exec(exec); -+ vc4_complete_exec(vc4->dev, exec); - - return ret; - } - -From dcdfacf7cbb2ad8feb6c11326919b7482b2ac3cd Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 20 Oct 2015 13:59:15 +0100 -Subject: [PATCH 093/251] drm/vc4: Add support for more display plane formats. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_plane.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c -index 65e5455..0f85eb5 100644 ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -59,6 +59,22 @@ static const struct hvs_format { - .drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888, - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, - }, -+ { -+ .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, -+ .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, -+ }, -+ { -+ .drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565, -+ .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false, -+ }, -+ { -+ .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, -+ .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, -+ }, -+ { -+ .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, -+ .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false, -+ }, - }; - - static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) - -From 4f981196d46dcd9576c87c957b15acc0a68dcca8 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 12:31:56 +0100 -Subject: [PATCH 094/251] drm/vc4: No need to stop the stopped threads. - -This was leftover debug code from the hackdriver. We never submit -unless the thread is already idle. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 55551ea..eeb0925 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -104,10 +104,6 @@ submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- /* Stop any existing thread and set state to "stopped at halt" */ -- V3D_WRITE(V3D_CTNCS(thread), V3D_CTRUN); -- barrier(); -- - V3D_WRITE(V3D_CTNCA(thread), start); - barrier(); - - -From adb820489d061187ae01daa98ab1a404dbe5cd86 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 12:33:43 +0100 -Subject: [PATCH 095/251] drm/vc4: Remove extra barrier()s aroudn CTnCA/CTnEA - setup. - -The writel() that these expand to already does barriers. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index eeb0925..0cea723 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -104,14 +104,11 @@ submit_cl(struct drm_device *dev, uint32_t thread, uint32_t start, uint32_t end) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- V3D_WRITE(V3D_CTNCA(thread), start); -- barrier(); -- -- /* Set the end address of the control list. Writing this -- * register is what starts the job. -+ /* Set the current and end address of the control list. -+ * Writing the end register is what starts the job. - */ -+ V3D_WRITE(V3D_CTNCA(thread), start); - V3D_WRITE(V3D_CTNEA(thread), end); -- barrier(); - } - - int - -From 90058bcf1d4a588a3ddba5e78e1f998a33d2d5b1 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 23 Oct 2015 14:57:22 +0100 -Subject: [PATCH 096/251] drm/vc4: Fix a typo in a V3D debug register. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_regs.h | 2 +- - drivers/gpu/drm/vc4/vc4_v3d.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h -index 9e4e904..4e52a0a 100644 ---- a/drivers/gpu/drm/vc4/vc4_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_regs.h -@@ -154,7 +154,7 @@ - #define V3D_PCTRS14 0x006f4 - #define V3D_PCTR15 0x006f8 - #define V3D_PCTRS15 0x006fc --#define V3D_BGE 0x00f00 -+#define V3D_DBGE 0x00f00 - #define V3D_FDBGO 0x00f04 - #define V3D_FDBGB 0x00f08 - #define V3D_FDBGR 0x00f0c -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index b9cb7cf..cf35f58 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -99,7 +99,7 @@ static const struct { - REGDEF(V3D_PCTRS14), - REGDEF(V3D_PCTR15), - REGDEF(V3D_PCTRS15), -- REGDEF(V3D_BGE), -+ REGDEF(V3D_DBGE), - REGDEF(V3D_FDBGO), - REGDEF(V3D_FDBGB), - REGDEF(V3D_FDBGR), - -From fa03eea2a7fd499bd9254430e4396cf91aa96d39 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 2 Nov 2015 17:07:33 +0000 -Subject: [PATCH 097/251] drm/vc4: Enable VC4 modules, and increase CMA size - with overlay - -If using the overlay, be careful not to boot to GUI or run startx, -or the Pi will almost hang, reporting stalls in kernel threads. ---- - arch/arm/boot/dts/overlays/README | 8 ++ - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 95 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - 4 files changed, 107 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d7f2979..1fa98ce 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -601,6 +601,14 @@ Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: vc4-kms-v3d -+Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. Running startx or -+ booting to GUI while this overlay is in use will cause interesting -+ lockups. -+Load: dtoverlay=vc4-kms-v3d -+Params: -+ -+ - Name: vga666 - Info: Overlay for the Fen Logic VGA666 board - This uses GPIOs 2-21 (so no I2C), and activates the output 2-3 seconds -diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -new file mode 100644 -index 0000000..cf5d5c9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -0,0 +1,95 @@ -+/* -+ * vc4-kms-v3d-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include "dt-bindings/clock/bcm2835.h" -+#include "dt-bindings/gpio/gpio.h" -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2c2>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&cprman>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&fb>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ pixelvalve@7e206000 { -+ compatible = "brcm,bcm2835-pixelvalve0"; -+ reg = <0x7e206000 0x100>; -+ interrupts = <2 13>; /* pwa0 */ -+ }; -+ -+ pixelvalve@7e207000 { -+ compatible = "brcm,bcm2835-pixelvalve1"; -+ reg = <0x7e207000 0x100>; -+ interrupts = <2 14>; /* pwa1 */ -+ }; -+ -+ hvs@7e400000 { -+ compatible = "brcm,bcm2835-hvs"; -+ reg = <0x7e400000 0x6000>; -+ interrupts = <2 1>; -+ }; -+ -+ pixelvalve@7e807000 { -+ compatible = "brcm,bcm2835-pixelvalve2"; -+ reg = <0x7e807000 0x100>; -+ interrupts = <2 10>; /* pixelvalve */ -+ }; -+ -+ hdmi@7e902000 { -+ compatible = "brcm,bcm2835-hdmi"; -+ reg = <0x7e902000 0x600>, -+ <0x7e808000 0x100>; -+ interrupts = <2 8>, <2 9>; -+ ddc = <&i2c2>; -+ hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>; -+ clocks = <&cprman BCM2835_PLLH_PIX>, -+ <&cprman BCM2835_CLOCK_HSM>; -+ clock-names = "pixel", "hdmi"; -+ }; -+ -+ v3d@7ec00000 { -+ compatible = "brcm,vc4-v3d"; -+ reg = <0x7ec00000 0x1000>; -+ interrupts = <1 10>; -+ }; -+ -+ gpu@7e4c0000 { -+ compatible = "brcm,bcm2835-vc4"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target-path = "/chosen"; -+ __overlay__ { -+ bootargs = "cma=256M@512M"; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 13999af..4e474c7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -802,6 +802,8 @@ CONFIG_VIDEO_TW9903=m - CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m -+CONFIG_DRM=m -+CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 146add9..d6aa058 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -795,6 +795,8 @@ CONFIG_VIDEO_TW9903=m - CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m -+CONFIG_DRM=m -+CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m - -From de2afd5a8db4a62e65057ace15fe15b498074dff Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Nov 2015 18:29:58 +0000 -Subject: [PATCH 098/251] squash: fixups - ---- - drivers/gpu/drm/vc4/Kconfig | 2 +- - drivers/gpu/drm/vc4/vc4_drv.c | 2 +- - drivers/gpu/drm/vc4/vc4_kms.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig -index 2d7d115..71f019f 100644 ---- a/drivers/gpu/drm/vc4/Kconfig -+++ b/drivers/gpu/drm/vc4/Kconfig -@@ -1,6 +1,6 @@ - config DRM_VC4 - tristate "Broadcom VC4 Graphics" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on DRM && HAVE_DMA_ATTRS - select DRM_KMS_HELPER - select DRM_KMS_CMA_HELPER -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index 3baf1fc..e2a2be2 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -127,7 +127,7 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -- .gem_obj_size = sizeof(struct vc4_bo), -+ //.gem_obj_size = sizeof(struct vc4_bo), - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index c83287a..2082713 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -45,7 +45,7 @@ vc4_atomic_complete_commit(struct vc4_commit *c) - - drm_atomic_helper_commit_modeset_disables(dev, state); - -- drm_atomic_helper_commit_planes(dev, state); -+ drm_atomic_helper_commit_planes(dev, state, false); - - drm_atomic_helper_commit_modeset_enables(dev, state); - - -From 454534cc445c73a8d95814b1bf8e2ef67f3c4f41 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Nov 2015 20:26:03 +0000 -Subject: [PATCH 099/251] squash: add missing vc4-kms-v3d-overlay.dtb to - makefile - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index fb7ac49..fc09bfb 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -52,6 +52,7 @@ dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += vc4-kms-v3d-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -From 971c63d209cdcdeec8eba9211e9f75add0c6b10b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 12 Oct 2015 11:23:34 -0700 -Subject: [PATCH 100/251] clk: bcm2835: Also build the driver for downstream - kernels. - -Signed-off-by: Eric Anholt ---- - drivers/clk/bcm/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index 3fc9506..a1b4cbc 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -3,7 +3,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o --obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o -+obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o - -From 64297bcfecf13b8fa1939fc725b772875157b0a4 Mon Sep 17 00:00:00 2001 -From: Holger Steinhaus -Date: Sat, 14 Nov 2015 18:37:43 +0100 -Subject: [PATCH 101/251] dts: Added overlay for gpio_ir_recv driver - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 18 ++++++++++- - arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 45 ++++++++++++++++++++++++++ - 3 files changed, 63 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/gpio-ir-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index fc09bfb..ebc3354 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,7 @@ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1fa98ce..b4578cc 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -196,6 +196,22 @@ Params: int_pin GPIO used for INT (default 25) - speed SPI bus speed (default 12000000) - - -+Name: gpio-ir -+Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- -+ based gpio_ir_recv driver maps received keys directly to a -+ /dev/input/event* device, all decoding is done by the kernel - LIRC is -+ not required! The key mapping and other decoding parameters can be -+ configured by "ir-keytable" tool. -+Load: dtoverlay=gpio-ir,= -+Params: gpio_pin Input pin number. Default is 18. -+ -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "down". -+ -+ rc-map-name Default rc keymap (can also be changed by -+ ir-keytable), defaults to "rc-rc6-mce" -+ -+ - Name: gpio-poweroff - Info: Drives a GPIO high or low on reboot - Load: dtoverlay=gpio-poweroff,= -@@ -308,7 +324,7 @@ Params: - Name: lirc-rpi - Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) - Consult the module documentation for more details. --Load: dtoverlay=lirc-rpi,=,... -+Load: dtoverlay=lirc-rpi,= - Params: gpio_out_pin GPIO for output (default "17") - - gpio_in_pin GPIO for input (default "18") -diff --git a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -new file mode 100644 -index 0000000..a2d6bc7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -@@ -0,0 +1,45 @@ -+// Definitions for ir-gpio module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ gpio_ir: ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ -+ // pin number, high or low -+ gpios = <&gpio 18 1>; -+ -+ // parameter for keymap name -+ linux,rc-map-name = "rc-rc6-mce"; -+ -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ gpio_ir_pins: gpio_ir_pins { -+ brcm,pins = <18>; // pin 18 -+ brcm,function = <0>; // in -+ brcm,pull = <1>; // down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ // parameters -+ gpio_pin = <&gpio_ir>,"gpios:4", -+ <&gpio_ir_pins>,"brcm,pins:0", -+ <&gpio_ir_pins>,"brcm,pull:0"; // pin number -+ gpio_pull = <&gpio_ir_pins>,"brcm,pull:0"; // pull-up/down state -+ -+ rc-map-name = <&gpio_ir>,"linux,rc-map-name"; // default rc map -+ }; -+}; - -From 1cb2b31fb379d569dd28ef81a69b04e748aa0a7e Mon Sep 17 00:00:00 2001 -From: Alistair Buxton -Date: Sun, 1 Nov 2015 22:27:56 +0000 -Subject: [PATCH 102/251] Build i2c_gpio module and add a device tree overlay - to configure it. - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 13 +++++++++++- - arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 28 +++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 43 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index ebc3354..e15d55c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b4578cc..9362443 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -287,9 +287,20 @@ Params: speed Display SPI bus speed - ledgpio GPIO used to control backlight - - -+Name: i2c-gpio -+Info: Adds support for software i2c controller on gpio pins -+Load: dtoverlay=i2c-gpio,= -+Params: i2c_gpio_sda GPIO used for I2C data (default "23") -+ -+ i2c_gpio_scl GPIO used for I2C clock (default "24") -+ -+ i2c_gpio_delay_us Clock delay in microseconds -+ (default "2" = ~100kHz) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices --Load: dtoverlay=i2c-rtc, -+Load: dtoverlay=i2c-rtc,= - Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device -diff --git a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -new file mode 100644 -index 0000000..2a2dc98 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -@@ -0,0 +1,28 @@ -+// Overlay for i2c_gpio bitbanging host bus. -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ i2c_gpio: i2c@0 { -+ compatible = "i2c-gpio"; -+ gpios = <&gpio 23 0 /* sda */ -+ &gpio 24 0 /* scl */ -+ >; -+ i2c-gpio,delay-us = <2>; /* ~100 kHz */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; -+ i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; -+ i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; -+ }; -+}; -+ -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 4e474c7..fc35254 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -595,6 +595,7 @@ CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m -+CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_SPIDEV=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index d6aa058..51dc019 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -588,6 +588,7 @@ CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m -+CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_SPIDEV=y - -From d8810f6aa46773aab926661593de341c6bd77cae Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Sun, 18 Oct 2015 17:07:24 -0700 -Subject: [PATCH 103/251] New overlay for PiScreen2r - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 +++ - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 100 ++++++++++++++++++++++ - 3 files changed, 115 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index e15d55c..8595b14 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -35,6 +35,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9362443..0a21248 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -425,6 +425,20 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: piscreen2r -+Info: PiScreen 2 with resistive TP display by OzzMaker.com -+Load: dtoverlay=piscreen2r,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -new file mode 100644 -index 0000000..7c018e0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -0,0 +1,100 @@ -+ /* -+ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen2_pins: piscreen2_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen2: piscreen2@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen2_pins>; -+ bgr; -+ spi-max-frequency = <64000000>; -+ rotate = <90>; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ txbuflen = <32768>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c0 0x11 0x09 -+ 0x10000c1 0x41 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000b6 0x00 0x02 -+ 0x10000f7 0xa9 0x51 0x2c 0x2 -+ 0x10000be 0x00 0x04 -+ 0x10000e9 0x00 -+ 0x1000011 -+ 0x1000029>; -+ -+ }; -+ -+ piscreen2_ts: piscreen2-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen2>,"spi-max-frequency:0"; -+ rotate = <&piscreen2>,"rotate:0"; -+ fps = <&piscreen2>,"fps:0"; -+ debug = <&piscreen2>,"debug:0"; -+ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -+ - -From f2812d3b0fa2cda5f79e89235222c787bce2adac Mon Sep 17 00:00:00 2001 -From: Ondrej Wisniewski -Date: Fri, 6 Nov 2015 15:01:28 +0100 -Subject: [PATCH 104/251] dts: Added overlay for Adafruit PiTFT 2.8" capacitive - touch screen - ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 22 ++++++ - .../dts/overlays/pitft28-capacitive-overlay.dts | 88 ++++++++++++++++++++++ - 3 files changed, 111 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 8595b14..7d747bc 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -36,6 +36,7 @@ dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0a21248..422a0d4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -439,6 +439,28 @@ Params: speed Display SPI bus speed - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: pitft28-capacitive -+Info: Adafruit PiTFT 2.8" capacitive touch screen -+Load: dtoverlay=pitft28-capacitive,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ touch-sizex Touchscreen size x (default 240) -+ -+ touch-sizey Touchscreen size y (default 320) -+ -+ touch-invx Touchscreen inverted x axis -+ -+ touch-invy Touchscreen inverted y axis -+ -+ touch-swapxy Touchscreen swapped x y axis -+ -+ - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= -diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -new file mode 100644 -index 0000000..48920e9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -@@ -0,0 +1,88 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" capacitive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ft6236: ft6236@38 { -+ compatible = "focaltech,ft6236"; -+ reg = <0x38>; -+ -+ interrupt-parent = <&gpio>; -+ interrupts = <24 2>; -+ touchscreen-size-x = <240>; -+ touchscreen-size-y = <320>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ touch-sizex = <&ft6236>,"touchscreen-size-x?"; -+ touch-sizey = <&ft6236>,"touchscreen-size-y?"; -+ touch-invx = <&ft6236>,"touchscreen-inverted-x?"; -+ touch-invy = <&ft6236>,"touchscreen-inverted-y?"; -+ touch-swapxy = <&ft6236>,"touchscreen-swapped-x-y?"; -+ }; -+}; - -From bc31b90ccadb0bfeaefbe40b460be9e7fa20b7f2 Mon Sep 17 00:00:00 2001 -From: Stuart MacLean -Date: Fri, 2 Oct 2015 15:12:59 +0100 -Subject: [PATCH 105/251] Add support for the HiFiBerry DAC+ Pro. - -The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators. - -An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame. ---- - .../dts/overlays/hifiberry-dacplus-overlay.dts | 15 +- - drivers/clk/Makefile | 1 + - drivers/clk/clk-hifiberry-dacpro.c | 160 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 244 +++++++++++++++++++-- - sound/soc/codecs/pcm512x.c | 3 +- - 5 files changed, 396 insertions(+), 27 deletions(-) - create mode 100644 drivers/clk/clk-hifiberry-dacpro.c - -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index deb9c62..f923a48 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -6,6 +6,16 @@ - compatible = "brcm,bcm2708"; - - fragment@0 { -+ target-path = "/clocks"; -+ __overlay__ { -+ dacpro_osc: dacpro_osc { -+ compatible = "hifiberry,dacpro-clk"; -+ #clock-cells = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { - target = <&sound>; - __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; -@@ -14,14 +24,14 @@ - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&i2s>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -32,6 +42,7 @@ - #sound-dai-cells = <0>; - compatible = "ti,pcm5122"; - reg = <0x4d>; -+ clocks = <&dacpro_osc>; - status = "okay"; - }; - }; -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index 820714c..94ccf03 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o - obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o - obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o - obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o - obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o - obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o - obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -diff --git a/drivers/clk/clk-hifiberry-dacpro.c b/drivers/clk/clk-hifiberry-dacpro.c -new file mode 100644 -index 0000000..3e35d45 ---- /dev/null -+++ b/drivers/clk/clk-hifiberry-dacpro.c -@@ -0,0 +1,160 @@ -+/* -+ * Clock Driver for HiFiBerry DAC Pro -+ * -+ * Author: Stuart MacLean -+ * Copyright 2015 -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+/** -+ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro -+ * @hw: clk_hw for the common clk framework -+ * @mode: 0 => CLK44EN, 1 => CLK48EN -+ */ -+struct clk_hifiberry_hw { -+ struct clk_hw hw; -+ uint8_t mode; -+}; -+ -+#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw) -+ -+static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = { -+ { .compatible = "hifiberry,dacpro-clk",}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids); -+ -+static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE : -+ CLK_48EN_RATE; -+} -+ -+static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long *parent_rate) -+{ -+ long actual_rate; -+ -+ if (rate <= CLK_44EN_RATE) { -+ actual_rate = (long)CLK_44EN_RATE; -+ } else if (rate >= CLK_48EN_RATE) { -+ actual_rate = (long)CLK_48EN_RATE; -+ } else { -+ long diff44Rate = (long)(rate - CLK_44EN_RATE); -+ long diff48Rate = (long)(CLK_48EN_RATE - rate); -+ -+ if (diff44Rate < diff48Rate) -+ actual_rate = (long)CLK_44EN_RATE; -+ else -+ actual_rate = (long)CLK_48EN_RATE; -+ } -+ return actual_rate; -+} -+ -+ -+static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ unsigned long actual_rate; -+ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw); -+ -+ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate, -+ &parent_rate); -+ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1; -+ return 0; -+} -+ -+ -+const struct clk_ops clk_hifiberry_dacpro_rate_ops = { -+ .recalc_rate = clk_hifiberry_dacpro_recalc_rate, -+ .round_rate = clk_hifiberry_dacpro_round_rate, -+ .set_rate = clk_hifiberry_dacpro_set_rate, -+}; -+ -+static int clk_hifiberry_dacpro_probe(struct platform_device *pdev) -+{ -+ int ret; -+ struct clk_hifiberry_hw *proclk; -+ struct clk *clk; -+ struct device *dev; -+ struct clk_init_data init; -+ -+ dev = &pdev->dev; -+ -+ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL); -+ if (!proclk) -+ return -ENOMEM; -+ -+ init.name = "clk-hifiberry-dacpro"; -+ init.ops = &clk_hifiberry_dacpro_rate_ops; -+ init.flags = CLK_IS_ROOT | CLK_IS_BASIC; -+ init.parent_names = NULL; -+ init.num_parents = 0; -+ -+ proclk->mode = 0; -+ proclk->hw.init = &init; -+ -+ clk = devm_clk_register(dev, &proclk->hw); -+ if (!IS_ERR(clk)) { -+ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -+ clk); -+ } else { -+ dev_err(dev, "Fail to register clock driver\n"); -+ kfree(proclk); -+ ret = PTR_ERR(clk); -+ } -+ return ret; -+} -+ -+static int clk_hifiberry_dacpro_remove(struct platform_device *pdev) -+{ -+ of_clk_del_provider(pdev->dev.of_node); -+ return 0; -+} -+ -+static struct platform_driver clk_hifiberry_dacpro_driver = { -+ .probe = clk_hifiberry_dacpro_probe, -+ .remove = clk_hifiberry_dacpro_remove, -+ .driver = { -+ .name = "clk-hifiberry-dacpro", -+ .of_match_table = clk_hifiberry_dacpro_dt_ids, -+ }, -+}; -+ -+static int __init clk_hifiberry_dacpro_init(void) -+{ -+ return platform_driver_register(&clk_hifiberry_dacpro_driver); -+} -+core_initcall(clk_hifiberry_dacpro_init); -+ -+static void __exit clk_hifiberry_dacpro_exit(void) -+{ -+ platform_driver_unregister(&clk_hifiberry_dacpro_driver); -+} -+module_exit(clk_hifiberry_dacpro_exit); -+ -+MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:clk-hifiberry-dacpro"); -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 11e4f39..a6b651c 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -1,8 +1,8 @@ - /* -- * ASoC Driver for HiFiBerry DAC+ -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro - * -- * Author: Daniel Matuschek -- * Copyright 2014 -+ * Author: Daniel Matuschek, Stuart MacLean -+ * Copyright 2014-2015 - * based on code by Florian Meier - * - * This program is free software; you can redistribute it and/or -@@ -17,6 +17,13 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #include - #include -@@ -26,34 +33,222 @@ - - #include "../codecs/pcm512x.h" - -+#define HIFIBERRY_DACPRO_NOCLOCK 0 -+#define HIFIBERRY_DACPRO_CLK44EN 1 -+#define HIFIBERRY_DACPRO_CLK48EN 2 -+ -+struct pcm512x_priv { -+ struct regmap *regmap; -+ struct clk *sclk; -+}; -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+static bool snd_rpi_hifiberry_is_dacpro; -+ -+static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, -+ int clk_id) -+{ -+ switch (clk_id) { -+ case HIFIBERRY_DACPRO_NOCLOCK: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); -+ break; -+ case HIFIBERRY_DACPRO_CLK44EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); -+ break; -+ case HIFIBERRY_DACPRO_CLK48EN: -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); -+ break; -+ } -+} -+ -+static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec) -+{ -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec) -+{ -+ int sck; -+ -+ sck = snd_soc_read(codec, PCM512x_RATE_DET_4); -+ return (!(sck & 0x40)); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( -+ struct snd_soc_codec *codec) -+{ -+ msleep(2); -+ return snd_rpi_hifiberry_dacplus_is_sclk(codec); -+} -+ -+static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec) -+{ -+ bool isClk44EN, isClk48En, isNoClk; -+ -+ snd_rpi_hifiberry_dacplus_clk_gpio(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN); -+ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK); -+ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN); -+ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec); -+ -+ return (isClk44EN && isClk48En && !isNoClk); -+} -+ -+static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate) -+{ -+ int type; -+ -+ switch (sample_rate) { -+ case 11025: -+ case 22050: -+ case 44100: -+ case 88200: -+ case 176400: -+ type = HIFIBERRY_DACPRO_CLK44EN; -+ break; -+ default: -+ type = HIFIBERRY_DACPRO_CLK48EN; -+ break; -+ } -+ return type; -+} -+ -+static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec, -+ int sample_rate) -+{ -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ -+ if (!IS_ERR(pcm512x->sclk)) { -+ int ctype; -+ -+ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate); -+ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) -+ ? CLK_44EN_RATE : CLK_48EN_RATE); -+ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype); -+ } -+} -+ - static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - { - struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *priv; -+ -+ snd_rpi_hifiberry_is_dacpro -+ = snd_rpi_hifiberry_dacplus_is_pro_card(codec); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_dai_link *dai = rtd->dai_link; -+ -+ dai->name = "HiFiBerry DAC+ Pro"; -+ dai->stream_name = "HiFiBerry DAC+ Pro HiFi"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBM_CFM; -+ -+ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); -+ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03); -+ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); -+ } else { -+ priv = snd_soc_codec_get_drvdata(codec); -+ priv->sclk = ERR_PTR(-ENOENT); -+ } -+ - snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -- snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_update_rate_den( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); -+ struct snd_ratnum *rats_no_pll; -+ unsigned int num = 0, den = 0; -+ int err; -+ -+ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); -+ if (!rats_no_pll) -+ return -ENOMEM; -+ -+ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; -+ rats_no_pll->den_min = 1; -+ rats_no_pll->den_max = 128; -+ rats_no_pll->den_step = 1; -+ -+ err = snd_interval_ratnum(hw_param_interval(params, -+ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); -+ if (err >= 0 && den) { -+ params->rate_num = num; -+ params->rate_den = den; -+ } -+ -+ devm_kfree(rtd->dev, rats_no_pll); - return 0; - } - --static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params) -+static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro( -+ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params) - { -+ int bratio = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio); -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ int ret; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ snd_rpi_hifiberry_dacplus_set_sclk(codec, -+ params_rate(params)); -+ -+ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai, -+ params); -+ if (!ret) -+ ret = snd_rpi_hifiberry_dacplus_update_rate_den( -+ substream, params); -+ } else { -+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ } -+ return ret; - } - --static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+static int snd_rpi_hifiberry_dacplus_startup( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - return 0; - } - --static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+static void snd_rpi_hifiberry_dacplus_shutdown( -+ struct snd_pcm_substream *substream) -+{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; -- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+ -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); - } - - /* machine stream operations */ -@@ -90,19 +285,20 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -- - if (pdev->dev.of_node) { -- struct device_node *i2s_node; -- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -- i2s_node = of_parse_phandle(pdev->dev.of_node, -- "i2s-controller", 0); -- -- if (i2s_node) { -- dai->cpu_dai_name = NULL; -- dai->cpu_of_node = i2s_node; -- dai->platform_name = NULL; -- dai->platform_of_node = i2s_node; -- } -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c -index 047c489..090fe0e 100644 ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -854,7 +854,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai, - int fssp; - int gpio; - -- lrclk_div = snd_soc_params_to_frame_size(params); -+ lrclk_div = snd_pcm_format_physical_width(params_format(params)) -+ * params_channels(params); - if (lrclk_div == 0) { - dev_err(dev, "No LRCLK?\n"); - return -EINVAL; - -From 0ef9ae2d5aba6fea2fe0520a24296a8fa4b858e5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 5 Oct 2015 10:47:45 +0100 -Subject: [PATCH 106/251] BCM270X_DT: Add at86rf233 overlay - -Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0. - -See: https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 21 +++++++-- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 54 ++++++++++++++++++++++++ - 3 files changed, 72 insertions(+), 4 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 7d747bc..be9dead 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 422a0d4..d0ef256 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -69,13 +69,14 @@ DT parameters: - - Parameters always have default values, although in some cases (e.g. "w1-gpio") - it is necessary to provided multiple overlays in order to get the desired --behaviour. See the list of overlays below for a description of the parameters and their defaults. -+behaviour. See the list of overlays below for a description of the parameters -+and their defaults. - - The Overlay and Parameter Reference - =================================== - --N.B. When editing this file, please preserve the indentation levels to make it simple to parse --programmatically. NO HARD TABS. -+N.B. When editing this file, please preserve the indentation levels to make it -+simple to parse programmatically. NO HARD TABS. - - - Name: -@@ -149,7 +150,7 @@ Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= - Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) - penirq GPIO used for PENIRQ. REQUIRED - penirq_pull Set GPIO pull (default 0=none, 2=pullup) - swapxy Swap x and y axis -@@ -170,6 +171,18 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: at86rf233 -+Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, -+ connected to spi0.0 -+Load: dtoverlay=at86rf233,= -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 6000000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) -+ -+ - Name: bmp085_i2c-sensor - Info: Configures the BMP085/BMP180 digital barometric pressure and temperature - sensors from Bosch Sensortec -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -new file mode 100644 -index 0000000..0460269 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -0,0 +1,54 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ lowpan0: at86rf233@0 { -+ compatible = "atmel,at86rf233"; -+ reg = <0>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 4>; /* active high */ -+ reset-gpio = <&gpio 24 1>; -+ sleep-gpio = <&gpio 25 1>; -+ spi-max-frequency = <6000000>; -+ xtal-trim = /bits/ 8 <0xf>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lowpan0_pins: lowpan0_pins { -+ brcm,pins = <23 24 25>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&lowpan0>, "interrupts:0", -+ <&lowpan0_pins>, "brcm,pins:0"; -+ reset = <&lowpan0>, "reset-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:4"; -+ sleep = <&lowpan0>, "sleep-gpio:4", -+ <&lowpan0_pins>, "brcm,pins:8"; -+ speed = <&lowpan0>, "spi-max-frequency:0"; -+ trim = <&lowpan0>, "xtal-trim.0"; -+ }; -+}; - -From 45d717abcc94edabe07e5909f1d984a392198921 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 18 Dec 2014 16:07:15 -0800 -Subject: [PATCH 107/251] mm: Remove the PFN busy warning - -See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is -expected sometimes when using CMA. However, that commit still spams -my kernel log with these warnings. - -Signed-off-by: Eric Anholt ---- - mm/page_alloc.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index c69531a..dc484d3 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -6780,8 +6780,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, - - /* Make sure the range is really isolated. */ - if (test_pages_isolated(outer_start, end, false)) { -- pr_info("%s: [%lx, %lx) PFNs busy\n", -- __func__, outer_start, end); - ret = -EBUSY; - goto done; - } - -From 11a46a37a0da7f87fc9e278178f294047110f6ab Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 19 Nov 2014 12:06:38 -0800 -Subject: [PATCH 108/251] drm: Put an optional field in the driver struct for - GEM obj struct size. - -This allows a driver to derive from the CMA object without copying all -of the code. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_gem_cma_helper.c | 5 ++++- - include/drm/drmP.h | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index e109b49..1c25500 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -58,8 +58,11 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size) - struct drm_gem_cma_object *cma_obj; - struct drm_gem_object *gem_obj; - int ret; -+ size_t obj_size = (drm->driver->gem_obj_size ? -+ drm->driver->gem_obj_size : -+ sizeof(*cma_obj)); - -- cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); -+ cma_obj = kzalloc(obj_size, GFP_KERNEL); - if (!cma_obj) - return ERR_PTR(-ENOMEM); - -diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 0a271ca..54f5469 100644 ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -639,6 +639,7 @@ struct drm_driver { - - u32 driver_features; - int dev_priv_size; -+ size_t gem_obj_size; - const struct drm_ioctl_desc *ioctls; - int num_ioctls; - const struct file_operations *fops; - -From b28efa9d1051537449004db1bfaf083429144d1b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 30 Oct 2015 10:09:02 -0700 -Subject: [PATCH 109/251] drm/vc4: Add an interface for capturing the GPU state - after a hang. - -This can be parsed with vc4-gpu-tools tools for trying to figure out -what was going on. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 4 +- - drivers/gpu/drm/vc4/vc4_drv.c | 1 + - drivers/gpu/drm/vc4/vc4_drv.h | 4 + - drivers/gpu/drm/vc4/vc4_gem.c | 185 ++++++++++++++++++++++++++++++++++++++++++ - include/uapi/drm/vc4_drm.h | 45 ++++++++++ - 5 files changed, 237 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index acd360c..58dcbae 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -415,8 +415,8 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma) - gem_obj = vma->vm_private_data; - bo = to_vc4_bo(gem_obj); - -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); - return -EINVAL; - } - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index e2a2be2..e8192b4 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -81,6 +81,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), -+ DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, DRM_ROOT_ONLY), - }; - - static struct drm_driver vc4_drm_driver = { -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index c079b82..24845c1 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -20,6 +20,8 @@ struct vc4_dev { - struct drm_fbdev_cma *fbdev; - struct rpi_firmware *firmware; - -+ struct vc4_hang_state *hang_state; -+ - /* The kernel-space BO cache. Tracks buffers that have been - * unreferenced by all other users (refcounts of 0!) but not - * yet freed, so we can do cheap allocations. -@@ -366,6 +368,8 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -+int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); - int vc4_mmap(struct file *filp, struct vm_area_struct *vma); - int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); - void *vc4_prime_vmap(struct drm_gem_object *obj); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 0cea723..d90c664 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -40,6 +40,186 @@ vc4_queue_hangcheck(struct drm_device *dev) - round_jiffies_up(jiffies + msecs_to_jiffies(100))); - } - -+struct vc4_hang_state { -+ struct drm_vc4_get_hang_state user_state; -+ -+ u32 bo_count; -+ struct drm_gem_object **bo; -+}; -+ -+static void -+vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) -+{ -+ unsigned int i; -+ -+ mutex_lock(&dev->struct_mutex); -+ for (i = 0; i < state->user_state.bo_count; i++) { -+ drm_gem_object_unreference(state->bo[i]); -+ } -+ mutex_unlock(&dev->struct_mutex); -+ -+ kfree(state); -+} -+ -+int -+vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_get_hang_state *get_state = data; -+ struct drm_vc4_get_hang_state_bo *bo_state; -+ struct vc4_hang_state *kernel_state; -+ struct drm_vc4_get_hang_state *state; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ unsigned long irqflags; -+ u32 i; -+ int ret; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ kernel_state = vc4->hang_state; -+ if (!kernel_state) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return -ENOENT; -+ } -+ state = &kernel_state->user_state; -+ -+ /* If the user's array isn't big enough, just return the -+ * required array size. -+ */ -+ if (get_state->bo_count < state->bo_count) { -+ get_state->bo_count = state->bo_count; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return 0; -+ } -+ -+ vc4->hang_state = NULL; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ /* Save the user's BO pointer, so we don't stomp it with the memcpy. */ -+ state->bo = get_state->bo; -+ memcpy(get_state, state, sizeof(*state)); -+ -+ bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL); -+ if (!bo_state) { -+ ret = -ENOMEM; -+ goto err_free; -+ } -+ -+ for (i = 0; i < state->bo_count; i++) { -+ struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]); -+ u32 handle; -+ ret = drm_gem_handle_create(file_priv, kernel_state->bo[i], -+ &handle); -+ -+ if (ret) { -+ state->bo_count = i - 1; -+ goto err; -+ } -+ bo_state[i].handle = handle; -+ bo_state[i].paddr = vc4_bo->base.paddr; -+ bo_state[i].size = vc4_bo->base.base.size; -+ } -+ -+ ret = copy_to_user((void __user *)(uintptr_t)get_state->bo, -+ bo_state, -+ state->bo_count * sizeof(*bo_state)); -+ kfree(bo_state); -+ -+ err_free: -+ -+ vc4_free_hang_state(dev, kernel_state); -+ -+err: -+ return ret; -+} -+ -+static void -+vc4_save_hang_state(struct drm_device *dev) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_vc4_get_hang_state *state; -+ struct vc4_hang_state *kernel_state; -+ struct vc4_exec_info *exec; -+ struct vc4_bo *bo; -+ unsigned long irqflags; -+ unsigned int i, unref_list_count; -+ -+ kernel_state = kcalloc(1, sizeof(*state), GFP_KERNEL); -+ if (!kernel_state) -+ return; -+ -+ state = &kernel_state->user_state; -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ exec = vc4_first_job(vc4); -+ if (!exec) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return; -+ } -+ -+ unref_list_count = 0; -+ list_for_each_entry(bo, &exec->unref_list, unref_head) -+ unref_list_count++; -+ -+ state->bo_count = exec->bo_count + unref_list_count; -+ kernel_state->bo = kcalloc(state->bo_count, sizeof(*kernel_state->bo), -+ GFP_ATOMIC); -+ if (!kernel_state->bo) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ return; -+ } -+ -+ for (i = 0; i < exec->bo_count; i++) { -+ drm_gem_object_reference(&exec->bo[i].bo->base); -+ kernel_state->bo[i] = &exec->bo[i].bo->base; -+ } -+ -+ list_for_each_entry(bo, &exec->unref_list, unref_head) { -+ drm_gem_object_reference(&bo->base.base); -+ kernel_state->bo[i] = &bo->base.base; -+ i++; -+ } -+ -+ state->start_bin = exec->ct0ca; -+ state->start_render = exec->ct1ca; -+ -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ -+ state->ct0ca = V3D_READ(V3D_CTNCA(0)); -+ state->ct0ea = V3D_READ(V3D_CTNEA(0)); -+ -+ state->ct1ca = V3D_READ(V3D_CTNCA(1)); -+ state->ct1ea = V3D_READ(V3D_CTNEA(1)); -+ -+ state->ct0cs = V3D_READ(V3D_CTNCS(0)); -+ state->ct1cs = V3D_READ(V3D_CTNCS(1)); -+ -+ state->ct0ra0 = V3D_READ(V3D_CT00RA0); -+ state->ct1ra0 = V3D_READ(V3D_CT01RA0); -+ -+ state->bpca = V3D_READ(V3D_BPCA); -+ state->bpcs = V3D_READ(V3D_BPCS); -+ state->bpoa = V3D_READ(V3D_BPOA); -+ state->bpos = V3D_READ(V3D_BPOS); -+ -+ state->vpmbase = V3D_READ(V3D_VPMBASE); -+ -+ state->dbge = V3D_READ(V3D_DBGE); -+ state->fdbgo = V3D_READ(V3D_FDBGO); -+ state->fdbgb = V3D_READ(V3D_FDBGB); -+ state->fdbgr = V3D_READ(V3D_FDBGR); -+ state->fdbgs = V3D_READ(V3D_FDBGS); -+ state->errstat = V3D_READ(V3D_ERRSTAT); -+ -+ spin_lock_irqsave(&vc4->job_lock, irqflags); -+ if (vc4->hang_state) { -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ vc4_free_hang_state(dev, kernel_state); -+ } else { -+ vc4->hang_state = kernel_state; -+ spin_unlock_irqrestore(&vc4->job_lock, irqflags); -+ } -+} -+ - static void - vc4_reset(struct drm_device *dev) - { -@@ -64,6 +244,8 @@ vc4_reset_work(struct work_struct *work) - struct vc4_dev *vc4 = - container_of(work, struct vc4_dev, hangcheck.reset_work); - -+ vc4_save_hang_state(vc4->dev); -+ - vc4_reset(vc4->dev); - } - -@@ -673,4 +855,7 @@ vc4_gem_destroy(struct drm_device *dev) - } - - vc4_bo_cache_destroy(dev); -+ -+ if (vc4->hang_state) -+ vc4_free_hang_state(dev, vc4->hang_state); - } -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 499daae..4a8d19f 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -32,6 +32,7 @@ - #define DRM_VC4_CREATE_BO 0x03 - #define DRM_VC4_MMAP_BO 0x04 - #define DRM_VC4_CREATE_SHADER_BO 0x05 -+#define DRM_VC4_GET_HANG_STATE 0x06 - - #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) - #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -@@ -39,6 +40,7 @@ - #define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) - #define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) - #define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) - - struct drm_vc4_submit_rcl_surface { - uint32_t hindex; /* Handle index, or ~0 if not present. */ -@@ -226,4 +228,47 @@ struct drm_vc4_mmap_bo { - uint64_t offset; - }; - -+struct drm_vc4_get_hang_state_bo { -+ uint32_t handle; -+ uint32_t paddr; -+ uint32_t size; -+ uint32_t pad; -+}; -+ -+/** -+ * struct drm_vc4_hang_state - ioctl argument for collecting state -+ * from a GPU hang for analysis. -+*/ -+struct drm_vc4_get_hang_state { -+ /** Pointer to array of struct drm_vc4_get_hang_state_bo. */ -+ uint64_t bo; -+ /** -+ * On input, the size of the bo array. Output is the number -+ * of bos to be returned. -+ */ -+ uint32_t bo_count; -+ -+ uint32_t start_bin, start_render; -+ -+ uint32_t ct0ca, ct0ea; -+ uint32_t ct1ca, ct1ea; -+ uint32_t ct0cs, ct1cs; -+ uint32_t ct0ra0, ct1ra0; -+ -+ uint32_t bpca, bpcs; -+ uint32_t bpoa, bpos; -+ -+ uint32_t vpmbase; -+ -+ uint32_t dbge; -+ uint32_t fdbgo; -+ uint32_t fdbgb; -+ uint32_t fdbgr; -+ uint32_t fdbgs; -+ uint32_t errstat; -+ -+ /* Pad that we may save more registers into in the future. */ -+ uint32_t pad[16]; -+}; -+ - #endif /* _UAPI_VC4_DRM_H_ */ - -From 341ad4b0afa7154311296be071b39f42f18fe228 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 4 Dec 2015 11:35:34 -0800 -Subject: [PATCH 110/251] drm/vc4: Update a bunch of code to match upstream - submission. - -This gets almost everything matching, except for the MSAA support and -using generic PM domains. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_gem_cma_helper.c | 13 +- - drivers/gpu/drm/vc4/vc4_bo.c | 322 +++++++++++++++++------------ - drivers/gpu/drm/vc4/vc4_crtc.c | 7 +- - drivers/gpu/drm/vc4/vc4_drv.c | 6 +- - drivers/gpu/drm/vc4/vc4_drv.h | 20 +- - drivers/gpu/drm/vc4/vc4_gem.c | 24 ++- - drivers/gpu/drm/vc4/vc4_irq.c | 5 +- - drivers/gpu/drm/vc4/vc4_kms.c | 1 + - drivers/gpu/drm/vc4/vc4_packet.h | 210 +++++++++---------- - drivers/gpu/drm/vc4/vc4_qpu_defines.h | 308 ++++++++++++++------------- - drivers/gpu/drm/vc4/vc4_render_cl.c | 4 +- - drivers/gpu/drm/vc4/vc4_v3d.c | 10 +- - drivers/gpu/drm/vc4/vc4_validate.c | 130 ++++++------ - drivers/gpu/drm/vc4/vc4_validate_shaders.c | 66 +++--- - include/drm/drmP.h | 8 +- - 15 files changed, 598 insertions(+), 536 deletions(-) - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index 1c25500..0f7b00b 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -58,15 +58,14 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size) - struct drm_gem_cma_object *cma_obj; - struct drm_gem_object *gem_obj; - int ret; -- size_t obj_size = (drm->driver->gem_obj_size ? -- drm->driver->gem_obj_size : -- sizeof(*cma_obj)); - -- cma_obj = kzalloc(obj_size, GFP_KERNEL); -- if (!cma_obj) -+ if (drm->driver->gem_create_object) -+ gem_obj = drm->driver->gem_create_object(drm, size); -+ else -+ gem_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); -+ if (!gem_obj) - return ERR_PTR(-ENOMEM); -- -- gem_obj = &cma_obj->base; -+ cma_obj = container_of(gem_obj, struct drm_gem_cma_object, base); - - ret = drm_gem_object_init(drm, gem_obj, size); - if (ret) -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index 58dcbae..6247ff8 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -12,6 +12,10 @@ - * access to system memory with no MMU in between. To support it, we - * use the GEM CMA helper functions to allocate contiguous ranges of - * physical memory for our BOs. -+ * -+ * Since the CMA allocator is very slow, we keep a cache of recently -+ * freed BOs around so that the kernel's allocation of objects for 3D -+ * rendering can return quickly. - */ - - #include "vc4_drv.h" -@@ -34,6 +38,36 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4) - vc4->bo_stats.size_cached / 1024); - } - -+#ifdef CONFIG_DEBUG_FS -+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *)m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo_stats stats; -+ -+ /* Take a snapshot of the current stats with the lock held. */ -+ mutex_lock(&vc4->bo_lock); -+ stats = vc4->bo_stats; -+ mutex_unlock(&vc4->bo_lock); -+ -+ seq_printf(m, "num bos allocated: %d\n", -+ stats.num_allocated); -+ seq_printf(m, "size bos allocated: %dkb\n", -+ stats.size_allocated / 1024); -+ seq_printf(m, "num bos used: %d\n", -+ stats.num_allocated - stats.num_cached); -+ seq_printf(m, "size bos used: %dkb\n", -+ (stats.size_allocated - stats.size_cached) / 1024); -+ seq_printf(m, "num bos cached: %d\n", -+ stats.num_cached); -+ seq_printf(m, "size bos cached: %dkb\n", -+ stats.size_cached / 1024); -+ -+ return 0; -+} -+#endif -+ - static uint32_t bo_page_index(size_t size) - { - return (size / PAGE_SIZE) - 1; -@@ -81,8 +115,8 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, - struct list_head *new_list; - uint32_t i; - -- new_list = kmalloc(new_size * sizeof(struct list_head), -- GFP_KERNEL); -+ new_list = kmalloc_array(new_size, sizeof(struct list_head), -+ GFP_KERNEL); - if (!new_list) - return NULL; - -@@ -90,7 +124,9 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, - * head locations. - */ - for (i = 0; i < vc4->bo_cache.size_list_size; i++) { -- struct list_head *old_list = &vc4->bo_cache.size_list[i]; -+ struct list_head *old_list = -+ &vc4->bo_cache.size_list[i]; -+ - if (list_empty(old_list)) - INIT_LIST_HEAD(&new_list[i]); - else -@@ -122,11 +158,60 @@ void vc4_bo_cache_purge(struct drm_device *dev) - mutex_unlock(&vc4->bo_lock); - } - --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) -+static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev, -+ uint32_t size) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -- uint32_t size = roundup(unaligned_size, PAGE_SIZE); - uint32_t page_index = bo_page_index(size); -+ struct vc4_bo *bo = NULL; -+ -+ size = roundup(size, PAGE_SIZE); -+ -+ mutex_lock(&vc4->bo_lock); -+ if (page_index >= vc4->bo_cache.size_list_size) -+ goto out; -+ -+ if (list_empty(&vc4->bo_cache.size_list[page_index])) -+ goto out; -+ -+ bo = list_first_entry(&vc4->bo_cache.size_list[page_index], -+ struct vc4_bo, size_head); -+ vc4_bo_remove_from_cache(bo); -+ kref_init(&bo->base.base.refcount); -+ -+out: -+ mutex_unlock(&vc4->bo_lock); -+ return bo; -+} -+ -+/** -+ * vc4_gem_create_object - Implementation of driver->gem_create_object. -+ * -+ * This lets the CMA helpers allocate object structs for us, and keep -+ * our BO stats correct. -+ */ -+struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_bo *bo; -+ -+ bo = kzalloc(sizeof(*bo), GFP_KERNEL); -+ if (!bo) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_lock(&vc4->bo_lock); -+ vc4->bo_stats.num_allocated++; -+ vc4->bo_stats.size_allocated += size; -+ mutex_unlock(&vc4->bo_lock); -+ -+ return &bo->base.base; -+} -+ -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, -+ bool from_cache) -+{ -+ size_t size = roundup(unaligned_size, PAGE_SIZE); -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_gem_cma_object *cma_obj; - int pass; - -@@ -134,18 +219,12 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - return NULL; - - /* First, try to get a vc4_bo from the kernel BO cache. */ -- mutex_lock(&vc4->bo_lock); -- if (page_index < vc4->bo_cache.size_list_size && -- !list_empty(&vc4->bo_cache.size_list[page_index])) { -- struct vc4_bo *bo = -- list_first_entry(&vc4->bo_cache.size_list[page_index], -- struct vc4_bo, size_head); -- vc4_bo_remove_from_cache(bo); -- mutex_unlock(&vc4->bo_lock); -- kref_init(&bo->base.base.refcount); -- return bo; -+ if (from_cache) { -+ struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size); -+ -+ if (bo) -+ return bo; - } -- mutex_unlock(&vc4->bo_lock); - - /* Otherwise, make a new BO. */ - for (pass = 0; ; pass++) { -@@ -179,9 +258,6 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size) - } - } - -- vc4->bo_stats.num_allocated++; -- vc4->bo_stats.size_allocated += size; -- - return to_vc4_bo(&cma_obj->base); - } - -@@ -199,7 +275,7 @@ int vc4_dumb_create(struct drm_file *file_priv, - if (args->size < args->pitch * args->height) - args->size = args->pitch * args->height; - -- bo = vc4_bo_create(dev, args->size); -+ bo = vc4_bo_create(dev, args->size, false); - if (!bo) - return -ENOMEM; - -@@ -209,8 +285,8 @@ int vc4_dumb_create(struct drm_file *file_priv, - return ret; - } - --static void --vc4_bo_cache_free_old(struct drm_device *dev) -+/* Must be called with bo_lock held. */ -+static void vc4_bo_cache_free_old(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long expire_time = jiffies - msecs_to_jiffies(1000); -@@ -313,15 +389,77 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) - return drm_gem_prime_export(dev, obj, flags); - } - --int --vc4_create_bo_ioctl(struct drm_device *dev, void *data, -- struct drm_file *file_priv) -+int vc4_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct drm_gem_object *gem_obj; -+ struct vc4_bo *bo; -+ int ret; -+ -+ ret = drm_gem_mmap(filp, vma); -+ if (ret) -+ return ret; -+ -+ gem_obj = vma->vm_private_data; -+ bo = to_vc4_bo(gem_obj); -+ -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -+ * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -+ * the whole buffer. -+ */ -+ vma->vm_flags &= ~VM_PFNMAP; -+ vma->vm_pgoff = 0; -+ -+ ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -+ bo->base.vaddr, bo->base.paddr, -+ vma->vm_end - vma->vm_start); -+ if (ret) -+ drm_gem_vm_close(vma); -+ -+ return ret; -+} -+ -+int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -+ DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -+ return -EINVAL; -+ } -+ -+ return drm_gem_cma_prime_mmap(obj, vma); -+} -+ -+void *vc4_prime_vmap(struct drm_gem_object *obj) -+{ -+ struct vc4_bo *bo = to_vc4_bo(obj); -+ -+ if (bo->validated_shader) { -+ DRM_ERROR("mmaping of shader BOs not allowed.\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return drm_gem_cma_prime_vmap(obj); -+} -+ -+int vc4_create_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) - { - struct drm_vc4_create_bo *args = data; - struct vc4_bo *bo = NULL; - int ret; - -- bo = vc4_bo_create(dev, args->size); -+ /* -+ * We can't allocate from the BO cache, because the BOs don't -+ * get zeroed, and that might leak data between users. -+ */ -+ bo = vc4_bo_create(dev, args->size, false); - if (!bo) - return -ENOMEM; - -@@ -331,6 +469,25 @@ vc4_create_bo_ioctl(struct drm_device *dev, void *data, - return ret; - } - -+int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct drm_vc4_mmap_bo *args = data; -+ struct drm_gem_object *gem_obj; -+ -+ gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -+ if (!gem_obj) { -+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -+ return -EINVAL; -+ } -+ -+ /* The mmap offset was set up at BO allocation time. */ -+ args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -+ -+ drm_gem_object_unreference_unlocked(gem_obj); -+ return 0; -+} -+ - int - vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -@@ -355,7 +512,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - return -EINVAL; - } - -- bo = vc4_bo_create(dev, args->size); -+ bo = vc4_bo_create(dev, args->size, true); - if (!bo) - return -ENOMEM; - -@@ -364,6 +521,11 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - args->size); - if (ret != 0) - goto fail; -+ /* Clear the rest of the memory from allocating from the BO -+ * cache. -+ */ -+ memset(bo->base.vaddr + args->size, 0, -+ bo->base.base.size - args->size); - - bo->validated_shader = vc4_validate_shader(&bo->base); - if (!bo->validated_shader) { -@@ -382,85 +544,6 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - return ret; - } - --int --vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, -- struct drm_file *file_priv) --{ -- struct drm_vc4_mmap_bo *args = data; -- struct drm_gem_object *gem_obj; -- -- gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); -- if (!gem_obj) { -- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); -- return -EINVAL; -- } -- -- /* The mmap offset was set up at BO allocation time. */ -- args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -- -- drm_gem_object_unreference(gem_obj); -- return 0; --} -- --int vc4_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- struct drm_gem_object *gem_obj; -- struct vc4_bo *bo; -- int ret; -- -- ret = drm_gem_mmap(filp, vma); -- if (ret) -- return ret; -- -- gem_obj = vma->vm_private_data; -- bo = to_vc4_bo(gem_obj); -- -- if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) { -- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n"); -- return -EINVAL; -- } -- -- /* -- * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the -- * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map -- * the whole buffer. -- */ -- vma->vm_flags &= ~VM_PFNMAP; -- vma->vm_pgoff = 0; -- -- ret = dma_mmap_writecombine(bo->base.base.dev->dev, vma, -- bo->base.vaddr, bo->base.paddr, -- vma->vm_end - vma->vm_start); -- if (ret) -- drm_gem_vm_close(vma); -- -- return ret; --} -- --int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) --{ -- struct vc4_bo *bo = to_vc4_bo(obj); -- -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -- return -EINVAL; -- } -- -- return drm_gem_cma_prime_mmap(obj, vma); --} -- --void *vc4_prime_vmap(struct drm_gem_object *obj) --{ -- struct vc4_bo *bo = to_vc4_bo(obj); -- -- if (bo->validated_shader) { -- DRM_ERROR("mmaping of shader BOs not allowed.\n"); -- return ERR_PTR(-EINVAL); -- } -- -- return drm_gem_cma_prime_vmap(obj); --} -- - void vc4_bo_cache_init(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -@@ -472,7 +555,7 @@ void vc4_bo_cache_init(struct drm_device *dev) - INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); - setup_timer(&vc4->bo_cache.time_timer, - vc4_bo_cache_time_timer, -- (unsigned long) dev); -+ (unsigned long)dev); - } - - void vc4_bo_cache_destroy(struct drm_device *dev) -@@ -489,28 +572,3 @@ void vc4_bo_cache_destroy(struct drm_device *dev) - vc4_bo_stats_dump(vc4); - } - } -- --#ifdef CONFIG_DEBUG_FS --int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct vc4_bo_stats stats; -- -- mutex_lock(&vc4->bo_lock); -- stats = vc4->bo_stats; -- mutex_unlock(&vc4->bo_lock); -- -- seq_printf(m, "num bos allocated: %d\n", stats.num_allocated); -- seq_printf(m, "size bos allocated: %dkb\n", stats.size_allocated / 1024); -- seq_printf(m, "num bos used: %d\n", (stats.num_allocated - -- stats.num_cached)); -- seq_printf(m, "size bos used: %dkb\n", (stats.size_allocated - -- stats.size_cached) / 1024); -- seq_printf(m, "num bos cached: %d\n", stats.num_cached); -- seq_printf(m, "size bos cached: %dkb\n", stats.size_cached / 1024); -- -- return 0; --} --#endif -diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c -index 3be2720..3c67914 100644 ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -501,6 +501,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) - vc4_plane_async_set_fb(plane, flip_state->fb); - if (flip_state->event) { - unsigned long flags; -+ - spin_lock_irqsave(&dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, flip_state->event); - spin_unlock_irqrestore(&dev->event_lock, flags); -@@ -562,9 +563,9 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, - } - - static int vc4_page_flip(struct drm_crtc *crtc, -- struct drm_framebuffer *fb, -- struct drm_pending_vblank_event *event, -- uint32_t flags) -+ struct drm_framebuffer *fb, -+ struct drm_pending_vblank_event *event, -+ uint32_t flags) - { - if (flags & DRM_MODE_PAGE_FLIP_ASYNC) - return vc4_async_page_flip(crtc, fb, event, flags); -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index e8192b4..22061ae 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -81,7 +81,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), - DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), -- DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, DRM_ROOT_ONLY), -+ DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, -+ DRM_ROOT_ONLY), - }; - - static struct drm_driver vc4_drm_driver = { -@@ -107,6 +108,7 @@ static struct drm_driver vc4_drm_driver = { - .debugfs_cleanup = vc4_debugfs_cleanup, - #endif - -+ .gem_create_object = vc4_create_object, - .gem_free_object = vc4_free_object, - .gem_vm_ops = &drm_gem_cma_vm_ops, - -@@ -128,8 +130,6 @@ static struct drm_driver vc4_drm_driver = { - .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), - .fops = &vc4_drm_fops, - -- //.gem_obj_size = sizeof(struct vc4_bo), -- - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 24845c1..53dfa8d 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -72,6 +72,9 @@ struct vc4_dev { - * job_done_work. - */ - struct list_head job_done_list; -+ /* Spinlock used to synchronize the job_list and seqno -+ * accesses between the IRQ handler and GEM ioctls. -+ */ - spinlock_t job_lock; - wait_queue_head_t job_wait_queue; - struct work_struct job_done_work; -@@ -318,8 +321,7 @@ struct vc4_texture_sample_info { - * and validate the shader state record's uniforms that define the texture - * samples. - */ --struct vc4_validated_shader_info --{ -+struct vc4_validated_shader_info { - uint32_t uniforms_size; - uint32_t uniforms_src_size; - uint32_t num_texture_samples; -@@ -355,8 +357,10 @@ struct vc4_validated_shader_info - #define wait_for(COND, MS) _wait_for(COND, MS, 1) - - /* vc4_bo.c */ -+struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); - void vc4_free_object(struct drm_gem_object *gem_obj); --struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size); -+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, -+ bool from_cache); - int vc4_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); -@@ -432,7 +436,8 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, - enum drm_plane_type type); - u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); - u32 vc4_plane_dlist_size(struct drm_plane_state *state); --void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb); -+void vc4_plane_async_set_fb(struct drm_plane *plane, -+ struct drm_framebuffer *fb); - - /* vc4_v3d.c */ - extern struct platform_driver vc4_v3d_driver; -@@ -450,9 +455,6 @@ vc4_validate_bin_cl(struct drm_device *dev, - int - vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); - --struct vc4_validated_shader_info * --vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -- - bool vc4_use_bo(struct vc4_exec_info *exec, - uint32_t hindex, - enum vc4_bo_mode mode, -@@ -464,3 +466,7 @@ bool vc4_check_tex_size(struct vc4_exec_info *exec, - struct drm_gem_cma_object *fbo, - uint32_t offset, uint8_t tiling_format, - uint32_t width, uint32_t height, uint8_t cpp); -+ -+/* vc4_validate_shader.c */ -+struct vc4_validated_shader_info * -+vc4_validate_shader(struct drm_gem_cma_object *shader_obj); -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index d90c664..fb0b92d 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -53,9 +53,8 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) - unsigned int i; - - mutex_lock(&dev->struct_mutex); -- for (i = 0; i < state->user_state.bo_count; i++) { -+ for (i = 0; i < state->user_state.bo_count; i++) - drm_gem_object_unreference(state->bo[i]); -- } - mutex_unlock(&dev->struct_mutex); - - kfree(state); -@@ -65,10 +64,10 @@ int - vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -- struct drm_vc4_get_hang_state *get_state = data; -+ struct drm_vc4_get_hang_state *get_state = data; - struct drm_vc4_get_hang_state_bo *bo_state; - struct vc4_hang_state *kernel_state; -- struct drm_vc4_get_hang_state *state; -+ struct drm_vc4_get_hang_state *state; - struct vc4_dev *vc4 = to_vc4_dev(dev); - unsigned long irqflags; - u32 i; -@@ -107,6 +106,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - for (i = 0; i < state->bo_count; i++) { - struct vc4_bo *vc4_bo = to_vc4_bo(kernel_state->bo[i]); - u32 handle; -+ - ret = drm_gem_handle_create(file_priv, kernel_state->bo[i], - &handle); - -@@ -124,7 +124,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, - state->bo_count * sizeof(*bo_state)); - kfree(bo_state); - -- err_free: -+err_free: - - vc4_free_hang_state(dev, kernel_state); - -@@ -578,7 +578,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - goto fail; - } - -- bo = vc4_bo_create(dev, exec_size); -+ bo = vc4_bo_create(dev, exec_size, true); - if (!bo) { - DRM_ERROR("Couldn't allocate BO for binning\n"); - ret = PTR_ERR(exec->exec_bo); -@@ -668,6 +668,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) - static void vc4_seqno_cb_work(struct work_struct *work) - { - struct vc4_seqno_cb *cb = container_of(work, struct vc4_seqno_cb, work); -+ - cb->func(cb); - } - -@@ -717,6 +718,7 @@ vc4_wait_for_seqno_ioctl_helper(struct drm_device *dev, - - if ((ret == -EINTR || ret == -ERESTARTSYS) && *timeout_ns != ~0ull) { - uint64_t delta = jiffies_to_nsecs(jiffies - start); -+ - if (*timeout_ns >= delta) - *timeout_ns -= delta; - } -@@ -750,9 +752,10 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, - } - bo = to_vc4_bo(gem_obj); - -- ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, &args->timeout_ns); -+ ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno, -+ &args->timeout_ns); - -- drm_gem_object_unreference(gem_obj); -+ drm_gem_object_unreference_unlocked(gem_obj); - return ret; - } - -@@ -793,7 +796,8 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, - if (ret) - goto fail; - } else { -- exec->ct0ca = exec->ct0ea = 0; -+ exec->ct0ca = 0; -+ exec->ct0ea = 0; - } - - ret = vc4_get_rcl(dev, exec); -@@ -831,7 +835,7 @@ vc4_gem_init(struct drm_device *dev) - INIT_WORK(&vc4->hangcheck.reset_work, vc4_reset_work); - setup_timer(&vc4->hangcheck.timer, - vc4_hangcheck_elapsed, -- (unsigned long) dev); -+ (unsigned long)dev); - - INIT_WORK(&vc4->job_done_work, vc4_job_done_work); - } -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -index f29b796..b68060e 100644 ---- a/drivers/gpu/drm/vc4/vc4_irq.c -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -56,7 +56,7 @@ vc4_overflow_mem_work(struct work_struct *work) - struct drm_device *dev = vc4->dev; - struct vc4_bo *bo; - -- bo = vc4_bo_create(dev, 256 * 1024); -+ bo = vc4_bo_create(dev, 256 * 1024, true); - if (!bo) { - DRM_ERROR("Couldn't allocate binner overflow mem\n"); - return; -@@ -87,9 +87,8 @@ vc4_overflow_mem_work(struct work_struct *work) - spin_unlock_irqrestore(&vc4->job_lock, irqflags); - } - -- if (vc4->overflow_mem) { -+ if (vc4->overflow_mem) - drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); -- } - vc4->overflow_mem = bo; - - V3D_WRITE(V3D_BPOA, bo->base.paddr); -diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c -index 2082713..f95f2df 100644 ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -132,6 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev, - struct drm_gem_cma_object *cma_bo = - drm_fb_cma_get_gem_obj(new_state->fb, 0); - struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ - wait_seqno = max(bo->seqno, wait_seqno); - } - } -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -index 9757bc8..cee38aa 100644 ---- a/drivers/gpu/drm/vc4/vc4_packet.h -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -27,60 +27,60 @@ - #include "vc4_regs.h" /* for VC4_MASK, VC4_GET_FIELD, VC4_SET_FIELD */ - - enum vc4_packet { -- VC4_PACKET_HALT = 0, -- VC4_PACKET_NOP = 1, -- -- VC4_PACKET_FLUSH = 4, -- VC4_PACKET_FLUSH_ALL = 5, -- VC4_PACKET_START_TILE_BINNING = 6, -- VC4_PACKET_INCREMENT_SEMAPHORE = 7, -- VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -- -- VC4_PACKET_BRANCH = 16, -- VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -- -- VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -- VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -- VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -- VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -- VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -- VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -- -- VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -- VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -- -- VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -- VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -- -- VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -- -- VC4_PACKET_GL_SHADER_STATE = 64, -- VC4_PACKET_NV_SHADER_STATE = 65, -- VC4_PACKET_VG_SHADER_STATE = 66, -- -- VC4_PACKET_CONFIGURATION_BITS = 96, -- VC4_PACKET_FLAT_SHADE_FLAGS = 97, -- VC4_PACKET_POINT_SIZE = 98, -- VC4_PACKET_LINE_WIDTH = 99, -- VC4_PACKET_RHT_X_BOUNDARY = 100, -- VC4_PACKET_DEPTH_OFFSET = 101, -- VC4_PACKET_CLIP_WINDOW = 102, -- VC4_PACKET_VIEWPORT_OFFSET = 103, -- VC4_PACKET_Z_CLIPPING = 104, -- VC4_PACKET_CLIPPER_XY_SCALING = 105, -- VC4_PACKET_CLIPPER_Z_SCALING = 106, -- -- VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -- VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -- VC4_PACKET_CLEAR_COLORS = 114, -- VC4_PACKET_TILE_COORDINATES = 115, -- -- /* Not an actual hardware packet -- this is what we use to put -- * references to GEM bos in the command stream, since we need the u32 -- * int the actual address packet in order to store the offset from the -- * start of the BO. -- */ -- VC4_PACKET_GEM_HANDLES = 254, -+ VC4_PACKET_HALT = 0, -+ VC4_PACKET_NOP = 1, -+ -+ VC4_PACKET_FLUSH = 4, -+ VC4_PACKET_FLUSH_ALL = 5, -+ VC4_PACKET_START_TILE_BINNING = 6, -+ VC4_PACKET_INCREMENT_SEMAPHORE = 7, -+ VC4_PACKET_WAIT_ON_SEMAPHORE = 8, -+ -+ VC4_PACKET_BRANCH = 16, -+ VC4_PACKET_BRANCH_TO_SUB_LIST = 17, -+ -+ VC4_PACKET_STORE_MS_TILE_BUFFER = 24, -+ VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF = 25, -+ VC4_PACKET_STORE_FULL_RES_TILE_BUFFER = 26, -+ VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER = 27, -+ VC4_PACKET_STORE_TILE_BUFFER_GENERAL = 28, -+ VC4_PACKET_LOAD_TILE_BUFFER_GENERAL = 29, -+ -+ VC4_PACKET_GL_INDEXED_PRIMITIVE = 32, -+ VC4_PACKET_GL_ARRAY_PRIMITIVE = 33, -+ -+ VC4_PACKET_COMPRESSED_PRIMITIVE = 48, -+ VC4_PACKET_CLIPPED_COMPRESSED_PRIMITIVE = 49, -+ -+ VC4_PACKET_PRIMITIVE_LIST_FORMAT = 56, -+ -+ VC4_PACKET_GL_SHADER_STATE = 64, -+ VC4_PACKET_NV_SHADER_STATE = 65, -+ VC4_PACKET_VG_SHADER_STATE = 66, -+ -+ VC4_PACKET_CONFIGURATION_BITS = 96, -+ VC4_PACKET_FLAT_SHADE_FLAGS = 97, -+ VC4_PACKET_POINT_SIZE = 98, -+ VC4_PACKET_LINE_WIDTH = 99, -+ VC4_PACKET_RHT_X_BOUNDARY = 100, -+ VC4_PACKET_DEPTH_OFFSET = 101, -+ VC4_PACKET_CLIP_WINDOW = 102, -+ VC4_PACKET_VIEWPORT_OFFSET = 103, -+ VC4_PACKET_Z_CLIPPING = 104, -+ VC4_PACKET_CLIPPER_XY_SCALING = 105, -+ VC4_PACKET_CLIPPER_Z_SCALING = 106, -+ -+ VC4_PACKET_TILE_BINNING_MODE_CONFIG = 112, -+ VC4_PACKET_TILE_RENDERING_MODE_CONFIG = 113, -+ VC4_PACKET_CLEAR_COLORS = 114, -+ VC4_PACKET_TILE_COORDINATES = 115, -+ -+ /* Not an actual hardware packet -- this is what we use to put -+ * references to GEM bos in the command stream, since we need the u32 -+ * int the actual address packet in order to store the offset from the -+ * start of the BO. -+ */ -+ VC4_PACKET_GEM_HANDLES = 254, - } __attribute__ ((__packed__)); - - #define VC4_PACKET_HALT_SIZE 1 -@@ -148,10 +148,10 @@ enum vc4_packet { - * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL (low bits of the address) - */ - --#define VC4_LOADSTORE_TILE_BUFFER_EOF (1 << 3) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK (1 << 2) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS (1 << 1) --#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR (1 << 0) -+#define VC4_LOADSTORE_TILE_BUFFER_EOF BIT(3) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_VG_MASK BIT(2) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_ZS BIT(1) -+#define VC4_LOADSTORE_TILE_BUFFER_DISABLE_FULL_COLOR BIT(0) - - /** @} */ - -@@ -160,10 +160,10 @@ enum vc4_packet { - * byte 0-1 of VC4_PACKET_STORE_TILE_BUFFER_GENERAL and - * VC4_PACKET_LOAD_TILE_BUFFER_GENERAL - */ --#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR (1 << 15) --#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR (1 << 14) --#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR (1 << 13) --#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP (1 << 12) -+#define VC4_STORE_TILE_BUFFER_DISABLE_VG_MASK_CLEAR BIT(15) -+#define VC4_STORE_TILE_BUFFER_DISABLE_ZS_CLEAR BIT(14) -+#define VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR BIT(13) -+#define VC4_STORE_TILE_BUFFER_DISABLE_SWAP BIT(12) - - #define VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK VC4_MASK(9, 8) - #define VC4_LOADSTORE_TILE_BUFFER_FORMAT_SHIFT 8 -@@ -201,28 +201,28 @@ enum vc4_packet { - #define VC4_INDEX_BUFFER_U16 (1 << 4) - - /* This flag is only present in NV shader state. */ --#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS (1 << 3) --#define VC4_SHADER_FLAG_ENABLE_CLIPPING (1 << 2) --#define VC4_SHADER_FLAG_VS_POINT_SIZE (1 << 1) --#define VC4_SHADER_FLAG_FS_SINGLE_THREAD (1 << 0) -+#define VC4_SHADER_FLAG_SHADED_CLIP_COORDS BIT(3) -+#define VC4_SHADER_FLAG_ENABLE_CLIPPING BIT(2) -+#define VC4_SHADER_FLAG_VS_POINT_SIZE BIT(1) -+#define VC4_SHADER_FLAG_FS_SINGLE_THREAD BIT(0) - - /** @{ byte 2 of config bits. */ --#define VC4_CONFIG_BITS_EARLY_Z_UPDATE (1 << 1) --#define VC4_CONFIG_BITS_EARLY_Z (1 << 0) -+#define VC4_CONFIG_BITS_EARLY_Z_UPDATE BIT(1) -+#define VC4_CONFIG_BITS_EARLY_Z BIT(0) - /** @} */ - - /** @{ byte 1 of config bits. */ --#define VC4_CONFIG_BITS_Z_UPDATE (1 << 7) -+#define VC4_CONFIG_BITS_Z_UPDATE BIT(7) - /** same values in this 3-bit field as PIPE_FUNC_* */ - #define VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT 4 --#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE (1 << 3) -+#define VC4_CONFIG_BITS_COVERAGE_READ_LEAVE BIT(3) - - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_NONZERO (0 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_ODD (1 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_OR (2 << 1) - #define VC4_CONFIG_BITS_COVERAGE_UPDATE_ZERO (3 << 1) - --#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT (1 << 0) -+#define VC4_CONFIG_BITS_COVERAGE_PIPE_SELECT BIT(0) - /** @} */ - - /** @{ byte 0 of config bits. */ -@@ -230,15 +230,15 @@ enum vc4_packet { - #define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X (1 << 6) - #define VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_16X (2 << 6) - --#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES (1 << 4) --#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET (1 << 3) --#define VC4_CONFIG_BITS_CW_PRIMITIVES (1 << 2) --#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK (1 << 1) --#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT (1 << 0) -+#define VC4_CONFIG_BITS_AA_POINTS_AND_LINES BIT(4) -+#define VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET BIT(3) -+#define VC4_CONFIG_BITS_CW_PRIMITIVES BIT(2) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_BACK BIT(1) -+#define VC4_CONFIG_BITS_ENABLE_PRIM_FRONT BIT(0) - /** @} */ - - /** @{ bits in the last u8 of VC4_PACKET_TILE_BINNING_MODE_CONFIG */ --#define VC4_BIN_CONFIG_DB_NON_MS (1 << 7) -+#define VC4_BIN_CONFIG_DB_NON_MS BIT(7) - - #define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_MASK VC4_MASK(6, 5) - #define VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_SHIFT 5 -@@ -254,17 +254,17 @@ enum vc4_packet { - #define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_128 2 - #define VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_256 3 - --#define VC4_BIN_CONFIG_AUTO_INIT_TSDA (1 << 2) --#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT (1 << 1) --#define VC4_BIN_CONFIG_MS_MODE_4X (1 << 0) -+#define VC4_BIN_CONFIG_AUTO_INIT_TSDA BIT(2) -+#define VC4_BIN_CONFIG_TILE_BUFFER_64BIT BIT(1) -+#define VC4_BIN_CONFIG_MS_MODE_4X BIT(0) - /** @} */ - - /** @{ bits in the last u16 of VC4_PACKET_TILE_RENDERING_MODE_CONFIG */ --#define VC4_RENDER_CONFIG_DB_NON_MS (1 << 12) --#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE (1 << 11) --#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G (1 << 10) --#define VC4_RENDER_CONFIG_COVERAGE_MODE (1 << 9) --#define VC4_RENDER_CONFIG_ENABLE_VG_MASK (1 << 8) -+#define VC4_RENDER_CONFIG_DB_NON_MS BIT(12) -+#define VC4_RENDER_CONFIG_EARLY_Z_COVERAGE_DISABLE BIT(11) -+#define VC4_RENDER_CONFIG_EARLY_Z_DIRECTION_G BIT(10) -+#define VC4_RENDER_CONFIG_COVERAGE_MODE BIT(9) -+#define VC4_RENDER_CONFIG_ENABLE_VG_MASK BIT(8) - - /** The values of the field are VC4_TILING_FORMAT_* */ - #define VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK VC4_MASK(7, 6) -@@ -280,8 +280,8 @@ enum vc4_packet { - #define VC4_RENDER_CONFIG_FORMAT_RGBA8888 1 - #define VC4_RENDER_CONFIG_FORMAT_BGR565 2 - --#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT (1 << 1) --#define VC4_RENDER_CONFIG_MS_MODE_4X (1 << 0) -+#define VC4_RENDER_CONFIG_TILE_BUFFER_64BIT BIT(1) -+#define VC4_RENDER_CONFIG_MS_MODE_4X BIT(0) - - #define VC4_PRIMITIVE_LIST_FORMAT_16_INDEX (1 << 4) - #define VC4_PRIMITIVE_LIST_FORMAT_32_XY (3 << 4) -@@ -291,24 +291,24 @@ enum vc4_packet { - #define VC4_PRIMITIVE_LIST_FORMAT_TYPE_RHT (3 << 0) - - enum vc4_texture_data_type { -- VC4_TEXTURE_TYPE_RGBA8888 = 0, -- VC4_TEXTURE_TYPE_RGBX8888 = 1, -- VC4_TEXTURE_TYPE_RGBA4444 = 2, -- VC4_TEXTURE_TYPE_RGBA5551 = 3, -- VC4_TEXTURE_TYPE_RGB565 = 4, -- VC4_TEXTURE_TYPE_LUMINANCE = 5, -- VC4_TEXTURE_TYPE_ALPHA = 6, -- VC4_TEXTURE_TYPE_LUMALPHA = 7, -- VC4_TEXTURE_TYPE_ETC1 = 8, -- VC4_TEXTURE_TYPE_S16F = 9, -- VC4_TEXTURE_TYPE_S8 = 10, -- VC4_TEXTURE_TYPE_S16 = 11, -- VC4_TEXTURE_TYPE_BW1 = 12, -- VC4_TEXTURE_TYPE_A4 = 13, -- VC4_TEXTURE_TYPE_A1 = 14, -- VC4_TEXTURE_TYPE_RGBA64 = 15, -- VC4_TEXTURE_TYPE_RGBA32R = 16, -- VC4_TEXTURE_TYPE_YUV422R = 17, -+ VC4_TEXTURE_TYPE_RGBA8888 = 0, -+ VC4_TEXTURE_TYPE_RGBX8888 = 1, -+ VC4_TEXTURE_TYPE_RGBA4444 = 2, -+ VC4_TEXTURE_TYPE_RGBA5551 = 3, -+ VC4_TEXTURE_TYPE_RGB565 = 4, -+ VC4_TEXTURE_TYPE_LUMINANCE = 5, -+ VC4_TEXTURE_TYPE_ALPHA = 6, -+ VC4_TEXTURE_TYPE_LUMALPHA = 7, -+ VC4_TEXTURE_TYPE_ETC1 = 8, -+ VC4_TEXTURE_TYPE_S16F = 9, -+ VC4_TEXTURE_TYPE_S8 = 10, -+ VC4_TEXTURE_TYPE_S16 = 11, -+ VC4_TEXTURE_TYPE_BW1 = 12, -+ VC4_TEXTURE_TYPE_A4 = 13, -+ VC4_TEXTURE_TYPE_A1 = 14, -+ VC4_TEXTURE_TYPE_RGBA64 = 15, -+ VC4_TEXTURE_TYPE_RGBA32R = 16, -+ VC4_TEXTURE_TYPE_YUV422R = 17, - }; - - #define VC4_TEX_P0_OFFSET_MASK VC4_MASK(31, 12) -diff --git a/drivers/gpu/drm/vc4/vc4_qpu_defines.h b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -index e47c994..d5c2f3c 100644 ---- a/drivers/gpu/drm/vc4/vc4_qpu_defines.h -+++ b/drivers/gpu/drm/vc4/vc4_qpu_defines.h -@@ -25,194 +25,190 @@ - #define VC4_QPU_DEFINES_H - - enum qpu_op_add { -- QPU_A_NOP, -- QPU_A_FADD, -- QPU_A_FSUB, -- QPU_A_FMIN, -- QPU_A_FMAX, -- QPU_A_FMINABS, -- QPU_A_FMAXABS, -- QPU_A_FTOI, -- QPU_A_ITOF, -- QPU_A_ADD = 12, -- QPU_A_SUB, -- QPU_A_SHR, -- QPU_A_ASR, -- QPU_A_ROR, -- QPU_A_SHL, -- QPU_A_MIN, -- QPU_A_MAX, -- QPU_A_AND, -- QPU_A_OR, -- QPU_A_XOR, -- QPU_A_NOT, -- QPU_A_CLZ, -- QPU_A_V8ADDS = 30, -- QPU_A_V8SUBS = 31, -+ QPU_A_NOP, -+ QPU_A_FADD, -+ QPU_A_FSUB, -+ QPU_A_FMIN, -+ QPU_A_FMAX, -+ QPU_A_FMINABS, -+ QPU_A_FMAXABS, -+ QPU_A_FTOI, -+ QPU_A_ITOF, -+ QPU_A_ADD = 12, -+ QPU_A_SUB, -+ QPU_A_SHR, -+ QPU_A_ASR, -+ QPU_A_ROR, -+ QPU_A_SHL, -+ QPU_A_MIN, -+ QPU_A_MAX, -+ QPU_A_AND, -+ QPU_A_OR, -+ QPU_A_XOR, -+ QPU_A_NOT, -+ QPU_A_CLZ, -+ QPU_A_V8ADDS = 30, -+ QPU_A_V8SUBS = 31, - }; - - enum qpu_op_mul { -- QPU_M_NOP, -- QPU_M_FMUL, -- QPU_M_MUL24, -- QPU_M_V8MULD, -- QPU_M_V8MIN, -- QPU_M_V8MAX, -- QPU_M_V8ADDS, -- QPU_M_V8SUBS, -+ QPU_M_NOP, -+ QPU_M_FMUL, -+ QPU_M_MUL24, -+ QPU_M_V8MULD, -+ QPU_M_V8MIN, -+ QPU_M_V8MAX, -+ QPU_M_V8ADDS, -+ QPU_M_V8SUBS, - }; - - enum qpu_raddr { -- QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -- /* 0-31 are the plain regfile a or b fields */ -- QPU_R_UNIF = 32, -- QPU_R_VARY = 35, -- QPU_R_ELEM_QPU = 38, -- QPU_R_NOP, -- QPU_R_XY_PIXEL_COORD = 41, -- QPU_R_MS_REV_FLAGS = 41, -- QPU_R_VPM = 48, -- QPU_R_VPM_LD_BUSY, -- QPU_R_VPM_LD_WAIT, -- QPU_R_MUTEX_ACQUIRE, -+ QPU_R_FRAG_PAYLOAD_ZW = 15, /* W for A file, Z for B file */ -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_R_UNIF = 32, -+ QPU_R_VARY = 35, -+ QPU_R_ELEM_QPU = 38, -+ QPU_R_NOP, -+ QPU_R_XY_PIXEL_COORD = 41, -+ QPU_R_MS_REV_FLAGS = 41, -+ QPU_R_VPM = 48, -+ QPU_R_VPM_LD_BUSY, -+ QPU_R_VPM_LD_WAIT, -+ QPU_R_MUTEX_ACQUIRE, - }; - - enum qpu_waddr { -- /* 0-31 are the plain regfile a or b fields */ -- QPU_W_ACC0 = 32, /* aka r0 */ -- QPU_W_ACC1, -- QPU_W_ACC2, -- QPU_W_ACC3, -- QPU_W_TMU_NOSWAP, -- QPU_W_ACC5, -- QPU_W_HOST_INT, -- QPU_W_NOP, -- QPU_W_UNIFORMS_ADDRESS, -- QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -- QPU_W_MS_FLAGS = 42, -- QPU_W_REV_FLAG = 42, -- QPU_W_TLB_STENCIL_SETUP = 43, -- QPU_W_TLB_Z, -- QPU_W_TLB_COLOR_MS, -- QPU_W_TLB_COLOR_ALL, -- QPU_W_TLB_ALPHA_MASK, -- QPU_W_VPM, -- QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -- QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -- QPU_W_MUTEX_RELEASE, -- QPU_W_SFU_RECIP, -- QPU_W_SFU_RECIPSQRT, -- QPU_W_SFU_EXP, -- QPU_W_SFU_LOG, -- QPU_W_TMU0_S, -- QPU_W_TMU0_T, -- QPU_W_TMU0_R, -- QPU_W_TMU0_B, -- QPU_W_TMU1_S, -- QPU_W_TMU1_T, -- QPU_W_TMU1_R, -- QPU_W_TMU1_B, -+ /* 0-31 are the plain regfile a or b fields */ -+ QPU_W_ACC0 = 32, /* aka r0 */ -+ QPU_W_ACC1, -+ QPU_W_ACC2, -+ QPU_W_ACC3, -+ QPU_W_TMU_NOSWAP, -+ QPU_W_ACC5, -+ QPU_W_HOST_INT, -+ QPU_W_NOP, -+ QPU_W_UNIFORMS_ADDRESS, -+ QPU_W_QUAD_XY, /* X for regfile a, Y for regfile b */ -+ QPU_W_MS_FLAGS = 42, -+ QPU_W_REV_FLAG = 42, -+ QPU_W_TLB_STENCIL_SETUP = 43, -+ QPU_W_TLB_Z, -+ QPU_W_TLB_COLOR_MS, -+ QPU_W_TLB_COLOR_ALL, -+ QPU_W_TLB_ALPHA_MASK, -+ QPU_W_VPM, -+ QPU_W_VPMVCD_SETUP, /* LD for regfile a, ST for regfile b */ -+ QPU_W_VPM_ADDR, /* LD for regfile a, ST for regfile b */ -+ QPU_W_MUTEX_RELEASE, -+ QPU_W_SFU_RECIP, -+ QPU_W_SFU_RECIPSQRT, -+ QPU_W_SFU_EXP, -+ QPU_W_SFU_LOG, -+ QPU_W_TMU0_S, -+ QPU_W_TMU0_T, -+ QPU_W_TMU0_R, -+ QPU_W_TMU0_B, -+ QPU_W_TMU1_S, -+ QPU_W_TMU1_T, -+ QPU_W_TMU1_R, -+ QPU_W_TMU1_B, - }; - - enum qpu_sig_bits { -- QPU_SIG_SW_BREAKPOINT, -- QPU_SIG_NONE, -- QPU_SIG_THREAD_SWITCH, -- QPU_SIG_PROG_END, -- QPU_SIG_WAIT_FOR_SCOREBOARD, -- QPU_SIG_SCOREBOARD_UNLOCK, -- QPU_SIG_LAST_THREAD_SWITCH, -- QPU_SIG_COVERAGE_LOAD, -- QPU_SIG_COLOR_LOAD, -- QPU_SIG_COLOR_LOAD_END, -- QPU_SIG_LOAD_TMU0, -- QPU_SIG_LOAD_TMU1, -- QPU_SIG_ALPHA_MASK_LOAD, -- QPU_SIG_SMALL_IMM, -- QPU_SIG_LOAD_IMM, -- QPU_SIG_BRANCH -+ QPU_SIG_SW_BREAKPOINT, -+ QPU_SIG_NONE, -+ QPU_SIG_THREAD_SWITCH, -+ QPU_SIG_PROG_END, -+ QPU_SIG_WAIT_FOR_SCOREBOARD, -+ QPU_SIG_SCOREBOARD_UNLOCK, -+ QPU_SIG_LAST_THREAD_SWITCH, -+ QPU_SIG_COVERAGE_LOAD, -+ QPU_SIG_COLOR_LOAD, -+ QPU_SIG_COLOR_LOAD_END, -+ QPU_SIG_LOAD_TMU0, -+ QPU_SIG_LOAD_TMU1, -+ QPU_SIG_ALPHA_MASK_LOAD, -+ QPU_SIG_SMALL_IMM, -+ QPU_SIG_LOAD_IMM, -+ QPU_SIG_BRANCH - }; - - enum qpu_mux { -- /* hardware mux values */ -- QPU_MUX_R0, -- QPU_MUX_R1, -- QPU_MUX_R2, -- QPU_MUX_R3, -- QPU_MUX_R4, -- QPU_MUX_R5, -- QPU_MUX_A, -- QPU_MUX_B, -+ /* hardware mux values */ -+ QPU_MUX_R0, -+ QPU_MUX_R1, -+ QPU_MUX_R2, -+ QPU_MUX_R3, -+ QPU_MUX_R4, -+ QPU_MUX_R5, -+ QPU_MUX_A, -+ QPU_MUX_B, - -- /* non-hardware mux values */ -- QPU_MUX_IMM, -+ /* non-hardware mux values */ -+ QPU_MUX_IMM, - }; - - enum qpu_cond { -- QPU_COND_NEVER, -- QPU_COND_ALWAYS, -- QPU_COND_ZS, -- QPU_COND_ZC, -- QPU_COND_NS, -- QPU_COND_NC, -- QPU_COND_CS, -- QPU_COND_CC, -+ QPU_COND_NEVER, -+ QPU_COND_ALWAYS, -+ QPU_COND_ZS, -+ QPU_COND_ZC, -+ QPU_COND_NS, -+ QPU_COND_NC, -+ QPU_COND_CS, -+ QPU_COND_CC, - }; - - enum qpu_pack_mul { -- QPU_PACK_MUL_NOP, -- QPU_PACK_MUL_8888 = 3, /* replicated to each 8 bits of the 32-bit dst. */ -- QPU_PACK_MUL_8A, -- QPU_PACK_MUL_8B, -- QPU_PACK_MUL_8C, -- QPU_PACK_MUL_8D, -+ QPU_PACK_MUL_NOP, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_MUL_8888 = 3, -+ QPU_PACK_MUL_8A, -+ QPU_PACK_MUL_8B, -+ QPU_PACK_MUL_8C, -+ QPU_PACK_MUL_8D, - }; - - enum qpu_pack_a { -- QPU_PACK_A_NOP, -- /* convert to 16 bit float if float input, or to int16. */ -- QPU_PACK_A_16A, -- QPU_PACK_A_16B, -- /* replicated to each 8 bits of the 32-bit dst. */ -- QPU_PACK_A_8888, -- /* Convert to 8-bit unsigned int. */ -- QPU_PACK_A_8A, -- QPU_PACK_A_8B, -- QPU_PACK_A_8C, -- QPU_PACK_A_8D, -+ QPU_PACK_A_NOP, -+ /* convert to 16 bit float if float input, or to int16. */ -+ QPU_PACK_A_16A, -+ QPU_PACK_A_16B, -+ /* replicated to each 8 bits of the 32-bit dst. */ -+ QPU_PACK_A_8888, -+ /* Convert to 8-bit unsigned int. */ -+ QPU_PACK_A_8A, -+ QPU_PACK_A_8B, -+ QPU_PACK_A_8C, -+ QPU_PACK_A_8D, - -- /* Saturating variants of the previous instructions. */ -- QPU_PACK_A_32_SAT, /* int-only */ -- QPU_PACK_A_16A_SAT, /* int or float */ -- QPU_PACK_A_16B_SAT, -- QPU_PACK_A_8888_SAT, -- QPU_PACK_A_8A_SAT, -- QPU_PACK_A_8B_SAT, -- QPU_PACK_A_8C_SAT, -- QPU_PACK_A_8D_SAT, -+ /* Saturating variants of the previous instructions. */ -+ QPU_PACK_A_32_SAT, /* int-only */ -+ QPU_PACK_A_16A_SAT, /* int or float */ -+ QPU_PACK_A_16B_SAT, -+ QPU_PACK_A_8888_SAT, -+ QPU_PACK_A_8A_SAT, -+ QPU_PACK_A_8B_SAT, -+ QPU_PACK_A_8C_SAT, -+ QPU_PACK_A_8D_SAT, - }; - - enum qpu_unpack_r4 { -- QPU_UNPACK_R4_NOP, -- QPU_UNPACK_R4_F16A_TO_F32, -- QPU_UNPACK_R4_F16B_TO_F32, -- QPU_UNPACK_R4_8D_REP, -- QPU_UNPACK_R4_8A, -- QPU_UNPACK_R4_8B, -- QPU_UNPACK_R4_8C, -- QPU_UNPACK_R4_8D, -+ QPU_UNPACK_R4_NOP, -+ QPU_UNPACK_R4_F16A_TO_F32, -+ QPU_UNPACK_R4_F16B_TO_F32, -+ QPU_UNPACK_R4_8D_REP, -+ QPU_UNPACK_R4_8A, -+ QPU_UNPACK_R4_8B, -+ QPU_UNPACK_R4_8C, -+ QPU_UNPACK_R4_8D, - }; - --#define QPU_MASK(high, low) ((((uint64_t)1<<((high)-(low)+1))-1)<<(low)) --/* Using the GNU statement expression extension */ --#define QPU_SET_FIELD(value, field) \ -- ({ \ -- uint64_t fieldval = (uint64_t)(value) << field ## _SHIFT; \ -- assert((fieldval & ~ field ## _MASK) == 0); \ -- fieldval & field ## _MASK; \ -- }) -+#define QPU_MASK(high, low) \ -+ ((((uint64_t)1 << ((high) - (low) + 1)) - 1) << (low)) - --#define QPU_GET_FIELD(word, field) ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) -+#define QPU_GET_FIELD(word, field) \ -+ ((uint32_t)(((word) & field ## _MASK) >> field ## _SHIFT)) - - #define QPU_SIG_SHIFT 60 - #define QPU_SIG_MASK QPU_MASK(63, 60) -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 0ffac8d..3516354 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -63,7 +63,6 @@ static inline void rcl_u32(struct vc4_rcl_setup *setup, u32 val) - setup->next_offset += 4; - } - -- - /* - * Emits a no-op STORE_TILE_BUFFER_GENERAL. - * -@@ -217,7 +216,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - } - size += xtiles * ytiles * loop_body_size; - -- setup->rcl = &vc4_bo_create(dev, size)->base; -+ setup->rcl = &vc4_bo_create(dev, size, true)->base; - if (!setup->rcl) - return -ENOMEM; - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, -@@ -256,6 +255,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - for (x = min_x_tile; x <= max_x_tile; x++) { - bool first = (x == min_x_tile && y == min_y_tile); - bool last = (x == max_x_tile && y == max_y_tile); -+ - emit_tile(exec, setup, x, y, first, last); - } - } -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index cf35f58..29a222f 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -125,7 +125,7 @@ int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) - - int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) - { -- struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - uint32_t ident1 = V3D_READ(V3D_IDENT1); -@@ -133,11 +133,13 @@ int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) - uint32_t tups = VC4_GET_FIELD(ident1, V3D_IDENT1_TUPS); - uint32_t qups = VC4_GET_FIELD(ident1, V3D_IDENT1_QUPS); - -- seq_printf(m, "Revision: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); -+ seq_printf(m, "Revision: %d\n", -+ VC4_GET_FIELD(ident1, V3D_IDENT1_REV)); - seq_printf(m, "Slices: %d\n", nslc); - seq_printf(m, "TMUs: %d\n", nslc * tups); - seq_printf(m, "QPUs: %d\n", nslc * qups); -- seq_printf(m, "Semaphores: %d\n", VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); -+ seq_printf(m, "Semaphores: %d\n", -+ VC4_GET_FIELD(ident1, V3D_IDENT1_NSEM)); - - return 0; - } -@@ -218,7 +220,7 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) - } - - static void vc4_v3d_unbind(struct device *dev, struct device *master, -- void *data) -+ void *data) - { - struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index ff3b62f..e44e355 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -48,7 +48,6 @@ - void *validated, \ - void *untrusted - -- - /** Return the width in pixels of a 64-byte microtile. */ - static uint32_t - utile_width(int cpp) -@@ -192,7 +191,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, - - if (size + offset < size || - size + offset > fbo->base.size) { -- DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %d)\n", -+ DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n", - width, height, - aligned_width, aligned_height, - size, offset, fbo->base.size); -@@ -278,7 +277,7 @@ validate_indexed_prim_list(VALIDATE_ARGS) - - if (offset > ib->base.size || - (ib->base.size - offset) / index_size < length) { -- DRM_ERROR("IB access overflow (%d + %d*%d > %d)\n", -+ DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", - offset, length, index_size, ib->base.size); - return -EINVAL; - } -@@ -377,6 +376,7 @@ static int - validate_tile_binning_config(VALIDATE_ARGS) - { - struct drm_device *dev = exec->exec_bo->base.dev; -+ struct vc4_bo *tile_bo; - uint8_t flags; - uint32_t tile_state_size, tile_alloc_size; - uint32_t tile_count; -@@ -438,12 +438,12 @@ validate_tile_binning_config(VALIDATE_ARGS) - */ - tile_alloc_size += 1024 * 1024; - -- exec->tile_bo = &vc4_bo_create(dev, exec->tile_alloc_offset + -- tile_alloc_size)->base; -+ tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size, -+ true); -+ exec->tile_bo = &tile_bo->base; - if (!exec->tile_bo) - return -ENOMEM; -- list_add_tail(&to_vc4_bo(&exec->tile_bo->base)->unref_head, -- &exec->unref_list); -+ list_add_tail(&tile_bo->unref_head, &exec->unref_list); - - /* tile alloc address. */ - *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + -@@ -463,8 +463,8 @@ validate_gem_handles(VALIDATE_ARGS) - return 0; - } - --#define VC4_DEFINE_PACKET(packet, name, func) \ -- [packet] = { packet ## _SIZE, name, func } -+#define VC4_DEFINE_PACKET(packet, func) \ -+ [packet] = { packet ## _SIZE, #packet, func } - - static const struct cmd_info { - uint16_t len; -@@ -472,42 +472,43 @@ static const struct cmd_info { - int (*func)(struct vc4_exec_info *exec, void *validated, - void *untrusted); - } cmd_info[] = { -- VC4_DEFINE_PACKET(VC4_PACKET_HALT, "halt", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_NOP, "nop", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, "flush", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, "flush all state", validate_flush_all), -- VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, "start tile binning", validate_start_tile_binning), -- VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, "increment semaphore", validate_increment_semaphore), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, "Indexed Primitive List", validate_indexed_prim_list), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, "Vertex Array Primitives", validate_gl_array_primitive), -- -- /* This is only used by clipped primitives (packets 48 and 49), which -- * we don't support parsing yet. -- */ -- VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, "primitive list format", NULL), -- -- VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, "GL Shader State", validate_gl_shader_state), -- VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, "NV Shader State", validate_nv_shader_state), -- -- VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, "configuration bits", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, "flat shade flags", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, "point size", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, "line width", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, "RHT X boundary", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, "Depth Offset", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, "Clip Window", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, "Viewport Offset", NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, "Clipper XY Scaling", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_HALT, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_NOP, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, -+ validate_start_tile_binning), -+ VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, -+ validate_increment_semaphore), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_INDEXED_PRIMITIVE, -+ validate_indexed_prim_list), -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_ARRAY_PRIMITIVE, -+ validate_gl_array_primitive), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, NULL), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, validate_gl_shader_state), -+ VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, validate_nv_shader_state), -+ -+ VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_POINT_SIZE, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_LINE_WIDTH, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_RHT_X_BOUNDARY, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_DEPTH_OFFSET, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIP_WINDOW, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_VIEWPORT_OFFSET, NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_XY_SCALING, NULL), - /* Note: The docs say this was also 105, but it was 106 in the - * initial userland code drop. - */ -- VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, "Clipper Z Scale and Offset", NULL), -+ VC4_DEFINE_PACKET(VC4_PACKET_CLIPPER_Z_SCALING, NULL), - -- VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, "tile binning configuration", validate_tile_binning_config), -+ VC4_DEFINE_PACKET(VC4_PACKET_TILE_BINNING_MODE_CONFIG, -+ validate_tile_binning_config), - -- VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, "GEM handles", validate_gem_handles), -+ VC4_DEFINE_PACKET(VC4_PACKET_GEM_HANDLES, validate_gem_handles), - }; - - int -@@ -526,7 +527,7 @@ vc4_validate_bin_cl(struct drm_device *dev, - u8 cmd = *(uint8_t *)src_pkt; - const struct cmd_info *info; - -- if (cmd > ARRAY_SIZE(cmd_info)) { -+ if (cmd >= ARRAY_SIZE(cmd_info)) { - DRM_ERROR("0x%08x: packet %d out of bounds\n", - src_offset, cmd); - return -EINVAL; -@@ -539,11 +540,6 @@ vc4_validate_bin_cl(struct drm_device *dev, - return -EINVAL; - } - --#if 0 -- DRM_INFO("0x%08x: packet %d (%s) size %d processing...\n", -- src_offset, cmd, info->name, info->len); --#endif -- - if (src_offset + info->len > len) { - DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x " - "exceeds bounds (0x%08x)\n", -@@ -558,8 +554,7 @@ vc4_validate_bin_cl(struct drm_device *dev, - if (info->func && info->func(exec, - dst_pkt + 1, - src_pkt + 1)) { -- DRM_ERROR("0x%08x: packet %d (%s) failed to " -- "validate\n", -+ DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n", - src_offset, cmd, info->name); - return -EINVAL; - } -@@ -618,12 +613,14 @@ reloc_tex(struct vc4_exec_info *exec, - - if (sample->is_direct) { - uint32_t remaining_size = tex->base.size - p0; -+ - if (p0 > tex->base.size - 4) { - DRM_ERROR("UBO offset greater than UBO size\n"); - goto fail; - } - if (p1 > remaining_size - 4) { -- DRM_ERROR("UBO clamp would allow reads outside of UBO\n"); -+ DRM_ERROR("UBO clamp would allow reads " -+ "outside of UBO\n"); - goto fail; - } - *validated_p0 = tex->paddr + p0; -@@ -786,7 +783,7 @@ validate_shader_rec(struct drm_device *dev, - struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; - uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; - int i; -- struct vc4_validated_shader_info *validated_shader; -+ struct vc4_validated_shader_info *shader; - - if (state->packet == VC4_PACKET_NV_SHADER_STATE) { - relocs = nv_relocs; -@@ -841,12 +838,12 @@ validate_shader_rec(struct drm_device *dev, - else - mode = VC4_MODE_RENDER; - -- if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) { -+ if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) - return false; -- } - } - - for (i = 0; i < nr_fixed_relocs; i++) { -+ struct vc4_bo *vc4_bo; - uint32_t o = relocs[i].offset; - uint32_t src_offset = *(uint32_t *)(pkt_u + o); - uint32_t *texture_handles_u; -@@ -858,34 +855,34 @@ validate_shader_rec(struct drm_device *dev, - switch (relocs[i].type) { - case RELOC_CODE: - if (src_offset != 0) { -- DRM_ERROR("Shaders must be at offset 0 of " -- "the BO.\n"); -+ DRM_ERROR("Shaders must be at offset 0 " -+ "of the BO.\n"); - goto fail; - } - -- validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -- if (!validated_shader) -+ vc4_bo = to_vc4_bo(&bo[i]->base); -+ shader = vc4_bo->validated_shader; -+ if (!shader) - goto fail; - -- if (validated_shader->uniforms_src_size > -- exec->uniforms_size) { -+ if (shader->uniforms_src_size > exec->uniforms_size) { - DRM_ERROR("Uniforms src buffer overflow\n"); - goto fail; - } - - texture_handles_u = exec->uniforms_u; - uniform_data_u = (texture_handles_u + -- validated_shader->num_texture_samples); -+ shader->num_texture_samples); - - memcpy(exec->uniforms_v, uniform_data_u, -- validated_shader->uniforms_size); -+ shader->uniforms_size); - - for (tex = 0; -- tex < validated_shader->num_texture_samples; -+ tex < shader->num_texture_samples; - tex++) { - if (!reloc_tex(exec, - uniform_data_u, -- &validated_shader->texture_samples[tex], -+ &shader->texture_samples[tex], - texture_handles_u[tex])) { - goto fail; - } -@@ -893,9 +890,9 @@ validate_shader_rec(struct drm_device *dev, - - *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; - -- exec->uniforms_u += validated_shader->uniforms_src_size; -- exec->uniforms_v += validated_shader->uniforms_size; -- exec->uniforms_p += validated_shader->uniforms_size; -+ exec->uniforms_u += shader->uniforms_src_size; -+ exec->uniforms_v += shader->uniforms_size; -+ exec->uniforms_p += shader->uniforms_size; - - break; - -@@ -926,7 +923,8 @@ validate_shader_rec(struct drm_device *dev, - max_index = ((vbo->base.size - offset - attr_size) / - stride); - if (state->max_index > max_index) { -- DRM_ERROR("primitives use index %d out of supplied %d\n", -+ DRM_ERROR("primitives use index %d out of " -+ "supplied %d\n", - state->max_index, max_index); - return -EINVAL; - } -diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -index 0aab9d7..f67124b 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c -+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c -@@ -24,24 +24,16 @@ - /** - * DOC: Shader validator for VC4. - * -- * The VC4 has no IOMMU between it and system memory. So, a user with access -- * to execute shaders could escalate privilege by overwriting system memory -- * (using the VPM write address register in the general-purpose DMA mode) or -- * reading system memory it shouldn't (reading it as a texture, or uniform -- * data, or vertex data). -+ * The VC4 has no IOMMU between it and system memory, so a user with -+ * access to execute shaders could escalate privilege by overwriting -+ * system memory (using the VPM write address register in the -+ * general-purpose DMA mode) or reading system memory it shouldn't -+ * (reading it as a texture, or uniform data, or vertex data). - * -- * This walks over a shader starting from some offset within a BO, ensuring -- * that its accesses are appropriately bounded, and recording how many texture -- * accesses are made and where so that we can do relocations for them in the -+ * This walks over a shader BO, ensuring that its accesses are -+ * appropriately bounded, and recording how many texture accesses are -+ * made and where so that we can do relocations for them in the - * uniform stream. -- * -- * The kernel API has shaders stored in user-mapped BOs. The BOs will be -- * forcibly unmapped from the process before validation, and any cache of -- * validated state will be flushed if the mapping is faulted back in. -- * -- * Storing the shaders in BOs means that the validation process will be slow -- * due to uncached reads, but since shaders are long-lived and shader BOs are -- * never actually modified, this shouldn't be a problem. - */ - - #include "vc4_drv.h" -@@ -70,7 +62,6 @@ waddr_to_live_reg_index(uint32_t waddr, bool is_b) - else - return waddr; - } else if (waddr <= QPU_W_ACC3) { -- - return 64 + waddr - QPU_W_ACC0; - } else { - return ~0; -@@ -85,15 +76,14 @@ raddr_add_a_to_live_reg_index(uint64_t inst) - uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A); - uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B); - -- if (add_a == QPU_MUX_A) { -+ if (add_a == QPU_MUX_A) - return raddr_a; -- } else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) { -+ else if (add_a == QPU_MUX_B && sig != QPU_SIG_SMALL_IMM) - return 32 + raddr_b; -- } else if (add_a <= QPU_MUX_R3) { -+ else if (add_a <= QPU_MUX_R3) - return 64 + add_a; -- } else { -+ else - return ~0; -- } - } - - static bool -@@ -111,9 +101,9 @@ is_tmu_write(uint32_t waddr) - } - - static bool --record_validated_texture_sample(struct vc4_validated_shader_info *validated_shader, -- struct vc4_shader_validation_state *validation_state, -- int tmu) -+record_texture_sample(struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ int tmu) - { - uint32_t s = validated_shader->num_texture_samples; - int i; -@@ -226,8 +216,8 @@ check_tmu_write(uint64_t inst, - validated_shader->uniforms_size += 4; - - if (submit) { -- if (!record_validated_texture_sample(validated_shader, -- validation_state, tmu)) { -+ if (!record_texture_sample(validated_shader, -+ validation_state, tmu)) { - return false; - } - -@@ -238,10 +228,10 @@ check_tmu_write(uint64_t inst, - } - - static bool --check_register_write(uint64_t inst, -- struct vc4_validated_shader_info *validated_shader, -- struct vc4_shader_validation_state *validation_state, -- bool is_mul) -+check_reg_write(uint64_t inst, -+ struct vc4_validated_shader_info *validated_shader, -+ struct vc4_shader_validation_state *validation_state, -+ bool is_mul) - { - uint32_t waddr = (is_mul ? - QPU_GET_FIELD(inst, QPU_WADDR_MUL) : -@@ -297,7 +287,7 @@ check_register_write(uint64_t inst, - return true; - - case QPU_W_TLB_STENCIL_SETUP: -- return true; -+ return true; - } - - return true; -@@ -360,7 +350,7 @@ track_live_clamps(uint64_t inst, - } - - validation_state->live_max_clamp_regs[lri_add] = true; -- } if (op_add == QPU_A_MIN) { -+ } else if (op_add == QPU_A_MIN) { - /* Track live clamps of a value clamped to a minimum of 0 and - * a maximum of some uniform's offset. - */ -@@ -392,8 +382,10 @@ check_instruction_writes(uint64_t inst, - return false; - } - -- ok = (check_register_write(inst, validated_shader, validation_state, false) && -- check_register_write(inst, validated_shader, validation_state, true)); -+ ok = (check_reg_write(inst, validated_shader, validation_state, -+ false) && -+ check_reg_write(inst, validated_shader, validation_state, -+ true)); - - track_live_clamps(inst, validated_shader, validation_state); - -@@ -441,7 +433,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) - shader = shader_obj->vaddr; - max_ip = shader_obj->base.size / sizeof(uint64_t); - -- validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL); -+ validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); - if (!validated_shader) - return NULL; - -@@ -497,7 +489,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) - - if (ip == max_ip) { - DRM_ERROR("shader failed to terminate before " -- "shader BO end at %d\n", -+ "shader BO end at %zd\n", - shader_obj->base.size); - goto fail; - } -diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 54f5469..987c25a 100644 ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -585,6 +585,13 @@ struct drm_driver { - int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); - void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); - -+ /** -+ * Hook for allocating the GEM object struct, for use by core -+ * helpers. -+ */ -+ struct drm_gem_object *(*gem_create_object)(struct drm_device *dev, -+ size_t size); -+ - /* prime: */ - /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ - int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, -@@ -639,7 +646,6 @@ struct drm_driver { - - u32 driver_features; - int dev_priv_size; -- size_t gem_obj_size; - const struct drm_ioctl_desc *ioctls; - int num_ioctls; - const struct file_operations *fops; - -From 527fa9469f0876bade592e985a6c973ca8c84839 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 11 Dec 2015 19:45:03 -0800 -Subject: [PATCH 111/251] drm: Use the driver's gem_object_free function from - CMA helpers. - -VC4 wraps the CMA objects in its own structures, so it needs to do its -own teardown (waiting for GPU to finish, updating bo_stats tracking). -The other CMA drivers are using drm_gem_cma_free_object as their -gem_free_object, so this should be a no-op for them. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/drm_fb_cma_helper.c | 6 +++--- - drivers/gpu/drm/drm_gem_cma_helper.c | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c -index c19a625..c1a37d3 100644 ---- a/drivers/gpu/drm/drm_fb_cma_helper.c -+++ b/drivers/gpu/drm/drm_fb_cma_helper.c -@@ -266,7 +266,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - fbi = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(fbi)) { - ret = PTR_ERR(fbi); -- goto err_drm_gem_cma_free_object; -+ goto err_gem_free_object; - } - - fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); -@@ -299,8 +299,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - - err_fb_info_destroy: - drm_fb_helper_release_fbi(helper); --err_drm_gem_cma_free_object: -- drm_gem_cma_free_object(&obj->base); -+err_gem_free_object: -+ dev->driver->gem_free_object(&obj->base); - return ret; - } - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index 0f7b00b..e5df53b 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, - return cma_obj; - - error: -- drm_gem_cma_free_object(&cma_obj->base); -+ drm->driver->gem_free_object(&cma_obj->base); - return ERR_PTR(ret); - } - EXPORT_SYMBOL_GPL(drm_gem_cma_create); -@@ -171,7 +171,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, - return cma_obj; - - err_handle_create: -- drm_gem_cma_free_object(gem_obj); -+ drm->driver->gem_free_object(gem_obj); - - return ERR_PTR(ret); - } - -From d5d7b446f3dc3c30886937f4750b96d5c40a0904 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 17 Jul 2015 13:15:50 -0700 -Subject: [PATCH 112/251] drm/vc4: Add support for MSAA rendering. - -For MSAA, you set a bit in the binner that halves the size of tiles in -each direction, so you can pack 4 samples per pixel in the tile -buffer. During rendering, you can load and store raw tile buffer -contents (to save the per-sample MSAA contents), or you can load/store -resolved tile buffer contents (loads spam the pixel value to all 4 -samples, and stores either average the 4 color samples, or store the -first sample for Z/S). - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_packet.h | 23 ++- - drivers/gpu/drm/vc4/vc4_render_cl.c | 274 ++++++++++++++++++++++++++++++------ - drivers/gpu/drm/vc4/vc4_validate.c | 5 +- - include/uapi/drm/vc4_drm.h | 11 +- - 4 files changed, 258 insertions(+), 55 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_packet.h b/drivers/gpu/drm/vc4/vc4_packet.h -index cee38aa..0f31cc0 100644 ---- a/drivers/gpu/drm/vc4/vc4_packet.h -+++ b/drivers/gpu/drm/vc4/vc4_packet.h -@@ -123,6 +123,11 @@ enum vc4_packet { - #define VC4_PACKET_TILE_COORDINATES_SIZE 3 - #define VC4_PACKET_GEM_HANDLES_SIZE 9 - -+/* Number of multisamples supported. */ -+#define VC4_MAX_SAMPLES 4 -+/* Size of a full resolution color or Z tile buffer load/store. */ -+#define VC4_TILE_BUFFER_SIZE (64 * 64 * 4) -+ - /** @{ - * Bits used by packets like VC4_PACKET_STORE_TILE_BUFFER_GENERAL and - * VC4_PACKET_TILE_RENDERING_MODE_CONFIG. -@@ -137,10 +142,20 @@ enum vc4_packet { - * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and - * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. - */ --#define VC4_LOADSTORE_FULL_RES_EOF (1 << 3) --#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL (1 << 2) --#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS (1 << 1) --#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR (1 << 0) -+#define VC4_LOADSTORE_FULL_RES_EOF BIT(3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0) -+ -+/** @{ -+ * -+ * low bits of VC4_PACKET_STORE_FULL_RES_TILE_BUFFER and -+ * VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER. -+ */ -+#define VC4_LOADSTORE_FULL_RES_EOF BIT(3) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL BIT(2) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_ZS BIT(1) -+#define VC4_LOADSTORE_FULL_RES_DISABLE_COLOR BIT(0) - - /** @{ - * -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 3516354..8f2ec57 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -37,9 +37,11 @@ - - struct vc4_rcl_setup { - struct drm_gem_cma_object *color_read; -- struct drm_gem_cma_object *color_ms_write; -+ struct drm_gem_cma_object *color_write; - struct drm_gem_cma_object *zs_read; - struct drm_gem_cma_object *zs_write; -+ struct drm_gem_cma_object *msaa_color_write; -+ struct drm_gem_cma_object *msaa_zs_write; - - struct drm_gem_cma_object *rcl; - u32 next_offset; -@@ -82,6 +84,22 @@ static void vc4_store_before_load(struct vc4_rcl_setup *setup) - } - - /* -+ * Calculates the physical address of the start of a tile in a RCL surface. -+ * -+ * Unlike the other load/store packets, -+ * VC4_PACKET_LOAD/STORE_FULL_RES_TILE_BUFFER don't look at the tile -+ * coordinates packet, and instead just store to the address given. -+ */ -+static uint32_t vc4_full_res_offset(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *bo, -+ struct drm_vc4_submit_rcl_surface *surf, -+ uint8_t x, uint8_t y) -+{ -+ return bo->paddr + surf->offset + VC4_TILE_BUFFER_SIZE * -+ (DIV_ROUND_UP(exec->args->width, 32) * y + x); -+} -+ -+/* - * Emits a PACKET_TILE_COORDINATES if one isn't already pending. - * - * The tile coordinates packet triggers a pending load if there is one, are -@@ -108,22 +126,41 @@ static void emit_tile(struct vc4_exec_info *exec, - * may be outstanding at a time. - */ - if (setup->color_read) { -- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -- rcl_u16(setup, args->color_read.bits); -- rcl_u32(setup, -- setup->color_read->paddr + args->color_read.offset); -+ if (args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->color_read, -+ &args->color_read, x, y) | -+ VC4_LOADSTORE_FULL_RES_DISABLE_ZS); -+ } else { -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->color_read.bits); -+ rcl_u32(setup, setup->color_read->paddr + -+ args->color_read.offset); -+ } - } - - if (setup->zs_read) { -- if (setup->color_read) { -- /* Exec previous load. */ -- vc4_tile_coordinates(setup, x, y); -- vc4_store_before_load(setup); -+ if (args->zs_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ rcl_u8(setup, VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->zs_read, -+ &args->zs_read, x, y) | -+ VC4_LOADSTORE_FULL_RES_DISABLE_COLOR); -+ } else { -+ if (setup->color_read) { -+ /* Exec previous load. */ -+ vc4_tile_coordinates(setup, x, y); -+ vc4_store_before_load(setup); -+ } -+ -+ rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -+ rcl_u16(setup, args->zs_read.bits); -+ rcl_u32(setup, setup->zs_read->paddr + -+ args->zs_read.offset); - } -- -- rcl_u8(setup, VC4_PACKET_LOAD_TILE_BUFFER_GENERAL); -- rcl_u16(setup, args->zs_read.bits); -- rcl_u32(setup, setup->zs_read->paddr + args->zs_read.offset); - } - - /* Clipping depends on tile coordinates having been -@@ -144,20 +181,60 @@ static void emit_tile(struct vc4_exec_info *exec, - (y * exec->bin_tiles_x + x) * 32)); - } - -+ if (setup->msaa_color_write) { -+ bool last_tile_write = (!setup->msaa_zs_write && -+ !setup->zs_write && -+ !setup->color_write); -+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_ZS; -+ -+ if (!last_tile_write) -+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL; -+ else if (last) -+ bits |= VC4_LOADSTORE_FULL_RES_EOF; -+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->msaa_color_write, -+ &args->msaa_color_write, x, y) | -+ bits); -+ } -+ -+ if (setup->msaa_zs_write) { -+ bool last_tile_write = (!setup->zs_write && -+ !setup->color_write); -+ uint32_t bits = VC4_LOADSTORE_FULL_RES_DISABLE_COLOR; -+ -+ if (setup->msaa_color_write) -+ vc4_tile_coordinates(setup, x, y); -+ if (!last_tile_write) -+ bits |= VC4_LOADSTORE_FULL_RES_DISABLE_CLEAR_ALL; -+ else if (last) -+ bits |= VC4_LOADSTORE_FULL_RES_EOF; -+ rcl_u8(setup, VC4_PACKET_STORE_FULL_RES_TILE_BUFFER); -+ rcl_u32(setup, -+ vc4_full_res_offset(exec, setup->msaa_zs_write, -+ &args->msaa_zs_write, x, y) | -+ bits); -+ } -+ - if (setup->zs_write) { -+ bool last_tile_write = !setup->color_write; -+ -+ if (setup->msaa_color_write || setup->msaa_zs_write) -+ vc4_tile_coordinates(setup, x, y); -+ - rcl_u8(setup, VC4_PACKET_STORE_TILE_BUFFER_GENERAL); - rcl_u16(setup, args->zs_write.bits | -- (setup->color_ms_write ? -- VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR : 0)); -+ (last_tile_write ? -+ 0 : VC4_STORE_TILE_BUFFER_DISABLE_COLOR_CLEAR)); - rcl_u32(setup, - (setup->zs_write->paddr + args->zs_write.offset) | -- ((last && !setup->color_ms_write) ? -+ ((last && last_tile_write) ? - VC4_LOADSTORE_TILE_BUFFER_EOF : 0)); - } - -- if (setup->color_ms_write) { -- if (setup->zs_write) { -- /* Reset after previous store */ -+ if (setup->color_write) { -+ if (setup->msaa_color_write || setup->msaa_zs_write || -+ setup->zs_write) { - vc4_tile_coordinates(setup, x, y); - } - -@@ -192,14 +269,26 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - } - - if (setup->color_read) { -- loop_body_size += (VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE); -+ if (args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE; -+ } else { -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; -+ } - } - if (setup->zs_read) { -- if (setup->color_read) { -- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -- loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ if (args->zs_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ loop_body_size += VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER_SIZE; -+ } else { -+ if (setup->color_read && -+ !(args->color_read.flags & -+ VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES)) { -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -+ } -+ loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; - } -- loop_body_size += VC4_PACKET_LOAD_TILE_BUFFER_GENERAL_SIZE; - } - - if (has_bin) { -@@ -207,13 +296,23 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - loop_body_size += VC4_PACKET_BRANCH_TO_SUB_LIST_SIZE; - } - -+ if (setup->msaa_color_write) -+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE; -+ if (setup->msaa_zs_write) -+ loop_body_size += VC4_PACKET_STORE_FULL_RES_TILE_BUFFER_SIZE; -+ - if (setup->zs_write) - loop_body_size += VC4_PACKET_STORE_TILE_BUFFER_GENERAL_SIZE; -- if (setup->color_ms_write) { -- if (setup->zs_write) -- loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE; -+ if (setup->color_write) - loop_body_size += VC4_PACKET_STORE_MS_TILE_BUFFER_SIZE; -- } -+ -+ /* We need a VC4_PACKET_TILE_COORDINATES in between each store. */ -+ loop_body_size += VC4_PACKET_TILE_COORDINATES_SIZE * -+ ((setup->msaa_color_write != NULL) + -+ (setup->msaa_zs_write != NULL) + -+ (setup->color_write != NULL) + -+ (setup->zs_write != NULL) - 1); -+ - size += xtiles * ytiles * loop_body_size; - - setup->rcl = &vc4_bo_create(dev, size, true)->base; -@@ -224,13 +323,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - - rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); - rcl_u32(setup, -- (setup->color_ms_write ? -- (setup->color_ms_write->paddr + -- args->color_ms_write.offset) : -+ (setup->color_write ? (setup->color_write->paddr + -+ args->color_write.offset) : - 0)); - rcl_u16(setup, args->width); - rcl_u16(setup, args->height); -- rcl_u16(setup, args->color_ms_write.bits); -+ rcl_u16(setup, args->color_write.bits); - - /* The tile buffer gets cleared when the previous tile is stored. If - * the clear values changed between frames, then the tile buffer has -@@ -267,6 +365,56 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - return 0; - } - -+static int vc4_full_res_bounds_check(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object *obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ struct drm_vc4_submit_cl *args = exec->args; -+ u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32); -+ -+ if (surf->offset > obj->base.size) { -+ DRM_ERROR("surface offset %d > BO size %zd\n", -+ surf->offset, obj->base.size); -+ return -EINVAL; -+ } -+ -+ if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE < -+ render_tiles_stride * args->max_y_tile + args->max_x_tile) { -+ DRM_ERROR("MSAA tile %d, %d out of bounds " -+ "(bo size %zd, offset %d).\n", -+ args->max_x_tile, args->max_y_tile, -+ obj->base.size, -+ surf->offset); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) -+{ -+ if (surf->flags != 0 || surf->bits != 0) { -+ DRM_ERROR("MSAA surface had nonzero flags/bits\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->hindex == ~0) -+ return 0; -+ -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) -+ return -EINVAL; -+ -+ if (surf->offset & 0xf) { -+ DRM_ERROR("MSAA write must be 16b aligned.\n"); -+ return -EINVAL; -+ } -+ -+ return vc4_full_res_bounds_check(exec, *obj, surf); -+} -+ - static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - struct drm_gem_cma_object **obj, - struct drm_vc4_submit_rcl_surface *surf) -@@ -278,9 +426,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - uint8_t format = VC4_GET_FIELD(surf->bits, - VC4_LOADSTORE_TILE_BUFFER_FORMAT); - int cpp; -+ int ret; - -- if (surf->pad != 0) { -- DRM_ERROR("Padding unset\n"); -+ if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ DRM_ERROR("Extra flags set\n"); - return -EINVAL; - } - -@@ -290,6 +439,25 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) - return -EINVAL; - -+ if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -+ if (surf == &exec->args->zs_write) { -+ DRM_ERROR("general zs write may not be a full-res.\n"); -+ return -EINVAL; -+ } -+ -+ if (surf->bits != 0) { -+ DRM_ERROR("load/store general bits set with " -+ "full res load/store.\n"); -+ return -EINVAL; -+ } -+ -+ ret = vc4_full_res_bounds_check(exec, *obj, surf); -+ if (!ret) -+ return ret; -+ -+ return 0; -+ } -+ - if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK | - VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK | - VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) { -@@ -341,9 +509,10 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - } - - static int --vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, -- struct drm_gem_cma_object **obj, -- struct drm_vc4_submit_rcl_surface *surf) -+vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, -+ struct vc4_rcl_setup *setup, -+ struct drm_gem_cma_object **obj, -+ struct drm_vc4_submit_rcl_surface *surf) - { - uint8_t tiling = VC4_GET_FIELD(surf->bits, - VC4_RENDER_CONFIG_MEMORY_FORMAT); -@@ -351,13 +520,15 @@ vc4_rcl_ms_surface_setup(struct vc4_exec_info *exec, - VC4_RENDER_CONFIG_FORMAT); - int cpp; - -- if (surf->pad != 0) { -- DRM_ERROR("Padding unset\n"); -+ if (surf->flags != 0) { -+ DRM_ERROR("No flags supported on render config.\n"); - return -EINVAL; - } - - if (surf->bits & ~(VC4_RENDER_CONFIG_MEMORY_FORMAT_MASK | -- VC4_RENDER_CONFIG_FORMAT_MASK)) { -+ VC4_RENDER_CONFIG_FORMAT_MASK | -+ VC4_RENDER_CONFIG_MS_MODE_4X | -+ VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) { - DRM_ERROR("Unknown bits in render config: 0x%04x\n", - surf->bits); - return -EINVAL; -@@ -413,18 +584,20 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) - if (has_bin && - (args->max_x_tile > exec->bin_tiles_x || - args->max_y_tile > exec->bin_tiles_y)) { -- DRM_ERROR("Render tiles (%d,%d) outside of bin config (%d,%d)\n", -+ DRM_ERROR("Render tiles (%d,%d) outside of bin config " -+ "(%d,%d)\n", - args->max_x_tile, args->max_y_tile, - exec->bin_tiles_x, exec->bin_tiles_y); - return -EINVAL; - } - -- ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); -+ ret = vc4_rcl_render_config_surface_setup(exec, &setup, -+ &setup.color_write, -+ &args->color_write); - if (ret) - return ret; - -- ret = vc4_rcl_ms_surface_setup(exec, &setup.color_ms_write, -- &args->color_ms_write); -+ ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); - if (ret) - return ret; - -@@ -436,10 +609,21 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) - if (ret) - return ret; - -+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_color_write, -+ &args->msaa_color_write); -+ if (ret) -+ return ret; -+ -+ ret = vc4_rcl_msaa_surface_setup(exec, &setup.msaa_zs_write, -+ &args->msaa_zs_write); -+ if (ret) -+ return ret; -+ - /* We shouldn't even have the job submitted to us if there's no - * surface to write out. - */ -- if (!setup.color_ms_write && !setup.zs_write) { -+ if (!setup.color_write && !setup.zs_write && -+ !setup.msaa_color_write && !setup.msaa_zs_write) { - DRM_ERROR("RCL requires color or Z/S write\n"); - return -EINVAL; - } -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index e44e355..2f22f19 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -400,9 +400,8 @@ validate_tile_binning_config(VALIDATE_ARGS) - } - - if (flags & (VC4_BIN_CONFIG_DB_NON_MS | -- VC4_BIN_CONFIG_TILE_BUFFER_64BIT | -- VC4_BIN_CONFIG_MS_MODE_4X)) { -- DRM_ERROR("unsupported bining config flags 0x%02x\n", flags); -+ VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) { -+ DRM_ERROR("unsupported binning config flags 0x%02x\n", flags); - return -EINVAL; - } - -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 4a8d19f..49cd992 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -46,10 +46,13 @@ struct drm_vc4_submit_rcl_surface { - uint32_t hindex; /* Handle index, or ~0 if not present. */ - uint32_t offset; /* Offset to start of buffer. */ - /* -- * Bits for either render config (color_ms_write) or load/store packet. -+ * Bits for either render config (color_write) or load/store packet. -+ * Bits should all be 0 for MSAA load/stores. - */ - uint16_t bits; -- uint16_t pad; -+ -+#define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0) -+ uint16_t flags; - }; - - /** -@@ -128,9 +131,11 @@ struct drm_vc4_submit_cl { - uint8_t max_x_tile; - uint8_t max_y_tile; - struct drm_vc4_submit_rcl_surface color_read; -- struct drm_vc4_submit_rcl_surface color_ms_write; -+ struct drm_vc4_submit_rcl_surface color_write; - struct drm_vc4_submit_rcl_surface zs_read; - struct drm_vc4_submit_rcl_surface zs_write; -+ struct drm_vc4_submit_rcl_surface msaa_color_write; -+ struct drm_vc4_submit_rcl_surface msaa_zs_write; - uint32_t clear_color[2]; - uint32_t clear_z; - uint8_t clear_s; - -From 8c5854914cb7ffd1d418a4013b2089eec87600d2 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 8 Dec 2015 14:00:43 -0800 -Subject: [PATCH 113/251] drm/vc4: A few more non-functional changes to sync to - upstream. - -At this point all that's left is the force-enable of HDMI connector, -and using direct firmware calls to turn on V3D instead of the generic -power domain support. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_v3d.c | 2 +- - include/uapi/drm/vc4_drm.h | 182 +++++++++++++++++++++--------------------- - 2 files changed, 92 insertions(+), 92 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c -index 29a222f..4d103f7 100644 ---- a/drivers/gpu/drm/vc4/vc4_v3d.c -+++ b/drivers/gpu/drm/vc4/vc4_v3d.c -@@ -109,7 +109,7 @@ static const struct { - - int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused) - { -- struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - int i; -diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h -index 49cd992..eeb37e3 100644 ---- a/include/uapi/drm/vc4_drm.h -+++ b/include/uapi/drm/vc4_drm.h -@@ -24,7 +24,7 @@ - #ifndef _UAPI_VC4_DRM_H_ - #define _UAPI_VC4_DRM_H_ - --#include -+#include "drm.h" - - #define DRM_VC4_SUBMIT_CL 0x00 - #define DRM_VC4_WAIT_SEQNO 0x01 -@@ -34,25 +34,25 @@ - #define DRM_VC4_CREATE_SHADER_BO 0x05 - #define DRM_VC4_GET_HANG_STATE 0x06 - --#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) --#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) --#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) --#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) --#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) --#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) --#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) -+#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) -+#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) -+#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) -+#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) -+#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) -+#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) -+#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) - - struct drm_vc4_submit_rcl_surface { -- uint32_t hindex; /* Handle index, or ~0 if not present. */ -- uint32_t offset; /* Offset to start of buffer. */ -+ __u32 hindex; /* Handle index, or ~0 if not present. */ -+ __u32 offset; /* Offset to start of buffer. */ - /* -- * Bits for either render config (color_write) or load/store packet. -- * Bits should all be 0 for MSAA load/stores. -+ * Bits for either render config (color_write) or load/store packet. -+ * Bits should all be 0 for MSAA load/stores. - */ -- uint16_t bits; -+ __u16 bits; - - #define VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES (1 << 0) -- uint16_t flags; -+ __u16 flags; - }; - - /** -@@ -76,7 +76,7 @@ struct drm_vc4_submit_cl { - * then writes out the state updates and draw calls necessary per tile - * to the tile allocation BO. - */ -- uint64_t bin_cl; -+ __u64 bin_cl; - - /* Pointer to the shader records. - * -@@ -85,16 +85,16 @@ struct drm_vc4_submit_cl { - * reference to the shader record has enough information to determine - * how many pointers are necessary (fixed number for shaders/uniforms, - * and an attribute count), so those BO indices into bo_handles are -- * just stored as uint32_ts before each shader record passed in. -+ * just stored as __u32s before each shader record passed in. - */ -- uint64_t shader_rec; -+ __u64 shader_rec; - - /* Pointer to uniform data and texture handles for the textures - * referenced by the shader. - * - * For each shader state record, there is a set of uniform data in the - * order referenced by the record (FS, VS, then CS). Each set of -- * uniform data has a uint32_t index into bo_handles per texture -+ * uniform data has a __u32 index into bo_handles per texture - * sample operation, in the order the QPU_W_TMUn_S writes appear in - * the program. Following the texture BO handle indices is the actual - * uniform data. -@@ -103,52 +103,52 @@ struct drm_vc4_submit_cl { - * because the kernel has to determine the sizes anyway during shader - * code validation. - */ -- uint64_t uniforms; -- uint64_t bo_handles; -+ __u64 uniforms; -+ __u64 bo_handles; - - /* Size in bytes of the binner command list. */ -- uint32_t bin_cl_size; -+ __u32 bin_cl_size; - /* Size in bytes of the set of shader records. */ -- uint32_t shader_rec_size; -+ __u32 shader_rec_size; - /* Number of shader records. - * - * This could just be computed from the contents of shader_records and - * the address bits of references to them from the bin CL, but it - * keeps the kernel from having to resize some allocations it makes. - */ -- uint32_t shader_rec_count; -+ __u32 shader_rec_count; - /* Size in bytes of the uniform state. */ -- uint32_t uniforms_size; -+ __u32 uniforms_size; - - /* Number of BO handles passed in (size is that times 4). */ -- uint32_t bo_handle_count; -+ __u32 bo_handle_count; - - /* RCL setup: */ -- uint16_t width; -- uint16_t height; -- uint8_t min_x_tile; -- uint8_t min_y_tile; -- uint8_t max_x_tile; -- uint8_t max_y_tile; -+ __u16 width; -+ __u16 height; -+ __u8 min_x_tile; -+ __u8 min_y_tile; -+ __u8 max_x_tile; -+ __u8 max_y_tile; - struct drm_vc4_submit_rcl_surface color_read; - struct drm_vc4_submit_rcl_surface color_write; - struct drm_vc4_submit_rcl_surface zs_read; - struct drm_vc4_submit_rcl_surface zs_write; - struct drm_vc4_submit_rcl_surface msaa_color_write; - struct drm_vc4_submit_rcl_surface msaa_zs_write; -- uint32_t clear_color[2]; -- uint32_t clear_z; -- uint8_t clear_s; -+ __u32 clear_color[2]; -+ __u32 clear_z; -+ __u8 clear_s; - -- uint32_t pad:24; -+ __u32 pad:24; - - #define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) -- uint32_t flags; -+ __u32 flags; - - /* Returned value of the seqno of this render job (for the - * wait ioctl). - */ -- uint64_t seqno; -+ __u64 seqno; - }; - - /** -@@ -159,8 +159,8 @@ struct drm_vc4_submit_cl { - * block, just return the status." - */ - struct drm_vc4_wait_seqno { -- uint64_t seqno; -- uint64_t timeout_ns; -+ __u64 seqno; -+ __u64 timeout_ns; - }; - - /** -@@ -172,9 +172,9 @@ struct drm_vc4_wait_seqno { - * completed. - */ - struct drm_vc4_wait_bo { -- uint32_t handle; -- uint32_t pad; -- uint64_t timeout_ns; -+ __u32 handle; -+ __u32 pad; -+ __u64 timeout_ns; - }; - - /** -@@ -184,11 +184,30 @@ struct drm_vc4_wait_bo { - * used in a future extension. - */ - struct drm_vc4_create_bo { -- uint32_t size; -- uint32_t flags; -+ __u32 size; -+ __u32 flags; - /** Returned GEM handle for the BO. */ -- uint32_t handle; -- uint32_t pad; -+ __u32 handle; -+ __u32 pad; -+}; -+ -+/** -+ * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -+ * -+ * This doesn't actually perform an mmap. Instead, it returns the -+ * offset you need to use in an mmap on the DRM device node. This -+ * means that tools like valgrind end up knowing about the mapped -+ * memory. -+ * -+ * There are currently no values for the flags argument, but it may be -+ * used in a future extension. -+ */ -+struct drm_vc4_mmap_bo { -+ /** Handle for the object being mapped. */ -+ __u32 handle; -+ __u32 flags; -+ /** offset into the drm node to use for subsequent mmap call. */ -+ __u64 offset; - }; - - /** -@@ -201,43 +220,24 @@ struct drm_vc4_create_bo { - */ - struct drm_vc4_create_shader_bo { - /* Size of the data argument. */ -- uint32_t size; -+ __u32 size; - /* Flags, currently must be 0. */ -- uint32_t flags; -+ __u32 flags; - - /* Pointer to the data. */ -- uint64_t data; -+ __u64 data; - - /** Returned GEM handle for the BO. */ -- uint32_t handle; -+ __u32 handle; - /* Pad, must be 0. */ -- uint32_t pad; --}; -- --/** -- * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. -- * -- * This doesn't actually perform an mmap. Instead, it returns the -- * offset you need to use in an mmap on the DRM device node. This -- * means that tools like valgrind end up knowing about the mapped -- * memory. -- * -- * There are currently no values for the flags argument, but it may be -- * used in a future extension. -- */ --struct drm_vc4_mmap_bo { -- /** Handle for the object being mapped. */ -- uint32_t handle; -- uint32_t flags; -- /** offset into the drm node to use for subsequent mmap call. */ -- uint64_t offset; -+ __u32 pad; - }; - - struct drm_vc4_get_hang_state_bo { -- uint32_t handle; -- uint32_t paddr; -- uint32_t size; -- uint32_t pad; -+ __u32 handle; -+ __u32 paddr; -+ __u32 size; -+ __u32 pad; - }; - - /** -@@ -246,34 +246,34 @@ struct drm_vc4_get_hang_state_bo { - */ - struct drm_vc4_get_hang_state { - /** Pointer to array of struct drm_vc4_get_hang_state_bo. */ -- uint64_t bo; -+ __u64 bo; - /** - * On input, the size of the bo array. Output is the number - * of bos to be returned. - */ -- uint32_t bo_count; -+ __u32 bo_count; - -- uint32_t start_bin, start_render; -+ __u32 start_bin, start_render; - -- uint32_t ct0ca, ct0ea; -- uint32_t ct1ca, ct1ea; -- uint32_t ct0cs, ct1cs; -- uint32_t ct0ra0, ct1ra0; -+ __u32 ct0ca, ct0ea; -+ __u32 ct1ca, ct1ea; -+ __u32 ct0cs, ct1cs; -+ __u32 ct0ra0, ct1ra0; - -- uint32_t bpca, bpcs; -- uint32_t bpoa, bpos; -+ __u32 bpca, bpcs; -+ __u32 bpoa, bpos; - -- uint32_t vpmbase; -+ __u32 vpmbase; - -- uint32_t dbge; -- uint32_t fdbgo; -- uint32_t fdbgb; -- uint32_t fdbgr; -- uint32_t fdbgs; -- uint32_t errstat; -+ __u32 dbge; -+ __u32 fdbgo; -+ __u32 fdbgb; -+ __u32 fdbgr; -+ __u32 fdbgs; -+ __u32 errstat; - - /* Pad that we may save more registers into in the future. */ -- uint32_t pad[16]; -+ __u32 pad[16]; - }; - - #endif /* _UAPI_VC4_DRM_H_ */ - -From 96201e14bde5eadd0a63d291930c6931206dd945 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 23:46:32 +0000 -Subject: [PATCH 114/251] drm/vc4: Use "hpd-gpios" for HDMI GPIO, like what - landed upstream. - -Signed-off-by: Eric Anholt ---- - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -index cf5d5c9..da37483 100644 ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -68,7 +68,7 @@ - <0x7e808000 0x100>; - interrupts = <2 8>, <2 9>; - ddc = <&i2c2>; -- hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>; -+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; - clocks = <&cprman BCM2835_PLLH_PIX>, - <&cprman BCM2835_CLOCK_HSM>; - clock-names = "pixel", "hdmi"; - -From c23f3c3bbf31b734f44040207eda9db1fdb3d565 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 7 Dec 2015 12:35:01 -0800 -Subject: [PATCH 115/251] drm/vc4: Synchronize validation code for v2 - submission upstream. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_drv.h | 24 +-- - drivers/gpu/drm/vc4/vc4_gem.c | 14 +- - drivers/gpu/drm/vc4/vc4_render_cl.c | 6 +- - drivers/gpu/drm/vc4/vc4_validate.c | 287 +++++++++++++++--------------------- - 4 files changed, 135 insertions(+), 196 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index 53dfa8d..ed93fa7 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -189,17 +189,6 @@ to_vc4_encoder(struct drm_encoder *encoder) - #define HVS_READ(offset) readl(vc4->hvs->regs + offset) - #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) - --enum vc4_bo_mode { -- VC4_MODE_UNDECIDED, -- VC4_MODE_RENDER, -- VC4_MODE_SHADER, --}; -- --struct vc4_bo_exec_state { -- struct drm_gem_cma_object *bo; -- enum vc4_bo_mode mode; --}; -- - struct vc4_exec_info { - /* Sequence number for this bin/render job. */ - uint64_t seqno; -@@ -210,7 +199,7 @@ struct vc4_exec_info { - /* This is the array of BOs that were looked up at the start of exec. - * Command validation will use indices into this array. - */ -- struct vc4_bo_exec_state *bo; -+ struct drm_gem_cma_object **bo; - uint32_t bo_count; - - /* Pointers for our position in vc4->job_list */ -@@ -238,7 +227,6 @@ struct vc4_exec_info { - * command lists. - */ - struct vc4_shader_state { -- uint8_t packet; - uint32_t addr; - /* Maximum vertex index referenced by any primitive using this - * shader state. -@@ -254,6 +242,7 @@ struct vc4_exec_info { - bool found_tile_binning_mode_config_packet; - bool found_start_tile_binning_packet; - bool found_increment_semaphore_packet; -+ bool found_flush; - uint8_t bin_tiles_x, bin_tiles_y; - struct drm_gem_cma_object *tile_bo; - uint32_t tile_alloc_offset; -@@ -265,6 +254,9 @@ struct vc4_exec_info { - uint32_t ct0ca, ct0ea; - uint32_t ct1ca, ct1ea; - -+ /* Pointer to the unvalidated bin CL (if present). */ -+ void *bin_u; -+ - /* Pointers to the shader recs. These paddr gets incremented as CL - * packets are relocated in validate_gl_shader_state, and the vaddrs - * (u and v) get incremented and size decremented as the shader recs -@@ -455,10 +447,8 @@ vc4_validate_bin_cl(struct drm_device *dev, - int - vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); - --bool vc4_use_bo(struct vc4_exec_info *exec, -- uint32_t hindex, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj); -+struct drm_gem_cma_object *vc4_use_bo(struct vc4_exec_info *exec, -+ uint32_t hindex); - - int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index fb0b92d..39f29e7 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -169,8 +169,8 @@ vc4_save_hang_state(struct drm_device *dev) - } - - for (i = 0; i < exec->bo_count; i++) { -- drm_gem_object_reference(&exec->bo[i].bo->base); -- kernel_state->bo[i] = &exec->bo[i].bo->base; -+ drm_gem_object_reference(&exec->bo[i]->base); -+ kernel_state->bo[i] = &exec->bo[i]->base; - } - - list_for_each_entry(bo, &exec->unref_list, unref_head) { -@@ -397,7 +397,7 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) - unsigned i; - - for (i = 0; i < exec->bo_count; i++) { -- bo = to_vc4_bo(&exec->bo[i].bo->base); -+ bo = to_vc4_bo(&exec->bo[i]->base); - bo->seqno = seqno; - } - -@@ -467,7 +467,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, - return -EINVAL; - } - -- exec->bo = kcalloc(exec->bo_count, sizeof(struct vc4_bo_exec_state), -+ exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *), - GFP_KERNEL); - if (!exec->bo) { - DRM_ERROR("Failed to allocate validated BO pointers\n"); -@@ -500,7 +500,7 @@ vc4_cl_lookup_bos(struct drm_device *dev, - goto fail; - } - drm_gem_object_reference(bo); -- exec->bo[i].bo = (struct drm_gem_cma_object *)bo; -+ exec->bo[i] = (struct drm_gem_cma_object *)bo; - } - spin_unlock(&file_priv->table_lock); - -@@ -591,6 +591,8 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - - exec->ct0ca = exec->exec_bo->paddr + bin_offset; - -+ exec->bin_u = bin; -+ - exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; - exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; - exec->shader_rec_size = args->shader_rec_size; -@@ -622,7 +624,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) - mutex_lock(&dev->struct_mutex); - if (exec->bo) { - for (i = 0; i < exec->bo_count; i++) -- drm_gem_object_unreference(&exec->bo[i].bo->base); -+ drm_gem_object_unreference(&exec->bo[i]->base); - kfree(exec->bo); - } - -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 8f2ec57..8a2a312 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -436,7 +436,8 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, - if (surf->hindex == ~0) - return 0; - -- if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) - return -EINVAL; - - if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { -@@ -537,7 +538,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec, - if (surf->hindex == ~0) - return 0; - -- if (!vc4_use_bo(exec, surf->hindex, VC4_MODE_RENDER, obj)) -+ *obj = vc4_use_bo(exec, surf->hindex); -+ if (!*obj) - return -EINVAL; - - if (tiling > VC4_TILING_FORMAT_LT) { -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index 2f22f19..0fb5b99 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -94,42 +94,42 @@ size_is_lt(uint32_t width, uint32_t height, int cpp) - height <= 4 * utile_height(cpp)); - } - --bool --vc4_use_bo(struct vc4_exec_info *exec, -- uint32_t hindex, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj) -+struct drm_gem_cma_object * -+vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) - { -- *obj = NULL; -+ struct drm_gem_cma_object *obj; -+ struct vc4_bo *bo; - - if (hindex >= exec->bo_count) { - DRM_ERROR("BO index %d greater than BO count %d\n", - hindex, exec->bo_count); -- return false; -+ return NULL; - } -+ obj = exec->bo[hindex]; -+ bo = to_vc4_bo(&obj->base); - -- if (exec->bo[hindex].mode != mode) { -- if (exec->bo[hindex].mode == VC4_MODE_UNDECIDED) { -- exec->bo[hindex].mode = mode; -- } else { -- DRM_ERROR("BO index %d reused with mode %d vs %d\n", -- hindex, exec->bo[hindex].mode, mode); -- return false; -- } -+ if (bo->validated_shader) { -+ DRM_ERROR("Trying to use shader BO as something other than " -+ "a shader\n"); -+ return NULL; - } - -- *obj = exec->bo[hindex].bo; -- return true; -+ return obj; -+} -+ -+static struct drm_gem_cma_object * -+vc4_use_handle(struct vc4_exec_info *exec, uint32_t gem_handles_packet_index) -+{ -+ return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index]); - } - - static bool --vc4_use_handle(struct vc4_exec_info *exec, -- uint32_t gem_handles_packet_index, -- enum vc4_bo_mode mode, -- struct drm_gem_cma_object **obj) -+validate_bin_pos(struct vc4_exec_info *exec, void *untrusted, uint32_t pos) - { -- return vc4_use_bo(exec, exec->bo_index[gem_handles_packet_index], -- mode, obj); -+ /* Note that the untrusted pointer passed to these functions is -+ * incremented past the packet byte. -+ */ -+ return (untrusted - 1 == exec->bin_u + pos); - } - - static uint32_t -@@ -202,13 +202,13 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, - } - - static int --validate_flush_all(VALIDATE_ARGS) -+validate_flush(VALIDATE_ARGS) - { -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("VC4_PACKET_FLUSH_ALL after " -- "VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 1)) { -+ DRM_ERROR("Bin CL must end with VC4_PACKET_FLUSH\n"); - return -EINVAL; - } -+ exec->found_flush = true; - - return 0; - } -@@ -233,17 +233,13 @@ validate_start_tile_binning(VALIDATE_ARGS) - static int - validate_increment_semaphore(VALIDATE_ARGS) - { -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Duplicate VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 2)) { -+ DRM_ERROR("Bin CL must end with " -+ "VC4_PACKET_INCREMENT_SEMAPHORE\n"); - return -EINVAL; - } - exec->found_increment_semaphore_packet = true; - -- /* Once we've found the semaphore increment, there should be one FLUSH -- * then the end of the command list. The FLUSH actually triggers the -- * increment, so we only need to make sure there -- */ -- - return 0; - } - -@@ -257,11 +253,6 @@ validate_indexed_prim_list(VALIDATE_ARGS) - uint32_t index_size = (*(uint8_t *)(untrusted + 0) >> 4) ? 2 : 1; - struct vc4_shader_state *shader_state; - -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -- return -EINVAL; -- } -- - /* Check overflow condition */ - if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); -@@ -272,7 +263,8 @@ validate_indexed_prim_list(VALIDATE_ARGS) - if (max_index > shader_state->max_index) - shader_state->max_index = max_index; - -- if (!vc4_use_handle(exec, 0, VC4_MODE_RENDER, &ib)) -+ ib = vc4_use_handle(exec, 0); -+ if (!ib) - return -EINVAL; - - if (offset > ib->base.size || -@@ -295,11 +287,6 @@ validate_gl_array_primitive(VALIDATE_ARGS) - uint32_t max_index; - struct vc4_shader_state *shader_state; - -- if (exec->found_increment_semaphore_packet) { -- DRM_ERROR("Drawing after VC4_PACKET_INCREMENT_SEMAPHORE\n"); -- return -EINVAL; -- } -- - /* Check overflow condition */ - if (exec->shader_state_count == 0) { - DRM_ERROR("shader state must precede primitives\n"); -@@ -329,7 +316,6 @@ validate_gl_shader_state(VALIDATE_ARGS) - return -EINVAL; - } - -- exec->shader_state[i].packet = VC4_PACKET_GL_SHADER_STATE; - exec->shader_state[i].addr = *(uint32_t *)untrusted; - exec->shader_state[i].max_index = 0; - -@@ -348,31 +334,6 @@ validate_gl_shader_state(VALIDATE_ARGS) - } - - static int --validate_nv_shader_state(VALIDATE_ARGS) --{ -- uint32_t i = exec->shader_state_count++; -- -- if (i >= exec->shader_state_size) { -- DRM_ERROR("More requests for shader states than declared\n"); -- return -EINVAL; -- } -- -- exec->shader_state[i].packet = VC4_PACKET_NV_SHADER_STATE; -- exec->shader_state[i].addr = *(uint32_t *)untrusted; -- -- if (exec->shader_state[i].addr & 15) { -- DRM_ERROR("NV shader state address 0x%08x misaligned\n", -- exec->shader_state[i].addr); -- return -EINVAL; -- } -- -- *(uint32_t *)validated = (exec->shader_state[i].addr + -- exec->shader_rec_p); -- -- return 0; --} -- --static int - validate_tile_binning_config(VALIDATE_ARGS) - { - struct drm_device *dev = exec->exec_bo->base.dev; -@@ -473,8 +434,8 @@ static const struct cmd_info { - } cmd_info[] = { - VC4_DEFINE_PACKET(VC4_PACKET_HALT, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_NOP, NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, NULL), -- VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, validate_flush_all), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH, validate_flush), -+ VC4_DEFINE_PACKET(VC4_PACKET_FLUSH_ALL, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_START_TILE_BINNING, - validate_start_tile_binning), - VC4_DEFINE_PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, -@@ -488,7 +449,6 @@ static const struct cmd_info { - VC4_DEFINE_PACKET(VC4_PACKET_PRIMITIVE_LIST_FORMAT, NULL), - - VC4_DEFINE_PACKET(VC4_PACKET_GL_SHADER_STATE, validate_gl_shader_state), -- VC4_DEFINE_PACKET(VC4_PACKET_NV_SHADER_STATE, validate_nv_shader_state), - - VC4_DEFINE_PACKET(VC4_PACKET_CONFIGURATION_BITS, NULL), - VC4_DEFINE_PACKET(VC4_PACKET_FLAT_SHADE_FLAGS, NULL), -@@ -575,8 +535,16 @@ vc4_validate_bin_cl(struct drm_device *dev, - return -EINVAL; - } - -- if (!exec->found_increment_semaphore_packet) { -- DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE\n"); -+ /* The bin CL must be ended with INCREMENT_SEMAPHORE and FLUSH. The -+ * semaphore is used to trigger the render CL to start up, and the -+ * FLUSH is what caps the bin lists with -+ * VC4_PACKET_RETURN_FROM_SUB_LIST (so they jump back to the main -+ * render CL when they get called to) and actually triggers the queued -+ * semaphore increment. -+ */ -+ if (!exec->found_increment_semaphore_packet || !exec->found_flush) { -+ DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + " -+ "VC4_PACKET_FLUSH\n"); - return -EINVAL; - } - -@@ -607,7 +575,8 @@ reloc_tex(struct vc4_exec_info *exec, - uint32_t cube_map_stride = 0; - enum vc4_texture_data_type type; - -- if (!vc4_use_bo(exec, texture_handle_index, VC4_MODE_RENDER, &tex)) -+ tex = vc4_use_bo(exec, texture_handle_index); -+ if (!tex) - return false; - - if (sample->is_direct) { -@@ -755,51 +724,28 @@ reloc_tex(struct vc4_exec_info *exec, - } - - static int --validate_shader_rec(struct drm_device *dev, -- struct vc4_exec_info *exec, -- struct vc4_shader_state *state) -+validate_gl_shader_rec(struct drm_device *dev, -+ struct vc4_exec_info *exec, -+ struct vc4_shader_state *state) - { - uint32_t *src_handles; - void *pkt_u, *pkt_v; -- enum shader_rec_reloc_type { -- RELOC_CODE, -- RELOC_VBO, -- }; -- struct shader_rec_reloc { -- enum shader_rec_reloc_type type; -- uint32_t offset; -- }; -- static const struct shader_rec_reloc gl_relocs[] = { -- { RELOC_CODE, 4 }, /* fs */ -- { RELOC_CODE, 16 }, /* vs */ -- { RELOC_CODE, 28 }, /* cs */ -- }; -- static const struct shader_rec_reloc nv_relocs[] = { -- { RELOC_CODE, 4 }, /* fs */ -- { RELOC_VBO, 12 } -+ static const uint32_t shader_reloc_offsets[] = { -+ 4, /* fs */ -+ 16, /* vs */ -+ 28, /* cs */ - }; -- const struct shader_rec_reloc *relocs; -- struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8]; -- uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size; -+ uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets); -+ struct drm_gem_cma_object *bo[shader_reloc_count + 8]; -+ uint32_t nr_attributes, nr_relocs, packet_size; - int i; -- struct vc4_validated_shader_info *shader; - -- if (state->packet == VC4_PACKET_NV_SHADER_STATE) { -- relocs = nv_relocs; -- nr_fixed_relocs = ARRAY_SIZE(nv_relocs); -- -- packet_size = 16; -- } else { -- relocs = gl_relocs; -- nr_fixed_relocs = ARRAY_SIZE(gl_relocs); -- -- nr_attributes = state->addr & 0x7; -- if (nr_attributes == 0) -- nr_attributes = 8; -- packet_size = gl_shader_rec_size(state->addr); -- } -- nr_relocs = nr_fixed_relocs + nr_attributes; -+ nr_attributes = state->addr & 0x7; -+ if (nr_attributes == 0) -+ nr_attributes = 8; -+ packet_size = gl_shader_rec_size(state->addr); - -+ nr_relocs = ARRAY_SIZE(shader_reloc_offsets) + nr_attributes; - if (nr_relocs * 4 > exec->shader_rec_size) { - DRM_ERROR("overflowed shader recs reading %d handles " - "from %d bytes left\n", -@@ -829,21 +775,30 @@ validate_shader_rec(struct drm_device *dev, - exec->shader_rec_v += roundup(packet_size, 16); - exec->shader_rec_size -= packet_size; - -- for (i = 0; i < nr_relocs; i++) { -- enum vc4_bo_mode mode; -+ if (!(*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD)) { -+ DRM_ERROR("Multi-threaded fragment shaders not supported.\n"); -+ return -EINVAL; -+ } - -- if (i < nr_fixed_relocs && relocs[i].type == RELOC_CODE) -- mode = VC4_MODE_SHADER; -- else -- mode = VC4_MODE_RENDER; -+ for (i = 0; i < shader_reloc_count; i++) { -+ if (src_handles[i] > exec->bo_count) { -+ DRM_ERROR("Shader handle %d too big\n", src_handles[i]); -+ return -EINVAL; -+ } - -- if (!vc4_use_bo(exec, src_handles[i], mode, &bo[i])) -- return false; -+ bo[i] = exec->bo[src_handles[i]]; -+ if (!bo[i]) -+ return -EINVAL; -+ } -+ for (i = shader_reloc_count; i < nr_relocs; i++) { -+ bo[i] = vc4_use_bo(exec, src_handles[i]); -+ if (!bo[i]) -+ return -EINVAL; - } - -- for (i = 0; i < nr_fixed_relocs; i++) { -- struct vc4_bo *vc4_bo; -- uint32_t o = relocs[i].offset; -+ for (i = 0; i < shader_reloc_count; i++) { -+ struct vc4_validated_shader_info *validated_shader; -+ uint32_t o = shader_reloc_offsets[i]; - uint32_t src_offset = *(uint32_t *)(pkt_u + o); - uint32_t *texture_handles_u; - void *uniform_data_u; -@@ -851,57 +806,50 @@ validate_shader_rec(struct drm_device *dev, - - *(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset; - -- switch (relocs[i].type) { -- case RELOC_CODE: -- if (src_offset != 0) { -- DRM_ERROR("Shaders must be at offset 0 " -- "of the BO.\n"); -- goto fail; -- } -+ if (src_offset != 0) { -+ DRM_ERROR("Shaders must be at offset 0 of " -+ "the BO.\n"); -+ return -EINVAL; -+ } - -- vc4_bo = to_vc4_bo(&bo[i]->base); -- shader = vc4_bo->validated_shader; -- if (!shader) -- goto fail; -+ validated_shader = to_vc4_bo(&bo[i]->base)->validated_shader; -+ if (!validated_shader) -+ return -EINVAL; - -- if (shader->uniforms_src_size > exec->uniforms_size) { -- DRM_ERROR("Uniforms src buffer overflow\n"); -- goto fail; -- } -+ if (validated_shader->uniforms_src_size > -+ exec->uniforms_size) { -+ DRM_ERROR("Uniforms src buffer overflow\n"); -+ return -EINVAL; -+ } - -- texture_handles_u = exec->uniforms_u; -- uniform_data_u = (texture_handles_u + -- shader->num_texture_samples); -- -- memcpy(exec->uniforms_v, uniform_data_u, -- shader->uniforms_size); -- -- for (tex = 0; -- tex < shader->num_texture_samples; -- tex++) { -- if (!reloc_tex(exec, -- uniform_data_u, -- &shader->texture_samples[tex], -- texture_handles_u[tex])) { -- goto fail; -- } -- } -+ texture_handles_u = exec->uniforms_u; -+ uniform_data_u = (texture_handles_u + -+ validated_shader->num_texture_samples); - -- *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; -+ memcpy(exec->uniforms_v, uniform_data_u, -+ validated_shader->uniforms_size); - -- exec->uniforms_u += shader->uniforms_src_size; -- exec->uniforms_v += shader->uniforms_size; -- exec->uniforms_p += shader->uniforms_size; -+ for (tex = 0; -+ tex < validated_shader->num_texture_samples; -+ tex++) { -+ if (!reloc_tex(exec, -+ uniform_data_u, -+ &validated_shader->texture_samples[tex], -+ texture_handles_u[tex])) { -+ return -EINVAL; -+ } -+ } - -- break; -+ *(uint32_t *)(pkt_v + o + 4) = exec->uniforms_p; - -- case RELOC_VBO: -- break; -- } -+ exec->uniforms_u += validated_shader->uniforms_src_size; -+ exec->uniforms_v += validated_shader->uniforms_size; -+ exec->uniforms_p += validated_shader->uniforms_size; - } - - for (i = 0; i < nr_attributes; i++) { -- struct drm_gem_cma_object *vbo = bo[nr_fixed_relocs + i]; -+ struct drm_gem_cma_object *vbo = -+ bo[ARRAY_SIZE(shader_reloc_offsets) + i]; - uint32_t o = 36 + i * 8; - uint32_t offset = *(uint32_t *)(pkt_u + o + 0); - uint32_t attr_size = *(uint8_t *)(pkt_u + o + 4) + 1; -@@ -933,9 +881,6 @@ validate_shader_rec(struct drm_device *dev, - } - - return 0; -- --fail: -- return -EINVAL; - } - - int -@@ -946,7 +891,7 @@ vc4_validate_shader_recs(struct drm_device *dev, - int ret = 0; - - for (i = 0; i < exec->shader_state_count; i++) { -- ret = validate_shader_rec(dev, exec, &exec->shader_state[i]); -+ ret = validate_gl_shader_rec(dev, exec, &exec->shader_state[i]); - if (ret) - return ret; - } - -From 677855b754d34a5fc02b572d3605e0a6ff754843 Mon Sep 17 00:00:00 2001 -From: janluca -Date: Sun, 27 Dec 2015 14:34:04 +0100 -Subject: [PATCH 116/251] MMC: Do not use mmc_debug if CONFIG_MMC_BCM2835 is - not set - -If CONFIG_MMC_BCM2835 was not set the compiling of the kernel failed -since mmc_debug was not defined but used in drivers/mmc/core/quirks.c. - -This patch add a ifdef-check for CONFIG_MMC_BCM2835 to the change of -commit 64d395457f793250d2e582eeb38cc3403b1db98c ---- - drivers/mmc/core/quirks.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index 87ae2e9..b79fe14 100644 ---- a/drivers/mmc/core/quirks.c -+++ b/drivers/mmc/core/quirks.c -@@ -53,7 +53,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { - - void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - { -+#ifdef CONFIG_MMC_BCM2835 - extern unsigned mmc_debug; -+#endif - const struct mmc_fixup *f; - u64 rev = cid_rev_card(card); - -@@ -81,7 +83,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. - * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). - */ -+#ifdef CONFIG_MMC_BCM2835 - if (mmc_debug & (1<<13)) - card->quirks |= MMC_QUIRK_BLK_NO_CMD23; -+#endif - } - EXPORT_SYMBOL(mmc_fixup_device); - -From 6c2f1c57e559b53e84735f0a38ad50e8177b3f4d Mon Sep 17 00:00:00 2001 -From: Devon Fyson -Date: Wed, 30 Dec 2015 16:40:47 -0500 -Subject: [PATCH 117/251] Extend clock timeout, fix modprobe baudrate - parameter. - -Set the BSC_CLKT clock streching timeout to 35ms as per SMBus specs.\n- Increase priority of baudrate parameter passed to modprobe (in /etc/modprobe.d/*.conf or command line). Currently custom baudrates don't work because they are overridden by clock-frequency in the platform_device passed to the function. ---- - drivers/i2c/busses/i2c-bcm2708.c | 45 ++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 16 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 85f411c..b152639 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -71,7 +71,8 @@ - - #define DRV_NAME "bcm2708_i2c" - --static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; -+static unsigned int baudrate_default = CONFIG_I2C_BCM2708_BAUDRATE; -+static unsigned int baudrate; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - MODULE_PARM_DESC(baudrate, "The I2C baudrate"); - -@@ -87,6 +88,7 @@ struct bcm2708_i2c { - int irq; - struct clk *clk; - u32 cdiv; -+ u32 clk_tout; - - struct completion done; - -@@ -126,7 +128,7 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) - - static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - { -- u32 cdiv, s; -+ u32 cdiv, s, clk_tout; - u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; - int wait_loops = I2C_WAIT_LOOP_COUNT; - -@@ -134,12 +136,14 @@ static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - * Use the value that we cached in the probe. - */ - cdiv = bi->cdiv; -+ clk_tout = bi->clk_tout; - - if (bi->msg->flags & I2C_M_RD) - c |= BSC_C_INTR | BSC_C_READ; - else - c |= BSC_C_INTT; - -+ bcm2708_wr(bi, BSC_CLKT, clk_tout); - bcm2708_wr(bi, BSC_DIV, cdiv); - bcm2708_wr(bi, BSC_A, bi->msg->addr); - bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -@@ -312,21 +316,24 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - struct bcm2708_i2c *bi; - struct i2c_adapter *adap; - unsigned long bus_hz; -- u32 cdiv; -- -- if (pdev->dev.of_node) { -- u32 bus_clk_rate; -- pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -- if (pdev->id < 0) { -- dev_err(&pdev->dev, "alias is missing\n"); -- return -EINVAL; -+ u32 cdiv, clk_tout; -+ -+ if (!baudrate) { -+ baudrate = baudrate_default; -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; -+ } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); - } -- if (!of_property_read_u32(pdev->dev.of_node, -- "clock-frequency", &bus_clk_rate)) -- baudrate = bus_clk_rate; -- else -- dev_warn(&pdev->dev, -- "Could not read clock-frequency property\n"); - } - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -417,7 +424,13 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - cdiv = 0xffff; - baudrate = bus_hz / cdiv; - } -+ -+ clk_tout = 35/1000*baudrate; //35ms timeout as per SMBus specs. -+ if (clk_tout > 0xffff) -+ clk_tout = 0xffff; -+ - bi->cdiv = cdiv; -+ bi->clk_tout = clk_tout; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", - pdev->id, (unsigned long)regs->start, irq, baudrate); - -From 138eda1c8216d04356fa821fe6500771bf14fb10 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 31 Dec 2015 16:44:58 +0100 -Subject: [PATCH 118/251] bcm270x_dt: Add dwc2 and dwc-otg overlays - ---- - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 21 +++++++++++++++++++ - arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 20 ++++++++++++++++++ - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 29 ++++++++++++++++++++++++++ - 4 files changed, 72 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/dwc-otg-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/dwc2-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index be9dead..aaa8976 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,8 @@ endif - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dwc2-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += dwc-otg-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d0ef256..4d3f974 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -198,6 +198,27 @@ Params: gpiopin GPIO connected to the sensor's DATA output. - (default 4) - - -+Name: dwc-otg -+Info: Selects the dwc_otg USB controller driver which has fiq support. This -+ is the default on all except the Pi Zero which defaults to dwc2. -+Load: dtoverlay=dwc-otg -+Params: -+ -+ -+Name: dwc2 -+Info: Selects the dwc2 USB controller driver -+Load: dtoverlay=dwc2,= -+Params: dr_mode Dual role mode: "host", "peripheral" or "otg" -+ -+ g-rx-fifo-size Size of rx fifo size in gadget mode -+ -+ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -+ mode -+ -+ g-tx-fifo-size Size of periodic tx fifo per endpoint -+ (except ep0) in gadget mode -+ -+ - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] - - -diff --git a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -new file mode 100644 -index 0000000..fc48bd1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&usb>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ __overlay__ { -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -new file mode 100644 -index 0000000..90c9811 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -0,0 +1,29 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&usb>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ __overlay__ { -+ compatible = "brcm,bcm2835-usb"; -+ reg = <0x7e980000 0x10000>; -+ interrupts = <1 9>; -+ dr_mode = "otg"; -+ g-np-tx-fifo-size = <32>; -+ g-rx-fifo-size = <256>; -+ g-tx-fifo-size = <256 128 128 64 64 64 32>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ dr_mode = <&usb>, "dr_mode"; -+ g-np-tx-fifo-size = <&usb>,"g-np-tx-fifo-size:0"; -+ g-rx-fifo-size = <&usb>,"g-rx-fifo-size:0"; -+ g-tx-fifo-size = <&usb>,"g-tx-fifo-size:0"; -+ }; -+}; - -From 534a6b55b445527c1a8aef9f0328987cb2c1c1d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Jan 2016 14:42:17 +0000 -Subject: [PATCH 119/251] BCM270X_DT: Add the sdtweak overlay, for tuning - sdhost - -The sdhost overlay declares the sdhost interface and allows parameters -to be set. This is overkill for situations where the user just wants to -tweak the parameters of a pre-declared sdhost interface, so create an -sdtweak overlay that does just that. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 ++++++++++++++ - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 21 +++++++++++++++++++++ - 3 files changed, 36 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index aaa8976..4d9d640 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -53,6 +53,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4d3f974..1c6b000 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -635,6 +635,20 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - (default on: polling once at boot-time) - - -+Name: sdtweak -+Info: Tunes the bcm2835-sdhost SD/MMC driver -+Load: dtoverlay=sdtweak,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ - Name: smi - Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25! - Load: dtoverlay=smi -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -new file mode 100644 -index 0000000..74c168d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -0,0 +1,21 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sdhost>; -+ frag1: __overlay__ { -+ brcm,overclock-50 = <0>; -+ brcm,pio-limit = <1>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&frag1>,"brcm,overclock-50:0"; -+ force_pio = <&frag1>,"brcm,force-pio?"; -+ pio_limit = <&frag1>,"brcm,pio-limit:0"; -+ debug = <&frag1>,"brcm,debug?"; -+ }; -+}; - -From baed92c64a0b70434069ec7f8cb906e33f7d50b4 Mon Sep 17 00:00:00 2001 -From: Andrew Litt -Date: Mon, 11 Jan 2016 07:54:21 +0000 -Subject: [PATCH 120/251] bcm2835-mmc: Don't override bus width capabilities - from devicetree - -Take out the force setting of the MMC_CAP_4_BIT_DATA host capability -so that the result read from devicetree via mmc_of_parse() is -preserved. ---- - drivers/mmc/host/bcm2835-mmc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 43aed6e..104f93e 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1305,7 +1305,7 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - /* host controller capabilities */ - mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | - MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED | -- MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA; -+ MMC_CAP_MMC_HIGHSPEED; - - mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; - - -From 2a12d02d01ad199df7c17296243ddef8a9ca6c33 Mon Sep 17 00:00:00 2001 -From: Andrew Litt -Date: Mon, 11 Jan 2016 07:55:54 +0000 -Subject: [PATCH 121/251] SDIO-overlay: add bus_width parameter - -Allow setting of the SDIO bus width capability of the bcm2835-mmc -host. This is helpful when only a 1 bit wide bus is connected -between host and device but both host and device advertise 4 bit -mode. ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1c6b000..34a1b7f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -634,6 +634,8 @@ Params: overclock_50 Clock (in MHz) to use when the MMC framework - poll_once Disable SDIO-device polling every second - (default on: polling once at boot-time) - -+ bus_width Set the SDIO host bus width (default 4 bits) -+ - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -index afc8742..7935e7a 100644 ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -11,6 +11,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; - non-removable; -+ bus-width = <4>; - status = "okay"; - }; - }; -@@ -28,5 +29,6 @@ - - __overrides__ { - poll_once = <&sdio_mmc>,"non-removable?"; -+ bus_width = <&sdio_mmc>,"bus-width:0"; - }; - }; - -From 1589aee29dc9d1fafe145b75a018771ed993e869 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:41:45 +0100 -Subject: [PATCH 122/251] bcm2835: extend allowed range of channels and - samplerates - -Allow everything the videocore accepts. ---- - sound/arm/bcm2835-pcm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 8c86375..31e3131 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -26,9 +26,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 1, -- .channels_max = 2, -+ .channels_max = 8, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, -@@ -43,9 +43,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 44100, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 2, -- .channels_max = 2, -+ .channels_max = 8, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, - -From 768a8ae2b4eebe250c3872901caae49ecf92b483 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:42:18 +0100 -Subject: [PATCH 123/251] bcm2835: restrict channels*rate to 8*960000 - -This is required at least for SPDIF. If the bitrate goes above, -videocore will either resample the audio or corrupt it due to -underruns. Supposedly the hardware isn't designed to output -higher rates, but it can still resample it down to supported -rates. - -Some code is based on ac97_pcm.c. ---- - sound/arm/bcm2835-pcm.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 31e3131..b17ed32 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -19,6 +19,9 @@ - - #include "bcm2835.h" - -+/* The hardware can not do much more num_channels*samplerate then this value */ -+#define MAX_COMBINED_RATE 768000 -+ - /* hardware definition */ - static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -@@ -107,6 +110,31 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+ -+static int rate_hw_constraint_rate(struct snd_pcm_hw_params *params, -+ struct snd_pcm_hw_rule *rule) -+{ -+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); -+ struct snd_interval rates = { -+ .min = 8000, -+ .max = min(192000u, MAX_COMBINED_RATE / max(channels->min, 1u)), -+ }; -+ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); -+ return snd_interval_refine(rate, &rates); -+} -+ -+static int rate_hw_constraint_channels(struct snd_pcm_hw_params *params, -+ struct snd_pcm_hw_rule *rule) -+{ -+ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); -+ struct snd_interval channels_interval = { -+ .min = 1, -+ .max = min(8u, MAX_COMBINED_RATE / max(rate->min, 1u)), -+ }; -+ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); -+ return snd_interval_refine(channels, &channels_interval); -+} -+ - /* open callback */ - static int snd_bcm2835_playback_open_generic( - struct snd_pcm_substream *substream, int spdif) -@@ -188,6 +216,19 @@ static int snd_bcm2835_playback_open_generic( - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - 16); - -+ /* When playing PCM, pretend that we support the full range of channels -+ * and sample rates. The GPU can't output it, but is able to resample -+ * the data to a rate the hardware can handle it. This won't work with -+ * compressed data; the resampler would just destroy it. */ -+ if (spdif) { -+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, -+ rate_hw_constraint_rate, NULL, -+ SNDRV_PCM_HW_PARAM_CHANNELS, -1); -+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, -+ rate_hw_constraint_channels, NULL, -+ SNDRV_PCM_HW_PARAM_RATE, -1); -+ } -+ - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); - -From 19d09a4d7b66ffed44ec5b9da81304f3a11f4586 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:42:48 +0100 -Subject: [PATCH 124/251] rpi: update vc_vchi_audioserv_defs.h - -Add audioserv 3 extensions. The changes were taken from the paste -linked here: - -https://github.com/raspberrypi/linux/pull/1166#issuecomment-151917067 ---- - sound/arm/vc_vchi_audioserv_defs.h | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/sound/arm/vc_vchi_audioserv_defs.h b/sound/arm/vc_vchi_audioserv_defs.h -index af3e6eb..5f4409f 100644 ---- a/sound/arm/vc_vchi_audioserv_defs.h -+++ b/sound/arm/vc_vchi_audioserv_defs.h -@@ -16,7 +16,7 @@ - #define _VC_AUDIO_DEFS_H_ - - #define VC_AUDIOSERV_MIN_VER 1 --#define VC_AUDIOSERV_VER 2 -+#define VC_AUDIOSERV_VER 3 - - // FourCC code used for VCHI connection - #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") -@@ -36,6 +36,7 @@ typedef enum { - VC_AUDIO_MSG_TYPE_START, // Configure audio - VC_AUDIO_MSG_TYPE_STOP, // Configure audio - VC_AUDIO_MSG_TYPE_WRITE, // Configure audio -+ VC_AUDIO_MSG_TYPE_LATENCY, // request latency in cycles - VC_AUDIO_MSG_TYPE_MAX - } VC_AUDIO_MSG_TYPE; - -@@ -44,6 +45,7 @@ typedef struct { - uint32_t channels; - uint32_t samplerate; - uint32_t bps; -+ uint32_t channelmap; - - } VC_AUDIO_CONFIG_T; - -@@ -84,6 +86,12 @@ typedef struct { - uint16_t max_packet; - } VC_AUDIO_WRITE_T; - -+// query latency in samples of sink -+typedef struct -+{ -+ uint32_t dummy; -+} VC_AUDIO_LATENCY_T; -+ - // Generic result for a request (VC->HOST) - typedef struct { - int32_t success; // Success value -@@ -108,9 +116,10 @@ typedef struct { - VC_AUDIO_START_T start; - VC_AUDIO_STOP_T stop; - VC_AUDIO_WRITE_T write; -+ VC_AUDIO_LATENCY_T latency; - VC_AUDIO_RESULT_T result; - VC_AUDIO_COMPLETE_T complete; - } u; - } VC_AUDIO_MSG_T; - --#endif // _VC_AUDIO_DEFS_H_ -+#endif // _VC_AUDIO_DEFS_H_ -\ No newline at end of file - -From c507443d3266d9f0cbdc1832089ad90b8943f48b Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:43:12 +0100 -Subject: [PATCH 125/251] bcm2835: implement channel map API - -Report all layouts supported by the HDMI protocol to userspace. -Make the videocore set the correct layout according to the -userspace request. - -Some code taken from patch_hdmi.c. In particular, the HDMI channel -layout table was copied without changes - with the idea in mind that -hopefully it can be shared one day. Or at least updating it will be -simpler. - -In my tests, everything appears to work, except when outputting -FL FR RL RR. Then my receiver outputs RL on both the RL and RR -speakers, while RR is never heard. ---- - sound/arm/bcm2835-ctl.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++ - sound/arm/bcm2835-pcm.c | 22 +++- - sound/arm/bcm2835-vchiq.c | 13 +++ - sound/arm/bcm2835.h | 4 + - 4 files changed, 311 insertions(+), 4 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index aad905f..92d3f76 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -300,6 +300,281 @@ static struct snd_kcontrol_new snd_bcm2835_spdif[] = { - }, - }; - -+struct cea_channel_speaker_allocation { -+ int ca_index; -+ int speakers[8]; -+}; -+ -+#define FL SNDRV_CHMAP_FL -+#define FR SNDRV_CHMAP_FR -+#define RL SNDRV_CHMAP_RL -+#define RR SNDRV_CHMAP_RR -+#define LFE SNDRV_CHMAP_LFE -+#define FC SNDRV_CHMAP_FC -+#define RLC SNDRV_CHMAP_RLC -+#define RRC SNDRV_CHMAP_RRC -+#define RC SNDRV_CHMAP_RC -+#define FLC SNDRV_CHMAP_FLC -+#define FRC SNDRV_CHMAP_FRC -+#define FLH SNDRV_CHMAP_TFL -+#define FRH SNDRV_CHMAP_TFR -+#define FLW SNDRV_CHMAP_FLW -+#define FRW SNDRV_CHMAP_FRW -+#define TC SNDRV_CHMAP_TC -+#define FCH SNDRV_CHMAP_TFC -+ -+/* -+ * CEA-861 channel maps -+ * -+ * Stolen from sound/pci/hda/patch_hdmi.c -+ * (unlike the source, this uses SNDRV_* constants directly, as by the -+ * map_tables array in patch_hdmi.c) -+ * Unknown entries use 0, which unfortunately is SNDRV_CHMAP_UNKNOWN instead -+ * of SNDRV_CHMAP_NA. -+ */ -+static struct cea_channel_speaker_allocation channel_allocations[] = { -+/* channel: 7 6 5 4 3 2 1 0 */ -+{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, -+ /* 2.1 */ -+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, -+ /* Dolby Surround */ -+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, -+ /* surround40 */ -+{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, -+ /* surround41 */ -+{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, -+ /* surround50 */ -+{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, -+ /* surround51 */ -+{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, -+ /* 6.1 */ -+{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, -+ /* surround71 */ -+{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, -+ -+{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, -+{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, -+{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, -+}; -+ -+static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, -+ unsigned int size, unsigned int __user *tlv) -+{ -+ unsigned int __user *dst; -+ int count = 0; -+ int i; -+ -+ if (size < 8) -+ return -ENOMEM; -+ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) -+ return -EFAULT; -+ size -= 8; -+ dst = tlv + 2; -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; -+ int num_chs = 0; -+ int chs_bytes; -+ int c; -+ -+ for (c = 0; c < 8; c++) { -+ if (ch->speakers[c]) -+ num_chs++; -+ } -+ -+ chs_bytes = num_chs * 4; -+ if (size < 8) -+ return -ENOMEM; -+ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || -+ put_user(chs_bytes, dst + 1)) -+ return -EFAULT; -+ dst += 2; -+ size -= 8; -+ count += 8; -+ if (size < chs_bytes) -+ return -ENOMEM; -+ size -= chs_bytes; -+ count += chs_bytes; -+ for (c = 0; c < 8; c++) { -+ int sp = ch->speakers[7 - c]; -+ if (sp) { -+ if (put_user(sp, dst)) -+ return -EFAULT; -+ dst++; -+ } -+ } -+ } -+ if (put_user(count, tlv + 1)) -+ return -EFAULT; -+ return 0; -+} -+ -+static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; -+ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -+ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); -+ struct cea_channel_speaker_allocation *ch = NULL; -+ int cur = 0; -+ int i; -+ -+ if (!substream || !substream->runtime) -+ return -ENODEV; -+ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ if (channel_allocations[i].ca_index == chip->cea_chmap) -+ ch = &channel_allocations[i]; -+ } -+ -+ /* If no layout was set yet, return a dummy. Apparently the userspace -+ * API will be confused if we don't. */ -+ if (!ch) -+ ch = &channel_allocations[0]; -+ -+ for (i = 0; i < 8; i++) { -+ if (ch->speakers[7 - i]) -+ ucontrol->value.integer.value[cur++] = ch->speakers[7 - i]; -+ } -+ while (cur < 8) -+ ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; -+ return 0; -+} -+ -+static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; -+ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -+ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); -+ int i, prepared = 0, cea_chmap = -1; -+ int remap[8]; -+ -+ if (!substream || !substream->runtime) -+ return -ENODEV; -+ -+ switch (substream->runtime->status->state) { -+ case SNDRV_PCM_STATE_OPEN: -+ case SNDRV_PCM_STATE_SETUP: -+ break; -+ case SNDRV_PCM_STATE_PREPARED: -+ prepared = 1; -+ break; -+ default: -+ return -EBUSY; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; -+ int matches = 1; -+ int cur = 0; -+ int x; -+ memset(remap, 0, sizeof(remap)); -+ for (x = 0; x < substream->runtime->channels; x++) { -+ int sp = ucontrol->value.integer.value[x]; -+ while (cur < 8 && !ch->speakers[7 - cur]) -+ cur++; -+ if (cur >= 8) { -+ /* user has more channels than ch */ -+ matches = 0; -+ break; -+ } -+ if (ch->speakers[7 - cur] != sp) { -+ matches = 0; -+ break; -+ } -+ remap[x] = cur; -+ cur++; -+ } -+ for (x = cur; x < 8; x++) { -+ if (ch->speakers[7 - x]) { -+ /* ch has more channels than user */ -+ matches = 0; -+ break; -+ } -+ } -+ if (matches) { -+ cea_chmap = ch->ca_index; -+ break; -+ } -+ } -+ -+ if (cea_chmap < 0) -+ return -EINVAL; -+ -+ /* don't change the layout if another substream is active */ -+ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) -+ return -EBUSY; /* unsure whether this is a good error code */ -+ -+ chip->cea_chmap = cea_chmap; -+ for (i = 0; i < 8; i++) -+ chip->map_channels[i] = remap[i]; -+ if (prepared) -+ snd_bcm2835_pcm_prepare_again(substream); -+ return 0; -+} -+ -+static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) -+{ -+ struct snd_pcm_chmap *chmap; -+ struct snd_kcontrol *kctl; -+ int err, i; -+ -+ err = snd_pcm_add_chmap_ctls(chip->pcm, -+ SNDRV_PCM_STREAM_PLAYBACK, -+ NULL, 8, 0, &chmap); -+ if (err < 0) -+ return err; -+ /* override handlers */ -+ chmap->private_data = chip; -+ kctl = chmap->kctl; -+ for (i = 0; i < kctl->count; i++) -+ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; -+ kctl->get = snd_bcm2835_chmap_ctl_get; -+ kctl->put = snd_bcm2835_chmap_ctl_put; -+ kctl->tlv.c = snd_bcm2835_chmap_ctl_tlv; -+ return 0; -+} -+ - int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) - { - int err; -@@ -313,6 +588,7 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) - if (err < 0) - return err; - } -+ snd_bcm2835_add_chmap_ctl(chip); - for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index b17ed32..1067460 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -231,6 +231,9 @@ static int snd_bcm2835_playback_open_generic( - - chip->alsa_stream[idx] = alsa_stream; - -+ if (!chip->opened) -+ chip->cea_chmap = -1; -+ - chip->opened |= (1 << idx); - alsa_stream->open = 1; - alsa_stream->draining = 1; -@@ -341,8 +344,7 @@ static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) - return snd_pcm_lib_free_pages(substream); - } - --/* prepare callback */ --static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) -+int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream) - { - bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; -@@ -350,8 +352,6 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - int channels; - int err; - -- audio_info(" .. IN\n"); -- - /* notify the vchiq that it should enter spdif passthrough mode by - * setting channels=0 (see - * https://github.com/raspberrypi/linux/issues/528) */ -@@ -367,6 +367,20 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - audio_error(" error setting hw params\n"); - } - -+ return err; -+} -+ -+/* prepare callback */ -+static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; -+ -+ audio_info(" .. IN\n"); -+ -+ snd_bcm2835_pcm_prepare_again(substream); -+ - bcm2835_audio_setup(alsa_stream); - - /* in preparation of the stream, set the controls (volume level) of the stream */ -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 3de3094..8ecd2d7 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -570,6 +570,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - VC_AUDIO_MSG_T m; - AUDIO_INSTANCE_T *instance = alsa_stream->instance; - int32_t success; -+ uint32_t chmap_value; -+ int i; - int ret; - LOG_DBG(" .. IN\n"); - -@@ -593,10 +595,21 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - - instance->result = -1; - -+ if (alsa_stream->chip->cea_chmap >= 0) { -+ chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; -+ } else { -+ chmap_value = 0; /* force stereo */ -+ for (i = 0; i < 8; i++) -+ alsa_stream->chip->map_channels[i] = i; -+ } -+ for (i = 0; i < 8; i++) -+ chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); -+ - m.type = VC_AUDIO_MSG_TYPE_CONFIG; - m.u.config.channels = channels; - m.u.config.samplerate = samplerate; - m.u.config.bps = bps; -+ m.u.config.channelmap = chmap_value; - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); -diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h -index 0f71c5d..997fb69 100755 ---- a/sound/arm/bcm2835.h -+++ b/sound/arm/bcm2835.h -@@ -107,6 +107,8 @@ typedef struct bcm2835_chip { - int old_volume; /* stores the volume value whist muted */ - int dest; - int mute; -+ int cea_chmap; /* currently requested Audio InfoFrame Data Byte 4 */ -+ int map_channels[8]; - - unsigned int opened; - unsigned int spdif_status; -@@ -149,6 +151,8 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip); - int snd_bcm2835_new_pcm(bcm2835_chip_t * chip); - int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip); - -+int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream); -+ - int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream); - int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream); - int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - -From 9e7ef4d08f6e2dbcdca8f7f2833f2eb38bee78e1 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:43:35 +0100 -Subject: [PATCH 126/251] bcm2835: access controls under the audio mutex - -I don't think the ALSA framework provides any kind of automatic -synchronization within the control callbacks. We most likely need -to ensure this manually, so add locking around all access to shared -mutable data. In particular, bcm2835_audio_set_ctls() should -probably always be called under our own audio lock. ---- - sound/arm/bcm2835-ctl.c | 74 +++++++++++++++++++++++++++++++++++++++++-------- - sound/arm/bcm2835-pcm.c | 4 +++ - 2 files changed, 66 insertions(+), 12 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index 92d3f76..5b8e6bd 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -94,6 +94,9 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - { - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) -@@ -103,6 +106,7 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) - ucontrol->value.integer.value[0] = chip->dest; - -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -112,11 +116,15 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int changed = 0; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { - audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); - if (chip->mute == CTRL_VOL_MUTE) { - /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ -- return 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ -+ changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ -+ goto unlock; - } - if (changed - || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { -@@ -142,6 +150,8 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, - printk(KERN_ERR "Failed to set ALSA controls..\n"); - } - -+unlock: -+ mutex_unlock(&chip->audio_mutex); - return changed; - } - -@@ -198,10 +208,14 @@ static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) && 0xff; - -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -212,12 +226,16 @@ static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, - unsigned int val = 0; - int i, change; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); - - change = val != chip->spdif_status; - chip->spdif_status = val; - -+ mutex_unlock(&chip->audio_mutex); - return change; - } - -@@ -253,9 +271,14 @@ static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) & 0xff; -+ -+ mutex_unlock(&chip->audio_mutex); - return 0; - } - -@@ -266,11 +289,15 @@ static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, - unsigned int val = 0; - int i, change; - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); - change = val != chip->spdif_status; - chip->spdif_status = val; - -+ mutex_unlock(&chip->audio_mutex); - return change; - } - -@@ -454,11 +481,17 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - struct cea_channel_speaker_allocation *ch = NULL; -+ int res = 0; - int cur = 0; - int i; - -- if (!substream || !substream->runtime) -- return -ENODEV; -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ -+ if (!substream || !substream->runtime) { -+ res = -ENODEV; -+ goto unlock; -+ } - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { - if (channel_allocations[i].ca_index == chip->cea_chmap) -@@ -476,7 +509,10 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - } - while (cur < 8) - ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; -- return 0; -+ -+unlock: -+ mutex_unlock(&chip->audio_mutex); -+ return res; - } - - static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, -@@ -487,10 +523,16 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - int i, prepared = 0, cea_chmap = -1; -+ int res = 0; - int remap[8]; - -- if (!substream || !substream->runtime) -- return -ENODEV; -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ -+ if (!substream || !substream->runtime) { -+ res = -ENODEV; -+ goto unlock; -+ } - - switch (substream->runtime->status->state) { - case SNDRV_PCM_STATE_OPEN: -@@ -500,7 +542,8 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - prepared = 1; - break; - default: -- return -EBUSY; -+ res = -EBUSY; -+ goto unlock; - } - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -@@ -538,19 +581,26 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - } - } - -- if (cea_chmap < 0) -- return -EINVAL; -+ if (cea_chmap < 0) { -+ res = -EINVAL; -+ goto unlock; -+ } - - /* don't change the layout if another substream is active */ -- if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) -- return -EBUSY; /* unsure whether this is a good error code */ -+ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) { -+ res = -EBUSY; /* unsure whether this is a good error code */ -+ goto unlock; -+ } - - chip->cea_chmap = cea_chmap; - for (i = 0; i < 8; i++) - chip->map_channels[i] = remap[i]; - if (prepared) - snd_bcm2835_pcm_prepare_again(substream); -- return 0; -+ -+unlock: -+ mutex_unlock(&chip->audio_mutex); -+ return res; - } - - static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 1067460..48da3bb 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -379,6 +379,9 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - - audio_info(" .. IN\n"); - -+ if (mutex_lock_interruptible(&chip->audio_mutex)) -+ return -EINTR; -+ - snd_bcm2835_pcm_prepare_again(substream); - - bcm2835_audio_setup(alsa_stream); -@@ -401,6 +404,7 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - alsa_stream->buffer_size, alsa_stream->period_size, - alsa_stream->pos, runtime->frame_bits); - -+ mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - return 0; - } - -From 04d7228226398968e0fc67ec3722760f729dbfc9 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:03 +0100 -Subject: [PATCH 127/251] bcm2835: always use 2/4/8 channels for multichannel - layouts - -Pad the unused channels with NA. This means userspace needs to write -additional, silent padding channels, which is not ideal, but better -than noise. - -Works around noise at the following channel counts: 3, 5, 6, 7 ---- - sound/arm/bcm2835-ctl.c | 89 +++++++++++++++++++++++++------------------------ - 1 file changed, 45 insertions(+), 44 deletions(-) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index 5b8e6bd..dec052b 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -349,6 +349,7 @@ struct cea_channel_speaker_allocation { - #define FRW SNDRV_CHMAP_FRW - #define TC SNDRV_CHMAP_TC - #define FCH SNDRV_CHMAP_TFC -+#define NA SNDRV_CHMAP_NA - - /* - * CEA-861 channel maps -@@ -356,69 +357,69 @@ struct cea_channel_speaker_allocation { - * Stolen from sound/pci/hda/patch_hdmi.c - * (unlike the source, this uses SNDRV_* constants directly, as by the - * map_tables array in patch_hdmi.c) -- * Unknown entries use 0, which unfortunately is SNDRV_CHMAP_UNKNOWN instead -- * of SNDRV_CHMAP_NA. -+ * Entries which do not have a physical output channel use 0. Entries which -+ * require userspace to output silence use NA (SNDRV_CHMAP_NA). - */ - static struct cea_channel_speaker_allocation channel_allocations[] = { - /* channel: 7 6 5 4 3 2 1 0 */ - { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, - /* 2.1 */ --{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, -+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, NA, LFE, FR, FL } }, - /* Dolby Surround */ --{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, NA, FR, FL } }, - /* surround40 */ --{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x08, .speakers = { NA, NA, RR, RL, NA, NA, FR, FL } }, - /* surround41 */ --{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x09, .speakers = { NA, NA, RR, RL, NA, LFE, FR, FL } }, - /* surround50 */ --{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x0a, .speakers = { NA, NA, RR, RL, FC, NA, FR, FL } }, - /* surround51 */ --{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0b, .speakers = { NA, NA, RR, RL, FC, LFE, FR, FL } }, - /* 6.1 */ --{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0f, .speakers = { NA, RC, RR, RL, FC, LFE, FR, FL } }, - /* surround71 */ - { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, - --{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, --{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, --{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, --{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, --{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, --{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, --{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, --{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, --{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, --{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, --{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, --{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, --{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, --{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x03, .speakers = { NA, NA, NA, NA, FC, LFE, FR, FL } }, -+{ .ca_index = 0x04, .speakers = { NA, NA, NA, RC, NA, NA, FR, FL } }, -+{ .ca_index = 0x05, .speakers = { NA, NA, NA, RC, NA, LFE, FR, FL } }, -+{ .ca_index = 0x06, .speakers = { NA, NA, NA, RC, FC, NA, FR, FL } }, -+{ .ca_index = 0x07, .speakers = { NA, NA, NA, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0c, .speakers = { NA, RC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x0d, .speakers = { NA, RC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x0e, .speakers = { NA, RC, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x14, .speakers = { FRC, FLC, NA, NA, NA, NA, FR, FL } }, -+{ .ca_index = 0x15, .speakers = { FRC, FLC, NA, NA, NA, LFE, FR, FL } }, -+{ .ca_index = 0x16, .speakers = { FRC, FLC, NA, NA, FC, NA, FR, FL } }, -+{ .ca_index = 0x17, .speakers = { FRC, FLC, NA, NA, FC, LFE, FR, FL } }, -+{ .ca_index = 0x18, .speakers = { FRC, FLC, NA, RC, NA, NA, FR, FL } }, -+{ .ca_index = 0x19, .speakers = { FRC, FLC, NA, RC, NA, LFE, FR, FL } }, -+{ .ca_index = 0x1a, .speakers = { FRC, FLC, NA, RC, FC, NA, FR, FL } }, -+{ .ca_index = 0x1b, .speakers = { FRC, FLC, NA, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, --{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, --{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, --{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x20, .speakers = { NA, FCH, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x21, .speakers = { NA, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x22, .speakers = { TC, NA, RR, RL, FC, NA, FR, FL } }, -+{ .ca_index = 0x23, .speakers = { TC, NA, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, NA, NA, FR, FL } }, -+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, NA, LFE, FR, FL } }, -+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, --{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, NA, FR, FL } }, - { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, - }; - - -From 7a65c83035dbea9a9ac43867cc82167d64e5c233 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:24 +0100 -Subject: [PATCH 128/251] bcm2835: only allow stereo if analogue jack is - selected - -Sending more than 2 channels to videocore while outputting to analogue -mysteriously outputs heavy artifacts. So just paint it over with a -hack: if analogue is explicitly selected as destination, do not -reporting support for anything other than stereo. - -I'm not sure how to deal with the auto case (destination 0). There's -probably way to retrieve this and even to listen to plug events, but -I didn't find one yet, and it's probably not worth the trouble. Just -don't use this setting, I guess. Unless you like noise. - -Changing the setting while an audio stream is active also doesn't -work properly. We could probably interrupt running streams by -returning ENODEV or using kernel hotplug stuff (maybe), but that -also doesn't seem worth the trouble. ---- - sound/arm/bcm2835-ctl.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index dec052b..e930718 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -423,9 +423,16 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { - { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, - }; - -+static int uses_analogue(bcm2835_chip_t *chip) -+{ -+ return chip->dest == 1; -+} -+ - static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, - unsigned int size, unsigned int __user *tlv) - { -+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); -+ bcm2835_chip_t *chip = info->private_data; - unsigned int __user *dst; - int count = 0; - int i; -@@ -442,6 +449,9 @@ static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, - int chs_bytes; - int c; - -+ if (i > 0 && uses_analogue(chip)) -+ break; -+ - for (c = 0; c < 8; c++) { - if (ch->speakers[c]) - num_chs++; -@@ -552,6 +562,8 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - int matches = 1; - int cur = 0; - int x; -+ if (i > 0 && uses_analogue(chip)) -+ break; - memset(remap, 0, sizeof(remap)); - for (x = 0; x < substream->runtime->channels; x++) { - int sp = ucontrol->value.integer.value[x]; - -From 1009b70932a4980e21de9429c596dbdccac1ecdb Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Wed, 13 Jan 2016 19:44:47 +0100 -Subject: [PATCH 129/251] bcm2835: interpolate audio delay - -It appears the GPU only sends us a message all 10ms to update -the playback progress. Other than this, the playback position -(what SNDRV_PCM_IOCTL_DELAY will return) is not updated at all. -Userspace will see jitter up to 10ms in the audio position. - -Make this a bit nicer for userspace by interpolating the -position using the CPU clock. - -I'm not sure if setting snd_pcm_runtime.delay is the right -approach for this. Or if there is maybe an already existing -mechanism for position interpolation in the ALSA core. - -I only set SNDRV_PCM_INFO_BATCH because this appears to remove -at least one situation snd_pcm_runtime.delay is used, so I have -to worry less in which place I have to update this field, or -how it interacts with the rest of ALSA. - -In the future, it might be nice to use VC_AUDIO_MSG_TYPE_LATENCY. -One problem is that it requires sending a videocore message, and -waiting for a reply, which could make the implementation much -harder due to locking and synchronization requirements. ---- - sound/arm/bcm2835-pcm.c | 12 +++++++++++- - sound/arm/bcm2835.h | 1 + - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c -index 48da3bb..f3a4c6d 100755 ---- a/sound/arm/bcm2835-pcm.c -+++ b/sound/arm/bcm2835-pcm.c -@@ -25,7 +25,7 @@ - /* hardware definition */ - static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), -+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -@@ -99,6 +99,8 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) - alsa_stream->pos %= alsa_stream->buffer_size; - } - -+ alsa_stream->interpolate_start = ktime_get_ns(); -+ - if (alsa_stream->substream) { - if (new_period) - snd_pcm_period_elapsed(alsa_stream->substream); -@@ -399,6 +401,7 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); - alsa_stream->pos = 0; -+ alsa_stream->interpolate_start = ktime_get_ns(); - - audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", - alsa_stream->buffer_size, alsa_stream->period_size, -@@ -495,6 +498,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) - { - struct snd_pcm_runtime *runtime = substream->runtime; - bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; -+ u64 now = ktime_get_ns(); - - audio_info(" .. IN\n"); - -@@ -503,6 +507,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) - frames_to_bytes(runtime, runtime->control->appl_ptr), - alsa_stream->pos); - -+ /* Give userspace better delay reporting by interpolating between GPU -+ * notifications, assuming audio speed is close enough to the clock -+ * used for ktime */ -+ if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) -+ runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); -+ - audio_info(" .. OUT\n"); - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, -diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h -index 997fb69..20ef108 100755 ---- a/sound/arm/bcm2835.h -+++ b/sound/arm/bcm2835.h -@@ -137,6 +137,7 @@ typedef struct bcm2835_alsa_stream { - unsigned int pos; - unsigned int buffer_size; - unsigned int period_size; -+ u64 interpolate_start; - - uint32_t enable_fifo_irq; - irq_handler_t fifo_irq_handler; - -From fb73e06c694d16d8be119e08e71bf5601f386352 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Jan 2016 17:16:38 +0000 -Subject: [PATCH 130/251] bcm2835-sdhost: Add workaround for odd behaviour on - some cards - -For reasons not understood, the sdhost driver fails when reading -sectors very near the end of some SD cards. The problem could -be related to the similar issue that reading the final sector -of any card as part of a multiple read never completes, and the -workaround is an extension of the mechanism introduced to solve -that problem which ensures those sectors are always read singly. ---- - drivers/mmc/host/bcm2835-sdhost.c | 61 +++++++++++++++++++++++++++++++++------ - 1 file changed, 52 insertions(+), 9 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index da08998..309633c 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -173,6 +173,9 @@ struct bcm2835_host { - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+ -+ u32 sectors; /* Cached card size in sectors */ -+ u32 single_read_sectors[8]; - }; - - -@@ -277,6 +280,9 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; - -+ if (host->debug) -+ pr_info("%s: reset\n", mmc_hostname(host->mmc)); -+ - bcm2835_sdhost_set_power(host, false); - - bcm2835_sdhost_write(host, 0, SDCMD); -@@ -299,6 +305,8 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - bcm2835_sdhost_set_power(host, true); - mdelay(10); - host->clock = 0; -+ host->sectors = 0; -+ host->single_read_sectors[0] = ~0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); -@@ -309,8 +317,6 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - { - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; -- if (host->debug) -- pr_info("%s: reset\n", mmc_hostname(mmc)); - spin_lock_irqsave(&host->lock, flags); - - bcm2835_sdhost_reset_internal(host); -@@ -676,6 +682,32 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ if (!host->sectors && host->mmc->card) -+ { -+ struct mmc_card *card = host->mmc->card; -+ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -+ /* -+ * The EXT_CSD sector count is in number of 512 byte -+ * sectors. -+ */ -+ host->sectors = card->ext_csd.sectors; -+ pr_err("%s: using ext_csd!\n", mmc_hostname(host->mmc)); -+ } else { -+ /* -+ * The CSD capacity field is in units of read_blkbits. -+ * set_capacity takes units of 512 bytes. -+ */ -+ host->sectors = card->csd.capacity << -+ (card->csd.read_blkbits - 9); -+ } -+ host->single_read_sectors[0] = host->sectors - 65; -+ host->single_read_sectors[1] = host->sectors - 64; -+ host->single_read_sectors[2] = host->sectors - 33; -+ host->single_read_sectors[3] = host->sectors - 32; -+ host->single_read_sectors[4] = host->sectors - 1; -+ host->single_read_sectors[5] = ~0; /* Safety net */ -+ } -+ - host->use_dma = host->have_dma && (data->blocks > host->pio_limit); - if (!host->use_dma) { - int flags; -@@ -1246,6 +1278,10 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - - bcm2835_sdhost_finish_data(host); - } else { -+ /* Reset the timer */ -+ mod_timer(&host->pio_timer, -+ jiffies + host->pio_timeout); -+ - bcm2835_sdhost_transfer_pio(host); - - /* Reset the timer */ -@@ -1450,8 +1486,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ /* Set the timeout to 250ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/4, SDTOUT); - - if (host->debug) - pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -@@ -1566,13 +1602,20 @@ static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, - reading the final sector of the card as part of a multiple read - problematic. Detect that case and shorten the read accordingly. - */ -- /* csd.capacity is in weird units - convert to sectors */ -- u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ struct bcm2835_host *host; -+ -+ host = mmc_priv(card->host); - -- if ((direction == MMC_DATA_READ) && -- ((blk_pos + blk_size) == card_sectors)) -- blk_size--; -+ if (direction == MMC_DATA_READ) -+ { -+ int i; -+ int sector; -+ for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -+ continue; - -+ if ((blk_pos + blk_size) > sector) -+ blk_size = (blk_pos == sector) ? 1 : (sector - blk_pos); -+ } - return blk_size; - } - - -From 6671675d3a1a7df0f838121c8166b57f0fd6f0c3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 22 Jan 2016 16:03:24 +0000 -Subject: [PATCH 131/251] bcm2835-sdhost: Add debug_flags dtparam - -Bit zero disables the single-read-sectors map: - -If the default MMC driver is bcm2835-mmc: - dtoverlay=sdhost,debug_flags=1 -If the default MMC driver is bcm2835-sdhost: - dtoverlay=sdtweak,debug_flags=1 -(although the sdhost overlay may also work, sdtweak is -less invasive and will work in more circumstances). - -Also revert the timeout change, just in case. ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 ++ - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 2 ++ - drivers/mmc/host/bcm2835-sdhost.c | 26 +++++++++++++++++++++----- - 3 files changed, 25 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index 85f0725..dbe6574 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -16,6 +16,7 @@ - frag1: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -+ brcm,debug-flags = <0>; - status = "okay"; - }; - }; -@@ -25,5 +26,6 @@ - force_pio = <&frag1>,"brcm,force-pio?"; - pio_limit = <&frag1>,"brcm,pio-limit:0"; - debug = <&frag1>,"brcm,debug?"; -+ debug_flags = <&frag1>,"brcm,debug-flags:0"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -index 74c168d..b0b208c 100644 ---- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -9,6 +9,7 @@ - frag1: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -+ brcm,debug-flags = <0>; - }; - }; - -@@ -17,5 +18,6 @@ - force_pio = <&frag1>,"brcm,force-pio?"; - pio_limit = <&frag1>,"brcm,pio-limit:0"; - debug = <&frag1>,"brcm,debug?"; -+ debug_flags = <&frag1>,"brcm,debug-flags:0"; - }; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 309633c..ef9b1e6 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -174,6 +174,8 @@ struct bcm2835_host { - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - -+ u32 debug_flags; -+ - u32 sectors; /* Cached card size in sectors */ - u32 single_read_sectors[8]; - }; -@@ -682,7 +684,7 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- if (!host->sectors && host->mmc->card) -+ if (!host->sectors && host->mmc->card && !(host->debug_flags & 1)) - { - struct mmc_card *card = host->mmc->card; - if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -@@ -1486,8 +1488,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- /* Set the timeout to 250ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/4, SDTOUT); -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) - pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -@@ -1606,8 +1608,16 @@ static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, - - host = mmc_priv(card->host); - -- if (direction == MMC_DATA_READ) -- { -+ if (!host->sectors) { -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ return blk_size; -+ } -+ -+ if (direction == MMC_DATA_READ) { - int i; - int sector; - for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -@@ -1838,8 +1848,14 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); - host->debug = of_property_read_bool(node, "brcm,debug"); -+ of_property_read_u32(node, -+ "brcm,debug-flags", -+ &host->debug_flags); - } - -+ if (host->debug_flags) -+ dev_err(dev, "debug_flags=%x\n", host->debug_flags); -+ - if (host->allow_dma) { - if (node) { - host->dma_chan_tx = - -From 559103cc40fb480a58ff12002ac79dc204c5c19d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 25 Jan 2016 09:12:06 +0000 -Subject: [PATCH 132/251] BCM270X_DT: Add sdio_overclock parameter to sdio - overlay - -The sdio_overclock parameter is like the overclock_50 parameter, i.e. -it sets an alternate frequency (in MHz) to use when the MMC framework -requests 50MHz, except that it applies to the SDIO bus. - -Be aware that the actual frequencies achievable are limited to even integer -divisions of 250MHz, and that the driver will round up to include fractions -(e.g. 62 will include 62.5) but then round down to the nearest frequency. -In other words, the chosen frequency is the highest possible that is less than -the parameter value + 1. In practise this means that 62 is the only sensible -value. - -Examples: - 250MHz/4 = 62.5MHz (sdio_overclock=62) - 250MHz/2 = 125MHz (sdio_overclock=125) # Too fast ---- - arch/arm/boot/dts/overlays/README | 9 ++++++--- - arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 ++ - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 34a1b7f..709d3e4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -53,8 +53,8 @@ have its contents deleted (or commented out). - Using Overlays - ============== - --Overlays are loaded using the "dtoverlay" directive. As an example, consider the --popular lirc-rpi module, the Linux Infrared Remote Control driver. In the -+Overlays are loaded using the "dtoverlay" directive. As an example, consider -+the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the - pre-DT world this would be loaded from /etc/modules, with an explicit - "modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, - this becomes a line in config.txt: -@@ -621,9 +621,12 @@ Name: sdio - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, - and enables SDIO via GPIOs 22-27. - Load: dtoverlay=sdio,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - requests 50MHz - -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz -+ - force_pio Disable DMA support (default off) - - pio_limit Number of blocks above which to use DMA -diff --git a/arch/arm/boot/dts/overlays/sdio-overlay.dts b/arch/arm/boot/dts/overlays/sdio-overlay.dts -index 7935e7a..398bd81 100644 ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -12,6 +12,7 @@ - pinctrl-0 = <&sdio_pins>; - non-removable; - bus-width = <4>; -+ brcm,overclock-50 = <0>; - status = "okay"; - }; - }; -@@ -30,5 +31,6 @@ - __overrides__ { - poll_once = <&sdio_mmc>,"non-removable?"; - bus_width = <&sdio_mmc>,"bus-width:0"; -+ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; - }; - }; - -From 73ad066f76a5c18c621dbc86b02ff90d3adc814a Mon Sep 17 00:00:00 2001 -From: Michael Lange -Date: Thu, 21 Jan 2016 18:10:16 +0100 -Subject: [PATCH 133/251] rtc: ds1307: add support for the DT property - 'wakeup-source' - -For RTC chips with no IRQ directly connected to the SoC, the RTC chip -can be forced as a wakeup source by stating that explicitly in -the device's .dts file using the "wakeup-source" boolean property. -This will guarantee the 'wakealarm' sysfs entry is available on the -device, if supported by the RTC. - -With these changes to the driver rtc-ds1307 and the necessary entries -in the .dts file, I get an working ds1337 RTC on the Witty Pi extension -board by UUGear for the Raspberry Pi. - -An example for the entry in the .dts file: - - rtc: ds1337@68 { - compatible = "dallas,ds1337"; - reg = <0x68>; - wakeup-source; - -If the "wakeup-source" property is set, do not request an IRQ. -Set also UIE mode to unsupported, to get a working 'hwclock' binary. - -Signed-off-by: Michael Lange -Signed-off-by: Alexandre Belloni ---- - drivers/rtc/rtc-ds1307.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 1cb13fe..28ca4bf 100644 ---- a/drivers/rtc/rtc-ds1307.c -+++ b/drivers/rtc/rtc-ds1307.c -@@ -860,6 +860,7 @@ static int ds1307_probe(struct i2c_client *client, - struct chip_desc *chip = &chips[id->driver_data]; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - bool want_irq = false; -+ bool ds1307_can_wakeup_device = false; - unsigned char *buf; - struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); - irq_handler_t irq_handler = ds1307_irq; -@@ -907,6 +908,20 @@ static int ds1307_probe(struct i2c_client *client, - ds1307->write_block_data = ds1307_write_block_data; - } - -+#ifdef CONFIG_OF -+/* -+ * For devices with no IRQ directly connected to the SoC, the RTC chip -+ * can be forced as a wakeup source by stating that explicitly in -+ * the device's .dts file using the "wakeup-source" boolean property. -+ * If the "wakeup-source" property is set, don't request an IRQ. -+ * This will guarantee the 'wakealarm' sysfs entry is available on the device, -+ * if supported by the RTC. -+ */ -+ if (of_property_read_bool(client->dev.of_node, "wakeup-source")) { -+ ds1307_can_wakeup_device = true; -+ } -+#endif -+ - switch (ds1307->type) { - case ds_1337: - case ds_1339: -@@ -925,11 +940,13 @@ static int ds1307_probe(struct i2c_client *client, - ds1307->regs[0] &= ~DS1337_BIT_nEOSC; - - /* -- * Using IRQ? Disable the square wave and both alarms. -+ * Using IRQ or defined as wakeup-source? -+ * Disable the square wave and both alarms. - * For some variants, be sure alarms can trigger when we're - * running on Vbackup (BBSQI/BBSQW) - */ -- if (ds1307->client->irq > 0 && chip->alarm) { -+ if (chip->alarm && (ds1307->client->irq > 0 || -+ ds1307_can_wakeup_device)) { - ds1307->regs[0] |= DS1337_BIT_INTCN - | bbsqi_bitpos[ds1307->type]; - ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); -@@ -1144,6 +1161,14 @@ read_rtc: - return PTR_ERR(ds1307->rtc); - } - -+ if (ds1307_can_wakeup_device) { -+ /* Disable request for an IRQ */ -+ want_irq = false; -+ dev_info(&client->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n"); -+ /* We cannot support UIE mode if we do not have an IRQ line */ -+ ds1307->rtc->uie_unsupported = 1; -+ } -+ - if (want_irq) { - err = devm_request_threaded_irq(&client->dev, - client->irq, NULL, irq_handler, - -From 4f6fbb96cdcdc9e66c0521d1b0a46ca0b1d2c47d Mon Sep 17 00:00:00 2001 -From: vitalogy -Date: Tue, 19 Jan 2016 07:02:02 +0100 -Subject: [PATCH 134/251] dt-overlay: add wittypi-overlay.dts - ---- - arch/arm/boot/dts/overlays/wittypi-overlay.dts | 44 ++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/wittypi-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -new file mode 100644 -index 0000000..be5987d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -@@ -0,0 +1,44 @@ -+/* -+ * Device Tree overlay for Witty Pi extension board by UUGear -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ compatible = "gpio-leds"; -+ wittypi_led: wittypi_led { -+ label = "wittypi_led"; -+ linux,default-trigger = "default-on"; -+ gpios = <&gpio 17 0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rtc: ds1337@68 { -+ compatible = "dallas,ds1337"; -+ reg = <0x68>; -+ wakeup-source; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ led_gpio = <&wittypi_led>,"gpios:4"; -+ led_trigger = <&wittypi_led>,"linux,default-trigger"; -+ }; -+ -+}; - -From ed208e16047972bbaf88000ab35b61fa82293247 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Jan 2016 16:28:05 +0000 -Subject: [PATCH 135/251] FIXUP i2c_bcm2708: Don't change module baudrate - parameter - -Overwriting the baudrate module parameter creates an apparent -forced baudrate for i2c busses after the first. Not only does this -override the baudrate from DT it also prevents the bus ID from -being initialised. - -Also fix whitespace errors. ---- - drivers/i2c/busses/i2c-bcm2708.c | 48 +++++++++++++++++++++------------------- - 1 file changed, 25 insertions(+), 23 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index b152639..c9b8e5c 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -71,7 +71,6 @@ - - #define DRV_NAME "bcm2708_i2c" - --static unsigned int baudrate_default = CONFIG_I2C_BCM2708_BAUDRATE; - static unsigned int baudrate; - module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - MODULE_PARM_DESC(baudrate, "The I2C baudrate"); -@@ -317,25 +316,28 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - struct i2c_adapter *adap; - unsigned long bus_hz; - u32 cdiv, clk_tout; -- -- if (!baudrate) { -- baudrate = baudrate_default; -- if (pdev->dev.of_node) { -- u32 bus_clk_rate; -- pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -- if (pdev->id < 0) { -- dev_err(&pdev->dev, "alias is missing\n"); -- return -EINVAL; -- } -- if (!of_property_read_u32(pdev->dev.of_node, -- "clock-frequency", &bus_clk_rate)) -- baudrate = bus_clk_rate; -- else -- dev_warn(&pdev->dev, -- "Could not read clock-frequency property\n"); -+ u32 baud; -+ -+ baud = CONFIG_I2C_BCM2708_BAUDRATE; -+ -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; - } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baud = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); - } - -+ if (baudrate) -+ baud = baudrate; -+ - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "could not get IO memory\n"); -@@ -419,21 +421,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - } - - bus_hz = clk_get_rate(bi->clk); -- cdiv = bus_hz / baudrate; -+ cdiv = bus_hz / baud; - if (cdiv > 0xffff) { - cdiv = 0xffff; -- baudrate = bus_hz / cdiv; -+ baud = bus_hz / cdiv; - } -- -- clk_tout = 35/1000*baudrate; //35ms timeout as per SMBus specs. -- if (clk_tout > 0xffff) -+ -+ clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs. -+ if (clk_tout > 0xffff) - clk_tout = 0xffff; - - bi->cdiv = cdiv; - bi->clk_tout = clk_tout; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -- pdev->id, (unsigned long)regs->start, irq, baudrate); -+ pdev->id, (unsigned long)regs->start, irq, baud); - - return 0; - - -From 1172f40b76155e169d23802f5bfd81555571cb7e Mon Sep 17 00:00:00 2001 -From: Digital Dreamtime -Date: Thu, 4 Feb 2016 14:14:44 +0000 -Subject: [PATCH 136/251] Allow up to 24dB digital gain to be applied when - using IQAudIO DAC+ - -24db_digital_gain DT param can be used to specify that PCM512x -codec "Digital" volume control should not be limited to 0dB gain, -and if specified will allow the full 24dB gain. ---- - arch/arm/boot/dts/overlays/README | 17 +++++++++++++++-- - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 6 +++++- - sound/soc/bcm/iqaudio-dac.c | 20 ++++++++++++++------ - 3 files changed, 34 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 709d3e4..3c8436e 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -362,8 +362,21 @@ Params: - - Name: iqaudio-dacplus - Info: Configures the IQaudio DAC+ audio card --Load: dtoverlay=iqaudio-dacplus --Params: -+Load: dtoverlay=iqaudio-dacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=iqaudio-dacplus,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) - - - Name: lirc-rpi -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -index 735d8ab..e0aaf8f 100644 ---- a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -7,7 +7,7 @@ - - fragment@0 { - target = <&sound>; -- __overlay__ { -+ frag0: __overlay__ { - compatible = "iqaudio,iqaudio-dac"; - i2s-controller = <&i2s>; - status = "okay"; -@@ -36,4 +36,8 @@ - }; - }; - }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; -+ }; - }; -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 37038d4..124d7a9 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -23,14 +23,19 @@ - #include - #include - -+static bool digital_gain_0db_limit = true; -+ - static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) - { -- int ret; -- struct snd_soc_card *card = rtd->card; -- -- ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -- if (ret < 0) -- dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } - - return 0; - } -@@ -94,6 +99,9 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - dai->platform_name = NULL; - dai->platform_of_node = i2s_node; - } -+ -+ digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, -+ "iqaudio,24db_digital_gain"); - } - - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); - -From d87eb9396da3d0cf59346531fb93cfaa452760d8 Mon Sep 17 00:00:00 2001 -From: Digital Dreamtime -Date: Thu, 4 Feb 2016 20:04:00 +0000 -Subject: [PATCH 137/251] Limit PCM512x "Digital" gain to 0dB by default with - HiFiBerry DAC+ - -24db_digital_gain DT param can be used to specify that PCM512x -codec "Digital" volume control should not be limited to 0dB gain, -and if specified will allow the full 24dB gain. ---- - arch/arm/boot/dts/overlays/README | 17 +++++++++++++++-- - .../arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 6 +++++- - sound/soc/bcm/hifiberry_dacplus.c | 14 ++++++++++++++ - 3 files changed, 34 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 3c8436e..296184f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -273,8 +273,21 @@ Params: - - Name: hifiberry-dacplus - Info: Configures the HifiBerry DAC+ audio card --Load: dtoverlay=hifiberry-dacplus --Params: -+Load: dtoverlay=hifiberry-dacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=hifiberry-dacplus,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24dB_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) - - - Name: hifiberry-digi -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -index f923a48..42a0194 100644 ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -17,7 +17,7 @@ - - fragment@1 { - target = <&sound>; -- __overlay__ { -+ frag1: __overlay__ { - compatible = "hifiberry,hifiberry-dacplus"; - i2s-controller = <&i2s>; - status = "okay"; -@@ -47,4 +47,8 @@ - }; - }; - }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag1>,"hifiberry,24db_digital_gain?"; -+ }; - }; -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index a6b651c..153dbcd 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -48,6 +48,7 @@ struct pcm512x_priv { - #define CLK_48EN_RATE 24576000UL - - static bool snd_rpi_hifiberry_is_dacpro; -+static bool digital_gain_0db_limit = true; - - static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec, - int clk_id) -@@ -167,6 +168,16 @@ static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) - snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); - snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); - -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } -+ - return 0; - } - -@@ -299,6 +310,9 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - dai->platform_name = NULL; - dai->platform_of_node = i2s_node; - } -+ -+ digital_gain_0db_limit = !of_property_read_bool( -+ pdev->dev.of_node, "hifiberry,24db_digital_gain"); - } - - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); - -From f279fd3295cc2407f05e56fafb77edc800148547 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 8 Feb 2016 09:46:33 +0000 -Subject: [PATCH 138/251] BCM270X_DT: Adjust overlay README formatting - ---- - arch/arm/boot/dts/overlays/README | 414 +++++++++++++++++++------------------- - 1 file changed, 207 insertions(+), 207 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 296184f..f987565 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -83,58 +83,58 @@ Name: - Info: Configures the base Raspberry Pi hardware - Load: - Params: -- audio Set to "on" to enable the onboard ALSA audio -- interface (default "off") -+ audio Set to "on" to enable the onboard ALSA audio -+ interface (default "off") - -- i2c_arm Set to "on" to enable the ARM's i2c interface -- (default "off") -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") - -- i2c_vc Set to "on" to enable the i2c interface -- usually reserved for the VideoCore processor -- (default "off") -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") - -- i2c An alias for i2c_arm -+ i2c An alias for i2c_arm - -- i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -- (default "100000") -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") - -- i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -- (default "100000") -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") - -- i2c_baudrate An alias for i2c_arm_baudrate -+ i2c_baudrate An alias for i2c_arm_baudrate - -- i2s Set to "on" to enable the i2s interface -- (default "off") -+ i2s Set to "on" to enable the i2s interface -+ (default "off") - -- spi Set to "on" to enable the spi interfaces -- (default "off") -+ spi Set to "on" to enable the spi interfaces -+ (default "off") - -- random Set to "on" to enable the hardware random -- number generator (default "on") -+ random Set to "on" to enable the hardware random -+ number generator (default "on") - -- uart0 Set to "off" to disable uart0 (default "on") -+ uart0 Set to "off" to disable uart0 (default "on") - -- watchdog Set to "on" to enable the hardware watchdog -- (default "off") -+ watchdog Set to "on" to enable the hardware watchdog -+ (default "off") - -- act_led_trigger Choose which activity the LED tracks. -- Use "heartbeat" for a nice load indicator. -- (default "mmc") -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") - -- act_led_activelow Set to "on" to invert the sense of the LED -- (default "off") -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") - -- act_led_gpio Set which GPIO to use for the activity LED -- (in case you want to connect it to an external -- device) -- (default "16" on a non-Plus board, "47" on a -- Plus or Pi 2) -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) - - pwr_led_trigger - pwr_led_activelow - pwr_led_gpio -- As for act_led_*, but using the PWR LED. -- Not available on Model A/B boards. -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. - - N.B. It is recommended to only enable those interfaces that are needed. - Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc -@@ -149,19 +149,19 @@ Params: - Name: ads7846 - Info: ADS7846 Touch controller - Load: dtoverlay=ads7846,= --Params: cs SPI bus Chip Select (default 1) -- speed SPI bus speed (default 2MHz, max 3.25MHz) -- penirq GPIO used for PENIRQ. REQUIRED -- penirq_pull Set GPIO pull (default 0=none, 2=pullup) -- swapxy Swap x and y axis -- xmin Minimum value on the X axis (default 0) -- ymin Minimum value on the Y axis (default 0) -- xmax Maximum value on the X axis (default 4095) -- ymax Maximum value on the Y axis (default 4095) -- pmin Minimum reported pressure value (default 0) -- pmax Maximum reported pressure value (default 65535) -- xohms Touchpanel sensitivity (X-plate resistance) -- (default 400) -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2MHz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) - - penirq is required and usually xohms (60-100) has to be set as well. - Apart from that, pmax (255) and swapxy are also common. -@@ -175,12 +175,12 @@ Name: at86rf233 - Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, - connected to spi0.0 - Load: dtoverlay=at86rf233,= --Params: interrupt GPIO used for INT (default 23) -- reset GPIO used for Reset (default 24) -- sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 6000000) -- trim Fine tuning of the internal capacitance -- arrays (0=+0pF, 15=+4.5pF, default 15) -+Params: interrupt GPIO used for INT (default 23) -+ reset GPIO used for Reset (default 24) -+ sleep GPIO used for Sleep (default 25) -+ speed SPI bus speed in Hz (default 6000000) -+ trim Fine tuning of the internal capacitance -+ arrays (0=+0pF, 15=+4.5pF, default 15) - - - Name: bmp085_i2c-sensor -@@ -194,8 +194,8 @@ Name: dht11 - Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors - Also sometimes found with the part number(s) AM230x. - Load: dtoverlay=dht11,= --Params: gpiopin GPIO connected to the sensor's DATA output. -- (default 4) -+Params: gpiopin GPIO connected to the sensor's DATA output. -+ (default 4) - - - Name: dwc-otg -@@ -208,15 +208,15 @@ Params: - Name: dwc2 - Info: Selects the dwc2 USB controller driver - Load: dtoverlay=dwc2,= --Params: dr_mode Dual role mode: "host", "peripheral" or "otg" -+Params: dr_mode Dual role mode: "host", "peripheral" or "otg" - -- g-rx-fifo-size Size of rx fifo size in gadget mode -+ g-rx-fifo-size Size of rx fifo size in gadget mode - -- g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -- mode -+ g-np-tx-fifo-size Size of non-periodic tx fifo size in gadget -+ mode - -- g-tx-fifo-size Size of periodic tx fifo per endpoint -- (except ep0) in gadget mode -+ g-tx-fifo-size Size of periodic tx fifo per endpoint -+ (except ep0) in gadget mode - - - [ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] -@@ -225,9 +225,9 @@ Params: dr_mode Dual role mode: "host", "peripheral" or "otg" - Name: enc28j60 - Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) - Load: dtoverlay=enc28j60,= --Params: int_pin GPIO used for INT (default 25) -+Params: int_pin GPIO used for INT (default 25) - -- speed SPI bus speed (default 12000000) -+ speed SPI bus speed (default 12000000) - - - Name: gpio-ir -@@ -237,26 +237,26 @@ Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- - not required! The key mapping and other decoding parameters can be - configured by "ir-keytable" tool. - Load: dtoverlay=gpio-ir,= --Params: gpio_pin Input pin number. Default is 18. -+Params: gpio_pin Input pin number. Default is 18. - -- gpio_pull Desired pull-up/down state (off, down, up) -- Default is "down". -+ gpio_pull Desired pull-up/down state (off, down, up) -+ Default is "down". - -- rc-map-name Default rc keymap (can also be changed by -- ir-keytable), defaults to "rc-rc6-mce" -+ rc-map-name Default rc keymap (can also be changed by -+ ir-keytable), defaults to "rc-rc6-mce" - - - Name: gpio-poweroff - Info: Drives a GPIO high or low on reboot - Load: dtoverlay=gpio-poweroff,= --Params: gpiopin GPIO for signalling (default 26) -+Params: gpiopin GPIO for signalling (default 26) - -- active_low Set if the power control device requires a -- high->low transition to trigger a power-down. -- Note that this will require the support of a -- custom dt-blob.bin to prevent a power-down -- during the boot process, and that a reboot -- will also cause the pin to go low. -+ active_low Set if the power control device requires a -+ high->low transition to trigger a power-down. -+ Note that this will require the support of a -+ custom dt-blob.bin to prevent a power-down -+ during the boot process, and that a reboot -+ will also cause the pin to go low. - - - Name: hifiberry-amp -@@ -300,65 +300,65 @@ Name: hy28a - Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics - Default values match Texy's display shield - Load: dtoverlay=hy28a,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - -- resetgpio GPIO used to reset controller -+ resetgpio GPIO used to reset controller - -- ledgpio GPIO used to control backlight -+ ledgpio GPIO used to control backlight - - - Name: hy28b - Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics - Default values match Texy's display shield - Load: dtoverlay=hy28b,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - -- resetgpio GPIO used to reset controller -+ resetgpio GPIO used to reset controller - -- ledgpio GPIO used to control backlight -+ ledgpio GPIO used to control backlight - - - Name: i2c-gpio - Info: Adds support for software i2c controller on gpio pins - Load: dtoverlay=i2c-gpio,= --Params: i2c_gpio_sda GPIO used for I2C data (default "23") -+Params: i2c_gpio_sda GPIO used for I2C data (default "23") - -- i2c_gpio_scl GPIO used for I2C clock (default "24") -+ i2c_gpio_scl GPIO used for I2C clock (default "24") - -- i2c_gpio_delay_us Clock delay in microseconds -- (default "2" = ~100kHz) -+ i2c_gpio_delay_us Clock delay in microseconds -+ (default "2" = ~100kHz) - - - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= --Params: ds1307 Select the DS1307 device -+Params: ds1307 Select the DS1307 device - -- ds3231 Select the DS3231 device -+ ds3231 Select the DS3231 device - -- mcp7941x Select the MCP7941x device -+ mcp7941x Select the MCP7941x device - -- pcf2127 Select the PCF2127 device -+ pcf2127 Select the PCF2127 device - -- pcf8523 Select the PCF8523 device -+ pcf8523 Select the PCF8523 device - -- pcf8563 Select the PCF8563 device -+ pcf8563 Select the PCF8563 device - - - Name: i2s-mmap -@@ -396,70 +396,70 @@ Name: lirc-rpi - Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) - Consult the module documentation for more details. - Load: dtoverlay=lirc-rpi,= --Params: gpio_out_pin GPIO for output (default "17") -+Params: gpio_out_pin GPIO for output (default "17") - -- gpio_in_pin GPIO for input (default "18") -+ gpio_in_pin GPIO for input (default "18") - -- gpio_in_pull Pull up/down/off on the input pin -- (default "down") -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") - -- sense Override the IR receive auto-detection logic: -- "0" = force active-high -- "1" = force active-low -- "-1" = use auto-detection -- (default "-1") -+ sense Override the IR receive auto-detection logic: -+ "0" = force active-high -+ "1" = force active-low -+ "-1" = use auto-detection -+ (default "-1") - -- softcarrier Turn the software carrier "on" or "off" -- (default "on") -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") - -- invert "on" = invert the output pin (default "off") -+ invert "on" = invert the output pin (default "off") - -- debug "on" = enable additional debug messages -- (default "off") -+ debug "on" = enable additional debug messages -+ (default "off") - - - Name: mcp2515-can0 - Info: Configures the MCP2515 CAN controller on spi0.0 - Load: dtoverlay=mcp2515-can0,= --Params: oscillator Clock frequency for the CAN controller (Hz) -+Params: oscillator Clock frequency for the CAN controller (Hz) - -- spimaxfrequency Maximum SPI frequence (Hz) -+ spimaxfrequency Maximum SPI frequence (Hz) - -- interrupt GPIO for interrupt signal -+ interrupt GPIO for interrupt signal - - - Name: mcp2515-can1 - Info: Configures the MCP2515 CAN controller on spi0.1 - Load: dtoverlay=mcp2515-can1,= --Params: oscillator Clock frequency for the CAN controller (Hz) -+Params: oscillator Clock frequency for the CAN controller (Hz) - -- spimaxfrequency Maximum SPI frequence (Hz) -+ spimaxfrequency Maximum SPI frequence (Hz) - -- interrupt GPIO for interrupt signal -+ interrupt GPIO for interrupt signal - - - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -- force_pio Disable DMA support -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support - - - Name: mz61581 - Info: MZ61581 display by Tontec - Load: dtoverlay=mz61581,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- txbuflen Transmit buffer length (default 32768) -+ txbuflen Transmit buffer length (default 32768) - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - [ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] -@@ -474,69 +474,69 @@ Params: speed Display SPI bus speed - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: piscreen2r - Info: PiScreen 2 with resistive TP display by OzzMaker.com - Load: dtoverlay=piscreen2r,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: pitft28-capacitive - Info: Adafruit PiTFT 2.8" capacitive touch screen - Load: dtoverlay=pitft28-capacitive,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- touch-sizex Touchscreen size x (default 240) -+ touch-sizex Touchscreen size x (default 240) - -- touch-sizey Touchscreen size y (default 320) -+ touch-sizey Touchscreen size y (default 320) - -- touch-invx Touchscreen inverted x axis -+ touch-invx Touchscreen inverted x axis - -- touch-invy Touchscreen inverted y axis -+ touch-invy Touchscreen inverted y axis - -- touch-swapxy Touchscreen swapped x y axis -+ touch-swapxy Touchscreen swapped x y axis - - - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen - Load: dtoverlay=pitft28-resistive,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - - - Name: pps-gpio - Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). - Load: dtoverlay=pps-gpio,= --Params: gpiopin Input GPIO (default "18") -+Params: gpiopin Input GPIO (default "18") - - - Name: pwm -@@ -553,9 +553,9 @@ Info: Configures a single PWM channel - 4) Currently the clock must have been enabled and configured - by other means. - Load: dtoverlay=pwm,= --Params: pin Output pin (default 18) - see table -- func Pin function (default 2 = Alt5) - see above -- clock PWM clock frequency (informational) -+Params: pin Output pin (default 18) - see table -+ func Pin function (default 2 = Alt5) - see above -+ clock PWM clock frequency (informational) - - - Name: pwm-2chan -@@ -572,11 +572,11 @@ Info: Configures both PWM channels - 4) Currently the clock must have been enabled and configured - by other means. - Load: dtoverlay=pwm-2chan,= --Params: pin Output pin (default 18) - see table -- pin2 Output pin for other channel (default 19) -- func Pin function (default 2 = Alt5) - see above -- func2 Function for pin2 (default 2 = Alt5) -- clock PWM clock frequency (informational) -+Params: pin Output pin (default 18) - see table -+ pin2 Output pin for other channel (default 19) -+ func Pin function (default 2 = Alt5) - see above -+ func2 Function for pin2 (default 2 = Alt5) -+ clock PWM clock frequency (informational) - - - Name: raspidac3 -@@ -600,15 +600,15 @@ Params: - Name: rpi-display - Info: RPi-Display - 2.8" Touch Display by Watterott - Load: dtoverlay=rpi-display,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- xohms Touchpanel sensitivity (X-plate resistance) -+ xohms Touchpanel sensitivity (X-plate resistance) - - - Name: rpi-ft5406 -@@ -632,52 +632,52 @@ Params: - Name: sdhost - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock - Load: dtoverlay=sdhost,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - - - Name: sdio - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, - and enables SDIO via GPIOs 22-27. - Load: dtoverlay=sdio,= --Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- sdio_overclock SDIO Clock (in MHz) to use when the MMC -- framework requests 50MHz -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - -- poll_once Disable SDIO-device polling every second -- (default on: polling once at boot-time) -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) - -- bus_width Set the SDIO host bus width (default 4 bits) -+ bus_width Set the SDIO host bus width (default 4 bits) - - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver - Load: dtoverlay=sdtweak,= --Params: overclock_50 Clock (in MHz) to use when the MMC framework -- requests 50MHz -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz - -- force_pio Disable DMA support (default off) -+ force_pio Disable DMA support (default off) - -- pio_limit Number of blocks above which to use DMA -- (default 1) -+ pio_limit Number of blocks above which to use DMA -+ (default 1) - -- debug Enable debug output (default off) -+ debug Enable debug output (default off) - - - Name: smi -@@ -708,25 +708,25 @@ Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad - Load: dtoverlay=tinylcd35,= --Params: speed Display SPI bus speed -+Params: speed Display SPI bus speed - -- rotate Display rotation {0,90,180,270} -+ rotate Display rotation {0,90,180,270} - -- fps Delay between frame updates -+ fps Delay between frame updates - -- debug Debug output level {0-7} -+ debug Debug output level {0-7} - -- touch Enable touch panel -+ touch Enable touch panel - -- touchgpio Touch controller IRQ GPIO -+ touchgpio Touch controller IRQ GPIO - -- xohms Touchpanel: Resistance of X-plate in ohms -+ xohms Touchpanel: Resistance of X-plate in ohms - -- rtc-pcf PCF8563 Real Time Clock -+ rtc-pcf PCF8563 Real Time Clock - -- rtc-ds DS1307 Real Time Clock -+ rtc-ds DS1307 Real Time Clock - -- keypad Enable keypad -+ keypad Enable keypad - - Examples: - Display with touchpanel, PCF8563 RTC and keypad: -@@ -738,9 +738,9 @@ Params: speed Display SPI bus speed - Name: uart1 - Info: Enable uart1 in place of uart0 - Load: dtoverlay=uart1,= --Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) -+Params: txd1_pin GPIO pin for TXD1 (14, 32 or 40 - default 14) - -- rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) -+ rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - - Name: vc4-kms-v3d -@@ -763,22 +763,22 @@ Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio,= --Params: gpiopin GPIO for I/O (default "4") -+Params: gpiopin GPIO for I/O (default "4") - -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature - - - Name: w1-gpio-pullup - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *do* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio-pullup,= --Params: gpiopin GPIO for I/O (default "4") -+Params: gpiopin GPIO for I/O (default "4") - -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature - -- extpullup GPIO for external pullup (default "5") -+ extpullup GPIO for external pullup (default "5") - - - Troubleshooting - -From 414077cd3a0694b0a49a8e1bc92b574290aa8fcf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 11 Feb 2016 16:51:01 +0000 -Subject: [PATCH 139/251] bcm2835-sdhost: Major revision - -This is a significant revision of the bcm2835-sdhost driver. It -improves on the original in a number of ways: - -1) Through the use of CMD23 for reads it appears to avoid problems - reading some sectors on certain high speed cards. -2) Better atomicity to prevent crashes. -3) Higher performance. -4) Activity logging included, for easier diagnosis in the event - of a problem. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 1284 ++++++++++++++++++++----------------- - 1 file changed, 686 insertions(+), 598 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index ef9b1e6..262180b 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -2,7 +2,7 @@ - * BCM2835 SD host driver. - * - * Author: Phil Elwell -- * Copyright 2015 -+ * Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd. - * - * Based on - * mmc-bcm2835.c by Gellert Weisz -@@ -24,12 +24,13 @@ - * along with this program. If not, see . - */ - --#define SAFE_READ_THRESHOLD 4 --#define SAFE_WRITE_THRESHOLD 4 --#define ALLOW_DMA 1 --#define ALLOW_CMD23 0 --#define ALLOW_FAST 1 --#define USE_BLOCK_IRQ 1 -+#define FIFO_READ_THRESHOLD 4 -+#define FIFO_WRITE_THRESHOLD 4 -+#define ALLOW_CMD23_READ 1 -+#define ALLOW_CMD23_WRITE 0 -+#define ENABLE_LOG 1 -+#define SDDATA_FIFO_PIO_BURST 8 -+#define CMD_DALLY_US 1 - - #include - #include -@@ -48,6 +49,7 @@ - #include - #include - #include -+#include - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -110,6 +112,28 @@ - #define SDEDM_READ_THRESHOLD_SHIFT 14 - #define SDEDM_THRESHOLD_MASK 0x1f - -+#define SDEDM_FSM_MASK 0xf -+#define SDEDM_FSM_IDENTMODE 0x0 -+#define SDEDM_FSM_DATAMODE 0x1 -+#define SDEDM_FSM_READDATA 0x2 -+#define SDEDM_FSM_WRITEDATA 0x3 -+#define SDEDM_FSM_READWAIT 0x4 -+#define SDEDM_FSM_READCRC 0x5 -+#define SDEDM_FSM_WRITECRC 0x6 -+#define SDEDM_FSM_WRITEWAIT1 0x7 -+#define SDEDM_FSM_POWERDOWN 0x8 -+#define SDEDM_FSM_POWERUP 0x9 -+#define SDEDM_FSM_WRITESTART1 0xa -+#define SDEDM_FSM_WRITESTART2 0xb -+#define SDEDM_FSM_GENPULSES 0xc -+#define SDEDM_FSM_WRITEWAIT2 0xd -+#define SDEDM_FSM_STARTPOWDOWN 0xf -+ -+#define SDDATA_FIFO_WORDS 16 -+ -+#define USE_CMD23_FLAGS ((ALLOW_CMD23_READ * MMC_DATA_READ) | \ -+ (ALLOW_CMD23_WRITE * MMC_DATA_WRITE)) -+ - #define MHZ 1000000 - - -@@ -131,15 +155,17 @@ struct bcm2835_host { - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -- struct timer_list timer; /* Timer for timeouts */ -+ struct work_struct cmd_wait_wq; /* Workqueue function */ - -- struct timer_list pio_timer; /* PIO error detection timer */ -+ struct timer_list timer; /* Timer for timeouts */ - - struct sg_mapping_iter sg_miter; /* SG state for PIO */ - unsigned int blocks; /* remaining PIO blocks */ - - int irq; /* Device IRQ */ - -+ u32 cmd_quick_poll_retries; -+ u32 ns_per_fifo_word; - - /* cached registers */ - u32 hcfg; -@@ -154,16 +180,21 @@ struct bcm2835_host { - - unsigned int use_busy:1; /* Wait for busy interrupt */ - -- unsigned int debug:1; /* Enable debug output */ -+ unsigned int use_sbc:1; /* Send CMD23 */ - -- u32 thread_isr; -+ unsigned int debug:1; /* Enable debug output */ - - /*DMA part*/ - struct dma_chan *dma_chan_rx; /* DMA channel for reads */ - struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ struct dma_chan *dma_chan; /* Channel in used */ -+ struct dma_async_tx_descriptor *dma_desc; -+ u32 dma_dir; -+ u32 drain_words; -+ struct page *drain_page; -+ u32 drain_offset; - - bool allow_dma; -- bool have_dma; - bool use_dma; - /*end of DMA part*/ - -@@ -173,13 +204,98 @@ struct bcm2835_host { - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+}; - -- u32 debug_flags; -+#if ENABLE_LOG - -- u32 sectors; /* Cached card size in sectors */ -- u32 single_read_sectors[8]; -+struct log_entry_struct { -+ char event[4]; -+ u32 timestamp; -+ u32 param1; -+ u32 param2; - }; - -+typedef struct log_entry_struct LOG_ENTRY_T; -+ -+LOG_ENTRY_T *sdhost_log_buf; -+dma_addr_t sdhost_log_addr; -+static u32 sdhost_log_idx; -+static spinlock_t log_lock; -+static void __iomem *timer_base; -+ -+#define LOG_ENTRIES (256*1) -+#define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) -+ -+static void log_init(u32 bus_to_phys) -+{ -+ spin_lock_init(&log_lock); -+ sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, -+ GFP_KERNEL); -+ if (sdhost_log_buf) { -+ pr_err("sdhost: log_buf @ %p (%x)\n", -+ sdhost_log_buf, sdhost_log_addr); -+ timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); -+ if (!timer_base) -+ pr_err("sdhost: failed to remap timer\n"); -+ } -+ else -+ pr_err("sdhost: failed to allocate log buf\n"); -+} -+ -+static void log_event_impl(const char *event, u32 param1, u32 param2) -+{ -+ if (sdhost_log_buf) { -+ LOG_ENTRY_T *entry; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&log_lock, flags); -+ -+ entry = sdhost_log_buf + sdhost_log_idx; -+ memcpy(entry->event, event, 4); -+ entry->timestamp = (readl(timer_base + 4) & 0x3fffffff) + -+ (smp_processor_id()<<30); -+ entry->param1 = param1; -+ entry->param2 = param2; -+ sdhost_log_idx = (sdhost_log_idx + 1) % LOG_ENTRIES; -+ -+ spin_unlock_irqrestore(&log_lock, flags); -+ } -+} -+ -+static void log_dump(void) -+{ -+ if (sdhost_log_buf) { -+ LOG_ENTRY_T *entry; -+ unsigned long flags; -+ int idx; -+ -+ spin_lock_irqsave(&log_lock, flags); -+ -+ idx = sdhost_log_idx; -+ do { -+ entry = sdhost_log_buf + idx; -+ if (entry->event[0] != '\0') -+ pr_err("[%08x] %.4s %x %x\n", -+ entry->timestamp, -+ entry->event, -+ entry->param1, -+ entry->param2); -+ idx = (idx + 1) % LOG_ENTRIES; -+ } while (idx != sdhost_log_idx); -+ -+ spin_unlock_irqrestore(&log_lock, flags); -+ } -+} -+ -+#define log_event(event, param1, param2) log_event_impl(event, param1, param2) -+ -+#else -+ -+#define log_init(x) (void)0 -+#define log_event(event, param1, param2) (void)0 -+#define log_dump() (void)0 -+ -+#endif - - static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) - { -@@ -201,7 +317,7 @@ static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, - const char *label) - { - if (cmd) -- pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", -+ pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", - mmc_hostname(host->mmc), - (cmd == host->cmd) ? '>' : ' ', - label, cmd->opcode, cmd->arg, cmd->flags, -@@ -211,73 +327,74 @@ static void bcm2835_sdhost_dumpcmd(struct bcm2835_host *host, - - static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) - { -- bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -- bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -- if (host->mrq->data) -- pr_err("%s: data blocks %x blksz %x - err %d\n", -- mmc_hostname(host->mmc), -- host->mrq->data->blocks, -- host->mrq->data->blksz, -- host->mrq->data->error); -- bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ if (host->mrq) -+ { -+ bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); -+ if (host->mrq->data) -+ pr_err("%s: data blocks %x blksz %x - err %d\n", -+ mmc_hostname(host->mmc), -+ host->mrq->data->blocks, -+ host->mrq->data->blksz, -+ host->mrq->data->error); -+ bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); -+ } - -- pr_info("%s: =========== REGISTER DUMP ===========\n", -+ pr_err("%s: =========== REGISTER DUMP ===========\n", - mmc_hostname(host->mmc)); - -- pr_info("%s: SDCMD 0x%08x\n", -+ pr_err("%s: SDCMD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCMD)); -- pr_info("%s: SDARG 0x%08x\n", -+ pr_err("%s: SDARG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDARG)); -- pr_info("%s: SDTOUT 0x%08x\n", -+ pr_err("%s: SDTOUT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDTOUT)); -- pr_info("%s: SDCDIV 0x%08x\n", -+ pr_err("%s: SDCDIV 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCDIV)); -- pr_info("%s: SDRSP0 0x%08x\n", -+ pr_err("%s: SDRSP0 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP0)); -- pr_info("%s: SDRSP1 0x%08x\n", -+ pr_err("%s: SDRSP1 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP1)); -- pr_info("%s: SDRSP2 0x%08x\n", -+ pr_err("%s: SDRSP2 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP2)); -- pr_info("%s: SDRSP3 0x%08x\n", -+ pr_err("%s: SDRSP3 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP3)); -- pr_info("%s: SDHSTS 0x%08x\n", -+ pr_err("%s: SDHSTS 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHSTS)); -- pr_info("%s: SDVDD 0x%08x\n", -+ pr_err("%s: SDVDD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDVDD)); -- pr_info("%s: SDEDM 0x%08x\n", -+ pr_err("%s: SDEDM 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDEDM)); -- pr_info("%s: SDHCFG 0x%08x\n", -+ pr_err("%s: SDHCFG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHCFG)); -- pr_info("%s: SDHBCT 0x%08x\n", -+ pr_err("%s: SDHBCT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBCT)); -- pr_info("%s: SDHBLC 0x%08x\n", -+ pr_err("%s: SDHBLC 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBLC)); - -- pr_info("%s: ===========================================\n", -+ pr_err("%s: ===========================================\n", - mmc_hostname(host->mmc)); - } - -- - static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) - { - bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); - } - -- - static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - { - u32 temp; -@@ -300,26 +417,24 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - temp = bcm2835_sdhost_read(host, SDEDM); - temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; -- host->sectors = 0; -- host->single_read_sectors[0] = ~0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); - } - -- - static void bcm2835_sdhost_reset(struct mmc_host *mmc) - { - struct bcm2835_host *host = mmc_priv(mmc); - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); -+ log_event("RST<", 0, 0); - - bcm2835_sdhost_reset_internal(host); - -@@ -344,82 +459,48 @@ static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - } - } - --static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) - { -- bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -- -- if (!write_complete) { -- /* Request an IRQ for the last block */ -- host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -- /* The write has now completed. Disable the interrupt -- and clear the status flag */ -- host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -- write_complete = true; -- } -- } -+ int timediff; -+ u32 alternate_idle; -+ u32 edm; - -- return write_complete; --} -+ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ? -+ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; - --static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) --{ -- int timediff; --#ifdef DEBUG -- static struct timeval start_time; -- static int max_stall_time = 0; -- static int total_stall_time = 0; -- struct timeval before, after; -+ edm = bcm2835_sdhost_read(host, SDEDM); - -- do_gettimeofday(&before); -- if (max_stall_time == 0) -- start_time = before; --#endif -+ log_event("WTC<", edm, 0); - - timediff = 0; - - while (1) { -- u32 edm = bcm2835_sdhost_read(host, SDEDM); -- if ((edm & 0xf) == 1) -+ u32 fsm = edm & SDEDM_FSM_MASK; -+ if ((fsm == SDEDM_FSM_IDENTMODE) || -+ (fsm == SDEDM_FSM_DATAMODE)) - break; -- timediff++; -- if (timediff > 5000000) { --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + -- (after.tv_usec - before.tv_usec); -+ if (fsm == alternate_idle) { -+ bcm2835_sdhost_write(host, -+ edm | SDEDM_FORCE_DATA_MODE, -+ SDEDM); -+ break; -+ } - -- pr_err(" wait_write_complete - still waiting after %dus\n", -- timediff); --#else -- pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff++; -+ if (timediff == 100000) { -+ pr_err("%s: wait_transfer_complete - still waiting after %d retries\n", -+ mmc_hostname(host->mmc), - timediff); --#endif -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- host->data->error = -ETIMEDOUT; -+ host->mrq->data->error = -ETIMEDOUT; -+ log_event("WTC!", edm, 0); - return; - } -+ cpu_relax(); -+ edm = bcm2835_sdhost_read(host, SDEDM); - } -- --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -- -- total_stall_time += timediff; -- if (timediff > max_stall_time) -- max_stall_time = timediff; -- -- if ((after.tv_sec - start_time.tv_sec) > 10) { -- pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -- max_stall_time, total_stall_time); -- start_time = after; -- max_stall_time = 0; -- total_stall_time = 0; -- } --#endif -+ log_event("WTC>", edm, 0); - } - - static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); -@@ -427,65 +508,44 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); - static void bcm2835_sdhost_dma_complete(void *param) - { - struct bcm2835_host *host = param; -- struct dma_chan *dma_chan; -+ struct mmc_data *data = host->data; - unsigned long flags; -- u32 dir_data; - - spin_lock_irqsave(&host->lock, flags); -+ log_event("DMA<", (u32)host->data, bcm2835_sdhost_read(host, SDHSTS)); -+ log_event("DMA ", bcm2835_sdhost_read(host, SDCMD), -+ bcm2835_sdhost_read(host, SDEDM)); - -- if (host->data) { -- bool write_complete; -- if (USE_BLOCK_IRQ) -- write_complete = bcm2835_sdhost_is_write_complete(host); -- else { -- bcm2835_sdhost_wait_write_complete(host); -- write_complete = true; -- } -- pr_debug("dma_complete() - write_complete=%d\n", -- write_complete); -- -- if (write_complete || (host->data->flags & MMC_DATA_READ)) -- { -- if (write_complete) { -- dma_chan = host->dma_chan_tx; -- dir_data = DMA_TO_DEVICE; -- } else { -- dma_chan = host->dma_chan_rx; -- dir_data = DMA_FROM_DEVICE; -- } -- -- dma_unmap_sg(dma_chan->device->dev, -- host->data->sg, host->data->sg_len, -- dir_data); -+ if (host->dma_chan) { -+ dma_unmap_sg(host->dma_chan->device->dev, -+ data->sg, data->sg_len, -+ host->dma_dir); - -- bcm2835_sdhost_finish_data(host); -- } -+ host->dma_chan = NULL; - } - -- spin_unlock_irqrestore(&host->lock, flags); --} -+ if (host->drain_words) { -+ void *page; -+ u32 *buf; - --static bool data_transfer_wait(struct bcm2835_host *host) --{ -- unsigned long timeout = 1000000; -- while (timeout) -- { -- u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -- if (sdhsts & SDHSTS_DATA_FLAG) { -- bcm2835_sdhost_write(host, SDHSTS_DATA_FLAG, SDHSTS); -- break; -+ page = kmap_atomic(host->drain_page); -+ buf = page + host->drain_offset; -+ -+ while (host->drain_words) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm >> 4) & 0x1f) -+ *(buf++) = bcm2835_sdhost_read(host, -+ SDDATA); -+ host->drain_words--; - } -- timeout--; -- } -- if (timeout == 0) { -- pr_err("%s: Data %s timeout\n", -- mmc_hostname(host->mmc), -- (host->data->flags & MMC_DATA_READ) ? "read" : "write"); -- bcm2835_sdhost_dumpregs(host); -- host->data->error = -ETIMEDOUT; -- return false; -+ -+ kunmap_atomic(page); - } -- return true; -+ -+ bcm2835_sdhost_finish_data(host); -+ -+ log_event("DMA>", (u32)host->data, 0); -+ spin_unlock_irqrestore(&host->lock, flags); - } - - static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) -@@ -493,32 +553,83 @@ static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) - unsigned long flags; - size_t blksize, len; - u32 *buf; -+ unsigned long wait_max; - - blksize = host->data->blksz; - -+ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); -+ - local_irq_save(flags); - - while (blksize) { -- if (!sg_miter_next(&host->sg_miter)) -- BUG(); -+ int copy_words; -+ u32 hsts = 0; -+ -+ if (!sg_miter_next(&host->sg_miter)) { -+ host->data->error = -EINVAL; -+ break; -+ } - - len = min(host->sg_miter.length, blksize); -- BUG_ON(len % 4); -+ if (len % 4) { -+ host->data->error = -EINVAL; -+ break; -+ } - - blksize -= len; - host->sg_miter.consumed = len; - - buf = (u32 *)host->sg_miter.addr; - -- while (len) { -- if (!data_transfer_wait(host)) -- break; -+ copy_words = len/4; -+ -+ while (copy_words) { -+ int burst_words, words; -+ u32 edm; -+ -+ burst_words = SDDATA_FIFO_PIO_BURST; -+ if (burst_words > copy_words) -+ burst_words = copy_words; -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ words = ((edm >> 4) & 0x1f); -+ -+ if (words < burst_words) { -+ int fsm_state = (edm & SDEDM_FSM_MASK); -+ if ((fsm_state != SDEDM_FSM_READDATA) && -+ (fsm_state != SDEDM_FSM_READWAIT) && -+ (fsm_state != SDEDM_FSM_READCRC)) { -+ hsts = bcm2835_sdhost_read(host, -+ SDHSTS); -+ pr_err("%s: fsm %x, hsts %x\n", -+ mmc_hostname(host->mmc), -+ fsm_state, hsts); -+ if (hsts & SDHSTS_ERROR_MASK) -+ break; -+ } -+ -+ if (time_after(jiffies, wait_max)) { -+ pr_err("%s: PIO read timeout - EDM %x\n", -+ mmc_hostname(host->mmc), -+ edm); -+ hsts = SDHSTS_REW_TIME_OUT; -+ break; -+ } -+ ndelay((burst_words - words) * -+ host->ns_per_fifo_word); -+ continue; -+ } else if (words > copy_words) { -+ words = copy_words; -+ } -+ -+ copy_words -= words; - -- *(buf++) = bcm2835_sdhost_read(host, SDDATA); -- len -= 4; -+ while (words) { -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ words--; -+ } - } - -- if (host->data->error) -+ if (hsts & SDHSTS_ERROR_MASK) - break; - } - -@@ -532,32 +643,83 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - unsigned long flags; - size_t blksize, len; - u32 *buf; -+ unsigned long wait_max; - - blksize = host->data->blksz; - -+ wait_max = jiffies + msecs_to_jiffies(host->pio_timeout); -+ - local_irq_save(flags); - - while (blksize) { -- if (!sg_miter_next(&host->sg_miter)) -- BUG(); -+ int copy_words; -+ u32 hsts = 0; -+ -+ if (!sg_miter_next(&host->sg_miter)) { -+ host->data->error = -EINVAL; -+ break; -+ } - - len = min(host->sg_miter.length, blksize); -- BUG_ON(len % 4); -+ if (len % 4) { -+ host->data->error = -EINVAL; -+ break; -+ } - - blksize -= len; - host->sg_miter.consumed = len; - -- buf = host->sg_miter.addr; -+ buf = (u32 *)host->sg_miter.addr; - -- while (len) { -- if (!data_transfer_wait(host)) -- break; -+ copy_words = len/4; -+ -+ while (copy_words) { -+ int burst_words, words; -+ u32 edm; -+ -+ burst_words = SDDATA_FIFO_PIO_BURST; -+ if (burst_words > copy_words) -+ burst_words = copy_words; -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f); -+ -+ if (words < burst_words) { -+ int fsm_state = (edm & SDEDM_FSM_MASK); -+ if ((fsm_state != SDEDM_FSM_WRITEDATA) && -+ (fsm_state != SDEDM_FSM_WRITESTART1) && -+ (fsm_state != SDEDM_FSM_WRITESTART2)) { -+ hsts = bcm2835_sdhost_read(host, -+ SDHSTS); -+ pr_err("%s: fsm %x, hsts %x\n", -+ mmc_hostname(host->mmc), -+ fsm_state, hsts); -+ if (hsts & SDHSTS_ERROR_MASK) -+ break; -+ } -+ -+ if (time_after(jiffies, wait_max)) { -+ pr_err("%s: PIO write timeout - EDM %x\n", -+ mmc_hostname(host->mmc), -+ edm); -+ hsts = SDHSTS_REW_TIME_OUT; -+ break; -+ } -+ ndelay((burst_words - words) * -+ host->ns_per_fifo_word); -+ continue; -+ } else if (words > copy_words) { -+ words = copy_words; -+ } -+ -+ copy_words -= words; - -- bcm2835_sdhost_write(host, *(buf++), SDDATA); -- len -= 4; -+ while (words) { -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ words--; -+ } - } - -- if (host->data->error) -+ if (hsts & SDHSTS_ERROR_MASK) - break; - } - -@@ -566,12 +728,12 @@ static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) - local_irq_restore(flags); - } - -- - static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - { - u32 sdhsts; - bool is_read; - BUG_ON(!host->data); -+ log_event("XFP<", (u32)host->data, host->blocks); - - is_read = (host->data->flags & MMC_DATA_READ) != 0; - if (is_read) -@@ -595,28 +757,21 @@ static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) - is_read ? "read" : "write", - sdhsts); - host->data->error = -ETIMEDOUT; -- } else if (!is_read && !host->data->error) { -- /* Start a timer in case a transfer error occurs because -- there is no error interrupt */ -- mod_timer(&host->pio_timer, jiffies + host->pio_timeout); - } -+ log_event("XFP>", (u32)host->data, host->blocks); - } - -- --static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) -+static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, -+ struct mmc_data *data) - { -- u32 len, dir_data, dir_slave; -+ int len, dir_data, dir_slave; - struct dma_async_tx_descriptor *desc = NULL; - struct dma_chan *dma_chan; - -- pr_debug("bcm2835_sdhost_transfer_dma()\n"); -- -- WARN_ON(!host->data); -- -- if (!host->data) -- return; -+ log_event("PRD<", (u32)data, 0); -+ pr_debug("bcm2835_sdhost_prepare_dma()\n"); - -- if (host->data->flags & MMC_DATA_READ) { -+ if (data->flags & MMC_DATA_READ) { - dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; -@@ -625,35 +780,71 @@ static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; - } -+ log_event("PRD1", (u32)dma_chan, 0); - - BUG_ON(!dma_chan->device); - BUG_ON(!dma_chan->device->dev); -- BUG_ON(!host->data->sg); -+ BUG_ON(!data->sg); -+ -+ /* The block doesn't manage the FIFO DREQs properly for multi-block -+ transfers, so don't attempt to DMA the final few words. -+ Unfortunately this requires the final sg entry to be trimmed. -+ N.B. This code demands that the overspill is contained in -+ a single sg entry. -+ */ -+ -+ host->drain_words = 0; -+ if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) { -+ struct scatterlist *sg; -+ u32 len; -+ int i; -+ -+ len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4, -+ (u32)data->blocks * data->blksz); - -- len = dma_map_sg(dma_chan->device->dev, host->data->sg, -- host->data->sg_len, dir_data); -- if (len > 0) { -- desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, -+ for_each_sg(data->sg, sg, data->sg_len, i) { -+ if (sg_is_last(sg)) { -+ BUG_ON(sg->length < len); -+ sg->length -= len; -+ host->drain_page = (struct page *)sg->page_link; -+ host->drain_offset = sg->offset + sg->length; -+ } -+ } -+ host->drain_words = len/4; -+ } -+ -+ len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, -+ dir_data); -+ -+ log_event("PRD2", len, 0); -+ if (len > 0) -+ desc = dmaengine_prep_slave_sg(dma_chan, data->sg, - len, dir_slave, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -- } else { -- dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -- } -+ log_event("PRD3", (u32)desc, 0); -+ - if (desc) { - desc->callback = bcm2835_sdhost_dma_complete; - desc->callback_param = host; -- dmaengine_submit(desc); -- dma_async_issue_pending(dma_chan); -+ host->dma_desc = desc; -+ host->dma_chan = dma_chan; -+ host->dma_dir = dir_data; - } -- -+ log_event("PDM>", (u32)data, 0); - } - -+static void bcm2835_sdhost_start_dma(struct bcm2835_host *host) -+{ -+ log_event("SDMA", (u32)host->data, (u32)host->dma_chan); -+ dmaengine_submit(host->dma_desc); -+ dma_async_issue_pending(host->dma_chan); -+} - - static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) - { - u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | - SDHCFG_BUSY_IRPT_EN; -- if (host->use_dma) -+ if (host->dma_desc) - host->hcfg = (host->hcfg & ~all_irqs) | - SDHCFG_BUSY_IRPT_EN; - else -@@ -664,13 +855,13 @@ static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - } - -- - static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) - { - struct mmc_data *data = cmd->data; - - WARN_ON(host->data); - -+ host->data = data; - if (!data) - return; - -@@ -679,46 +870,19 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - BUG_ON(data->blksz > host->mmc->max_blk_size); - BUG_ON(data->blocks > 65535); - -- host->data = data; - host->data_complete = 0; - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- if (!host->sectors && host->mmc->card && !(host->debug_flags & 1)) -- { -- struct mmc_card *card = host->mmc->card; -- if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -- /* -- * The EXT_CSD sector count is in number of 512 byte -- * sectors. -- */ -- host->sectors = card->ext_csd.sectors; -- pr_err("%s: using ext_csd!\n", mmc_hostname(host->mmc)); -- } else { -- /* -- * The CSD capacity field is in units of read_blkbits. -- * set_capacity takes units of 512 bytes. -- */ -- host->sectors = card->csd.capacity << -- (card->csd.read_blkbits - 9); -- } -- host->single_read_sectors[0] = host->sectors - 65; -- host->single_read_sectors[1] = host->sectors - 64; -- host->single_read_sectors[2] = host->sectors - 33; -- host->single_read_sectors[3] = host->sectors - 32; -- host->single_read_sectors[4] = host->sectors - 1; -- host->single_read_sectors[5] = ~0; /* Safety net */ -- } - -- host->use_dma = host->have_dma && (data->blocks > host->pio_limit); -- if (!host->use_dma) { -+ if (!host->dma_desc) { -+ /* Use PIO */ - int flags; - -- flags = SG_MITER_ATOMIC; - if (data->flags & MMC_DATA_READ) -- flags |= SG_MITER_TO_SG; -+ flags = SG_MITER_TO_SG; - else -- flags |= SG_MITER_FROM_SG; -+ flags = SG_MITER_FROM_SG; - sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); - host->blocks = data->blocks; - } -@@ -726,19 +890,20 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - bcm2835_sdhost_set_transfer_irqs(host); - - bcm2835_sdhost_write(host, data->blksz, SDHBCT); -- bcm2835_sdhost_write(host, host->use_dma ? data->blocks : 0, SDHBLC); -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); - - BUG_ON(!host->data); - } - -- --void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) -+bool bcm2835_sdhost_send_command(struct bcm2835_host *host, -+ struct mmc_command *cmd) - { - u32 sdcmd, sdhsts; - unsigned long timeout; - int delay; - - WARN_ON(host->cmd); -+ log_event("CMD<", cmd->opcode, cmd->arg); - - if (cmd->data) - pr_debug("%s: send_command %d 0x%x " -@@ -761,9 +926,9 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - pr_err("%s: previous command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); -- cmd->error = -EIO; -+ cmd->error = -EILSEQ; - tasklet_schedule(&host->finish_tasklet); -- return; -+ return false; - } - timeout--; - udelay(10); -@@ -791,23 +956,24 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - if (sdhsts & SDHSTS_ERROR_MASK) - bcm2835_sdhost_write(host, sdhsts, SDHSTS); - -- bcm2835_sdhost_prepare_data(host, cmd); -- -- bcm2835_sdhost_write(host, cmd->arg, SDARG); -- - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { - pr_err("%s: unsupported response type!\n", - mmc_hostname(host->mmc)); - cmd->error = -EINVAL; - tasklet_schedule(&host->finish_tasklet); -- return; -+ return false; - } - -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ - sdcmd = cmd->opcode & SDCMD_CMD_MASK; - -- if (!(cmd->flags & MMC_RSP_PRESENT)) -+ host->use_busy = 0; -+ if (!(cmd->flags & MMC_RSP_PRESENT)) { - sdcmd |= SDCMD_NO_RESPONSE; -- else { -+ } else { - if (cmd->flags & MMC_RSP_136) - sdcmd |= SDCMD_LONG_RESPONSE; - if (cmd->flags & MMC_RSP_BUSY) { -@@ -817,6 +983,7 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - } - - if (cmd->data) { -+ log_event("CMDD", cmd->data->blocks, cmd->data->blksz); - if (host->delay_after_stop) { - struct timeval now; - int time_since_stop; -@@ -839,10 +1006,12 @@ void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command * - } - - bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); --} - -+ return true; -+} - --static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, -+ unsigned long *irq_flags); - static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); - - static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) -@@ -852,6 +1021,7 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - data = host->data; - BUG_ON(!data); - -+ log_event("FDA<", (u32)host->mrq, (u32)host->cmd); - pr_debug("finish_data(error %d, stop %d, sbc %d)\n", - data->error, data->stop ? 1 : 0, - host->mrq->sbc ? 1 : 0); -@@ -859,10 +1029,7 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - -- if (data->error) { -- data->bytes_xfered = 0; -- } else -- data->bytes_xfered = data->blksz * data->blocks; -+ data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks); - - host->data_complete = 1; - -@@ -877,9 +1044,9 @@ static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) - } - else - bcm2835_sdhost_transfer_complete(host); -+ log_event("FDA>", (u32)host->mrq, (u32)host->cmd); - } - -- - static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - { - struct mmc_data *data; -@@ -891,6 +1058,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - data = host->data; - host->data = NULL; - -+ log_event("TCM<", (u32)data, data->error); - pr_debug("transfer_complete(error %d, stop %d)\n", - data->error, data->stop ? 1 : 0); - -@@ -899,88 +1067,114 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - * a) open-ended multiblock transfer (no CMD23) - * b) error in multiblock transfer - */ -- if (data->stop && -- (data->error || -- !host->mrq->sbc)) { -- host->flush_fifo = 1; -- bcm2835_sdhost_send_command(host, data->stop); -- if (host->delay_after_stop) -- do_gettimeofday(&host->stop_time); -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); -+ if (host->mrq->stop && (data->error || !host->use_sbc)) { -+ if (bcm2835_sdhost_send_command(host, host->mrq->stop)) { -+ /* No busy, so poll for completion */ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, NULL); -+ -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ } - } else { -+ bcm2835_sdhost_wait_transfer_complete(host); - tasklet_schedule(&host->finish_tasklet); - } -+ log_event("TCM>", (u32)data, 0); - } - --static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) -+/* If irq_flags is valid, the caller is in a thread context and is allowed -+ to sleep */ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host, -+ unsigned long *irq_flags) - { - u32 sdcmd; -- unsigned long timeout; -+ u32 retries; - #ifdef DEBUG - struct timeval before, after; - int timediff = 0; - #endif - -+ log_event("FCM<", (u32)host->mrq, (u32)host->cmd); - pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); - - BUG_ON(!host->cmd || !host->mrq); - --#ifdef DEBUG -- do_gettimeofday(&before); --#endif -- /* Wait max 100 ms */ -- timeout = 10000; -+ /* Poll quickly at first */ -+ -+ retries = host->cmd_quick_poll_retries; -+ if (!retries) { -+ /* Work out how many polls take 1us by timing 10us */ -+ struct timeval start, now; -+ int us_diff; -+ -+ retries = 1; -+ do { -+ int i; -+ -+ retries *= 2; -+ -+ do_gettimeofday(&start); -+ -+ for (i = 0; i < retries; i++) { -+ cpu_relax(); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ } -+ -+ do_gettimeofday(&now); -+ us_diff = (now.tv_sec - start.tv_sec) * 1000000 + -+ (now.tv_usec - start.tv_usec); -+ } while (us_diff < 10); -+ -+ host->cmd_quick_poll_retries = ((retries * us_diff + 9)*CMD_DALLY_US)/10 + 1; -+ retries = 1; // We've already waited long enough this time -+ } -+ -+ retries = host->cmd_quick_poll_retries; - for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -- (sdcmd & SDCMD_NEW_FLAG) && timeout; -- timeout--) { -- if (host->flush_fifo) { -- while (bcm2835_sdhost_read(host, SDHSTS) & -- SDHSTS_DATA_FLAG) -- (void)bcm2835_sdhost_read(host, SDDATA); -- } -- udelay(10); -+ (sdcmd & SDCMD_NEW_FLAG) && !(sdcmd & SDCMD_FAIL_FLAG) && retries; -+ retries--) { -+ cpu_relax(); - sdcmd = bcm2835_sdhost_read(host, SDCMD); - } --#ifdef DEBUG -- do_gettimeofday(&after); -- timediff = (after.tv_sec - before.tv_sec)*1000000 + -- (after.tv_usec - before.tv_usec); - -- pr_debug(" finish_command - waited %dus\n", timediff); --#endif -+ if (!retries) { -+ unsigned long wait_max; -+ -+ if (!irq_flags) { -+ /* Schedule the work */ -+ log_event("CWWQ", 0, 0); -+ schedule_work(&host->cmd_wait_wq); -+ return; -+ } -+ -+ /* Wait max 100 ms */ -+ wait_max = jiffies + msecs_to_jiffies(100); -+ while (time_before(jiffies, wait_max)) { -+ spin_unlock_irqrestore(&host->lock, *irq_flags); -+ usleep_range(1, 10); -+ spin_lock_irqsave(&host->lock, *irq_flags); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ if (!(sdcmd & SDCMD_NEW_FLAG) || -+ (sdcmd & SDCMD_FAIL_FLAG)) -+ break; -+ } -+ } - -- if (timeout == 0) { -+ /* Check for errors */ -+ if (sdcmd & SDCMD_NEW_FLAG) { - pr_err("%s: command never completed.\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_dumpregs(host); - host->cmd->error = -EIO; - tasklet_schedule(&host->finish_tasklet); - return; -- } -- -- if (host->flush_fifo) { -- for (timeout = 100; -- (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -- timeout--) { -- (void)bcm2835_sdhost_read(host, SDDATA); -- } -- host->flush_fifo = 0; -- if (timeout == 0) { -- pr_err("%s: FIFO never drained.\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -- tasklet_schedule(&host->finish_tasklet); -- return; -- } -- } -- -- /* Check for errors */ -- if (sdcmd & SDCMD_FAIL_FLAG) -- { -+ } else if (sdcmd & SDCMD_FAIL_FLAG) { - u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); - -+ /* Clear the errors */ -+ bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS); -+ - if (host->debug) - pr_info("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", - mmc_hostname(host->mmc), sdcmd, sdhsts, -@@ -1003,7 +1197,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - mmc_hostname(host->mmc), - host->cmd->opcode); - bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -+ host->cmd->error = -EILSEQ; - } - tasklet_schedule(&host->finish_tasklet); - return; -@@ -1018,31 +1212,31 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - pr_debug("%s: finish_command %08x %08x %08x %08x\n", - mmc_hostname(host->mmc), - host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); -+ log_event("RSP ", host->cmd->resp[0], host->cmd->resp[1]); - } else { - host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); - pr_debug("%s: finish_command %08x\n", - mmc_hostname(host->mmc), - host->cmd->resp[0]); -+ log_event("RSP ", host->cmd->resp[0], 0); - } - } - -- host->cmd->error = 0; -- - if (host->cmd == host->mrq->sbc) { - /* Finished CMD23, now send actual command. */ - host->cmd = NULL; -- bcm2835_sdhost_send_command(host, host->mrq->cmd); -- -- if (host->cmd->data && host->use_dma) -- /* DMA transfer starts now, PIO starts after irq */ -- bcm2835_sdhost_transfer_dma(host); -+ if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) { -+ if (host->data && host->dma_desc) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_start_dma(host); - -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); -- } else if (host->cmd == host->mrq->stop) -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, NULL); -+ } -+ } else if (host->cmd == host->mrq->stop) { - /* Finished CMD12 */ - tasklet_schedule(&host->finish_tasklet); -- else { -+ } else { - /* Processed actual command. */ - host->cmd = NULL; - if (!host->data) -@@ -1050,6 +1244,7 @@ static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) - else if (host->data_complete) - bcm2835_sdhost_transfer_complete(host); - } -+ log_event("FCM>", (u32)host->mrq, (u32)host->cmd); - } - - static void bcm2835_sdhost_timeout(unsigned long data) -@@ -1060,10 +1255,12 @@ static void bcm2835_sdhost_timeout(unsigned long data) - host = (struct bcm2835_host *)data; - - spin_lock_irqsave(&host->lock, flags); -+ log_event("TIM<", 0, 0); - - if (host->mrq) { - pr_err("%s: timeout waiting for hardware interrupt.\n", - mmc_hostname(host->mmc)); -+ log_dump(); - bcm2835_sdhost_dumpregs(host); - - if (host->data) { -@@ -1084,74 +1281,15 @@ static void bcm2835_sdhost_timeout(unsigned long data) - spin_unlock_irqrestore(&host->lock, flags); - } - --static void bcm2835_sdhost_pio_timeout(unsigned long data) -+static void bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - { -- struct bcm2835_host *host; -- unsigned long flags; -- -- host = (struct bcm2835_host *)data; -- -- spin_lock_irqsave(&host->lock, flags); -- -- if (host->data) { -- u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -- -- if (sdhsts & SDHSTS_REW_TIME_OUT) { -- pr_err("%s: transfer timeout\n", -- mmc_hostname(host->mmc)); -- if (host->debug) -- bcm2835_sdhost_dumpregs(host); -- } else { -- pr_err("%s: unexpected transfer timeout\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- } -- -- bcm2835_sdhost_write(host, SDHSTS_TRANSFER_ERROR_MASK, -- SDHSTS); -- -- host->data->error = -ETIMEDOUT; -- -- bcm2835_sdhost_finish_data(host); -- } -- -- mmiowb(); -- spin_unlock_irqrestore(&host->lock, flags); --} -- --static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) --{ -- if (enable) -- host->hcfg |= SDHCFG_SDIO_IRPT_EN; -- else -- host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -- bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- mmiowb(); --} -- --static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) --{ -- struct bcm2835_host *host = mmc_priv(mmc); -- unsigned long flags; -- -- pr_debug("%s: enable_sdio_irq(%d)\n", mmc_hostname(mmc), enable); -- spin_lock_irqsave(&host->lock, flags); -- bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -- spin_unlock_irqrestore(&host->lock, flags); --} -- --static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) --{ -- const u32 handled = (SDHSTS_REW_TIME_OUT | SDHSTS_CMD_TIME_OUT | -- SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -- SDHSTS_FIFO_ERROR); -- -+ log_event("IRQB", (u32)host->cmd, intmask); - if (!host->cmd) { - pr_err("%s: got command busy interrupt 0x%08x even " - "though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return 0; -+ return; - } - - if (!host->use_busy) { -@@ -1159,7 +1297,7 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - "though not expecting one.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return 0; -+ return; - } - host->use_busy = 0; - -@@ -1182,28 +1320,23 @@ static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) - } else if (intmask & SDHSTS_CMD_TIME_OUT) - host->cmd->error = -ETIMEDOUT; - -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); - } - else -- bcm2835_sdhost_finish_command(host); -- -- return handled; -+ bcm2835_sdhost_finish_command(host, NULL); - } - --static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) -+static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - { -- const u32 handled = (SDHSTS_REW_TIME_OUT | -- SDHSTS_CRC16_ERROR | -- SDHSTS_FIFO_ERROR); -- - /* There are no dedicated data/space available interrupt - status bits, so it is necessary to use the single shared - data/space available FIFO status bits. It is therefore not - an error to get here when there is no data transfer in - progress. */ -+ log_event("IRQD", (u32)host->data, intmask); - if (!host->data) -- return 0; -+ return; - - if (intmask & (SDHSTS_CRC16_ERROR | - SDHSTS_FIFO_ERROR | -@@ -1214,46 +1347,37 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - else - host->data->error = -ETIMEDOUT; - -- bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); -- return handled; -+ if (host->debug) { -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ } - } - -- /* Use the block interrupt for writes after the first block */ -- if (host->data->flags & MMC_DATA_WRITE) { -+ if (host->data->error) { -+ bcm2835_sdhost_finish_data(host); -+ } else if (host->data->flags & MMC_DATA_WRITE) { -+ /* Use the block interrupt for writes after the first block */ - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); - host->hcfg |= SDHCFG_BLOCK_IRPT_EN; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -- if (host->data->error) -- bcm2835_sdhost_finish_data(host); -- else -- bcm2835_sdhost_transfer_pio(host); -+ bcm2835_sdhost_transfer_pio(host); - } else { -- if (!host->data->error) { -- bcm2835_sdhost_transfer_pio(host); -- host->blocks--; -- } -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; - if ((host->blocks == 0) || host->data->error) - bcm2835_sdhost_finish_data(host); - } -- -- return handled; - } - --static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) -+static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - { -- struct dma_chan *dma_chan; -- u32 dir_data; -- const u32 handled = (SDHSTS_REW_TIME_OUT | -- SDHSTS_CRC16_ERROR | -- SDHSTS_FIFO_ERROR); -- -+ log_event("IRQK", (u32)host->data, intmask); - if (!host->data) { - pr_err("%s: got block interrupt 0x%08x even " - "though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - bcm2835_sdhost_dumpregs(host); -- return handled; -+ return; - } - - if (intmask & (SDHSTS_CRC16_ERROR | -@@ -1265,149 +1389,69 @@ static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) - else - host->data->error = -ETIMEDOUT; - -- if (host->debug) -+ if (host->debug) { -+ log_dump(); - bcm2835_sdhost_dumpregs(host); -- tasklet_schedule(&host->finish_tasklet); -- return handled; -+ } - } - -- if (!host->use_dma) { -+ if (!host->dma_desc) { - BUG_ON(!host->blocks); -- host->blocks--; -- if ((host->blocks == 0) || host->data->error) { -- /* Cancel the timer */ -- del_timer(&host->pio_timer); -- -+ if (host->data->error || (--host->blocks == 0)) { - bcm2835_sdhost_finish_data(host); - } else { -- /* Reset the timer */ -- mod_timer(&host->pio_timer, -- jiffies + host->pio_timeout); -- - bcm2835_sdhost_transfer_pio(host); -- -- /* Reset the timer */ -- mod_timer(&host->pio_timer, -- jiffies + host->pio_timeout); - } - } else if (host->data->flags & MMC_DATA_WRITE) { -- dma_chan = host->dma_chan_tx; -- dir_data = DMA_TO_DEVICE; -- dma_unmap_sg(dma_chan->device->dev, -- host->data->sg, host->data->sg_len, -- dir_data); -- - bcm2835_sdhost_finish_data(host); - } -- -- return handled; - } - -- - static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - { - irqreturn_t result = IRQ_NONE; - struct bcm2835_host *host = dev_id; -- u32 unexpected = 0, early = 0; -- int loops = 0; -+ u32 intmask; - - spin_lock(&host->lock); - -- for (loops = 0; loops < 1; loops++) { -- u32 intmask, handled; -- -- intmask = bcm2835_sdhost_read(host, SDHSTS); -- handled = intmask & (SDHSTS_BUSY_IRPT | -- SDHSTS_BLOCK_IRPT | -- SDHSTS_SDIO_IRPT | -- SDHSTS_DATA_FLAG); -- if ((handled == SDHSTS_DATA_FLAG) && -- (loops == 0) && !host->data) { -- pr_err("%s: sdhost_irq data interrupt 0x%08x even " -- "though no data operation was in progress.\n", -- mmc_hostname(host->mmc), -- (unsigned)intmask); -- -- bcm2835_sdhost_dumpregs(host); -- } -- -- if (!handled) -- break; -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ log_event("IRQ<", intmask, 0); - -- if (loops) -- early |= handled; -+ bcm2835_sdhost_write(host, -+ SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG, -+ SDHSTS); - -+ if (intmask & SDHSTS_BLOCK_IRPT) { -+ bcm2835_sdhost_block_irq(host, intmask); - result = IRQ_HANDLED; -+ } - -- /* Clear all interrupts and notifications */ -- bcm2835_sdhost_write(host, intmask, SDHSTS); -- -- if (intmask & SDHSTS_BUSY_IRPT) -- handled |= bcm2835_sdhost_busy_irq(host, intmask); -- -- /* There is no true data interrupt status bit, so it is -- necessary to qualify the data flag with the interrupt -- enable bit */ -- if ((intmask & SDHSTS_DATA_FLAG) && -- (host->hcfg & SDHCFG_DATA_IRPT_EN)) -- handled |= bcm2835_sdhost_data_irq(host, intmask); -- -- if (intmask & SDHSTS_BLOCK_IRPT) -- handled |= bcm2835_sdhost_block_irq(host, intmask); -- -- if (intmask & SDHSTS_SDIO_IRPT) { -- bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -- host->thread_isr |= SDHSTS_SDIO_IRPT; -- result = IRQ_WAKE_THREAD; -- } -+ if (intmask & SDHSTS_BUSY_IRPT) { -+ bcm2835_sdhost_busy_irq(host, intmask); -+ result = IRQ_HANDLED; -+ } - -- unexpected |= (intmask & ~handled); -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) { -+ bcm2835_sdhost_data_irq(host, intmask); -+ result = IRQ_HANDLED; - } - - mmiowb(); - -+ log_event("IRQ>", bcm2835_sdhost_read(host, SDHSTS), 0); - spin_unlock(&host->lock); - -- if (early) -- pr_debug("%s: early %x (loops %d)\n", -- mmc_hostname(host->mmc), early, loops); -- -- if (unexpected) { -- pr_err("%s: unexpected interrupt 0x%08x.\n", -- mmc_hostname(host->mmc), unexpected); -- bcm2835_sdhost_dumpregs(host); -- } -- - return result; - } - --static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) --{ -- struct bcm2835_host *host = dev_id; -- unsigned long flags; -- u32 isr; -- -- spin_lock_irqsave(&host->lock, flags); -- isr = host->thread_isr; -- host->thread_isr = 0; -- spin_unlock_irqrestore(&host->lock, flags); -- -- if (isr & SDHSTS_SDIO_IRPT) { -- sdio_run_irqs(host->mmc); -- --/* Is this necessary? Why re-enable an interrupt which is enabled? -- spin_lock_irqsave(&host->lock, flags); -- if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -- bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -- spin_unlock_irqrestore(&host->lock, flags); --*/ -- } -- -- return isr ? IRQ_HANDLED : IRQ_NONE; --} -- -- -- - void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -@@ -1417,9 +1461,8 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); - - if ((host->overclock_50 > 50) && -- (clock == 50*MHZ)) { -+ (clock == 50*MHZ)) - clock = host->overclock_50 * MHZ + (MHZ - 1); -- } - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1466,6 +1509,11 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -+ /* Calibrate some delays */ -+ -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ - if (clock > input_clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ -@@ -1501,6 +1549,7 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - { - struct bcm2835_host *host; - unsigned long flags; -+ u32 edm, fsm; - - host = mmc_priv(mmc); - -@@ -1521,6 +1570,8 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - } - - /* Reset the error statuses in case this is a retry */ -+ if (mrq->sbc) -+ mrq->sbc->error = 0; - if (mrq->cmd) - mrq->cmd->error = 0; - if (mrq->data) -@@ -1536,28 +1587,58 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - return; - } - -+ if (host->use_dma && mrq->data && -+ (mrq->data->blocks > host->pio_limit)) -+ bcm2835_sdhost_prepare_dma(host, mrq->data); -+ - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -- - host->mrq = mrq; - -- if (mrq->sbc) -- bcm2835_sdhost_send_command(host, mrq->sbc); -- else -- bcm2835_sdhost_send_command(host, mrq->cmd); -+ edm = bcm2835_sdhost_read(host, SDEDM); -+ fsm = edm & SDEDM_FSM_MASK; - -- mmiowb(); -- spin_unlock_irqrestore(&host->lock, flags); -+ log_event("REQ<", (u32)mrq, edm); -+ if ((fsm != SDEDM_FSM_IDENTMODE) && -+ (fsm != SDEDM_FSM_DATAMODE)) { -+ pr_err("%s: previous command (%d) not complete (EDM %x)\n", -+ mmc_hostname(host->mmc), -+ bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, -+ edm); -+ log_event("REQ!", (u32)mrq, edm); -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ mrq->cmd->error = -EILSEQ; -+ tasklet_schedule(&host->finish_tasklet); -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; -+ } - -- if (!mrq->sbc && mrq->cmd->data && host->use_dma) -- /* DMA transfer starts now, PIO starts after irq */ -- bcm2835_sdhost_transfer_dma(host); -+ host->use_sbc = !!mrq->sbc && -+ (host->mrq->data->flags & USE_CMD23_FLAGS); -+ if (host->use_sbc) { -+ if (bcm2835_sdhost_send_command(host, mrq->sbc)) { -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, &flags); -+ } -+ } else if (bcm2835_sdhost_send_command(host, mrq->cmd)) { -+ if (host->data && host->dma_desc) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_start_dma(host); - -- if (!host->use_busy) -- bcm2835_sdhost_finish_command(host); --} -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host, &flags); -+ } - -+ log_event("CMD ", (u32)mrq->cmd->opcode, -+ mrq->data ? (u32)mrq->data->blksz : 0); -+ mmiowb(); -+ -+ log_event("REQ>", (u32)mrq, 0); -+ spin_unlock_irqrestore(&host->lock, flags); -+} - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { -@@ -1574,6 +1655,8 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - - spin_lock_irqsave(&host->lock, flags); - -+ log_event("IOS<", ios->clock, 0); -+ - if (!ios->clock || ios->clock != host->clock) { - bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -@@ -1596,59 +1679,53 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - spin_unlock_irqrestore(&host->lock, flags); - } - --static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -- unsigned int direction, -- u32 blk_pos, int blk_size) -+static struct mmc_host_ops bcm2835_sdhost_ops = { -+ .request = bcm2835_sdhost_request, -+ .set_ios = bcm2835_sdhost_set_ios, -+ .hw_reset = bcm2835_sdhost_reset, -+}; -+ -+static void bcm2835_sdhost_cmd_wait_work(struct work_struct *work) - { -- /* There is a bug in the host controller hardware that makes -- reading the final sector of the card as part of a multiple read -- problematic. Detect that case and shorten the read accordingly. -- */ - struct bcm2835_host *host; -+ unsigned long flags; - -- host = mmc_priv(card->host); -+ host = container_of(work, struct bcm2835_host, cmd_wait_wq); - -- if (!host->sectors) { -- /* csd.capacity is in weird units - convert to sectors */ -- u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -- if ((direction == MMC_DATA_READ) && -- ((blk_pos + blk_size) == card_sectors)) -- blk_size--; -- return blk_size; -- } -+ spin_lock_irqsave(&host->lock, flags); - -- if (direction == MMC_DATA_READ) { -- int i; -- int sector; -- for (i = 0; blk_pos > (sector = host->single_read_sectors[i]); i++) -- continue; -+ log_event("CWK<", (u32)host->cmd, (u32)host->mrq); - -- if ((blk_pos + blk_size) > sector) -- blk_size = (blk_pos == sector) ? 1 : (sector - blk_pos); -+ /* -+ * If this tasklet gets rescheduled while running, it will -+ * be run again afterwards but without any active request. -+ */ -+ if (!host->mrq) { -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; - } -- return blk_size; --} - -+ bcm2835_sdhost_finish_command(host, &flags); - --static struct mmc_host_ops bcm2835_sdhost_ops = { -- .request = bcm2835_sdhost_request, -- .set_ios = bcm2835_sdhost_set_ios, -- .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -- .hw_reset = bcm2835_sdhost_reset, -- .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, --}; -+ mmiowb(); -+ -+ log_event("CWK>", (u32)host->cmd, 0); - -+ spin_unlock_irqrestore(&host->lock, flags); -+} - - static void bcm2835_sdhost_tasklet_finish(unsigned long param) - { - struct bcm2835_host *host; - unsigned long flags; - struct mmc_request *mrq; -+ struct dma_chan *terminate_chan = NULL; - - host = (struct bcm2835_host *)param; - - spin_lock_irqsave(&host->lock, flags); - -+ log_event("TSK<", (u32)host->mrq, 0); - /* - * If this tasklet gets rescheduled while running, it will - * be run again afterwards but without any active request. -@@ -1683,11 +1760,23 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - mmiowb(); - -+ host->dma_desc = NULL; -+ terminate_chan = host->dma_chan; -+ host->dma_chan = NULL; -+ - spin_unlock_irqrestore(&host->lock, flags); -- mmc_request_done(host->mmc, mrq); --} - -+ if (terminate_chan) -+ { -+ int err = dmaengine_terminate_all(terminate_chan); -+ if (err) -+ pr_err("%s: failed to terminate DMA (%d)\n", -+ mmc_hostname(host->mmc), err); -+ } - -+ mmc_request_done(host->mmc, mrq); -+ log_event("TSK>", (u32)mrq, 0); -+} - - int bcm2835_sdhost_add_host(struct bcm2835_host *host) - { -@@ -1709,10 +1798,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmc->f_max, mmc->f_min, mmc->max_busy_timeout); - - /* host controller capabilities */ -- mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | -+ mmc->caps |= - MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE | -- (ALLOW_CMD23 * MMC_CAP_CMD23); -+ ((ALLOW_CMD23_READ|ALLOW_CMD23_WRITE) * MMC_CAP_CMD23); - - spin_lock_init(&host->lock); - -@@ -1722,9 +1811,9 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - pr_err("%s: unable to initialise DMA channels. " - "Falling back to PIO\n", - mmc_hostname(mmc)); -- host->have_dma = false; -+ host->use_dma = false; - } else { -- host->have_dma = true; -+ host->use_dma = true; - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -@@ -1741,7 +1830,7 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); - } - } else { -- host->have_dma = false; -+ host->use_dma = false; - } - - mmc->max_segs = 128; -@@ -1756,16 +1845,15 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - tasklet_init(&host->finish_tasklet, - bcm2835_sdhost_tasklet_finish, (unsigned long)host); - -- setup_timer(&host->timer, bcm2835_sdhost_timeout, -- (unsigned long)host); -+ INIT_WORK(&host->cmd_wait_wq, bcm2835_sdhost_cmd_wait_work); - -- setup_timer(&host->pio_timer, bcm2835_sdhost_pio_timeout, -+ setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - - bcm2835_sdhost_init(host, 0); -- ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, -- bcm2835_sdhost_thread_irq, -- IRQF_SHARED, mmc_hostname(mmc), host); -+ -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -1776,11 +1864,11 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - mmc_add_host(mmc); - - pio_limit_string[0] = '\0'; -- if (host->have_dma && (host->pio_limit > 0)) -+ if (host->use_dma && (host->pio_limit > 0)) - sprintf(pio_limit_string, " (>%d)", host->pio_limit); - pr_info("%s: %s loaded - DMA %s%s\n", - mmc_hostname(mmc), DRIVER_NAME, -- host->have_dma ? "enabled" : "disabled", -+ host->use_dma ? "enabled" : "disabled", - pio_limit_string); - - return 0; -@@ -1810,8 +1898,11 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - mmc->ops = &bcm2835_sdhost_ops; - host = mmc_priv(mmc); - host->mmc = mmc; -+ host->cmd_quick_poll_retries = 0; - host->pio_timeout = msecs_to_jiffies(500); -+ host->pio_limit = 1; - host->max_delay = 1; /* Warn if over 1ms */ -+ host->allow_dma = 1; - spin_lock_init(&host->lock); - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -1827,13 +1918,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - return -ENODEV; - } - host->bus_addr = be32_to_cpup(addr); -+ log_init(iomem->start - host->bus_addr); - pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", - (unsigned long)host->ioaddr, - (unsigned long)iomem->start, - (unsigned long)host->bus_addr); - -- host->allow_dma = ALLOW_DMA; -- - if (node) { - /* Read any custom properties */ - of_property_read_u32(node, -@@ -1845,16 +1935,17 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,pio-limit", - &host->pio_limit); -- host->allow_dma = ALLOW_DMA && -+ host->allow_dma = - !of_property_read_bool(node, "brcm,force-pio"); - host->debug = of_property_read_bool(node, "brcm,debug"); -- of_property_read_u32(node, -- "brcm,debug-flags", -- &host->debug_flags); - } - -- if (host->debug_flags) -- dev_err(dev, "debug_flags=%x\n", host->debug_flags); -+ host->dma_chan = NULL; -+ host->dma_desc = NULL; -+ -+ /* Formally recognise the other way of disabling DMA */ -+ if (host->pio_limit == 0x7fffffff) -+ host->allow_dma = false; - - if (host->allow_dma) { - if (node) { -@@ -1940,15 +2031,12 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - return 0; - } - -- - static const struct of_device_id bcm2835_sdhost_match[] = { - { .compatible = "brcm,bcm2835-sdhost" }, - { } - }; - MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); - -- -- - static struct platform_driver bcm2835_sdhost_driver = { - .probe = bcm2835_sdhost_probe, - .remove = bcm2835_sdhost_remove, - -From 28749d393c5f8b68c20ab5827c0e519eb96c89fe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 12 Feb 2016 15:38:00 +0000 -Subject: [PATCH 140/251] BCM270X_DT: Add dtparams for the SD interface - -Add new base dtparams sd_overclock, sd_force_pio, sd_pio_limit -and sd_debug. ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 - - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 13 +++++++++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++++ - arch/arm/boot/dts/overlays/README | 11 ++++++++++- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 1 - - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 27 +++++++++++++------------- - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 14 ++++++------- - 10 files changed, 58 insertions(+), 23 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 2e4df17..d2d6fa0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -141,5 +141,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 0445b46..d033ee4 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -131,5 +131,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 87c1a54..8bcafb4 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -97,6 +97,5 @@ - i2c0_baudrate = <&i2c0>,"clock-frequency:0"; - i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -- core_freq = <&clk_core>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 3c8bdde..e09e499 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -7,6 +7,13 @@ - }; - }; - -+&gpio { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ - &leds { - act_led: act { - label = "led0"; -@@ -29,6 +36,8 @@ - - / { - __overrides__ { -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -@@ -36,5 +45,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 75fb4ce..18d3c45 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -135,6 +135,7 @@ - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; -+ brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - status = "disabled"; - }; -@@ -203,6 +204,7 @@ - dmas = <&dma 11>, - <&dma 11>; - dma-names = "tx", "rx"; -+ brcm,overclock-50 = <0>; - status = "disabled"; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 5206ba2..aca253f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -141,5 +141,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index f987565..0a2df01 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -112,6 +112,16 @@ Params: - random Set to "on" to enable the hardware random - number generator (default "on") - -+ sd_overclock Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ sd_force_pio Disable DMA support for SD driver (default off) -+ -+ sd_pio_limit Number of blocks above which to use DMA for -+ SD card (default 1) -+ -+ sd_debug Enable debug output from SD driver (default off) -+ - uart0 Set to "off" to disable uart0 (default "on") - - watchdog Set to "on" to enable the hardware watchdog -@@ -443,7 +453,6 @@ Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -- force_pio Disable DMA support - - - Name: mz61581 -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -index 00a22be..d32b02c 100644 ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -34,6 +34,5 @@ - - __overrides__ { - overclock_50 = <&frag0>,"brcm,overclock-50:0"; -- force_pio = <&frag0>,"brcm,force-pio?"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index dbe6574..a431177 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -1,19 +1,14 @@ - /dts-v1/; - /plugin/; - -+/* Provide backwards compatible aliases for the old sdhost dtparams. */ -+ - /{ - compatible = "brcm,bcm2708"; - - fragment@0 { -- target = <&mmc>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- -- fragment@1 { - target = <&sdhost>; -- frag1: __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - brcm,debug-flags = <0>; -@@ -21,11 +16,17 @@ - }; - }; - -+ fragment@1 { -+ target = <&mmc>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ - __overrides__ { -- overclock_50 = <&frag1>,"brcm,overclock-50:0"; -- force_pio = <&frag1>,"brcm,force-pio?"; -- pio_limit = <&frag1>,"brcm,pio-limit:0"; -- debug = <&frag1>,"brcm,debug?"; -- debug_flags = <&frag1>,"brcm,debug-flags:0"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; -+ pio_limit = <&frag0>,"brcm,pio-limit:0"; -+ debug = <&frag0>,"brcm,debug?"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -index b0b208c..e4a4677 100644 ---- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -1,23 +1,23 @@ - /dts-v1/; - /plugin/; - -+/* Provide backwards compatible aliases for the old sdhost dtparams. */ -+ - /{ - compatible = "brcm,bcm2708"; - - fragment@0 { - target = <&sdhost>; -- frag1: __overlay__ { -+ frag0: __overlay__ { - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -- brcm,debug-flags = <0>; - }; - }; - - __overrides__ { -- overclock_50 = <&frag1>,"brcm,overclock-50:0"; -- force_pio = <&frag1>,"brcm,force-pio?"; -- pio_limit = <&frag1>,"brcm,pio-limit:0"; -- debug = <&frag1>,"brcm,debug?"; -- debug_flags = <&frag1>,"brcm,debug-flags:0"; -+ overclock_50 = <&frag0>,"brcm,overclock-50:0"; -+ force_pio = <&frag0>,"brcm,force-pio?"; -+ pio_limit = <&frag0>,"brcm,pio-limit:0"; -+ debug = <&frag0>,"brcm,debug?"; - }; - }; - -From bad7a004e1e990eefa9f402684b19021baa81812 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 12 Feb 2016 14:50:25 +0000 -Subject: [PATCH 141/251] dcw_otg: trim xfer length when buffer larger than - allocated size is received - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index 8db3dfc..d672a76 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -737,6 +737,11 @@ static int update_urb_state_xfer_comp(dwc_hc_t * hc, - DWC_OTG_HC_XFER_COMPLETE, - &short_read); - -+ if (urb->actual_length + xfer_length > urb->length) { -+ DWC_WARN("%s(): trimming xfer length\n", __func__); -+ xfer_length = urb->length - urb->actual_length; -+ } -+ - /* non DWORD-aligned buffer case handling. */ - if (hc->align_buff && xfer_length && hc->ep_is_in) { - dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, -@@ -1423,6 +1428,12 @@ static void update_urb_state_xfer_intr(dwc_hc_t * hc, - { - uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, - halt_status, NULL); -+ -+ if (urb->actual_length + bytes_transferred > urb->length) { -+ DWC_WARN("%s(): trimming xfer length\n", __func__); -+ bytes_transferred = urb->length - urb->actual_length; -+ } -+ - /* non DWORD-aligned buffer case handling. */ - if (hc->align_buff && bytes_transferred && hc->ep_is_in) { - dwc_memcpy(urb->buf + urb->actual_length, hc->qh->dw_align_buf, - -From 3f19b475b6394511ee22af77c8287ea1c1b8295a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 15 Feb 2016 10:00:27 +0000 -Subject: [PATCH 142/251] bcm2835-sdhost: Restore ATOMIC flag to PIO sg mapping - -Allocation problems have been seen in a wireless driver, and -this is the only change which might have been responsible. ---- - drivers/mmc/host/bcm2835-sdhost.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 262180b..d66385c 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -874,15 +874,14 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -- - if (!host->dma_desc) { - /* Use PIO */ -- int flags; -+ int flags = SG_MITER_ATOMIC; - - if (data->flags & MMC_DATA_READ) -- flags = SG_MITER_TO_SG; -+ flags |= SG_MITER_TO_SG; - else -- flags = SG_MITER_FROM_SG; -+ flags |= SG_MITER_FROM_SG; - sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); - host->blocks = data->blocks; - } - -From 962dfa8efd816762704046d501b703eb153fca3f Mon Sep 17 00:00:00 2001 +From cc4993db27b70169abaecdbbc2e5131c10a7c2b2 Mon Sep 17 00:00:00 2001 From: Craig Roberts Date: Tue, 16 Feb 2016 10:03:42 +0000 -Subject: [PATCH 143/251] Updated smsc95xx driver to check for a valid MAC +Subject: [PATCH 081/114] Updated smsc95xx driver to check for a valid MAC address in eeprom before using smsc95xx.macaddr parameter passed on command line. @@ -146852,10 +126367,10 @@ meaning they don't end up with the same MAC address as the built-in RPi adaptor. 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 3244a90..7483222 100755 +index 08ced57..a61bd08 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c -@@ -817,10 +817,6 @@ static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) +@@ -821,10 +821,6 @@ static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) static void smsc95xx_init_mac_address(struct usbnet *dev) { @@ -146866,7 +126381,7 @@ index 3244a90..7483222 100755 /* try reading mac address from EEPROM */ if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -@@ -831,7 +827,11 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) +@@ -835,7 +831,11 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) } } @@ -146880,1345 +126395,25 @@ index 3244a90..7483222 100755 netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); } -From 0139c7899ec18de29f16b6dad11ea5cddd06ae62 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 17 Feb 2016 19:02:31 +0000 -Subject: [PATCH 144/251] dcw_otg: Make trimming messages less noisy - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -index d672a76..e6b38ac 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -738,7 +738,8 @@ static int update_urb_state_xfer_comp(dwc_hc_t * hc, - &short_read); - - if (urb->actual_length + xfer_length > urb->length) { -- DWC_WARN("%s(): trimming xfer length\n", __func__); -+ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", -+ hc->dev_addr, __func__, __LINE__); - xfer_length = urb->length - urb->actual_length; - } - -@@ -1430,7 +1431,8 @@ static void update_urb_state_xfer_intr(dwc_hc_t * hc, - halt_status, NULL); - - if (urb->actual_length + bytes_transferred > urb->length) { -- DWC_WARN("%s(): trimming xfer length\n", __func__); -+ printk_once(KERN_DEBUG "dwc_otg: DEVICE:%03d : %s:%d:trimming xfer length\n", -+ hc->dev_addr, __func__, __LINE__); - bytes_transferred = urb->length - urb->actual_length; - } - - -From e41f1f667f3d2f4e6e22dc585a6d4dabbc5aafd7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 18 Feb 2016 15:28:14 +0000 -Subject: [PATCH 145/251] BCM270X_DT: at86rf233 overlay - drop to 3MHz - -The consensus is that 6MHz is too fast, but that 3MHz is OK. - -See: https://github.com/raspberrypi/linux/issues/1294 - https://github.com/raspberrypi/linux/issues/1151 ---- - arch/arm/boot/dts/overlays/README | 2 +- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 0a2df01..4de0b6f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -188,7 +188,7 @@ Load: dtoverlay=at86rf233,= - Params: interrupt GPIO used for INT (default 23) - reset GPIO used for Reset (default 24) - sleep GPIO used for Sleep (default 25) -- speed SPI bus speed in Hz (default 6000000) -+ speed SPI bus speed in Hz (default 3000000) - trim Fine tuning of the internal capacitance - arrays (0=+0pF, 15=+4.5pF, default 15) - -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index 0460269..eab4052 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -25,7 +25,7 @@ - interrupts = <23 4>; /* active high */ - reset-gpio = <&gpio 24 1>; - sleep-gpio = <&gpio 25 1>; -- spi-max-frequency = <6000000>; -+ spi-max-frequency = <3000000>; - xtal-trim = /bits/ 8 <0xf>; - }; - }; - -From 61f20e3098ef685f6a14238c58b7158e637652bc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 19 Feb 2016 12:04:48 +0000 -Subject: [PATCH 146/251] bcm2835-sdhost: Downgrade log message status - ---- - drivers/mmc/host/bcm2835-sdhost.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index d66385c..4f6cab5 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -232,8 +232,8 @@ static void log_init(u32 bus_to_phys) - sdhost_log_buf = dma_zalloc_coherent(NULL, LOG_SIZE, &sdhost_log_addr, - GFP_KERNEL); - if (sdhost_log_buf) { -- pr_err("sdhost: log_buf @ %p (%x)\n", -- sdhost_log_buf, sdhost_log_addr); -+ pr_info("sdhost: log_buf @ %p (%x)\n", -+ sdhost_log_buf, sdhost_log_addr); - timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); - if (!timer_base) - pr_err("sdhost: failed to remap timer\n"); - -From 8d7f055a36864ccb388a526cca31a4e416125ac6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 15 Jan 2016 16:48:27 +0000 -Subject: [PATCH 147/251] config: Enable HCI over UARTs - ---- - arch/arm/configs/bcm2709_defconfig | 3 +++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - 2 files changed, 5 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index fc35254..48ecb2e 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -376,6 +376,9 @@ CONFIG_BT_BNEP_PROTO_FILTER=y - CONFIG_BT_HIDP=m - CONFIG_BT_6LOWPAN=m - CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y - CONFIG_BT_HCIBCM203X=m - CONFIG_BT_HCIBPA10X=m - CONFIG_BT_HCIBFUSB=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 51dc019..4368f0d 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -370,6 +370,8 @@ CONFIG_BT_HIDP=m - CONFIG_BT_6LOWPAN=m - CONFIG_BT_HCIBTUSB=m - CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y - CONFIG_BT_HCIBCM203X=m - CONFIG_BT_HCIBPA10X=m - CONFIG_BT_HCIBFUSB=m - -From 4e80e74fc12bf2b3f75908afce3fe399323ccb90 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Dec 2015 13:37:07 +0000 -Subject: [PATCH 148/251] hci_h5: Don't send conf_req when ACTIVE - -Without this patch, a modem and kernel can continuously bombard each -other with conf_req and conf_rsp messages, in a demented game of tag. ---- - drivers/bluetooth/hci_h5.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index abee221..2825833 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -314,7 +314,8 @@ static void h5_handle_internal_rx(struct hci_uart *hu) - h5_link_control(hu, conf_req, 3); - } else if (memcmp(data, conf_req, 2) == 0) { - h5_link_control(hu, conf_rsp, 2); -- h5_link_control(hu, conf_req, 3); -+ if (h5->state != H5_ACTIVE) -+ h5_link_control(hu, conf_req, 3); - } else if (memcmp(data, conf_rsp, 2) == 0) { - if (H5_HDR_LEN(hdr) > 2) - h5->tx_win = (data[2] & 7); - -From 7ea16aeff2daf97ada8b68b9acad503f5a922c61 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH 149/251] amba_pl011: Don't use DT aliases for numbering - -The pl011 driver looks for DT aliases of the form "serial", -and if found uses as the device ID. This can cause -/dev/ttyAMA0 to become /dev/ttyAMA1, which is confusing if the -other serial port is provided by the 8250 driver which doesn't -use the same logic. ---- - drivers/tty/serial/amba-pl011.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 899a771..68b3353 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -2313,7 +2313,12 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, - if (IS_ERR(base)) - return PTR_ERR(base); - -+ /* Don't use DT serial aliases - it causes the device to -+ be renumbered to ttyAMA1 if it is the second serial port in the -+ system, even though the other one is ttyS0. The 8250 driver -+ doesn't use this logic, so always remains ttyS0. - index = pl011_probe_dt_alias(index, dev); -+ */ - - uap->old_cr = 0; - uap->port.dev = dev; - -From cce16b3c1c46f74a3178029ac894c89aea751af4 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 15:35:57 -0800 -Subject: [PATCH 150/251] clk: bcm2835: Add bindings for the auxiliary - peripheral clock gates. - -These will be used for enabling UART1, SPI1, and SPI2. - -Signed-off-by: Eric Anholt -Acked-by: Rob Herring -Signed-off-by: Michael Turquette ---- - .../bindings/clock/brcm,bcm2835-aux-clock.txt | 31 ++++++++++++++++++++++ - include/dt-bindings/clock/bcm2835-aux.h | 17 ++++++++++++ - 2 files changed, 48 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt - create mode 100644 include/dt-bindings/clock/bcm2835-aux.h - -diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt -new file mode 100644 -index 0000000..7a837d2 ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-aux-clock.txt -@@ -0,0 +1,31 @@ -+Broadcom BCM2835 auxiliary peripheral support -+ -+This binding uses the common clock binding: -+ Documentation/devicetree/bindings/clock/clock-bindings.txt -+ -+The auxiliary peripherals (UART, SPI1, and SPI2) have a small register -+area controlling clock gating to the peripherals, and providing an IRQ -+status register. -+ -+Required properties: -+- compatible: Should be "brcm,bcm2835-aux" -+- #clock-cells: Should be <1>. The permitted clock-specifier values can be -+ found in include/dt-bindings/clock/bcm2835-aux.h -+- reg: Specifies base physical address and size of the registers -+- clocks: The parent clock phandle -+ -+Example: -+ -+ clocks: cprman@7e101000 { -+ compatible = "brcm,bcm2835-cprman"; -+ #clock-cells = <1>; -+ reg = <0x7e101000 0x2000>; -+ clocks = <&clk_osc>; -+ }; -+ -+ aux: aux@0x7e215004 { -+ compatible = "brcm,bcm2835-aux"; -+ #clock-cells = <1>; -+ reg = <0x7e215000 0x8>; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ }; -diff --git a/include/dt-bindings/clock/bcm2835-aux.h b/include/dt-bindings/clock/bcm2835-aux.h -new file mode 100644 -index 0000000..d91156e ---- /dev/null -+++ b/include/dt-bindings/clock/bcm2835-aux.h -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2015 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#define BCM2835_AUX_CLOCK_UART 0 -+#define BCM2835_AUX_CLOCK_SPI1 1 -+#define BCM2835_AUX_CLOCK_SPI2 2 -+#define BCM2835_AUX_CLOCK_COUNT 3 - -From 16aac0eab690fbafcf6cb70a19ceffd848cc8ee8 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 15 Dec 2015 15:35:58 -0800 -Subject: [PATCH 151/251] clk: bcm2835: Add a driver for the auxiliary - peripheral clock gates. - -There are a pair of SPI masters and a mini UART that were last minute -additions. As a result, they didn't get integrated in the same way as -the other gates off of the VPU clock in CPRMAN. - -Signed-off-by: Eric Anholt -Signed-off-by: Michael Turquette - -updated Makefile to preserve the rasoberry pi architectures ---- - drivers/clk/bcm/Makefile | 1 + - drivers/clk/bcm/clk-bcm2835-aux.c | 85 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 86 insertions(+) - create mode 100644 drivers/clk/bcm/clk-bcm2835-aux.c - -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index a1b4cbc..84070d5 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -4,6 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o - obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o -+obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o -diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c -new file mode 100644 -index 0000000..e4f89e2 ---- /dev/null -+++ b/drivers/clk/bcm/clk-bcm2835-aux.c -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2015 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BCM2835_AUXIRQ 0x00 -+#define BCM2835_AUXENB 0x04 -+ -+static int bcm2835_aux_clk_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct clk_onecell_data *onecell; -+ const char *parent; -+ struct clk *parent_clk; -+ struct resource *res; -+ void __iomem *reg, *gate; -+ -+ parent_clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(parent_clk)) -+ return PTR_ERR(parent_clk); -+ parent = __clk_get_name(parent_clk); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ reg = devm_ioremap_resource(dev, res); -+ if (!reg) -+ return -ENODEV; -+ -+ onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); -+ if (!onecell) -+ return -ENOMEM; -+ onecell->clk_num = BCM2835_AUX_CLOCK_COUNT; -+ onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT, -+ sizeof(*onecell->clks), GFP_KERNEL); -+ if (!onecell->clks) -+ return -ENOMEM; -+ -+ gate = reg + BCM2835_AUXENB; -+ onecell->clks[BCM2835_AUX_CLOCK_UART] = -+ clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL); -+ -+ onecell->clks[BCM2835_AUX_CLOCK_SPI1] = -+ clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL); -+ -+ onecell->clks[BCM2835_AUX_CLOCK_SPI2] = -+ clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL); -+ -+ of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm2835_aux_clk_of_match[] = { -+ { .compatible = "brcm,bcm2835-aux", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_aux_clk_of_match); -+ -+static struct platform_driver bcm2835_aux_clk_driver = { -+ .driver = { -+ .name = "bcm2835-aux-clk", -+ .of_match_table = bcm2835_aux_clk_of_match, -+ }, -+ .probe = bcm2835_aux_clk_probe, -+}; -+builtin_platform_driver(bcm2835_aux_clk_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver"); -+MODULE_LICENSE("GPL v2"); - -From c7b36d3709441f04c40763f17c82e6734cc14fc1 Mon Sep 17 00:00:00 2001 -From: Fraser -Date: Tue, 23 Feb 2016 10:04:37 +1100 -Subject: [PATCH 152/251] Aux SPI 1&2 implementation - -Adds aux spi 1 & 2 devices to compatible raspberry PIs. -* Minor config of the driver build environment to ensure they get built -for CONFIG_ARCH_BCM2708 & CONFIG_ARCH_BCM2709 devices. -* Adds the aux spi driver into the defconfigs as a module. -* Adds the auxiliary and spi1/2 devices into the device tree in a -disabled state -* Provides decide tree overlays which enables the devices and gives -users a degree of control over how they are setup. ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 34 ++++++++- - arch/arm/boot/dts/overlays/Makefile | 6 ++ - arch/arm/boot/dts/overlays/README | 99 +++++++++++++++++++++++++ - arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 57 ++++++++++++++ - arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 69 +++++++++++++++++ - arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 81 ++++++++++++++++++++ - arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 57 ++++++++++++++ - arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 69 +++++++++++++++++ - arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 81 ++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/clk/bcm/Makefile | 2 +- - drivers/spi/Kconfig | 2 +- - 13 files changed, 556 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 18d3c45..4f65203 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -1,3 +1,4 @@ -+#include - #include "skeleton.dtsi" - - / { -@@ -5,6 +6,7 @@ - - aliases { - audio = &audio; -+ aux = &aux; - sound = &sound; - soc = &soc; - dma = &dma; -@@ -19,6 +21,8 @@ - spi0 = &spi0; - i2c0 = &i2c0; - uart1 = &uart1; -+ spi1 = &spi1; -+ spi2 = &spi2; - mmc = &mmc; - i2c1 = &i2c1; - i2c2 = &i2c2; -@@ -186,6 +190,14 @@ - status = "disabled"; - }; - -+ aux: aux@0x7e215004 { -+ compatible = "brcm,bcm2835-aux"; -+ #clock-cells = <1>; -+ reg = <0x7e215000 0x8>; -+ clocks = <&clk_core>; -+ status = "disabled"; -+ }; -+ - uart1: uart@7e215040 { - compatible = "brcm,bcm2835-aux-uart", "ns16550"; - reg = <0x7e215040 0x40>; -@@ -194,7 +206,27 @@ - reg-shift = <2>; - no-loopback-test; - status = "disabled"; -- }; -+ }; -+ -+ spi1: spi@7e215080 { -+ compatible = "brcm,bcm2835-aux-spi"; -+ reg = <0x7e215080 0x40>, <0x7e215000 0x8>; -+ interrupts = <1 29>; -+ clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi2: spi@7e2150C0 { -+ compatible = "brcm,bcm2835-aux-spi"; -+ reg = <0x7e2150C0 0x40>, <0x7e215000 0x8>; -+ interrupts = <1 29>; -+ clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; - - mmc: mmc@7e300000 { - compatible = "brcm,bcm2835-mmc"; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4d9d640..a787d66 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -57,6 +57,12 @@ dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-1cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-2cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi1-3cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-1cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-2cs-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi2-3cs-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4de0b6f..cf5f5be 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -713,6 +713,105 @@ Load: dtoverlay=spi-gpio35-39 - Params: - - -+Name: spi1-1cs -+Info: Enables spi1 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi1-2cs -+Info: Enables spi1 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.1 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi1-3cs -+Info: Enables spi1 with three chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi1 is only accessible on devices with a 40pin header, eg: -+ A+, B+, Zero and PI2 B; as well as the Compute Module. -+Load: dtoverlay=spi1-3cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI1_CE0). -+ cs1_pin GPIO pin for CS1 (default 17 - BCM SPI1_CE1). -+ cs2_pin GPIO pin for CS2 (default 16 - BCM SPI1_CE2). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.1 (default -+ is 'okay' or enabled). -+ cs2_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev1.2 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-1cs -+Info: Enables spi2 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-2cs -+Info: Enables spi2 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.1 (default -+ is 'okay' or enabled). -+ -+ -+Name: spi2-3cs -+Info: Enables spi2 with three chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+ N.B.: spi2 is only accessible with the Compute Module. -+Load: dtoverlay=spi2-3cs,= -+Params: cs0_pin GPIO pin for CS0 (default 43 - BCM SPI2_CE0). -+ cs1_pin GPIO pin for CS1 (default 44 - BCM SPI2_CE1). -+ cs2_pin GPIO pin for CS2 (default 45 - BCM SPI2_CE2). -+ cs0_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.0 (default -+ is 'okay' or enabled). -+ cs1_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.1 (default -+ is 'okay' or enabled). -+ cs2_spidev Set to 'disabled' to stop the creation of a -+ userspace device node /dev/spidev2.2 (default -+ is 'okay' or enabled). -+ -+ - Name: tinylcd35 - Info: 3.5" Color TFT Display by www.tinylcd.com - Options: Touch, RTC, keypad -diff --git a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -new file mode 100644 -index 0000000..71c2439 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -@@ -0,0 +1,57 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -new file mode 100644 -index 0000000..2ae0885 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -@@ -0,0 +1,69 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18 17>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>, <&gpio 17 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ cs1_spidev = <&spidev1_1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -new file mode 100644 -index 0000000..8f79044 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <18 17 16>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi1>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 18 1>, <&gpio 17 1>, <&gpio 16 1>; -+ status = "okay"; -+ -+ spidev1_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev1_2: spidev@2 { -+ compatible = "spidev"; -+ reg = <2>; /* CE2 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi1_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi1_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs2_pin = <&spi1_cs_pins>,"brcm,pins:8", -+ <&frag1>,"cs-gpios:28"; -+ cs0_spidev = <&spidev1_0>,"status"; -+ cs1_spidev = <&spidev1_1>,"status"; -+ cs2_spidev = <&spidev1_2>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -new file mode 100644 -index 0000000..6f57bc7 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -@@ -0,0 +1,57 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -new file mode 100644 -index 0000000..d090631 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -@@ -0,0 +1,69 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43 44>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>, <&gpio 44 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ cs1_spidev = <&spidev2_1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -new file mode 100644 -index 0000000..e258672 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi2_pins: spi2_pins { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ }; -+ -+ spi2_cs_pins: spi2_cs_pins { -+ brcm,pins = <43 44 45>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi2>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins &spi2_cs_pins>; -+ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; -+ status = "okay"; -+ -+ spidev2_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ -+ spidev2_2: spidev@2 { -+ compatible = "spidev"; -+ reg = <2>; /* CE2 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&spi2_cs_pins>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&spi2_cs_pins>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs2_pin = <&spi2_cs_pins>,"brcm,pins:8", -+ <&frag1>,"cs-gpios:28"; -+ cs0_spidev = <&spidev2_0>,"status"; -+ cs1_spidev = <&spidev2_1>,"status"; -+ cs2_spidev = <&spidev2_2>,"status"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 48ecb2e..76b3a88 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -601,6 +601,7 @@ CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m - CONFIG_SPI_SPIDEV=y - CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 4368f0d..1ca1695 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -593,6 +593,7 @@ CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m - CONFIG_SPI_SPIDEV=y - CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m -diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile -index 84070d5..d60fd3f 100644 ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -4,7 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o - obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835.o --obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o -+obj-$(CONFIG_ARCH_BCM2835)$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += clk-bcm2835-aux.o - obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index e842e86..c9d1558 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -90,7 +90,7 @@ config SPI_BCM2835 - - config SPI_BCM2835AUX - tristate "BCM2835 SPI auxiliary controller" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - depends on GPIOLIB - help - This selects a driver for the Broadcom BCM2835 SPI aux master. - -From 9c53b072c7283c02625434a42fbc2aaa3b2b4bbc Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Tue, 23 Feb 2016 17:28:23 +0100 -Subject: [PATCH 153/251] ASoC: bcm: add missing .owner fields in sound card - drivers - -If snd_soc_card.owner is not set the kernel won't do usage refcounting -and one can remove the card driver module while it's in use (eg playback -active) - which leads to a kernel crash. - -The missing owner field also prevents ALSA slot ordering -(options snd slots=module-name1,module-name-2,...) from working with -the I2S cards as it has no module name to match against. - -Fix these issues by setting the .owner field in the snd_soc_card structs. - -Signed-off-by: Matthias Reichl ---- - sound/soc/bcm/hifiberry_amp.c | 1 + - sound/soc/bcm/hifiberry_dac.c | 1 + - sound/soc/bcm/hifiberry_dacplus.c | 1 + - sound/soc/bcm/hifiberry_digi.c | 1 + - sound/soc/bcm/iqaudio-dac.c | 1 + - sound/soc/bcm/raspidac3.c | 1 + - sound/soc/bcm/rpi-dac.c | 1 + - sound/soc/bcm/rpi-proto.c | 1 + - 8 files changed, 8 insertions(+) - -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -index 5903915..0bb12e4 100644 ---- a/sound/soc/bcm/hifiberry_amp.c -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -61,6 +61,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { - - static struct snd_soc_card snd_rpi_hifiberry_amp = { - .name = "snd_rpi_hifiberry_amp", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_amp_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -index 3ab0f47..29ecc08 100644 ---- a/sound/soc/bcm/hifiberry_dac.c -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -63,6 +63,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_dac = { - .name = "snd_rpi_hifiberry_dac", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index 153dbcd..03d8d2a 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -287,6 +287,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_dacplus = { - .name = "snd_rpi_hifiberry_dacplus", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_dacplus_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), - }; -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 80732b8..9840e15 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -164,6 +164,7 @@ static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_digi = { - .name = "snd_rpi_hifiberry_digi", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_hifiberry_digi_dai, - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), - }; -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 124d7a9..a5eaa9e 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -77,6 +77,7 @@ static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_iqaudio_dac = { - .name = "IQaudIODAC", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_iqaudio_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), - }; -diff --git a/sound/soc/bcm/raspidac3.c b/sound/soc/bcm/raspidac3.c -index 3cabf5b..e7422e2 100644 ---- a/sound/soc/bcm/raspidac3.c -+++ b/sound/soc/bcm/raspidac3.c -@@ -128,6 +128,7 @@ static struct snd_soc_dai_link snd_rpi_raspidac3_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_raspidac3 = { - .name = "RaspiDAC Rev.3x HiFi Audio Card", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_raspidac3_dai, - .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai), - }; -diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c -index d5fac1b..59dc89e 100644 ---- a/sound/soc/bcm/rpi-dac.c -+++ b/sound/soc/bcm/rpi-dac.c -@@ -60,6 +60,7 @@ static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_rpi_dac = { - .name = "snd_rpi_rpi_dac", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_rpi_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), - }; -diff --git a/sound/soc/bcm/rpi-proto.c b/sound/soc/bcm/rpi-proto.c -index c6e45a0..9db678e 100644 ---- a/sound/soc/bcm/rpi-proto.c -+++ b/sound/soc/bcm/rpi-proto.c -@@ -91,6 +91,7 @@ static struct snd_soc_dai_link snd_rpi_proto_dai[] = { - /* audio machine driver */ - static struct snd_soc_card snd_rpi_proto = { - .name = "snd_rpi_proto", -+ .owner = THIS_MODULE, - .dai_link = snd_rpi_proto_dai, - .num_links = ARRAY_SIZE(snd_rpi_proto_dai), - }; - -From 797d7607625bed287bdadcee2471a247ced1ded5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 20 Jan 2016 17:50:09 +0000 -Subject: [PATCH 154/251] smsx95xx: Add option to disable the crimes against - truesize fix - -It may improve iperf numbers on Pi 1, but may generate dmesg warnings and possibly cause network issues -See issue 1248. ---- - drivers/net/usb/smsc95xx.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - mode change 100755 => 100644 drivers/net/usb/smsc95xx.c - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -old mode 100755 -new mode 100644 -index 7483222..a61bd08 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -75,6 +75,10 @@ static bool turbo_mode = false; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -+static bool truesize_mode = false; -+module_param(truesize_mode, bool, 0644); -+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value"); -+ - static char *macaddr = ":"; - module_param(macaddr, charp, 0); - MODULE_PARM_DESC(macaddr, "MAC address"); -@@ -1841,6 +1845,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(skb); - skb_trim(skb, skb->len - 4); /* remove fcs */ -+ if (truesize_mode) -+ skb->truesize = size + sizeof(struct sk_buff); - - return 1; - } -@@ -1858,6 +1864,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - if (dev->net->features & NETIF_F_RXCSUM) - smsc95xx_rx_csum_offload(ax_skb); - skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ -+ if (truesize_mode) -+ ax_skb->truesize = size + sizeof(struct sk_buff); - - usbnet_skb_return(dev, ax_skb); - } - -From 93c08f5b50bbb8181c4d34bb40fc57e4e3142f8f Mon Sep 17 00:00:00 2001 +From 2a1212d768fc0b6304908ca72aa0fb151c4d33cf Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 23 Feb 2016 19:56:04 +0000 -Subject: [PATCH 155/251] bcm2835-virtgpio: Virtual GPIO driver +Subject: [PATCH 082/114] bcm2835-virtgpio: Virtual GPIO driver Add a virtual GPIO driver that uses the firmware mailbox interface to request that the VPU toggles LEDs. --- - arch/arm/configs/bcm2709_defconfig | 1 + - drivers/gpio/Kconfig | 6 + - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-bcm-virt.c | 180 +++++++++++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 5 files changed, 189 insertions(+) + drivers/gpio/Kconfig | 6 ++ + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-bcm-virt.c | 179 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 186 insertions(+) create mode 100644 drivers/gpio/gpio-bcm-virt.c -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 76b3a88..6d6b519 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -607,6 +607,7 @@ CONFIG_PPS=m - CONFIG_PPS_CLIENT_LDISC=m - CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_BCM_VIRT=y - CONFIG_GPIO_ARIZONA=m - CONFIG_GPIO_STMPE=y - CONFIG_W1=m diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index b18bea0..a1f4cce 100644 +index 5f3429f..86cb971 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -132,6 +132,12 @@ config GPIO_BCM_KONA +@@ -142,6 +142,12 @@ config GPIO_BCM_KONA help Turn on GPIO support for Broadcom "Kona" chips. @@ -148230,14 +126425,14 @@ index b18bea0..a1f4cce 100644 + config GPIO_BRCMSTB tristate "BRCMSTB GPIO support" - default y if ARCH_BRCMSTB + default y if (ARCH_BRCMSTB || BMIPS_GENERIC) diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index 986dbd8..b2ccc9f 100644 +index 1e0b74f..908596d 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o +@@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o - obj-$(CONFIG_ATH79) += gpio-ath79.o + obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o +obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o @@ -148245,10 +126440,10 @@ index 986dbd8..b2ccc9f 100644 obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o diff --git a/drivers/gpio/gpio-bcm-virt.c b/drivers/gpio/gpio-bcm-virt.c new file mode 100644 -index 0000000..53edcb4 +index 0000000..f3e0f16 --- /dev/null +++ b/drivers/gpio/gpio-bcm-virt.c -@@ -0,0 +1,180 @@ +@@ -0,0 +1,179 @@ +/* + * brcmvirt GPIO driver + * @@ -148264,7 +126459,6 @@ index 0000000..53edcb4 +#include +#include +#include -+#include +#include +#include + @@ -148376,7 +126570,7 @@ index 0000000..53edcb4 + + ucb->gc.label = MODULE_NAME; + ucb->gc.owner = THIS_MODULE; -+ ucb->gc.dev = dev; ++ //ucb->gc.dev = dev; + ucb->gc.of_node = np; + ucb->gc.base = 100; + ucb->gc.ngpio = NUM_GPIO; @@ -148429,1312 +126623,1550 @@ index 0000000..53edcb4 +MODULE_AUTHOR("Dom Cobley "); +MODULE_DESCRIPTION("brcmvirt GPIO driver"); +MODULE_ALIAS("platform:brcmvirt-gpio"); -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index b011489..c844968 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -93,6 +93,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -From 686310b3289232a8ae9d21061318e2ee3ca65c3d Mon Sep 17 00:00:00 2001 +From 50af5c701f50215b5ce53f54d40ec9682f66dd6b Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 4 Mar 2016 12:49:09 +0000 +Subject: [PATCH 083/114] DRM_VC4: Allow to be built for ARCH_BCM270x + +--- + drivers/gpu/drm/vc4/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig +index 5848104..870fea5 100644 +--- a/drivers/gpu/drm/vc4/Kconfig ++++ b/drivers/gpu/drm/vc4/Kconfig +@@ -1,6 +1,6 @@ + config DRM_VC4 + tristate "Broadcom VC4 Graphics" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST + depends on DRM + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + +From 9771718ad680a80b06fe3d20ac2851ccd78115cf Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Thu, 21 Jan 2016 17:57:49 +0000 -Subject: [PATCH 156/251] BCM270X_DT: Add Pi3 support +Date: Thu, 17 Dec 2015 13:37:07 +0000 +Subject: [PATCH 084/114] hci_h5: Don't send conf_req when ACTIVE +Without this patch, a modem and kernel can continuously bombard each +other with conf_req and conf_rsp messages, in a demented game of tag. --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 192 ++++++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2710.dtsi | 102 ++++++++++++++++++ - 3 files changed, 295 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2710-rpi-3-b.dts - create mode 100644 arch/arm/boot/dts/bcm2710.dtsi + drivers/bluetooth/hci_h5.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index d583e67..fdc450f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-b-plus.dtb - dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rpi-cm.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-cm.dtb - dtb-$(CONFIG_ARCH_BCM2709) += bcm2709-rpi-2-b.dtb -+dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb - - # Raspberry Pi - ifeq ($(CONFIG_ARCH_BCM2708),y) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -new file mode 100644 -index 0000000..cc06089 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -0,0 +1,192 @@ -+/dts-v1/; -+ -+#include "bcm2710.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2710","brcm,bcm2709"; -+ model = "Raspberry Pi 3 Model B"; -+}; -+ -+&gpio { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = <1>; /* output */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = <7>; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ bt_pins: bt_pins { -+ brcm,pins = <28 29 30 31 43>; -+ brcm,function = <6 6 6 6 4>; /* alt2:PCM alt0:GPCLK2 */ -+ brcm,pull = <0 0 0 0 0>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins = <32 33>; -+ brcm,function = <7>; /* alt3=UART0 */ -+ brcm,pull = <0 0>; -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 0>; -+ }; -+}; -+ -+&sdhost { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ bus-width = <4>; -+ status = "okay"; -+}; -+ -+&mmc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ bus-width = <4>; -+ status = "okay"; -+ brcm,overclock-50 = <0>; -+}; -+ -+&soc { -+ virtgpio: virtgpio { -+ compatible = "brcm,bcm2835-virtgpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins &bt_pins>; -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&random { -+ status = "okay"; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&virtgpio 0 0>; -+ }; -+}; -+ -+/ { -+ chosen { -+ bootargs = "8250.nr_uarts=1"; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c2_iknowwhatimdoing = <&i2c2>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; -+ core_freq = <&clk_core>,"clock-frequency:0"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi -new file mode 100644 -index 0000000..1a48686 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710.dtsi -@@ -0,0 +1,102 @@ -+#include "bcm2708_common.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2710","brcm,bcm2709"; -+ model = "BCM2710"; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc { -+ ranges = <0x7e000000 0x3f000000 0x01000000>, -+ <0x40000000 0x40000000 0x00040000>; -+ -+ 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>; -+ }; -+ -+ gpiomem { -+ compatible = "brcm,bcm2835-gpiomem"; -+ reg = <0x7e200000 0x1000>; -+ status = "okay"; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ clock-frequency = <19200000>; -+ interrupt-parent = <&local_intc>; -+ interrupts = <0>, // PHYS_SECURE_PPI -+ <1>, // PHYS_NONSECURE_PPI -+ <3>, // VIRT_PPI -+ <2>; // HYP_PPI -+ always-on; -+ }; -+ -+ syscon@40000000 { -+ compatible = "brcm,bcm2836-arm-local", "syscon"; -+ reg = <0x40000000 0x100>; -+ }; -+ }; -+ -+ cpus: cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ v7_cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x000>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x001>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu2: cpu@2 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x002>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu3: cpu@3 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0x003>; -+ clock-frequency = <800000000>; -+ }; -+ }; -+ -+ __overrides__ { -+ arm_freq = <&v7_cpu0>, "clock-frequency:0", -+ <&v7_cpu1>, "clock-frequency:0", -+ <&v7_cpu2>, "clock-frequency:0", -+ <&v7_cpu3>, "clock-frequency:0"; -+ }; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -+ -+&intc { -+ compatible = "brcm,bcm2836-armctrl-ic"; -+ interrupt-parent = <&local_intc>; -+ interrupts = <8>; -+}; +diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c +index 0879d64..5161ab3 100644 +--- a/drivers/bluetooth/hci_h5.c ++++ b/drivers/bluetooth/hci_h5.c +@@ -310,7 +310,8 @@ static void h5_handle_internal_rx(struct hci_uart *hu) + h5_link_control(hu, conf_req, 3); + } else if (memcmp(data, conf_req, 2) == 0) { + h5_link_control(hu, conf_rsp, 2); +- h5_link_control(hu, conf_req, 3); ++ if (h5->state != H5_ACTIVE) ++ h5_link_control(hu, conf_req, 3); + } else if (memcmp(data, conf_rsp, 2) == 0) { + if (H5_HDR_LEN(hdr) > 2) + h5->tx_win = (data[2] & 0x07); -From 5704ec08a597c580de377bb0fca760fa30b927b0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Mon, 8 Feb 2016 23:49:41 +0000 -Subject: [PATCH 157/251] DT: Add overlays to configure I2C pins - -Lifted from -https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=120938&p=825883 -so not claiming this to be my own work. -Adds overlays i2c0-bcm2708 and i2c1-bcm2708 that allow the pin -allocations for i2c-0 and i2c-1 to be changed. ---- - arch/arm/boot/dts/overlays/Makefile | 2 ++ - arch/arm/boot/dts/overlays/README | 16 ++++++++++ - .../arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 36 +++++++++++++++++++++ - .../arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 37 ++++++++++++++++++++++ - 4 files changed, 91 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index a787d66..f2bc3ce 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,8 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c0-bcm2708-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c1-bcm2708-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index cf5f5be..7d7bbb8 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -371,6 +371,22 @@ Params: ds1307 Select the DS1307 device - pcf8563 Select the PCF8563 device - - -+Name: i2c0-bcm2708 -+Info: Enable the i2c_bcm2708 driver for the i2c0 bus -+Load: dtoverlay=i2c0-bcm2708,= -+Params: sda0_pin GPIO pin for SDA0 (0, 28 [or 44] - default 0) -+ scl0_pin GPIO pin for SCL0 (1, 29 [or 45] - default 1) -+ -+ -+Name: i2c1-bcm2708 -+Info: Enable the i2c_bcm2708 driver for the i2c1 bus -+Load: dtoverlay=i2c1-bcm2708,= -+Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) -+ scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) -+ pin_func Alternative pin function (4 (alt0), 6 (alt2) - -+ default 4) -+ -+ - Name: i2s-mmap - Info: Enables mmap support in the bcm2708-i2s driver - Load: dtoverlay=i2s-mmap -diff --git a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -new file mode 100644 -index 0000000..5c0e55b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -@@ -0,0 +1,36 @@ -+/* -+ * Device tree overlay for i2c_bcm2708, i2c0 bus -+ * -+ * Compile: -+ * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c0>; -+ __overlay__ { -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ sda0_pin = <&i2c0_pins>,"brcm,pins:0"; -+ scl0_pin = <&i2c0_pins>,"brcm,pins:4"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e303b9c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -@@ -0,0 +1,37 @@ -+/* -+ * Device tree overlay for i2c_bcm2708, i2c1 bus -+ * -+ * Compile: -+ * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ pinctrl-0 = <&i2c1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ sda1_pin = <&i2c1_pins>,"brcm,pins:0"; -+ scl1_pin = <&i2c1_pins>,"brcm,pins:4"; -+ pin_func = <&i2c1_pins>,"brcm,function:0"; -+ }; -+}; - -From c0d707957191b16ee951b09e3b2d28e5a5cda0f3 Mon Sep 17 00:00:00 2001 -From: Dhiraj Goel -Date: Thu, 3 Mar 2016 21:10:50 -0800 -Subject: [PATCH 158/251] bcm2835-camera: fix a bug in computation of frame - timestamp - -Fixes #1318 ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index e83334c..98a892e 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -360,8 +360,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, - div = - div_u64_rem(runtime_us, USEC_PER_SEC, &rem); - buf->vb.timestamp.tv_sec = -- dev->capture.kernel_start_ts.tv_sec - 1 + -- div; -+ dev->capture.kernel_start_ts.tv_sec + div; - buf->vb.timestamp.tv_usec = - dev->capture.kernel_start_ts.tv_usec + rem; - - -From e16268752be460f8d65e4d613c690508ce985f3f Mon Sep 17 00:00:00 2001 +From 93e515c0f77abfacf54ccbc12b4d94618e0b423d Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Wed, 2 Mar 2016 10:59:05 +0000 -Subject: [PATCH 159/251] BCM270X_DT: Add pi3-disable-bt overlay +Date: Tue, 23 Feb 2016 17:26:48 +0000 +Subject: [PATCH 085/114] amba_pl011: Don't use DT aliases for numbering -Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. To disable -the systemd service that initialises the modem so it doesn't use the UART: - - sudo systemctl disable hciuart - -Signed-off-by: Phil Elwell +The pl011 driver looks for DT aliases of the form "serial", +and if found uses as the device ID. This can cause +/dev/ttyAMA0 to become /dev/ttyAMA1, which is confusing if the +other serial port is provided by the 8250 driver which doesn't +use the same logic. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 48 ++++++++++++++++++++++ - 3 files changed, 57 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts + drivers/tty/serial/amba-pl011.c | 5 +++++ + 1 file changed, 5 insertions(+) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f2bc3ce..2c2b2fa 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7d7bbb8..4f0be23 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -496,6 +496,14 @@ Params: speed Display SPI bus speed - [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 7c198e0..4f9e97b 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -2413,7 +2413,12 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, + if (IS_ERR(base)) + return PTR_ERR(base); ++ /* Don't use DT serial aliases - it causes the device to ++ be renumbered to ttyAMA1 if it is the second serial port in the ++ system, even though the other one is ttyS0. The 8250 driver ++ doesn't use this logic, so always remains ttyS0. + index = pl011_probe_dt_alias(index, dev); ++ */ -+Name: pi3-disable-bt -+Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 -+ N.B. To disable the systemd service that initialises the modem so it -+ doesn't use the UART, use 'sudo systemctl disable hciuart'. -+Load: dtoverlay=pi3-disable-bt -+Params: -+ -+ - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= -diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -new file mode 100644 -index 0000000..05403e2 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -0,0 +1,48 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. -+ To disable the systemd service that initialises the modem so it doesn't use -+ the UART: -+ -+ sudo systemctl disable hciuart -+*/ -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ uart0_pins: uart0_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <4>; /* alt0 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/uart@7e201000"; -+ serial1 = "/soc/uart@7e215040"; -+ }; -+ }; -+}; + uap->old_cr = 0; + uap->port.dev = dev; -From 59b04f45fe08783a5564c784869cfc93cd40c109 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 09:53:03 +0000 -Subject: [PATCH 160/251] BCM270X_DT: Add pi3-miniuart-bt DT overlay +From b1fc98ab68bbf110e2c839a25dc3c09eb0fd5d22 Mon Sep 17 00:00:00 2001 +From: wm4 +Date: Wed, 13 Jan 2016 19:41:45 +0100 +Subject: [PATCH 086/114] bcm2835-pcm: Numerous enhancements -Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -usable baudrate. +bcm2835: extend allowed range of channels and samplerates -It is also necessary to edit /lib/systemd/system/hciuart.server and -replace ttyAMA0 with ttyS0. +Allow everything the videocore accepts. -If cmdline.txt uses the alias serial0 to refer to the user-accessable port -then the firmware will replace with the appropriate port whether or not -this overlay is used. +bcm2835: restrict channels*rate to 8*960000 -Signed-off-by: Phil Elwell +This is required at least for SPDIF. If the bitrate goes above, +videocore will either resample the audio or corrupt it due to +underruns. Supposedly the hardware isn't designed to output +higher rates, but it can still resample it down to supported +rates. + +Some code is based on ac97_pcm.c. + +rpi: update vc_vchi_audioserv_defs.h + +Add audioserv 3 extensions. The changes were taken from the paste +linked here: + +https://github.com/raspberrypi/linux/pull/1166#issuecomment-151917067 + +bcm2835: implement channel map API + +Report all layouts supported by the HDMI protocol to userspace. +Make the videocore set the correct layout according to the +userspace request. + +Some code taken from patch_hdmi.c. In particular, the HDMI channel +layout table was copied without changes - with the idea in mind that +hopefully it can be shared one day. Or at least updating it will be +simpler. + +In my tests, everything appears to work, except when outputting +FL FR RL RR. Then my receiver outputs RL on both the RL and RR +speakers, while RR is never heard. + +bcm2835: access controls under the audio mutex + +I don't think the ALSA framework provides any kind of automatic +synchronization within the control callbacks. We most likely need +to ensure this manually, so add locking around all access to shared +mutable data. In particular, bcm2835_audio_set_ctls() should +probably always be called under our own audio lock. + +bcm2835: always use 2/4/8 channels for multichannel layouts + +Pad the unused channels with NA. This means userspace needs to write +additional, silent padding channels, which is not ideal, but better +than noise. + +Works around noise at the following channel counts: 3, 5, 6, 7 + +bcm2835: only allow stereo if analogue jack is selected + +Sending more than 2 channels to videocore while outputting to analogue +mysteriously outputs heavy artifacts. So just paint it over with a +hack: if analogue is explicitly selected as destination, do not +reporting support for anything other than stereo. + +I'm not sure how to deal with the auto case (destination 0). There's +probably way to retrieve this and even to listen to plug events, but +I didn't find one yet, and it's probably not worth the trouble. Just +don't use this setting, I guess. Unless you like noise. + +Changing the setting while an audio stream is active also doesn't +work properly. We could probably interrupt running streams by +returning ENODEV or using kernel hotplug stuff (maybe), but that +also doesn't seem worth the trouble. + +bcm2835: interpolate audio delay + +It appears the GPU only sends us a message all 10ms to update +the playback progress. Other than this, the playback position +(what SNDRV_PCM_IOCTL_DELAY will return) is not updated at all. +Userspace will see jitter up to 10ms in the audio position. + +Make this a bit nicer for userspace by interpolating the +position using the CPU clock. + +I'm not sure if setting snd_pcm_runtime.delay is the right +approach for this. Or if there is maybe an already existing +mechanism for position interpolation in the ALSA core. + +I only set SNDRV_PCM_INFO_BATCH because this appears to remove +at least one situation snd_pcm_runtime.delay is used, so I have +to worry less in which place I have to update this field, or +how it interacts with the rest of ALSA. + +In the future, it might be nice to use VC_AUDIO_MSG_TYPE_LATENCY. +One problem is that it requires sending a videocore message, and +waiting for a reply, which could make the implementation much +harder due to locking and synchronization requirements. --- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 10 ++++ - .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 61 ++++++++++++++++++++++ - 3 files changed, 72 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts + sound/arm/bcm2835-ctl.c | 341 ++++++++++++++++++++++++++++++++++++- + sound/arm/bcm2835-pcm.c | 87 +++++++++- + sound/arm/bcm2835-vchiq.c | 13 ++ + sound/arm/bcm2835.h | 5 + + sound/arm/vc_vchi_audioserv_defs.h | 13 +- + 5 files changed, 447 insertions(+), 12 deletions(-) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 2c2b2fa..687cc7c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -40,6 +40,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4f0be23..6a7aa31 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -504,6 +504,16 @@ Load: dtoverlay=pi3-disable-bt - Params: +diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c +index aad905f..e930718 100755 +--- a/sound/arm/bcm2835-ctl.c ++++ b/sound/arm/bcm2835-ctl.c +@@ -94,6 +94,9 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + { + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ + BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); -+Name: pi3-miniuart-bt -+Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -+ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -+ usable baudrate. -+ N.B. It is also necessary to edit /lib/systemd/system/hciuart.server -+ and replace ttyAMA0 with ttyS0. -+Load: dtoverlay=pi3-miniuart-bt -+Params: + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) +@@ -103,6 +106,7 @@ static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) + ucontrol->value.integer.value[0] = chip->dest; + ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -112,11 +116,15 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { + audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); + if (chip->mute == CTRL_VOL_MUTE) { + /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ +- return 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ ++ changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ ++ goto unlock; + } + if (changed + || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { +@@ -142,6 +150,8 @@ static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, + printk(KERN_ERR "Failed to set ALSA controls..\n"); + } + ++unlock: ++ mutex_unlock(&chip->audio_mutex); + return changed; + } + +@@ -198,10 +208,14 @@ static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -new file mode 100644 -index 0000000..ae1292a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -0,0 +1,61 @@ -+/dts-v1/; -+/plugin/; + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) && 0xff; + ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -212,12 +226,16 @@ static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, + unsigned int val = 0; + int i, change; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -+ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -+ usable baudrate. + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); + + change = val != chip->spdif_status; + chip->spdif_status = val; + ++ mutex_unlock(&chip->audio_mutex); + return change; + } + +@@ -253,9 +271,14 @@ static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+ It is also necessary to edit /lib/systemd/system/hciuart.server and -+ replace ttyAMA0 with ttyS0. + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = + (chip->spdif_status >> (i * 8)) & 0xff; + -+ If cmdline.txt uses the alias serial0 to refer to the user-accessable port -+ then the firmware will replace with the appropriate port whether or not -+ this overlay is used. -+*/ ++ mutex_unlock(&chip->audio_mutex); + return 0; + } + +@@ -266,11 +289,15 @@ static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, + unsigned int val = 0; + int i, change; + ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; + -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ uart0_pins: uart0_pins { -+ brcm,pins = <14 15>; -+ brcm,function = <4>; /* alt0 */ -+ brcm,pull = <0 2>; -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins = <32 33>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/uart@7e201000"; -+ serial1 = "/soc/uart@7e215040"; -+ }; -+ }; -+}; - -From 7c539311298d0f848ba5e300d251572d4f02a891 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 13:38:39 +0000 -Subject: [PATCH 161/251] Pi3 DT: Add dtparams for the SD interface - -Add new base dtparams sd_overclock, sd_force_pio, sd_pio_limit -and sd_debug. These were missed out of the initial Pi3 DTB. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index cc06089..36972d8 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -188,5 +188,9 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -+ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -+ sd_force_pio = <&sdhost>,"brcm,force-pio?"; -+ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -+ sd_debug = <&sdhost>,"brcm,debug"; - }; + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); + change = val != chip->spdif_status; + chip->spdif_status = val; + ++ mutex_unlock(&chip->audio_mutex); + return change; + } + +@@ -300,6 +327,317 @@ static struct snd_kcontrol_new snd_bcm2835_spdif[] = { + }, }; - -From a852495aa0826899b7cf9b7c341ef4c5baea1073 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 15:05:11 +0000 -Subject: [PATCH 162/251] vchiq_arm: Tweak the logging output - -Signed-off-by: Phil Elwell ---- - .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++------------- - 1 file changed, 13 insertions(+), 18 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -index 2c98da4..160db24 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -891,16 +891,14 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, - error_count); - return VCHIQ_ERROR; - } -- if (i == 0) { -- if (SRVTRACE_ENABLED(service, -- VCHIQ_LOG_INFO)) -- vchiq_log_dump_mem("Sent", 0, -- header->data + pos, -- min(64u, -- elements[0].size)); -- } - } -+ if (SRVTRACE_ENABLED(service, -+ VCHIQ_LOG_INFO)) -+ vchiq_log_dump_mem("Sent", 0, -+ header->data, -+ min(16, pos)); ++struct cea_channel_speaker_allocation { ++ int ca_index; ++ int speakers[8]; ++}; + - spin_lock("a_spinlock); - service_quota->message_use_count++; - -@@ -1039,16 +1037,13 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, - error_count); - return VCHIQ_ERROR; - } -- if (i == 0) { -- if (vchiq_sync_log_level >= -- VCHIQ_LOG_TRACE) -- vchiq_log_dump_mem("Sent Sync", -- 0, header->data + pos, -- min(64u, -- elements[0].size)); -- } - } - -+ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) -+ vchiq_log_dump_mem("Sent Sync", -+ 0, header->data, -+ min(16, pos)); ++#define FL SNDRV_CHMAP_FL ++#define FR SNDRV_CHMAP_FR ++#define RL SNDRV_CHMAP_RL ++#define RR SNDRV_CHMAP_RR ++#define LFE SNDRV_CHMAP_LFE ++#define FC SNDRV_CHMAP_FC ++#define RLC SNDRV_CHMAP_RLC ++#define RRC SNDRV_CHMAP_RRC ++#define RC SNDRV_CHMAP_RC ++#define FLC SNDRV_CHMAP_FLC ++#define FRC SNDRV_CHMAP_FRC ++#define FLH SNDRV_CHMAP_TFL ++#define FRH SNDRV_CHMAP_TFR ++#define FLW SNDRV_CHMAP_FLW ++#define FRW SNDRV_CHMAP_FRW ++#define TC SNDRV_CHMAP_TC ++#define FCH SNDRV_CHMAP_TFC ++#define NA SNDRV_CHMAP_NA + - VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); - VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); - } else { -@@ -1720,7 +1715,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, -- min(64, size)); -+ min(16, size)); - } - - if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) -@@ -2187,7 +2182,7 @@ sync_func(void *v) - remoteport, localport, size); - if (size > 0) - vchiq_log_dump_mem("Rcvd", 0, header->data, -- min(64, size)); -+ min(16, size)); - } - - switch (type) { - -From e7f05008cced2d27c9b221614ca469dd48f5bc81 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Mar 2016 16:46:39 +0000 -Subject: [PATCH 163/251] bcm2835-sdhost: Only claim one DMA channel - -With both MMC controllers enabled there are few DMA channels left. The -bcm2835-sdhost driver only uses DMA in one direction at a time, so it -doesn't need to claim two channels. - -See: https://github.com/raspberrypi/linux/issues/1327 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +-- - drivers/mmc/host/bcm2835-sdhost.c | 70 ++++++++++++++++++++++++----------- - 2 files changed, 50 insertions(+), 25 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4f65203..4f833a9 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -136,9 +136,8 @@ - reg = <0x7e202000 0x100>; - interrupts = <2 24>; - clocks = <&clk_core>; -- dmas = <&dma 13>, -- <&dma 13>; -- dma-names = "tx", "rx"; -+ dmas = <&dma 13>; -+ dma-names = "rx-tx"; - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; - status = "disabled"; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 4f6cab5..4cc4272 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -185,9 +185,10 @@ struct bcm2835_host { - unsigned int debug:1; /* Enable debug output */ - - /*DMA part*/ -- struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -- struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -- struct dma_chan *dma_chan; /* Channel in used */ -+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -+ struct dma_chan *dma_chan; /* Channel in use */ -+ struct dma_slave_config dma_cfg_rx; -+ struct dma_slave_config dma_cfg_tx; - struct dma_async_tx_descriptor *dma_desc; - u32 dma_dir; - u32 drain_words; -@@ -771,12 +772,11 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, - log_event("PRD<", (u32)data, 0); - pr_debug("bcm2835_sdhost_prepare_dma()\n"); - -+ dma_chan = host->dma_chan_rxtx; - if (data->flags & MMC_DATA_READ) { -- dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; - } else { -- dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; ++/* ++ * CEA-861 channel maps ++ * ++ * Stolen from sound/pci/hda/patch_hdmi.c ++ * (unlike the source, this uses SNDRV_* constants directly, as by the ++ * map_tables array in patch_hdmi.c) ++ * Entries which do not have a physical output channel use 0. Entries which ++ * require userspace to output silence use NA (SNDRV_CHMAP_NA). ++ */ ++static struct cea_channel_speaker_allocation channel_allocations[] = { ++/* channel: 7 6 5 4 3 2 1 0 */ ++{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, ++ /* 2.1 */ ++{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, NA, LFE, FR, FL } }, ++ /* Dolby Surround */ ++{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, NA, FR, FL } }, ++ /* surround40 */ ++{ .ca_index = 0x08, .speakers = { NA, NA, RR, RL, NA, NA, FR, FL } }, ++ /* surround41 */ ++{ .ca_index = 0x09, .speakers = { NA, NA, RR, RL, NA, LFE, FR, FL } }, ++ /* surround50 */ ++{ .ca_index = 0x0a, .speakers = { NA, NA, RR, RL, FC, NA, FR, FL } }, ++ /* surround51 */ ++{ .ca_index = 0x0b, .speakers = { NA, NA, RR, RL, FC, LFE, FR, FL } }, ++ /* 6.1 */ ++{ .ca_index = 0x0f, .speakers = { NA, RC, RR, RL, FC, LFE, FR, FL } }, ++ /* surround71 */ ++{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, ++ ++{ .ca_index = 0x03, .speakers = { NA, NA, NA, NA, FC, LFE, FR, FL } }, ++{ .ca_index = 0x04, .speakers = { NA, NA, NA, RC, NA, NA, FR, FL } }, ++{ .ca_index = 0x05, .speakers = { NA, NA, NA, RC, NA, LFE, FR, FL } }, ++{ .ca_index = 0x06, .speakers = { NA, NA, NA, RC, FC, NA, FR, FL } }, ++{ .ca_index = 0x07, .speakers = { NA, NA, NA, RC, FC, LFE, FR, FL } }, ++{ .ca_index = 0x0c, .speakers = { NA, RC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x0d, .speakers = { NA, RC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x0e, .speakers = { NA, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x14, .speakers = { FRC, FLC, NA, NA, NA, NA, FR, FL } }, ++{ .ca_index = 0x15, .speakers = { FRC, FLC, NA, NA, NA, LFE, FR, FL } }, ++{ .ca_index = 0x16, .speakers = { FRC, FLC, NA, NA, FC, NA, FR, FL } }, ++{ .ca_index = 0x17, .speakers = { FRC, FLC, NA, NA, FC, LFE, FR, FL } }, ++{ .ca_index = 0x18, .speakers = { FRC, FLC, NA, RC, NA, NA, FR, FL } }, ++{ .ca_index = 0x19, .speakers = { FRC, FLC, NA, RC, NA, LFE, FR, FL } }, ++{ .ca_index = 0x1a, .speakers = { FRC, FLC, NA, RC, FC, NA, FR, FL } }, ++{ .ca_index = 0x1b, .speakers = { FRC, FLC, NA, RC, FC, LFE, FR, FL } }, ++{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x20, .speakers = { NA, FCH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x21, .speakers = { NA, FCH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x22, .speakers = { TC, NA, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x23, .speakers = { TC, NA, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, NA, NA, FR, FL } }, ++{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, NA, LFE, FR, FL } }, ++{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, ++{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, NA, FR, FL } }, ++{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, ++}; ++ ++static int uses_analogue(bcm2835_chip_t *chip) ++{ ++ return chip->dest == 1; ++} ++ ++static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, ++ unsigned int size, unsigned int __user *tlv) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int __user *dst; ++ int count = 0; ++ int i; ++ ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) ++ return -EFAULT; ++ size -= 8; ++ dst = tlv + 2; ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; ++ int num_chs = 0; ++ int chs_bytes; ++ int c; ++ ++ if (i > 0 && uses_analogue(chip)) ++ break; ++ ++ for (c = 0; c < 8; c++) { ++ if (ch->speakers[c]) ++ num_chs++; ++ } ++ ++ chs_bytes = num_chs * 4; ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || ++ put_user(chs_bytes, dst + 1)) ++ return -EFAULT; ++ dst += 2; ++ size -= 8; ++ count += 8; ++ if (size < chs_bytes) ++ return -ENOMEM; ++ size -= chs_bytes; ++ count += chs_bytes; ++ for (c = 0; c < 8; c++) { ++ int sp = ch->speakers[7 - c]; ++ if (sp) { ++ if (put_user(sp, dst)) ++ return -EFAULT; ++ dst++; ++ } ++ } ++ } ++ if (put_user(count, tlv + 1)) ++ return -EFAULT; ++ return 0; ++} ++ ++static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ++ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); ++ struct cea_channel_speaker_allocation *ch = NULL; ++ int res = 0; ++ int cur = 0; ++ int i; ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ if (!substream || !substream->runtime) { ++ res = -ENODEV; ++ goto unlock; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ if (channel_allocations[i].ca_index == chip->cea_chmap) ++ ch = &channel_allocations[i]; ++ } ++ ++ /* If no layout was set yet, return a dummy. Apparently the userspace ++ * API will be confused if we don't. */ ++ if (!ch) ++ ch = &channel_allocations[0]; ++ ++ for (i = 0; i < 8; i++) { ++ if (ch->speakers[7 - i]) ++ ucontrol->value.integer.value[cur++] = ch->speakers[7 - i]; ++ } ++ while (cur < 8) ++ ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; ++ ++unlock: ++ mutex_unlock(&chip->audio_mutex); ++ return res; ++} ++ ++static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); ++ bcm2835_chip_t *chip = info->private_data; ++ unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); ++ struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); ++ int i, prepared = 0, cea_chmap = -1; ++ int res = 0; ++ int remap[8]; ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ if (!substream || !substream->runtime) { ++ res = -ENODEV; ++ goto unlock; ++ } ++ ++ switch (substream->runtime->status->state) { ++ case SNDRV_PCM_STATE_OPEN: ++ case SNDRV_PCM_STATE_SETUP: ++ break; ++ case SNDRV_PCM_STATE_PREPARED: ++ prepared = 1; ++ break; ++ default: ++ res = -EBUSY; ++ goto unlock; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { ++ struct cea_channel_speaker_allocation *ch = &channel_allocations[i]; ++ int matches = 1; ++ int cur = 0; ++ int x; ++ if (i > 0 && uses_analogue(chip)) ++ break; ++ memset(remap, 0, sizeof(remap)); ++ for (x = 0; x < substream->runtime->channels; x++) { ++ int sp = ucontrol->value.integer.value[x]; ++ while (cur < 8 && !ch->speakers[7 - cur]) ++ cur++; ++ if (cur >= 8) { ++ /* user has more channels than ch */ ++ matches = 0; ++ break; ++ } ++ if (ch->speakers[7 - cur] != sp) { ++ matches = 0; ++ break; ++ } ++ remap[x] = cur; ++ cur++; ++ } ++ for (x = cur; x < 8; x++) { ++ if (ch->speakers[7 - x]) { ++ /* ch has more channels than user */ ++ matches = 0; ++ break; ++ } ++ } ++ if (matches) { ++ cea_chmap = ch->ca_index; ++ break; ++ } ++ } ++ ++ if (cea_chmap < 0) { ++ res = -EINVAL; ++ goto unlock; ++ } ++ ++ /* don't change the layout if another substream is active */ ++ if (chip->opened != (1 << substream->number) && chip->cea_chmap != cea_chmap) { ++ res = -EBUSY; /* unsure whether this is a good error code */ ++ goto unlock; ++ } ++ ++ chip->cea_chmap = cea_chmap; ++ for (i = 0; i < 8; i++) ++ chip->map_channels[i] = remap[i]; ++ if (prepared) ++ snd_bcm2835_pcm_prepare_again(substream); ++ ++unlock: ++ mutex_unlock(&chip->audio_mutex); ++ return res; ++} ++ ++static int snd_bcm2835_add_chmap_ctl(bcm2835_chip_t * chip) ++{ ++ struct snd_pcm_chmap *chmap; ++ struct snd_kcontrol *kctl; ++ int err, i; ++ ++ err = snd_pcm_add_chmap_ctls(chip->pcm, ++ SNDRV_PCM_STREAM_PLAYBACK, ++ NULL, 8, 0, &chmap); ++ if (err < 0) ++ return err; ++ /* override handlers */ ++ chmap->private_data = chip; ++ kctl = chmap->kctl; ++ for (i = 0; i < kctl->count; i++) ++ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; ++ kctl->get = snd_bcm2835_chmap_ctl_get; ++ kctl->put = snd_bcm2835_chmap_ctl_put; ++ kctl->tlv.c = snd_bcm2835_chmap_ctl_tlv; ++ return 0; ++} ++ + int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) + { + int err; +@@ -313,6 +651,7 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip) + if (err < 0) + return err; } -@@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host, - host->drain_words = len/4; ++ snd_bcm2835_add_chmap_ctl(chip); + for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); +diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c +index 8c86375..f3a4c6d 100755 +--- a/sound/arm/bcm2835-pcm.c ++++ b/sound/arm/bcm2835-pcm.c +@@ -19,16 +19,19 @@ + + #include "bcm2835.h" + ++/* The hardware can not do much more num_channels*samplerate then this value */ ++#define MAX_COMBINED_RATE 768000 ++ + /* hardware definition */ + static struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | +- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), ++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 1, +- .channels_max = 2, ++ .channels_max = 8, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, +@@ -43,9 +46,9 @@ static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 44100, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 2, +- .channels_max = 2, ++ .channels_max = 8, + .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, + .period_bytes_max = 128 * 1024, +@@ -96,6 +99,8 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) + alsa_stream->pos %= alsa_stream->buffer_size; } -+ /* The parameters have already been validated, so this will not fail */ -+ (void)dmaengine_slave_config(dma_chan, -+ (dir_data == DMA_FROM_DEVICE) ? -+ &host->dma_cfg_rx : -+ &host->dma_cfg_tx); ++ alsa_stream->interpolate_start = ktime_get_ns(); + - len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len, - dir_data); + if (alsa_stream->substream) { + if (new_period) + snd_pcm_period_elapsed(alsa_stream->substream); +@@ -107,6 +112,31 @@ static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id) + return IRQ_HANDLED; + } -@@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - spin_lock_init(&host->lock); ++ ++static int rate_hw_constraint_rate(struct snd_pcm_hw_params *params, ++ struct snd_pcm_hw_rule *rule) ++{ ++ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); ++ struct snd_interval rates = { ++ .min = 8000, ++ .max = min(192000u, MAX_COMBINED_RATE / max(channels->min, 1u)), ++ }; ++ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); ++ return snd_interval_refine(rate, &rates); ++} ++ ++static int rate_hw_constraint_channels(struct snd_pcm_hw_params *params, ++ struct snd_pcm_hw_rule *rule) ++{ ++ struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); ++ struct snd_interval channels_interval = { ++ .min = 1, ++ .max = min(8u, MAX_COMBINED_RATE / max(rate->min, 1u)), ++ }; ++ struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); ++ return snd_interval_refine(channels, &channels_interval); ++} ++ + /* open callback */ + static int snd_bcm2835_playback_open_generic( + struct snd_pcm_substream *substream, int spdif) +@@ -188,8 +218,24 @@ static int snd_bcm2835_playback_open_generic( + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 16); - if (host->allow_dma) { -- if (IS_ERR_OR_NULL(host->dma_chan_tx) || -- IS_ERR_OR_NULL(host->dma_chan_rx)) { -- pr_err("%s: unable to initialise DMA channels. " -+ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { -+ pr_err("%s: unable to initialise DMA channel. " - "Falling back to PIO\n", - mmc_hostname(mmc)); - host->use_dma = false; - } else { -- host->use_dma = true; ++ /* When playing PCM, pretend that we support the full range of channels ++ * and sample rates. The GPU can't output it, but is able to resample ++ * the data to a rate the hardware can handle it. This won't work with ++ * compressed data; the resampler would just destroy it. */ ++ if (spdif) { ++ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ++ rate_hw_constraint_rate, NULL, ++ SNDRV_PCM_HW_PARAM_CHANNELS, -1); ++ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, ++ rate_hw_constraint_channels, NULL, ++ SNDRV_PCM_HW_PARAM_RATE, -1); ++ } ++ + chip->alsa_stream[idx] = alsa_stream; + ++ if (!chip->opened) ++ chip->cea_chmap = -1; ++ + chip->opened |= (1 << idx); + alsa_stream->open = 1; + alsa_stream->draining = 1; +@@ -300,8 +346,7 @@ static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) + return snd_pcm_lib_free_pages(substream); + } + +-/* prepare callback */ +-static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) ++int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream) + { + bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -309,8 +354,6 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + int channels; + int err; + +- audio_info(" .. IN\n"); - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.slave_id = 13; /* DREQ channel */ - -+ /* Validate the slave configurations */ -+ - cfg.direction = DMA_MEM_TO_DEV; - cfg.src_addr = 0; - cfg.dst_addr = host->bus_addr + SDDATA; -- ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); - -- cfg.direction = DMA_DEV_TO_MEM; -- cfg.src_addr = host->bus_addr + SDDATA; -- cfg.dst_addr = 0; -- ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ -+ if (ret == 0) { -+ host->dma_cfg_tx = cfg; -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDDATA; -+ cfg.dst_addr = 0; -+ -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ } -+ -+ if (ret == 0) { -+ host->dma_cfg_rx = cfg; -+ -+ host->use_dma = true; -+ } else { -+ pr_err("%s: unable to configure DMA channel. " -+ "Falling back to PIO\n", -+ mmc_hostname(mmc)); -+ dma_release_channel(host->dma_chan_rxtx); -+ host->dma_chan_rxtx = NULL; -+ host->use_dma = false; -+ } - } - } else { - host->use_dma = false; -@@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - - if (host->allow_dma) { - if (node) { -- host->dma_chan_tx = -- dma_request_slave_channel(dev, "tx"); -- host->dma_chan_rx = -- dma_request_slave_channel(dev, "rx"); -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx-tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx"); - } else { - dma_cap_mask_t mask; - - dma_cap_zero(mask); - /* we don't care about the channel, any would work */ - dma_cap_set(DMA_SLAVE, mask); -- host->dma_chan_tx = -- dma_request_channel(mask, NULL, NULL); -- host->dma_chan_rx = -+ host->dma_chan_rxtx = - dma_request_channel(mask, NULL, NULL); - } + /* notify the vchiq that it should enter spdif passthrough mode by + * setting channels=0 (see + * https://github.com/raspberrypi/linux/issues/528) */ +@@ -326,6 +369,23 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + audio_error(" error setting hw params\n"); } + ++ return err; ++} ++ ++/* prepare callback */ ++static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ ++ audio_info(" .. IN\n"); ++ ++ if (mutex_lock_interruptible(&chip->audio_mutex)) ++ return -EINTR; ++ ++ snd_bcm2835_pcm_prepare_again(substream); ++ + bcm2835_audio_setup(alsa_stream); + + /* in preparation of the stream, set the controls (volume level) of the stream */ +@@ -341,11 +401,13 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); + alsa_stream->pos = 0; ++ alsa_stream->interpolate_start = ktime_get_ns(); + + audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", + alsa_stream->buffer_size, alsa_stream->period_size, + alsa_stream->pos, runtime->frame_bits); + ++ mutex_unlock(&chip->audio_mutex); + audio_info(" .. OUT\n"); + return 0; + } +@@ -436,6 +498,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; ++ u64 now = ktime_get_ns(); + + audio_info(" .. IN\n"); + +@@ -444,6 +507,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) + frames_to_bytes(runtime, runtime->control->appl_ptr), + alsa_stream->pos); + ++ /* Give userspace better delay reporting by interpolating between GPU ++ * notifications, assuming audio speed is close enough to the clock ++ * used for ktime */ ++ if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) ++ runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); ++ + audio_info(" .. OUT\n"); + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, +diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c +index 3de3094..8ecd2d7 100755 +--- a/sound/arm/bcm2835-vchiq.c ++++ b/sound/arm/bcm2835-vchiq.c +@@ -570,6 +570,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, + VC_AUDIO_MSG_T m; + AUDIO_INSTANCE_T *instance = alsa_stream->instance; + int32_t success; ++ uint32_t chmap_value; ++ int i; + int ret; + LOG_DBG(" .. IN\n"); + +@@ -593,10 +595,21 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, + + instance->result = -1; + ++ if (alsa_stream->chip->cea_chmap >= 0) { ++ chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; ++ } else { ++ chmap_value = 0; /* force stereo */ ++ for (i = 0; i < 8; i++) ++ alsa_stream->chip->map_channels[i] = i; ++ } ++ for (i = 0; i < 8; i++) ++ chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); ++ + m.type = VC_AUDIO_MSG_TYPE_CONFIG; + m.u.config.channels = channels; + m.u.config.samplerate = samplerate; + m.u.config.bps = bps; ++ m.u.config.channelmap = chmap_value; + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); +diff --git a/sound/arm/bcm2835.h b/sound/arm/bcm2835.h +index 0f71c5d..20ef108 100755 +--- a/sound/arm/bcm2835.h ++++ b/sound/arm/bcm2835.h +@@ -107,6 +107,8 @@ typedef struct bcm2835_chip { + int old_volume; /* stores the volume value whist muted */ + int dest; + int mute; ++ int cea_chmap; /* currently requested Audio InfoFrame Data Byte 4 */ ++ int map_channels[8]; + + unsigned int opened; + unsigned int spdif_status; +@@ -135,6 +137,7 @@ typedef struct bcm2835_alsa_stream { + unsigned int pos; + unsigned int buffer_size; + unsigned int period_size; ++ u64 interpolate_start; + + uint32_t enable_fifo_irq; + irq_handler_t fifo_irq_handler; +@@ -149,6 +152,8 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t * chip); + int snd_bcm2835_new_pcm(bcm2835_chip_t * chip); + int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip); + ++int snd_bcm2835_pcm_prepare_again(struct snd_pcm_substream *substream); ++ + int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream); + int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream); + int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, +diff --git a/sound/arm/vc_vchi_audioserv_defs.h b/sound/arm/vc_vchi_audioserv_defs.h +index af3e6eb..5f4409f 100644 +--- a/sound/arm/vc_vchi_audioserv_defs.h ++++ b/sound/arm/vc_vchi_audioserv_defs.h +@@ -16,7 +16,7 @@ + #define _VC_AUDIO_DEFS_H_ + + #define VC_AUDIOSERV_MIN_VER 1 +-#define VC_AUDIOSERV_VER 2 ++#define VC_AUDIOSERV_VER 3 + + // FourCC code used for VCHI connection + #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") +@@ -36,6 +36,7 @@ typedef enum { + VC_AUDIO_MSG_TYPE_START, // Configure audio + VC_AUDIO_MSG_TYPE_STOP, // Configure audio + VC_AUDIO_MSG_TYPE_WRITE, // Configure audio ++ VC_AUDIO_MSG_TYPE_LATENCY, // request latency in cycles + VC_AUDIO_MSG_TYPE_MAX + } VC_AUDIO_MSG_TYPE; + +@@ -44,6 +45,7 @@ typedef struct { + uint32_t channels; + uint32_t samplerate; + uint32_t bps; ++ uint32_t channelmap; + + } VC_AUDIO_CONFIG_T; + +@@ -84,6 +86,12 @@ typedef struct { + uint16_t max_packet; + } VC_AUDIO_WRITE_T; + ++// query latency in samples of sink ++typedef struct ++{ ++ uint32_t dummy; ++} VC_AUDIO_LATENCY_T; ++ + // Generic result for a request (VC->HOST) + typedef struct { + int32_t success; // Success value +@@ -108,9 +116,10 @@ typedef struct { + VC_AUDIO_START_T start; + VC_AUDIO_STOP_T stop; + VC_AUDIO_WRITE_T write; ++ VC_AUDIO_LATENCY_T latency; + VC_AUDIO_RESULT_T result; + VC_AUDIO_COMPLETE_T complete; + } u; + } VC_AUDIO_MSG_T; + +-#endif // _VC_AUDIO_DEFS_H_ ++#endif // _VC_AUDIO_DEFS_H_ +\ No newline at end of file -From afe2e242d78005f19d1611ad15124ce576225778 Mon Sep 17 00:00:00 2001 +From 799752a785774372412162ca01eba8f21518c833 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou +Date: Wed, 3 Dec 2014 13:23:28 +0200 +Subject: [PATCH 087/114] OF: DT-Overlay configfs interface + +This is a port of Pantelis Antoniou's v3 port that makes use of the +new upstreamed configfs support for binary attributes. + +Original commit message: + +Add a runtime interface to using configfs for generic device tree overlay +usage. With it its possible to use device tree overlays without having +to use a per-platform overlay manager. + +Please see Documentation/devicetree/configfs-overlays.txt for more info. + +Changes since v2: +- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) +- Created a documentation entry +- Slight rewording in Kconfig + +Changes since v1: +- of_resolve() -> of_resolve_phandles(). + +Originally-signed-off-by: Pantelis Antoniou +Signed-off-by: Phil Elwell +--- + Documentation/devicetree/configfs-overlays.txt | 31 +++ + drivers/of/Kconfig | 7 + + drivers/of/Makefile | 1 + + drivers/of/configfs.c | 314 +++++++++++++++++++++++++ + 4 files changed, 353 insertions(+) + create mode 100644 Documentation/devicetree/configfs-overlays.txt + create mode 100644 drivers/of/configfs.c + +diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt +new file mode 100644 +index 0000000..5fa43e0 +--- /dev/null ++++ b/Documentation/devicetree/configfs-overlays.txt +@@ -0,0 +1,31 @@ ++Howto use the configfs overlay interface. ++ ++A device-tree configfs entry is created in /config/device-tree/overlays ++and and it is manipulated using standard file system I/O. ++Note that this is a debug level interface, for use by developers and ++not necessarily something accessed by normal users due to the ++security implications of having direct access to the kernel's device tree. ++ ++* To create an overlay you mkdir the directory: ++ ++ # mkdir /config/device-tree/overlays/foo ++ ++* Either you echo the overlay firmware file to the path property file. ++ ++ # echo foo.dtbo >/config/device-tree/overlays/foo/path ++ ++* Or you cat the contents of the overlay to the dtbo file ++ ++ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo ++ ++The overlay file will be applied, and devices will be created/destroyed ++as required. ++ ++To remove it simply rmdir the directory. ++ ++ # rmdir /config/device-tree/overlays/foo ++ ++The rationalle of the dual interface (firmware & direct copy) is that each is ++better suited to different use patterns. The firmware interface is what's ++intended to be used by hardware managers in the kernel, while the copy interface ++make sense for developers (since it avoids problems with namespaces). +diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig +index e2a4841..7e5e6c4 100644 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -112,4 +112,11 @@ config OF_OVERLAY + While this option is selected automatically when needed, you can + enable it manually to improve device tree unit test coverage. + ++config OF_CONFIGFS ++ bool "Device Tree Overlay ConfigFS interface" ++ select CONFIGFS_FS ++ select OF_OVERLAY ++ help ++ Enable a simple user-space driven DT overlay interface. ++ + endif # OF +diff --git a/drivers/of/Makefile b/drivers/of/Makefile +index 156c072..46c8f57 100644 +--- a/drivers/of/Makefile ++++ b/drivers/of/Makefile +@@ -1,4 +1,5 @@ + obj-y = base.o device.o platform.o ++obj-$(CONFIG_OF_CONFIGFS) += configfs.o + obj-$(CONFIG_OF_DYNAMIC) += dynamic.o + obj-$(CONFIG_OF_FLATTREE) += fdt.o + obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +new file mode 100644 +index 0000000..7b66deb +--- /dev/null ++++ b/drivers/of/configfs.c +@@ -0,0 +1,314 @@ ++/* ++ * Configfs entries for device-tree ++ * ++ * Copyright (C) 2013 - Pantelis Antoniou ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "of_private.h" ++ ++struct cfs_overlay_item { ++ struct config_item item; ++ ++ char path[PATH_MAX]; ++ ++ const struct firmware *fw; ++ struct device_node *overlay; ++ int ov_id; ++ ++ void *dtbo; ++ int dtbo_size; ++}; ++ ++static int create_overlay(struct cfs_overlay_item *overlay, void *blob) ++{ ++ int err; ++ ++ /* unflatten the tree */ ++ of_fdt_unflatten_tree(blob, &overlay->overlay); ++ if (overlay->overlay == NULL) { ++ pr_err("%s: failed to unflatten tree\n", __func__); ++ err = -EINVAL; ++ goto out_err; ++ } ++ pr_debug("%s: unflattened OK\n", __func__); ++ ++ /* mark it as detached */ ++ of_node_set_flag(overlay->overlay, OF_DETACHED); ++ ++ /* perform resolution */ ++ err = of_resolve_phandles(overlay->overlay); ++ if (err != 0) { ++ pr_err("%s: Failed to resolve tree\n", __func__); ++ goto out_err; ++ } ++ pr_debug("%s: resolved OK\n", __func__); ++ ++ err = of_overlay_create(overlay->overlay); ++ if (err < 0) { ++ pr_err("%s: Failed to create overlay (err=%d)\n", ++ __func__, err); ++ goto out_err; ++ } ++ overlay->ov_id = err; ++ ++out_err: ++ return err; ++} ++ ++static inline struct cfs_overlay_item *to_cfs_overlay_item( ++ struct config_item *item) ++{ ++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; ++} ++ ++static ssize_t cfs_overlay_item_path_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ return sprintf(page, "%s\n", overlay->path); ++} ++ ++static ssize_t cfs_overlay_item_path_store(struct config_item *item, ++ const char *page, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ const char *p = page; ++ char *s; ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy to path buffer (and make sure it's always zero terminated */ ++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); ++ overlay->path[sizeof(overlay->path) - 1] = '\0'; ++ ++ /* strip trailing newlines */ ++ s = overlay->path + strlen(overlay->path); ++ while (s > overlay->path && *--s == '\n') ++ *s = '\0'; ++ ++ pr_debug("%s: path is '%s'\n", __func__, overlay->path); ++ ++ err = request_firmware(&overlay->fw, overlay->path, NULL); ++ if (err != 0) ++ goto out_err; ++ ++ err = create_overlay(overlay, (void *)overlay->fw->data); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ ++ release_firmware(overlay->fw); ++ overlay->fw = NULL; ++ ++ overlay->path[0] = '\0'; ++ return err; ++} ++ ++static ssize_t cfs_overlay_item_status_show(struct config_item *item, ++ char *page) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ return sprintf(page, "%s\n", ++ overlay->ov_id >= 0 ? "applied" : "unapplied"); ++} ++ ++CONFIGFS_ATTR(cfs_overlay_item_, path); ++CONFIGFS_ATTR_RO(cfs_overlay_item_, status); ++ ++static struct configfs_attribute *cfs_overlay_attrs[] = { ++ &cfs_overlay_item_attr_path, ++ &cfs_overlay_item_attr_status, ++ NULL, ++}; ++ ++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, ++ void *buf, size_t max_count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ pr_debug("%s: buf=%p max_count=%u\n", __func__, ++ buf, max_count); ++ ++ if (overlay->dtbo == NULL) ++ return 0; ++ ++ /* copy if buffer provided */ ++ if (buf != NULL) { ++ /* the buffer must be large enough */ ++ if (overlay->dtbo_size > max_count) ++ return -ENOSPC; ++ ++ memcpy(buf, overlay->dtbo, overlay->dtbo_size); ++ } ++ ++ return overlay->dtbo_size; ++} ++ ++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, ++ const void *buf, size_t count) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ int err; ++ ++ /* if it's set do not allow changes */ ++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) ++ return -EPERM; ++ ++ /* copy the contents */ ++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); ++ if (overlay->dtbo == NULL) ++ return -ENOMEM; ++ ++ overlay->dtbo_size = count; ++ ++ err = create_overlay(overlay, overlay->dtbo); ++ if (err != 0) ++ goto out_err; ++ ++ return count; ++ ++out_err: ++ kfree(overlay->dtbo); ++ overlay->dtbo = NULL; ++ overlay->dtbo_size = 0; ++ ++ return err; ++} ++ ++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); ++ ++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { ++ &cfs_overlay_item_attr_dtbo, ++ NULL, ++}; ++ ++static void cfs_overlay_release(struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ if (overlay->ov_id >= 0) ++ of_overlay_destroy(overlay->ov_id); ++ if (overlay->fw) ++ release_firmware(overlay->fw); ++ /* kfree with NULL is safe */ ++ kfree(overlay->dtbo); ++ kfree(overlay); ++} ++ ++static struct configfs_item_operations cfs_overlay_item_ops = { ++ .release = cfs_overlay_release, ++}; ++ ++static struct config_item_type cfs_overlay_type = { ++ .ct_item_ops = &cfs_overlay_item_ops, ++ .ct_attrs = cfs_overlay_attrs, ++ .ct_bin_attrs = cfs_overlay_bin_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *cfs_overlay_group_make_item( ++ struct config_group *group, const char *name) ++{ ++ struct cfs_overlay_item *overlay; ++ ++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); ++ if (!overlay) ++ return ERR_PTR(-ENOMEM); ++ overlay->ov_id = -1; ++ ++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); ++ return &overlay->item; ++} ++ ++static void cfs_overlay_group_drop_item(struct config_group *group, ++ struct config_item *item) ++{ ++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); ++ ++ config_item_put(&overlay->item); ++} ++ ++static struct configfs_group_operations overlays_ops = { ++ .make_item = cfs_overlay_group_make_item, ++ .drop_item = cfs_overlay_group_drop_item, ++}; ++ ++static struct config_item_type overlays_type = { ++ .ct_group_ops = &overlays_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct configfs_group_operations of_cfs_ops = { ++ /* empty - we don't allow anything to be created */ ++}; ++ ++static struct config_item_type of_cfs_type = { ++ .ct_group_ops = &of_cfs_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ ++struct config_group of_cfs_overlay_group; ++ ++struct config_group *of_cfs_def_groups[] = { ++ &of_cfs_overlay_group, ++ NULL ++}; ++ ++static struct configfs_subsystem of_cfs_subsys = { ++ .su_group = { ++ .cg_item = { ++ .ci_namebuf = "device-tree", ++ .ci_type = &of_cfs_type, ++ }, ++ .default_groups = of_cfs_def_groups, ++ }, ++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), ++}; ++ ++static int __init of_cfs_init(void) ++{ ++ int ret; ++ ++ pr_info("%s\n", __func__); ++ ++ config_group_init(&of_cfs_subsys.su_group); ++ config_group_init_type_name(&of_cfs_overlay_group, "overlays", ++ &overlays_type); ++ ++ ret = configfs_register_subsystem(&of_cfs_subsys); ++ if (ret != 0) { ++ pr_err("%s: failed to register subsys\n", __func__); ++ goto out; ++ } ++ pr_info("%s: OK\n", __func__); ++out: ++ return ret; ++} ++late_initcall(of_cfs_init); + +From 8ac9864a4bd3d7b096fc385db58d39b53da206f3 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 8 Mar 2016 09:49:16 +0000 -Subject: [PATCH 164/251] bcm2835-mmc: Only claim one DMA channel +Date: Fri, 13 Mar 2015 12:43:36 +0000 +Subject: [PATCH 088/114] Protect __release_resource against resources without + parents -With both MMC controllers enabled there are few DMA channels left. The -bcm2835-mmc driver only uses DMA in one direction at a time, so it -doesn't need to claim two channels. - -See: https://github.com/raspberrypi/linux/issues/1327 +Without this patch, removing a device tree overlay can crash here. Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +-- - drivers/mmc/host/bcm2835-mmc.c | 69 +++++++++++++++++++++++++---------- - 2 files changed, 51 insertions(+), 23 deletions(-) + kernel/resource.c | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4f833a9..e0be77a 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -232,9 +232,8 @@ - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -+ dmas = <&dma 11>; -+ dma-names = "rx-tx"; - brcm,overclock-50 = <0>; - status = "disabled"; - }; -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 104f93e..ceb3793 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -108,8 +108,9 @@ struct bcm2835_host { - u32 shadow; +diff --git a/kernel/resource.c b/kernel/resource.c +index 9b5f044..f8a9af6 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -246,6 +246,12 @@ static int __release_resource(struct resource *old, bool release_child) + { + struct resource *tmp, **p, *chd; - /*DMA part*/ -- struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -- struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -+ struct dma_slave_config dma_cfg_rx; -+ struct dma_slave_config dma_cfg_tx; - struct dma_async_tx_descriptor *tx_desc; /* descriptor */ - - bool have_dma; -@@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(void *param) - - if (host->data && !(host->data->flags & MMC_DATA_WRITE)) { - /* otherwise handled in SDHCI IRQ */ -- dma_chan = host->dma_chan_rx; -+ dma_chan = host->dma_chan_rxtx; - dir_data = DMA_FROM_DEVICE; - - dma_unmap_sg(dma_chan->device->dev, -@@ -493,16 +494,21 @@ static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) - if (host->blocks == 0) - return; - -+ dma_chan = host->dma_chan_rxtx; - if (host->data->flags & MMC_DATA_READ) { -- dma_chan = host->dma_chan_rx; - dir_data = DMA_FROM_DEVICE; - dir_slave = DMA_DEV_TO_MEM; - } else { -- dma_chan = host->dma_chan_tx; - dir_data = DMA_TO_DEVICE; - dir_slave = DMA_MEM_TO_DEV; - } - -+ /* The parameters have already been validated, so this will not fail */ -+ (void)dmaengine_slave_config(dma_chan, -+ (dir_data == DMA_FROM_DEVICE) ? -+ &host->dma_cfg_rx : -+ &host->dma_cfg_tx); -+ - BUG_ON(!dma_chan->device); - BUG_ON(!dma_chan->device->dev); - BUG_ON(!host->data->sg); -@@ -936,7 +942,7 @@ static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask) - if (host->data->flags & MMC_DATA_WRITE) { - /* IRQ handled here */ - -- dma_chan = host->dma_chan_tx; -+ dma_chan = host->dma_chan_rxtx; - dir_data = DMA_TO_DEVICE; - dma_unmap_sg(dma_chan->device->dev, - host->data->sg, host->data->sg_len, -@@ -1316,28 +1322,47 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; - #else -- if (IS_ERR_OR_NULL(host->dma_chan_tx) || -- IS_ERR_OR_NULL(host->dma_chan_rx)) { -- dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n", -+ if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) { -+ dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n", - DRIVER_NAME); - host->have_dma = false; - } else { -- dev_info(dev, "DMA channels allocated"); -- host->have_dma = true; -+ dev_info(dev, "DMA channel allocated"); - - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - cfg.slave_id = 11; /* DREQ channel */ - -+ /* Validate the slave configurations */ -+ - cfg.direction = DMA_MEM_TO_DEV; - cfg.src_addr = 0; - cfg.dst_addr = host->bus_addr + SDHCI_BUFFER; -- ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); - -- cfg.direction = DMA_DEV_TO_MEM; -- cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -- cfg.dst_addr = 0; -- ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ -+ if (ret == 0) { -+ host->dma_cfg_tx = cfg; -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->bus_addr + SDHCI_BUFFER; -+ cfg.dst_addr = 0; -+ -+ ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg); -+ } -+ -+ if (ret == 0) { -+ host->dma_cfg_rx = cfg; -+ -+ host->use_dma = true; -+ } else { -+ pr_err("%s: unable to configure DMA channel. " -+ "Faling back to PIO\n", -+ mmc_hostname(mmc)); -+ dma_release_channel(host->dma_chan_rxtx); -+ host->dma_chan_rxtx = NULL; -+ host->use_dma = false; -+ } - } - #endif - mmc->max_segs = 128; -@@ -1416,16 +1441,20 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) - - #ifndef FORCE_PIO - if (node) { -- host->dma_chan_tx = dma_request_slave_channel(dev, "tx"); -- host->dma_chan_rx = dma_request_slave_channel(dev, "rx"); -+ host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "tx"); -+ if (!host->dma_chan_rxtx) -+ host->dma_chan_rxtx = -+ dma_request_slave_channel(dev, "rx"); - } else { - dma_cap_mask_t mask; - - dma_cap_zero(mask); - /* we don't care about the channel, any would work */ - dma_cap_set(DMA_SLAVE, mask); -- host->dma_chan_tx = dma_request_channel(mask, NULL, NULL); -- host->dma_chan_rx = dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL); - } - #endif - clk = devm_clk_get(dev, NULL); ++ if (!old->parent) { ++ WARN(old->sibling, "sibling but no parent"); ++ if (old->sibling) ++ return -EINVAL; ++ return 0; ++ } + p = &old->parent->child; + for (;;) { + tmp = *p; -From ba461323859e90843ed2a65dd223a60244782814 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 8 Mar 2016 17:08:39 +0000 -Subject: [PATCH 165/251] config: rebuild with savedefconfig - ---- - arch/arm/configs/bcm2709_defconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6d6b519..116002b 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -593,7 +593,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y --CONFIG_HW_RANDOM_BCM2835=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -@@ -1112,7 +1111,7 @@ CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m - CONFIG_IIO=m - CONFIG_IIO_BUFFER=y --CONFIG_IIO_BUFFER_CB=y -+CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m - CONFIG_DHT11=m - -From 226c823c6dde5546476a22be8d681712924ad6ef Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 8 Mar 2016 17:06:33 +0000 -Subject: [PATCH 166/251] config: Add module for mcp3422 ADC - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 116002b..7793baf 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1114,6 +1114,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m -+CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 1ca1695..f09be87 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1121,6 +1121,7 @@ CONFIG_IIO_BUFFER=y - CONFIG_IIO_BUFFER_CB=m - CONFIG_IIO_KFIFO_BUF=m - CONFIG_MCP320X=m -+CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m - CONFIG_RASPBERRYPI_FIRMWARE=y - -From f27ae7ba1432ab3604faaf8ca79ed31a5edc8d42 Mon Sep 17 00:00:00 2001 +From 91a49d58dc66d3523951fe8c810ce6cf224b0074 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 8 Mar 2016 16:18:57 +0000 -Subject: [PATCH 167/251] Pi3 DT: Add pull-ups on the UART RX lines +Date: Fri, 13 Mar 2015 20:00:21 +0000 +Subject: [PATCH 089/114] BCM270X_DT: Add a .dtbo target, use for overlays + +Change the filenames and extensions to keep the pre-DDT style of +overlay (-overlay.dtb) distinct from new ones that use a +different style of local fixups (.dtbo), and to match other +platforms. + +The RPi firmware uses the DDTK trailer atom to choose which type of +overlay to use for each kernel. Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++-- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) + arch/arm/boot/.gitignore | 2 +- + scripts/Makefile.dtbinst | 10 +++++++--- + scripts/Makefile.lib | 10 ++++++++++ + 3 files changed, 18 insertions(+), 4 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 36972d8..5a0c45a 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -53,13 +53,13 @@ - uart0_pins: uart0_pins { - brcm,pins = <32 33>; - brcm,function = <7>; /* alt3=UART0 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; +diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore +index 3c79f85..eaaeb17 100644 +--- a/arch/arm/boot/.gitignore ++++ b/arch/arm/boot/.gitignore +@@ -3,4 +3,4 @@ zImage + xipImage + bootpImage + uImage +-*.dtb ++*.dtb* +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index a1be75d..ad8dc1c 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -27,6 +27,7 @@ ifeq ("$(dtbinst-root)", "$(obj)") + endif - uart1_pins: uart1_pins { - brcm,pins = <14 15>; - brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; - }; + dtbinst-files := $(dtb-y) ++dtboinst-files := $(dtbo-y) + dtbinst-dirs := $(dts-dirs) -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index ae1292a..0b8f0ca 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -46,7 +46,7 @@ - uart1_pins: uart1_pins { - brcm,pins = <32 33>; - brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 0>; -+ brcm,pull = <0 2>; - }; - }; - }; + # Helper targets for Installing DTBs into the boot directory +@@ -35,15 +36,18 @@ quiet_cmd_dtb_install = INSTALL $< + + install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) + +-$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep ++$(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs): | __dtbs_install_prep + + $(dtbinst-files): %.dtb: $(obj)/%.dtb + $(call cmd,dtb_install,$(install-dir)) + ++$(dtboinst-files): %.dtbo: $(obj)/%.dtbo ++ $(call cmd,dtb_install,$(install-dir)) ++ + $(dtbinst-dirs): + $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(dtbinst-files) $(dtbinst-dirs) +-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) ++PHONY += $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) ++__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) + + .PHONY: $(PHONY) +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index ddf83d0..c819ddc 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -306,6 +306,16 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ + $(obj)/%.dtb: $(src)/%.dts FORCE + $(call if_changed_dep,dtc) + ++quiet_cmd_dtco = DTCO $@ ++cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ ++ $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ ++ -i $(dir $<) $(DTC_FLAGS) \ ++ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ ++ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ++ ++$(obj)/%.dtbo: $(src)/%-overlay.dts FORCE ++ $(call if_changed_dep,dtco) ++ + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + + # Bzip2 -From e5b66ba646a96ad37ea4c7cc240c34e9d77f0eea Mon Sep 17 00:00:00 2001 +From 96fd3ebbca3c81575bf3dc7681c0f67243fc1af3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 29 May 2015 11:18:58 +0100 +Subject: [PATCH 090/114] scripts/knlinfo: Decode DDTK atom + +Show the DDTK atom as being a boolean. + +Signed-off-by: Phil Elwell +--- + scripts/knlinfo | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/scripts/knlinfo b/scripts/knlinfo +index b9ef124..263ec93 100755 +--- a/scripts/knlinfo ++++ b/scripts/knlinfo +@@ -16,6 +16,7 @@ my $trailer_magic = 'RPTL'; + + my %atom_formats = + ( ++ 'DDTK' => \&format_bool, + 'DTOK' => \&format_bool, + 'KVer' => \&format_string, + '270X' => \&format_bool, +@@ -148,7 +149,7 @@ sub format_atom + sub format_bool + { + my ($data) = @_; +- return unpack('V', $data) ? 'true' : 'false'; ++ return unpack('V', $data) ? 'y' : 'n'; + } + + sub format_int + +From 5ba639e7dfecaa2341b48645ea6297469cb644fd Mon Sep 17 00:00:00 2001 +From: Cheong2K +Date: Fri, 26 Feb 2016 18:20:10 +0800 +Subject: [PATCH 091/114] brcm: adds support for BCM43341 wifi + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 43fd3f4..c3c7c79 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -606,6 +606,7 @@ BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); + BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); ++BRCMF_FW_NVRAM_DEF(43341, "brcmfmac43341-sdio.bin", "brcmfmac43341-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); + BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt"); + BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt"); +@@ -622,6 +623,7 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), ++ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43341), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), + BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +index 699f2c2..15598b3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -35,6 +35,7 @@ + #define BRCM_CC_4330_CHIP_ID 0x4330 + #define BRCM_CC_4334_CHIP_ID 0x4334 + #define BRCM_CC_43340_CHIP_ID 43340 ++#define BRCM_CC_43341_CHIP_ID 43341 + #define BRCM_CC_43362_CHIP_ID 43362 + #define BRCM_CC_4335_CHIP_ID 0x4335 + #define BRCM_CC_4339_CHIP_ID 0x4339 + +From 469393b56eef50bc105c7508c4a35bc66cc120ce Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 9 Mar 2016 17:25:59 +0000 -Subject: [PATCH 168/251] brcmfmac: Disable power management +Subject: [PATCH 092/114] brcmfmac: Disable power management Disable wireless power saving in the brcmfmac WLAN driver. This is a temporary measure until the connectivity loss resulting from power @@ -149742,14 +128174,14 @@ saving is resolved. Signed-off-by: Phil Elwell --- - drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -index deb5f78..90f65d9 100644 ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -2567,6 +2567,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d5c2a27..5a08f59 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2623,6 +2623,8 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, * preference in cfg struct to apply this to * FW later while initializing the dongle */ @@ -149759,4523 +128191,148 @@ index deb5f78..90f65d9 100644 if (!check_vif_up(ifp->vif)) { -From 6be841fb1dc54f49488ac814034726a0eecb26c7 Mon Sep 17 00:00:00 2001 +From 8077a80f7213a87ae6ee2adc25799fec6e1bfe4d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 22 Jan 2016 13:06:39 -0800 +Subject: [PATCH 093/114] drm/vc4: Add a debugfs node for tracking execution + state. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.h | 1 + + drivers/gpu/drm/vc4/vc4_gem.c | 14 ++++++++++++++ + 3 files changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c +index d76ad10..a99aa86 100644 +--- a/drivers/gpu/drm/vc4/vc4_debugfs.c ++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c +@@ -17,6 +17,7 @@ + + static const struct drm_info_list vc4_debugfs_list[] = { + {"bo_stats", vc4_bo_stats_debugfs, 0}, ++ {"gem_exec", vc4_gem_exec_debugfs, 0}, + {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, + {"hvs_regs", vc4_hvs_debugfs_regs, 0}, + {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index fa2ad15..f092986 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -440,6 +440,7 @@ void vc4_job_handle_completed(struct vc4_dev *vc4); + int vc4_queue_seqno_cb(struct drm_device *dev, + struct vc4_seqno_cb *cb, uint64_t seqno, + void (*func)(struct vc4_seqno_cb *cb)); ++int vc4_gem_exec_debugfs(struct seq_file *m, void *arg); + + /* vc4_hdmi.c */ + extern struct platform_driver vc4_hdmi_driver; +diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c +index 8d4384f..aa4517c 100644 +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -32,6 +32,20 @@ + #include "vc4_regs.h" + #include "vc4_trace.h" + ++#ifdef CONFIG_DEBUG_FS ++int vc4_gem_exec_debugfs(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *)m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(dev); ++ ++ seq_printf(m, "Emitted seqno: 0x%016llx\n", vc4->emit_seqno); ++ seq_printf(m, "Finished seqno: 0x%016llx\n", vc4->finished_seqno); ++ ++ return 0; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ + static void + vc4_queue_hangcheck(struct drm_device *dev) + { + +From 3fc260b067c746366f51c43394ac398b3155b097 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 25 Jan 2016 13:03:33 -0800 +Subject: [PATCH 094/114] drm/vc4: Include vc4_drm.h in uapi in downstream + build. + +Signed-off-by: Eric Anholt +--- + include/uapi/drm/Kbuild | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild +index 9355dd8..68828bf 100644 +--- a/include/uapi/drm/Kbuild ++++ b/include/uapi/drm/Kbuild +@@ -15,6 +15,7 @@ header-y += radeon_drm.h + header-y += savage_drm.h + header-y += sis_drm.h + header-y += tegra_drm.h ++header-y += vc4_drm.h + header-y += via_drm.h + header-y += vmwgfx_drm.h + header-y += msm_drm.h + +From 05001f87c74655bc0b286e53494dfad5ac3bc5e7 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Wed, 9 Mar 2016 21:28:52 +0000 -Subject: [PATCH 169/251] BCM270X_DT: rpi-display overlay - add swapxy param +Date: Wed, 23 Mar 2016 17:22:10 +0000 +Subject: [PATCH 095/114] DT configfs: Fix build errors on other platforms Signed-off-by: Phil Elwell --- - arch/arm/boot/dts/overlays/README | 5 +---- - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 1 + - 2 files changed, 2 insertions(+), 4 deletions(-) + drivers/of/configfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 6a7aa31..6fa5b80 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -644,14 +644,11 @@ Name: rpi-display - Info: RPi-Display - 2.8" Touch Display by Watterott - Load: dtoverlay=rpi-display,= - Params: speed Display SPI bus speed -- - rotate Display rotation {0,90,180,270} -- - fps Delay between frame updates -- - debug Debug output level {0-7} -- - xohms Touchpanel sensitivity (X-plate resistance) -+ swapxy Swap x and y axis +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +index 7b66deb..168b9d3 100644 +--- a/drivers/of/configfs.c ++++ b/drivers/of/configfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include "of_private.h" - Name: rpi-ft5406 -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -index a8fa974..ccb296e 100644 ---- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -78,5 +78,6 @@ - fps = <&rpidisplay>,"fps:0"; - debug = <&rpidisplay>,"debug:0"; - xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ swapxy = <&rpidisplay_ts>,"ti,swap-xy?"; - }; - }; +@@ -153,7 +154,7 @@ ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, + { + struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); + +- pr_debug("%s: buf=%p max_count=%u\n", __func__, ++ pr_debug("%s: buf=%p max_count=%zu\n", __func__, + buf, max_count); + + if (overlay->dtbo == NULL) -From 0775a4eb95034a3460293cbd08bc7c6ebbe47a0f Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Fri, 11 Mar 2016 11:44:35 +0000 -Subject: [PATCH 170/251] Remove I2S config from bt_pins. - -Remove I2S config from bt_pins. Causes issues with clock alignment when I2S is -used by an external DAC via GPIO header. ---- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 +++--- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 5a0c45a..2cb7d43 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -45,9 +45,9 @@ - }; - - bt_pins: bt_pins { -- brcm,pins = <28 29 30 31 43>; -- brcm,function = <6 6 6 6 4>; /* alt2:PCM alt0:GPCLK2 */ -- brcm,pull = <0 0 0 0 0>; -+ brcm,pins = <43>; -+ brcm,function = <4>; /* alt0:GPCLK2 */ -+ brcm,pull = <0>; - }; - - uart0_pins: uart0_pins { -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index 0b8f0ca..f07afcb 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -29,7 +29,7 @@ - target = <&uart1>; - __overlay__ { - pinctrl-names = "default"; -- pinctrl-0 = <&uart1_pins>; -+ pinctrl-0 = <&uart1_pins &bt_pins>; - status = "okay"; - }; - }; - -From c80d4e337d289f911bc3d9c972cbcc85c0bf758c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 10 Aug 2015 09:44:59 +0100 -Subject: [PATCH 171/251] Revert "scripts/dtc: Add overlay support" - -This reverts commit fa6d1755c2fdd9451077d8248e3804f0619f19b9. ---- - scripts/dtc/checks.c | 119 +-- - scripts/dtc/dtc-lexer.l | 5 - - scripts/dtc/dtc-lexer.lex.c_shipped | 490 +++++---- - scripts/dtc/dtc-parser.tab.c_shipped | 1896 +++++++++++++++------------------- - scripts/dtc/dtc-parser.tab.h_shipped | 107 +- - scripts/dtc/dtc-parser.y | 23 +- - scripts/dtc/dtc.c | 9 +- - scripts/dtc/dtc.h | 38 - - scripts/dtc/flattree.c | 141 +-- - scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1145 insertions(+), 1685 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index efd1bc6..e81a8c7 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -458,91 +458,21 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -- struct fixup *f, **fp; -- struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; -- int has_phandle_refs; -- -- has_phandle_refs = 0; -- for_each_marker_of_type(m, REF_PHANDLE) { -- has_phandle_refs = 1; -- break; -- } -- -- if (!has_phandle_refs) -- return; - - for_each_marker_of_type(m, REF_PHANDLE) { - assert(m->offset + sizeof(cell_t) <= prop->val.len); - - refnode = get_node_by_ref(dt, m->ref); -- if (!refnode && !symbol_fixup_support) { -+ if (! refnode) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ m->ref); - continue; - } - -- if (!refnode) { -- /* allocate fixup entry */ -- fe = xmalloc(sizeof(*fe)); -- -- fe->node = node; -- fe->prop = prop; -- fe->offset = m->offset; -- fe->next = NULL; -- -- /* search for an already existing fixup */ -- for_each_fixup(dt, f) -- if (strcmp(f->ref, m->ref) == 0) -- break; -- -- /* no fixup found, add new */ -- if (f == NULL) { -- f = xmalloc(sizeof(*f)); -- f->ref = m->ref; -- f->entries = NULL; -- f->next = NULL; -- -- /* add it to the tree */ -- fp = &dt->fixups; -- while (*fp) -- fp = &(*fp)->next; -- *fp = f; -- } -- -- /* and now append fixup entry */ -- fep = &f->entries; -- while (*fep) -- fep = &(*fep)->next; -- *fep = fe; -- -- /* mark the entry as unresolved */ -- phandle = 0xdeadbeef; -- } else { -- phandle = get_node_phandle(dt, refnode); -- -- /* if it's a plugin, we need to record it */ -- if (symbol_fixup_support && dt->is_plugin) { -- -- /* allocate a new local fixup entry */ -- fe = xmalloc(sizeof(*fe)); -- -- fe->node = node; -- fe->prop = prop; -- fe->offset = m->offset; -- fe->next = NULL; -- -- /* append it to the local fixups */ -- fep = &dt->local_fixups; -- while (*fep) -- fep = &(*fep)->next; -- *fep = fe; -- } -- } -- -- *((cell_t *)(prop->val.val + m->offset)) = -- cpu_to_fdt32(phandle); -+ phandle = get_node_phandle(dt, refnode); -+ *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -@@ -722,45 +652,6 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - --static void check_auto_label_phandles(struct check *c, struct node *dt, -- struct node *node) --{ -- struct label *l; -- struct symbol *s, **sp; -- int has_label; -- -- if (!symbol_fixup_support) -- return; -- -- has_label = 0; -- for_each_label(node->labels, l) { -- has_label = 1; -- break; -- } -- -- if (!has_label) -- return; -- -- /* force allocation of a phandle for this node */ -- (void)get_node_phandle(dt, node); -- -- /* add the symbol */ -- for_each_label(node->labels, l) { -- -- s = xmalloc(sizeof(*s)); -- s->label = l; -- s->node = node; -- s->next = NULL; -- -- /* add it to the symbols list */ -- sp = &dt->symbols; -- while (*sp) -- sp = &((*sp)->next); -- *sp = s; -- } --} --NODE_WARNING(auto_label_phandles, NULL); -- - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -779,8 +670,6 @@ static struct check *check_table[] = { - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -- &auto_label_phandles, -- - &always_fail, - }; - -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index dd44ba2..0ee1caf 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -113,11 +113,6 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - --<*>"/plugin/" { -- DPRINT("Keyword: /plugin/\n"); -- return DT_PLUGIN; -- } -- - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 1518525..11cd78e 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -9,7 +9,7 @@ - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 - #define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 35 -+#define YY_FLEX_SUBMINOR_VERSION 39 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -162,7 +162,12 @@ typedef unsigned int flex_uint32_t; - typedef struct yy_buffer_state *YY_BUFFER_STATE; - #endif - --extern int yyleng; -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ -+extern yy_size_t yyleng; - - extern FILE *yyin, *yyout; - -@@ -171,6 +176,7 @@ extern FILE *yyin, *yyout; - #define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) -+ #define YY_LINENO_REWIND_TO(ptr) - - /* Return all but the first "n" matched characters back to the input stream. */ - #define yyless(n) \ -@@ -188,11 +194,6 @@ extern FILE *yyin, *yyout; - - #define unput(c) yyunput( c, (yytext_ptr) ) - --#ifndef YY_TYPEDEF_YY_SIZE_T --#define YY_TYPEDEF_YY_SIZE_T --typedef size_t yy_size_t; --#endif -- - #ifndef YY_STRUCT_YY_BUFFER_STATE - #define YY_STRUCT_YY_BUFFER_STATE - struct yy_buffer_state -@@ -210,7 +211,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- int yy_n_chars; -+ yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -280,8 +281,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static int yy_n_chars; /* number of characters read into yy_ch_buf */ --int yyleng; -+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -+yy_size_t yyleng; - - /* Points to current character in buffer. */ - static char *yy_c_buf_p = (char *) 0; -@@ -309,7 +310,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - - YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); - YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); - - void *yyalloc (yy_size_t ); - void *yyrealloc (void *,yy_size_t ); -@@ -341,7 +342,7 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap(n) 1 -+#define yywrap() 1 - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; -@@ -372,8 +373,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 31 --#define YY_END_OF_BUFFER 32 -+#define YY_NUM_RULES 30 -+#define YY_END_OF_BUFFER 31 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -381,26 +382,25 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[166] = -+static yyconst flex_int16_t yy_accept[159] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -- 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -- 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -- 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -- 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -- 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -- 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -- 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -- 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -- 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -- 0, 0, 0, 8, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -+ 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -+ 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -+ 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -+ 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -+ 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -+ 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -+ 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -+ 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -+ -+ 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -+ 5, 8, 0, 0, 0, 0, 7, 0 - } ; - - static yyconst flex_int32_t yy_ec[256] = -@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -- 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -- 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, -+ 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -+ 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -+ 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,165 +435,163 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[48] = -+static yyconst flex_int32_t yy_meta[47] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[180] = -+static yyconst flex_int16_t yy_base[173] = - { 0, -- 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -- 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -- 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -- 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -- 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -- 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -- 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -- 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -- 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -- 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -- -- 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -- 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -- 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -- 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -- 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -- 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -- 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -- 281, 288, 292, 300, 308, 312, 318, 326, 334 -+ 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -+ 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -+ 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -+ 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -+ 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -+ 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -+ 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -+ 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -+ 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -+ 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -+ -+ 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -+ 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -+ 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -+ 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -+ 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -+ 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -+ 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -+ 318, 326 - } ; - --static yyconst flex_int16_t yy_def[180] = -+static yyconst flex_int16_t yy_def[173] = - { 0, -- 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -- 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -- 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -- 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -- 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -- 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -- 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -- 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -- -- 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -- 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -- 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -- 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165 -+ 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -+ 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -+ 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -+ 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -+ 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -+ 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -+ 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ -+ 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -+ 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -+ 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158 - } ; - --static yyconst flex_int16_t yy_nxt[449] = -+static yyconst flex_int16_t yy_nxt[438] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -- 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -- 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -- 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -- 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -- 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -- 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -- 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -- 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -- 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -- 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -- 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -- 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -- 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -- 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -- -- 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -- 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -- 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -- 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -- 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -- 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -- 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -- 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -- 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -- 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -- -- 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -- 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -- 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -- 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -- 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -- 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -- 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -- 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -- 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -- 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -- -- 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165 -+ 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -+ 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -+ 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -+ 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -+ 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -+ 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -+ 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -+ 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -+ 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -+ 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -+ 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -+ 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -+ 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -+ 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -+ 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -+ -+ 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -+ 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -+ 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -+ 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -+ 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -+ 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -+ 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -+ 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -+ 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -+ 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -+ -+ 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -+ 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -+ 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -+ 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -+ 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -+ 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -+ 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -+ 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -+ 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -+ 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158 - } ; - --static yyconst flex_int16_t yy_chk[449] = -+static yyconst flex_int16_t yy_chk[438] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -- 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -- 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -+ 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -+ 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -- 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -- 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -- 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -- 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -- 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -- 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -- 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -- 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -- -- 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -- 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -- 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -- 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -- 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -- 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -- 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -- 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -- 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -- 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -- -- 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -- 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -- 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -- 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -- 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -- 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -- 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -- 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -- 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, -+ 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -+ 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -+ 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -+ 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -+ 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -+ 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -+ 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -+ 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -+ 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -+ -+ 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -+ 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -+ 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -+ 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -+ 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -+ 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -+ 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -+ 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -+ 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -+ 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -+ -+ 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -+ 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -+ 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -+ 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -+ 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -+ 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -+ 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -+ 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -- 165, 165, 165, 165, 165, 165, 165, 165 -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -+ 158, 158, 158, 158, 158, 158, 158 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -664,7 +662,7 @@ static int dts_version = 1; - static void push_input_file(const char *filename); - static bool pop_input_file(void); - static void lexical_error(const char *fmt, ...); --#line 668 "dtc-lexer.lex.c" -+#line 666 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -706,7 +704,7 @@ FILE *yyget_out (void ); - - void yyset_out (FILE * out_str ); - --int yyget_leng (void ); -+yy_size_t yyget_leng (void ); - - char *yyget_text (void ); - -@@ -855,10 +853,6 @@ YY_DECL - register char *yy_cp, *yy_bp; - register int yy_act; - --#line 68 "dtc-lexer.l" -- --#line 861 "dtc-lexer.lex.c" -- - if ( !(yy_init) ) - { - (yy_init) = 1; -@@ -885,6 +879,11 @@ YY_DECL - yy_load_buffer_state( ); - } - -+ { -+#line 68 "dtc-lexer.l" -+ -+#line 886 "dtc-lexer.lex.c" -+ - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); -@@ -902,7 +901,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; -+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -911,13 +910,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 165 ); -+ while ( yy_current_state != 158 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -1008,31 +1007,23 @@ case 5: - YY_RULE_SETUP - #line 116 "dtc-lexer.l" - { -- DPRINT("Keyword: /plugin/\n"); -- return DT_PLUGIN; -- } -- YY_BREAK --case 6: --YY_RULE_SETUP --#line 121 "dtc-lexer.l" --{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 7: -+case 6: - YY_RULE_SETUP --#line 127 "dtc-lexer.l" -+#line 122 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 8: -+case 7: - YY_RULE_SETUP --#line 133 "dtc-lexer.l" -+#line 128 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("\n"); -@@ -1040,9 +1031,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 9: -+case 8: - YY_RULE_SETUP --#line 140 "dtc-lexer.l" -+#line 135 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("\n"); -@@ -1050,9 +1041,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 10: -+case 9: - YY_RULE_SETUP --#line 147 "dtc-lexer.l" -+#line 142 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1060,9 +1051,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 11: -+case 10: - YY_RULE_SETUP --#line 154 "dtc-lexer.l" -+#line 149 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1082,10 +1073,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 12: --/* rule 12 can match eol */ -+case 11: -+/* rule 11 can match eol */ - YY_RULE_SETUP --#line 173 "dtc-lexer.l" -+#line 168 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1107,18 +1098,18 @@ YY_RULE_SETUP - return DT_CHAR_LITERAL; - } - YY_BREAK --case 13: -+case 12: - YY_RULE_SETUP --#line 194 "dtc-lexer.l" -+#line 189 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 14: -+case 13: - YY_RULE_SETUP --#line 200 "dtc-lexer.l" -+#line 195 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1126,27 +1117,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 15: -+case 14: - YY_RULE_SETUP --#line 207 "dtc-lexer.l" -+#line 202 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 16: -+case 15: - YY_RULE_SETUP --#line 213 "dtc-lexer.l" -+#line 208 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 17: -+case 16: - YY_RULE_SETUP --#line 219 "dtc-lexer.l" -+#line 214 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1155,75 +1146,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 18: -+case 17: - YY_RULE_SETUP --#line 227 "dtc-lexer.l" -+#line 222 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 19: --/* rule 19 can match eol */ -+case 18: -+/* rule 18 can match eol */ - YY_RULE_SETUP --#line 232 "dtc-lexer.l" -+#line 227 "dtc-lexer.l" - /* eat whitespace */ - YY_BREAK --case 20: --/* rule 20 can match eol */ -+case 19: -+/* rule 19 can match eol */ - YY_RULE_SETUP --#line 233 "dtc-lexer.l" -+#line 228 "dtc-lexer.l" - /* eat C-style comments */ - YY_BREAK --case 21: --/* rule 21 can match eol */ -+case 20: -+/* rule 20 can match eol */ - YY_RULE_SETUP --#line 234 "dtc-lexer.l" -+#line 229 "dtc-lexer.l" - /* eat C++-style comments */ - YY_BREAK --case 22: -+case 21: - YY_RULE_SETUP --#line 236 "dtc-lexer.l" -+#line 231 "dtc-lexer.l" - { return DT_LSHIFT; }; - YY_BREAK --case 23: -+case 22: - YY_RULE_SETUP --#line 237 "dtc-lexer.l" -+#line 232 "dtc-lexer.l" - { return DT_RSHIFT; }; - YY_BREAK --case 24: -+case 23: - YY_RULE_SETUP --#line 238 "dtc-lexer.l" -+#line 233 "dtc-lexer.l" - { return DT_LE; }; - YY_BREAK --case 25: -+case 24: - YY_RULE_SETUP --#line 239 "dtc-lexer.l" -+#line 234 "dtc-lexer.l" - { return DT_GE; }; - YY_BREAK --case 26: -+case 25: - YY_RULE_SETUP --#line 240 "dtc-lexer.l" -+#line 235 "dtc-lexer.l" - { return DT_EQ; }; - YY_BREAK --case 27: -+case 26: - YY_RULE_SETUP --#line 241 "dtc-lexer.l" -+#line 236 "dtc-lexer.l" - { return DT_NE; }; - YY_BREAK --case 28: -+case 27: - YY_RULE_SETUP --#line 242 "dtc-lexer.l" -+#line 237 "dtc-lexer.l" - { return DT_AND; }; - YY_BREAK --case 29: -+case 28: - YY_RULE_SETUP --#line 243 "dtc-lexer.l" -+#line 238 "dtc-lexer.l" - { return DT_OR; }; - YY_BREAK --case 30: -+case 29: - YY_RULE_SETUP --#line 245 "dtc-lexer.l" -+#line 240 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1239,12 +1230,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 31: -+case 30: - YY_RULE_SETUP --#line 260 "dtc-lexer.l" -+#line 255 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1248 "dtc-lexer.lex.c" -+#line 1239 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1374,6 +1365,7 @@ ECHO; - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -+ } /* end of user's declarations */ - } /* end of yylex */ - - /* yy_get_next_buffer - try to read in a new buffer -@@ -1429,21 +1421,21 @@ static int yy_get_next_buffer (void) - - else - { -- int num_to_read = -+ yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { -- int new_size = b->yy_buf_size * 2; -+ yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1474,7 +1466,7 @@ static int yy_get_next_buffer (void) - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -- (yy_n_chars), (size_t) num_to_read ); -+ (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } -@@ -1536,7 +1528,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1564,13 +1556,13 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 166 ) -+ if ( yy_current_state >= 159 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 165); -+ yy_is_jam = (yy_current_state == 158); - -- return yy_is_jam ? 0 : yy_current_state; -+ return yy_is_jam ? 0 : yy_current_state; - } - - #ifndef YY_NO_INPUT -@@ -1597,7 +1589,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- int offset = (yy_c_buf_p) - (yytext_ptr); -+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1871,7 +1863,7 @@ void yypop_buffer_state (void) - */ - static void yyensure_buffer_stack (void) - { -- int num_to_alloc; -+ yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - -@@ -1968,12 +1960,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- int i; -+ yy_size_t i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; -@@ -2055,7 +2047,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --int yyget_leng (void) -+yy_size_t yyget_leng (void) - { - return yyleng; - } -@@ -2203,7 +2195,7 @@ void yyfree (void * ptr ) - - #define YYTABLES_NAME "yytables" - --#line 260 "dtc-lexer.l" -+#line 254 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 2c1784e..116458c 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.5. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison implementation for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,7 +26,7 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "2.5" -+#define YYBISON_VERSION "3.0.2" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -58,18 +58,13 @@ - /* Pull parsers. */ - #define YYPULL 1 - --/* Using locations. */ --#define YYLSP_NEEDED 1 - - - - /* Copy the first part of user declarations. */ -- --/* Line 268 of yacc.c */ --#line 20 "dtc-parser.y" -+#line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include --#include - - #include "dtc.h" - #include "srcpos.h" -@@ -85,14 +80,15 @@ extern void yyerror(char const *s); - extern struct boot_info *the_boot_info; - extern bool treesource_error; - -+#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ - --/* Line 268 of yacc.c */ --#line 91 "dtc-parser.tab.c" -- --/* Enabling traces. */ --#ifndef YYDEBUG --# define YYDEBUG 0 --#endif -+# ifndef YY_NULLPTR -+# if defined __cplusplus && 201103L <= __cplusplus -+# define YY_NULLPTR nullptr -+# else -+# define YY_NULLPTR 0 -+# endif -+# endif - - /* Enabling verbose error messages. */ - #ifdef YYERROR_VERBOSE -@@ -102,51 +98,53 @@ extern bool treesource_error; - # define YYERROR_VERBOSE 0 - #endif - --/* Enabling the token table. */ --#ifndef YYTOKEN_TABLE --# define YYTOKEN_TABLE 0 -+/* In a future release of Bison, this section will be replaced -+ by #include "dtc-parser.tab.h". */ -+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -+/* Debug traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+#if YYDEBUG -+extern int yydebug; - #endif - -- --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_PLUGIN = 259, -- DT_MEMRESERVE = 260, -- DT_LSHIFT = 261, -- DT_RSHIFT = 262, -- DT_LE = 263, -- DT_GE = 264, -- DT_EQ = 265, -- DT_NE = 266, -- DT_AND = 267, -- DT_OR = 268, -- DT_BITS = 269, -- DT_DEL_PROP = 270, -- DT_DEL_NODE = 271, -- DT_PROPNODENAME = 272, -- DT_LITERAL = 273, -- DT_CHAR_LITERAL = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_LSHIFT = 260, -+ DT_RSHIFT = 261, -+ DT_LE = 262, -+ DT_GE = 263, -+ DT_EQ = 264, -+ DT_NE = 265, -+ DT_AND = 266, -+ DT_OR = 267, -+ DT_BITS = 268, -+ DT_DEL_PROP = 269, -+ DT_DEL_NODE = 270, -+ DT_PROPNODENAME = 271, -+ DT_LITERAL = 272, -+ DT_CHAR_LITERAL = 273, -+ DT_BYTE = 274, -+ DT_STRING = 275, -+ DT_LABEL = 276, -+ DT_REF = 277, -+ DT_INCBIN = 278 -+ }; - #endif - -- -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { -- --/* Line 293 of yacc.c */ --#line 39 "dtc-parser.y" -+#line 38 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; -@@ -164,37 +162,37 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; - -- -- --/* Line 293 of yacc.c */ --#line 173 "dtc-parser.tab.c" --} YYSTYPE; -+#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - -+/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --} YYLTYPE; --# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+}; - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - - --/* Copy the second part of user declarations. */ -+extern YYSTYPE yylval; -+extern YYLTYPE yylloc; -+int yyparse (void); - -+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ - --/* Line 343 of yacc.c */ --#line 198 "dtc-parser.tab.c" -+/* Copy the second part of user declarations. */ -+ -+#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -208,11 +206,8 @@ typedef unsigned char yytype_uint8; - - #ifdef YYTYPE_INT8 - typedef YYTYPE_INT8 yytype_int8; --#elif (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --typedef signed char yytype_int8; - #else --typedef short int yytype_int8; -+typedef signed char yytype_int8; - #endif - - #ifdef YYTYPE_UINT16 -@@ -232,8 +227,7 @@ typedef short int yytype_int16; - # define YYSIZE_T __SIZE_TYPE__ - # elif defined size_t - # define YYSIZE_T size_t --# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# elif ! defined YYSIZE_T - # include /* INFRINGES ON USER NAME SPACE */ - # define YYSIZE_T size_t - # else -@@ -247,38 +241,67 @@ typedef short int yytype_int16; - # if defined YYENABLE_NLS && YYENABLE_NLS - # if ENABLE_NLS - # include /* INFRINGES ON USER NAME SPACE */ --# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# define YY_(Msgid) dgettext ("bison-runtime", Msgid) - # endif - # endif - # ifndef YY_ --# define YY_(msgid) msgid -+# define YY_(Msgid) Msgid -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE -+# if (defined __GNUC__ \ -+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ -+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -+# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -+# else -+# define YY_ATTRIBUTE(Spec) /* empty */ -+# endif -+#endif -+ -+#ifndef YY_ATTRIBUTE_PURE -+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -+#endif -+ -+#ifndef YY_ATTRIBUTE_UNUSED -+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -+#endif -+ -+#if !defined _Noreturn \ -+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -+# if defined _MSC_VER && 1200 <= _MSC_VER -+# define _Noreturn __declspec (noreturn) -+# else -+# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) - # endif - #endif - - /* Suppress unused-variable warnings by "using" E. */ - #if ! defined lint || defined __GNUC__ --# define YYUSE(e) ((void) (e)) -+# define YYUSE(E) ((void) (E)) - #else --# define YYUSE(e) /* empty */ -+# define YYUSE(E) /* empty */ - #endif - --/* Identity function, used to suppress warnings about constant conditions. */ --#ifndef lint --# define YYID(n) (n) --#else --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static int --YYID (int yyi) -+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -+/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ -+ _Pragma ("GCC diagnostic push") \ -+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ -+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ -+ _Pragma ("GCC diagnostic pop") - #else --static int --YYID (yyi) -- int yyi; -+# define YY_INITIAL_VALUE(Value) Value - #endif --{ -- return yyi; --} -+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END - #endif -+#ifndef YY_INITIAL_VALUE -+# define YY_INITIAL_VALUE(Value) /* Nothing. */ -+#endif -+ - - #if ! defined yyoverflow || YYERROR_VERBOSE - -@@ -297,9 +320,9 @@ YYID (yyi) - # define alloca _alloca - # else - # define YYSTACK_ALLOC alloca --# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS - # include /* INFRINGES ON USER NAME SPACE */ -+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 - # endif -@@ -309,8 +332,8 @@ YYID (yyi) - # endif - - # ifdef YYSTACK_ALLOC -- /* Pacify GCC's `empty if-body' warning. */ --# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+ /* Pacify GCC's 'empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) - # ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely -@@ -326,7 +349,7 @@ YYID (yyi) - # endif - # if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ -- && (defined YYFREE || defined free))) -+ && (defined YYFREE || defined free))) - # include /* INFRINGES ON USER NAME SPACE */ - # ifndef EXIT_SUCCESS - # define EXIT_SUCCESS 0 -@@ -334,15 +357,13 @@ YYID (yyi) - # endif - # ifndef YYMALLOC - # define YYMALLOC malloc --# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined malloc && ! defined EXIT_SUCCESS - void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif - # ifndef YYFREE - # define YYFREE free --# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) -+# if ! defined free && ! defined EXIT_SUCCESS - void free (void *); /* INFRINGES ON USER NAME SPACE */ - # endif - # endif -@@ -352,8 +373,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ - - #if (! defined yyoverflow \ - && (! defined __cplusplus \ -- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - - /* A type that is properly aligned for any stack member. */ - union yyalloc -@@ -379,35 +400,35 @@ union yyalloc - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ --# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -- do \ -- { \ -- YYSIZE_T yynewbytes; \ -- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -- Stack = &yyptr->Stack_alloc; \ -- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -- yyptr += yynewbytes / sizeof (*yyptr); \ -- } \ -- while (YYID (0)) -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (0) - - #endif - - #if defined YYCOPY_NEEDED && YYCOPY_NEEDED --/* Copy COUNT objects from FROM to TO. The source and destination do -+/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ - # ifndef YYCOPY - # if defined __GNUC__ && 1 < __GNUC__ --# define YYCOPY(To, From, Count) \ -- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# define YYCOPY(Dst, Src, Count) \ -+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) - # else --# define YYCOPY(To, From, Count) \ -- do \ -- { \ -- YYSIZE_T yyi; \ -- for (yyi = 0; yyi < (Count); yyi++) \ -- (To)[yyi] = (From)[yyi]; \ -- } \ -- while (YYID (0)) -+# define YYCOPY(Dst, Src, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (Dst)[yyi] = (Src)[yyi]; \ -+ } \ -+ while (0) - # endif - # endif - #endif /* !YYCOPY_NEEDED */ -@@ -418,37 +439,39 @@ union yyalloc - #define YYLAST 136 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 48 -+#define YYNTOKENS 47 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 29 -+#define YYNNTS 28 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 82 --/* YYNRULES -- Number of states. */ --#define YYNSTATES 147 -+#define YYNRULES 80 -+/* YYNSTATES -- Number of states. */ -+#define YYNSTATES 144 - --/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned -+ by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 279 -+#define YYMAXUTOK 278 - --#define YYTRANSLATE(YYX) \ -+#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - --/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM -+ as returned by yylex, without out-of-bounds checking. */ - static const yytype_uint8 yytranslate[] = - { - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -- 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -- 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -+ 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -+ 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, -+ 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, -+ 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -463,335 +486,292 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23 - }; - - #if YYDEBUG --/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -- YYRHS. */ --static const yytype_uint16 yyprhs[] = --{ -- 0, 0, 3, 9, 10, 13, 14, 17, 22, 25, -- 28, 32, 37, 41, 46, 52, 53, 56, 61, 64, -- 68, 71, 74, 78, 83, 86, 96, 102, 105, 106, -- 109, 112, 116, 118, 121, 124, 127, 129, 131, 135, -- 137, 139, 145, 147, 151, 153, 157, 159, 163, 165, -- 169, 171, 175, 177, 181, 185, 187, 191, 195, 199, -- 203, 207, 211, 213, 217, 221, 223, 227, 231, 235, -- 237, 239, 242, 245, 248, 249, 252, 255, 256, 259, -- 262, 265, 269 --}; -- --/* YYRHS -- A `-1'-separated list of the rules' RHS. */ --static const yytype_int8 yyrhs[] = --{ -- 49, 0, -1, 3, 25, 50, 51, 53, -1, -1, -- 4, 25, -1, -1, 52, 51, -1, 5, 60, 60, -- 25, -1, 22, 52, -1, 26, 54, -1, 53, 26, -- 54, -1, 53, 22, 23, 54, -1, 53, 23, 54, -- -1, 53, 16, 23, 25, -1, 27, 55, 75, 28, -- 25, -1, -1, 55, 56, -1, 17, 29, 57, 25, -- -1, 17, 25, -1, 15, 17, 25, -1, 22, 56, -- -1, 58, 21, -1, 58, 59, 30, -1, 58, 31, -- 74, 32, -1, 58, 23, -1, 58, 24, 33, 21, -- 34, 60, 34, 60, 35, -1, 58, 24, 33, 21, -- 35, -1, 57, 22, -1, -1, 57, 34, -1, 58, -- 22, -1, 14, 18, 36, -1, 36, -1, 59, 60, -- -1, 59, 23, -1, 59, 22, -1, 18, -1, 19, -- -1, 33, 61, 35, -1, 62, -1, 63, -1, 63, -- 37, 61, 38, 62, -1, 64, -1, 63, 13, 64, -- -1, 65, -1, 64, 12, 65, -1, 66, -1, 65, -- 39, 66, -1, 67, -1, 66, 40, 67, -1, 68, -- -1, 67, 41, 68, -1, 69, -1, 68, 10, 69, -- -1, 68, 11, 69, -1, 70, -1, 69, 36, 70, -- -1, 69, 30, 70, -1, 69, 8, 70, -1, 69, -- 9, 70, -1, 70, 6, 71, -1, 70, 7, 71, -- -1, 71, -1, 71, 42, 72, -1, 71, 43, 72, -- -1, 72, -1, 72, 44, 73, -1, 72, 26, 73, -- -1, 72, 45, 73, -1, 73, -1, 60, -1, 43, -- 73, -1, 46, 73, -1, 47, 73, -1, -1, 74, -- 20, -1, 74, 22, -1, -1, 76, 75, -1, 76, -- 56, -1, 17, 54, -1, 16, 17, 25, -1, 22, -- 76, -1 --}; -- --/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 108, 108, 119, 122, 130, 133, 140, 144, 152, -- 156, 161, 172, 182, 197, 205, 208, 215, 219, 223, -- 227, 235, 239, 243, 247, 251, 267, 277, 285, 288, -- 292, 299, 315, 320, 339, 353, 360, 361, 362, 369, -- 373, 374, 378, 379, 383, 384, 388, 389, 393, 394, -- 398, 399, 403, 404, 405, 409, 410, 411, 412, 413, -- 417, 418, 419, 423, 424, 425, 429, 430, 431, 432, -- 436, 437, 438, 439, 444, 447, 451, 459, 462, 466, -- 474, 478, 482 -+ 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -+ 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -+ 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -+ 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -+ 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -+ 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -+ 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -+ 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -+ 465 - }; - #endif - --#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+#if YYDEBUG || YYERROR_VERBOSE || 0 - /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -- "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -- "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -- "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -- "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -- "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -- "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -- "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -- "integer_prim", "integer_expr", "integer_trinary", "integer_or", -- "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -- "integer_eq", "integer_rela", "integer_shift", "integer_add", -- "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", 0 -+ "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -+ "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -+ "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -+ "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -+ "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -+ "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -+ "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -+ "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -+ "integer_expr", "integer_trinary", "integer_or", "integer_and", -+ "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -+ "integer_rela", "integer_shift", "integer_add", "integer_mul", -+ "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR - }; - #endif - - # ifdef YYPRINT --/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -- token YYLEX-NUM. */ -+/* YYTOKNUM[NUM] -- (External) token number corresponding to the -+ (internal) symbol number NUM (which must be that of a token). */ - static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -- 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -- 94, 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -+ 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -+ 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ --static const yytype_uint8 yyr1[] = --{ -- 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -- 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, -- 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, -- 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, -- 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, -- 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, -- 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, -- 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, -- 76, 76, 76 --}; -+#define YYPACT_NINF -81 - --/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ --static const yytype_uint8 yyr2[] = -+#define yypact_value_is_default(Yystate) \ -+ (!!((Yystate) == (-81))) -+ -+#define YYTABLE_NINF -1 -+ -+#define yytable_value_is_error(Yytable_value) \ -+ 0 -+ -+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+static const yytype_int8 yypact[] = - { -- 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -- 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, -- 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, -- 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, -- 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, -- 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, -- 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, -- 2, 3, 2 -+ 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -+ -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -+ -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -+ 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -+ 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -+ -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -+ 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -+ 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -+ 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -+ 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -+ -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -+ -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -+ -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -+ 74, 25, 75, -81 - }; - --/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -- Performed when YYTABLE doesn't specify something else to do. Zero -- means the default is an error. */ -+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE does not specify something else to do. Zero -+ means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -- 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, -- 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, -- 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, -- 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, -+ 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -+ 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -+ 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -+ 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -+ 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, -- 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, -- 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, -- 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, -- 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, -- 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, -- 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, -- 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, -- 23, 0, 26, 0, 0, 0, 25 -+ 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -+ 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -+ 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -+ 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -+ 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -+ 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -+ 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -+ 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -+ 0, 0, 0, 23 - }; - --/* YYDEFGOTO[NTERM-NUM]. */ --static const yytype_int16 yydefgoto[] = -+ /* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = - { -- -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, -- 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, -- 31, 32, 33, 34, 35, 36, 131, 97, 98 -+ -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -+ -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -+ 37, 27, 34, 38, -14, -81, 22, 24 - }; - --/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -- STATE-NUM. */ --#define YYPACT_NINF -84 --static const yytype_int8 yypact[] = -+ /* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int16 yydefgoto[] = - { -- 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, -- 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, -- -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, -- 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, -- 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, -- -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -- -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, -- 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, -- 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, -- -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, -- -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, -- -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, -- -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, -- 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, -- -84, 24, -84, 77, 24, 80, -84 -+ -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -+ 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -+ 29, 30, 31, 32, 33, 128, 94, 95 - }; - --/* YYPGOTO[NTERM-NUM]. */ --static const yytype_int8 yypgoto[] = -+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule whose -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+static const yytype_uint8 yytable[] = - { -- -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, -- -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, -- 82, 29, 18, 25, 26, -17, -84, 20, 28 -+ 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -+ 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -+ 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -+ 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -+ 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -+ 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -+ 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -+ 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -+ 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -+ 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -+ 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -+ 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -+ 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -+ 0, 0, 75, 140, 0, 0, 142 - }; - --/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -- positive, shift that token. If negative, reduce the rule which -- number is the opposite. If YYTABLE_NINF, syntax error. */ --#define YYTABLE_NINF -1 --static const yytype_uint8 yytable[] = -+static const yytype_int16 yycheck[] = - { -- 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, -- 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, -- 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, -- 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, -- 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, -- 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, -- 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, -- 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, -- 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, -- 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, -- 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, -- 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, -- 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 143, 0, 78, 145 -+ 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -+ 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -+ 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -+ 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -+ 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -+ 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -+ 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -+ 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -+ 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -+ 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -+ 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -+ 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -+ 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -+ -1, -1, 50, 138, -1, -1, 141 - }; - --#define yypact_value_is_default(yystate) \ -- ((yystate) == (-84)) -- --#define yytable_value_is_error(yytable_value) \ -- YYID (0) -+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -+ 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -+ 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -+ 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -+ 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -+ 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -+ 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -+ 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -+ 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -+ 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -+ 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -+ 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -+ 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -+ 58, 33, 58, 34 -+}; - --static const yytype_int16 yycheck[] = -+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = - { -- 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, -- 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, -- 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, -- 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, -- 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, -- 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, -- 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, -- 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, -- 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, -- 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, -- 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, -- 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, -- 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, 141, -1, 53, 144 -+ 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -+ 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -+ 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -+ 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -+ 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -+ 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -+ 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -+ 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -+ 74 - }; - --/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -- symbol of state STATE-NUM. */ --static const yytype_uint8 yystos[] = -+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = - { -- 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -- 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -- 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -- 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -- 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, -- 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, -- 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, -- 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, -- 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, -- 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, -- 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, -- 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, -- 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, -- 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, -- 32, 34, 35, 60, 34, 60, 35 -+ 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -+ 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -+ 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -+ 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -+ 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -+ 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -+ 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -+ 2 - }; - --#define yyerrok (yyerrstatus = 0) --#define yyclearin (yychar = YYEMPTY) --#define YYEMPTY (-2) --#define YYEOF 0 -- --#define YYACCEPT goto yyacceptlab --#define YYABORT goto yyabortlab --#define YYERROR goto yyerrorlab -- -- --/* Like YYERROR except do call yyerror. This remains here temporarily -- to ease the transition to the new meaning of YYERROR, for GCC. -- Once GCC version 2 has supplanted version 1, this can go. However, -- YYFAIL appears to be in use. Nevertheless, it is formally deprecated -- in Bison 2.4.2's NEWS entry, where a plan to phase it out is -- discussed. */ -- --#define YYFAIL goto yyerrlab --#if defined YYFAIL -- /* This is here to suppress warnings from the GCC cpp's -- -Wunused-macros. Normally we don't worry about that warning, but -- some users do, and we want to make it easy for users to remove -- YYFAIL uses, which will produce warnings from Bison 2.5. */ --#endif -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ - - #define YYRECOVERING() (!!yyerrstatus) - --#define YYBACKUP(Token, Value) \ --do \ -- if (yychar == YYEMPTY && yylen == 1) \ -- { \ -- yychar = (Token); \ -- yylval = (Value); \ -- YYPOPSTACK (1); \ -- goto yybackup; \ -- } \ -- else \ -- { \ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ YYPOPSTACK (yylen); \ -+ yystate = *yyssp; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ - yyerror (YY_("syntax error: cannot back up")); \ -- YYERROR; \ -- } \ --while (YYID (0)) -- -+ YYERROR; \ -+ } \ -+while (0) - --#define YYTERROR 1 --#define YYERRCODE 256 -+/* Error token number */ -+#define YYTERROR 1 -+#define YYERRCODE 256 - - - /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - --#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - #ifndef YYLLOC_DEFAULT --# define YYLLOC_DEFAULT(Current, Rhs, N) \ -- do \ -- if (YYID (N)) \ -- { \ -- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -- } \ -- else \ -- { \ -- (Current).first_line = (Current).last_line = \ -- YYRHSLOC (Rhs, 0).last_line; \ -- (Current).first_column = (Current).last_column = \ -- YYRHSLOC (Rhs, 0).last_column; \ -- } \ -- while (YYID (0)) -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (N) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (0) - #endif - -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+ -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (0) -+ - - /* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know -@@ -799,82 +779,73 @@ while (YYID (0)) - - #ifndef YY_LOCATION_PRINT - # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL --# define YY_LOCATION_PRINT(File, Loc) \ -- fprintf (File, "%d.%d-%d.%d", \ -- (Loc).first_line, (Loc).first_column, \ -- (Loc).last_line, (Loc).last_column) --# else --# define YY_LOCATION_PRINT(File, Loc) ((void) 0) --# endif --#endif -- - --/* YYLEX -- calling `yylex' with the right arguments. */ -+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - --#ifdef YYLEX_PARAM --# define YYLEX yylex (YYLEX_PARAM) --#else --# define YYLEX yylex () --#endif -+YY_ATTRIBUTE_UNUSED -+static unsigned -+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -+{ -+ unsigned res = 0; -+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; -+ if (0 <= yylocp->first_line) -+ { -+ res += YYFPRINTF (yyo, "%d", yylocp->first_line); -+ if (0 <= yylocp->first_column) -+ res += YYFPRINTF (yyo, ".%d", yylocp->first_column); -+ } -+ if (0 <= yylocp->last_line) -+ { -+ if (yylocp->first_line < yylocp->last_line) -+ { -+ res += YYFPRINTF (yyo, "-%d", yylocp->last_line); -+ if (0 <= end_col) -+ res += YYFPRINTF (yyo, ".%d", end_col); -+ } -+ else if (0 <= end_col && yylocp->first_column < end_col) -+ res += YYFPRINTF (yyo, "-%d", end_col); -+ } -+ return res; -+ } - --/* Enable debugging if requested. */ --#if YYDEBUG -+# define YY_LOCATION_PRINT(File, Loc) \ -+ yy_location_print_ (File, &(Loc)) - --# ifndef YYFPRINTF --# include /* INFRINGES ON USER NAME SPACE */ --# define YYFPRINTF fprintf -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) - # endif -+#endif - --# define YYDPRINTF(Args) \ --do { \ -- if (yydebug) \ -- YYFPRINTF Args; \ --} while (YYID (0)) - --# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ --do { \ -- if (yydebug) \ -- { \ -- YYFPRINTF (stderr, "%s ", Title); \ -- yy_symbol_print (stderr, \ -- Type, Value, Location); \ -- YYFPRINTF (stderr, "\n"); \ -- } \ --} while (YYID (0)) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (0) - - --/*--------------------------------. --| Print this symbol on YYOUTPUT. | --`--------------------------------*/ -+/*----------------------------------------. -+| Print this symbol's value on YYOUTPUT. | -+`----------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) --#else --static void --yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -- YYLTYPE const * const yylocationp; --#endif - { -+ FILE *yyo = yyoutput; -+ YYUSE (yyo); -+ YYUSE (yylocationp); - if (!yyvaluep) - return; -- YYUSE (yylocationp); - # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); --# else -- YYUSE (yyoutput); - # endif -- switch (yytype) -- { -- default: -- break; -- } -+ YYUSE (yytype); - } - - -@@ -882,23 +853,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) - | Print this symbol on YYOUTPUT. | - `--------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) --#else --static void --yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) -- FILE *yyoutput; -- int yytype; -- YYSTYPE const * const yyvaluep; -- YYLTYPE const * const yylocationp; --#endif - { -- if (yytype < YYNTOKENS) -- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -- else -- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ YYFPRINTF (yyoutput, "%s %s (", -+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); -@@ -911,16 +870,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) - | TOP (included). | - `------------------------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) --#else --static void --yy_stack_print (yybottom, yytop) -- yytype_int16 *yybottom; -- yytype_int16 *yytop; --#endif - { - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) -@@ -931,50 +882,42 @@ yy_stack_print (yybottom, yytop) - YYFPRINTF (stderr, "\n"); - } - --# define YY_STACK_PRINT(Bottom, Top) \ --do { \ -- if (yydebug) \ -- yy_stack_print ((Bottom), (Top)); \ --} while (YYID (0)) -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (0) - - - /*------------------------------------------------. - | Report that the YYRULE is going to be reduced. | - `------------------------------------------------*/ - --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --static void --yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) --#else - static void --yy_reduce_print (yyvsp, yylsp, yyrule) -- YYSTYPE *yyvsp; -- YYLTYPE *yylsp; -- int yyrule; --#endif -+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) - { -+ unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; -- unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -- yyrule - 1, yylno); -+ yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); -- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -- &(yyvsp[(yyi + 1) - (yynrhs)]) -- , &(yylsp[(yyi + 1) - (yynrhs)]) ); -+ yy_symbol_print (stderr, -+ yystos[yyssp[yyi + 1 - yynrhs]], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } - } - --# define YY_REDUCE_PRINT(Rule) \ --do { \ -- if (yydebug) \ -- yy_reduce_print (yyvsp, yylsp, Rule); \ --} while (YYID (0)) -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ -+} while (0) - - /* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -@@ -988,7 +931,7 @@ int yydebug; - - - /* YYINITDEPTH -- initial size of the parser's stacks. */ --#ifndef YYINITDEPTH -+#ifndef YYINITDEPTH - # define YYINITDEPTH 200 - #endif - -@@ -1011,15 +954,8 @@ int yydebug; - # define yystrlen strlen - # else - /* Return the length of YYSTR. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static YYSIZE_T - yystrlen (const char *yystr) --#else --static YYSIZE_T --yystrlen (yystr) -- const char *yystr; --#endif - { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) -@@ -1035,16 +971,8 @@ yystrlen (yystr) - # else - /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static char * - yystpcpy (char *yydest, const char *yysrc) --#else --static char * --yystpcpy (yydest, yysrc) -- char *yydest; -- const char *yysrc; --#endif - { - char *yyd = yydest; - const char *yys = yysrc; -@@ -1074,27 +1002,27 @@ yytnamerr (char *yyres, const char *yystr) - char const *yyp = yystr; - - for (;;) -- switch (*++yyp) -- { -- case '\'': -- case ',': -- goto do_not_strip_quotes; -- -- case '\\': -- if (*++yyp != '\\') -- goto do_not_strip_quotes; -- /* Fall through. */ -- default: -- if (yyres) -- yyres[yyn] = *yyp; -- yyn++; -- break; -- -- case '"': -- if (yyres) -- yyres[yyn] = '\0'; -- return yyn; -- } -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } - do_not_strip_quotes: ; - } - -@@ -1117,12 +1045,11 @@ static int - yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) - { -- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); -+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; -- YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ -- const char *yyformat = 0; -+ const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per -@@ -1130,10 +1057,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - int yycount = 0; - - /* There are many possibilities here to consider: -- - Assume YYFAIL is not used. It's too flawed to consider. See -- -- for details. YYERROR is fine as it does not invoke this -- function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected -@@ -1182,11 +1105,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - break; - } - yyarg[yycount++] = yytname[yyx]; -- yysize1 = yysize + yytnamerr (0, yytname[yyx]); -- if (! (yysize <= yysize1 -- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -+ { -+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); -+ if (! (yysize <= yysize1 -+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } - } - } - } -@@ -1206,10 +1131,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - # undef YYCASE_ - } - -- yysize1 = yysize + yystrlen (yyformat); -- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -- return 2; -- yysize = yysize1; -+ { -+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat); -+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } - - if (*yymsg_alloc < yysize) - { -@@ -1246,50 +1173,21 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - | Release the memory associated to this symbol. | - `-----------------------------------------------*/ - --/*ARGSUSED*/ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - static void - yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) --#else --static void --yydestruct (yymsg, yytype, yyvaluep, yylocationp) -- const char *yymsg; -- int yytype; -- YYSTYPE *yyvaluep; -- YYLTYPE *yylocationp; --#endif - { - YYUSE (yyvaluep); - YYUSE (yylocationp); -- - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - -- switch (yytype) -- { -- -- default: -- break; -- } -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+ YYUSE (yytype); -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - } - - --/* Prevent warnings from -Wmissing-prototypes. */ --#ifdef YYPARSE_PARAM --#if defined __STDC__ || defined __cplusplus --int yyparse (void *YYPARSE_PARAM); --#else --int yyparse (); --#endif --#else /* ! YYPARSE_PARAM */ --#if defined __STDC__ || defined __cplusplus --int yyparse (void); --#else --int yyparse (); --#endif --#endif /* ! YYPARSE_PARAM */ - - - /* The lookahead symbol. */ -@@ -1297,10 +1195,12 @@ int yychar; - - /* The semantic value of the lookahead symbol. */ - YYSTYPE yylval; -- - /* Location data for the lookahead symbol. */ --YYLTYPE yylloc; -- -+YYLTYPE yylloc -+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -+ = { 1, 1, 1, 1 } -+# endif -+; - /* Number of syntax errors so far. */ - int yynerrs; - -@@ -1309,38 +1209,19 @@ int yynerrs; - | yyparse. | - `----------*/ - --#ifdef YYPARSE_PARAM --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) --int --yyparse (void *YYPARSE_PARAM) --#else --int --yyparse (YYPARSE_PARAM) -- void *YYPARSE_PARAM; --#endif --#else /* ! YYPARSE_PARAM */ --#if (defined __STDC__ || defined __C99__FUNC__ \ -- || defined __cplusplus || defined _MSC_VER) - int - yyparse (void) --#else --int --yyparse () -- --#endif --#endif - { - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: -- `yyss': related to states. -- `yyvs': related to semantic values. -- `yyls': related to locations. -+ 'yyss': related to states. -+ 'yyvs': related to semantic values. -+ 'yyls': related to locations. - -- Refer to the stacks thru separate pointers, to allow yyoverflow -+ Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ -@@ -1366,7 +1247,7 @@ yyparse () - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ -- int yytoken; -+ int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -@@ -1385,10 +1266,9 @@ yyparse () - Keep to zero when no symbol should be popped. */ - int yylen = 0; - -- yytoken = 0; -- yyss = yyssa; -- yyvs = yyvsa; -- yyls = yylsa; -+ yyssp = yyss = yyssa; -+ yyvsp = yyvs = yyvsa; -+ yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); -@@ -1397,21 +1277,7 @@ yyparse () - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ -- -- /* Initialize stack pointers. -- Waste one element of value and location stack -- so that they stay on the same level as the state stack. -- The wasted elements are never initialized. */ -- yyssp = yyss; -- yyvsp = yyvs; -- yylsp = yyls; -- --#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -- /* Initialize the default location before parsing starts. */ -- yylloc.first_line = yylloc.last_line = 1; -- yylloc.first_column = yylloc.last_column = 1; --#endif -- -+ yylsp[0] = yylloc; - goto yysetstate; - - /*------------------------------------------------------------. -@@ -1432,26 +1298,26 @@ yyparse () - - #ifdef yyoverflow - { -- /* Give user a chance to reallocate the stack. Use copies of -- these so that the &'s don't force the real ones into -- memory. */ -- YYSTYPE *yyvs1 = yyvs; -- yytype_int16 *yyss1 = yyss; -- YYLTYPE *yyls1 = yyls; -- -- /* Each stack pointer address is followed by the size of the -- data in use in that stack, in bytes. This used to be a -- conditional around just the two extra args, but that might -- be undefined if yyoverflow is a macro. */ -- yyoverflow (YY_("memory exhausted"), -- &yyss1, yysize * sizeof (*yyssp), -- &yyvs1, yysize * sizeof (*yyvsp), -- &yyls1, yysize * sizeof (*yylsp), -- &yystacksize); -- -- yyls = yyls1; -- yyss = yyss1; -- yyvs = yyvs1; -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; - } - #else /* no yyoverflow */ - # ifndef YYSTACK_RELOCATE -@@ -1459,23 +1325,23 @@ yyparse () - # else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) -- goto yyexhaustedlab; -+ goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) -- yystacksize = YYMAXDEPTH; -+ yystacksize = YYMAXDEPTH; - - { -- yytype_int16 *yyss1 = yyss; -- union yyalloc *yyptr = -- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -- if (! yyptr) -- goto yyexhaustedlab; -- YYSTACK_RELOCATE (yyss_alloc, yyss); -- YYSTACK_RELOCATE (yyvs_alloc, yyvs); -- YYSTACK_RELOCATE (yyls_alloc, yyls); -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+ YYSTACK_RELOCATE (yyls_alloc, yyls); - # undef YYSTACK_RELOCATE -- if (yyss1 != yyssa) -- YYSTACK_FREE (yyss1); -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); - } - # endif - #endif /* no yyoverflow */ -@@ -1485,10 +1351,10 @@ yyparse () - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", -- (unsigned long int) yystacksize)); -+ (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) -- YYABORT; -+ YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -@@ -1517,7 +1383,7 @@ yybackup: - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); -- yychar = YYLEX; -+ yychar = yylex (); - } - - if (yychar <= YYEOF) -@@ -1557,7 +1423,9 @@ yybackup: - yychar = YYEMPTY; - - yystate = yyn; -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - -@@ -1580,7 +1448,7 @@ yyreduce: - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: -- `$$ = $1'. -+ '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison -@@ -1595,322 +1463,273 @@ yyreduce: - switch (yyn) - { - case 2: -- --/* Line 1806 of yacc.c */ --#line 109 "dtc-parser.y" -+#line 105 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyvsp[(5) - (5)].node)->is_plugin = (yyvsp[(3) - (5)].is_plugin); -- (yyvsp[(5) - (5)].node)->is_root = 1; -- the_boot_info = build_boot_info((yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), -- guess_boot_cpuid((yyvsp[(5) - (5)].node))); -+ the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } -+#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: -- --/* Line 1806 of yacc.c */ --#line 119 "dtc-parser.y" -+#line 113 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.is_plugin) = 0; -+ (yyval.re) = NULL; - } -+#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: -- --/* Line 1806 of yacc.c */ --#line 123 "dtc-parser.y" -+#line 117 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.is_plugin) = 1; -+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } -+#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: -- --/* Line 1806 of yacc.c */ --#line 130 "dtc-parser.y" -+#line 124 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } -+#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: -- --/* Line 1806 of yacc.c */ --#line 134 "dtc-parser.y" -+#line 128 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); -+ (yyval.re) = (yyvsp[0].re); - } -+#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: -- --/* Line 1806 of yacc.c */ --#line 141 "dtc-parser.y" -+#line 136 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); -+ (yyval.node) = name_node((yyvsp[0].node), ""); - } -+#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: -- --/* Line 1806 of yacc.c */ --#line 145 "dtc-parser.y" -+#line 140 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.re) = (yyvsp[(2) - (2)].re); -+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } -+#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: -- --/* Line 1806 of yacc.c */ --#line 153 "dtc-parser.y" -+#line 145 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); -+ -+ add_label(&target->labels, (yyvsp[-2].labelref)); -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: -- --/* Line 1806 of yacc.c */ --#line 157 "dtc-parser.y" -+#line 156 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); -+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); -+ -+ if (target) -+ merge_nodes(target, (yyvsp[0].node)); -+ else -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[-2].node); - } -+#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: -- --/* Line 1806 of yacc.c */ --#line 162 "dtc-parser.y" -+#line 166 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -- add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); - if (target) -- merge_nodes(target, (yyvsp[(4) - (4)].node)); -+ delete_node(target); - else -- ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); -+ -+ -+ (yyval.node) = (yyvsp[-3].node); - } -+#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: -- --/* Line 1806 of yacc.c */ --#line 173 "dtc-parser.y" -+#line 181 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); -- -- if (target) -- merge_nodes(target, (yyvsp[(3) - (3)].node)); -- else -- ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); -- (yyval.node) = (yyvsp[(1) - (3)].node); -+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } -+#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: -- --/* Line 1806 of yacc.c */ --#line 183 "dtc-parser.y" -+#line 188 "dtc-parser.y" /* yacc.c:1646 */ - { -- struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); -- -- if (target) -- delete_node(target); -- else -- ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); -- -- -- (yyval.node) = (yyvsp[(1) - (4)].node); -+ (yyval.proplist) = NULL; - } -+#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: -- --/* Line 1806 of yacc.c */ --#line 198 "dtc-parser.y" -+#line 192 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); -+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } -+#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: -- --/* Line 1806 of yacc.c */ --#line 205 "dtc-parser.y" -+#line 199 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = NULL; -+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } -+#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: -- --/* Line 1806 of yacc.c */ --#line 209 "dtc-parser.y" -+#line 203 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); -+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } -+#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: -- --/* Line 1806 of yacc.c */ --#line 216 "dtc-parser.y" -+#line 207 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); -+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } -+#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: -- --/* Line 1806 of yacc.c */ --#line 220 "dtc-parser.y" -+#line 211 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); -+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); -+ (yyval.prop) = (yyvsp[0].prop); - } -+#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: -- --/* Line 1806 of yacc.c */ --#line 224 "dtc-parser.y" -+#line 219 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); -+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } -+#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: -- --/* Line 1806 of yacc.c */ --#line 228 "dtc-parser.y" -+#line 223 "dtc-parser.y" /* yacc.c:1646 */ - { -- add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.prop) = (yyvsp[(2) - (2)].prop); -+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } -+#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: -- --/* Line 1806 of yacc.c */ --#line 236 "dtc-parser.y" -+#line 227 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); -+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } -+#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: -- --/* Line 1806 of yacc.c */ --#line 240 "dtc-parser.y" -+#line 231 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } -+#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 23: -- --/* Line 1806 of yacc.c */ --#line 244 "dtc-parser.y" -+#line 235 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -- } -- break; -- -- case 24: -- --/* Line 1806 of yacc.c */ --#line 248 "dtc-parser.y" -- { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -- } -- break; -- -- case 25: -- --/* Line 1806 of yacc.c */ --#line 252 "dtc-parser.y" -- { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; - -- if ((yyvsp[(6) - (9)].integer) != 0) -- if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) -+ if ((yyvsp[-3].integer) != 0) -+ if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", -- (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, -+ (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, - strerror(errno)); - -- d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); -+ d = data_copy_file(f, (yyvsp[-1].integer)); - -- (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); -+ (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } -+#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: -- --/* Line 1806 of yacc.c */ --#line 268 "dtc-parser.y" -+ case 24: -+#line 251 "dtc-parser.y" /* yacc.c:1646 */ - { -- FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); -+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - -- (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); -+ (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } -+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: -- --/* Line 1806 of yacc.c */ --#line 278 "dtc-parser.y" -+ case 25: -+#line 261 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: -- --/* Line 1806 of yacc.c */ --#line 285 "dtc-parser.y" -+ case 26: -+#line 268 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: -- --/* Line 1806 of yacc.c */ --#line 289 "dtc-parser.y" -+ case 27: -+#line 272 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = (yyvsp[(1) - (2)].data); -+ (yyval.data) = (yyvsp[-1].data); - } -+#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: -- --/* Line 1806 of yacc.c */ --#line 293 "dtc-parser.y" -+ case 28: -+#line 276 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: -- --/* Line 1806 of yacc.c */ --#line 300 "dtc-parser.y" -+ case 29: -+#line 283 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - -- bits = (yyvsp[(2) - (3)].integer); -+ bits = (yyvsp[-1].integer); - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { -- ERROR(&(yylsp[(2) - (3)]), "Array elements must be" -+ ERROR(&(yylsp[-1]), "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } -@@ -1918,25 +1737,23 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } -+#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: -- --/* Line 1806 of yacc.c */ --#line 316 "dtc-parser.y" -+ case 30: -+#line 299 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } -+#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: -- --/* Line 1806 of yacc.c */ --#line 321 "dtc-parser.y" -+ case 31: -+#line 304 "dtc-parser.y" /* yacc.c:1646 */ - { -- if ((yyvsp[(1) - (2)].array).bits < 64) { -- uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; -+ if ((yyvsp[-1].array).bits < 64) { -+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one -@@ -1945,293 +1762,258 @@ yyreduce: - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ -- if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) -- ERROR(&(yylsp[(2) - (2)]), "Value out of range for" -- " %d-bit array element", (yyvsp[(1) - (2)].array).bits); -+ if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) -+ ERROR(&(yylsp[0]), "Value out of range for" -+ " %d-bit array element", (yyvsp[-1].array).bits); - } - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } -+#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 34: -- --/* Line 1806 of yacc.c */ --#line 340 "dtc-parser.y" -+ case 32: -+#line 323 "dtc-parser.y" /* yacc.c:1646 */ - { -- uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); -+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -- if ((yyvsp[(1) - (2)].array).bits == 32) -- (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, -+ if ((yyvsp[-1].array).bits == 32) -+ (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, - REF_PHANDLE, -- (yyvsp[(2) - (2)].labelref)); -+ (yyvsp[0].labelref)); - else -- ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " -+ ERROR(&(yylsp[0]), "References are only allowed in " - "arrays with 32-bit elements."); - -- (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); -+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } -+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 35: -- --/* Line 1806 of yacc.c */ --#line 354 "dtc-parser.y" -+ case 33: -+#line 337 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } -+#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 38: -- --/* Line 1806 of yacc.c */ --#line 363 "dtc-parser.y" -+ case 36: -+#line 346 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.integer) = (yyvsp[(2) - (3)].integer); -+ (yyval.integer) = (yyvsp[-1].integer); - } -+#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 41: -+ case 39: -+#line 357 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } -+#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 374 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); } -+ case 41: -+#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } -+#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 43: -- --/* Line 1806 of yacc.c */ --#line 379 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); } -+#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } -+#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 45: -- --/* Line 1806 of yacc.c */ --#line 384 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); } -+#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } -+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 47: -- --/* Line 1806 of yacc.c */ --#line 389 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); } -+#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } -+#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 49: -- --/* Line 1806 of yacc.c */ --#line 394 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); } -+#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } -+#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 51: -- --/* Line 1806 of yacc.c */ --#line 399 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); } -+#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } -+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 53: -- --/* Line 1806 of yacc.c */ --#line 404 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); } -+ case 52: -+#line 388 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } -+#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 54: -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } -+#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 405 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); } -+ case 55: -+#line 394 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } -+#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 56: -- --/* Line 1806 of yacc.c */ --#line 410 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); } -+#line 395 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } -+#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 57: -- --/* Line 1806 of yacc.c */ --#line 411 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); } -+#line 396 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } -+#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 58: -- --/* Line 1806 of yacc.c */ --#line 412 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); } -+#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } -+#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 59: -- --/* Line 1806 of yacc.c */ --#line 413 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); } -- break; -- -- case 60: -- --/* Line 1806 of yacc.c */ --#line 417 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); } -+#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } -+#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 61: -- --/* Line 1806 of yacc.c */ --#line 418 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); } -+#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -+#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 63: -- --/* Line 1806 of yacc.c */ --#line 423 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); } -+ case 62: -+#line 407 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } -+#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 64: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } -+#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; - --/* Line 1806 of yacc.c */ --#line 424 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); } -+ case 65: -+#line 413 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } -+#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 66: -- --/* Line 1806 of yacc.c */ --#line 429 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); } -+#line 414 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } -+#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 67: -- --/* Line 1806 of yacc.c */ --#line 430 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); } -+ case 69: -+#line 420 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = -(yyvsp[0].integer); } -+#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 68: -- --/* Line 1806 of yacc.c */ --#line 431 "dtc-parser.y" -- { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); } -+ case 70: -+#line 421 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = ~(yyvsp[0].integer); } -+#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 71: -- --/* Line 1806 of yacc.c */ --#line 437 "dtc-parser.y" -- { (yyval.integer) = -(yyvsp[(2) - (2)].integer); } -+#line 422 "dtc-parser.y" /* yacc.c:1646 */ -+ { (yyval.integer) = !(yyvsp[0].integer); } -+#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 72: -- --/* Line 1806 of yacc.c */ --#line 438 "dtc-parser.y" -- { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); } -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = empty_data; -+ } -+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 73: -- --/* Line 1806 of yacc.c */ --#line 439 "dtc-parser.y" -- { (yyval.integer) = !(yyvsp[(2) - (2)].integer); } -+#line 431 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); -+ } -+#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 74: -- --/* Line 1806 of yacc.c */ --#line 444 "dtc-parser.y" -+#line 435 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = empty_data; -+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -+#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: -- --/* Line 1806 of yacc.c */ --#line 448 "dtc-parser.y" -+#line 442 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); -+ (yyval.nodelist) = NULL; - } -+#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: -- --/* Line 1806 of yacc.c */ --#line 452 "dtc-parser.y" -+#line 446 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } -+#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: -- --/* Line 1806 of yacc.c */ --#line 459 "dtc-parser.y" -+#line 450 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = NULL; -+ ERROR(&(yylsp[0]), "Properties must precede subnodes"); -+ YYERROR; - } -+#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: -- --/* Line 1806 of yacc.c */ --#line 463 "dtc-parser.y" -+#line 458 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); -+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } -+#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: -- --/* Line 1806 of yacc.c */ --#line 467 "dtc-parser.y" -+#line 462 "dtc-parser.y" /* yacc.c:1646 */ - { -- ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); -- YYERROR; -+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } -+#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 80: -- --/* Line 1806 of yacc.c */ --#line 475 "dtc-parser.y" -+#line 466 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); -+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); -+ (yyval.node) = (yyvsp[0].node); - } -+#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 81: - --/* Line 1806 of yacc.c */ --#line 479 "dtc-parser.y" -- { -- (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); -- } -- break; -- -- case 82: -- --/* Line 1806 of yacc.c */ --#line 483 "dtc-parser.y" -- { -- add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); -- (yyval.node) = (yyvsp[(2) - (2)].node); -- } -- break; -- -- -- --/* Line 1806 of yacc.c */ --#line 2235 "dtc-parser.tab.c" -+#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2254,7 +2036,7 @@ yyreduce: - *++yyvsp = yyval; - *++yylsp = yyloc; - -- /* Now `shift' the result of the reduction. Determine what state -+ /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - -@@ -2269,9 +2051,9 @@ yyreduce: - goto yynewstate; - - --/*------------------------------------. --| yyerrlab -- here on detecting error | --`------------------------------------*/ -+/*--------------------------------------. -+| yyerrlab -- here on detecting error. | -+`--------------------------------------*/ - yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ -@@ -2322,20 +2104,20 @@ yyerrlab: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an -- error, discard it. */ -+ error, discard it. */ - - if (yychar <= YYEOF) -- { -- /* Return failure if at end of input. */ -- if (yychar == YYEOF) -- YYABORT; -- } -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } - else -- { -- yydestruct ("Error: discarding", -- yytoken, &yylval, &yylloc); -- yychar = YYEMPTY; -- } -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } - } - - /* Else will try to reuse lookahead token after shifting the error -@@ -2355,7 +2137,7 @@ yyerrorlab: - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; -@@ -2368,35 +2150,37 @@ yyerrorlab: - | yyerrlab1 -- common code for both syntax error and YYERROR. | - `-------------------------------------------------------------*/ - yyerrlab1: -- yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) -- { -- yyn += YYTERROR; -- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -- { -- yyn = yytable[yyn]; -- if (0 < yyn) -- break; -- } -- } -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) -- YYABORT; -+ YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", -- yystos[yystate], yyvsp, yylsp); -+ yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of -@@ -2425,7 +2209,7 @@ yyabortlab: - yyresult = 1; - goto yyreturn; - --#if !defined(yyoverflow) || YYERROR_VERBOSE -+#if !defined yyoverflow || YYERROR_VERBOSE - /*-------------------------------------------------. - | yyexhaustedlab -- memory exhaustion comes here. | - `-------------------------------------------------*/ -@@ -2444,14 +2228,14 @@ yyreturn: - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } -- /* Do not reclaim the symbols of the rule which action triggered -+ /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", -- yystos[*yyssp], yyvsp, yylsp); -+ yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } - #ifndef yyoverflow -@@ -2462,18 +2246,12 @@ yyreturn: - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - #endif -- /* Make sure YYID is used. */ -- return YYID (yyresult); -+ return yyresult; - } -- -- -- --/* Line 2067 of yacc.c */ --#line 489 "dtc-parser.y" -+#line 472 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) - { - ERROR(&yylloc, "%s", s); - } -- -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 0b22bbb..30867c6 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,19 +1,19 @@ --/* A Bison parser, made by GNU Bison 2.5. */ -+/* A Bison parser, made by GNU Bison 3.0.2. */ - - /* Bison interface for Yacc-like parsers in C -- -- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. -- -+ -+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. -- -+ - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -- -+ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -@@ -26,50 +26,55 @@ - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. -- -+ - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -+#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -+# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -+/* Debug traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+#if YYDEBUG -+extern int yydebug; -+#endif - --/* Tokens. */ -+/* Token type. */ - #ifndef YYTOKENTYPE - # define YYTOKENTYPE -- /* Put the tokens into the symbol table, so that GDB and other debuggers -- know about them. */ -- enum yytokentype { -- DT_V1 = 258, -- DT_PLUGIN = 259, -- DT_MEMRESERVE = 260, -- DT_LSHIFT = 261, -- DT_RSHIFT = 262, -- DT_LE = 263, -- DT_GE = 264, -- DT_EQ = 265, -- DT_NE = 266, -- DT_AND = 267, -- DT_OR = 268, -- DT_BITS = 269, -- DT_DEL_PROP = 270, -- DT_DEL_NODE = 271, -- DT_PROPNODENAME = 272, -- DT_LITERAL = 273, -- DT_CHAR_LITERAL = 274, -- DT_BYTE = 275, -- DT_STRING = 276, -- DT_LABEL = 277, -- DT_REF = 278, -- DT_INCBIN = 279 -- }; -+ enum yytokentype -+ { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_LSHIFT = 260, -+ DT_RSHIFT = 261, -+ DT_LE = 262, -+ DT_GE = 263, -+ DT_EQ = 264, -+ DT_NE = 265, -+ DT_AND = 266, -+ DT_OR = 267, -+ DT_BITS = 268, -+ DT_DEL_PROP = 269, -+ DT_DEL_NODE = 270, -+ DT_PROPNODENAME = 271, -+ DT_LITERAL = 272, -+ DT_CHAR_LITERAL = 273, -+ DT_BYTE = 274, -+ DT_STRING = 275, -+ DT_LABEL = 276, -+ DT_REF = 277, -+ DT_INCBIN = 278 -+ }; - #endif - -- -- -+/* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE -+typedef union YYSTYPE YYSTYPE; -+union YYSTYPE - { -- --/* Line 2068 of yacc.c */ --#line 39 "dtc-parser.y" -+#line 38 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; -@@ -87,32 +92,30 @@ typedef union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; -- -- - --/* Line 2068 of yacc.c */ --#line 96 "dtc-parser.tab.h" --} YYSTYPE; -+#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ -+}; - # define YYSTYPE_IS_TRIVIAL 1 --# define yystype YYSTYPE /* obsolescent; will be withdrawn */ - # define YYSTYPE_IS_DECLARED 1 - #endif - --extern YYSTYPE yylval; -- -+/* Location type. */ - #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED --typedef struct YYLTYPE -+typedef struct YYLTYPE YYLTYPE; -+struct YYLTYPE - { - int first_line; - int first_column; - int last_line; - int last_column; --} YYLTYPE; --# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+}; - # define YYLTYPE_IS_DECLARED 1 - # define YYLTYPE_IS_TRIVIAL 1 - #endif - -+ -+extern YYSTYPE yylval; - extern YYLTYPE yylloc; -+int yyparse (void); - -+#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 56b9c15..5a897e3 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,7 +19,6 @@ - */ - %{ - #include --#include - - #include "dtc.h" - #include "srcpos.h" -@@ -53,11 +52,9 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -- int is_plugin; - } - - %token DT_V1 --%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -74,7 +71,6 @@ extern bool treesource_error; - - %type propdata - %type propdataprefix --%type plugindecl - %type memreserve - %type memreserves - %type arrayprefix -@@ -105,23 +101,10 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' plugindecl memreserves devicetree -+ DT_V1 ';' memreserves devicetree - { -- $5->is_plugin = $3; -- $5->is_root = 1; -- the_boot_info = build_boot_info($4, $5, -- guess_boot_cpuid($5)); -- } -- ; -- --plugindecl: -- /* empty */ -- { -- $$ = 0; -- } -- | DT_PLUGIN ';' -- { -- $$ = 1; -+ the_boot_info = build_boot_info($3, $4, -+ guess_boot_cpuid($4)); - } - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 0cbb14c..8c4add6 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -29,7 +29,6 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ --int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -52,7 +51,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] "; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv@"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -70,7 +69,6 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -- {"symbols", a_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -101,7 +99,6 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -- "\n\tSymbols and Fixups support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -189,9 +186,7 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- case '@': -- symbol_fixup_support = 1; -- break; -+ - case 'h': - usage(NULL); - default: -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index fe45748..56212c8 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -54,7 +54,6 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ --extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -133,25 +132,6 @@ struct label { - struct label *next; - }; - --struct fixup_entry { -- int offset; -- struct node *node; -- struct property *prop; -- struct fixup_entry *next; --}; -- --struct fixup { -- char *ref; -- struct fixup_entry *entries; -- struct fixup *next; --}; -- --struct symbol { -- struct label *label; -- struct node *node; -- struct symbol *next; --}; -- - struct property { - bool deleted; - char *name; -@@ -178,12 +158,6 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -- -- int is_root; -- int is_plugin; -- struct fixup *fixups; -- struct symbol *symbols; -- struct fixup_entry *local_fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -207,18 +181,6 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - --#define for_each_fixup(n, f) \ -- for ((f) = (n)->fixups; (f); (f) = (f)->next) -- --#define for_each_fixup_entry(f, fe) \ -- for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -- --#define for_each_symbol(n, s) \ -- for ((s) = (n)->symbols; (s); (s) = (s)->next) -- --#define for_each_local_fixup_entry(n, fe) \ -- for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -- - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index f439b40..bd99fa2 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -262,12 +262,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - struct property *prop; - struct node *child; - bool seen_name_prop = false; -- struct symbol *sym; -- struct fixup *f; -- struct fixup_entry *fe; -- char *name, *s; -- const char *fullpath; -- int namesz, nameoff, vallen; - - if (tree->deleted) - return; -@@ -282,6 +276,8 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - emit->align(etarget, sizeof(cell_t)); - - for_each_property(tree, prop) { -+ int nameoff; -+ - if (streq(prop->name, "name")) - seen_name_prop = true; - -@@ -314,139 +310,6 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -- if (!symbol_fixup_support) -- goto no_symbols; -- -- /* add the symbol nodes (if any) */ -- if (tree->symbols) { -- -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__symbols__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- for_each_symbol(tree, sym) { -- -- vallen = strlen(sym->node->fullpath); -- -- nameoff = stringtable_insert(strbuf, sym->label->label); -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, sym->node->fullpath, -- strlen(sym->node->fullpath)); -- emit->align(etarget, sizeof(cell_t)); -- } -- -- emit->endnode(etarget, NULL); -- } -- -- /* add the fixup nodes */ -- if (tree->fixups) { -- -- /* emit the external fixups */ -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__fixups__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- for_each_fixup(tree, f) { -- -- namesz = 0; -- for_each_fixup_entry(f, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- namesz += strlen(fullpath) + 1; -- namesz += strlen(fe->prop->name) + 1; -- namesz += 32; /* space for : + '\0' */ -- } -- -- name = xmalloc(namesz); -- -- s = name; -- for_each_fixup_entry(f, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- snprintf(s, name + namesz - s, "%s:%s:%d", -- fullpath, -- fe->prop->name, fe->offset); -- s += strlen(s) + 1; -- } -- -- nameoff = stringtable_insert(strbuf, f->ref); -- vallen = s - name - 1; -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, name, vallen); -- emit->align(etarget, sizeof(cell_t)); -- -- free(name); -- } -- -- emit->endnode(etarget, tree->labels); -- } -- -- /* add the local fixup property */ -- if (tree->local_fixups) { -- -- /* emit the external fixups */ -- emit->beginnode(etarget, NULL); -- emit->string(etarget, "__local_fixups__", 0); -- emit->align(etarget, sizeof(cell_t)); -- -- namesz = 0; -- for_each_local_fixup_entry(tree, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- namesz += strlen(fullpath) + 1; -- namesz += strlen(fe->prop->name) + 1; -- namesz += 32; /* space for : + '\0' */ -- } -- -- name = xmalloc(namesz); -- -- s = name; -- for_each_local_fixup_entry(tree, fe) { -- fullpath = fe->node->fullpath; -- if (fullpath[0] == '\0') -- fullpath = "/"; -- snprintf(s, name + namesz - s, "%s:%s:%d", -- fullpath, fe->prop->name, -- fe->offset); -- s += strlen(s) + 1; -- } -- -- nameoff = stringtable_insert(strbuf, "fixup"); -- vallen = s - name - 1; -- -- emit->property(etarget, NULL); -- emit->cell(etarget, vallen + 1); -- emit->cell(etarget, nameoff); -- -- if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -- emit->align(etarget, 8); -- -- emit->string(etarget, name, vallen); -- emit->align(etarget, sizeof(cell_t)); -- -- free(name); -- -- emit->endnode(etarget, tree->labels); -- } -- --no_symbols: - emit->endnode(etarget, tree->labels); - } - -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 86b7338..5b8c7d5 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd-dirty" -+#define DTC_VERSION "DTC 1.4.1-g9d3649bd" - -From 4db35c3559c7b70c617593f51cdde1e6a9f75376 Mon Sep 17 00:00:00 2001 +From 440679f12679191111976b233adfeec72263860e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 10 Aug 2015 09:49:15 +0100 -Subject: [PATCH 172/251] scripts/dtc: Update to upstream version 1.4.1 +Subject: [PATCH 096/114] scripts/dtc: Update to upstream version 1.4.1 Includes the new localfixups format. Signed-off-by: Phil Elwell --- - scripts/dtc/checks.c | 105 ++++- + scripts/dtc/checks.c | 105 +++++- scripts/dtc/dtc-lexer.l | 5 + - scripts/dtc/dtc-lexer.lex.c_shipped | 490 ++++++++++++------------ - scripts/dtc/dtc-parser.tab.c_shipped | 722 ++++++++++++++++++----------------- + scripts/dtc/dtc-lexer.lex.c_shipped | 537 +++++++++++++------------- + scripts/dtc/dtc-parser.tab.c_shipped | 714 ++++++++++++++++++----------------- scripts/dtc/dtc-parser.tab.h_shipped | 46 +-- scripts/dtc/dtc-parser.y | 22 +- scripts/dtc/dtc.c | 9 +- scripts/dtc/dtc.h | 40 ++ scripts/dtc/flattree.c | 202 ++++++++++ scripts/dtc/version_gen.h | 2 +- - 10 files changed, 1021 insertions(+), 622 deletions(-) + 10 files changed, 1028 insertions(+), 654 deletions(-) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index e81a8c7..540a3ea 100644 +index 0c03ac9..b369c5e 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -458,6 +458,8 @@ static void fixup_phandle_references(struct check *c, struct node *dt, @@ -154415,10 +128472,10 @@ index e81a8c7..540a3ea 100644 }; diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 0ee1caf..dd44ba2 100644 +index 790fbf6..40bbc87 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l -@@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...); +@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...); return DT_V1; } @@ -154431,7 +128488,7 @@ index 0ee1caf..dd44ba2 100644 DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index 11cd78e..1518525 100644 +index ba525c2..1518525 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped @@ -9,7 +9,7 @@ @@ -154941,10 +128998,85 @@ index 11cd78e..1518525 100644 yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); -@@ -1007,23 +1008,31 @@ case 5: +@@ -951,39 +952,31 @@ case 2: YY_RULE_SETUP - #line 116 "dtc-lexer.l" + #line 75 "dtc-lexer.l" { +- char *line, *fnstart, *fnend; +- struct data fn; ++ char *line, *tmp, *fn; + /* skip text before line # */ + line = yytext; + while (!isdigit((unsigned char)*line)) + line++; +- +- /* regexp ensures that first and list " +- * in the whole yytext are those at +- * beginning and end of the filename string */ +- fnstart = memchr(yytext, '"', yyleng); +- for (fnend = yytext + yyleng - 1; +- *fnend != '"'; fnend--) +- ; +- assert(fnstart && fnend && (fnend > fnstart)); +- +- fn = data_copy_escape_string(fnstart + 1, +- fnend - fnstart - 1); +- +- /* Don't allow nuls in filenames */ +- if (memchr(fn.val, '\0', fn.len - 1)) +- lexical_error("nul in line number directive"); +- ++ /* skip digits in line # */ ++ tmp = line; ++ while (!isspace((unsigned char)*tmp)) ++ tmp++; ++ /* "NULL"-terminate line # */ ++ *tmp = '\0'; ++ /* start of filename */ ++ fn = strchr(tmp + 1, '"') + 1; ++ /* strip trailing " from filename */ ++ tmp = strchr(fn, '"'); ++ *tmp = 0; + /* -1 since #line is the number of the next line */ +- srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); +- data_free(fn); ++ srcpos_set_line(xstrdup(fn), atoi(line) - 1); + } + YY_BREAK + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(BYTESTRING): + case YY_STATE_EOF(PROPNODENAME): + case YY_STATE_EOF(V1): +-#line 104 "dtc-lexer.l" ++#line 96 "dtc-lexer.l" + { + if (!pop_input_file()) { + yyterminate(); +@@ -993,7 +986,7 @@ case YY_STATE_EOF(V1): + case 3: + /* rule 3 can match eol */ + YY_RULE_SETUP +-#line 110 "dtc-lexer.l" ++#line 102 "dtc-lexer.l" + { + DPRINT("String: %s\n", yytext); + yylval.data = data_copy_escape_string(yytext+1, +@@ -1003,7 +996,7 @@ YY_RULE_SETUP + YY_BREAK + case 4: + YY_RULE_SETUP +-#line 117 "dtc-lexer.l" ++#line 109 "dtc-lexer.l" + { + DPRINT("Keyword: /dts-v1/\n"); + dts_version = 1; +@@ -1013,25 +1006,33 @@ YY_RULE_SETUP + YY_BREAK + case 5: + YY_RULE_SETUP +-#line 124 "dtc-lexer.l" ++#line 116 "dtc-lexer.l" ++{ + DPRINT("Keyword: /plugin/\n"); + return DT_PLUGIN; + } @@ -154952,7 +129084,7 @@ index 11cd78e..1518525 100644 +case 6: +YY_RULE_SETUP +#line 121 "dtc-lexer.l" -+{ + { DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; @@ -154961,7 +129093,7 @@ index 11cd78e..1518525 100644 -case 6: +case 7: YY_RULE_SETUP --#line 122 "dtc-lexer.l" +-#line 130 "dtc-lexer.l" +#line 127 "dtc-lexer.l" { DPRINT("Keyword: /bits/\n"); @@ -154972,48 +129104,60 @@ index 11cd78e..1518525 100644 -case 7: +case 8: YY_RULE_SETUP --#line 128 "dtc-lexer.l" +-#line 136 "dtc-lexer.l" +#line 133 "dtc-lexer.l" { DPRINT("Keyword: /delete-property/\n"); DPRINT("\n"); -@@ -1031,9 +1040,9 @@ YY_RULE_SETUP +@@ -1039,9 +1040,9 @@ YY_RULE_SETUP return DT_DEL_PROP; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP --#line 135 "dtc-lexer.l" +-#line 143 "dtc-lexer.l" +#line 140 "dtc-lexer.l" { DPRINT("Keyword: /delete-node/\n"); DPRINT("\n"); -@@ -1041,9 +1050,9 @@ YY_RULE_SETUP +@@ -1049,9 +1050,9 @@ YY_RULE_SETUP return DT_DEL_NODE; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP --#line 142 "dtc-lexer.l" +-#line 150 "dtc-lexer.l" +#line 147 "dtc-lexer.l" { DPRINT("Label: %s\n", yytext); yylval.labelref = xstrdup(yytext); -@@ -1051,9 +1060,9 @@ YY_RULE_SETUP +@@ -1059,9 +1060,9 @@ YY_RULE_SETUP return DT_LABEL; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP --#line 149 "dtc-lexer.l" +-#line 157 "dtc-lexer.l" +#line 154 "dtc-lexer.l" { char *e; DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1073,10 +1082,10 @@ YY_RULE_SETUP +@@ -1069,10 +1070,7 @@ YY_RULE_SETUP + errno = 0; + yylval.integer = strtoull(yytext, &e, 0); + +- if (*e && e[strspn(e, "UL")]) { +- lexical_error("Bad integer literal '%s'", +- yytext); +- } ++ assert(!(*e) || !e[strspn(e, "UL")]); + + if (errno == ERANGE) + lexical_error("Integer literal '%s' out of range", +@@ -1084,10 +1082,10 @@ YY_RULE_SETUP return DT_LITERAL; } YY_BREAK @@ -155022,19 +129166,19 @@ index 11cd78e..1518525 100644 +case 12: +/* rule 12 can match eol */ YY_RULE_SETUP --#line 168 "dtc-lexer.l" +-#line 179 "dtc-lexer.l" +#line 173 "dtc-lexer.l" { struct data d; DPRINT("Character literal: %s\n", yytext); -@@ -1098,18 +1107,18 @@ YY_RULE_SETUP +@@ -1109,18 +1107,18 @@ YY_RULE_SETUP return DT_CHAR_LITERAL; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP --#line 189 "dtc-lexer.l" +-#line 200 "dtc-lexer.l" +#line 194 "dtc-lexer.l" { /* label reference */ DPRINT("Ref: %s\n", yytext+1); @@ -155045,19 +129189,19 @@ index 11cd78e..1518525 100644 -case 13: +case 14: YY_RULE_SETUP --#line 195 "dtc-lexer.l" +-#line 206 "dtc-lexer.l" +#line 200 "dtc-lexer.l" { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); -@@ -1117,27 +1126,27 @@ YY_RULE_SETUP +@@ -1128,27 +1126,27 @@ YY_RULE_SETUP return DT_REF; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP --#line 202 "dtc-lexer.l" +-#line 213 "dtc-lexer.l" +#line 207 "dtc-lexer.l" { yylval.byte = strtol(yytext, NULL, 16); @@ -155068,7 +129212,7 @@ index 11cd78e..1518525 100644 -case 15: +case 16: YY_RULE_SETUP --#line 208 "dtc-lexer.l" +-#line 219 "dtc-lexer.l" +#line 213 "dtc-lexer.l" { DPRINT("/BYTESTRING\n"); @@ -155079,19 +129223,19 @@ index 11cd78e..1518525 100644 -case 16: +case 17: YY_RULE_SETUP --#line 214 "dtc-lexer.l" +-#line 225 "dtc-lexer.l" +#line 219 "dtc-lexer.l" { DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1146,75 +1155,75 @@ YY_RULE_SETUP +@@ -1157,75 +1155,75 @@ YY_RULE_SETUP return DT_PROPNODENAME; } YY_BREAK -case 17: +case 18: YY_RULE_SETUP --#line 222 "dtc-lexer.l" +-#line 233 "dtc-lexer.l" +#line 227 "dtc-lexer.l" { DPRINT("Binary Include\n"); @@ -155101,13 +129245,13 @@ index 11cd78e..1518525 100644 -case 18: -/* rule 18 can match eol */ -YY_RULE_SETUP --#line 227 "dtc-lexer.l" +-#line 238 "dtc-lexer.l" -/* eat whitespace */ - YY_BREAK case 19: /* rule 19 can match eol */ YY_RULE_SETUP --#line 228 "dtc-lexer.l" +-#line 239 "dtc-lexer.l" -/* eat C-style comments */ +#line 232 "dtc-lexer.l" +/* eat whitespace */ @@ -155115,7 +129259,7 @@ index 11cd78e..1518525 100644 case 20: /* rule 20 can match eol */ YY_RULE_SETUP --#line 229 "dtc-lexer.l" +-#line 240 "dtc-lexer.l" -/* eat C++-style comments */ +#line 233 "dtc-lexer.l" +/* eat C-style comments */ @@ -155123,63 +129267,63 @@ index 11cd78e..1518525 100644 case 21: +/* rule 21 can match eol */ YY_RULE_SETUP --#line 231 "dtc-lexer.l" +-#line 242 "dtc-lexer.l" -{ return DT_LSHIFT; }; +#line 234 "dtc-lexer.l" +/* eat C++-style comments */ YY_BREAK case 22: YY_RULE_SETUP --#line 232 "dtc-lexer.l" +-#line 243 "dtc-lexer.l" -{ return DT_RSHIFT; }; +#line 236 "dtc-lexer.l" +{ return DT_LSHIFT; }; YY_BREAK case 23: YY_RULE_SETUP --#line 233 "dtc-lexer.l" +-#line 244 "dtc-lexer.l" -{ return DT_LE; }; +#line 237 "dtc-lexer.l" +{ return DT_RSHIFT; }; YY_BREAK case 24: YY_RULE_SETUP --#line 234 "dtc-lexer.l" +-#line 245 "dtc-lexer.l" -{ return DT_GE; }; +#line 238 "dtc-lexer.l" +{ return DT_LE; }; YY_BREAK case 25: YY_RULE_SETUP --#line 235 "dtc-lexer.l" +-#line 246 "dtc-lexer.l" -{ return DT_EQ; }; +#line 239 "dtc-lexer.l" +{ return DT_GE; }; YY_BREAK case 26: YY_RULE_SETUP --#line 236 "dtc-lexer.l" +-#line 247 "dtc-lexer.l" -{ return DT_NE; }; +#line 240 "dtc-lexer.l" +{ return DT_EQ; }; YY_BREAK case 27: YY_RULE_SETUP --#line 237 "dtc-lexer.l" +-#line 248 "dtc-lexer.l" -{ return DT_AND; }; +#line 241 "dtc-lexer.l" +{ return DT_NE; }; YY_BREAK case 28: YY_RULE_SETUP --#line 238 "dtc-lexer.l" +-#line 249 "dtc-lexer.l" -{ return DT_OR; }; +#line 242 "dtc-lexer.l" +{ return DT_AND; }; YY_BREAK case 29: YY_RULE_SETUP --#line 240 "dtc-lexer.l" +-#line 251 "dtc-lexer.l" +#line 243 "dtc-lexer.l" +{ return DT_OR; }; + YY_BREAK @@ -155189,23 +129333,23 @@ index 11cd78e..1518525 100644 { DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); -@@ -1230,12 +1239,12 @@ YY_RULE_SETUP +@@ -1241,12 +1239,12 @@ YY_RULE_SETUP return yytext[0]; } YY_BREAK -case 30: +case 31: YY_RULE_SETUP --#line 255 "dtc-lexer.l" +-#line 266 "dtc-lexer.l" +#line 260 "dtc-lexer.l" ECHO; YY_BREAK --#line 1239 "dtc-lexer.lex.c" +-#line 1250 "dtc-lexer.lex.c" +#line 1248 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { -@@ -1365,7 +1374,6 @@ ECHO; +@@ -1376,7 +1374,6 @@ ECHO; "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ @@ -155213,7 +129357,7 @@ index 11cd78e..1518525 100644 } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer -@@ -1421,21 +1429,21 @@ static int yy_get_next_buffer (void) +@@ -1432,21 +1429,21 @@ static int yy_get_next_buffer (void) else { @@ -155238,7 +129382,7 @@ index 11cd78e..1518525 100644 if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; -@@ -1466,7 +1474,7 @@ static int yy_get_next_buffer (void) +@@ -1477,7 +1474,7 @@ static int yy_get_next_buffer (void) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), @@ -155247,7 +129391,7 @@ index 11cd78e..1518525 100644 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } -@@ -1528,7 +1536,7 @@ static int yy_get_next_buffer (void) +@@ -1539,7 +1536,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; @@ -155256,7 +129400,7 @@ index 11cd78e..1518525 100644 yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1556,13 +1564,13 @@ static int yy_get_next_buffer (void) +@@ -1567,13 +1564,13 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; @@ -155273,7 +129417,7 @@ index 11cd78e..1518525 100644 } #ifndef YY_NO_INPUT -@@ -1589,7 +1597,7 @@ static int yy_get_next_buffer (void) +@@ -1600,7 +1597,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ @@ -155282,7 +129426,7 @@ index 11cd78e..1518525 100644 ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) -@@ -1863,7 +1871,7 @@ void yypop_buffer_state (void) +@@ -1874,7 +1871,7 @@ void yypop_buffer_state (void) */ static void yyensure_buffer_stack (void) { @@ -155291,7 +129435,7 @@ index 11cd78e..1518525 100644 if (!(yy_buffer_stack)) { -@@ -1960,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +@@ -1971,12 +1968,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) * * @return the newly allocated buffer state object. */ @@ -155306,7 +129450,7 @@ index 11cd78e..1518525 100644 /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; -@@ -2047,7 +2055,7 @@ FILE *yyget_out (void) +@@ -2058,7 +2055,7 @@ FILE *yyget_out (void) /** Get the length of the current token. * */ @@ -155315,17 +129459,17 @@ index 11cd78e..1518525 100644 { return yyleng; } -@@ -2195,7 +2203,7 @@ void yyfree (void * ptr ) +@@ -2206,7 +2203,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" --#line 254 "dtc-lexer.l" +-#line 265 "dtc-lexer.l" +#line 260 "dtc-lexer.l" diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 116458c..844c462 100644 +index 31cec50..844c462 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped @@ -65,6 +65,7 @@ @@ -155487,9 +129631,9 @@ index 116458c..844c462 100644 - 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, - 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, - 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, -- 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, -- 465 +- 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, +- 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, +- 481 + 0, 108, 108, 118, 121, 129, 132, 139, 143, 151, + 155, 160, 171, 181, 196, 204, 207, 214, 218, 222, + 226, 234, 238, 242, 246, 250, 266, 276, 284, 287, @@ -156188,7 +130332,7 @@ index 116458c..844c462 100644 { uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); -@@ -1787,233 +1807,233 @@ yyreduce: +@@ -1787,247 +1807,233 @@ yyreduce: (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); } @@ -156372,166 +130516,161 @@ index 116458c..844c462 100644 break; - case 65: --#line 413 "dtc-parser.y" /* yacc.c:1646 */ +-#line 414 "dtc-parser.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); +- } else { +- ERROR(&(yyloc), "Division by zero"); +- (yyval.integer) = 0; +- } +- } +-#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ + case 67: +#line 429 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } --#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } +#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 66: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ +-#line 423 "dtc-parser.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); +- } else { +- ERROR(&(yyloc), "Division by zero"); +- (yyval.integer) = 0; +- } +- } +-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ + case 68: +#line 430 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } --#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } +#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 69: --#line 420 "dtc-parser.y" /* yacc.c:1646 */ + case 71: -+#line 436 "dtc-parser.y" /* yacc.c:1646 */ + #line 436 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = -(yyvsp[0].integer); } --#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 70: --#line 421 "dtc-parser.y" /* yacc.c:1646 */ + case 72: -+#line 437 "dtc-parser.y" /* yacc.c:1646 */ + #line 437 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 71: --#line 422 "dtc-parser.y" /* yacc.c:1646 */ + case 73: -+#line 438 "dtc-parser.y" /* yacc.c:1646 */ + #line 438 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.integer) = !(yyvsp[0].integer); } --#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 72: --#line 427 "dtc-parser.y" /* yacc.c:1646 */ + case 74: -+#line 443 "dtc-parser.y" /* yacc.c:1646 */ + #line 443 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = empty_data; } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 73: --#line 431 "dtc-parser.y" /* yacc.c:1646 */ + case 75: -+#line 447 "dtc-parser.y" /* yacc.c:1646 */ + #line 447 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); } --#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1975 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 74: --#line 435 "dtc-parser.y" /* yacc.c:1646 */ + case 76: -+#line 451 "dtc-parser.y" /* yacc.c:1646 */ + #line 451 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); } --#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 75: --#line 442 "dtc-parser.y" /* yacc.c:1646 */ + case 77: -+#line 458 "dtc-parser.y" /* yacc.c:1646 */ + #line 458 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.nodelist) = NULL; } --#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 76: --#line 446 "dtc-parser.y" /* yacc.c:1646 */ + case 78: -+#line 462 "dtc-parser.y" /* yacc.c:1646 */ + #line 462 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); } --#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 77: --#line 450 "dtc-parser.y" /* yacc.c:1646 */ + case 79: -+#line 466 "dtc-parser.y" /* yacc.c:1646 */ + #line 466 "dtc-parser.y" /* yacc.c:1646 */ { ERROR(&(yylsp[0]), "Properties must precede subnodes"); YYERROR; } --#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2008 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 78: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ + case 80: -+#line 474 "dtc-parser.y" /* yacc.c:1646 */ + #line 474 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); } --#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2016 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 79: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ + case 81: -+#line 478 "dtc-parser.y" /* yacc.c:1646 */ + #line 478 "dtc-parser.y" /* yacc.c:1646 */ { (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); } --#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2024 "dtc-parser.tab.c" /* yacc.c:1646 */ break; - case 80: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ + case 82: -+#line 482 "dtc-parser.y" /* yacc.c:1646 */ + #line 482 "dtc-parser.y" /* yacc.c:1646 */ { add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); (yyval.node) = (yyvsp[0].node); } --#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2033 "dtc-parser.tab.c" /* yacc.c:1646 */ break; --#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ +-#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ +#line 2037 "dtc-parser.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires -@@ -2248,7 +2268,7 @@ yyreturn: - #endif - return yyresult; - } --#line 472 "dtc-parser.y" /* yacc.c:1906 */ -+#line 488 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped index 30867c6..276d078 100644 --- a/scripts/dtc/dtc-parser.tab.h_shipped @@ -156605,7 +130744,7 @@ index 30867c6..276d078 100644 # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 5a897e3..d23927d 100644 +index 000873f..bd67bac 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -19,6 +19,7 @@ @@ -156663,10 +130802,10 @@ index 5a897e3..d23927d 100644 ; diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 8c4add6..91e91e7 100644 +index 5fa23c4..1f8c285 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c -@@ -29,6 +29,7 @@ int reservenum; /* Number of memory reservation slots */ +@@ -31,6 +31,7 @@ int reservenum; /* Number of memory reservation slots */ int minsize; /* Minimum blob size */ int padsize; /* Additional padding to blob */ int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ @@ -156674,7 +130813,7 @@ index 8c4add6..91e91e7 100644 static void fill_fullpaths(struct node *tree, const char *prefix) { -@@ -51,7 +52,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) +@@ -53,7 +54,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) #define FDT_VERSION(version) _FDT_VERSION(version) #define _FDT_VERSION(version) #version static const char usage_synopsis[] = "dtc [options] "; @@ -156683,7 +130822,7 @@ index 8c4add6..91e91e7 100644 static struct option const usage_long_opts[] = { {"quiet", no_argument, NULL, 'q'}, {"in-format", a_argument, NULL, 'I'}, -@@ -69,6 +70,7 @@ static struct option const usage_long_opts[] = { +@@ -71,6 +72,7 @@ static struct option const usage_long_opts[] = { {"phandle", a_argument, NULL, 'H'}, {"warning", a_argument, NULL, 'W'}, {"error", a_argument, NULL, 'E'}, @@ -156691,7 +130830,7 @@ index 8c4add6..91e91e7 100644 {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {NULL, no_argument, NULL, 0x0}, -@@ -99,6 +101,7 @@ static const char * const usage_opts_help[] = { +@@ -101,6 +103,7 @@ static const char * const usage_opts_help[] = { "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", "\n\tEnable/disable warnings (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")", @@ -156699,7 +130838,7 @@ index 8c4add6..91e91e7 100644 "\n\tPrint this help and exit", "\n\tPrint version and exit", NULL, -@@ -186,7 +189,9 @@ int main(int argc, char *argv[]) +@@ -233,7 +236,9 @@ int main(int argc, char *argv[]) case 'E': parse_checks_option(false, true, optarg); break; @@ -157003,5678 +131142,346 @@ index bd99fa2..2385137 100644 } diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 5b8c7d5..2595dfd 100644 +index 11d93e6..2595dfd 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g9d3649bd" +-#define DTC_VERSION "DTC 1.4.1-gb06e55c8" +#define DTC_VERSION "DTC 1.4.1-g25efc119" -From 04317cda235aa8627422fd132fe4bbb19036f4a5 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou -Date: Thu, 22 Oct 2015 23:30:04 +0300 -Subject: [PATCH 173/251] configfs: implement binary attributes - -ConfigFS lacked binary attributes up until now. This patch -introduces support for binary attributes in a somewhat similar -manner of sysfs binary attributes albeit with changes that -fit the configfs usage model. - -Problems that configfs binary attributes fix are everything that -requires a binary blob as part of the configuration of a resource, -such as bitstream loading for FPGAs, DTBs for dynamically created -devices etc. - -Look at Documentation/filesystems/configfs/configfs.txt for internals -and howto use them. - -This patch is against linux-next as of today that contains -Christoph's configfs rework. - -Signed-off-by: Pantelis Antoniou -[hch: folded a fix from Geert Uytterhoeven ] -[hch: a few tiny updates based on review feedback] -Signed-off-by: Christoph Hellwig ---- - Documentation/filesystems/configfs/configfs.txt | 57 +++++- - fs/configfs/configfs_internal.h | 14 +- - fs/configfs/dir.c | 18 +- - fs/configfs/file.c | 255 +++++++++++++++++++++++- - fs/configfs/inode.c | 2 +- - include/linux/configfs.h | 50 +++++ - 6 files changed, 374 insertions(+), 22 deletions(-) - -diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt -index af68efd..e5fe521 100644 ---- a/Documentation/filesystems/configfs/configfs.txt -+++ b/Documentation/filesystems/configfs/configfs.txt -@@ -51,15 +51,27 @@ configfs tree is always there, whether mounted on /config or not. - An item is created via mkdir(2). The item's attributes will also - appear at this time. readdir(3) can determine what the attributes are, - read(2) can query their default values, and write(2) can store new --values. Like sysfs, attributes should be ASCII text files, preferably --with only one value per file. The same efficiency caveats from sysfs --apply. Don't mix more than one attribute in one attribute file. -- --Like sysfs, configfs expects write(2) to store the entire buffer at --once. When writing to configfs attributes, userspace processes should --first read the entire file, modify the portions they wish to change, and --then write the entire buffer back. Attribute files have a maximum size --of one page (PAGE_SIZE, 4096 on i386). -+values. Don't mix more than one attribute in one attribute file. -+ -+There are two types of configfs attributes: -+ -+* Normal attributes, which similar to sysfs attributes, are small ASCII text -+files, with a maximum size of one page (PAGE_SIZE, 4096 on i386). Preferably -+only one value per file should be used, and the same caveats from sysfs apply. -+Configfs expects write(2) to store the entire buffer at once. When writing to -+normal configfs attributes, userspace processes should first read the entire -+file, modify the portions they wish to change, and then write the entire -+buffer back. -+ -+* Binary attributes, which are somewhat similar to sysfs binary attributes, -+but with a few slight changes to semantics. The PAGE_SIZE limitation does not -+apply, but the whole binary item must fit in single kernel vmalloc'ed buffer. -+The write(2) calls from user space are buffered, and the attributes' -+write_bin_attribute method will be invoked on the final close, therefore it is -+imperative for user-space to check the return code of close(2) in order to -+verify that the operation finished successfully. -+To avoid a malicious user OOMing the kernel, there's a per-binary attribute -+maximum buffer value. - - When an item needs to be destroyed, remove it with rmdir(2). An - item cannot be destroyed if any other item has a link to it (via -@@ -171,6 +183,7 @@ among other things. For that, it needs a type. - struct configfs_item_operations *ct_item_ops; - struct configfs_group_operations *ct_group_ops; - struct configfs_attribute **ct_attrs; -+ struct configfs_bin_attribute **ct_bin_attrs; - }; - - The most basic function of a config_item_type is to define what -@@ -201,6 +214,32 @@ be called whenever userspace asks for a read(2) on the attribute. If an - attribute is writable and provides a ->store method, that method will be - be called whenever userspace asks for a write(2) on the attribute. - -+[struct configfs_bin_attribute] -+ -+ struct configfs_attribute { -+ struct configfs_attribute cb_attr; -+ void *cb_private; -+ size_t cb_max_size; -+ }; -+ -+The binary attribute is used when the one needs to use binary blob to -+appear as the contents of a file in the item's configfs directory. -+To do so add the binary attribute to the NULL-terminated array -+config_item_type->ct_bin_attrs, and the item appears in configfs, the -+attribute file will appear with the configfs_bin_attribute->cb_attr.ca_name -+filename. configfs_bin_attribute->cb_attr.ca_mode specifies the file -+permissions. -+The cb_private member is provided for use by the driver, while the -+cb_max_size member specifies the maximum amount of vmalloc buffer -+to be used. -+ -+If binary attribute is readable and the config_item provides a -+ct_item_ops->read_bin_attribute() method, that method will be called -+whenever userspace asks for a read(2) on the attribute. The converse -+will happen for write(2). The reads/writes are bufferred so only a -+single read/write will occur; the attributes' need not concern itself -+with it. -+ - [struct config_group] - - A config_item cannot live in a vacuum. The only way one can be created -diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h -index b65d1ef..ccc31fa 100644 ---- a/fs/configfs/configfs_internal.h -+++ b/fs/configfs/configfs_internal.h -@@ -53,13 +53,14 @@ struct configfs_dirent { - #define CONFIGFS_ROOT 0x0001 - #define CONFIGFS_DIR 0x0002 - #define CONFIGFS_ITEM_ATTR 0x0004 -+#define CONFIGFS_ITEM_BIN_ATTR 0x0008 - #define CONFIGFS_ITEM_LINK 0x0020 - #define CONFIGFS_USET_DIR 0x0040 - #define CONFIGFS_USET_DEFAULT 0x0080 - #define CONFIGFS_USET_DROPPING 0x0100 - #define CONFIGFS_USET_IN_MKDIR 0x0200 - #define CONFIGFS_USET_CREATING 0x0400 --#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) -+#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR) - - extern struct mutex configfs_symlink_mutex; - extern spinlock_t configfs_dirent_lock; -@@ -72,6 +73,8 @@ extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *, - extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *)); - - extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); -+extern int configfs_create_bin_file(struct config_item *, -+ const struct configfs_bin_attribute *); - extern int configfs_make_dirent(struct configfs_dirent *, - struct dentry *, void *, umode_t, int); - extern int configfs_dirent_is_ready(struct configfs_dirent *); -@@ -88,7 +91,7 @@ extern void configfs_release_fs(void); - extern struct rw_semaphore configfs_rename_sem; - extern const struct file_operations configfs_dir_operations; - extern const struct file_operations configfs_file_operations; --extern const struct file_operations bin_fops; -+extern const struct file_operations configfs_bin_file_operations; - extern const struct inode_operations configfs_dir_inode_operations; - extern const struct inode_operations configfs_root_inode_operations; - extern const struct inode_operations configfs_symlink_inode_operations; -@@ -119,6 +122,13 @@ static inline struct configfs_attribute * to_attr(struct dentry * dentry) - return ((struct configfs_attribute *) sd->s_element); - } - -+static inline struct configfs_bin_attribute *to_bin_attr(struct dentry *dentry) -+{ -+ struct configfs_attribute *attr = to_attr(dentry); -+ -+ return container_of(attr, struct configfs_bin_attribute, cb_attr); -+} -+ - static inline struct config_item *configfs_get_config_item(struct dentry *dentry) - { - struct config_item * item = NULL; -diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c -index a7a1b21..7ae97e8 100644 ---- a/fs/configfs/dir.c -+++ b/fs/configfs/dir.c -@@ -255,6 +255,12 @@ static void configfs_init_file(struct inode * inode) - inode->i_fop = &configfs_file_operations; - } - -+static void configfs_init_bin_file(struct inode *inode) -+{ -+ inode->i_size = 0; -+ inode->i_fop = &configfs_bin_file_operations; -+} -+ - static void init_symlink(struct inode * inode) - { - inode->i_op = &configfs_symlink_inode_operations; -@@ -423,7 +429,9 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den - spin_unlock(&configfs_dirent_lock); - - error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, -- configfs_init_file); -+ (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ? -+ configfs_init_bin_file : -+ configfs_init_file); - if (error) { - configfs_put(sd); - return error; -@@ -583,6 +591,7 @@ static int populate_attrs(struct config_item *item) - { - struct config_item_type *t = item->ci_type; - struct configfs_attribute *attr; -+ struct configfs_bin_attribute *bin_attr; - int error = 0; - int i; - -@@ -594,6 +603,13 @@ static int populate_attrs(struct config_item *item) - break; - } - } -+ if (t->ct_bin_attrs) { -+ for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) { -+ error = configfs_create_bin_file(item, bin_attr); -+ if (error) -+ break; -+ } -+ } - - if (error) - detach_attrs(item); -diff --git a/fs/configfs/file.c b/fs/configfs/file.c -index d39099e..3687187 100644 ---- a/fs/configfs/file.c -+++ b/fs/configfs/file.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -48,6 +49,10 @@ struct configfs_buffer { - struct configfs_item_operations * ops; - struct mutex mutex; - int needs_read_fill; -+ bool read_in_progress; -+ bool write_in_progress; -+ char *bin_buffer; -+ int bin_buffer_size; - }; - - -@@ -123,6 +128,87 @@ out: - return retval; - } - -+/** -+ * configfs_read_bin_file - read a binary attribute. -+ * @file: file pointer. -+ * @buf: buffer to fill. -+ * @count: number of bytes to read. -+ * @ppos: starting offset in file. -+ * -+ * Userspace wants to read a binary attribute file. The attribute -+ * descriptor is in the file's ->d_fsdata. The target item is in the -+ * directory's ->d_fsdata. -+ * -+ * We check whether we need to refill the buffer. If so we will -+ * call the attributes' attr->read() twice. The first time we -+ * will pass a NULL as a buffer pointer, which the attributes' method -+ * will use to return the size of the buffer required. If no error -+ * occurs we will allocate the buffer using vmalloc and call -+ * attr->read() again passing that buffer as an argument. -+ * Then we just copy to user-space using simple_read_from_buffer. -+ */ -+ -+static ssize_t -+configfs_read_bin_file(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct configfs_buffer *buffer = file->private_data; -+ struct dentry *dentry = file->f_path.dentry; -+ struct config_item *item = to_item(dentry->d_parent); -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ ssize_t retval = 0; -+ ssize_t len = min_t(size_t, count, PAGE_SIZE); -+ -+ mutex_lock(&buffer->mutex); -+ -+ /* we don't support switching read/write modes */ -+ if (buffer->write_in_progress) { -+ retval = -ETXTBSY; -+ goto out; -+ } -+ buffer->read_in_progress = 1; -+ -+ if (buffer->needs_read_fill) { -+ /* perform first read with buf == NULL to get extent */ -+ len = bin_attr->read(item, NULL, 0); -+ if (len <= 0) { -+ retval = len; -+ goto out; -+ } -+ -+ /* do not exceed the maximum value */ -+ if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) { -+ retval = -EFBIG; -+ goto out; -+ } -+ -+ buffer->bin_buffer = vmalloc(len); -+ if (buffer->bin_buffer == NULL) { -+ retval = -ENOMEM; -+ goto out; -+ } -+ buffer->bin_buffer_size = len; -+ -+ /* perform second read to fill buffer */ -+ len = bin_attr->read(item, buffer->bin_buffer, len); -+ if (len < 0) { -+ retval = len; -+ vfree(buffer->bin_buffer); -+ buffer->bin_buffer_size = 0; -+ buffer->bin_buffer = NULL; -+ goto out; -+ } -+ -+ buffer->needs_read_fill = 0; -+ } -+ -+ retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+out: -+ mutex_unlock(&buffer->mutex); -+ return retval; -+} -+ - - /** - * fill_write_buffer - copy buffer from userspace. -@@ -209,10 +295,80 @@ configfs_write_file(struct file *file, const char __user *buf, size_t count, lof - return len; - } - --static int check_perm(struct inode * inode, struct file * file) -+/** -+ * configfs_write_bin_file - write a binary attribute. -+ * @file: file pointer -+ * @buf: data to write -+ * @count: number of bytes -+ * @ppos: starting offset -+ * -+ * Writing to a binary attribute file is similar to a normal read. -+ * We buffer the consecutive writes (binary attribute files do not -+ * support lseek) in a continuously growing buffer, but we don't -+ * commit until the close of the file. -+ */ -+ -+static ssize_t -+configfs_write_bin_file(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct configfs_buffer *buffer = file->private_data; -+ struct dentry *dentry = file->f_path.dentry; -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ void *tbuf = NULL; -+ ssize_t len; -+ -+ mutex_lock(&buffer->mutex); -+ -+ /* we don't support switching read/write modes */ -+ if (buffer->read_in_progress) { -+ len = -ETXTBSY; -+ goto out; -+ } -+ buffer->write_in_progress = 1; -+ -+ /* buffer grows? */ -+ if (*ppos + count > buffer->bin_buffer_size) { -+ -+ if (bin_attr->cb_max_size && -+ *ppos + count > bin_attr->cb_max_size) { -+ len = -EFBIG; -+ } -+ -+ tbuf = vmalloc(*ppos + count); -+ if (tbuf == NULL) { -+ len = -ENOMEM; -+ goto out; -+ } -+ -+ /* copy old contents */ -+ if (buffer->bin_buffer) { -+ memcpy(tbuf, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+ vfree(buffer->bin_buffer); -+ } -+ -+ /* clear the new area */ -+ memset(tbuf + buffer->bin_buffer_size, 0, -+ *ppos + count - buffer->bin_buffer_size); -+ buffer->bin_buffer = tbuf; -+ buffer->bin_buffer_size = *ppos + count; -+ } -+ -+ len = simple_write_to_buffer(buffer->bin_buffer, -+ buffer->bin_buffer_size, ppos, buf, count); -+ if (len > 0) -+ *ppos += len; -+out: -+ mutex_unlock(&buffer->mutex); -+ return len; -+} -+ -+static int check_perm(struct inode * inode, struct file * file, int type) - { - struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); - struct configfs_attribute * attr = to_attr(file->f_path.dentry); -+ struct configfs_bin_attribute *bin_attr = NULL; - struct configfs_buffer * buffer; - struct configfs_item_operations * ops = NULL; - int error = 0; -@@ -220,6 +376,9 @@ static int check_perm(struct inode * inode, struct file * file) - if (!item || !attr) - goto Einval; - -+ if (type & CONFIGFS_ITEM_BIN_ATTR) -+ bin_attr = to_bin_attr(file->f_path.dentry); -+ - /* Grab the module reference for this attribute if we have one */ - if (!try_module_get(attr->ca_owner)) { - error = -ENODEV; -@@ -236,9 +395,14 @@ static int check_perm(struct inode * inode, struct file * file) - * and we must have a store method. - */ - if (file->f_mode & FMODE_WRITE) { -- if (!(inode->i_mode & S_IWUGO) || !attr->store) -+ if (!(inode->i_mode & S_IWUGO)) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_ATTR) && !attr->store) - goto Eaccess; - -+ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write) -+ goto Eaccess; - } - - /* File needs read support. -@@ -246,7 +410,13 @@ static int check_perm(struct inode * inode, struct file * file) - * must be a show method for it. - */ - if (file->f_mode & FMODE_READ) { -- if (!(inode->i_mode & S_IRUGO) || !attr->show) -+ if (!(inode->i_mode & S_IRUGO)) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_ATTR) && !attr->show) -+ goto Eaccess; -+ -+ if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read) - goto Eaccess; - } - -@@ -260,6 +430,8 @@ static int check_perm(struct inode * inode, struct file * file) - } - mutex_init(&buffer->mutex); - buffer->needs_read_fill = 1; -+ buffer->read_in_progress = 0; -+ buffer->write_in_progress = 0; - buffer->ops = ops; - file->private_data = buffer; - goto Done; -@@ -277,12 +449,7 @@ static int check_perm(struct inode * inode, struct file * file) - return error; - } - --static int configfs_open_file(struct inode * inode, struct file * filp) --{ -- return check_perm(inode,filp); --} -- --static int configfs_release(struct inode * inode, struct file * filp) -+static int configfs_release(struct inode *inode, struct file *filp) - { - struct config_item * item = to_item(filp->f_path.dentry->d_parent); - struct configfs_attribute * attr = to_attr(filp->f_path.dentry); -@@ -303,6 +470,47 @@ static int configfs_release(struct inode * inode, struct file * filp) - return 0; - } - -+static int configfs_open_file(struct inode *inode, struct file *filp) -+{ -+ return check_perm(inode, filp, CONFIGFS_ITEM_ATTR); -+} -+ -+static int configfs_open_bin_file(struct inode *inode, struct file *filp) -+{ -+ return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR); -+} -+ -+static int configfs_release_bin_file(struct inode *inode, struct file *filp) -+{ -+ struct configfs_buffer *buffer = filp->private_data; -+ struct dentry *dentry = filp->f_path.dentry; -+ struct config_item *item = to_item(dentry->d_parent); -+ struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry); -+ ssize_t len = 0; -+ int ret; -+ -+ buffer->read_in_progress = 0; -+ -+ if (buffer->write_in_progress) { -+ buffer->write_in_progress = 0; -+ -+ len = bin_attr->write(item, buffer->bin_buffer, -+ buffer->bin_buffer_size); -+ -+ /* vfree on NULL is safe */ -+ vfree(buffer->bin_buffer); -+ buffer->bin_buffer = NULL; -+ buffer->bin_buffer_size = 0; -+ buffer->needs_read_fill = 1; -+ } -+ -+ ret = configfs_release(inode, filp); -+ if (len < 0) -+ return len; -+ return ret; -+} -+ -+ - const struct file_operations configfs_file_operations = { - .read = configfs_read_file, - .write = configfs_write_file, -@@ -311,6 +519,14 @@ const struct file_operations configfs_file_operations = { - .release = configfs_release, - }; - -+const struct file_operations configfs_bin_file_operations = { -+ .read = configfs_read_bin_file, -+ .write = configfs_write_bin_file, -+ .llseek = NULL, /* bin file is not seekable */ -+ .open = configfs_open_bin_file, -+ .release = configfs_release_bin_file, -+}; -+ - /** - * configfs_create_file - create an attribute file for an item. - * @item: item we're creating for. -@@ -332,3 +548,24 @@ int configfs_create_file(struct config_item * item, const struct configfs_attrib - return error; - } - -+/** -+ * configfs_create_bin_file - create a binary attribute file for an item. -+ * @item: item we're creating for. -+ * @attr: atrribute descriptor. -+ */ -+ -+int configfs_create_bin_file(struct config_item *item, -+ const struct configfs_bin_attribute *bin_attr) -+{ -+ struct dentry *dir = item->ci_dentry; -+ struct configfs_dirent *parent_sd = dir->d_fsdata; -+ umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG; -+ int error = 0; -+ -+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_NORMAL); -+ error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode, -+ CONFIGFS_ITEM_BIN_ATTR); -+ mutex_unlock(&dir->d_inode->i_mutex); -+ -+ return error; -+} -diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c -index eae8757..0cc810e 100644 ---- a/fs/configfs/inode.c -+++ b/fs/configfs/inode.c -@@ -218,7 +218,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd) - if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) - return sd->s_dentry->d_name.name; - -- if (sd->s_type & CONFIGFS_ITEM_ATTR) { -+ if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) { - attr = sd->s_element; - return attr->ca_name; - } -diff --git a/include/linux/configfs.h b/include/linux/configfs.h -index 758a029..f7300d0 100644 ---- a/include/linux/configfs.h -+++ b/include/linux/configfs.h -@@ -51,6 +51,7 @@ struct module; - struct configfs_item_operations; - struct configfs_group_operations; - struct configfs_attribute; -+struct configfs_bin_attribute; - struct configfs_subsystem; - - struct config_item { -@@ -84,6 +85,7 @@ struct config_item_type { - struct configfs_item_operations *ct_item_ops; - struct configfs_group_operations *ct_group_ops; - struct configfs_attribute **ct_attrs; -+ struct configfs_bin_attribute **ct_bin_attrs; - }; - - /** -@@ -154,6 +156,54 @@ static struct configfs_attribute _pfx##attr_##_name = { \ - .store = _pfx##_name##_store, \ - } - -+struct file; -+struct vm_area_struct; -+ -+struct configfs_bin_attribute { -+ struct configfs_attribute cb_attr; /* std. attribute */ -+ void *cb_private; /* for user */ -+ size_t cb_max_size; /* max core size */ -+ ssize_t (*read)(struct config_item *, void *, size_t); -+ ssize_t (*write)(struct config_item *, const void *, size_t); -+}; -+ -+#define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_bin_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO | S_IWUSR, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .read = _pfx##_name##_read, \ -+ .write = _pfx##_name##_write, \ -+} -+ -+#define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .read = _pfx##_name##_read, \ -+} -+ -+#define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .cb_attr = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IWUSR, \ -+ .ca_owner = THIS_MODULE, \ -+ }, \ -+ .cb_private = _priv, \ -+ .cb_max_size = _maxsz, \ -+ .write = _pfx##_name##_write, \ -+} -+ - /* - * If allow_link() exists, the item can symlink(2) out to other - * items. If the item is a group, it may support mkdir(2). - -From 15c5929aef0ebd49a3afc31a307b0fa3e24a2923 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou -Date: Wed, 3 Dec 2014 13:23:28 +0200 -Subject: [PATCH 174/251] OF: DT-Overlay configfs interface - -This is a port of Pantelis Antoniou's v3 port that makes use of the -new upstreamed configfs support for binary attributes. - -Original commit message: - -Add a runtime interface to using configfs for generic device tree overlay -usage. With it its possible to use device tree overlays without having -to use a per-platform overlay manager. - -Please see Documentation/devicetree/configfs-overlays.txt for more info. - -Changes since v2: -- Removed ifdef CONFIG_OF_OVERLAY (since for now it's required) -- Created a documentation entry -- Slight rewording in Kconfig - -Changes since v1: -- of_resolve() -> of_resolve_phandles(). - -Originally-signed-off-by: Pantelis Antoniou -Signed-off-by: Phil Elwell ---- - Documentation/devicetree/configfs-overlays.txt | 31 +++ - drivers/of/Kconfig | 7 + - drivers/of/Makefile | 1 + - drivers/of/configfs.c | 314 +++++++++++++++++++++++++ - 4 files changed, 353 insertions(+) - create mode 100644 Documentation/devicetree/configfs-overlays.txt - create mode 100644 drivers/of/configfs.c - -diff --git a/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt -new file mode 100644 -index 0000000..5fa43e0 ---- /dev/null -+++ b/Documentation/devicetree/configfs-overlays.txt -@@ -0,0 +1,31 @@ -+Howto use the configfs overlay interface. -+ -+A device-tree configfs entry is created in /config/device-tree/overlays -+and and it is manipulated using standard file system I/O. -+Note that this is a debug level interface, for use by developers and -+not necessarily something accessed by normal users due to the -+security implications of having direct access to the kernel's device tree. -+ -+* To create an overlay you mkdir the directory: -+ -+ # mkdir /config/device-tree/overlays/foo -+ -+* Either you echo the overlay firmware file to the path property file. -+ -+ # echo foo.dtbo >/config/device-tree/overlays/foo/path -+ -+* Or you cat the contents of the overlay to the dtbo file -+ -+ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo -+ -+The overlay file will be applied, and devices will be created/destroyed -+as required. -+ -+To remove it simply rmdir the directory. -+ -+ # rmdir /config/device-tree/overlays/foo -+ -+The rationalle of the dual interface (firmware & direct copy) is that each is -+better suited to different use patterns. The firmware interface is what's -+intended to be used by hardware managers in the kernel, while the copy interface -+make sense for developers (since it avoids problems with namespaces). -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index e2a4841..7e5e6c4 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -112,4 +112,11 @@ config OF_OVERLAY - While this option is selected automatically when needed, you can - enable it manually to improve device tree unit test coverage. - -+config OF_CONFIGFS -+ bool "Device Tree Overlay ConfigFS interface" -+ select CONFIGFS_FS -+ select OF_OVERLAY -+ help -+ Enable a simple user-space driven DT overlay interface. -+ - endif # OF -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index 156c072..46c8f57 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,4 +1,5 @@ - obj-y = base.o device.o platform.o -+obj-$(CONFIG_OF_CONFIGFS) += configfs.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o - obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o -diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c -new file mode 100644 -index 0000000..7b66deb ---- /dev/null -+++ b/drivers/of/configfs.c -@@ -0,0 +1,314 @@ -+/* -+ * Configfs entries for device-tree -+ * -+ * Copyright (C) 2013 - Pantelis Antoniou -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "of_private.h" -+ -+struct cfs_overlay_item { -+ struct config_item item; -+ -+ char path[PATH_MAX]; -+ -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int ov_id; -+ -+ void *dtbo; -+ int dtbo_size; -+}; -+ -+static int create_overlay(struct cfs_overlay_item *overlay, void *blob) -+{ -+ int err; -+ -+ /* unflatten the tree */ -+ of_fdt_unflatten_tree(blob, &overlay->overlay); -+ if (overlay->overlay == NULL) { -+ pr_err("%s: failed to unflatten tree\n", __func__); -+ err = -EINVAL; -+ goto out_err; -+ } -+ pr_debug("%s: unflattened OK\n", __func__); -+ -+ /* mark it as detached */ -+ of_node_set_flag(overlay->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(overlay->overlay); -+ if (err != 0) { -+ pr_err("%s: Failed to resolve tree\n", __func__); -+ goto out_err; -+ } -+ pr_debug("%s: resolved OK\n", __func__); -+ -+ err = of_overlay_create(overlay->overlay); -+ if (err < 0) { -+ pr_err("%s: Failed to create overlay (err=%d)\n", -+ __func__, err); -+ goto out_err; -+ } -+ overlay->ov_id = err; -+ -+out_err: -+ return err; -+} -+ -+static inline struct cfs_overlay_item *to_cfs_overlay_item( -+ struct config_item *item) -+{ -+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; -+} -+ -+static ssize_t cfs_overlay_item_path_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ return sprintf(page, "%s\n", overlay->path); -+} -+ -+static ssize_t cfs_overlay_item_path_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ const char *p = page; -+ char *s; -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); -+ overlay->path[sizeof(overlay->path) - 1] = '\0'; -+ -+ /* strip trailing newlines */ -+ s = overlay->path + strlen(overlay->path); -+ while (s > overlay->path && *--s == '\n') -+ *s = '\0'; -+ -+ pr_debug("%s: path is '%s'\n", __func__, overlay->path); -+ -+ err = request_firmware(&overlay->fw, overlay->path, NULL); -+ if (err != 0) -+ goto out_err; -+ -+ err = create_overlay(overlay, (void *)overlay->fw->data); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ -+ release_firmware(overlay->fw); -+ overlay->fw = NULL; -+ -+ overlay->path[0] = '\0'; -+ return err; -+} -+ -+static ssize_t cfs_overlay_item_status_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ return sprintf(page, "%s\n", -+ overlay->ov_id >= 0 ? "applied" : "unapplied"); -+} -+ -+CONFIGFS_ATTR(cfs_overlay_item_, path); -+CONFIGFS_ATTR_RO(cfs_overlay_item_, status); -+ -+static struct configfs_attribute *cfs_overlay_attrs[] = { -+ &cfs_overlay_item_attr_path, -+ &cfs_overlay_item_attr_status, -+ NULL, -+}; -+ -+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, -+ void *buf, size_t max_count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ pr_debug("%s: buf=%p max_count=%u\n", __func__, -+ buf, max_count); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ /* copy if buffer provided */ -+ if (buf != NULL) { -+ /* the buffer must be large enough */ -+ if (overlay->dtbo_size > max_count) -+ return -ENOSPC; -+ -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ } -+ -+ return overlay->dtbo_size; -+} -+ -+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, -+ const void *buf, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy the contents */ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) -+ return -ENOMEM; -+ -+ overlay->dtbo_size = count; -+ -+ err = create_overlay(overlay, overlay->dtbo); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ return err; -+} -+ -+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); -+ -+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { -+ &cfs_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+static void cfs_overlay_release(struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ if (overlay->ov_id >= 0) -+ of_overlay_destroy(overlay->ov_id); -+ if (overlay->fw) -+ release_firmware(overlay->fw); -+ /* kfree with NULL is safe */ -+ kfree(overlay->dtbo); -+ kfree(overlay); -+} -+ -+static struct configfs_item_operations cfs_overlay_item_ops = { -+ .release = cfs_overlay_release, -+}; -+ -+static struct config_item_type cfs_overlay_type = { -+ .ct_item_ops = &cfs_overlay_item_ops, -+ .ct_attrs = cfs_overlay_attrs, -+ .ct_bin_attrs = cfs_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *cfs_overlay_group_make_item( -+ struct config_group *group, const char *name) -+{ -+ struct cfs_overlay_item *overlay; -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->ov_id = -1; -+ -+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); -+ return &overlay->item; -+} -+ -+static void cfs_overlay_group_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ config_item_put(&overlay->item); -+} -+ -+static struct configfs_group_operations overlays_ops = { -+ .make_item = cfs_overlay_group_make_item, -+ .drop_item = cfs_overlay_group_drop_item, -+}; -+ -+static struct config_item_type overlays_type = { -+ .ct_group_ops = &overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_group_operations of_cfs_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type of_cfs_type = { -+ .ct_group_ops = &of_cfs_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group of_cfs_overlay_group; -+ -+struct config_group *of_cfs_def_groups[] = { -+ &of_cfs_overlay_group, -+ NULL -+}; -+ -+static struct configfs_subsystem of_cfs_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &of_cfs_type, -+ }, -+ .default_groups = of_cfs_def_groups, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), -+}; -+ -+static int __init of_cfs_init(void) -+{ -+ int ret; -+ -+ pr_info("%s\n", __func__); -+ -+ config_group_init(&of_cfs_subsys.su_group); -+ config_group_init_type_name(&of_cfs_overlay_group, "overlays", -+ &overlays_type); -+ -+ ret = configfs_register_subsystem(&of_cfs_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto out; -+ } -+ pr_info("%s: OK\n", __func__); -+out: -+ return ret; -+} -+late_initcall(of_cfs_init); - -From ee377daa5f1e9811fa04bbf254f4930ed5c7c9c5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 13 Mar 2015 12:43:36 +0000 -Subject: [PATCH 175/251] Protect __release_resource against resources without - parents - -Without this patch, removing a device tree overlay can crash here. - -Signed-off-by: Phil Elwell ---- - kernel/resource.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/kernel/resource.c b/kernel/resource.c -index 249b1eb..eb973a5 100644 ---- a/kernel/resource.c -+++ b/kernel/resource.c -@@ -237,6 +237,12 @@ static int __release_resource(struct resource *old) - { - struct resource *tmp, **p; - -+ if (!old->parent) { -+ WARN(old->sibling, "sibling but no parent"); -+ if (old->sibling) -+ return -EINVAL; -+ return 0; -+ } - p = &old->parent->child; - for (;;) { - tmp = *p; - -From fa4cb194572f56c3ab11913af77d31084b8f40e5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 13 Mar 2015 20:00:21 +0000 -Subject: [PATCH 176/251] BCM270X_DT: Add a .dtbo target, use for overlays - -Change the filenames and extensions to keep the pre-DDT style of -overlay (-overlay.dtb) distinct from new ones that use a -different style of local fixups (.dtbo), and to match other -platforms. - -The RPi firmware uses the DDTK trailer atom to choose which type of -overlay to use for each kernel. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/.gitignore | 2 +- - arch/arm/boot/dts/overlays/Makefile | 135 +++++++++++++++++------------------- - scripts/Makefile.lib | 10 +++ - 3 files changed, 76 insertions(+), 71 deletions(-) - -diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore -index 3c79f85..eaaeb17 100644 ---- a/arch/arm/boot/.gitignore -+++ b/arch/arm/boot/.gitignore -@@ -3,4 +3,4 @@ zImage - xipImage - bootpImage - uImage --*.dtb -+*.dtb* -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 687cc7c..d81fa09 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -12,78 +12,73 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif - --dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dwc2-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dwc-otg-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += gpio-ir-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += gpio-poweroff-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c0-bcm2708-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c1-bcm2708-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pi3-disable-bt-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-capacitive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-backlight-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdtweak-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-1cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-2cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi1-3cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-1cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-2cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi2-3cs-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-gpio35-39-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += vc4-kms-v3d-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += enc28j60.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += gpio-ir.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += gpio-poweroff.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-amp.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-dacplus.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hifiberry-digi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += iqaudio-dacplus.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += lirc-rpi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += piscreen2r.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pitft28-capacitive.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-display.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-ft5406.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-proto.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += rpi-sense.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdhost.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += sdtweak.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi-dev.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi-nand.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += smi.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-1cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-2cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi1-3cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-1cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-2cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi2-3cs.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += spi-gpio35-39.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += tinylcd35.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += uart1.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo - - targets += dtbs dtbs_install --targets += $(dtb-y) -+targets += $(dtbo-y) - - endif - --always := $(dtb-y) --clean-files := *.dtb -- --# Enable fixups to support overlays on BCM2708 platforms --ifeq ($(RPI_DT_OVERLAYS),y) -- DTC_FLAGS ?= -@ --endif -+always := $(dtbo-y) -+clean-files := *.dtbo -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 79e8661..7209d62 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -292,6 +292,16 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(obj)/%.dtb: $(src)/%.dts FORCE - $(call if_changed_dep,dtc) - -+quiet_cmd_dtco = DTCO $@ -+cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -+ $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ -+ -i $(dir $<) $(DTC_FLAGS) \ -+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ -+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -+ -+$(obj)/%.dtbo: $(src)/%-overlay.dts FORCE -+ $(call if_changed_dep,dtco) -+ - dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) - - # Bzip2 - -From 3c760a6a8f336bfb891214091b71bc3408c93b6f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 11:18:58 +0100 -Subject: [PATCH 177/251] scripts/knlinfo: Decode DDTK atom - -Show the DDTK atom as being a boolean. - -Signed-off-by: Phil Elwell ---- - scripts/knlinfo | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/scripts/knlinfo b/scripts/knlinfo -index b9ef124..263ec93 100755 ---- a/scripts/knlinfo -+++ b/scripts/knlinfo -@@ -16,6 +16,7 @@ my $trailer_magic = 'RPTL'; - - my %atom_formats = - ( -+ 'DDTK' => \&format_bool, - 'DTOK' => \&format_bool, - 'KVer' => \&format_string, - '270X' => \&format_bool, -@@ -148,7 +149,7 @@ sub format_atom - sub format_bool - { - my ($data) = @_; -- return unpack('V', $data) ? 'true' : 'false'; -+ return unpack('V', $data) ? 'y' : 'n'; - } - - sub format_int - -From 2db1009fef8b23bac3b3ae61dd1382bffb0827b1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 11:48:59 +0100 -Subject: [PATCH 178/251] Enable Dynamic Device Tree for bcmrpi_defconfig and - bcm2709_defconfig - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7793baf..0fff5a3 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -403,6 +403,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m -+CONFIG_OF_CONFIGFS=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1161,7 +1162,6 @@ CONFIG_NTFS_FS=m - CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f09be87..2db41e6 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -396,6 +396,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m -+CONFIG_OF_OVERLAY=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y - -From efe315038fd3581998bf6c93f432ac6cf85bb53f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sun, 13 Mar 2016 16:14:44 +0000 -Subject: [PATCH 179/251] SQUASH: Add CONFIG_OF_CONFIGFS to bcmrpi_defconfig - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcmrpi_defconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 2db41e6..74149cf 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -396,7 +396,7 @@ CONFIG_MTD=m - CONFIG_MTD_BLOCK=m - CONFIG_MTD_NAND=m - CONFIG_MTD_UBI=m --CONFIG_OF_OVERLAY=y -+CONFIG_OF_CONFIGFS=y - CONFIG_ZRAM=m - CONFIG_ZRAM_LZ4_COMPRESS=y - CONFIG_BLK_DEV_LOOP=y -@@ -1169,7 +1169,6 @@ CONFIG_NTFS_FS=m - CONFIG_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_CONFIGFS_FS=y - CONFIG_ECRYPT_FS=m - CONFIG_HFS_FS=m - CONFIG_HFSPLUS_FS=m - -From 558d3a84b6363b021f77f138615cbf7b72c6f38c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 14 Mar 2016 16:56:54 +0000 -Subject: [PATCH 180/251] dts, kbuild: dtbs_install installs .dtbo files too - -Signed-off-by: Phil Elwell ---- - scripts/Makefile.dtbinst | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst -index 1c15717..43647b3 100644 ---- a/scripts/Makefile.dtbinst -+++ b/scripts/Makefile.dtbinst -@@ -29,6 +29,7 @@ ifeq ("$(dtbinst-root)", "$(obj)") - endif - - dtbinst-files := $(dtb-y) -+dtboinst-files := $(dtbo-y) - dtbinst-dirs := $(dts-dirs) - - # Helper targets for Installing DTBs into the boot directory -@@ -37,15 +38,18 @@ quiet_cmd_dtb_install = INSTALL $< - - install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) - --$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep -+$(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs): | __dtbs_install_prep - - $(dtbinst-files): %.dtb: $(obj)/%.dtb - $(call cmd,dtb_install,$(install-dir)) - -+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo -+ $(call cmd,dtb_install,$(install-dir)) -+ - $(dtbinst-dirs): - $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ - --PHONY += $(dtbinst-files) $(dtbinst-dirs) --__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) -+PHONY += $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) -+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(dtbinst-dirs) - - .PHONY: $(PHONY) - -From 3df4e691dcda317e661b026201c28db902be6830 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 14:10:29 +0000 -Subject: [PATCH 181/251] bcm2835-sdhost: Workaround for "slow" sectors - -Some cards have been seen to cause timeouts after certain sectors are -read. This workaround enforces a minimum delay between the stop after -reading one of those sectors and a subsequent data command. - -Using CMD23 (SET_BLOCK_COUNT) avoids this problem, so good cards will -not be penalised by this workaround. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 50 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 46 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 4cc4272..f43aae0 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -202,9 +202,12 @@ struct bcm2835_host { - int max_delay; /* maximum length of time spent waiting */ - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+ u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -+ -+ u32 sectors; /* Cached card size in sectors */ - }; - - #if ENABLE_LOG -@@ -425,6 +428,7 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host) - bcm2835_sdhost_set_power(host, true); - mdelay(10); - host->clock = 0; -+ host->sectors = 0; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - mmiowb(); -@@ -880,6 +884,24 @@ static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_co - host->flush_fifo = 0; - host->data->bytes_xfered = 0; - -+ if (!host->sectors && host->mmc->card) { -+ struct mmc_card *card = host->mmc->card; -+ if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { -+ /* -+ * The EXT_CSD sector count is in number of 512 byte -+ * sectors. -+ */ -+ host->sectors = card->ext_csd.sectors; -+ } else { -+ /* -+ * The CSD capacity field is in units of read_blkbits. -+ * set_capacity takes units of 512 bytes. -+ */ -+ host->sectors = card->csd.capacity << -+ (card->csd.read_blkbits - 9); -+ } -+ } -+ - if (!host->dma_desc) { - /* Use PIO */ - int flags = SG_MITER_ATOMIC; -@@ -989,7 +1011,7 @@ bool bcm2835_sdhost_send_command(struct bcm2835_host *host, - - if (cmd->data) { - log_event("CMDD", cmd->data->blocks, cmd->data->blksz); -- if (host->delay_after_stop) { -+ if (host->delay_after_this_stop) { - struct timeval now; - int time_since_stop; - do_gettimeofday(&now); -@@ -998,12 +1020,32 @@ bool bcm2835_sdhost_send_command(struct bcm2835_host *host, - /* Possibly less than one second */ - time_since_stop = time_since_stop * 1000000 + - (now.tv_usec - host->stop_time.tv_usec); -- if (time_since_stop < host->delay_after_stop) -- udelay(host->delay_after_stop - -+ if (time_since_stop < -+ host->delay_after_this_stop) -+ udelay(host->delay_after_this_stop - - time_since_stop); - } - } - -+ host->delay_after_this_stop = host->delay_after_stop; -+ if ((cmd->data->flags & MMC_DATA_READ) && !host->use_sbc) { -+ /* See if read crosses one of the hazardous sectors */ -+ u32 first_blk, last_blk; -+ -+ /* Intentionally include the following sector because -+ without CMD23/SBC the read may run on. */ -+ first_blk = host->mrq->cmd->arg; -+ last_blk = first_blk + cmd->data->blocks; -+ -+ if (((last_blk >= (host->sectors - 64)) && -+ (first_blk <= (host->sectors - 64))) || -+ ((last_blk >= (host->sectors - 32)) && -+ (first_blk <= (host->sectors - 32)))) { -+ host->delay_after_this_stop = -+ max(250u, host->delay_after_stop); -+ } -+ } -+ - if (cmd->data->flags & MMC_DATA_WRITE) - sdcmd |= SDCMD_WRITE_CMD; - if (cmd->data->flags & MMC_DATA_READ) -@@ -1078,7 +1120,7 @@ static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) - if (!host->use_busy) - bcm2835_sdhost_finish_command(host, NULL); - -- if (host->delay_after_stop) -+ if (host->delay_after_this_stop) - do_gettimeofday(&host->stop_time); - } - } else { - -From 16f0b8c220be3459c873578037994693c7e025d1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 15:49:16 +0000 -Subject: [PATCH 182/251] BCM270X_DT: Add labels to spidev nodes - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++-- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++-- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 4 ++-- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++-- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++-- - 5 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index d2d6fa0..00ea1b2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index d033ee4..2f8a718 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 8bcafb4..954896e 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -42,7 +42,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -50,7 +50,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index aca253f..66523d6 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -59,7 +59,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -67,7 +67,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 2cb7d43..1ce4ea2 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -110,7 +110,7 @@ - pinctrl-0 = <&spi0_pins &spi0_cs_pins>; - cs-gpios = <&gpio 8 1>, <&gpio 7 1>; - -- spidev@0{ -+ spidev0: spidev@0{ - compatible = "spidev"; - reg = <0>; /* CE0 */ - #address-cells = <1>; -@@ -118,7 +118,7 @@ - spi-max-frequency = <500000>; - }; - -- spidev@1{ -+ spidev1: spidev@1{ - compatible = "spidev"; - reg = <1>; /* CE1 */ - #address-cells = <1>; - -From 320ed2194edfdcd5fcc93772a353b7480fd4aa5a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 16:27:26 +0000 -Subject: [PATCH 183/251] BCM270X_DT: Use spidev labels in overlays - ---- - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 11 +++++---- - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 11 +++++---- - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 22 ++++++++++------- - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 16 ++++++++----- - .../arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 16 ++++++++----- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 22 ++++++++++------- - .../dts/overlays/pitft28-capacitive-overlay.dts | 17 +++++++------ - .../dts/overlays/pitft28-resistive-overlay.dts | 24 ++++++++++++------- - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 22 ++++++++++------- - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 28 +++++++++++++--------- - 14 files changed, 174 insertions(+), 103 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -index 6a92cd1..edf2dc9 100644 ---- a/arch/arm/boot/dts/overlays/ads7846-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - ads7846_pins: ads7846_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -index eab4052..880c753 100644 ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -14,10 +14,6 @@ - - status = "okay"; - -- spidev@0{ -- status = "disabled"; -- }; -- - lowpan0: at86rf233@0 { - compatible = "atmel,at86rf233"; - reg = <0>; -@@ -32,6 +28,13 @@ - }; - - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - lowpan0_pins: lowpan0_pins { -diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -index 8fae869..db8a8fe 100644 ---- a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -+++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -14,10 +14,6 @@ - - status = "okay"; - -- spidev@0{ -- status = "disabled"; -- }; -- - eth1: enc28j60@0{ - compatible = "microchip,enc28j60"; - reg = <0>; /* CE0 */ -@@ -32,6 +28,13 @@ - }; - - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - eth1_pins: eth1_pins { -diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -index 3cd3083..ac0f3c2 100644 ---- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - hy28a_pins: hy28a_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -index f774c4a..8018aeb 100644 ---- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - hy28b_pins: hy28b_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -index 398d59c..c96cdae 100755 ---- a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -12,14 +12,18 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- spidev@0{ -- status = "disabled"; -- }; - }; - }; - -- /* the interrupt pin of the can-controller */ - fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - can0_pins: can0_pins { -@@ -30,7 +34,7 @@ - }; - - /* the clock/oscillator of the can-controller */ -- fragment@2 { -+ fragment@3 { - target-path = "/clocks"; - __overlay__ { - /* external oscillator of mcp2515 on SPI0.0 */ -@@ -43,7 +47,7 @@ - }; - - /* the spi config of the can-controller itself binding everything together */ -- fragment@3 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -index 6bef9ae..67bd0d9 100644 ---- a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -12,14 +12,18 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- spidev@1{ -- status = "disabled"; -- }; - }; - }; - -- /* the interrupt pin of the can-controller */ - fragment@1 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - can1_pins: can1_pins { -@@ -30,7 +34,7 @@ - }; - - /* the clock/oscillator of the can-controller */ -- fragment@2 { -+ fragment@3 { - target-path = "/clocks"; - __overlay__ { - /* external oscillator of mcp2515 on spi0.1 */ -@@ -43,7 +47,7 @@ - }; - - /* the spi config of the can-controller itself binding everything together */ -- fragment@3 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -index 9242a6e..2c29aae 100644 ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - mz61581_pins: mz61581_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index ba4ad33..40a1f29 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - piscreen_pins: piscreen_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -index 7c018e0..9c0bed8 100644 ---- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - piscreen2_pins: piscreen2_pins { -@@ -34,7 +40,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -index 48920e9..5c07526 100644 ---- a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -@@ -13,14 +13,17 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; - }; - }; - -- fragment@1 { -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { - target = <&gpio>; - __overlay__ { - pitft_pins: pitft_pins { -@@ -31,7 +34,7 @@ - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -55,7 +58,7 @@ - }; - }; - -- fragment@3 { -+ fragment@4 { - target = <&i2c1>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -index d506eae..ed2afc2 100644 ---- a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - pitft_pins: pitft_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -95,7 +101,7 @@ - }; - }; - -- fragment@3 { -+ fragment@5 { - target-path = "/soc"; - __overlay__ { - backlight { -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -index ccb296e..d7e72ee 100644 ---- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -13,18 +13,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - rpi_display_pins: rpi_display_pins { -@@ -35,7 +41,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -index f7102c8..33c0651 100644 ---- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -30,18 +30,24 @@ - target = <&spi0>; - __overlay__ { - status = "okay"; -+ }; -+ }; - -- spidev@0{ -- status = "disabled"; -- }; -+ fragment@1 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - -- spidev@1{ -- status = "disabled"; -- }; -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; - }; - }; - -- fragment@1 { -+ fragment@3 { - target = <&gpio>; - __overlay__ { - tinylcd35_pins: tinylcd35_pins { -@@ -60,7 +66,7 @@ - }; - }; - -- fragment@2 { -+ fragment@4 { - target = <&spi0>; - __overlay__ { - /* needed to avoid dtc warning */ -@@ -124,7 +130,7 @@ - - /* RTC */ - -- fragment@3 { -+ fragment@5 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -138,7 +144,7 @@ - }; - }; - -- fragment@4 { -+ fragment@6 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -156,7 +162,7 @@ - * Values for input event code is found under the - * 'Keys and buttons' heading in include/uapi/linux/input.h - */ -- fragment@5 { -+ fragment@7 { - target-path = "/soc"; - __overlay__ { - keypad: keypad { - -From 19da6ff34954c7a0c2aecef0451463522ea24ca1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Mar 2016 16:41:37 +0000 -Subject: [PATCH 184/251] BCM270X_DT: Build and document the wittypi overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++++++ - arch/arm/boot/dts/overlays/wittypi-overlay.dts | 2 +- - 3 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d81fa09..4f3ca9c 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -74,6 +74,7 @@ dtbo-$(RPI_DT_OVERLAYS) += vc4-kms-v3d.dtbo - dtbo-$(RPI_DT_OVERLAYS) += vga666.dtbo - dtbo-$(RPI_DT_OVERLAYS) += w1-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += w1-gpio-pullup.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += wittypi.dtbo - - targets += dtbs dtbs_install - targets += $(dtbo-y) -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 6fa5b80..d939739 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -920,6 +920,14 @@ Params: gpiopin GPIO for I/O (default "4") - extpullup GPIO for external pullup (default "5") - - -+Name: wittypi -+Info: Configures the wittypi RTC module. -+Load: dtoverlay=wittypi,= -+Params: led_gpio GPIO for LED (default "17") -+ led_trigger Choose which activity the LED tracks (default -+ "default-on") -+ -+ - Troubleshooting - =============== - -diff --git a/arch/arm/boot/dts/overlays/wittypi-overlay.dts b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -index be5987d..8498134 100644 ---- a/arch/arm/boot/dts/overlays/wittypi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -@@ -37,7 +37,7 @@ - }; - - __overrides__ { -- led_gpio = <&wittypi_led>,"gpios:4"; -+ led_gpio = <&wittypi_led>,"gpios:4"; - led_trigger = <&wittypi_led>,"linux,default-trigger"; - }; - - -From e45f33c187edcda0e4affe6930068deadebf8b6c Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Tue, 15 Mar 2016 21:13:39 +0100 -Subject: [PATCH 185/251] scripts/dtc: Fix UMR causing corrupt dtbo overlay - files - -struct fixup_entry is allocated from the heap but it's member -local_fixup_generated was never initialized. This lead to -corrupted dtbo files. - -Fix this by initializing local_fixup_generated to false. - -Signed-off-by: Matthias Reichl ---- - scripts/dtc/checks.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 540a3ea..2b3b3a7 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -523,6 +523,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - fe->prop = prop; - fe->offset = m->offset; - fe->next = NULL; -+ fe->local_fixup_generated = false; - - /* append it to the local fixups */ - fep = &dt->local_fixups; - -From e45af7e57db63c4bd5d0ad7fe400cfdd36df42d4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 16 Mar 2016 08:35:06 +0000 -Subject: [PATCH 186/251] BCM270X_DT: Add dtparam for uart1 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 + - arch/arm/boot/dts/overlays/README | 3 +++ - 6 files changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 00ea1b2..0e9a22d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -120,6 +120,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 2f8a718..a60342c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -114,6 +114,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 954896e..cd0e1ac 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -89,6 +89,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 66523d6..9176d57 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -120,6 +120,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index 1ce4ea2..d2d39c6 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -171,6 +171,7 @@ - __overrides__ { - uart0 = <&uart0>,"status"; - uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ uart1 = <&uart1>,"status"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index d939739..4ce7921 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -124,6 +124,9 @@ Params: - - uart0 Set to "off" to disable uart0 (default "on") - -+ uart1 Set to "on" or "off" to enable or disable uart1 -+ (default varies) -+ - watchdog Set to "on" to enable the hardware watchdog - (default "off") - - -From 3f7271f5e6747663f2db11f01721ee60961e0178 Mon Sep 17 00:00:00 2001 -From: Przemek Rudy -Date: Fri, 11 Mar 2016 22:41:26 +0100 -Subject: [PATCH 187/251] dwc-overlay: Use label so overrides can apply. - ---- - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -index 90c9811..527abc9 100644 ---- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -8,7 +8,7 @@ - target = <&usb>; - #address-cells = <1>; - #size-cells = <1>; -- __overlay__ { -+ dwc2_usb: __overlay__ { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; -@@ -21,9 +21,9 @@ - }; - - __overrides__ { -- dr_mode = <&usb>, "dr_mode"; -- g-np-tx-fifo-size = <&usb>,"g-np-tx-fifo-size:0"; -- g-rx-fifo-size = <&usb>,"g-rx-fifo-size:0"; -- g-tx-fifo-size = <&usb>,"g-tx-fifo-size:0"; -+ dr_mode = <&dwc2_usb>, "dr_mode"; -+ g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; -+ g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; -+ g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; - }; - }; - -From 5b7b03b9220d45e9fa99c2f9c73a08792cc4684b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 22 Jan 2016 13:06:39 -0800 -Subject: [PATCH 188/251] drm/vc4: Add a debugfs node for tracking execution - state. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + - drivers/gpu/drm/vc4/vc4_drv.h | 1 + - drivers/gpu/drm/vc4/vc4_gem.c | 14 ++++++++++++++ - 3 files changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c -index d76ad10..a99aa86 100644 ---- a/drivers/gpu/drm/vc4/vc4_debugfs.c -+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c -@@ -17,6 +17,7 @@ - - static const struct drm_info_list vc4_debugfs_list[] = { - {"bo_stats", vc4_bo_stats_debugfs, 0}, -+ {"gem_exec", vc4_gem_exec_debugfs, 0}, - {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, - {"hvs_regs", vc4_hvs_debugfs_regs, 0}, - {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0}, -diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h -index ed93fa7..aa0d00e 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -403,6 +403,7 @@ void vc4_job_handle_completed(struct vc4_dev *vc4); - int vc4_queue_seqno_cb(struct drm_device *dev, - struct vc4_seqno_cb *cb, uint64_t seqno, - void (*func)(struct vc4_seqno_cb *cb)); -+int vc4_gem_exec_debugfs(struct seq_file *m, void *arg); - - /* vc4_hdmi.c */ - extern struct platform_driver vc4_hdmi_driver; -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 39f29e7..1243f4e 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -31,6 +31,20 @@ - #include "vc4_regs.h" - #include "vc4_trace.h" - -+#ifdef CONFIG_DEBUG_FS -+int vc4_gem_exec_debugfs(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *)m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ -+ seq_printf(m, "Emitted seqno: 0x%016llx\n", vc4->emit_seqno); -+ seq_printf(m, "Finished seqno: 0x%016llx\n", vc4->finished_seqno); -+ -+ return 0; -+} -+#endif /* CONFIG_DEBUG_FS */ -+ - static void - vc4_queue_hangcheck(struct drm_device *dev) - { - -From 04fb589070fd36693251a40ceb61743bb3a0c2c6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:03:33 -0800 -Subject: [PATCH 189/251] drm/vc4: Include vc4_drm.h in uapi in downstream - build. - -Signed-off-by: Eric Anholt ---- - include/uapi/drm/Kbuild | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild -index 38d4370..23381b5 100644 ---- a/include/uapi/drm/Kbuild -+++ b/include/uapi/drm/Kbuild -@@ -14,6 +14,7 @@ header-y += radeon_drm.h - header-y += savage_drm.h - header-y += sis_drm.h - header-y += tegra_drm.h -+header-y += vc4_drm.h - header-y += via_drm.h - header-y += vmwgfx_drm.h - header-y += msm_drm.h - -From 3472309b991f5f8c75a655d2f077a1eb632af3cf Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:05:00 -0800 -Subject: [PATCH 190/251] drm/vc4: Validate that WAIT_BO padding is cleared. - -This is ABI future-proofing if we ever want to extend the pad to mean -something. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 1243f4e..849d374 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -761,6 +761,9 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_gem_object *gem_obj; - struct vc4_bo *bo; - -+ if (args->pad != 0) -+ return -EINVAL; -+ - gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!gem_obj) { - DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); - -From fc63883845d0d69d746b00a54d8cf2aaf2db30a5 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 13:52:41 -0800 -Subject: [PATCH 191/251] drm/vc4: Fix the clear color for the first tile - rendered. - -Apparently in hardware (as opposed to simulation), the clear colors -need to be uploaded before the render config, otherwise they won't -take effect. Fixes igt's vc4_wait_bo/used-bo-* subtests. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_render_cl.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index 8a2a312..dea97f4 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -321,15 +321,6 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, - &exec->unref_list); - -- rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -- rcl_u32(setup, -- (setup->color_write ? (setup->color_write->paddr + -- args->color_write.offset) : -- 0)); -- rcl_u16(setup, args->width); -- rcl_u16(setup, args->height); -- rcl_u16(setup, args->color_write.bits); -- - /* The tile buffer gets cleared when the previous tile is stored. If - * the clear values changed between frames, then the tile buffer has - * stale clear values in it, so we have to do a store in None mode (no -@@ -349,6 +340,15 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - rcl_u32(setup, 0); /* no address, since we're in None mode */ - } - -+ rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG); -+ rcl_u32(setup, -+ (setup->color_write ? (setup->color_write->paddr + -+ args->color_write.offset) : -+ 0)); -+ rcl_u16(setup, args->width); -+ rcl_u16(setup, args->height); -+ rcl_u16(setup, args->color_write.bits); -+ - for (y = min_y_tile; y <= max_y_tile; y++) { - for (x = min_x_tile; x <= max_x_tile; x++) { - bool first = (x == min_x_tile && y == min_y_tile); - -From 6128659e9deeb8f7b15a0e8bb9e4e974afe39064 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:13:12 -0800 -Subject: [PATCH 192/251] drm/vc4: Return an ERR_PTR from BO creation instead - of NULL. - -Fixes igt vc4_create_bo/create-bo-0 by returning -EINVAL from the -ioctl instead of -ENOMEM. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_bo.c | 23 +++++++++++++---------- - drivers/gpu/drm/vc4/vc4_gem.c | 4 ++-- - drivers/gpu/drm/vc4/vc4_irq.c | 2 +- - drivers/gpu/drm/vc4/vc4_render_cl.c | 4 ++-- - drivers/gpu/drm/vc4/vc4_validate.c | 4 ++-- - 5 files changed, 20 insertions(+), 17 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c -index 6247ff8..8477579 100644 ---- a/drivers/gpu/drm/vc4/vc4_bo.c -+++ b/drivers/gpu/drm/vc4/vc4_bo.c -@@ -213,10 +213,10 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, - size_t size = roundup(unaligned_size, PAGE_SIZE); - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_gem_cma_object *cma_obj; -- int pass; -+ int pass, ret; - - if (size == 0) -- return NULL; -+ return ERR_PTR(-EINVAL); - - /* First, try to get a vc4_bo from the kernel BO cache. */ - if (from_cache) { -@@ -247,14 +247,17 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, - * unreferenced BOs to the cache, and then - * free the cache. - */ -- vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, true); -+ ret = vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, -+ true); -+ if (ret) -+ return ERR_PTR(ret); - vc4_job_handle_completed(vc4); - vc4_bo_cache_purge(dev); - break; - case 3: - DRM_ERROR("Failed to allocate from CMA:\n"); - vc4_bo_stats_dump(vc4); -- return NULL; -+ return ERR_PTR(-ENOMEM); - } - } - -@@ -276,8 +279,8 @@ int vc4_dumb_create(struct drm_file *file_priv, - args->size = args->pitch * args->height; - - bo = vc4_bo_create(dev, args->size, false); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); -@@ -460,8 +463,8 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, - * get zeroed, and that might leak data between users. - */ - bo = vc4_bo_create(dev, args->size, false); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); - drm_gem_object_unreference_unlocked(&bo->base.base); -@@ -513,8 +516,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, - } - - bo = vc4_bo_create(dev, args->size, true); -- if (!bo) -- return -ENOMEM; -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); - - ret = copy_from_user(bo->base.vaddr, - (void __user *)(uintptr_t)args->data, -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index 849d374..f8c003a 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -593,9 +593,9 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) - } - - bo = vc4_bo_create(dev, exec_size, true); -- if (!bo) { -+ if (IS_ERR(bo)) { - DRM_ERROR("Couldn't allocate BO for binning\n"); -- ret = PTR_ERR(exec->exec_bo); -+ ret = PTR_ERR(bo); - goto fail; - } - exec->exec_bo = &bo->base; -diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c -index b68060e..78a2135 100644 ---- a/drivers/gpu/drm/vc4/vc4_irq.c -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -57,7 +57,7 @@ vc4_overflow_mem_work(struct work_struct *work) - struct vc4_bo *bo; - - bo = vc4_bo_create(dev, 256 * 1024, true); -- if (!bo) { -+ if (IS_ERR(bo)) { - DRM_ERROR("Couldn't allocate binner overflow mem\n"); - return; - } -diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c -index dea97f4..0f12418 100644 ---- a/drivers/gpu/drm/vc4/vc4_render_cl.c -+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c -@@ -316,8 +316,8 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, - size += xtiles * ytiles * loop_body_size; - - setup->rcl = &vc4_bo_create(dev, size, true)->base; -- if (!setup->rcl) -- return -ENOMEM; -+ if (IS_ERR(setup->rcl)) -+ return PTR_ERR(setup->rcl); - list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, - &exec->unref_list); - -diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c -index 0fb5b99..8396960 100644 ---- a/drivers/gpu/drm/vc4/vc4_validate.c -+++ b/drivers/gpu/drm/vc4/vc4_validate.c -@@ -401,8 +401,8 @@ validate_tile_binning_config(VALIDATE_ARGS) - tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size, - true); - exec->tile_bo = &tile_bo->base; -- if (!exec->tile_bo) -- return -ENOMEM; -+ if (IS_ERR(exec->tile_bo)) -+ return PTR_ERR(exec->tile_bo); - list_add_tail(&tile_bo->unref_head, &exec->unref_list); - - /* tile alloc address. */ - -From e62f39b87fb3577d0c154ee50459a8d0b83865ca Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:32:41 -0800 -Subject: [PATCH 193/251] drm/vc4: Fix -ERESTARTSYS error return from BO waits. - -This caused the wait ioctls to claim that waiting had completed when -we actually got interrupted by a signal before it was done. Fixes -broken rendering throttling that produced serious lag in X window -dragging. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index f8c003a..dc3044d 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -352,12 +352,10 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, - finish_wait(&vc4->job_wait_queue, &wait); - trace_vc4_wait_for_seqno_end(dev, seqno); - -- if (ret && ret != -ERESTARTSYS) { -+ if (ret && ret != -ERESTARTSYS) - DRM_ERROR("timeout waiting for render thread idle\n"); -- return ret; -- } - -- return 0; -+ return ret; - } - - static void - -From 7942d03413ee330d2fb041dc62dabc8ce738cc0c Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 25 Jan 2016 14:33:50 -0800 -Subject: [PATCH 194/251] drm/vc4: Drop error message on seqno wait timeouts. - -These ioctls end up getting exposed to userspace, and having normal -user requests print DRM errors is obviously wrong. The message was -originally to give us some idea of what happened when a hang occurred, -but we have a DRM_INFO from reset for that. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_gem.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c -index dc3044d..a6fa63f 100644 ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -352,9 +352,6 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, - finish_wait(&vc4->job_wait_queue, &wait); - trace_vc4_wait_for_seqno_end(dev, seqno); - -- if (ret && ret != -ERESTARTSYS) -- DRM_ERROR("timeout waiting for render thread idle\n"); -- - return ret; - } - - -From 9ceac017a764704d9919a494590e8fea0e458adc Mon Sep 17 00:00:00 2001 -From: campag -Date: Wed, 24 Feb 2016 16:45:42 +0000 -Subject: [PATCH 195/251] BCM270X_DT: Add 1-bit SDIO using minimal pins... - -... for that mode: GPIOs 22-25. ---- - arch/arm/boot/dts/overlays/README | 21 ++++++++++++++ - arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts | 36 ++++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 4ce7921..7118510 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -709,6 +709,27 @@ Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - bus_width Set the SDIO host bus width (default 4 bits) - - -+Name: sdio-1bit -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -+ and enables 1-bit SDIO via GPIOs 22-25. -+Load: dtoverlay=sdio-1bit,= -+Params: overclock_50 SD Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ -+ sdio_overclock SDIO Clock (in MHz) to use when the MMC -+ framework requests 50MHz -+ -+ force_pio Disable DMA support (default off) -+ -+ pio_limit Number of blocks above which to use DMA -+ (default 1) -+ -+ debug Enable debug output (default off) -+ -+ poll_once Disable SDIO-device polling every second -+ (default on: polling once at boot-time) -+ -+ - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver - Load: dtoverlay=sdtweak,= -diff --git a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts -new file mode 100644 -index 0000000..46d4538 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts -@@ -0,0 +1,36 @@ -+/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ -+ -+/include/ "sdhost-overlay.dts" -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@3 { -+ target = <&mmc>; -+ sdio_mmc: __overlay__ { -+ compatible = "brcm,bcm2835-mmc"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ non-removable; -+ bus-width = <1>; -+ brcm,overclock-50 = <0>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ sdio_pins: sdio_pins { -+ brcm,pins = <22 23 24 25>; -+ brcm,function = <7 7 7 7>; /* ALT3 = SD1 */ -+ brcm,pull = <0 2 2 2>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ poll_once = <&sdio_mmc>,"non-removable?"; -+ sdio_overclock = <&sdio_mmc>,"brcm,overclock-50:0"; -+ }; -+}; - -From 6dd9dc84456f9341739f6c6d2c7d5b1f08d5c8fe Mon Sep 17 00:00:00 2001 -From: Cheong2K -Date: Fri, 26 Feb 2016 18:20:10 +0800 -Subject: [PATCH 196/251] brcm: adds support for BCM43341 wifi - ---- - drivers/net/wireless/brcm80211/brcmfmac/sdio.c | 5 +++++ - drivers/net/wireless/brcm80211/include/brcm_hw_ids.h | 1 + - 2 files changed, 6 insertions(+) - -diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -index 7e74ac3..818f756 100644 ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -613,6 +613,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { - #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" - #define BCM43340_FIRMWARE_NAME "brcm/brcmfmac43340-sdio.bin" - #define BCM43340_NVRAM_NAME "brcm/brcmfmac43340-sdio.txt" -+#define BCM43341_FIRMWARE_NAME "brcm/brcmfmac43341-sdio.bin" -+#define BCM43341_NVRAM_NAME "brcm/brcmfmac43341-sdio.txt" - #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" - #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" - #define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" -@@ -642,6 +644,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4334_NVRAM_NAME); - MODULE_FIRMWARE(BCM43340_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM43340_NVRAM_NAME); -+MODULE_FIRMWARE(BCM43341_FIRMWARE_NAME); -+MODULE_FIRMWARE(BCM43341_NVRAM_NAME); - MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); - MODULE_FIRMWARE(BCM4335_NVRAM_NAME); - MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); -@@ -679,6 +683,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { - { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, - { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, - { BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43340) }, -+ { BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43341) }, - { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, - { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, - { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, -diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -index aa06ea2..f3ae83d 100644 ---- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h -@@ -34,6 +34,7 @@ - #define BRCM_CC_4330_CHIP_ID 0x4330 - #define BRCM_CC_4334_CHIP_ID 0x4334 - #define BRCM_CC_43340_CHIP_ID 43340 -+#define BRCM_CC_43341_CHIP_ID 43341 - #define BRCM_CC_43362_CHIP_ID 43362 - #define BRCM_CC_4335_CHIP_ID 0x4335 - #define BRCM_CC_4339_CHIP_ID 0x4339 - -From 0702cbfdf586a8c1b67d28cdfc84a0623c8b12f1 Mon Sep 17 00:00:00 2001 -From: Michael Heimpold -Date: Fri, 29 Jan 2016 12:00:37 +0100 -Subject: [PATCH 197/251] Add overlay and enable support for QCA7000 board - -This adds a device tree overlay for the QCA7000 which can be used -when attaching an I2SE's PLC Stamp micro EVK to the Raspberry Pi. - -This Evaluation Board embeds a QCA7000 chip, a Homeplug Green PHY -powerline chip from Qualcomm/Atheros for the Internet of Things. - -This patch also enables the required QCA7000 driver module -in the default configurations. - -Signed-off-by: Stefan Wahren -Signed-off-by: Michael Heimpold ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - arch/arm/boot/dts/overlays/qca7000-overlay.dts | 52 ++++++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 63 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/qca7000-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4f3ca9c..f4ae95a 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -48,6 +48,7 @@ dtbo-$(RPI_DT_OVERLAYS) += pitft28-resistive.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pps-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pwm.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pwm-2chan.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += qca7000.dtbo - dtbo-$(RPI_DT_OVERLAYS) += raspidac3.dtbo - dtbo-$(RPI_DT_OVERLAYS) += rpi-backlight.dtbo - dtbo-$(RPI_DT_OVERLAYS) += rpi-dac.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 7118510..2a354b3 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -625,6 +625,14 @@ Params: pin Output pin (default 18) - see table - clock PWM clock frequency (informational) - - -+Name: qca7000 -+Info: I2SE's Evaluation Board for PLC Stamp micro -+Load: dtoverlay=qca7000,= -+Params: int_pin GPIO pin for interrupt signal (default 23) -+ -+ speed SPI bus speed (default 12 MHz) -+ -+ - Name: raspidac3 - Info: Configures the RaspiDAV Rev.3x audio card - Load: dtoverlay=raspidac3 -diff --git a/arch/arm/boot/dts/overlays/qca7000-overlay.dts b/arch/arm/boot/dts/overlays/qca7000-overlay.dts -new file mode 100644 -index 0000000..b4e6013 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts -@@ -0,0 +1,52 @@ -+// Overlay for the Qualcomm Atheros QCA7000 on I2SE's PLC Stamp micro EVK -+// Visit: https://www.i2se.com/product/plc-stamp-micro-evk for details -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0 { -+ status = "disabled"; -+ }; -+ -+ eth1: qca7000@0 { -+ compatible = "qca,qca7000"; -+ reg = <0>; /* CE0 */ -+ pinctrl-names = "default"; -+ pinctrl-0 = <ð1_pins>; -+ interrupt-parent = <&gpio>; -+ interrupts = <23 0x1>; /* rising edge */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ eth1_pins: eth1_pins { -+ brcm,pins = <23>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ int_pin = <ð1>, "interrupts:0", -+ <ð1_pins>, "brcm,pins:0"; -+ speed = <ð1>, "spi-max-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 0fff5a3..b63632d 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -446,6 +446,7 @@ CONFIG_NETCONSOLE=m - CONFIG_TUN=m - CONFIG_VETH=m - CONFIG_ENC28J60=m -+CONFIG_QCA7000=m - CONFIG_MDIO_BITBANG=m - CONFIG_PPP=m - CONFIG_PPP_BSDCOMP=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 74149cf..e720c74 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -439,6 +439,7 @@ CONFIG_NETCONSOLE=m - CONFIG_TUN=m - CONFIG_VETH=m - CONFIG_ENC28J60=m -+CONFIG_QCA7000=m - CONFIG_MDIO_BITBANG=m - CONFIG_PPP=m - CONFIG_PPP_BSDCOMP=m - -From 5fbc1847fdefcf563be0c51ffc07de6666036ba6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 9 Mar 2016 13:28:24 +0000 -Subject: [PATCH 198/251] serial: Take care starting a hung-up tty's port - -tty_port_hangup sets a port's tty field to NULL (holding the port lock), -but uart_tx_stopped, called from __uart_start (with the port lock), -uses the tty field without checking for NULL. - -Change uart_tx_stopped to treat a NULL tty field as another stopped -indication. - -Signed-off-by: Phil Elwell ---- - include/linux/serial_core.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h -index 297d4fa..00ce6c6 100644 ---- a/include/linux/serial_core.h -+++ b/include/linux/serial_core.h -@@ -397,7 +397,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); - static inline int uart_tx_stopped(struct uart_port *port) - { - struct tty_struct *tty = port->state->port.tty; -- if (tty->stopped || port->hw_stopped) -+ if (!tty || tty->stopped || port->hw_stopped) - return 1; - return 0; - } - -From b8127d80609179210ae5ceea4929391991dbce9a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Mar 2016 10:16:16 +0000 -Subject: [PATCH 199/251] pi3-miniuart-bt-overlay: Correct and clarify info - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 6 ++++-- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 6 ++++-- - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 2a354b3..b674394 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -511,8 +511,10 @@ Name: pi3-miniuart-bt - Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore - UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum - usable baudrate. -- N.B. It is also necessary to edit /lib/systemd/system/hciuart.server -- and replace ttyAMA0 with ttyS0. -+ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service -+ and replace ttyAMA0 with ttyS0, unless you have a system with udev rules -+ that create /dev/serial0 and /dev/serial1, in which case use -+ /dev/serial1 instead because it will always be correct. - Load: dtoverlay=pi3-miniuart-bt - Params: - -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index f07afcb..38ed33b 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -5,8 +5,10 @@ - UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum - usable baudrate. - -- It is also necessary to edit /lib/systemd/system/hciuart.server and -- replace ttyAMA0 with ttyS0. -+ It is also necessary to edit /lib/systemd/system/hciuart.service and -+ replace ttyAMA0 with ttyS0, unless you have a system with udev rules -+ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 -+ instead because it will always be correct. - - If cmdline.txt uses the alias serial0 to refer to the user-accessable port - then the firmware will replace with the appropriate port whether or not - -From ee65eba2fa76dc0ca35f2c74ec655f89d9d33b13 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 17 Mar 2016 10:41:56 +0000 -Subject: [PATCH 200/251] pwm overlays: Params must have in-overlay targets - ---- - arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts | 9 ++++++++- - arch/arm/boot/dts/overlays/pwm-overlay.dts | 9 ++++++++- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -index 957e1a4..18e4e4f 100644 ---- a/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pwm-2chan-overlay.dts -@@ -36,11 +36,18 @@ N.B.: - }; - }; - -+ fragment@2 { -+ target = <&clk_pwm>; -+ frag2: __overlay__ { -+ clock-frequency = <100000000>; -+ }; -+ }; -+ - __overrides__ { - pin = <&pwm_pins>,"brcm,pins:0"; - pin2 = <&pwm_pins>,"brcm,pins:4"; - func = <&pwm_pins>,"brcm,function:0"; - func2 = <&pwm_pins>,"brcm,function:4"; -- clock = <&clk_pwm>,"clock-frequency:0"; -+ clock = <&frag2>,"clock-frequency:0"; - }; - }; -diff --git a/arch/arm/boot/dts/overlays/pwm-overlay.dts b/arch/arm/boot/dts/overlays/pwm-overlay.dts -index ddd67ff..bf030a6 100644 ---- a/arch/arm/boot/dts/overlays/pwm-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pwm-overlay.dts -@@ -34,9 +34,16 @@ N.B.: - }; - }; - -+ fragment@2 { -+ target = <&clk_pwm>; -+ frag2: __overlay__ { -+ clock-frequency = <100000000>; -+ }; -+ }; -+ - __overrides__ { - pin = <&pwm_pins>,"brcm,pins:0"; - func = <&pwm_pins>,"brcm,function:0"; -- clock = <&clk_pwm>,"clock-frequency:0"; -+ clock = <&frag2>,"clock-frequency:0"; - }; - }; - -From 62279457d4e5c3a132a0c8fe60c0d9c51c3edd9d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 18 Mar 2016 13:06:29 +0000 -Subject: [PATCH 201/251] BCM270X_DT: Switch Compute Module to MMC - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index e09e499..90e330d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -8,9 +8,9 @@ - }; - - &gpio { -- sdhost_pins: sdhost_pins { -+ mmc_pins: mmc_pins { - brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <4>; /* alt0 */ -+ brcm,function = <7>; /* alt3 */ - }; - }; - -@@ -22,12 +22,14 @@ - }; - }; - --&sdhost { -+ -+&mmc { - pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -- bus-width = <4>; -+ pinctrl-0 = <&mmc_pins>; - non-removable; -+ bus-width = <4>; - status = "okay"; -+ brcm,overclock-50 = <0>; - }; - - &fb { -@@ -45,9 +47,6 @@ - audio = <&audio>,"status"; - watchdog = <&watchdog>,"status"; - random = <&random>,"status"; -- sd_overclock = <&sdhost>,"brcm,overclock-50:0"; -- sd_force_pio = <&sdhost>,"brcm,force-pio?"; -- sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; -- sd_debug = <&sdhost>,"brcm,debug"; -+ sd_overclock = <&mmc>,"brcm,overclock-50:0"; - }; - }; - -From 82ecf79397939c59b5b50cd683b823e1233568f7 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Fri, 18 Mar 2016 17:38:37 +0000 -Subject: [PATCH 202/251] dwc_otg: Don't free qh align buffers in atomic - context - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -index acd0dd7..3b2a607 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -56,6 +56,9 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) - { - dwc_otg_qtd_t *qtd, *qtd_tmp; - dwc_irqflags_t flags; -+ uint32_t buf_size = 0; -+ uint8_t *align_buf_virt = NULL; -+ dwc_dma_t align_buf_dma; - - /* Free each QTD in the QTD list */ - DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); -@@ -67,17 +70,19 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) - if (hcd->core_if->dma_desc_enable) { - dwc_otg_hcd_qh_free_ddma(hcd, qh); - } else if (qh->dw_align_buf) { -- uint32_t buf_size; - if (qh->ep_type == UE_ISOCHRONOUS) { - buf_size = 4096; - } else { - buf_size = hcd->core_if->core_params->max_transfer_size; - } -- DWC_DMA_FREE(buf_size, qh->dw_align_buf, qh->dw_align_buf_dma); -+ align_buf_virt = qh->dw_align_buf; -+ align_buf_dma = qh->dw_align_buf_dma; - } - - DWC_FREE(qh); - DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); -+ if (align_buf_virt) -+ DWC_DMA_FREE(buf_size, align_buf_virt, align_buf_dma); - return; - } - - -From 6e02745d8e2fc480d3442e6adaf4547e100611b5 Mon Sep 17 00:00:00 2001 +From a4862ba9bf7e56d3c2e8556c19eda52fc0f6b9c4 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Mon, 21 Mar 2016 15:38:38 +0000 -Subject: [PATCH 203/251] dwc_otg: Enable the hack for Split Interrupt - transactions by default +Date: Thu, 31 Mar 2016 16:49:52 +0100 +Subject: [PATCH 097/114] config: Enabled IPV6_SUBTREES -dwc_otg.fiq_fsm_mask=0xF has long been a suggestion for users with audio stutters or other USB bandwidth issues. -So far we are aware of many success stories but no failure caused by this setting. -Make it a default to learn more. - -See: https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=70437 - -Signed-off-by: popcornmix --- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 177745a..2536c11 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -106,6 +106,7 @@ CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m + CONFIG_IPV6_TUNNEL=m + CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IPV6_MROUTE=y + CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y + CONFIG_IPV6_PIMSM_V2=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0b87299..bfb6936 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -73,6 +73,7 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IP_ROUTE_MULTIPATH=y + CONFIG_IP_ROUTE_VERBOSE=y + CONFIG_IP_PNP=y + +From 042c70e53211e4062dff7ddf59a7b360b5370736 Mon Sep 17 00:00:00 2001 +From: Slawomir Stepien +Date: Sun, 3 Apr 2016 13:11:58 +0200 +Subject: [PATCH 098/114] [media]: bcm2835-camera: fix compilation error + +There is an error when compiling rpi-4.6.y branch: + CC [M] drivers/media/platform/bcm2835/bcm2835-camera.o +drivers/media/platform/bcm2835/bcm2835-camera.c:639:17: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] + .queue_setup = queue_setup, + ^ +drivers/media/platform/bcm2835/bcm2835-camera.c:639:17: note: (near initialization for 'bm2835_mmal_video_qops.queue_setup') + +The const void *parg in setup_queue callback is not needed since commit: +df9ecb0cad14b952a2865f8b3af86b2bbadfab45. +This commit removes it. + +Signed-off-by: Slawomir Stepien +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index 95edadf..cb060a7 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -247,7 +247,7 @@ bool fiq_fsm_enable = true; - //Bulk split-transaction NAK holdoff in microframes - uint16_t nak_holdoff = 8; +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index fbf89a2..fd20d1e 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -236,7 +236,7 @@ static struct mmal_fmt *get_format(struct v4l2_format *f) + Videobuf queue operations + ------------------------------------------------------------------*/ --unsigned short fiq_fsm_mask = 0x07; -+unsigned short fiq_fsm_mask = 0x0F; - - /** - * This function shows the Driver Version. +-static int queue_setup(struct vb2_queue *vq, const void *parg, ++static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], void *alloc_ctxs[]) + { -From 6a2fc8f71762aab14aee7311f8b7cd94aa316773 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 19 Mar 2016 16:51:37 +0000 -Subject: [PATCH 204/251] BCM270X_DT: Remove explicit claiming of UART pins +From 7eb6433554a5b01c7aded991216424b7c3a0561c Mon Sep 17 00:00:00 2001 +From: Slawomir Stepien +Date: Sun, 3 Apr 2016 18:59:57 +0200 +Subject: [PATCH 099/114] DT configfs: fix build error -It is convenient to be able to map a different function to the UART -pins (e.g. DPI for vga666) without having to disable the UART first. +There is an error when compiling rpi-4.6.y branch: + CC drivers/of/configfs.o +drivers/of/configfs.c:291:21: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] + .default_groups = of_cfs_def_groups, + ^ +drivers/of/configfs.c:291:21: note: (near initialization for 'of_cfs_subsys.su_group.default_groups.next') -Signed-off-by: Phil Elwell +The .default_groups is linked list since commit +1ae1602de028acaa42a0f6ff18d19756f8e825c6. +This commit uses configfs_add_default_group to fix this problem. + +Signed-off-by: Slawomir Stepien --- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 6 +++--- - .../boot/dts/overlays/pi3-disable-bt-overlay.dts | 10 ++++----- - .../boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 25 +++++++++++----------- - 3 files changed, 20 insertions(+), 21 deletions(-) + drivers/of/configfs.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -index d2d39c6..adba682 100644 ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -57,9 +57,9 @@ - }; +diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c +index 168b9d3..68f889d 100644 +--- a/drivers/of/configfs.c ++++ b/drivers/of/configfs.c +@@ -277,18 +277,12 @@ static struct config_item_type of_cfs_type = { - uart1_pins: uart1_pins { -- brcm,pins = <14 15>; -- brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 2>; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; + struct config_group of_cfs_overlay_group; -diff --git a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -index 05403e2..68f6069 100644 ---- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -28,13 +28,11 @@ - }; - - fragment@2 { -- target = <&gpio>; -+ target = <&uart0_pins>; - __overlay__ { -- uart0_pins: uart0_pins { -- brcm,pins = <14 15>; -- brcm,function = <4>; /* alt0 */ -- brcm,pull = <0 2>; -- }; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; - -diff --git a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -index 38ed33b..17d04cf 100644 ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -37,23 +37,24 @@ - }; - - fragment@2 { -- target = <&gpio>; -+ target = <&uart0_pins>; - __overlay__ { -- uart0_pins: uart0_pins { -- brcm,pins = <14 15>; -- brcm,function = <4>; /* alt0 */ -- brcm,pull = <0 2>; -- }; +-struct config_group *of_cfs_def_groups[] = { +- &of_cfs_overlay_group, +- NULL +-}; - -- uart1_pins: uart1_pins { -- brcm,pins = <32 33>; -- brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 2>; -- }; -+ brcm,pins; -+ brcm,function; -+ brcm,pull; - }; - }; + static struct configfs_subsystem of_cfs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "device-tree", + .ci_type = &of_cfs_type, + }, +- .default_groups = of_cfs_def_groups, + }, + .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), + }; +@@ -302,6 +296,8 @@ static int __init of_cfs_init(void) + config_group_init(&of_cfs_subsys.su_group); + config_group_init_type_name(&of_cfs_overlay_group, "overlays", + &overlays_type); ++ configfs_add_default_group(&of_cfs_overlay_group, ++ &of_cfs_subsys.su_group); - fragment@3 { -+ target = <&uart1_pins>; -+ __overlay__ { -+ brcm,pins = <32 33>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ -+ fragment@4 { - target-path = "/aliases"; - __overlay__ { - serial0 = "/soc/uart@7e201000"; + ret = configfs_register_subsystem(&of_cfs_subsys); + if (ret != 0) { -From 403390e94d98b9f7b6f41397b04b2f29900cdcb0 Mon Sep 17 00:00:00 2001 -From: Rodrigo Freire -Date: Tue, 22 Mar 2016 12:40:33 -0300 -Subject: [PATCH 205/251] lirc_rpi: Lower IR reception error to debug +From 851b603db5ec7c276c4219ac92c0b085abb90f00 Mon Sep 17 00:00:00 2001 +From: dienet +Date: Wed, 13 Apr 2016 19:07:46 +0200 +Subject: [PATCH 100/114] vchiq_arm: do not use page_cache_release(page) macro + (#1403) -Lowers a IR reception error condition message to KERNEL_DEBUG +This macro is gone since 1fa64f198b9f8d6ec0f7aec7c18dc94684391140. + +Signed-off-by: Slawomir Stepien --- - drivers/staging/media/lirc/lirc_rpi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index cd09c99..0624439 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -271,7 +271,7 @@ static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) - data = PULSE_MASK; /* really long time */ - if (!(signal^sense)) { - /* sanity check */ -- printk(KERN_WARNING LIRC_DRIVER_NAME -+ printk(KERN_DEBUG LIRC_DRIVER_NAME - ": AIEEEE: %d %d %lx %lx %lx %lx\n", - signal, sense, tv.tv_sec, lasttv.tv_sec, - tv.tv_usec, lasttv.tv_usec); - -From 0fb8769fe60a8bba6f871ff6d91a04fb7950b67d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 14:16:25 +0000 -Subject: [PATCH 206/251] vchiq_arm: Access the dequeue_pending flag locked - -Reading through this code looking for another problem (now found in userland) -the use of dequeue_pending outside a lock didn't seem safe. - -Signed-off-by: Phil Elwell ---- - .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 4 ++-- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index c29040f..705c055 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -439,7 +439,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, + while (actual_pages > 0) + { + actual_pages--; +- page_cache_release(pages[actual_pages]); ++ put_page(pages[actual_pages]); + } + kfree(pagelist); + if (actual_pages == 0) +@@ -578,7 +578,7 @@ free_pagelist(PAGELIST_T *pagelist, int actual) + offset = 0; + set_page_dirty(pg); + } +- page_cache_release(pg); ++ put_page(pg); + } + } + diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index e11c0e0..71883e5 100644 +index a5cc385..dd62676 100644 --- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -279,6 +279,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - USER_SERVICE_T *user_service; - VCHIQ_SERVICE_T *service; - VCHIQ_INSTANCE_T instance; -+ int skip_completion = 0; +@@ -1520,7 +1520,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) + kunmap(page); + + for (page_idx = 0; page_idx < num_pages; page_idx++) +- page_cache_release(pages[page_idx]); ++ put_page(pages[page_idx]); + + kfree(pages); + } + +From ba7d03eecfa21c6dc350b236beaad715acac723f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 18 Apr 2016 23:00:31 +0100 +Subject: [PATCH 101/114] vchiq: Upate to match get_user_pages prototype + +--- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 3 +-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index 705c055..4cb5bff 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -420,7 +420,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, + *need_release = 0; /* do not try and release vmalloc pages */ + } else { + down_read(&task->mm->mmap_sem); +- actual_pages = get_user_pages(task, task->mm, ++ actual_pages = get_user_pages( + (unsigned long)buf & ~(PAGE_SIZE - 1), + num_pages, + (type == PAGELIST_READ) /*Write */ , +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +index dd62676..a76060c 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -1480,8 +1480,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes) + } + + down_read(¤t->mm->mmap_sem); +- rc = get_user_pages(current, /* task */ +- current->mm, /* mm */ ++ rc = get_user_pages( + (unsigned long)virt_addr, /* start */ + num_pages, /* len */ + 0, /* write */ + +From 0ae92b6f6101216e8f6aa5d68b9adad458e91ae7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 21 Apr 2016 13:49:32 +0100 +Subject: [PATCH 102/114] vchiq_arm: Add completion records under the mutex + +An issue was observed when flushing openmax components +which generate a large number of messages returning +buffers to host. + +We occasionally found a duplicate message from 16 +messages prior, resulting in a buffer returned twice. + +While only one thread adds completions, without the +mutex you don't get the protection of the automatic +memory barrier you get with synchronisation objects. + +Signed-off-by: Phil Elwell +--- + drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +index a76060c..51e6018 100644 +--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + VCHIQ_COMPLETION_DATA_T *completion; DEBUG_INITIALISE(g_state.local) - DEBUG_TRACE(SERVICE_CALLBACK_LINE); -@@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - user_service->msg_queue[user_service->msg_insert & - (MSG_QUEUE_SIZE - 1)] = header; - user_service->msg_insert++; -- spin_unlock(&msg_queue_spinlock); -- -- up(&user_service->insert_event); - - /* If there is a thread waiting in DEQUEUE_MESSAGE, or if - ** there is a MESSAGE_AVAILABLE in the completion queue then -@@ -356,13 +354,22 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, - if (((user_service->message_available_pos - - instance->completion_remove) >= 0) || - user_service->dequeue_pending) { -- DEBUG_TRACE(SERVICE_CALLBACK_LINE); - user_service->dequeue_pending = 0; -- return VCHIQ_SUCCESS; -+ skip_completion = 1; - } - -+ spin_unlock(&msg_queue_spinlock); ++ mutex_lock(&instance->completion_mutex); + -+ up(&user_service->insert_event); + while (instance->completion_insert == + (instance->completion_remove + MAX_COMPLETIONS)) { + /* Out of space - wait for the client */ +@@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + vchiq_log_trace(vchiq_arm_log_level, + "add_completion - completion queue full"); + DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); + - header = NULL; - } ++ mutex_unlock(&instance->completion_mutex); + if (down_interruptible(&instance->remove_event) != 0) { + vchiq_log_info(vchiq_arm_log_level, + "service_callback interrupted"); + return VCHIQ_RETRY; +- } else if (instance->closing) { ++ } + -+ if (skip_completion) { -+ DEBUG_TRACE(SERVICE_CALLBACK_LINE); -+ return VCHIQ_SUCCESS; -+ } -+ - DEBUG_TRACE(SERVICE_CALLBACK_LINE); - - return add_completion(instance, reason, header, user_service, - -From 797c1c2110ba155df9fbdb44a7c052f7beeb0a50 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 15:57:14 +0000 -Subject: [PATCH 207/251] BCM270X_DT: Add pi3-act-led overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 19 +++++++++++++++ - arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 27 ++++++++++++++++++++++ - 3 files changed, 47 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index f4ae95a..4c3db73 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -39,6 +39,7 @@ dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can0.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mcp2515-can1.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mmc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += mz61581.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += pi3-act-led.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pi3-disable-bt.dtbo - dtbo-$(RPI_DT_OVERLAYS) += pi3-miniuart-bt.dtbo - dtbo-$(RPI_DT_OVERLAYS) += piscreen.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index b674394..9b49868 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -136,12 +136,14 @@ Params: - - act_led_activelow Set to "on" to invert the sense of the LED - (default "off") -+ N.B. For Pi3 see pi3-act-led overlay. - - act_led_gpio Set which GPIO to use for the activity LED - (in case you want to connect it to an external - device) - (default "16" on a non-Plus board, "47" on a - Plus or Pi 2) -+ N.B. For Pi3 see pi3-act-led overlay. - - pwr_led_trigger - pwr_led_activelow -@@ -499,6 +501,23 @@ Params: speed Display SPI bus speed - [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] - - -+Name: pi3-act-led -+Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -+ from the VPU. There is a special driver for this with a separate DT -+ node, which has the unfortunate consequence of breaking the -+ act_led_gpio and act_led_activelow dtparams. -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+Load: dtoverlay=pi3-act-led,= -+Params: activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ REQUIRED -+ -+ - Name: pi3-disable-bt - Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 - N.B. To disable the systemd service that initialises the modem so it -diff --git a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -new file mode 100644 -index 0000000..14a59dc ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -+ from the VPU. There is a special driver for this with a separate DT node, -+ which has the unfortunate consequence of breaking the act_led_gpio and -+ act_led_activelow dtparams. -+ -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+*/ -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&act_led>; -+ frag0: __overlay__ { -+ gpios = <&gpio 0 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio = <&frag0>,"gpios:4"; -+ activelow = <&frag0>,"gpios:8"; -+ }; -+}; - -From 6de376456d86ba0211a2e8c10cf50fda9f3b6e20 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Mar 2016 20:53:47 +0000 -Subject: [PATCH 208/251] vchiq_arm: Service callbacks must not fail - -Service callbacks are not allowed to return an error. The internal callback -that delivers events and messages to user tasks does not enqueue them if -the service is closing, but this is not an error and should not be -reported as such. - -Signed-off-by: Phil Elwell ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 71883e5..a5cc385 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -224,7 +224,7 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - } else if (instance->closing) { ++ mutex_lock(&instance->completion_mutex); ++ if (instance->closing) { ++ mutex_unlock(&instance->completion_mutex); vchiq_log_info(vchiq_arm_log_level, "service_callback closing"); -- return VCHIQ_ERROR; -+ return VCHIQ_SUCCESS; - } - DEBUG_TRACE(SERVICE_CALLBACK_LINE); - } - -From 4793b34f7a3f71b1acfcd769b8d25fdcbb01b2cd Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Thu, 17 Mar 2016 18:16:16 +0000 -Subject: [PATCH 209/251] Add configs and overlay for PCA9548 I2C mux - -Adds kernel configs for I2C muxes and a dt overlay for PCA9548 -that adds the 8 muxed I2C buses and mux device. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++ - .../boot/dts/overlays/i2c-mux-pca9548a-overlay.dts | 67 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - 5 files changed, 78 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 4c3db73..7c4fc30 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hy28a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9b49868..a9b1ff5 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -360,6 +360,12 @@ Params: i2c_gpio_sda GPIO used for I2C data (default "23") - (default "2" = ~100kHz) + return VCHIQ_SUCCESS; +@@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, + if (reason == VCHIQ_MESSAGE_AVAILABLE) + user_service->message_available_pos = + instance->completion_insert; ++ + instance->completion_insert++; ++ mutex_unlock(&instance->completion_mutex); ++ + up(&instance->insert_event); -+Name: i2c-mux-pca9548a -+Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm -+Load: dtoverlay=i2c-mux-pca9548a,= -+Params: addr I2C address of PCA9548A (default 0x70) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= -diff --git a/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts -new file mode 100644 -index 0000000..1729fd6 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-mux-pca9548a-overlay.dts -@@ -0,0 +1,67 @@ -+// Definitions for NXP PCA9548A I2C mux on ARM I2C bus. -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ i2cmux: mux@70 { -+ compatible = "nxp,pca9548"; -+ reg = <0x70>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ }; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ }; -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ }; -+ i2c@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ }; -+ i2c@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ }; -+ i2c@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ }; -+ i2c@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ }; -+ }; -+ }; -+ }; -+ __overrides__ { -+ addr = <&i2cmux>,"reg:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index b63632d..2c8e4b7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -600,6 +600,8 @@ CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m -+CONFIG_I2C_MUX=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e720c74..f6e2d84 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -593,6 +593,8 @@ CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m -+CONFIG_I2C_MUX=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m + return VCHIQ_SUCCESS; -From 77700bbcd5dc6285892ea67acba46e45c3341b66 Mon Sep 17 00:00:00 2001 -From: Nicolas Boullis -Date: Wed, 23 Mar 2016 23:40:15 +0100 -Subject: [PATCH 210/251] BCM270X_DT: Add DS1339 to i2c-rtc overlay - ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 8 ++++++++ - 2 files changed, 12 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index a9b1ff5..e88e7c8 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -371,6 +371,8 @@ Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= - Params: ds1307 Select the DS1307 device - -+ ds1339 Select the DS1339 device -+ - ds3231 Select the DS3231 device - - mcp7941x Select the MCP7941x device -@@ -381,6 +383,8 @@ Params: ds1307 Select the DS1307 device - - pcf8563 Select the PCF8563 device - -+ trickle-resistor-ohms Resistor value for trickle charge (DS1339-only) -+ - - Name: i2c0-bcm2708 - Info: Enable the i2c_bcm2708 driver for the i2c0 bus -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index fed4bd8..eecec16 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -17,6 +17,12 @@ - reg = <0x68>; - status = "disable"; - }; -+ ds1339: ds1339@68 { -+ compatible = "dallas,ds1339"; -+ trickle-resistor-ohms = <0>; -+ reg = <0x68>; -+ status = "disable"; -+ }; - mcp7941x: mcp7941x@6f { - compatible = "microchip,mcp7941x"; - reg = <0x6f>; -@@ -46,10 +52,12 @@ - }; - __overrides__ { - ds1307 = <&ds1307>,"status"; -+ ds1339 = <&ds1339>,"status"; - ds3231 = <&ds3231>,"status"; - mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - pcf8563 = <&pcf8563>,"status"; -+ trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0"; - }; - }; - -From c17b3228544635d56826292c0989d2e944917148 Mon Sep 17 00:00:00 2001 +From b203738cc5b4bd877e5f1db0d3e745b5865507aa Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Tue, 29 Mar 2016 15:32:30 +0100 -Subject: [PATCH 211/251] copy_from_user: CPU_SW_DOMAIN_PAN compatibility +Date: Thu, 21 Apr 2016 15:44:14 +0100 +Subject: [PATCH 103/114] bcm2835-i2s: Reduce the TX DREQ threshold -The downstream copy_from_user acceleration must also play nice with -CONFIG_CPU_SW_DOMAIN_PAN. +TX FIFO overrun is thought to be the cause of channel swapping, so +reducing the DREQ threshold seems reasonable and appears to be +effective. -See: https://github.com/raspberrypi/linux/issues/1381 +See: https://github.com/raspberrypi/linux/issues/1417 Signed-off-by: Phil Elwell --- - arch/arm/lib/uaccess_with_memcpy.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) + sound/soc/bcm/bcm2835-i2s.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) -diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c -index c29df92..6681df5 100644 ---- a/arch/arm/lib/uaccess_with_memcpy.c -+++ b/arch/arm/lib/uaccess_with_memcpy.c -@@ -186,6 +186,7 @@ out: - unsigned long noinline - __copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) - { -+ unsigned long ua_flags; - int atomic; +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index c7f3fc7..8064e3f 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -403,15 +403,22 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, - if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { -@@ -217,7 +218,9 @@ __copy_from_user_memcpy(void *to, const void __user *from, unsigned long n) - if (tocopy > n) - tocopy = n; + /* Setup the DMA parameters */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, +- BCM2835_I2S_RXTHR(1) +- | BCM2835_I2S_TXTHR(1) +- | BCM2835_I2S_DMAEN, 0xffffffff); ++ BCM2835_I2S_RXTHR(3) ++ | BCM2835_I2S_TXTHR(3) ++ | BCM2835_I2S_DMAEN, ++ BCM2835_I2S_RXTHR(1) ++ | BCM2835_I2S_TXTHR(1) ++ | BCM2835_I2S_DMAEN); -+ ua_flags = uaccess_save_and_enable(); - memcpy(to, (const void *)from, tocopy); -+ uaccess_restore(ua_flags); - to += tocopy; - from += tocopy; - n -= tocopy; -@@ -261,9 +264,14 @@ arm_copy_from_user(void *to, const void __user *from, unsigned long n) - * With frame pointer disabled, tail call optimization kicks in - * as well making this test almost invisible. - */ -- if (n < COPY_FROM_USER_THRESHOLD) -- return __copy_from_user_std(to, from, n); -- return __copy_from_user_memcpy(to, from, n); -+ if (n < COPY_TO_USER_THRESHOLD) { -+ unsigned long ua_flags = uaccess_save_and_enable(); -+ n = __copy_from_user_std(to, from, n); -+ uaccess_restore(ua_flags); -+ } else { -+ n = __copy_from_user_memcpy(to, from, n); -+ } -+ return n; - } - - static unsigned long noinline + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, +- BCM2835_I2S_TX_PANIC(0x10) +- | BCM2835_I2S_RX_PANIC(0x30) +- | BCM2835_I2S_TX(0x30) +- | BCM2835_I2S_RX(0x20), 0xffffffff); ++ BCM2835_I2S_TX_PANIC(0x7f) ++ | BCM2835_I2S_RX_PANIC(0x7f) ++ | BCM2835_I2S_TX(0x7f) ++ | BCM2835_I2S_RX(0x7f), ++ BCM2835_I2S_TX_PANIC(0x10) ++ | BCM2835_I2S_RX_PANIC(0x30) ++ | BCM2835_I2S_TX(0x20) ++ | BCM2835_I2S_RX(0x20)); + + /* Clear FIFOs */ + bcm2835_i2s_clear_fifos(dev, true, true); -From 6abb732a5e79d2ab8384b6b70fd17e5347f59d0e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 16:33:09 +0100 -Subject: [PATCH 212/251] bcm2835-sdhost: Adjust to core clock changes - -The SDHOST block uses the core clock, so previously it has been -necessary to prevent the core clock from changing in order to maintain -performance and prevent accidental SD bus overclocking. - -With this patch the sdhost driver is notified of clock changes, allowing -it to delay them while an SD access is outstanding and to delay new SD -accesses while the clock is changing. This feature is disabled in the -case where the core frequency can never change. - -Now that the driver copes with changes to the core clock, it is safe -to disable the io_is_busy feature of the on-demand governor. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/Kconfig | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++++++++++++++++++++++++++++------ - 2 files changed, 119 insertions(+), 22 deletions(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index d509d10..98a7fa5 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -36,6 +36,7 @@ config MMC_BCM2835_PIO_DMA_BARRIER - config MMC_BCM2835_SDHOST - tristate "Support for the SDHost controller on BCM2708/9" - depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ depends on RASPBERRYPI_FIRMWARE - help - This selects the SDHost controller on BCM2835/6. - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index f43aae0..1deecef 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -50,6 +50,10 @@ - #include - #include - #include -+#include -+#include -+#include -+ - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -136,6 +140,8 @@ - - #define MHZ 1000000 - -+#define RPI_FIRMWARE_CLOCK_CORE 4 -+ - - struct bcm2835_host { - spinlock_t lock; -@@ -151,7 +157,9 @@ struct bcm2835_host { - - bool slow_card; /* Force 11-bit divisor */ - -- unsigned int max_clk; /* Max possible freq */ -+ unsigned int max_clk; /* Max src clock freq */ -+ unsigned int min_clk; /* Min src clock freq */ -+ unsigned int cur_clk; /* Current src clock freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -183,6 +191,7 @@ struct bcm2835_host { - unsigned int use_sbc:1; /* Send CMD23 */ - - unsigned int debug:1; /* Enable debug output */ -+ unsigned int variable_clock:1; /* The core clock may change */ - - /*DMA part*/ - struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -@@ -208,6 +217,9 @@ struct bcm2835_host { - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -+ -+ struct notifier_block cpufreq_nb; /* The cpufreq callback list item */ -+ struct semaphore cpufreq_semaphore; /* Interlock between SD activity and cpufreq changes */ - }; - - #if ENABLE_LOG -@@ -227,6 +239,10 @@ static u32 sdhost_log_idx; - static spinlock_t log_lock; - static void __iomem *timer_base; - -+static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -+ unsigned long action, void *data); -+static unsigned int get_core_clock(unsigned int mode); -+ - #define LOG_ENTRIES (256*1) - #define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) - -@@ -448,20 +464,14 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - --static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -+static void bcm2835_sdhost_init(struct bcm2835_host *host) - { -- pr_debug("bcm2835_sdhost_init(%d)\n", soft); -+ pr_debug("bcm2835_sdhost_init()\n"); - - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - - bcm2835_sdhost_reset_internal(host); -- -- if (soft) { -- /* force clock reconfiguration */ -- host->clock = 0; -- bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -- } - } - - static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) -@@ -1499,10 +1509,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ -- unsigned int input_clock = clock; -+ unsigned int clock = host->clock; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1543,17 +1553,17 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - return; - } - -- div = host->max_clk / clock; -+ div = host->cur_clk / clock; - if (div < 2) - div = 2; -- if ((host->max_clk / div) > clock) -+ if ((host->cur_clk / div) > clock) - div++; - div -= 2; - - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- clock = host->max_clk / (div + 2); -+ clock = host->cur_clk / (div + 2); - host->mmc->actual_clock = clock; - - /* Calibrate some delays */ -@@ -1561,7 +1571,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - host->ns_per_fifo_word = (1000000000/clock) * - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); - -- if (clock > input_clock) { -+ if (clock > host->clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ - host->overclock_50 = (clock/MHZ); -@@ -1587,9 +1597,9 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) -- pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), input_clock, -- host->max_clk, host->cdiv, host->mmc->actual_clock); -+ pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->cur_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1638,6 +1648,13 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - (mrq->data->blocks > host->pio_limit)) - bcm2835_sdhost_prepare_dma(host, mrq->data); - -+ if (host->variable_clock && -+ (down_killable(&host->cpufreq_semaphore) != 0)) { -+ mrq->cmd->error = -EINTR; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1687,6 +1704,52 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - spin_unlock_irqrestore(&host->lock, flags); - } - -+static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -+ unsigned long action, void *data) -+{ -+ struct cpufreq_freqs *freq = data; -+ struct bcm2835_host *host; -+ -+ host = container_of(nb, struct bcm2835_host, cpufreq_nb); -+ -+ if (freq->cpu == 0) { -+ switch (action) { -+ case CPUFREQ_PRECHANGE: -+ if (down_killable(&host->cpufreq_semaphore) != 0) -+ return NOTIFY_BAD; -+ break; -+ case CPUFREQ_POSTCHANGE: -+ if (freq->new > freq->old) -+ host->cur_clk = host->max_clk; -+ else -+ host->cur_clk = host->min_clk; -+ bcm2835_sdhost_set_clock(host); -+ up(&host->cpufreq_semaphore); -+ break; -+ default: -+ break; -+ } -+ } -+ return NOTIFY_OK; -+} -+ -+static unsigned int get_core_clock(unsigned int mode) -+{ -+ struct rpi_firmware *fw = rpi_firmware_get(NULL); -+ struct { -+ u32 id; -+ u32 val; -+ } packet; -+ int ret; -+ -+ packet.id = RPI_FIRMWARE_CLOCK_CORE; -+ ret = rpi_firmware_property(fw, mode, &packet, sizeof(packet)); -+ if (ret) -+ return 0; -+ -+ return packet.val; -+} -+ - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { - -@@ -1700,13 +1763,16 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -+ if (ios->clock && !host->cur_clk) -+ host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ - spin_lock_irqsave(&host->lock, flags); - - log_event("IOS<", ios->clock, 0); - - if (!ios->clock || ios->clock != host->clock) { -- bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -+ bcm2835_sdhost_set_clock(host); - } - - /* set bus width */ -@@ -1795,7 +1861,7 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); -- bcm2835_sdhost_set_clock(host,50*MHZ); -+ bcm2835_sdhost_set_clock(host); - mrq->cmd->error = -EILSEQ; - mrq->cmd->retries = 1; - } -@@ -1813,6 +1879,9 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - spin_unlock_irqrestore(&host->lock, flags); - -+ if (host->variable_clock) -+ up(&host->cpufreq_semaphore); -+ - if (terminate_chan) - { - int err = dmaengine_terminate_all(terminate_chan); -@@ -1915,10 +1984,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - -- bcm2835_sdhost_init(host, 0); -+ bcm2835_sdhost_init(host); - - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -- mmc_hostname(mmc), host); -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -1953,6 +2022,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -+ unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2062,6 +2132,28 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - if (ret) - goto err; - -+ /* Query the core clock frequencies */ -+ host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); -+ if (max_clk != host->max_clk) { -+ pr_warn("%s: Expected max clock %d, found %d\n", -+ mmc_hostname(mmc), host->max_clk, max_clk); -+ host->max_clk = max_clk; -+ } -+ -+ if (host->min_clk != host->max_clk) { -+ host->cpufreq_nb.notifier_call = -+ bcm2835_sdhost_cpufreq_callback; -+ sema_init(&host->cpufreq_semaphore, 1); -+ cpufreq_register_notifier(&host->cpufreq_nb, -+ CPUFREQ_TRANSITION_NOTIFIER); -+ host->variable_clock = 1; -+ host->cur_clk = 0; /* Get this later */ -+ } else { -+ host->variable_clock = 0; -+ host->cur_clk = host->max_clk; -+ } -+ - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); -@@ -2081,6 +2173,10 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - - pr_debug("bcm2835_sdhost_remove\n"); - -+ if (host->variable_clock) -+ cpufreq_unregister_notifier(&host->cpufreq_nb, -+ CPUFREQ_TRANSITION_NOTIFIER); -+ - mmc_remove_host(host->mmc); - - bcm2835_sdhost_set_power(host, false); - -From 788985576c5b7f413466d4ea5e1b9c471ff2b7fc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 17:07:15 +0100 -Subject: [PATCH 213/251] BCM270X_DT: Document hazards of sdhost overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index e88e7c8..337be4a 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -712,7 +712,11 @@ Params: - - - Name: sdhost --Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock. -+ N.B. This overlay is designed for situations where the mmc driver is -+ the default, so it disables the other (mmc) interface - this will kill -+ WiFi on a Pi3. If this isn't what you want, either use the sdtweak -+ overlay or the new sd_* dtparams of the base DTBs. - Load: dtoverlay=sdhost,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz -@@ -771,6 +775,8 @@ Params: overclock_50 SD Clock (in MHz) to use when the MMC framework - - Name: sdtweak - Info: Tunes the bcm2835-sdhost SD/MMC driver -+ N.B. This functionality is now available via the sd_* dtparams in the -+ base DTB. - Load: dtoverlay=sdtweak,= - Params: overclock_50 Clock (in MHz) to use when the MMC framework - requests 50MHz - -From 58fb42a1ecf4bec15d3236183955f4b54f199e75 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 17:23:15 +0100 -Subject: [PATCH 214/251] cpufreq: Temporarily ignore io_is_busy=1 - -To speed testing of the new sdhost driver that adapts to changes in -core_freq, hack the on-demand governor to treat io_is_busy=1 as -io_is_busy=0. The io_is_busy feature can still be forced using -io_is_busy=2. - -Signed-off-by: Phil Elwell ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 03ac6ce..99a9610 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- od_tuners->io_is_busy = !!input; -+ // XXX temporary hack -+ if (input > 1) -+ input = 1; -+ else -+ input = 0; -+ od_tuners->io_is_busy = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From 8bf41d1b2f41d6af2c196497168d3cc8f97a0071 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 30 Mar 2016 20:18:38 +0100 -Subject: [PATCH 215/251] Revert "cpufreq: Temporarily ignore io_is_busy=1" - -This reverts commit 2af1218a8a0220fec526f64d03977b8451afb4c8. ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 99a9610..03ac6ce 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,12 +307,7 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- // XXX temporary hack -- if (input > 1) -- input = 1; -- else -- input = 0; -- od_tuners->io_is_busy = input; -+ od_tuners->io_is_busy = !!input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From f9634b17e0d05988abbe329efd4b9eee59aadb0c Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Thu, 7 Jan 2016 15:50:22 +0100 -Subject: [PATCH 216/251] net, sched: add skb_at_tc_ingress helper - -Add a skb_at_tc_ingress() as this will be needed elsewhere as well and -can hide the ugly ifdef. - -Signed-off-by: Daniel Borkmann -Acked-by: Alexei Starovoitov -Signed-off-by: David S. Miller ---- - include/net/sch_generic.h | 9 +++++++++ - net/sched/cls_bpf.c | 6 +----- - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h -index b2a8e63..636a362 100644 ---- a/include/net/sch_generic.h -+++ b/include/net/sch_generic.h -@@ -407,6 +407,15 @@ bool tcf_destroy(struct tcf_proto *tp, bool force); - void tcf_destroy_chain(struct tcf_proto __rcu **fl); - int skb_do_redirect(struct sk_buff *); - -+static inline bool skb_at_tc_ingress(const struct sk_buff *skb) -+{ -+#ifdef CONFIG_NET_CLS_ACT -+ return G_TC_AT(skb->tc_verd) & AT_INGRESS; -+#else -+ return false; -+#endif -+} -+ - /* Reset all TX qdiscs greater then index of a device. */ - static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) - { -diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c -index 5faaa54..b3c8bb4 100644 ---- a/net/sched/cls_bpf.c -+++ b/net/sched/cls_bpf.c -@@ -79,12 +79,8 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp, - struct tcf_result *res) - { - struct cls_bpf_head *head = rcu_dereference_bh(tp->root); -+ bool at_ingress = skb_at_tc_ingress(skb); - struct cls_bpf_prog *prog; --#ifdef CONFIG_NET_CLS_ACT -- bool at_ingress = G_TC_AT(skb->tc_verd) & AT_INGRESS; --#else -- bool at_ingress = false; --#endif - int ret = -1; - - if (unlikely(!skb_mac_header_was_set(skb))) - -From de42773e4545e48e35472cdf01f1bcb7af1f27cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Linus=20L=C3=BCssing?= -Date: Wed, 24 Feb 2016 04:21:42 +0100 -Subject: [PATCH 217/251] net: fix bridge multicast packet checksum validation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We need to update the skb->csum after pulling the skb, otherwise -an unnecessary checksum (re)computation can ocure for IGMP/MLD packets -in the bridge code. Additionally this fixes the following splats for -network devices / bridge ports with support for and enabled RX checksum -offloading: - -[...] -[ 43.986968] eth0: hw csum failure -[ 43.990344] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.4.0 #2 -[ 43.996193] Hardware name: BCM2709 -[ 43.999647] [<800204e0>] (unwind_backtrace) from [<8001cf14>] (show_stack+0x10/0x14) -[ 44.007432] [<8001cf14>] (show_stack) from [<801ab614>] (dump_stack+0x80/0x90) -[ 44.014695] [<801ab614>] (dump_stack) from [<802e4548>] (__skb_checksum_complete+0x6c/0xac) -[ 44.023090] [<802e4548>] (__skb_checksum_complete) from [<803a055c>] (ipv6_mc_validate_checksum+0x104/0x178) -[ 44.032959] [<803a055c>] (ipv6_mc_validate_checksum) from [<802e111c>] (skb_checksum_trimmed+0x130/0x188) -[ 44.042565] [<802e111c>] (skb_checksum_trimmed) from [<803a06e8>] (ipv6_mc_check_mld+0x118/0x338) -[ 44.051501] [<803a06e8>] (ipv6_mc_check_mld) from [<803b2c98>] (br_multicast_rcv+0x5dc/0xd00) -[ 44.060077] [<803b2c98>] (br_multicast_rcv) from [<803aa510>] (br_handle_frame_finish+0xac/0x51c) -[...] - -Fixes: 9afd85c9e455 ("net: Export IGMP/MLD message validation code") -Reported-by: Álvaro Fernández Rojas -Signed-off-by: Linus Lüssing -Signed-off-by: David S. Miller ---- - net/core/skbuff.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 5bf88f5..8616d11 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -2948,6 +2948,24 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page, - EXPORT_SYMBOL_GPL(skb_append_pagefrags); - - /** -+ * skb_push_rcsum - push skb and update receive checksum -+ * @skb: buffer to update -+ * @len: length of data pulled -+ * -+ * This function performs an skb_push on the packet and updates -+ * the CHECKSUM_COMPLETE checksum. It should be used on -+ * receive path processing instead of skb_push unless you know -+ * that the checksum difference is zero (e.g., a valid IP header) -+ * or you are setting ip_summed to CHECKSUM_NONE. -+ */ -+static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len) -+{ -+ skb_push(skb, len); -+ skb_postpush_rcsum(skb, skb->data, len); -+ return skb->data; -+} -+ -+/** - * skb_pull_rcsum - pull skb and update receive checksum - * @skb: buffer to update - * @len: length of data pulled -@@ -4084,9 +4102,9 @@ struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb, - if (!pskb_may_pull(skb_chk, offset)) - goto err; - -- __skb_pull(skb_chk, offset); -+ skb_pull_rcsum(skb_chk, offset); - ret = skb_chkf(skb_chk); -- __skb_push(skb_chk, offset); -+ skb_push_rcsum(skb_chk, offset); - - if (ret) - goto err; - -From 2c0f60ed53c5a180397b2b740bbf796e09471012 Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Thu, 7 Jan 2016 15:50:23 +0100 -Subject: [PATCH 218/251] bpf: add skb_postpush_rcsum and fix dev_forward_skb - occasions - -Add a small helper skb_postpush_rcsum() and fix up redirect locations -that need CHECKSUM_COMPLETE fixups on ingress. dev_forward_skb() expects -a proper csum that covers also Ethernet header, f.e. since 2c26d34bbcc0 -("net/core: Handle csum for CHECKSUM_COMPLETE VXLAN forwarding"), we -also do skb_postpull_rcsum() after pulling Ethernet header off via -eth_type_trans(). - -When using eBPF in a netns setup f.e. with vxlan in collect metadata mode, -I can trigger the following csum issue with an IPv6 setup: - - [ 505.144065] dummy1: hw csum failure - [...] - [ 505.144108] Call Trace: - [ 505.144112] [] dump_stack+0x44/0x5c - [ 505.144134] [] netdev_rx_csum_fault+0x3a/0x40 - [ 505.144142] [] __skb_checksum_complete+0xcf/0xe0 - [ 505.144149] [] nf_ip6_checksum+0xb2/0x120 - [ 505.144161] [] icmpv6_error+0x17e/0x328 [nf_conntrack_ipv6] - [ 505.144170] [] ? ip6t_do_table+0x2fa/0x645 [ip6_tables] - [ 505.144177] [] ? ipv6_get_l4proto+0x65/0xd0 [nf_conntrack_ipv6] - [ 505.144189] [] nf_conntrack_in+0xc2/0x5a0 [nf_conntrack] - [ 505.144196] [] ipv6_conntrack_in+0x1c/0x20 [nf_conntrack_ipv6] - [ 505.144204] [] nf_iterate+0x5d/0x70 - [ 505.144210] [] nf_hook_slow+0x66/0xc0 - [ 505.144218] [] ipv6_rcv+0x3f2/0x4f0 - [ 505.144225] [] ? ip6_make_skb+0x1b0/0x1b0 - [ 505.144232] [] __netif_receive_skb_core+0x36b/0x9a0 - [ 505.144239] [] ? __netif_receive_skb+0x18/0x60 - [ 505.144245] [] __netif_receive_skb+0x18/0x60 - [ 505.144252] [] process_backlog+0x9f/0x140 - [ 505.144259] [] net_rx_action+0x145/0x320 - [...] - -What happens is that on ingress, we push Ethernet header back in, either -from cls_bpf or right before skb_do_redirect(), but without updating csum. -The "hw csum failure" can be fixed by using the new skb_postpush_rcsum() -helper for the dev_forward_skb() case to correct the csum diff again. - -Thanks to Hannes Frederic Sowa for the csum_partial() idea! - -Fixes: 3896d655f4d4 ("bpf: introduce bpf_clone_redirect() helper") -Fixes: 27b29f63058d ("bpf: add bpf_redirect() helper") -Signed-off-by: Daniel Borkmann -Acked-by: Alexei Starovoitov -Signed-off-by: David S. Miller ---- - include/linux/skbuff.h | 17 +++++++++++++++++ - net/core/filter.c | 17 +++++++++++++---- - 2 files changed, 30 insertions(+), 4 deletions(-) - -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 75f136a..d84c593 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2724,6 +2724,23 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb, - - unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); - -+static inline void skb_postpush_rcsum(struct sk_buff *skb, -+ const void *start, unsigned int len) -+{ -+ /* For performing the reverse operation to skb_postpull_rcsum(), -+ * we can instead of ... -+ * -+ * skb->csum = csum_add(skb->csum, csum_partial(start, len, 0)); -+ * -+ * ... just use this equivalent version here to save a few -+ * instructions. Feeding csum of 0 in csum_partial() and later -+ * on adding skb->csum is equivalent to feed skb->csum in the -+ * first place. -+ */ -+ if (skb->ip_summed == CHECKSUM_COMPLETE) -+ skb->csum = csum_partial(start, len, skb->csum); -+} -+ - /** - * pskb_trim_rcsum - trim received skb and update checksum - * @skb: buffer to trim -diff --git a/net/core/filter.c b/net/core/filter.c -index 37157c4..6e337ea 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -1288,8 +1288,9 @@ static u64 bpf_skb_store_bytes(u64 r1, u64 r2, u64 r3, u64 r4, u64 flags) - /* skb_store_bits cannot return -EFAULT here */ - skb_store_bits(skb, offset, ptr, len); - -- if (BPF_RECOMPUTE_CSUM(flags) && skb->ip_summed == CHECKSUM_COMPLETE) -- skb->csum = csum_add(skb->csum, csum_partial(ptr, len, 0)); -+ if (BPF_RECOMPUTE_CSUM(flags)) -+ skb_postpush_rcsum(skb, ptr, len); -+ - return 0; - } - -@@ -1415,8 +1416,12 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5) - if (unlikely(!skb2)) - return -ENOMEM; - -- if (BPF_IS_REDIRECT_INGRESS(flags)) -+ if (BPF_IS_REDIRECT_INGRESS(flags)) { -+ if (skb_at_tc_ingress(skb2)) -+ skb_postpush_rcsum(skb2, skb_mac_header(skb2), -+ skb2->mac_len); - return dev_forward_skb(dev, skb2); -+ } - - skb2->dev = dev; - skb_sender_cpu_clear(skb2); -@@ -1459,8 +1464,12 @@ int skb_do_redirect(struct sk_buff *skb) - return -EINVAL; - } - -- if (BPF_IS_REDIRECT_INGRESS(ri->flags)) -+ if (BPF_IS_REDIRECT_INGRESS(ri->flags)) { -+ if (skb_at_tc_ingress(skb)) -+ skb_postpush_rcsum(skb, skb_mac_header(skb), -+ skb->mac_len); - return dev_forward_skb(dev, skb); -+ } - - skb->dev = dev; - skb_sender_cpu_clear(skb); - -From 67ba5d253f79ddbf1c28d7e3cb48efd0b845f87c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 31 Mar 2016 15:44:53 +0100 -Subject: [PATCH 219/251] bcm2835-sdhost: Precalc divisors and overclocks - -Recalculating the clock divisors when the core clock changes is wasteful -and makes it harder to manage the overclock settings. Instead, -precalculate them and only report significant changes. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++++++++---------------- - 1 file changed, 88 insertions(+), 64 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 1deecef..cc18ec8 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -154,12 +154,15 @@ struct bcm2835_host { - u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ -+ int clocks[2]; - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max src clock freq */ -- unsigned int min_clk; /* Min src clock freq */ -- unsigned int cur_clk; /* Current src clock freq */ -+ unsigned int src_clks[2]; /* Min/max src clock freqs */ -+ unsigned int cur_clk_idx; /* Index of current clock */ -+ unsigned int next_clk_idx; /* Next clock index */ -+ unsigned int cdivs[2]; - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -213,7 +216,7 @@ struct bcm2835_host { - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 overclock; /* Current frequency if overclocked, else zero */ -+ u32 prev_overclock_50; - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -@@ -1509,10 +1512,35 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - -+static void bcm2835_sdhost_select_clock(struct bcm2835_host *host, int idx) -+{ -+ unsigned int clock = host->clocks[idx]; -+ unsigned int cdiv = host->cdivs[idx]; -+ -+ host->mmc->actual_clock = clock; -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ -+ host->cdiv = cdiv; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, clock/2, SDTOUT); -+ -+ host->cur_clk_idx = host->next_clk_idx = idx; -+ -+ if (host->debug) -+ pr_info("%s: clock=%d -> src_clk=%d, cdiv=%x (actual %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->src_clks[idx], host->cdiv, -+ host->mmc->actual_clock); -+} -+ - void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ - unsigned int clock = host->clock; -+ int clk_idx; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1553,53 +1581,45 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- div = host->cur_clk / clock; -- if (div < 2) -- div = 2; -- if ((host->cur_clk / div) > clock) -- div++; -- div -= 2; -- -- if (div > SDCDIV_MAX_CDIV) -- div = SDCDIV_MAX_CDIV; -- -- clock = host->cur_clk / (div + 2); -- host->mmc->actual_clock = clock; -- -- /* Calibrate some delays */ -- -- host->ns_per_fifo_word = (1000000000/clock) * -- ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -- -- if (clock > host->clock) { -- /* Save the closest value, to make it easier -- to reduce in the event of error */ -- host->overclock_50 = (clock/MHZ); -- -- if (clock != host->overclock) { -- pr_warn("%s: overclocking to %dHz\n", -- mmc_hostname(host->mmc), clock); -- host->overclock = clock; -- } -- } -- else if (host->overclock) -+ /* Calculate the clock divisors */ -+ for (clk_idx = 0; clk_idx <= host->variable_clock; clk_idx++) - { -- host->overclock = 0; -- if (clock == 50 * MHZ) -- pr_warn("%s: cancelling overclock\n", -- mmc_hostname(host->mmc)); -+ unsigned int cur_clk = host->src_clks[clk_idx]; -+ unsigned int actual_clock; -+ -+ div = cur_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((cur_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ actual_clock = cur_clk / (div + 2); -+ -+ host->cdivs[clk_idx] = div; -+ host->clocks[clk_idx] = actual_clock; -+ -+ if (host->overclock_50 != host->prev_overclock_50) { -+ const char *clk_name = ""; -+ if (host->variable_clock) -+ clk_name = clk_idx ? " (turbo)" : " (normal)"; -+ if (actual_clock > host->clock) -+ pr_info("%s: overclocking to %dHz%s\n", -+ mmc_hostname(host->mmc), -+ actual_clock, clk_name); -+ else if ((host->overclock_50 < 50) && (clk_idx == 0)) -+ pr_info("%s: cancelling overclock%s\n", -+ mmc_hostname(host->mmc), -+ host->variable_clock ? "s" : ""); -+ } - } - -- host->cdiv = div; -- bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -- -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); -+ if (host->clock == 50*MHZ) -+ host->prev_overclock_50 = host->overclock_50; - -- if (host->debug) -- pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->cur_clk, host->cdiv, host->mmc->actual_clock); -+ bcm2835_sdhost_select_clock(host, host->cur_clk_idx); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1657,6 +1677,9 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - - spin_lock_irqsave(&host->lock, flags); - -+ if (host->next_clk_idx != host->cur_clk_idx) -+ bcm2835_sdhost_select_clock(host, host->next_clk_idx); -+ - WARN_ON(host->mrq != NULL); - host->mrq = mrq; - -@@ -1719,11 +1742,7 @@ static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, - return NOTIFY_BAD; - break; - case CPUFREQ_POSTCHANGE: -- if (freq->new > freq->old) -- host->cur_clk = host->max_clk; -- else -- host->cur_clk = host->min_clk; -- bcm2835_sdhost_set_clock(host); -+ host->next_clk_idx = (freq->new > freq->old); - up(&host->cpufreq_semaphore); - break; - default: -@@ -1763,8 +1782,11 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && !host->cur_clk) -- host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ if (ios->clock && (host->cur_clk_idx == -1)) { -+ unsigned int cur_clk = -+ get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -+ host->cur_clk_idx = (cur_clk == host->src_clks[0]) ? 0 : 1; -+ } - - spin_lock_irqsave(&host->lock, flags); - -@@ -1854,11 +1876,12 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (host->overclock) { -+ if (host->clock > 50*MHZ) { - if ((mrq->cmd && mrq->cmd->error) || - (mrq->data && mrq->data->error) || - (mrq->stop && mrq->stop->error)) { -- host->overclock_50--; -+ host->overclock_50 = (host->clock/MHZ) - 1; -+ - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_set_clock(host); -@@ -2022,7 +2045,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk; -+ unsigned int max_clk, min_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2128,12 +2151,8 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - else - mmc->caps |= MMC_CAP_4_BIT_DATA; - -- ret = bcm2835_sdhost_add_host(host); -- if (ret) -- goto err; -- - /* Query the core clock frequencies */ -- host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); - max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - if (max_clk != host->max_clk) { - pr_warn("%s: Expected max clock %d, found %d\n", -@@ -2141,19 +2160,24 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->max_clk = max_clk; - } - -- if (host->min_clk != host->max_clk) { -+ host->src_clks[0] = min_clk; -+ host->cur_clk_idx = -1; -+ if (max_clk != min_clk) { -+ host->src_clks[1] = max_clk; - host->cpufreq_nb.notifier_call = - bcm2835_sdhost_cpufreq_callback; - sema_init(&host->cpufreq_semaphore, 1); - cpufreq_register_notifier(&host->cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - host->variable_clock = 1; -- host->cur_clk = 0; /* Get this later */ - } else { - host->variable_clock = 0; -- host->cur_clk = host->max_clk; - } - -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); - -From 7a21e0c9d567d27b000ef8350ee503776720852d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Apr 2016 12:35:32 +0100 -Subject: [PATCH 220/251] Revert "bcm2835-sdhost: Precalc divisors and - overclocks" - -This reverts commit 20260462773366a5734e5268dae0a4c179a21a2d. ---- - drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++---------------------- - 1 file changed, 64 insertions(+), 88 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index cc18ec8..1deecef 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -154,15 +154,12 @@ struct bcm2835_host { - u32 pio_timeout; /* In jiffies */ - - int clock; /* Current clock speed */ -- int clocks[2]; - - bool slow_card; /* Force 11-bit divisor */ - - unsigned int max_clk; /* Max src clock freq */ -- unsigned int src_clks[2]; /* Min/max src clock freqs */ -- unsigned int cur_clk_idx; /* Index of current clock */ -- unsigned int next_clk_idx; /* Next clock index */ -- unsigned int cdivs[2]; -+ unsigned int min_clk; /* Min src clock freq */ -+ unsigned int cur_clk; /* Current src clock freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -216,7 +213,7 @@ struct bcm2835_host { - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -- u32 prev_overclock_50; -+ u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -@@ -1512,35 +1509,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --static void bcm2835_sdhost_select_clock(struct bcm2835_host *host, int idx) --{ -- unsigned int clock = host->clocks[idx]; -- unsigned int cdiv = host->cdivs[idx]; -- -- host->mmc->actual_clock = clock; -- host->ns_per_fifo_word = (1000000000/clock) * -- ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -- -- host->cdiv = cdiv; -- bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -- -- /* Set the timeout to 500ms */ -- bcm2835_sdhost_write(host, clock/2, SDTOUT); -- -- host->cur_clk_idx = host->next_clk_idx = idx; -- -- if (host->debug) -- pr_info("%s: clock=%d -> src_clk=%d, cdiv=%x (actual %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->src_clks[idx], host->cdiv, -- host->mmc->actual_clock); --} -- - void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - { - int div = 0; /* Initialized for compiler warning */ - unsigned int clock = host->clock; -- int clk_idx; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1581,45 +1553,53 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- /* Calculate the clock divisors */ -- for (clk_idx = 0; clk_idx <= host->variable_clock; clk_idx++) -- { -- unsigned int cur_clk = host->src_clks[clk_idx]; -- unsigned int actual_clock; -- -- div = cur_clk / clock; -- if (div < 2) -- div = 2; -- if ((cur_clk / div) > clock) -- div++; -- div -= 2; -- -- if (div > SDCDIV_MAX_CDIV) -- div = SDCDIV_MAX_CDIV; -- actual_clock = cur_clk / (div + 2); -- -- host->cdivs[clk_idx] = div; -- host->clocks[clk_idx] = actual_clock; -- -- if (host->overclock_50 != host->prev_overclock_50) { -- const char *clk_name = ""; -- if (host->variable_clock) -- clk_name = clk_idx ? " (turbo)" : " (normal)"; -- if (actual_clock > host->clock) -- pr_info("%s: overclocking to %dHz%s\n", -- mmc_hostname(host->mmc), -- actual_clock, clk_name); -- else if ((host->overclock_50 < 50) && (clk_idx == 0)) -- pr_info("%s: cancelling overclock%s\n", -- mmc_hostname(host->mmc), -- host->variable_clock ? "s" : ""); -+ div = host->cur_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((host->cur_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ -+ clock = host->cur_clk / (div + 2); -+ host->mmc->actual_clock = clock; -+ -+ /* Calibrate some delays */ -+ -+ host->ns_per_fifo_word = (1000000000/clock) * -+ ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); -+ -+ if (clock > host->clock) { -+ /* Save the closest value, to make it easier -+ to reduce in the event of error */ -+ host->overclock_50 = (clock/MHZ); -+ -+ if (clock != host->overclock) { -+ pr_warn("%s: overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); -+ host->overclock = clock; - } - } -+ else if (host->overclock) -+ { -+ host->overclock = 0; -+ if (clock == 50 * MHZ) -+ pr_warn("%s: cancelling overclock\n", -+ mmc_hostname(host->mmc)); -+ } -+ -+ host->cdiv = div; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -- if (host->clock == 50*MHZ) -- host->prev_overclock_50 = host->overclock_50; -+ /* Set the timeout to 500ms */ -+ bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - -- bcm2835_sdhost_select_clock(host, host->cur_clk_idx); -+ if (host->debug) -+ pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), host->clock, -+ host->cur_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1677,9 +1657,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - - spin_lock_irqsave(&host->lock, flags); - -- if (host->next_clk_idx != host->cur_clk_idx) -- bcm2835_sdhost_select_clock(host, host->next_clk_idx); -- - WARN_ON(host->mrq != NULL); - host->mrq = mrq; - -@@ -1742,7 +1719,11 @@ static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, - return NOTIFY_BAD; - break; - case CPUFREQ_POSTCHANGE: -- host->next_clk_idx = (freq->new > freq->old); -+ if (freq->new > freq->old) -+ host->cur_clk = host->max_clk; -+ else -+ host->cur_clk = host->min_clk; -+ bcm2835_sdhost_set_clock(host); - up(&host->cpufreq_semaphore); - break; - default: -@@ -1782,11 +1763,8 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && (host->cur_clk_idx == -1)) { -- unsigned int cur_clk = -- get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -- host->cur_clk_idx = (cur_clk == host->src_clks[0]) ? 0 : 1; -- } -+ if (ios->clock && !host->cur_clk) -+ host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1876,12 +1854,11 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - /* Drop the overclock after any data corruption, or after any - error overclocked */ -- if (host->clock > 50*MHZ) { -+ if (host->overclock) { - if ((mrq->cmd && mrq->cmd->error) || - (mrq->data && mrq->data->error) || - (mrq->stop && mrq->stop->error)) { -- host->overclock_50 = (host->clock/MHZ) - 1; -- -+ host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); - bcm2835_sdhost_set_clock(host); -@@ -2045,7 +2022,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk, min_clk; -+ unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2151,8 +2128,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - else - mmc->caps |= MMC_CAP_4_BIT_DATA; - -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ - /* Query the core clock frequencies */ -- min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -+ host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); - max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); - if (max_clk != host->max_clk) { - pr_warn("%s: Expected max clock %d, found %d\n", -@@ -2160,24 +2141,19 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - host->max_clk = max_clk; - } - -- host->src_clks[0] = min_clk; -- host->cur_clk_idx = -1; -- if (max_clk != min_clk) { -- host->src_clks[1] = max_clk; -+ if (host->min_clk != host->max_clk) { - host->cpufreq_nb.notifier_call = - bcm2835_sdhost_cpufreq_callback; - sema_init(&host->cpufreq_semaphore, 1); - cpufreq_register_notifier(&host->cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - host->variable_clock = 1; -+ host->cur_clk = 0; /* Get this later */ - } else { - host->variable_clock = 0; -+ host->cur_clk = host->max_clk; - } - -- ret = bcm2835_sdhost_add_host(host); -- if (ret) -- goto err; -- - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); - -From a44f96721ff123198ef527c1471425cc5e2ee1b1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 4 Apr 2016 12:35:51 +0100 -Subject: [PATCH 221/251] Revert "bcm2835-sdhost: Adjust to core clock changes" - -This reverts commit 4b89d07fd299a0f4e25321920cb74416ba2e638e. ---- - drivers/mmc/host/Kconfig | 1 - - drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++-------------------------------- - 2 files changed, 22 insertions(+), 119 deletions(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 98a7fa5..d509d10 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -36,7 +36,6 @@ config MMC_BCM2835_PIO_DMA_BARRIER - config MMC_BCM2835_SDHOST - tristate "Support for the SDHost controller on BCM2708/9" - depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -- depends on RASPBERRYPI_FIRMWARE - help - This selects the SDHost controller on BCM2835/6. - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 1deecef..f43aae0 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -50,10 +50,6 @@ - #include - #include - #include --#include --#include --#include -- - - #define DRIVER_NAME "sdhost-bcm2835" - -@@ -140,8 +136,6 @@ - - #define MHZ 1000000 - --#define RPI_FIRMWARE_CLOCK_CORE 4 -- - - struct bcm2835_host { - spinlock_t lock; -@@ -157,9 +151,7 @@ struct bcm2835_host { - - bool slow_card; /* Force 11-bit divisor */ - -- unsigned int max_clk; /* Max src clock freq */ -- unsigned int min_clk; /* Min src clock freq */ -- unsigned int cur_clk; /* Current src clock freq */ -+ unsigned int max_clk; /* Max possible freq */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -191,7 +183,6 @@ struct bcm2835_host { - unsigned int use_sbc:1; /* Send CMD23 */ - - unsigned int debug:1; /* Enable debug output */ -- unsigned int variable_clock:1; /* The core clock may change */ - - /*DMA part*/ - struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */ -@@ -217,9 +208,6 @@ struct bcm2835_host { - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ - - u32 sectors; /* Cached card size in sectors */ -- -- struct notifier_block cpufreq_nb; /* The cpufreq callback list item */ -- struct semaphore cpufreq_semaphore; /* Interlock between SD activity and cpufreq changes */ - }; - - #if ENABLE_LOG -@@ -239,10 +227,6 @@ static u32 sdhost_log_idx; - static spinlock_t log_lock; - static void __iomem *timer_base; - --static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -- unsigned long action, void *data); --static unsigned int get_core_clock(unsigned int mode); -- - #define LOG_ENTRIES (256*1) - #define LOG_SIZE (sizeof(LOG_ENTRY_T)*LOG_ENTRIES) - -@@ -464,14 +448,20 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc) - - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - --static void bcm2835_sdhost_init(struct bcm2835_host *host) -+static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) - { -- pr_debug("bcm2835_sdhost_init()\n"); -+ pr_debug("bcm2835_sdhost_init(%d)\n", soft); - - /* Set interrupt enables */ - host->hcfg = SDHCFG_BUSY_IRPT_EN; - - bcm2835_sdhost_reset_internal(host); -+ -+ if (soft) { -+ /* force clock reconfiguration */ -+ host->clock = 0; -+ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -+ } - } - - static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host) -@@ -1509,10 +1499,10 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - return result; - } - --void bcm2835_sdhost_set_clock(struct bcm2835_host *host) -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -- unsigned int clock = host->clock; -+ unsigned int input_clock = clock; - - if (host->debug) - pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock); -@@ -1553,17 +1543,17 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - return; - } - -- div = host->cur_clk / clock; -+ div = host->max_clk / clock; - if (div < 2) - div = 2; -- if ((host->cur_clk / div) > clock) -+ if ((host->max_clk / div) > clock) - div++; - div -= 2; - - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- clock = host->cur_clk / (div + 2); -+ clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - - /* Calibrate some delays */ -@@ -1571,7 +1561,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - host->ns_per_fifo_word = (1000000000/clock) * - ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32); - -- if (clock > host->clock) { -+ if (clock > input_clock) { - /* Save the closest value, to make it easier - to reduce in the event of error */ - host->overclock_50 = (clock/MHZ); -@@ -1597,9 +1587,9 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host) - bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT); - - if (host->debug) -- pr_info("%s: clock=%d -> cur_clk=%d, cdiv=%x (actual clock %d)\n", -- mmc_hostname(host->mmc), host->clock, -- host->cur_clk, host->cdiv, host->mmc->actual_clock); -+ pr_info("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ mmc_hostname(host->mmc), input_clock, -+ host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1648,13 +1638,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - (mrq->data->blocks > host->pio_limit)) - bcm2835_sdhost_prepare_dma(host, mrq->data); - -- if (host->variable_clock && -- (down_killable(&host->cpufreq_semaphore) != 0)) { -- mrq->cmd->error = -EINTR; -- mmc_request_done(mmc, mrq); -- return; -- } -- - spin_lock_irqsave(&host->lock, flags); - - WARN_ON(host->mrq != NULL); -@@ -1704,52 +1687,6 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq - spin_unlock_irqrestore(&host->lock, flags); - } - --static int bcm2835_sdhost_cpufreq_callback(struct notifier_block *nb, -- unsigned long action, void *data) --{ -- struct cpufreq_freqs *freq = data; -- struct bcm2835_host *host; -- -- host = container_of(nb, struct bcm2835_host, cpufreq_nb); -- -- if (freq->cpu == 0) { -- switch (action) { -- case CPUFREQ_PRECHANGE: -- if (down_killable(&host->cpufreq_semaphore) != 0) -- return NOTIFY_BAD; -- break; -- case CPUFREQ_POSTCHANGE: -- if (freq->new > freq->old) -- host->cur_clk = host->max_clk; -- else -- host->cur_clk = host->min_clk; -- bcm2835_sdhost_set_clock(host); -- up(&host->cpufreq_semaphore); -- break; -- default: -- break; -- } -- } -- return NOTIFY_OK; --} -- --static unsigned int get_core_clock(unsigned int mode) --{ -- struct rpi_firmware *fw = rpi_firmware_get(NULL); -- struct { -- u32 id; -- u32 val; -- } packet; -- int ret; -- -- packet.id = RPI_FIRMWARE_CLOCK_CORE; -- ret = rpi_firmware_property(fw, mode, &packet, sizeof(packet)); -- if (ret) -- return 0; -- -- return packet.val; --} -- - static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { - -@@ -1763,16 +1700,13 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - ios->clock, ios->power_mode, ios->bus_width, - ios->timing, ios->signal_voltage, ios->drv_type); - -- if (ios->clock && !host->cur_clk) -- host->cur_clk = get_core_clock(RPI_FIRMWARE_GET_CLOCK_RATE); -- - spin_lock_irqsave(&host->lock, flags); - - log_event("IOS<", ios->clock, 0); - - if (!ios->clock || ios->clock != host->clock) { -+ bcm2835_sdhost_set_clock(host, ios->clock); - host->clock = ios->clock; -- bcm2835_sdhost_set_clock(host); - } - - /* set bus width */ -@@ -1861,7 +1795,7 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); -- bcm2835_sdhost_set_clock(host); -+ bcm2835_sdhost_set_clock(host,50*MHZ); - mrq->cmd->error = -EILSEQ; - mrq->cmd->retries = 1; - } -@@ -1879,9 +1813,6 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param) - - spin_unlock_irqrestore(&host->lock, flags); - -- if (host->variable_clock) -- up(&host->cpufreq_semaphore); -- - if (terminate_chan) - { - int err = dmaengine_terminate_all(terminate_chan); -@@ -1984,10 +1915,10 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host) - setup_timer(&host->timer, bcm2835_sdhost_timeout, - (unsigned long)host); - -- bcm2835_sdhost_init(host); -+ bcm2835_sdhost_init(host, 0); - - ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -- mmc_hostname(mmc), host); -+ mmc_hostname(mmc), host); - if (ret) { - pr_err("%s: failed to request IRQ %d: %d\n", - mmc_hostname(mmc), host->irq, ret); -@@ -2022,7 +1953,6 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - struct bcm2835_host *host; - struct mmc_host *mmc; - const __be32 *addr; -- unsigned int max_clk; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2132,28 +2062,6 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - if (ret) - goto err; - -- /* Query the core clock frequencies */ -- host->min_clk = get_core_clock(RPI_FIRMWARE_GET_MIN_CLOCK_RATE); -- max_clk = get_core_clock(RPI_FIRMWARE_GET_MAX_CLOCK_RATE); -- if (max_clk != host->max_clk) { -- pr_warn("%s: Expected max clock %d, found %d\n", -- mmc_hostname(mmc), host->max_clk, max_clk); -- host->max_clk = max_clk; -- } -- -- if (host->min_clk != host->max_clk) { -- host->cpufreq_nb.notifier_call = -- bcm2835_sdhost_cpufreq_callback; -- sema_init(&host->cpufreq_semaphore, 1); -- cpufreq_register_notifier(&host->cpufreq_nb, -- CPUFREQ_TRANSITION_NOTIFIER); -- host->variable_clock = 1; -- host->cur_clk = 0; /* Get this later */ -- } else { -- host->variable_clock = 0; -- host->cur_clk = host->max_clk; -- } -- - platform_set_drvdata(pdev, host); - - pr_debug("bcm2835_sdhost_probe -> OK\n"); -@@ -2173,10 +2081,6 @@ static int bcm2835_sdhost_remove(struct platform_device *pdev) - - pr_debug("bcm2835_sdhost_remove\n"); - -- if (host->variable_clock) -- cpufreq_unregister_notifier(&host->cpufreq_nb, -- CPUFREQ_TRANSITION_NOTIFIER); -- - mmc_remove_host(host->mmc); - - bcm2835_sdhost_set_power(host, false); - -From 99a50a0418f27f7b894ee9668b2ed02b435c9113 Mon Sep 17 00:00:00 2001 +From 3c3beab16b1e6d776d25d1867516bcaa298e58a3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 4 Apr 2016 16:03:18 +0100 -Subject: [PATCH 222/251] bcm2835-sdhost: Firmware manages the clock divisor +Subject: [PATCH 104/114] bcm2835-sdhost: Firmware manages the clock divisor The bcm2835-sdhost driver hands control of the CDIV clock divisor register to matching firmware, allowing it to adjust to a changing @@ -162688,9 +131495,8 @@ lower) than "normal" mode. Signed-off-by: Phil Elwell --- - drivers/mmc/host/bcm2835-sdhost.c | 120 ++++++++++++++++++----------- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 74 insertions(+), 47 deletions(-) + drivers/mmc/host/bcm2835-sdhost.c | 120 +++++++++++++++++++++++--------------- + 1 file changed, 73 insertions(+), 47 deletions(-) diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c index f43aae0..54087b2 100644 @@ -162887,1067 +131693,11 @@ index f43aae0..54087b2 100644 ret = bcm2835_sdhost_add_host(host); if (ret) goto err; -diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h -index c844968..e312e9c 100644 ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -79,6 +79,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, - RPI_FIRMWARE_SET_TURBO = 0x00038009, - RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, -+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, - - /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, -From 3a3bd335bf71e17af13de24423c806f9a26480b7 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 4 Apr 2016 19:52:27 +0100 -Subject: [PATCH 223/251] Revert "Revert "cpufreq: Temporarily ignore - io_is_busy=1"" - -This reverts commit c353af0f83220068c10f6593b1767576b9b6cc18. ---- - drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c -index 03ac6ce..99a9610 100644 ---- a/drivers/cpufreq/cpufreq_ondemand.c -+++ b/drivers/cpufreq/cpufreq_ondemand.c -@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, - ret = sscanf(buf, "%u", &input); - if (ret != 1) - return -EINVAL; -- od_tuners->io_is_busy = !!input; -+ // XXX temporary hack -+ if (input > 1) -+ input = 1; -+ else -+ input = 0; -+ od_tuners->io_is_busy = input; - - /* we need to re-evaluate prev_cpu_idle */ - for_each_online_cpu(j) { - -From 82caca6544d42613722befb52dd121bd9c7d8159 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 31 Mar 2016 16:49:52 +0100 -Subject: [PATCH 224/251] config: Enabled IPV6_SUBTREES - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 2c8e4b7..d509168 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -106,6 +106,7 @@ CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - CONFIG_IPV6_TUNNEL=m - CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IPV6_MROUTE=y - CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y - CONFIG_IPV6_PIMSM_V2=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index f6e2d84..060ec5f 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -73,6 +73,7 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IP_ROUTE_MULTIPATH=y - CONFIG_IP_ROUTE_VERBOSE=y - CONFIG_IP_PNP=y - -From 67cf7c950c17a731c934a3b30b474cb8886744c5 Mon Sep 17 00:00:00 2001 -From: Sam Nazarko -Date: Fri, 1 Apr 2016 17:27:21 +0100 -Subject: [PATCH 225/251] add smsc95xx packetsize module_param - -Signed-off-by: Sam Nazarko ---- - drivers/net/usb/smsc95xx.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index a61bd08..3c23b11 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -83,6 +83,10 @@ static char *macaddr = ":"; - module_param(macaddr, charp, 0); - MODULE_PARM_DESC(macaddr, "MAC address"); - -+static int packetsize = 0; -+module_param(packetsize, int, 0644); -+MODULE_PARM_DESC(packetsize, "Override the RX URB packet size"); -+ - static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, - u32 *data, int in_pm) - { -@@ -1006,13 +1010,13 @@ static int smsc95xx_reset(struct usbnet *dev) - - if (!turbo_mode) { - burst_cap = 0; -- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE; - } else if (dev->udev->speed == USB_SPEED_HIGH) { -- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; -- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE; -+ burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE; - } else { -- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; -- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; -+ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE; -+ burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE; - } - - netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", - -From fd1df6d4b4d6ebf352da378dcca5965297b242ec Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 5 Apr 2016 19:40:12 +0100 -Subject: [PATCH 226/251] reboot: Use power off rather than busy spinning when - halt is requested - ---- - arch/arm/kernel/reboot.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c -index 3826935..2cd6af2 100644 ---- a/arch/arm/kernel/reboot.c -+++ b/arch/arm/kernel/reboot.c -@@ -102,11 +102,7 @@ void machine_shutdown(void) - */ - void machine_halt(void) - { -- local_irq_disable(); -- smp_send_stop(); -- -- local_irq_disable(); -- while (1); -+ machine_power_off(); - } - - /* - -From d1766b543e9362da3ed16d5b03828a67214e7476 Mon Sep 17 00:00:00 2001 -From: HiassofT -Date: Wed, 6 Apr 2016 21:45:01 +0200 -Subject: [PATCH 227/251] Revert "bcm2835-dma: Fix dreq not set for slave - transfers" - -This reverts commit 8ad957e866a1fe1450f663f2b00a57d7de44904c. - - - -DMA channels are set in devicetree, thus dreq will be set, - -and this commit is no longer needed. - - - -Signed-off-by: Matthias Reichl ---- - drivers/dma/bcm2835-dma.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c -index 985019b..d26b6bd 100644 ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -679,8 +679,6 @@ static int bcm2835_dma_slave_config(struct dma_chan *chan, - } - - c->cfg = *cfg; -- if (!c->dreq) -- c->dreq = cfg->slave_id; - - return 0; - } - -From 68172482aa367aa118a7a46537206c817669b10c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson <6by9@users.noreply.github.com> -Date: Fri, 1 Apr 2016 15:28:46 +0100 -Subject: [PATCH 228/251] RPi config: Add CONFIG_PWM_PCA9685 for NXP PCA9685 - driver over I2C - -Includes DT overlay to configure it. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 +++++ - .../boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts | 26 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 5 files changed, 35 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 7c4fc30..239c6a1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -30,6 +30,7 @@ dtbo-$(RPI_DT_OVERLAYS) += hy28b.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-rtc.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-gpio.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c-mux-pca9548a.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += i2c-pwm-pca9685a.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c0-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2c1-bcm2708.dtbo - dtbo-$(RPI_DT_OVERLAYS) += i2s-mmap.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 337be4a..9df71a4 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -366,6 +366,12 @@ Load: dtoverlay=i2c-mux-pca9548a,= - Params: addr I2C address of PCA9548A (default 0x70) - - -+Name: i2c-pwm-pca9685a -+Info: Adds support for an NXP PCA9685A I2C PWM controller on i2c_arm -+Load: dtoverlay=i2c-pwm-pca9685a,= -+Params: addr I2C address of PCA9685A (default 0x40) -+ -+ - Name: i2c-rtc - Info: Adds support for a number of I2C Real Time Clock devices - Load: dtoverlay=i2c-rtc,= -diff --git a/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -new file mode 100644 -index 0000000..d1ffd23 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -@@ -0,0 +1,26 @@ -+// Definitions for NXP PCA9685A I2C PWM controller on ARM I2C bus. -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pca: pca@40 { -+ compatible = "nxp,pca9685"; -+ #pwm-cells = <2>; -+ reg = <0x40>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ addr = <&pca>,"reg:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d509168..299d7be 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1122,6 +1122,7 @@ CONFIG_MCP320X=m - CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 060ec5f..acda16b 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1129,6 +1129,7 @@ CONFIG_MCP320X=m - CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m - CONFIG_RASPBERRYPI_FIRMWARE=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_POSIX_ACL=y - -From 3d3c095375d6ac4508dc49a80d615b1fd56eb12a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 8 Apr 2016 17:43:27 +0100 -Subject: [PATCH 229/251] BCM270X_DT: Don't generate "linux,phandle" props - -The EPAPR standard says to use "phandle" properties to store phandles, -rather than the deprecated "linux,phandle" version. By default, dtc -generates both, but adding "-H epapr" causes it to only generate -"phandle"s, saving some space and clutter. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 2 +- - scripts/Makefile.lib | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index fdc450f..49badba 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -813,5 +813,5 @@ clean-files := *.dtb - - # Enable fixups to support overlays on BCM2708 platforms - ifeq ($(RPI_DT_OVERLAYS),y) -- DTC_FLAGS ?= -@ -+ DTC_FLAGS ?= -@ -H epapr - endif -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 7209d62..3079c4f 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -294,7 +294,7 @@ $(obj)/%.dtb: $(src)/%.dts FORCE - - quiet_cmd_dtco = DTCO $@ - cmd_dtco = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -- $(objtree)/scripts/dtc/dtc -@ -O dtb -o $@ -b 0 \ -+ $(objtree)/scripts/dtc/dtc -@ -H epapr -O dtb -o $@ -b 0 \ - -i $(dir $<) $(DTC_FLAGS) \ - -d $(depfile).dtc.tmp $(dtc-tmp) ; \ - cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) - -From 5cec9f4a5fb37bc1041c351ab309001c4f9f9d1d Mon Sep 17 00:00:00 2001 -From: 6by9 <6by9@users.noreply.github.com> -Date: Fri, 8 Apr 2016 18:15:43 +0100 -Subject: [PATCH 230/251] V4L2 driver updates (#1393) - -* BCM2835-V4L2: Correct ISO control and add V4L2_CID_ISO_SENSITIVITY_AUTO - -https://github.com/raspberrypi/linux/issues/1251 - -V4L2_CID_ISO_SENSITIVITY was not advertising ISO*1000 as it should. -V4L2_CID_ISO_SENSITIVITY_AUTO was not implemented, so was taking -V4L2_CID_ISO_SENSITIVITY as 0 for auto mode. -Still accepts 0 for auto, but also abides by the new parameter. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add a video_nr parameter. - -Adds a kernel parameter "video_nr" to specify the preferred -/dev/videoX device node. -https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=136120&p=905545 - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add support for multiple cameras - -Ask GPU on load how many cameras have been detected, and -enumerate that number of devices. -Only applicable on the Compute Module as no other device -exposes multiple CSI2 interfaces. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Add control of the overlay location and alpha. - -Actually do something useful in vidioc_s_fmt_vid_overlay and -vidioc_try_fmt_vid_overlay, rather than effectively having -read-only fields. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: V4L2-Compliance failure fix - -VIDIOC_TRY_FMT was failing due to bytesperline not -being set correctly by default. - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> - -* BCM2835-V4L2: Make all module parameters static - -Clean up to correct variable scope - -Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com> ---- - drivers/media/platform/bcm2835/bcm2835-camera.c | 372 +++++++++++++++-------- - drivers/media/platform/bcm2835/bcm2835-camera.h | 19 +- - drivers/media/platform/bcm2835/controls.c | 31 +- - drivers/media/platform/bcm2835/mmal-parameters.h | 33 ++ - 4 files changed, 320 insertions(+), 135 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c -index 98a892e..0e6c9b4 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.c -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c -@@ -45,6 +45,8 @@ - #define MAX_VIDEO_MODE_WIDTH 1280 - #define MAX_VIDEO_MODE_HEIGHT 720 - -+#define MAX_BCM2835_CAMERAS 2 -+ - MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture"); - MODULE_AUTHOR("Vincent Sanders"); - MODULE_LICENSE("GPL"); -@@ -54,8 +56,13 @@ int bcm2835_v4l2_debug; - module_param_named(debug, bcm2835_v4l2_debug, int, 0644); - MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2"); - --int max_video_width = MAX_VIDEO_MODE_WIDTH; --int max_video_height = MAX_VIDEO_MODE_HEIGHT; -+#define UNSET (-1) -+static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET }; -+module_param_array(video_nr, int, NULL, 0644); -+MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect"); -+ -+static int max_video_width = MAX_VIDEO_MODE_WIDTH; -+static int max_video_height = MAX_VIDEO_MODE_HEIGHT; - module_param(max_video_width, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - MODULE_PARM_DESC(max_video_width, "Threshold for video mode"); - module_param(max_video_height, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -@@ -70,11 +77,12 @@ MODULE_PARM_DESC(max_video_height, "Threshold for video mode"); - * our function table list (actually switch to an alternate set, but same - * result). - */ --int gst_v4l2src_is_broken = 0; -+static int gst_v4l2src_is_broken; - module_param(gst_v4l2src_is_broken, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - MODULE_PARM_DESC(gst_v4l2src_is_broken, "If non-zero, enable workaround for Gstreamer"); - --static struct bm2835_mmal_dev *gdev; /* global device data */ -+/* global device data array */ -+static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS]; - - #define FPS_MIN 1 - #define FPS_MAX 90 -@@ -413,6 +421,17 @@ static int enable_camera(struct bm2835_mmal_dev *dev) - { - int ret; - if (!dev->camera_use_count) { -+ ret = vchiq_mmal_port_parameter_set( -+ dev->instance, -+ &dev->component[MMAL_COMPONENT_CAMERA]->control, -+ MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num, -+ sizeof(dev->camera_num)); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, -+ "Failed setting camera num, ret %d\n", ret); -+ return -EINVAL; -+ } -+ - ret = vchiq_mmal_component_enable( - dev->instance, - dev->component[MMAL_COMPONENT_CAMERA]); -@@ -647,6 +666,30 @@ static struct vb2_ops bm2835_mmal_video_qops = { - IOCTL operations - ------------------------------------------------------------------*/ - -+static int set_overlay_params(struct bm2835_mmal_dev *dev, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ struct mmal_parameter_displayregion prev_config = { -+ .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA | -+ MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN, -+ .layer = PREVIEW_LAYER, -+ .alpha = dev->overlay.global_alpha, -+ .fullscreen = 0, -+ .dest_rect = { -+ .x = dev->overlay.w.left, -+ .y = dev->overlay.w.top, -+ .width = dev->overlay.w.width, -+ .height = dev->overlay.w.height, -+ }, -+ }; -+ ret = vchiq_mmal_port_parameter_set(dev->instance, port, -+ MMAL_PARAMETER_DISPLAYREGION, -+ &prev_config, sizeof(prev_config)); -+ -+ return ret; -+} -+ - /* overlay ioctl */ - static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -@@ -678,10 +721,31 @@ static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, - static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) - { -- /* Only support one format so get the current one. */ -- vidioc_g_fmt_vid_overlay(file, priv, f); -+ struct bm2835_mmal_dev *dev = video_drvdata(file); - -- /* todo: allow the size and/or offset to be changed. */ -+ f->fmt.win.field = V4L2_FIELD_NONE; -+ f->fmt.win.chromakey = 0; -+ f->fmt.win.clips = NULL; -+ f->fmt.win.clipcount = 0; -+ f->fmt.win.bitmap = NULL; -+ -+ v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, MAX_WIDTH, 1, -+ &f->fmt.win.w.height, MIN_HEIGHT, MAX_HEIGHT, -+ 1, 0); -+ v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, MAX_WIDTH, 1, -+ &f->fmt.win.w.top, MIN_HEIGHT, MAX_HEIGHT, -+ 1, 0); -+ -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "Overlay: Now w/h %dx%d l/t %dx%d\n", -+ f->fmt.win.w.width, f->fmt.win.w.height, -+ f->fmt.win.w.left, f->fmt.win.w.top); -+ -+ v4l2_dump_win_format(1, -+ bcm2835_v4l2_debug, -+ &dev->v4l2_dev, -+ &f->fmt.win, -+ __func__); - return 0; - } - -@@ -693,8 +757,11 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, - vidioc_try_fmt_vid_overlay(file, priv, f); - - dev->overlay = f->fmt.win; -+ if (dev->component[MMAL_COMPONENT_PREVIEW]->enabled) { -+ set_overlay_params(dev, -+ &dev->component[MMAL_COMPONENT_PREVIEW]->input[0]); -+ } - -- /* todo: program the preview port parameters */ - return 0; - } - -@@ -704,20 +771,6 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) - struct bm2835_mmal_dev *dev = video_drvdata(file); - struct vchiq_mmal_port *src; - struct vchiq_mmal_port *dst; -- struct mmal_parameter_displayregion prev_config = { -- .set = MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_ALPHA | -- MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_FULLSCREEN, -- .layer = PREVIEW_LAYER, -- .alpha = 255, -- .fullscreen = 0, -- .dest_rect = { -- .x = dev->overlay.w.left, -- .y = dev->overlay.w.top, -- .width = dev->overlay.w.width, -- .height = dev->overlay.w.height, -- }, -- }; -- - if ((on && dev->component[MMAL_COMPONENT_PREVIEW]->enabled) || - (!on && !dev->component[MMAL_COMPONENT_PREVIEW]->enabled)) - return 0; /* already in requested state */ -@@ -749,9 +802,7 @@ static int vidioc_overlay(struct file *file, void *f, unsigned int on) - if (ret < 0) - goto error; - -- ret = vchiq_mmal_port_parameter_set(dev->instance, dst, -- MMAL_PARAMETER_DISPLAYREGION, -- &prev_config, sizeof(prev_config)); -+ ret = set_overlay_params(dev, dst); - if (ret < 0) - goto error; - -@@ -782,6 +833,9 @@ static int vidioc_g_fbuf(struct file *file, void *fh, - struct vchiq_mmal_port *preview_port = - &dev->component[MMAL_COMPONENT_CAMERA]-> - output[MMAL_CAMERA_PORT_PREVIEW]; -+ -+ a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | -+ V4L2_FBUF_CAP_GLOBAL_ALPHA; - a->flags = V4L2_FBUF_FLAG_OVERLAY; - a->fmt.width = preview_port->es.video.width; - a->fmt.height = preview_port->es.video.height; -@@ -1445,6 +1499,34 @@ static struct video_device vdev_template = { - .release = video_device_release_empty, - }; - -+static int get_num_cameras(struct vchiq_mmal_instance *instance) -+{ -+ int ret; -+ struct vchiq_mmal_component *cam_info_component; -+ struct mmal_parameter_camera_info_t cam_info = {0}; -+ int param_size = sizeof(cam_info); -+ -+ /* create a camera_info component */ -+ ret = vchiq_mmal_component_init(instance, "camera_info", -+ &cam_info_component); -+ if (ret < 0) -+ /* Unusual failure - let's guess one camera. */ -+ return 1; -+ -+ if (vchiq_mmal_port_parameter_get(instance, -+ &cam_info_component->control, -+ MMAL_PARAMETER_CAMERA_INFO, -+ &cam_info, -+ ¶m_size)) { -+ pr_info("Failed to get camera info\n"); -+ } -+ -+ vchiq_mmal_component_finalise(instance, -+ cam_info_component); -+ -+ return cam_info.num_cameras; -+} -+ - static int set_camera_parameters(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *camera) - { -@@ -1685,7 +1767,9 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev, - /* video device needs to be able to access instance data */ - video_set_drvdata(vfd, dev); - -- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); -+ ret = video_register_device(vfd, -+ VFL_TYPE_GRABBER, -+ video_nr[dev->camera_num]); - if (ret < 0) - return ret; - -@@ -1696,10 +1780,52 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev, - return 0; - } - -+void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev) -+{ -+ if (!dev) -+ return; -+ -+ v4l2_info(&dev->v4l2_dev, "unregistering %s\n", -+ video_device_node_name(&dev->vdev)); -+ -+ video_unregister_device(&dev->vdev); -+ -+ if (dev->capture.encode_component) { -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "mmal_exit - disconnect tunnel\n"); -+ vchiq_mmal_port_connect_tunnel(dev->instance, -+ dev->capture.camera_port, NULL); -+ vchiq_mmal_component_disable(dev->instance, -+ dev->capture.encode_component); -+ } -+ vchiq_mmal_component_disable(dev->instance, -+ dev->component[MMAL_COMPONENT_CAMERA]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev-> -+ component[MMAL_COMPONENT_VIDEO_ENCODE]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev-> -+ component[MMAL_COMPONENT_IMAGE_ENCODE]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev->component[MMAL_COMPONENT_PREVIEW]); -+ -+ vchiq_mmal_component_finalise(dev->instance, -+ dev->component[MMAL_COMPONENT_CAMERA]); -+ -+ v4l2_ctrl_handler_free(&dev->ctrl_handler); -+ -+ v4l2_device_unregister(&dev->v4l2_dev); -+ -+ kfree(dev); -+} -+ - static struct v4l2_format default_v4l2_format = { - .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG, - .fmt.pix.width = 1024, -- .fmt.pix.bytesperline = 1024, -+ .fmt.pix.bytesperline = 0, - .fmt.pix.height = 768, - .fmt.pix.sizeimage = 1024*768, - }; -@@ -1709,76 +1835,93 @@ static int __init bm2835_mmal_init(void) - int ret; - struct bm2835_mmal_dev *dev; - struct vb2_queue *q; -+ int camera; -+ unsigned int num_cameras; -+ struct vchiq_mmal_instance *instance; - -- dev = kzalloc(sizeof(*gdev), GFP_KERNEL); -- if (!dev) -- return -ENOMEM; -- -- /* setup device defaults */ -- dev->overlay.w.left = 150; -- dev->overlay.w.top = 50; -- dev->overlay.w.width = 1024; -- dev->overlay.w.height = 768; -- dev->overlay.clipcount = 0; -- dev->overlay.field = V4L2_FIELD_NONE; -- -- dev->capture.fmt = &formats[3]; /* JPEG */ -- -- /* v4l device registration */ -- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), -- "%s", BM2835_MMAL_MODULE_NAME); -- ret = v4l2_device_register(NULL, &dev->v4l2_dev); -- if (ret) -- goto free_dev; -- -- /* setup v4l controls */ -- ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); -+ ret = vchiq_mmal_init(&instance); - if (ret < 0) -- goto unreg_dev; -- dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; -+ return ret; - -- /* mmal init */ -- ret = mmal_init(dev); -- if (ret < 0) -- goto unreg_dev; -- -- /* initialize queue */ -- q = &dev->capture.vb_vidq; -- memset(q, 0, sizeof(*q)); -- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; -- q->drv_priv = dev; -- q->buf_struct_size = sizeof(struct mmal_buffer); -- q->ops = &bm2835_mmal_video_qops; -- q->mem_ops = &vb2_vmalloc_memops; -- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -- ret = vb2_queue_init(q); -- if (ret < 0) -- goto unreg_dev; -+ num_cameras = get_num_cameras(instance); -+ if (num_cameras > MAX_BCM2835_CAMERAS) -+ num_cameras = MAX_BCM2835_CAMERAS; - -- /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */ -- mutex_init(&dev->mutex); -+ for (camera = 0; camera < num_cameras; camera++) { -+ dev = kzalloc(sizeof(struct bm2835_mmal_dev), GFP_KERNEL); -+ if (!dev) -+ return -ENOMEM; - -- /* initialise video devices */ -- ret = bm2835_mmal_init_device(dev, &dev->vdev); -- if (ret < 0) -- goto unreg_dev; -+ dev->camera_num = camera; - -- /* Really want to call vidioc_s_fmt_vid_cap with the default -- * format, but currently the APIs don't join up. -- */ -- ret = mmal_setup_components(dev, &default_v4l2_format); -- if (ret < 0) { -- v4l2_err(&dev->v4l2_dev, -- "%s: could not setup components\n", __func__); -- goto unreg_dev; -- } -+ /* setup device defaults */ -+ dev->overlay.w.left = 150; -+ dev->overlay.w.top = 50; -+ dev->overlay.w.width = 1024; -+ dev->overlay.w.height = 768; -+ dev->overlay.clipcount = 0; -+ dev->overlay.field = V4L2_FIELD_NONE; -+ dev->overlay.global_alpha = 255; - -- v4l2_info(&dev->v4l2_dev, -- "Broadcom 2835 MMAL video capture ver %s loaded.\n", -- BM2835_MMAL_VERSION); -+ dev->capture.fmt = &formats[3]; /* JPEG */ -+ -+ /* v4l device registration */ -+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), -+ "%s", BM2835_MMAL_MODULE_NAME); -+ ret = v4l2_device_register(NULL, &dev->v4l2_dev); -+ if (ret) -+ goto free_dev; -+ -+ /* setup v4l controls */ -+ ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); -+ if (ret < 0) -+ goto unreg_dev; -+ dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; -+ -+ /* mmal init */ -+ dev->instance = instance; -+ ret = mmal_init(dev); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* initialize queue */ -+ q = &dev->capture.vb_vidq; -+ memset(q, 0, sizeof(*q)); -+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; -+ q->drv_priv = dev; -+ q->buf_struct_size = sizeof(struct mmal_buffer); -+ q->ops = &bm2835_mmal_video_qops; -+ q->mem_ops = &vb2_vmalloc_memops; -+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -+ ret = vb2_queue_init(q); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */ -+ mutex_init(&dev->mutex); -+ -+ /* initialise video devices */ -+ ret = bm2835_mmal_init_device(dev, &dev->vdev); -+ if (ret < 0) -+ goto unreg_dev; -+ -+ /* Really want to call vidioc_s_fmt_vid_cap with the default -+ * format, but currently the APIs don't join up. -+ */ -+ ret = mmal_setup_components(dev, &default_v4l2_format); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, -+ "%s: could not setup components\n", __func__); -+ goto unreg_dev; -+ } - -- gdev = dev; -+ v4l2_info(&dev->v4l2_dev, -+ "Broadcom 2835 MMAL video capture ver %s loaded.\n", -+ BM2835_MMAL_VERSION); -+ -+ gdev[camera] = dev; -+ } - return 0; - - unreg_dev: -@@ -1788,8 +1931,11 @@ unreg_dev: - free_dev: - kfree(dev); - -- v4l2_err(&dev->v4l2_dev, -- "%s: error %d while loading driver\n", -+ for ( ; camera > 0; camera--) { -+ bcm2835_cleanup_instance(gdev[camera]); -+ gdev[camera] = NULL; -+ } -+ pr_info("%s: error %d while loading driver\n", - BM2835_MMAL_MODULE_NAME, ret); - - return ret; -@@ -1797,46 +1943,14 @@ free_dev: - - static void __exit bm2835_mmal_exit(void) - { -- if (!gdev) -- return; -- -- v4l2_info(&gdev->v4l2_dev, "unregistering %s\n", -- video_device_node_name(&gdev->vdev)); -+ int camera; -+ struct vchiq_mmal_instance *instance = gdev[0]->instance; - -- video_unregister_device(&gdev->vdev); -- -- if (gdev->capture.encode_component) { -- v4l2_dbg(1, bcm2835_v4l2_debug, &gdev->v4l2_dev, -- "mmal_exit - disconnect tunnel\n"); -- vchiq_mmal_port_connect_tunnel(gdev->instance, -- gdev->capture.camera_port, NULL); -- vchiq_mmal_component_disable(gdev->instance, -- gdev->capture.encode_component); -+ for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) { -+ bcm2835_cleanup_instance(gdev[camera]); -+ gdev[camera] = NULL; - } -- vchiq_mmal_component_disable(gdev->instance, -- gdev->component[MMAL_COMPONENT_CAMERA]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev-> -- component[MMAL_COMPONENT_VIDEO_ENCODE]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev-> -- component[MMAL_COMPONENT_IMAGE_ENCODE]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev->component[MMAL_COMPONENT_PREVIEW]); -- -- vchiq_mmal_component_finalise(gdev->instance, -- gdev->component[MMAL_COMPONENT_CAMERA]); -- -- vchiq_mmal_finalise(gdev->instance); -- -- v4l2_ctrl_handler_free(&gdev->ctrl_handler); -- -- v4l2_device_unregister(&gdev->v4l2_dev); -- -- kfree(gdev); -+ vchiq_mmal_finalise(instance); - } - - module_init(bm2835_mmal_init); -diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h -index 7fe9f65..202906b 100644 ---- a/drivers/media/platform/bcm2835/bcm2835-camera.h -+++ b/drivers/media/platform/bcm2835/bcm2835-camera.h -@@ -15,7 +15,7 @@ - * core driver device - */ - --#define V4L2_CTRL_COUNT 28 /* number of v4l controls */ -+#define V4L2_CTRL_COUNT 29 /* number of v4l controls */ - - enum { - MMAL_COMPONENT_CAMERA = 0, -@@ -58,6 +58,8 @@ struct bm2835_mmal_dev { - enum mmal_parameter_exposuremeteringmode metering_mode; - unsigned int manual_shutter_speed; - bool exp_auto_priority; -+ bool manual_iso_enabled; -+ uint32_t iso; - - /* allocated mmal instance and components */ - struct vchiq_mmal_instance *instance; -@@ -104,6 +106,8 @@ struct bm2835_mmal_dev { - - } capture; - -+ unsigned int camera_num; -+ - }; - - int bm2835_mmal_init_controls( -@@ -124,3 +128,16 @@ int set_framerate_params(struct bm2835_mmal_dev *dev); - (pix_fmt)->pixelformat, (pix_fmt)->bytesperline, \ - (pix_fmt)->sizeimage, (pix_fmt)->colorspace, (pix_fmt)->priv); \ - } -+#define v4l2_dump_win_format(level, debug, dev, win_fmt, desc) \ -+{ \ -+ v4l2_dbg(level, debug, dev, \ -+"%s: w %u h %u l %u t %u field %u chromakey %06X clip %p " \ -+"clipcount %u bitmap %p\n", \ -+ desc == NULL ? "" : desc, \ -+ (win_fmt)->w.width, (win_fmt)->w.height, \ -+ (win_fmt)->w.left, (win_fmt)->w.top, \ -+ (win_fmt)->field, \ -+ (win_fmt)->chromakey, \ -+ (win_fmt)->clips, (win_fmt)->clipcount, \ -+ (win_fmt)->bitmap); \ -+} -diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c -index f9f903f..fe61330 100644 ---- a/drivers/media/platform/bcm2835/controls.c -+++ b/drivers/media/platform/bcm2835/controls.c -@@ -49,10 +49,13 @@ static const s64 ev_bias_qmenu[] = { - 4000 - }; - --/* Supported ISO values -+/* Supported ISO values (*1000) - * ISOO = auto ISO - */ - static const s64 iso_qmenu[] = { -+ 0, 100000, 200000, 400000, 800000, -+}; -+static const uint32_t iso_values[] = { - 0, 100, 200, 400, 800, - }; - -@@ -201,7 +204,7 @@ static int ctrl_set_value(struct bm2835_mmal_dev *dev, - &u32_value, sizeof(u32_value)); - } - --static int ctrl_set_value_menu(struct bm2835_mmal_dev *dev, -+static int ctrl_set_iso(struct bm2835_mmal_dev *dev, - struct v4l2_ctrl *ctrl, - const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl) - { -@@ -211,12 +214,23 @@ static int ctrl_set_value_menu(struct bm2835_mmal_dev *dev, - if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min) - return 1; - -+ if (ctrl->id == V4L2_CID_ISO_SENSITIVITY) -+ dev->iso = iso_values[ctrl->val]; -+ else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO) -+ dev->manual_iso_enabled = -+ (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL ? -+ true : -+ false); -+ - control = &dev->component[MMAL_COMPONENT_CAMERA]->control; - -- u32_value = mmal_ctrl->imenu[ctrl->val]; -+ if (dev->manual_iso_enabled) -+ u32_value = dev->iso; -+ else -+ u32_value = 0; - - return vchiq_mmal_port_parameter_set(dev->instance, control, -- mmal_ctrl->mmal_id, -+ MMAL_PARAMETER_ISO, - &u32_value, sizeof(u32_value)); - } - -@@ -956,7 +970,14 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = { - V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU, - 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu, - MMAL_PARAMETER_ISO, -- &ctrl_set_value_menu, -+ &ctrl_set_iso, -+ false -+ }, -+ { -+ V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, -+ 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, -+ MMAL_PARAMETER_ISO, -+ &ctrl_set_iso, - false - }, - { -diff --git a/drivers/media/platform/bcm2835/mmal-parameters.h b/drivers/media/platform/bcm2835/mmal-parameters.h -index aa0fd18..f6abb5c 100644 ---- a/drivers/media/platform/bcm2835/mmal-parameters.h -+++ b/drivers/media/platform/bcm2835/mmal-parameters.h -@@ -654,3 +654,36 @@ struct mmal_parameter_imagefx_parameters { - u32 num_effect_params; - u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; - }; -+ -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 -+ -+struct mmal_parameter_camera_info_camera_t { -+ u32 port_id; -+ u32 max_width; -+ u32 max_height; -+ u32 lens_present; -+ u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; -+}; -+ -+enum mmal_parameter_camera_info_flash_type_t { -+ /* Make values explicit to ensure they match values in config ini */ -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF -+}; -+ -+struct mmal_parameter_camera_info_flash_t { -+ enum mmal_parameter_camera_info_flash_type_t flash_type; -+}; -+ -+struct mmal_parameter_camera_info_t { -+ u32 num_cameras; -+ u32 num_flashes; -+ struct mmal_parameter_camera_info_camera_t -+ cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; -+ struct mmal_parameter_camera_info_flash_t -+ flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; -+}; - -From 4366809281c7cf500e97f9a113cb1234d273aed3 Mon Sep 17 00:00:00 2001 +From 60b77dc3f91119ad7cb3a2ae39797754575bc275 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 Apr 2016 12:50:58 +0100 -Subject: [PATCH 231/251] bcm2835-sdhost: Reset the clock in task context +Subject: [PATCH 105/114] bcm2835-sdhost: Reset the clock in task context Since reprogramming the clock can now involve a round-trip to the firmware it must not be done at atomic context, and a tasklet @@ -164054,1273 +131804,55 @@ index 54087b2..a57faed 100644 host->pio_limit = 1; host->max_delay = 1; /* Warn if over 1ms */ -From 37e270746e49ee6bf0e7a8404503e67364519ce2 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 7 Apr 2016 12:44:24 +0100 -Subject: [PATCH 232/251] config: Enable CONFIG_IPV6_ROUTER_PREF for networks - with multiple routers +From c439a5c39d8d64ddd8d835cac6b42550811d3581 Mon Sep 17 00:00:00 2001 +From: Sam Nazarko +Date: Fri, 1 Apr 2016 17:27:21 +0100 +Subject: [PATCH 106/114] add smsc95xx packetsize module_param +Signed-off-by: Sam Nazarko --- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) + drivers/net/usb/smsc95xx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 299d7be..7bfc073 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -101,6 +101,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index acda16b..59026b3 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -95,6 +95,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - -From aa9f1aedb9a495b6688cc30a17a0b01c3ab03f8c Mon Sep 17 00:00:00 2001 -From: jochenberger -Date: Thu, 7 Apr 2016 21:38:46 +0200 -Subject: [PATCH 233/251] Enable hid-betopff module - -Add force feedback support for Betop based devices -https://github.com/raspberrypi/linux/blob/rpi-4.1.y/drivers/hid/hid-betopff.c ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7bfc073..31e3ac5 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -867,6 +867,7 @@ CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m - CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m - CONFIG_HID_CHERRY=m - CONFIG_HID_CHICONY=m - CONFIG_HID_CYPRESS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 59026b3..ac9287f 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -859,6 +859,7 @@ CONFIG_HID_A4TECH=m - CONFIG_HID_ACRUX=m - CONFIG_HID_APPLE=m - CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m - CONFIG_HID_CHERRY=m - CONFIG_HID_CHICONY=m - CONFIG_HID_CYPRESS=m - -From 51edceabf0a57229b0ccb3742640aefe4fcb161d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 12 Apr 2016 12:45:16 +0100 -Subject: [PATCH 234/251] config: Make IPV6 a module and regenerate with - defconfig - ---- - arch/arm/configs/bcm2709_defconfig | 4 ++-- - arch/arm/configs/bcmrpi_defconfig | 6 +++--- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 31e3ac5..5a8ab1e 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -101,6 +101,7 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6=m - CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m -@@ -600,10 +601,9 @@ CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m --CONFIG_I2C_MUX=m --CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index ac9287f..852751e 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -73,7 +73,6 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y --CONFIG_IPV6_SUBTREES=y - CONFIG_IP_ROUTE_MULTIPATH=y - CONFIG_IP_ROUTE_VERBOSE=y - CONFIG_IP_PNP=y -@@ -95,12 +94,14 @@ CONFIG_INET_XFRM_MODE_TUNNEL=m - CONFIG_INET_XFRM_MODE_BEET=m - CONFIG_INET_LRO=m - CONFIG_INET_DIAG=m -+CONFIG_IPV6=m - CONFIG_IPV6_ROUTER_PREF=y - CONFIG_INET6_AH=m - CONFIG_INET6_ESP=m - CONFIG_INET6_IPCOMP=m - CONFIG_IPV6_TUNNEL=m - CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y - CONFIG_IPV6_MROUTE=y - CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y - CONFIG_IPV6_PIMSM_V2=y -@@ -593,10 +594,9 @@ CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_GPIO=m --CONFIG_I2C_MUX=m --CONFIG_I2C_MUX_PCA954x=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m - -From 037a9e0fd0cb7eeb947bb4dbff674833419dd7f7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 5 Apr 2016 13:01:54 +0100 -Subject: [PATCH 235/251] BCM270X_DT: Add dpi24 overlay - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 +++++++ - arch/arm/boot/dts/overlays/dpi24-overlay.dts | 31 ++++++++++++++++++++++++++++ - 3 files changed, 40 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/dpi24-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 239c6a1..688ba0b 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -15,6 +15,7 @@ endif - dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 9df71a4..1438908 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -213,6 +213,14 @@ Params: gpiopin GPIO connected to the sensor's DATA output. - (default 4) +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index a61bd08..3c23b11 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -83,6 +83,10 @@ static char *macaddr = ":"; + module_param(macaddr, charp, 0); + MODULE_PARM_DESC(macaddr, "MAC address"); - -+Name: dpi24 -+Info: Overlay for a generic 24-bit DPI display -+ This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output -+ 2-3 seconds after the kernel has started. -+Load: dtoverlay=dpi24 -+Params: ++static int packetsize = 0; ++module_param(packetsize, int, 0644); ++MODULE_PARM_DESC(packetsize, "Override the RX URB packet size"); + -+ - Name: dwc-otg - Info: Selects the dwc_otg USB controller driver which has fiq support. This - is the default on all except the Pi Zero which defaults to dwc2. -diff --git a/arch/arm/boot/dts/overlays/dpi24-overlay.dts b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -new file mode 100644 -index 0000000..e4dbe40 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -@@ -0,0 +1,31 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ // There is no DPI driver module, but we need a platform device -+ // node (that doesn't already use pinctrl) to hang the pinctrl -+ // reference on - leds will do -+ -+ fragment@0 { -+ target = <&leds>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dpi24_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ dpi24_pins: dpi24_pins { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15 16 17 18 19 20 -+ 21 22 23 24 25 26 27>; -+ brcm,function = <6>; /* alt2 */ -+ brcm,pull = <0>; /* no pull */ -+ }; -+ }; -+ }; -+}; - -From 8e95bfba2bfc4186ee007176c9d2f7c42c369312 Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Thu, 14 Apr 2016 00:57:33 +0100 -Subject: [PATCH 236/251] Modify IQAudIO DAC+ ASoC driver to set card/dai - config from dt - -Add the ability to set the card name, dai name and dai stream name, from -dt config. - -Signed-off-by: DigitalDreamtime ---- - sound/soc/bcm/iqaudio-dac.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index a5eaa9e..b6b6dcf 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -61,8 +61,6 @@ static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { - - static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) { -- .name = "IQaudIO DAC", -- .stream_name = "IQaudIO DAC HiFi", - .cpu_dai_name = "bcm2708-i2s.0", - .codec_dai_name = "pcm512x-hifi", - .platform_name = "bcm2708-i2s.0", -@@ -76,7 +74,6 @@ static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { +@@ -1006,13 +1010,13 @@ static int smsc95xx_reset(struct usbnet *dev) - /* audio machine driver */ - static struct snd_soc_card snd_rpi_iqaudio_dac = { -- .name = "IQaudIODAC", - .owner = THIS_MODULE, - .dai_link = snd_rpi_iqaudio_dac_dai, - .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), -@@ -90,6 +87,7 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - - if (pdev->dev.of_node) { - struct device_node *i2s_node; -+ struct snd_soc_card *card = &snd_rpi_iqaudio_dac; - struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; - i2s_node = of_parse_phandle(pdev->dev.of_node, - "i2s-controller", 0); -@@ -103,6 +101,15 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - - digital_gain_0db_limit = !of_property_read_bool(pdev->dev.of_node, - "iqaudio,24db_digital_gain"); -+ if (of_property_read_string(pdev->dev.of_node, "card_name", -+ &card->name)) -+ card->name = "IQaudIODAC"; -+ if (of_property_read_string(pdev->dev.of_node, "dai_name", -+ &dai->name)) -+ dai->name = "IQaudIO DAC"; -+ if (of_property_read_string(pdev->dev.of_node, "dai_stream_name", -+ &dai->stream_name)) -+ dai->stream_name = "IQaudIO DAC HiFi"; + if (!turbo_mode) { + burst_cap = 0; +- dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE; + } else if (dev->udev->speed == USB_SPEED_HIGH) { +- burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; +- dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE; ++ burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE; + } else { +- burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; +- dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; ++ dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE; ++ burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE; } - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); + netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", -From 7ea9f79b042605984245d4a0387f0e667fdc947c Mon Sep 17 00:00:00 2001 -From: DigitalDreamtime -Date: Thu, 14 Apr 2016 01:00:58 +0100 -Subject: [PATCH 237/251] Add support for the Digital Dreamtime Akkordion music - player. - -Support the Digital Dreamtime Akkordion using the OEM IQAudIO DAC+ or -DACZero modules. Set ALSA card name, ("Akkordion"), from dt config. - -Signed-off-by: DigitalDreamtime ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 20 ++++++++++ - .../dts/overlays/akkordion-iqdacplus-overlay.dts | 46 ++++++++++++++++++++++ - 3 files changed, 67 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 688ba0b..6bd6048 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - endif - - dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 1438908..5d0887f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -186,6 +186,26 @@ Params: cs SPI bus Chip Select (default 1) - www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt - - -+Name: akkordion-iqdacplus -+Info: Configures the Digital Dreamtime Akkordion Music Player (based on the -+ OEM IQAudIO DAC+ or DAC Zero module). -+Load: dtoverlay=akkordion-iqdacplus,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ dtoverlay=akkordion-iqdacplus,24db_digital_gain -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24db_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ - Name: at86rf233 - Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver, - connected to spi0.0 -diff --git a/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -new file mode 100644 -index 0000000..47c7664 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -@@ -0,0 +1,46 @@ -+// Definitions for Digital Dreamtime Akkordion using IQaudIO DAC+ or DACZero -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ frag0: __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ card_name = "Akkordion"; -+ dai_name = "IQaudIO DAC"; -+ dai_stream_name = "IQaudIO DAC HiFi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"iqaudio,24db_digital_gain?"; -+ }; -+}; - -From 2544f9707d98c5d4251e0d6792a5a40016adedcb Mon Sep 17 00:00:00 2001 -From: Aaron Shaw -Date: Thu, 7 Apr 2016 21:26:21 +0100 -Subject: [PATCH 238/251] Add Support for BoomBerry Audio boards - ---- - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/README | 26 +++ - .../boot/dts/overlays/boomberry-dac-overlay.dts | 43 +++++ - .../boot/dts/overlays/boomberry-digi-overlay.dts | 39 ++++ - arch/arm/configs/bcm2709_defconfig | 2 + - arch/arm/configs/bcmrpi_defconfig | 2 + - sound/soc/bcm/Kconfig | 14 ++ - sound/soc/bcm/Makefile | 4 + - sound/soc/bcm/boomberry-dac.c | 163 ++++++++++++++++ - sound/soc/bcm/boomberry-digi.c | 215 +++++++++++++++++++++ - 10 files changed, 510 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts - create mode 100644 sound/soc/bcm/boomberry-dac.c - create mode 100644 sound/soc/bcm/boomberry-digi.c - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index 6bd6048..4842dc1 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -16,6 +16,8 @@ dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo - dtbo-$(RPI_DT_OVERLAYS) += akkordion-iqdacplus.dtbo - dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo - dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += boomberry-dac.dtbo -+dtbo-$(RPI_DT_OVERLAYS) += boomberry-digi.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo - dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index 5d0887f..eb5fc04 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -225,6 +225,32 @@ Load: dtoverlay=bmp085_i2c-sensor - Params: - - -+Name: boomberry-dac -+Info: Configures the BoomBerry DAC HAT, Amp HAT, DAC Zero and Amp Zero audio -+ cards -+Load: dtoverlay=boomberry-dac,= -+Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec -+ Digital volume control. Enable with -+ "dtoverlay=boomberry-dac,24db_digital_gain" -+ (The default behaviour is that the Digital -+ volume control is limited to a maximum of -+ 0dB. ie. it can attenuate but not provide -+ gain. For most users, this will be desired -+ as it will prevent clipping. By appending -+ the 24dB_digital_gain parameter, the Digital -+ volume control will allow up to 24dB of -+ gain. If this parameter is enabled, it is the -+ responsibility of the user to ensure that -+ the Digital volume control is set to a value -+ that does not result in clipping/distortion!) -+ -+ -+Name: boomberry-digi -+Info: Configures the BoomBerry Digi HAT and Digi Zero audio cards -+Load: dtoverlay=boomberry-digi -+Params: -+ -+ - Name: dht11 - Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors - Also sometimes found with the part number(s) AM230x. -diff --git a/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts -new file mode 100644 -index 0000000..0f7c9b0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/boomberry-dac-overlay.dts -@@ -0,0 +1,43 @@ -+// Definitions for BoomBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ frag0: __overlay__ { -+ compatible = "boomberry,boomberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ 24db_digital_gain = <&frag0>,"boomberry,24db_digital_gain?"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts -new file mode 100644 -index 0000000..a86e1d0 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/boomberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for BoomBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "boomberry,boomberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5a8ab1e..84ec380 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -853,6 +853,8 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SNG_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 852751e..603ba04 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -845,6 +845,8 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 1a3f826..3383381 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -50,6 +50,20 @@ config SND_BCM2708_SOC_RPI_PROTO - help - Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). - -+config SND_BCM2708_SOC_BOOMBERRY_DAC -+ tristate "Support for BoomBerry DAC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_PCM512x -+ help -+ Say Y or M if you want to add support for BoomBerry DAC. -+ -+config SND_BCM2708_SOC_BOOMBERRY_DIGI -+ tristate "Support for BoomBerry Digi" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_WM8804 -+ help -+ Say Y or M if you want to add support for BoomBerry Digi. -+ - config SND_BCM2708_SOC_IQAUDIO_DAC - tristate "Support for IQaudIO-DAC" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index b21e11e..b04b0d2 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -8,6 +8,8 @@ snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-hifiberry-amp-objs := hifiberry_amp.o -+snd-soc-boomberry-dac-objs := boomberry-dac.o -+snd-soc-boomberry-digi-objs := boomberry-digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-rpi-proto-objs := rpi-proto.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o -@@ -17,6 +19,8 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o -+obj-$(CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC) += snd-soc-boomberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI) += snd-soc-boomberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/boomberry-dac.c b/sound/soc/bcm/boomberry-dac.c -new file mode 100644 -index 0000000..08845ad ---- /dev/null -+++ b/sound/soc/bcm/boomberry-dac.c -@@ -0,0 +1,163 @@ -+/* -+ * ASoC Driver for BoomBerry DAC Raspberry Pi HAT Sound Card -+ * -+ * Author: Milan Neskovic -+ * Copyright 2016 -+ * based on code by Daniel Matuschek -+ * based on code by Florian Meier -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/pcm512x.h" -+ -+static bool digital_gain_0db_limit = true; -+ -+static int snd_rpi_boomberry_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ -+ if (digital_gain_0db_limit) -+ { -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); -+ } -+ -+ return 0; -+} -+ -+static int snd_rpi_boomberry_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ /*return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);*/ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+static int snd_rpi_boomberry_dac_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static void snd_rpi_boomberry_dac_shutdown(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_boomberry_dac_ops = { -+ .hw_params = snd_rpi_boomberry_dac_hw_params, -+ .startup = snd_rpi_boomberry_dac_startup, -+ .shutdown = snd_rpi_boomberry_dac_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_boomberry_dac_dai[] = { -+{ -+ .name = "BoomBerry DAC", -+ .stream_name = "BoomBerry DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004d", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_boomberry_dac_ops, -+ .init = snd_rpi_boomberry_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_boomberry_dac = { -+ .name = "snd_rpi_boomberry_dac", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_boomberry_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_boomberry_dac_dai), -+}; -+ -+static int snd_rpi_boomberry_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_boomberry_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_boomberry_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ -+ digital_gain_0db_limit = !of_property_read_bool( -+ pdev->dev.of_node, "boomberry,24db_digital_gain"); -+ } -+ -+ ret = snd_soc_register_card(&snd_rpi_boomberry_dac); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_boomberry_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_boomberry_dac); -+} -+ -+static const struct of_device_id snd_rpi_boomberry_dac_of_match[] = { -+ { .compatible = "boomberry,boomberry-dac", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_boomberry_dac_of_match); -+ -+static struct platform_driver snd_rpi_boomberry_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-boomberry-dac", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_boomberry_dac_of_match, -+ }, -+ .probe = snd_rpi_boomberry_dac_probe, -+ .remove = snd_rpi_boomberry_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_boomberry_dac_driver); -+ -+MODULE_AUTHOR("Milan Neskovic "); -+MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI DAC HAT Sound Card"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/bcm/boomberry-digi.c b/sound/soc/bcm/boomberry-digi.c -new file mode 100644 -index 0000000..3d5b5ff ---- /dev/null -+++ b/sound/soc/bcm/boomberry-digi.c -@@ -0,0 +1,215 @@ -+/* -+ * ASoC Driver for BoomBerry Raspberry Pi Digi HAT Sound Card -+ * -+ * Author: Milan Neskovic -+ * Copyright 2016 -+ * based on code by Daniel Matuschek -+ * based on code by Florian Meier -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/wm8804.h" -+ -+static int snd_rpi_boomberry_digi_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ /* enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ return 0; -+} -+ -+static int snd_rpi_boomberry_digi_startup(struct snd_pcm_substream *substream) { -+ /* turn on digital output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); -+ return 0; -+} -+ -+static void snd_rpi_boomberry_digi_shutdown(struct snd_pcm_substream *substream) { -+ /* turn off output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); -+} -+ -+static int snd_rpi_boomberry_digi_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ int sysclk = 27000000; /* This is fixed on this board */ -+ -+ long mclk_freq=0; -+ int mclk_div=1; -+ int sampling_freq=1; -+ -+ int ret; -+ -+ int samplerate = params_rate(params); -+ -+ if (samplerate<=96000) { -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ } else { -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ } -+ -+ switch (samplerate) { -+ case 32000: -+ sampling_freq=0x03; -+ break; -+ case 44100: -+ sampling_freq=0x00; -+ break; -+ case 48000: -+ sampling_freq=0x02; -+ break; -+ case 88200: -+ sampling_freq=0x08; -+ break; -+ case 96000: -+ sampling_freq=0x0a; -+ break; -+ case 176400: -+ sampling_freq=0x0c; -+ break; -+ case 192000: -+ sampling_freq=0x0e; -+ break; -+ default: -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", -+ samplerate); -+ } -+ -+ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -+ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); -+ -+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, -+ sysclk, SND_SOC_CLOCK_OUT); -+ if (ret < 0) { -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK: %d\n", ret); -+ return ret; -+ } -+ -+ /* Enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ /* Power on */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); -+ -+ /* set sampling frequency status bits */ -+ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_boomberry_digi_ops = { -+ .hw_params = snd_rpi_boomberry_digi_hw_params, -+ .startup = snd_rpi_boomberry_digi_startup, -+ .shutdown = snd_rpi_boomberry_digi_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_boomberry_digi_dai[] = { -+{ -+ .name = "BoomBerry Digi", -+ .stream_name = "BoomBerry Digi HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "wm8804-spdif", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "wm8804.1-003b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &snd_rpi_boomberry_digi_ops, -+ .init = snd_rpi_boomberry_digi_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_boomberry_digi = { -+ .name = "snd_rpi_boomberry_digi", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_boomberry_digi_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_boomberry_digi_dai), -+}; -+ -+static int snd_rpi_boomberry_digi_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_boomberry_digi.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_boomberry_digi_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ -+ ret = snd_soc_register_card(&snd_rpi_boomberry_digi); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_boomberry_digi_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_boomberry_digi); -+} -+ -+static const struct of_device_id snd_rpi_boomberry_digi_of_match[] = { -+ { .compatible = "boomberry,boomberry-digi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_boomberry_digi_of_match); -+ -+static struct platform_driver snd_rpi_boomberry_digi_driver = { -+ .driver = { -+ .name = "snd-rpi-boomberry-digi", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_boomberry_digi_of_match, -+ }, -+ .probe = snd_rpi_boomberry_digi_probe, -+ .remove = snd_rpi_boomberry_digi_remove, -+}; -+ -+module_platform_driver(snd_rpi_boomberry_digi_driver); -+ -+MODULE_AUTHOR("Milan Neskovic "); -+MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI Digi HAT Sound Card"); -+MODULE_LICENSE("GPL v2"); - -From e3ea2e74ce1c734d3bbfd1270e8934cb3de80431 Mon Sep 17 00:00:00 2001 -From: Aaron Shaw -Date: Fri, 8 Apr 2016 00:06:00 +0100 -Subject: [PATCH 239/251] Add support for mcp7940x family of RTC - ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 6 ++++++ - 2 files changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index eb5fc04..6a62e6f 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -435,6 +435,8 @@ Params: ds1307 Select the DS1307 device - - ds3231 Select the DS3231 device - -+ mcp7940x Select the MCP7940x device -+ - mcp7941x Select the MCP7941x device - - pcf2127 Select the PCF2127 device -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -index eecec16..4065647 100644 ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -23,6 +23,11 @@ - reg = <0x68>; - status = "disable"; - }; -+ mcp7940x: mcp7940x@6f { -+ compatible = "microchip,mcp7940x"; -+ reg = <0x6f>; -+ status = "disable"; -+ }; - mcp7941x: mcp7941x@6f { - compatible = "microchip,mcp7941x"; - reg = <0x6f>; -@@ -54,6 +59,7 @@ - ds1307 = <&ds1307>,"status"; - ds1339 = <&ds1339>,"status"; - ds3231 = <&ds3231>,"status"; -+ mcp7940x = <&mcp7940x>,"status"; - mcp7941x = <&mcp7941x>,"status"; - pcf2127 = <&pcf2127>,"status"; - pcf8523 = <&pcf8523>,"status"; - -From a10d74e309c02ad451678e59c320d62208944605 Mon Sep 17 00:00:00 2001 -From: Jeremy McDermond -Date: Thu, 14 Apr 2016 09:39:20 -0700 -Subject: [PATCH 240/251] bcm2709_defconfig: Fix typo on BoomBerry - configuration directive - -The BoomBerry configuration directive in bcm2709_defconfig has a typo. ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 84ec380..7353332 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -854,7 +854,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SNG_BCM2708_SOC_BOOMBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - -From eb62c144a47bbc7d0015d65629fad05884aa654b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 15 Apr 2016 10:48:39 +0100 -Subject: [PATCH 241/251] boomberry-dac: Adjust for ALSA API change - -As of 4.4, snd_soc_limit_volume now takes a struct snd_soc_card * -rather than a struct snd_soc_codec *. - -Signed-off-by: Phil Elwell ---- - sound/soc/bcm/boomberry-dac.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/sound/soc/bcm/boomberry-dac.c b/sound/soc/bcm/boomberry-dac.c -index 08845ad..8d39de2 100644 ---- a/sound/soc/bcm/boomberry-dac.c -+++ b/sound/soc/bcm/boomberry-dac.c -@@ -40,9 +40,8 @@ static int snd_rpi_boomberry_dac_init(struct snd_soc_pcm_runtime *rtd) - { - int ret; - struct snd_soc_card *card = rtd->card; -- struct snd_soc_codec *codec = rtd->codec; - -- ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); - if (ret < 0) - dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); - } - -From d113d5842f6896cdcdd7c7c2e5733fe0ed0a5b06 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Sun, 17 Apr 2016 04:44:47 -0700 -Subject: [PATCH 242/251] vmcs: Remove unused sm_cache_map_vector definition - (#1411) - -The code using it also ifdef'ed with 0, anyyd gcc 6 -complains - -error: 'sm_cache_map_vector' defined but not used - -The code using it also ifdef'ed out - -Signed-off-by: Khem Raj ---- - drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 5d16e35..1db6716 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -197,12 +197,14 @@ struct SM_STATE_T { - static struct SM_STATE_T *sm_state; - static int sm_inited; - -+#if 0 - static const char *const sm_cache_map_vector[] = { - "(null)", - "host", - "videocore", - "host+videocore", - }; -+#endif - - /* ---- Private Function Prototypes -------------------------------------- */ - - -From 8842f5b24445286359d13b8f85230384a361f26b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 Apr 2016 11:56:53 +0100 -Subject: [PATCH 243/251] scripts/mkknlimg: Append a trailer for all input - -Now that the firmware assumes an unsigned kernel is DT-capable, it is -helpful to be able to mark a kernel as being non-DT-capable. - -Signed-off-by: Phil Elwell ---- - scripts/mkknlimg | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index 005f404..78c5845 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -98,7 +98,7 @@ my $append_trailer; - my $trailer; - my $kver = '?'; - --$append_trailer = $dtok; -+$append_trailer = 1; - - if ($res) - { -@@ -108,7 +108,6 @@ if ($res) - - if ($flags & FLAG_PI) - { -- $append_trailer = 1; - $dtok ||= ($flags & FLAG_DTOK) != 0; - $is_270x ||= ($flags & FLAG_270X) != 0; - $is_283x ||= ($flags & FLAG_283X) != 0; -@@ -116,18 +115,18 @@ if ($res) - } - else - { -- print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); -+ print ("* This doesn't look like a Raspberry Pi kernel.\n"); - } - } - elsif (!$dtok) - { -- print ("* Is this a valid kernel? In pass-through mode.\n"); -+ print ("* Is this a valid kernel?\n"); - } - - if ($append_trailer) - { - printf("DT: %s\n", $dtok ? "y" : "n"); -- printf("DDT: %s\n", $ddtk ? "y" : "n") if ($ddtk); -+ printf("DDT: %s\n", $ddtk ? "y" : "n"); - printf("270x: %s\n", $is_270x ? "y" : "n"); - printf("283x: %s\n", $is_283x ? "y" : "n"); - -@@ -136,7 +135,7 @@ if ($append_trailer) - push @atoms, [ $trailer_magic, pack('V', 0) ]; - push @atoms, [ 'KVer', $kver ]; - push @atoms, [ 'DTOK', pack('V', $dtok) ]; -- push @atoms, [ 'DDTK', pack('V', $ddtk) ] if ($ddtk); -+ push @atoms, [ 'DDTK', pack('V', $ddtk) ]; - push @atoms, [ '270X', pack('V', $is_270x) ]; - push @atoms, [ '283X', pack('V', $is_283x) ]; - push @atoms, [ '283x', pack('V', $is_283x && !$is_270x) ]; - -From 4713de1914febfd095de6c68d7152c10ba60a475 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Apr 2016 13:55:29 +0100 -Subject: [PATCH 244/251] scripts/dtc: Only emit local fixups for overlays - -Signed-off-by: Phil Elwell ---- - scripts/dtc/checks.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 2b3b3a7..fedfa79 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -514,7 +514,7 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - } - - /* if it's a local reference, we need to record it */ -- if (symbol_fixup_support) { -+ if (symbol_fixup_support && dt->is_plugin) { - - /* allocate a new local fixup entry */ - fe = xmalloc(sizeof(*fe)); - -From 8f691a8d8e5dd4a0e48f3fcc766936215a0efb27 Mon Sep 17 00:00:00 2001 +From 1d3ef6f3ee8e621efbfcf2147d80aba94ed50a12 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 19 Apr 2016 12:57:52 +0100 -Subject: [PATCH 245/251] bcm2835_thermal: Don't report unsupported trip type +Subject: [PATCH 107/114] bcm2835_thermal: Don't report unsupported trip type --- drivers/thermal/bcm2835-thermal.c | 34 +--------------------------------- @@ -165389,316 +131921,301 @@ index 08d8dc7..c63fb9f 100644 if (IS_ERR(tz)) { dev_err(&pdev->dev, "Failed to register the thermal device\n"); -From f92bda16cd790cb612920ed266d19c6ae2620c22 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:08:35 +0200 -Subject: [PATCH 246/251] bcm2835: do not require substream for accessing chmap - ctl +From c1e63a730e6d4ec6d212d39f37a425fc4bbcd7a0 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Sun, 17 Apr 2016 04:44:47 -0700 +Subject: [PATCH 108/114] vmcs: Remove unused sm_cache_map_vector definition + (#1411) -Fixes alsasctl store/restore operation. +The code using it also ifdef'ed with 0, anyyd gcc 6 +complains + +error: 'sm_cache_map_vector' defined but not used + +The code using it also ifdef'ed out + +Signed-off-by: Khem Raj --- - sound/arm/bcm2835-ctl.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) + drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 ++ + 1 file changed, 2 insertions(+) -diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c -index e930718..8b855f9 100755 ---- a/sound/arm/bcm2835-ctl.c -+++ b/sound/arm/bcm2835-ctl.c -@@ -489,8 +489,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, +diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c +index 5d16e35..1db6716 100644 +--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c ++++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c +@@ -197,12 +197,14 @@ struct SM_STATE_T { + static struct SM_STATE_T *sm_state; + static int sm_inited; + ++#if 0 + static const char *const sm_cache_map_vector[] = { + "(null)", + "host", + "videocore", + "host+videocore", + }; ++#endif + + /* ---- Private Function Prototypes -------------------------------------- */ + + +From 150f46922b0f2da460cc2cd447c6c039285dce27 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 5 Apr 2016 13:01:54 +0100 +Subject: [PATCH 109/114] BCM270X_DT: Add dpi24 overlay + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 +++++++ + arch/arm/boot/dts/overlays/dpi24-overlay.dts | 31 ++++++++++++++++++++++++++++ + 3 files changed, 40 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/dpi24-overlay.dts + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 7c4fc30..e6daef5 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -15,6 +15,7 @@ endif + dtbo-$(RPI_DT_OVERLAYS) += ads7846.dtbo + dtbo-$(RPI_DT_OVERLAYS) += at86rf233.dtbo + dtbo-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor.dtbo ++dtbo-$(RPI_DT_OVERLAYS) += dpi24.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dwc2.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dwc-otg.dtbo + dtbo-$(RPI_DT_OVERLAYS) += dht11.dtbo +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index e88e7c8..5f8e4fd 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -213,6 +213,14 @@ Params: gpiopin GPIO connected to the sensor's DATA output. + (default 4) + + ++Name: dpi24 ++Info: Overlay for a generic 24-bit DPI display ++ This uses GPIOs 0-27 (so no I2C, uart etc.), and activates the output ++ 2-3 seconds after the kernel has started. ++Load: dtoverlay=dpi24 ++Params: ++ ++ + Name: dwc-otg + Info: Selects the dwc_otg USB controller driver which has fiq support. This + is the default on all except the Pi Zero which defaults to dwc2. +diff --git a/arch/arm/boot/dts/overlays/dpi24-overlay.dts b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +new file mode 100644 +index 0000000..e4dbe40 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +@@ -0,0 +1,31 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ // There is no DPI driver module, but we need a platform device ++ // node (that doesn't already use pinctrl) to hang the pinctrl ++ // reference on - leds will do ++ ++ fragment@0 { ++ target = <&leds>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dpi24_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ dpi24_pins: dpi24_pins { ++ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 ++ 12 13 14 15 16 17 18 19 20 ++ 21 22 23 24 25 26 27>; ++ brcm,function = <6>; /* alt2 */ ++ brcm,pull = <0>; /* no pull */ ++ }; ++ }; ++ }; ++}; + +From 21f5b65c2dfc30fd3c75bb9ad242eed0c5f3a5d8 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 5 Apr 2016 19:40:12 +0100 +Subject: [PATCH 110/114] reboot: Use power off rather than busy spinning when + halt is requested + +--- + arch/arm/kernel/reboot.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c +index 71a2ff9..812c15e 100644 +--- a/arch/arm/kernel/reboot.c ++++ b/arch/arm/kernel/reboot.c +@@ -102,11 +102,7 @@ void machine_shutdown(void) + */ + void machine_halt(void) { - struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); - bcm2835_chip_t *chip = info->private_data; -- unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); -- struct snd_pcm_substream *substream = snd_pcm_chmap_substream(info, idx); - struct cea_channel_speaker_allocation *ch = NULL; - int res = 0; - int cur = 0; -@@ -499,11 +497,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - -- if (!substream || !substream->runtime) { -- res = -ENODEV; -- goto unlock; -- } +- local_irq_disable(); +- smp_send_stop(); - - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { - if (channel_allocations[i].ca_index == chip->cea_chmap) - ch = &channel_allocations[i]; -@@ -521,7 +514,6 @@ static int snd_bcm2835_chmap_ctl_get(struct snd_kcontrol *kcontrol, - while (cur < 8) - ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA; - --unlock: - mutex_unlock(&chip->audio_mutex); - return res; +- local_irq_disable(); +- while (1); ++ machine_power_off(); } -@@ -541,7 +533,7 @@ static int snd_bcm2835_chmap_ctl_put(struct snd_kcontrol *kcontrol, - return -EINTR; - - if (!substream || !substream->runtime) { -- res = -ENODEV; -+ /* ignore and return success for the sake of alsactl */ - goto unlock; - } + /* -From 2c9ca7ae6ac79df824b94224936d378d725b7bb7 Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:29:41 +0200 -Subject: [PATCH 247/251] bcm2835: add fallback channel layouts if channel map - API is not used - -Should be more useful than just forcing stereo. - -We can't match the exact legacy ALSA channel layouts, so this is a -"best effort" hack. - -I'm not sure what happens if the application requests channel counts -that are not power-of-2s. The channel map API hopefully forces -applications which use the channel map API to request the correct -count by adding padding channels, but the bare API enforces -nothing. Possibly this could be added to rate_hw_constraint_channels -at a later point. ---- - sound/arm/bcm2835-vchiq.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 8ecd2d7..9371073 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -598,7 +598,16 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - if (alsa_stream->chip->cea_chmap >= 0) { - chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; - } else { -- chmap_value = 0; /* force stereo */ -+ /* fallback layouts for applications which do not use chmap API */ -+ chmap_value = 0x00; -+ switch (channels) { -+ case 3: chmap_value = 0x01; break; -+ case 4: chmap_value = 0x03; break; -+ case 5: chmap_value = 0x07; break; -+ case 6: chmap_value = 0x0b; break; -+ case 7: chmap_value = 0x0f; break; -+ case 8: chmap_value = 0x13; break; -+ } - for (i = 0; i < 8; i++) - alsa_stream->chip->map_channels[i] = i; - } - -From a9670f6cc4cd89aa953d6240b037ebfa161e552b Mon Sep 17 00:00:00 2001 -From: wm4 -Date: Tue, 19 Apr 2016 16:38:03 +0200 -Subject: [PATCH 248/251] bcm2835: log which channel map is set - ---- - sound/arm/bcm2835-vchiq.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c -index 9371073..876986d 100755 ---- a/sound/arm/bcm2835-vchiq.c -+++ b/sound/arm/bcm2835-vchiq.c -@@ -596,8 +596,11 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - instance->result = -1; - - if (alsa_stream->chip->cea_chmap >= 0) { -+ LOG_INFO("Using application requested channel map: %d\n", -+ alsa_stream->chip->cea_chmap); - chmap_value = (unsigned)alsa_stream->chip->cea_chmap << 24; - } else { -+ LOG_INFO("Using fallback channel map.\n"); - /* fallback layouts for applications which do not use chmap API */ - chmap_value = 0x00; - switch (channels) { -@@ -614,6 +617,8 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream, - for (i = 0; i < 8; i++) - chmap_value |= alsa_stream->chip->map_channels[i] << (i * 3); - -+ LOG_INFO("Requesting AUDS channel map: 0x%lx\n", (long)chmap_value); -+ - m.type = VC_AUDIO_MSG_TYPE_CONFIG; - m.u.config.channels = channels; - m.u.config.samplerate = samplerate; - -From 9135f5620348b62310684d40896ae21d993a563d Mon Sep 17 00:00:00 2001 +From 7e5b50942960069881572b173d745c22958e9d69 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Thu, 21 Apr 2016 13:49:32 +0100 -Subject: [PATCH 249/251] vchiq_arm: Add completion records under the mutex +Date: Wed, 30 Mar 2016 17:23:15 +0100 +Subject: [PATCH 111/114] cpufreq: Temporarily ignore io_is_busy=1 -An issue was observed when flushing openmax components -which generate a large number of messages returning -buffers to host. - -We occasionally found a duplicate message from 16 -messages prior, resulting in a buffer returned twice. - -While only one thread adds completions, without the -mutex you don't get the protection of the automatic -memory barrier you get with synchronisation objects. +To speed testing of the new sdhost driver that adapts to changes in +core_freq, hack the on-demand governor to treat io_is_busy=1 as +io_is_busy=0. The io_is_busy feature can still be forced using +io_is_busy=2. Signed-off-by: Phil Elwell --- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) + drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index a5cc385..4886236 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - VCHIQ_COMPLETION_DATA_T *completion; - DEBUG_INITIALISE(g_state.local) +diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c +index acd8027..72c5a4c 100644 +--- a/drivers/cpufreq/cpufreq_ondemand.c ++++ b/drivers/cpufreq/cpufreq_ondemand.c +@@ -216,7 +216,12 @@ static ssize_t store_io_is_busy(struct dbs_data *dbs_data, const char *buf, + ret = sscanf(buf, "%u", &input); + if (ret != 1) + return -EINVAL; +- dbs_data->io_is_busy = !!input; ++ // XXX temporary hack ++ if (input > 1) ++ input = 1; ++ else ++ input = 0; ++ dbs_data->io_is_busy = input; -+ mutex_lock(&instance->completion_mutex); -+ - while (instance->completion_insert == - (instance->completion_remove + MAX_COMPLETIONS)) { - /* Out of space - wait for the client */ -@@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - vchiq_log_trace(vchiq_arm_log_level, - "add_completion - completion queue full"); - DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); -+ -+ mutex_unlock(&instance->completion_mutex); - if (down_interruptible(&instance->remove_event) != 0) { - vchiq_log_info(vchiq_arm_log_level, - "service_callback interrupted"); - return VCHIQ_RETRY; -- } else if (instance->closing) { -+ } -+ -+ mutex_lock(&instance->completion_mutex); -+ if (instance->closing) { -+ mutex_unlock(&instance->completion_mutex); - vchiq_log_info(vchiq_arm_log_level, - "service_callback closing"); - return VCHIQ_SUCCESS; -@@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, - if (reason == VCHIQ_MESSAGE_AVAILABLE) - user_service->message_available_pos = - instance->completion_insert; -+ - instance->completion_insert++; - -+ mutex_unlock(&instance->completion_mutex); -+ - up(&instance->insert_event); - - return VCHIQ_SUCCESS; + /* we need to re-evaluate prev_cpu_idle */ + gov_update_cpu_data(dbs_data); -From 14ba3016c66394dca226fc4fd66b2fd2e677497c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 Apr 2016 16:07:15 +0100 -Subject: [PATCH 250/251] config: Add DRM_UDL module +From 5852c38e95e3f81ba96c4aa8014f9267700ce90f Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 21 Apr 2016 20:24:17 +0100 +Subject: [PATCH 112/114] config: Make IPV6 a module and regenerate with + defconfig -See: https://github.com/raspberrypi/linux/issues/1422 - -Signed-off-by: Phil Elwell --- - arch/arm/configs/bcm2709_defconfig | 5 +++-- - arch/arm/configs/bcmrpi_defconfig | 5 +++-- - 2 files changed, 6 insertions(+), 4 deletions(-) + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm/configs/bcmrpi_defconfig | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7353332..7788ecb 100644 +index 2536c11..d930029 100644 --- a/arch/arm/configs/bcm2709_defconfig +++ b/arch/arm/configs/bcm2709_defconfig -@@ -814,6 +814,7 @@ CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_DRM=m -+CONFIG_DRM_UDL=m - CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -@@ -853,10 +854,10 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_ADAU1701=m +@@ -4,7 +4,6 @@ CONFIG_LOCALVERSION="-v7" + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y + CONFIG_POSIX_MQUEUE=y +-CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y +@@ -101,6 +100,7 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m + CONFIG_INET_XFRM_MODE_TUNNEL=m + CONFIG_INET_XFRM_MODE_BEET=m + CONFIG_INET_DIAG=m ++CONFIG_IPV6=m + CONFIG_INET6_AH=m + CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 603ba04..5b8b19a 100644 +index bfb6936..4cfb186 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -806,6 +806,7 @@ CONFIG_VIDEO_TW9906=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_DRM=m -+CONFIG_DRM_UDL=m - CONFIG_DRM_VC4=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -@@ -845,10 +846,10 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_RASPIDAC3=m - CONFIG_SND_SOC_ADAU1701=m +@@ -3,7 +3,6 @@ CONFIG_PHYS_OFFSET=0 + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y + CONFIG_POSIX_MQUEUE=y +-CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y +@@ -73,7 +72,6 @@ CONFIG_INET=y + CONFIG_IP_MULTICAST=y + CONFIG_IP_ADVANCED_ROUTER=y + CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IPV6_SUBTREES=y + CONFIG_IP_ROUTE_MULTIPATH=y + CONFIG_IP_ROUTE_VERBOSE=y + CONFIG_IP_PNP=y +@@ -94,11 +92,13 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=m + CONFIG_INET_XFRM_MODE_TUNNEL=m + CONFIG_INET_XFRM_MODE_BEET=m + CONFIG_INET_DIAG=m ++CONFIG_IPV6=m + CONFIG_INET6_AH=m + CONFIG_INET6_ESP=m + CONFIG_INET6_IPCOMP=m + CONFIG_IPV6_TUNNEL=m + CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y + CONFIG_IPV6_MROUTE=y + CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y + CONFIG_IPV6_PIMSM_V2=y -From a114d1bd49a30b9b3aa31d4b18069986e0335e12 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 Apr 2016 15:44:14 +0100 -Subject: [PATCH 251/251] bcm2835-i2s: Reduce the TX DREQ threshold +From c7bb9cf080179e9abd76a48c2cb517369590780c Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 21 Apr 2016 20:31:55 +0100 +Subject: [PATCH 113/114] firmware: Add RPI_FIRMWARE_SET_SDHOST_CLOCK -TX FIFO overrun is thought to be the cause of channel swapping, so -reducing the DREQ threshold seems reasonable and appears to be -effective. - -See: https://github.com/raspberrypi/linux/issues/1417 - -Signed-off-by: Phil Elwell --- - sound/soc/bcm/bcm2835-i2s.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 1 file changed, 1 insertion(+) -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 04c1d13..aedb01f 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -555,15 +555,22 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 73e4956..227a107 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -81,6 +81,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, ++ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, - /* Setup the DMA parameters */ - regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, -- BCM2835_I2S_RXTHR(1) -- | BCM2835_I2S_TXTHR(1) -- | BCM2835_I2S_DMAEN, 0xffffffff); -+ BCM2835_I2S_RXTHR(3) -+ | BCM2835_I2S_TXTHR(3) -+ | BCM2835_I2S_DMAEN, -+ BCM2835_I2S_RXTHR(1) -+ | BCM2835_I2S_TXTHR(1) -+ | BCM2835_I2S_DMAEN); - - regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, -- BCM2835_I2S_TX_PANIC(0x10) -- | BCM2835_I2S_RX_PANIC(0x30) -- | BCM2835_I2S_TX(0x30) -- | BCM2835_I2S_RX(0x20), 0xffffffff); -+ BCM2835_I2S_TX_PANIC(0x7f) -+ | BCM2835_I2S_RX_PANIC(0x7f) -+ | BCM2835_I2S_TX(0x7f) -+ | BCM2835_I2S_RX(0x7f), -+ BCM2835_I2S_TX_PANIC(0x10) -+ | BCM2835_I2S_RX_PANIC(0x30) -+ | BCM2835_I2S_TX(0x20) -+ | BCM2835_I2S_RX(0x20)); - - /* Clear FIFOs */ - bcm2835_i2s_clear_fifos(dev, true, true); + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, + +From 815cdfe7c75dbdbf13fc3d5b629ed0a68c895ef4 Mon Sep 17 00:00:00 2001 +From: dienet +Date: Fri, 22 Apr 2016 21:58:41 +0200 +Subject: [PATCH 114/114] fbdev: bcm2708_fb: remove unused variable and + duplicated comment (#1426) + +The yres varialbe is not used anywhere in this function. Also this comment looks +to be duplicated. Remove them. + +Signed-off-by: Slawomir Stepien +--- + drivers/video/fbdev/bcm2708_fb.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c +index a20539a..cae5aab 100644 +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -218,9 +218,6 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) + { + /* info input, var output */ +- int yres; +- +- /* info input, var output */ + print_debug("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size,