CONFIG_PWM_BCM2835=y
CONFIG_PWM_SYSFS=y
CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_RASPBERRYPI_POWER=y
CONFIG_RATIONAL=y
CONFIG_RAW_DRIVER=y
# CONFIG_RCU_STALL_COMMON is not set
CONFIG_PWM_BCM2835=y
CONFIG_PWM_SYSFS=y
CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_RASPBERRYPI_POWER=y
CONFIG_RATIONAL=y
CONFIG_RAW_DRIVER=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_PWM_BCM2835=y
CONFIG_PWM_SYSFS=y
CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_RASPBERRYPI_POWER=y
CONFIG_RATIONAL=y
CONFIG_RAW_DRIVER=y
CONFIG_RCU_STALL_COMMON=y
$(eval $(call KernelPackage,sound-soc-bcm2835-i2s))
+define KernelPackage/sound-soc-boomberry-dac
+ TITLE:=Support for BoomBerry DAC
+ KCONFIG:= \
+ CONFIG_SND_BCM2708_SOC_BOOMBERRY_DAC \
+ CONFIG_SND_SOC_PCM512x
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/bcm/snd-soc-boomberry-dac.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-boomberry-dac)
+ DEPENDS:= \
+ kmod-sound-soc-bcm2835-i2s \
+ +kmod-i2c-bcm2708
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-boomberry-dac/description
+ This package contains support for BoomBerry DAC
+endef
+
+$(eval $(call KernelPackage,sound-soc-boomberry-dac))
+
+define KernelPackage/sound-soc-boomberry-digi
+ TITLE:=Support for BoomBerry Digi
+ KCONFIG:= \
+ CONFIG_SND_BCM2708_SOC_BOOMBERRY_DIGI \
+ CONFIG_SND_SOC_WM8804
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/bcm/snd-soc-boomberry-digi.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804 snd-soc-boomberry-digi)
+ DEPENDS:= \
+ kmod-sound-soc-bcm2835-i2s \
+ +kmod-i2c-bcm2708
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-boomberry-digi/description
+ This package contains support for BoomBerry Digi
+endef
+
+$(eval $(call KernelPackage,sound-soc-boomberry-digi))
+
define KernelPackage/sound-soc-hifiberry-dac
TITLE:=Support for HifiBerry DAC
KCONFIG:= \
-From 23b133903a357066adb48bceb76aba8bd30d8c66 Mon Sep 17 00:00:00 2001
+From e3aec450775ffe2df234b44a59b66800eeff00c8 Mon Sep 17 00:00:00 2001
From: Steve Glendinning <steve.glendinning@smsc.com>
Date: Thu, 19 Feb 2015 18:47:12 +0000
-Subject: [PATCH 001/232] smsx95xx: fix crimes against truesize
+Subject: [PATCH 001/304] 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.
-From e7515ee9af1d150d50b55d8f8f53d735a23cb253 Mon Sep 17 00:00:00 2001
+From c8fa4edd9b4f1dbc6c8edc80643bd08070d9e4a9 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 17 Apr 2015 16:58:45 +0100
-Subject: [PATCH 002/232] smsc95xx: Disable turbo mode by default
+Subject: [PATCH 002/304] smsc95xx: Disable turbo mode by default
---
drivers/net/usb/smsc95xx.c | 2 +-
-From 849ff5353023c95d40040ecfd279e216074b3d1c Mon Sep 17 00:00:00 2001
+From 9a7ab264528085a6838fb176e6ea518e4cd2cc18 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Jun 2014 13:42:01 +0100
-Subject: [PATCH 003/232] vmstat: Workaround for issue where dirty page count
+Subject: [PATCH 003/304] vmstat: Workaround for issue where dirty page count
goes negative
See:
-From d29365673ed37e7688bd3f35c4a5ad719f878190 Mon Sep 17 00:00:00 2001
+From 5562d1c3a783a1384a6502e9c7ef63756fffb4a8 Mon Sep 17 00:00:00 2001
From: Robert Tiemann <rtie@gmx.de>
Date: Mon, 20 Jul 2015 11:01:25 +0200
-Subject: [PATCH 004/232] BCM2835_DT: Fix I2S register map
+Subject: [PATCH 004/304] BCM2835_DT: Fix I2S register map
---
Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++--
-From c891de13b385afb3e4b2c97ac5bbea7e2d97252f Mon Sep 17 00:00:00 2001
+From a072785b4d4e3290bb1992fa97009562b8cbcee3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 4 Dec 2015 17:41:50 +0000
-Subject: [PATCH 005/232] irq-bcm2836: Prevent spurious interrupts, and trap
+Subject: [PATCH 005/304] irq-bcm2836: Prevent spurious interrupts, and trap
them early
The old arch-specific IRQ macros included a dsb to ensure the
-From 60f7ee79b375d72f5ef46ec542b925b1f1428bad Mon Sep 17 00:00:00 2001
+From 0551c5ca00a862c2902bd3640aa08f948332e525 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 12 Jun 2015 19:01:05 +0200
-Subject: [PATCH 006/232] irqchip: bcm2835: Add FIQ support
+Subject: [PATCH 006/304] irqchip: bcm2835: Add FIQ support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 890dccbb9c60be182adefb61b3ede805ccba1a91 Mon Sep 17 00:00:00 2001
+From dd7d7256191e694771fffcc05c9c43e0ca77b724 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 23 Oct 2015 16:26:55 +0200
-Subject: [PATCH 007/232] irqchip: irq-bcm2835: Add 2836 FIQ support
+Subject: [PATCH 007/304] irqchip: irq-bcm2835: Add 2836 FIQ support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 9a27662aac88f95b3de1915333a0265614f88a0d Mon Sep 17 00:00:00 2001
+From a1c1d55bb480c9d67814d0a965efdaabb83b4f85 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 14:12:42 +0100
-Subject: [PATCH 008/232] serial: 8250: Don't crash when nr_uarts is 0
+Subject: [PATCH 008/304] serial: 8250: Don't crash when nr_uarts is 0
---
drivers/tty/serial/8250/8250_core.c | 2 ++
-From 4d7ff05e4d4d8d8adb4e7b4dd5fa8f63ae2be0f6 Mon Sep 17 00:00:00 2001
+From faa0db48929e02320294b4bb6b40c3478aee984e Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Thu, 10 Jul 2014 13:59:47 +0200
-Subject: [PATCH 009/232] pinctrl-bcm2835: Set base to 0 give expected gpio
+Subject: [PATCH 009/304] pinctrl-bcm2835: Set base to 0 give expected gpio
numbering
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
-From 969dc44a700e1be13c3f80445d40c1fe51cc4370 Mon Sep 17 00:00:00 2001
+From ae53bc0b0589b078b38bcd662aaa1589506d3108 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 24 Feb 2015 13:40:50 +0000
-Subject: [PATCH 010/232] pinctrl-bcm2835: Fix interrupt handling for GPIOs
+Subject: [PATCH 010/304] pinctrl-bcm2835: Fix interrupt handling for GPIOs
28-31 and 46-53
Contrary to the documentation, the BCM2835 GPIO controller actually has
-From b949246bf51fa852bad45136cdd6bcd91a29539e Mon Sep 17 00:00:00 2001
+From 6b21816af06720e064a2f84ddafb858692c25472 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 26 Feb 2015 09:58:22 +0000
-Subject: [PATCH 011/232] pinctrl-bcm2835: Only request the interrupts listed
+Subject: [PATCH 011/304] pinctrl-bcm2835: Only request the interrupts listed
in the DTB
Although the GPIO controller can generate three interrupts (four counting
-From 19bcdacc5a67abe6a2d604a39ddfed5a54c77b2e Mon Sep 17 00:00:00 2001
+From f685e187de2908b8b6399055a972e841a6e8e97a Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 24 Jun 2015 14:10:44 +0100
-Subject: [PATCH 012/232] spi-bcm2835: Support pin groups other than 7-11
+Subject: [PATCH 012/304] 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
-From 7ce5cbfba6e930c2178f342a4390972f1efd75ef Mon Sep 17 00:00:00 2001
+From 7f7e20a0070ff81ced9eb8eedd8efc19af959605 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Wed, 3 Jun 2015 12:26:13 +0200
-Subject: [PATCH 013/232] ARM: bcm2835: Set Serial number and Revision
+Subject: [PATCH 013/304] ARM: bcm2835: Set Serial number and Revision
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 569baa856d805e594011f2d1444b6849c291544d Mon Sep 17 00:00:00 2001
+From 61037c6b43a4e3f1a53582fb92ee7f964b6bace5 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 16:44:05 +0200
-Subject: [PATCH 014/232] bcm2835-i2s: get base address for DMA from devicetree
+Subject: [PATCH 014/304] bcm2835-i2s: get base address for DMA from devicetree
Code copied from spi-bcm2835. Get physical address from devicetree
instead of using hardcoded constant.
-From c61a7aef15a1aee86e1de59dca2ad7002995f9cf Mon Sep 17 00:00:00 2001
+From 09feefa33b3f36291dc3a406bcf80dddf72568e9 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 15:21:16 +0200
-Subject: [PATCH 015/232] bcm2835-i2s: add 24bit support, update bclk_ratio to
+Subject: [PATCH 015/304] bcm2835-i2s: add 24bit support, update bclk_ratio to
more correct values
Code ported from bcm2708-i2s driver in Raspberry Pi tree.
-From e2a75ce0e2b6319150e14401f9822adba7895c9c Mon Sep 17 00:00:00 2001
+From b10789f9366de21dc44df087c4e65aa4a56a1dd9 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 15:25:51 +0200
-Subject: [PATCH 016/232] bcm2835-i2s: setup clock only if CPU is clock master
+Subject: [PATCH 016/304] bcm2835-i2s: setup clock only if CPU is clock master
Code ported from bcm2708-i2s driver in Raspberry Pi tree.
-From 433841fc5958e1ddbd503b579a022fb67defd74b Mon Sep 17 00:00:00 2001
+From 08c03b0127c99d816f84a03d9f62c2b8313b359e Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 15:49:51 +0200
-Subject: [PATCH 017/232] bcm2835-i2s: Eliminate debugfs directory error
+Subject: [PATCH 017/304] bcm2835-i2s: Eliminate debugfs directory error
Code ported from bcm2708-i2s driver in Raspberry Pi tree.
-From 7b4481818fe920904457496db40d59dd3d0a83bb Mon Sep 17 00:00:00 2001
+From 6eb24a344f83c6b0768e6e63fa1865d3f444ed5a Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 15:35:20 +0200
-Subject: [PATCH 018/232] bcm2835-i2s: Register PCM device
+Subject: [PATCH 018/304] bcm2835-i2s: Register PCM device
Code ported from bcm2708-i2s driver in Raspberry Pi tree.
-From 027ba808e84799c97ae1c64f8424ac8eb7235cc4 Mon Sep 17 00:00:00 2001
+From 0c4d87b48e1ec19d0de0ceae22981647a927a83a Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 15:55:21 +0200
-Subject: [PATCH 019/232] bcm2835-i2s: Enable MMAP support via a DT property
+Subject: [PATCH 019/304] bcm2835-i2s: Enable MMAP support via a DT property
Code ported from bcm2708-i2s driver in Raspberry Pi tree.
-From 8a349301238aabb40c9da5ca8c8492b6b8d146f6 Mon Sep 17 00:00:00 2001
+From b2a69d30bbcbf96f6469a7cab9f9831351ea3d75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Thu, 9 Apr 2015 12:34:11 +0200
-Subject: [PATCH 020/232] dmaengine: bcm2835: Add slave dma support
+Subject: [PATCH 020/304] dmaengine: bcm2835: Add slave dma support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 290f55520c62025da992d6be0002fc1e3738cfdb Mon Sep 17 00:00:00 2001
+From 6018cc9ef34ff7c465cf5c7674de004facf9bec8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 3 Oct 2015 15:58:59 +0200
-Subject: [PATCH 021/232] dmaengine: bcm2835: set residue_granularity field
+Subject: [PATCH 021/304] dmaengine: bcm2835: set residue_granularity field
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 6f56fff39c811953809b011f59c49a2122c4d173 Mon Sep 17 00:00:00 2001
+From 64eb22fa4c7f019d40afc335d780079dfc52de91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 3 Oct 2015 22:22:55 +0200
-Subject: [PATCH 022/232] dmaengine: bcm2835: Load driver early and support
+Subject: [PATCH 022/304] dmaengine: bcm2835: Load driver early and support
legacy API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From df03f00c5e21559185b5a61ea5e8238e10959ab1 Mon Sep 17 00:00:00 2001
+From b28f69e34f275f12d22b469f8ed74de076c058fb Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sat, 10 Oct 2015 12:29:18 +0200
-Subject: [PATCH 023/232] bcm2835-dma: Fix dreq not set for slave transfers
+Subject: [PATCH 023/304] bcm2835-dma: Fix dreq not set for slave transfers
Set dreq to slave_id if it is not set like in bcm2708-dmaengine.
---
-From 052c2005b6ecedc5abad86632f5781adda310aa7 Mon Sep 17 00:00:00 2001
+From 2de86278755ccd71765ff6c658295a825ae85bcd Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 11 Oct 2015 12:28:30 +0200
-Subject: [PATCH 024/232] bcm2835-dma: Limit cyclic transfers on lite channels
+Subject: [PATCH 024/304] bcm2835-dma: Limit cyclic transfers on lite channels
to 32k
Transfers larger than 32k cause repeated clicking with I2S soundcards.
-From a72021ae99021409319d552dad744572b20febfb Mon Sep 17 00:00:00 2001
+From 03eed3ba7f50f36bfe465aff568bbdf6c7e9505a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 15 Aug 2015 20:50:02 +0200
-Subject: [PATCH 025/232] bcm2835: Add support for uart1
+Subject: [PATCH 025/304] bcm2835: Add support for uart1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 4364707caa6d3d9edf84fa8469a04f33e1ba5d76 Mon Sep 17 00:00:00 2001
+From 494564a4ddb2a550ec340dee8ffd46de8faa8267 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:21:20 +0200
-Subject: [PATCH 026/232] firmware: bcm2835: Add missing property tags
+Subject: [PATCH 026/304] firmware: bcm2835: Add missing property tags
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From cd721670ab8c729d0c62e99a1d173c2575b63282 Mon Sep 17 00:00:00 2001
+From 65fc8b10fa17a19d8c92a1b7a601e47a749060b6 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sun, 12 May 2013 12:24:19 +0100
-Subject: [PATCH 027/232] Main bcm2708/bcm2709 linux port
+Subject: [PATCH 027/304] Main bcm2708/bcm2709 linux port
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 812484cc27980e3351360200478e7044de983f40 Mon Sep 17 00:00:00 2001
+From fc29614ab47f681dafa8e72e785df2608c542619 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 11 Nov 2015 21:01:15 +0000
-Subject: [PATCH 028/232] squash: include ARCH_BCM2708 / ARCH_BCM2709
+Subject: [PATCH 028/304] squash: include ARCH_BCM2708 / ARCH_BCM2709
---
drivers/char/hw_random/Kconfig | 2 +-
-From 7efc2851a46faa1aceda5f6ec255d0e814812ccf Mon Sep 17 00:00:00 2001
+From e3bac792b4c542025127f57394356e5c495e75dc Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 1 May 2013 19:46:17 +0100
-Subject: [PATCH 029/232] Add dwc_otg driver
+Subject: [PATCH 029/304] Add dwc_otg driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From d3b7394edae550f295e185be4651ed43529e7042 Mon Sep 17 00:00:00 2001
+From c8719ed281ffb6b738af0e8acc16aa13c0381749 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 17:06:34 +0100
-Subject: [PATCH 030/232] bcm2708 framebuffer driver
+Subject: [PATCH 030/304] bcm2708 framebuffer driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 99b7c3cfd05f5898e96d7c44c5970880f2c0cd16 Mon Sep 17 00:00:00 2001
+From 451d996dcc4cc8460fea6b74331aaa762823d312 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:22:53 +0100
-Subject: [PATCH 031/232] dmaengine: Add support for BCM2708
+Subject: [PATCH 031/304] dmaengine: Add support for BCM2708
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 65c8aadfd88010efb2d2a2821fea7aac978b6c78 Mon Sep 17 00:00:00 2001
+From 231ef69db2b015b7da9994ef893090206bf5f63f Mon Sep 17 00:00:00 2001
From: gellert <gellert@raspberrypi.org>
Date: Fri, 15 Aug 2014 16:35:06 +0100
-Subject: [PATCH 032/232] MMC: added alternative MMC driver
+Subject: [PATCH 032/304] MMC: added alternative MMC driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From c58bec0d84082837415562c6567396e9e5ba62f7 Mon Sep 17 00:00:00 2001
+From 73744a39303ad063a4b964a2bc48391be72c9310 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 25 Mar 2015 17:49:47 +0000
-Subject: [PATCH 033/232] Adding bcm2835-sdhost driver, and an overlay to
+Subject: [PATCH 033/304] Adding bcm2835-sdhost driver, and an overlay to
enable it
BCM2835 has two SD card interfaces. This driver uses the other one.
-From 36d8db53953365eecdf56695944e9f9919634de0 Mon Sep 17 00:00:00 2001
+From 7d966829e3d7a49f3efc033f41902c52edc2e07d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:31:47 +0100
-Subject: [PATCH 034/232] cma: Add vc_cma driver to enable use of CMA
+Subject: [PATCH 034/304] 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
-From 2dd634f97c4fb77d9e81be289a8da29c390a0309 Mon Sep 17 00:00:00 2001
+From 03aa66334a94cbdaac80f3673a2e6e766b29ff32 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 26 Mar 2012 22:15:50 +0100
-Subject: [PATCH 035/232] bcm2708: alsa sound driver
+Subject: [PATCH 035/304] bcm2708: alsa sound driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 112360f76c91c892f1a29825eb2807bbf86ac67d Mon Sep 17 00:00:00 2001
+From b1e77a013c963839cd74707aa58532286cfacfcc Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 2 Jul 2013 23:42:01 +0100
-Subject: [PATCH 036/232] bcm2708 vchiq driver
+Subject: [PATCH 036/304] bcm2708 vchiq driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From b0acaf43055bacef7918c835517ff6ea7da26e83 Mon Sep 17 00:00:00 2001
+From afecc66589fdfd0dcfde79917a82c51172d6c002 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 16:07:06 +0100
-Subject: [PATCH 037/232] vc_mem: Add vc_mem driver
+Subject: [PATCH 037/304] vc_mem: Add vc_mem driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 5f05accd033e4b032f64717a0276d7174f697919 Mon Sep 17 00:00:00 2001
+From cd630a79b98d0406559589a658c0d0b206e523bc Mon Sep 17 00:00:00 2001
From: Tim Gover <tgover@broadcom.com>
Date: Tue, 22 Jul 2014 15:41:04 +0100
-Subject: [PATCH 038/232] vcsm: VideoCore shared memory service for BCM2835
+Subject: [PATCH 038/304] vcsm: VideoCore shared memory service for BCM2835
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 1ee3b49a62efe1416a6b40fb5c6032288f3d2b08 Mon Sep 17 00:00:00 2001
+From e2633bbfb7a44ca624c5c67df3cab9e39e8357cf Mon Sep 17 00:00:00 2001
From: Luke Wren <luke@raspberrypi.org>
Date: Fri, 21 Aug 2015 23:14:48 +0100
-Subject: [PATCH 039/232] Add /dev/gpiomem device for rootless user GPIO access
+Subject: [PATCH 039/304] Add /dev/gpiomem device for rootless user GPIO access
Signed-off-by: Luke Wren <luke@raspberrypi.org>
-From e19c303e7d54d986e0bd3e47107a83e30329c1d0 Mon Sep 17 00:00:00 2001
+From 2c8e4852592e64f426a482df8b662984bb4f6c9e Mon Sep 17 00:00:00 2001
From: Luke Wren <wren6991@gmail.com>
Date: Sat, 5 Sep 2015 01:14:45 +0100
-Subject: [PATCH 040/232] Add SMI driver
+Subject: [PATCH 040/304] Add SMI driver
Signed-off-by: Luke Wren <wren6991@gmail.com>
---
-From c0fe401b61ae4d002f6fc84438ce69c5917c580a Mon Sep 17 00:00:00 2001
+From 810a555a6fe83edc69126deba240839f152d8938 Mon Sep 17 00:00:00 2001
From: Luke Wren <wren6991@gmail.com>
Date: Sat, 5 Sep 2015 01:16:10 +0100
-Subject: [PATCH 041/232] Add SMI NAND driver
+Subject: [PATCH 041/304] Add SMI NAND driver
Signed-off-by: Luke Wren <wren6991@gmail.com>
---
-From 0bc00c67aea43098c7b066e7b123379b260cc7de Mon Sep 17 00:00:00 2001
+From 1f298174c176aa408de36b46421ac114357ac0e9 Mon Sep 17 00:00:00 2001
From: Aron Szabo <aron@aron.ws>
Date: Sat, 16 Jun 2012 12:15:55 +0200
-Subject: [PATCH 042/232] lirc: added support for RaspberryPi GPIO
+Subject: [PATCH 042/304] 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
-From 007ef35b2cf5d8a0197e81e712b38fb72cebae2e Mon Sep 17 00:00:00 2001
+From 3d01c18ff8973905ef050b20b13063f9e7759c3a Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:49:20 +0100
-Subject: [PATCH 043/232] Add cpufreq driver
+Subject: [PATCH 043/304] Add cpufreq driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
-From 9f251fdbaaf3bd895c2901413748679d68a0c644 Mon Sep 17 00:00:00 2001
+From a1dd93ad1499de093098226931462628cc86e4e6 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 19:24:24 +0000
-Subject: [PATCH 044/232] Added hwmon/thermal driver for reporting core
+Subject: [PATCH 044/304] Added hwmon/thermal driver for reporting core
temperature. Thanks Dorian
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From 28a4399bf03eeb3ec5b7b56c9445b296e1427665 Mon Sep 17 00:00:00 2001
+From 0feef39a2329ed935108d53e02fe38cb4578dfbf Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 15:44:08 +0100
-Subject: [PATCH 045/232] Add Chris Boot's i2c driver
+Subject: [PATCH 045/304] Add Chris Boot's i2c driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 75804edaed6c45d813dcee866d39445130d82539 Mon Sep 17 00:00:00 2001
+From 3423e9a9b7e0d6e988832d1362f2fb3ce76bf07c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:27:06 +0200
-Subject: [PATCH 046/232] char: broadcom: Add vcio module
+Subject: [PATCH 046/304] char: broadcom: Add vcio module
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 80b7c5e2cc3d633b3d3a1afbdb537e2ccfe906c7 Mon Sep 17 00:00:00 2001
+From f259f2e35226640b67ff324789f3638a724bab53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:25:01 +0200
-Subject: [PATCH 047/232] firmware: bcm2835: Support ARCH_BCM270x
+Subject: [PATCH 047/304] firmware: bcm2835: Support ARCH_BCM270x
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From e15fddd4332bd3a762d0feef48ff2b5e3df10af0 Mon Sep 17 00:00:00 2001
+From 877bf225ae61519f04b880abe2d84ae7dc585475 Mon Sep 17 00:00:00 2001
From: Vincent Sanders <vincent.sanders@collabora.co.uk>
Date: Wed, 30 Jan 2013 12:45:18 +0000
-Subject: [PATCH 048/232] bcm2835: add v4l2 camera device
+Subject: [PATCH 048/304] bcm2835: add v4l2 camera device
- Supports raw YUV capture, preview, JPEG and H264.
- Uses videobuf2 for data transfer, using dma_buf.
-From 91e833ab0b220bb0bb810bb9605b0a03cd76baa8 Mon Sep 17 00:00:00 2001
+From 35361c41437a4d81c47bc56189369201c5f1d2e4 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 11 May 2015 09:00:42 +0100
-Subject: [PATCH 049/232] scripts: Add mkknlimg and knlinfo scripts from tools
+Subject: [PATCH 049/304] scripts: Add mkknlimg and knlinfo scripts from tools
repo
The Raspberry Pi firmware looks for a trailer on the kernel image to
-From 918b9e451bbaebb775725a292fd3b6e3d4cf804f Mon Sep 17 00:00:00 2001
+From e88c206c101194b8513860c135ee77366d7456eb Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 5 Dec 2014 17:26:26 +0000
-Subject: [PATCH 050/232] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
+Subject: [PATCH 050/304] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
---
drivers/of/fdt.c | 29 ++++++++++++++++++++++++-----
-From d1fdaf68df66e82bea1081b490ebeea414d69203 Mon Sep 17 00:00:00 2001
+From f3552e720773b9e13a0667606c8438ae14d0538b Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Wed, 9 Jul 2014 14:46:08 +0200
-Subject: [PATCH 051/232] BCM2708: Add core Device Tree support
+Subject: [PATCH 051/304] BCM2708: Add core Device Tree support
Add the bare minimum needed to boot BCM2708 from a Device Tree.
-From da7cdef4979282624e0e7527c3c8334a59f39676 Mon Sep 17 00:00:00 2001
+From 96c7eeec2f269f779e14eef94e19804f70ac5c36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 15 Aug 2015 20:47:07 +0200
-Subject: [PATCH 052/232] bcm2835: Match with BCM2708 Device Trees
+Subject: [PATCH 052/304] bcm2835: Match with BCM2708 Device Trees
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From b28366cb5b514e5c59586f9a5509d3afff5337d5 Mon Sep 17 00:00:00 2001
+From 2d65eb731311b3bb43ac2b2194d76be99246aefc Mon Sep 17 00:00:00 2001
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Date: Mon, 17 Jun 2013 13:32:11 +0300
-Subject: [PATCH 053/232] fbdev: add FBIOCOPYAREA ioctl
+Subject: [PATCH 053/304] fbdev: add FBIOCOPYAREA ioctl
Based on the patch authored by Ali Gholami Rudi at
https://lkml.org/lkml/2009/7/13/153
-From dbf03b37592b79d891cb796fda13d8495a6a5234 Mon Sep 17 00:00:00 2001
+From 2b0758010872540fd290ed5c3ab489f7318fc977 Mon Sep 17 00:00:00 2001
From: Harm Hanemaaijer <fgenfb@yahoo.com>
Date: Thu, 20 Jun 2013 20:21:39 +0200
-Subject: [PATCH 057/232] Speed up console framebuffer imageblit function
+Subject: [PATCH 057/304] 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
-From cf63ba6ba21e8a1d62b1eb4917af42d6bcfa4445 Mon Sep 17 00:00:00 2001
+From eec29af59aca3d4f7edd6760c12ff33e8650d20d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 17:26:38 +0000
-Subject: [PATCH 058/232] Allow mac address to be set in smsc95xx
+Subject: [PATCH 058/304] Allow mac address to be set in smsc95xx
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
-From 20f0537c77ac3ef4e446bd0013c37ddd3af3936b Mon Sep 17 00:00:00 2001
+From cb3ff14d3ee1bfb19828f1f48fe486f33d7a6fbb Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 May 2013 11:46:50 +0100
-Subject: [PATCH 059/232] enabling the realtime clock 1-wire chip DS1307 and
+Subject: [PATCH 059/304] 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
-From fbd8454a22771ed12e1905a52934a6a871bc492e Mon Sep 17 00:00:00 2001
+From b0237d9659cb376e049e205dd9db20c210237388 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:54:08 +0100
-Subject: [PATCH 060/232] Added Device IDs for August DVB-T 205
+Subject: [PATCH 060/304] Added Device IDs for August DVB-T 205
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++
-From 6f8e2aeb77e4437eab3a46d74a1a2b9533812c81 Mon Sep 17 00:00:00 2001
+From 2cf0ecd618278861b4f7a9e7b72f39974493e18d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Dec 2013 22:16:19 +0000
-Subject: [PATCH 061/232] config: Enable CONFIG_MEMCG, but leave it disabled
+Subject: [PATCH 061/304] config: Enable CONFIG_MEMCG, but leave it disabled
(due to memory cost). Enable with cgroup_enable=memory.
---
-From b507ac15b579d88a09bf915f2f3ca8de7f1e4bf7 Mon Sep 17 00:00:00 2001
+From 6566720748ca71f63386608bb4c72e3b1efcc43a Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:59:51 +0100
-Subject: [PATCH 062/232] ASoC: Add support for PCM5102A codec
+Subject: [PATCH 062/304] ASoC: Add support for PCM5102A codec
Some definitions to support the PCM5102A codec
by Texas Instruments.
-From 9f5e88b201753c68a90fa45a269aa82febc58fc6 Mon Sep 17 00:00:00 2001
+From d47c284760f870b312b4ed488b71d0b549e0ef70 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:19:08 +0100
-Subject: [PATCH 063/232] ASoC: Add support for HifiBerry DAC
+Subject: [PATCH 063/304] ASoC: Add support for HifiBerry DAC
This adds a machine driver for the HifiBerry DAC.
It is a sound card that can
-From 95bf71f0e826b97bad98f350e2fee6ba515a38cf Mon Sep 17 00:00:00 2001
+From 26ee57a5d9cd05e006b277446c9535aeda3c93d6 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:21:34 +0100
-Subject: [PATCH 064/232] ASoC: Add support for Rpi-DAC
+Subject: [PATCH 064/304] ASoC: Add support for Rpi-DAC
---
sound/soc/bcm/Kconfig | 7 +++
-From 455d188d2a22ced675219587856c0dc66efc7256 Mon Sep 17 00:00:00 2001
+From ca1252c2232d7a7d44c8ae1fc35ae11ef2cd860d Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:41:23 +0100
-Subject: [PATCH 065/232] ASoC: wm8804: Implement MCLK configuration options,
+Subject: [PATCH 065/304] 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
-From 442de6ae737fbd27bcf2fde8be857beccc59fd1f Mon Sep 17 00:00:00 2001
+From 376d0b5d94c6d78d943f30b81de14bc66f7b2911 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:42:08 +0100
-Subject: [PATCH 066/232] ASoC: BCM:Add support for HiFiBerry Digi. Driver is
+Subject: [PATCH 066/304] ASoC: BCM:Add support for HiFiBerry Digi. Driver is
based on the patched WM8804 driver.
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
-From 836e7d5d46f17115b728986e3077c78c211a7678 Mon Sep 17 00:00:00 2001
+From b271e01a647c30ff8c6e66b2d4109e72235da27d Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Thu, 16 Jan 2014 07:36:35 +0100
-Subject: [PATCH 067/232] ASoC: wm8804: Set idle_bias_off to false Idle bias
+Subject: [PATCH 067/304] ASoC: wm8804: Set idle_bias_off to false Idle bias
has been change to remove warning on driver startup
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
-From 7ab81054051a41288e4aa2bb21d4740e0d78a4ac Mon Sep 17 00:00:00 2001
+From 21af89410a1ca12bce1dcfcd49af1eea66437af9 Mon Sep 17 00:00:00 2001
From: Gordon Garrity <gordon@iqaudio.com>
Date: Sat, 8 Mar 2014 16:56:57 +0000
-Subject: [PATCH 068/232] Add IQaudIO Sound Card support for Raspberry Pi
+Subject: [PATCH 068/304] Add IQaudIO Sound Card support for Raspberry Pi
Set a limit of 0dB on Digital Volume Control
-From efb984b47e685c966a3b55874de2c1fb5b0b1140 Mon Sep 17 00:00:00 2001
+From 1aaeb4fd759f159edc94ed53c7e1d02a57a107ae Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 14 Jul 2014 22:02:09 +0100
-Subject: [PATCH 069/232] hid: Reduce default mouse polling interval to 60Hz
+Subject: [PATCH 069/304] hid: Reduce default mouse polling interval to 60Hz
Reduces overhead when using X
---
-From 72a92f2e40881dcb46e50021c5c5fe2c20d8c461 Mon Sep 17 00:00:00 2001
+From bdc06975313393c21c0f72d52f1733a2333d1b70 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 10:06:56 +0200
-Subject: [PATCH 070/232] Added support for HiFiBerry DAC+
+Subject: [PATCH 070/304] 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.
-From f25572414689152e6208e5ca921185b1db536b24 Mon Sep 17 00:00:00 2001
+From 1d152bc8e97a3f004604ff4c10e5243266b4a312 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 11:09:58 +0200
-Subject: [PATCH 071/232] Added driver for HiFiBerry Amp amplifier add-on board
+Subject: [PATCH 071/304] 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.
-From d0bfff366e12c9b401ac7eafabab7337e82549ea Mon Sep 17 00:00:00 2001
+From 455ba80fce771499a5045cfddd741895f38cbc01 Mon Sep 17 00:00:00 2001
From: Ryan Coe <bluemrp9@gmail.com>
Date: Sat, 31 Jan 2015 18:25:49 -0700
-Subject: [PATCH 072/232] Update ds1307 driver for device-tree support
+Subject: [PATCH 072/304] Update ds1307 driver for device-tree support
Signed-off-by: Ryan Coe <bluemrp9@gmail.com>
---
-From 96aac93fdea2caa77d4746aa001c2d792b314112 Mon Sep 17 00:00:00 2001
+From 0613a9ad697b96c7aa5f3b6cb7d0c3bb236428e8 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 6 Feb 2015 13:50:57 +0000
-Subject: [PATCH 073/232] BCM270x_DT: Add pwr_led, and the required "input"
+Subject: [PATCH 073/304] BCM270x_DT: Add pwr_led, and the required "input"
trigger
The "input" trigger makes the associated GPIO an input. This is to support
-From d3a1dcc1ce28233707c395b11cd2403ba22aebda Mon Sep 17 00:00:00 2001
+From 46c40754e960e05c4b7f0d76241e75b5363527d5 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 27 Feb 2015 15:10:24 +0000
-Subject: [PATCH 074/232] enc28j60: Add device tree compatible string and an
+Subject: [PATCH 074/304] enc28j60: Add device tree compatible string and an
overlay
---
-From a058f705de89cb54126d9bf8d099acb7ececb6e7 Mon Sep 17 00:00:00 2001
+From fd2629ca6b3487d6efe7c49c93cb44a47cbf9e5a Mon Sep 17 00:00:00 2001
From: Waldemar Brodkorb <wbrodkorb@conet.de>
Date: Wed, 25 Mar 2015 09:26:17 +0100
-Subject: [PATCH 075/232] Add driver for rpi-proto
+Subject: [PATCH 075/304] 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
-From 78cf26e64b4ce0c4567829c42990a89ab59a6553 Mon Sep 17 00:00:00 2001
+From e892ae7922d86bdede4f59336222cb9d8cf60994 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 13 Apr 2015 17:16:29 +0100
-Subject: [PATCH 076/232] config: Add default configs
+Subject: [PATCH 076/304] config: Add default configs
---
arch/arm/configs/bcm2709_defconfig | 1254 +++++++++++++++++++++++++++++++++++
-From 0ee42e134a9a28fd825e1390634113108c0eebc0 Mon Sep 17 00:00:00 2001
+From b08ccdff6e3f9a0b17edaf423f140775a5a25c72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Wed, 29 Apr 2015 17:24:02 +0200
-Subject: [PATCH 077/232] bcm2835: bcm2835_defconfig
+Subject: [PATCH 077/304] bcm2835: bcm2835_defconfig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From d46fbf49354f8c82cc216d56d9addad113703c50 Mon Sep 17 00:00:00 2001
+From d9eaf4c9a302c60d131ce6e7384ae36085cf5731 Mon Sep 17 00:00:00 2001
From: Gordon Hollingworth <gordon@raspberrypi.org>
Date: Tue, 12 May 2015 14:47:56 +0100
-Subject: [PATCH 078/232] rpi-ft5406: Add touchscreen driver for pi LCD display
+Subject: [PATCH 078/304] 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
-From 4514b02d95de8be6d6298ee20a5204815cf669d0 Mon Sep 17 00:00:00 2001
+From 93aae11e6e1bcd5178685f85938e7c339d91a95e Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 13 Oct 2014 11:47:53 +0100
-Subject: [PATCH 079/232] Improve __copy_to_user and __copy_from_user
+Subject: [PATCH 079/304] Improve __copy_to_user and __copy_from_user
performance
Provide a __copy_from_user that uses memcpy. On BCM2708, use
-From 11e9f3f8268e79dd28450eacffe1d7484f2a7361 Mon Sep 17 00:00:00 2001
+From 328a04523323650c59fef1657143e87513c79751 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 25 Jun 2015 12:16:11 +0100
-Subject: [PATCH 080/232] gpio-poweroff: Allow it to work on Raspberry Pi
+Subject: [PATCH 080/304] 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
-From 958d09ad7f70ff5dd38a6c60b9e3f103e125168a Mon Sep 17 00:00:00 2001
+From c2c3af65be6009ded5c3c8984ab7f58f5e7797ee Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 14 Jul 2015 10:26:09 +0100
-Subject: [PATCH 081/232] spidev: Add "spidev" compatible string to silence
+Subject: [PATCH 081/304] spidev: Add "spidev" compatible string to silence
warning
See: https://github.com/raspberrypi/linux/issues/1054
-From 462447ecf49eb6dd6d77f3d21b272dd4fa68bee9 Mon Sep 17 00:00:00 2001
+From 7508b75a2466c9d6f9061fde718eb6bbfed44ede Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 14 Jul 2015 17:00:18 +0100
-Subject: [PATCH 082/232] scripts/dtc: Add overlay support
+Subject: [PATCH 082/304] scripts/dtc: Add overlay support
---
scripts/dtc/checks.c | 119 ++-
-From 98ec469c223432d4f40317023a04cfa71f661c10 Mon Sep 17 00:00:00 2001
+From 4969b05b74287320b646ec19371c1e04f1d98336 Mon Sep 17 00:00:00 2001
From: Phil Elwell <pelwell@users.noreply.github.com>
Date: Tue, 14 Jul 2015 14:32:47 +0100
-Subject: [PATCH 083/232] mfd: Add Raspberry Pi Sense HAT core driver
+Subject: [PATCH 083/304] mfd: Add Raspberry Pi Sense HAT core driver
---
drivers/input/joystick/Kconfig | 8 +
-From 5133d16d705f9ccf7f558ebc43861e1800512969 Mon Sep 17 00:00:00 2001
+From f8cf34f551e172b02306ce12da00e8c8c2550660 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jan@grulich.eu>
Date: Mon, 24 Aug 2015 16:03:47 +0100
-Subject: [PATCH 084/232] RaspiDAC3 support
+Subject: [PATCH 084/304] RaspiDAC3 support
Signed-off-by: Jan Grulich <jan@grulich.eu>
-From 570d2d99cbf2b830e0d1be01dcc6fdd339b4d157 Mon Sep 17 00:00:00 2001
+From bdf67add80855689e7580feaa8ae1c82d2f9d209 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jan@grulich.eu>
Date: Mon, 24 Aug 2015 16:02:34 +0100
-Subject: [PATCH 085/232] tpa6130a2: Add headphone switch control
+Subject: [PATCH 085/304] tpa6130a2: Add headphone switch control
Signed-off-by: Jan Grulich <jan@grulich.eu>
---
-From a9e2bfff9a39efe94a066735509643fc3bed1ba0 Mon Sep 17 00:00:00 2001
+From 19b6a85b13ed26364b6bb0946cf51ede345d8e2d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 28 Sep 2015 23:38:59 +0100
-Subject: [PATCH 086/232] irq-bcm2835: Fix building with 2708
+Subject: [PATCH 086/304] irq-bcm2835: Fix building with 2708
---
drivers/irqchip/irq-bcm2835.c | 3 ++-
-From 0a8cace2c9d473ac347cc08dfe19b24ad5ca3d2b Mon Sep 17 00:00:00 2001
+From 6e7a4e8116e8379bd3be1d88092bfb9cacee7e14 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Wed, 21 Oct 2015 14:55:21 +0100
-Subject: [PATCH 087/232] rpi_display: add backlight driver and overlay
+Subject: [PATCH 087/304] 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
-From ec2e48fda22c57cab56a4332d1a095f91c919493 Mon Sep 17 00:00:00 2001
+From a18791e434387ff2dec3fd8e32d0ae41896d40a5 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Mon, 16 Nov 2015 14:05:35 +0000
-Subject: [PATCH 088/232] bcm2835-dma: Fix up convert to DMA pool
+Subject: [PATCH 088/304] bcm2835-dma: Fix up convert to DMA pool
---
drivers/dma/bcm2835-dma.c | 36 ++++++++++++++++++++++++++----------
-From 9a67f8f17bb07bbfeee650327c88b6d381ab4af1 Mon Sep 17 00:00:00 2001
+From 8a51551a8e90b0af9ca4d1519e4ab3c4e3f0e672 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 11 Nov 2015 11:38:59 +0000
-Subject: [PATCH 089/232] scripts: Multi-platform support for mkknlimg and
+Subject: [PATCH 089/304] scripts: Multi-platform support for mkknlimg and
knlinfo
The firmware uses tags in the kernel trailer to choose which dtb file
-From 16c40415a78ba028f126b68e2cabf860186ff4f4 Mon Sep 17 00:00:00 2001
+From 1f7a26d3f23eca72e81b23fd2c624975e252b1dc Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 2 Mar 2015 13:01:12 -0800
-Subject: [PATCH 090/232] drm/vc4: Add suport for 3D rendering using the V3D
+Subject: [PATCH 090/304] drm/vc4: Add suport for 3D rendering using the V3D
engine.
This is a squash of the out-of-tree development series. Since that
-From fbec01e2d17b924d91850e17eeecf975e74c9ebf Mon Sep 17 00:00:00 2001
+From 561ea7d6af345cf43a05a188d73f2e9e29a9cde8 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 14 Oct 2015 11:32:14 -0700
-Subject: [PATCH 091/232] drm/vc4: Force HDMI to connected.
+Subject: [PATCH 091/304] drm/vc4: Force HDMI to connected.
For some reason on the downstream tree, the HPD GPIO isn't working.
-From d27b72cbcf572b0e2c18359f494d1f6aa90dd6f3 Mon Sep 17 00:00:00 2001
+From 128c58414e4c53bb5f57330b0928666a14b51f05 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 19 Oct 2015 08:23:18 -0700
-Subject: [PATCH 092/232] drm/vc4: bo cache locking fixes.
+Subject: [PATCH 092/304] drm/vc4: bo cache locking fixes.
Signed-off-by: Eric Anholt <eric@anholt.net>
---
-From 6473779beaeda1017d8487c3f510015f2b9b8f9d Mon Sep 17 00:00:00 2001
+From 6678a113e6eb5104d000f02c8cdc09eec50297ae Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 19 Oct 2015 08:29:41 -0700
-Subject: [PATCH 093/232] drm/vc4: bo cache locking cleanup.
+Subject: [PATCH 093/304] drm/vc4: bo cache locking cleanup.
Signed-off-by: Eric Anholt <eric@anholt.net>
---
-From 1ec9d09f4b9ec69b3b0422fa3c26b3bcc82af64e Mon Sep 17 00:00:00 2001
+From a97d62dbd1d65bcd0bb51aa66b1e928381146cd7 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 19 Oct 2015 08:32:24 -0700
-Subject: [PATCH 094/232] drm/vc4: Use job_lock to protect seqno_cb_list.
+Subject: [PATCH 094/304] drm/vc4: Use job_lock to protect seqno_cb_list.
We're (mostly) not supposed to be using struct_mutex in drivers these
days.
-From 016847d7cd5222d15f9213dc772d3808cd5d6e17 Mon Sep 17 00:00:00 2001
+From fb03ccdfb2baae625f8ab04d4d627dbe97545484 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 19 Oct 2015 08:44:35 -0700
-Subject: [PATCH 095/232] drm/vc4: Drop struct_mutex around CL validation.
+Subject: [PATCH 095/304] 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
-From 69aa18660bbe1ee6524c8220beb2af711146bc7f Mon Sep 17 00:00:00 2001
+From ec7429376e7e208e133d1b3fc4b48c45e9fd4826 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 19 Oct 2015 08:44:35 -0700
-Subject: [PATCH 096/232] drm/vc4: Drop struct_mutex around CL validation.
+Subject: [PATCH 096/304] 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
-From 111e49bbb002b4dd86ef0c7e0b314c336e6a01c3 Mon Sep 17 00:00:00 2001
+From 61c118e19ca1111715a2b762ff8687039e1daf6e Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Tue, 20 Oct 2015 13:59:15 +0100
-Subject: [PATCH 097/232] drm/vc4: Add support for more display plane formats.
+Subject: [PATCH 097/304] drm/vc4: Add support for more display plane formats.
Signed-off-by: Eric Anholt <eric@anholt.net>
---
-From 81dbf19b16cc789162ac94cd4e764a667111386e Mon Sep 17 00:00:00 2001
+From 966f44478d6ccb55bfd20b1249cb20a729519190 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 23 Oct 2015 12:31:56 +0100
-Subject: [PATCH 098/232] drm/vc4: No need to stop the stopped threads.
+Subject: [PATCH 098/304] 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.
-From 9db0b8d54024bf5a2d0c3239aa571d890e8c8b3a Mon Sep 17 00:00:00 2001
+From 7c5a9af8ff8784fa03e51c1db9c00d846edc7cdd Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 23 Oct 2015 12:33:43 +0100
-Subject: [PATCH 099/232] drm/vc4: Remove extra barrier()s aroudn CTnCA/CTnEA
+Subject: [PATCH 099/304] drm/vc4: Remove extra barrier()s aroudn CTnCA/CTnEA
setup.
The writel() that these expand to already does barriers.
-From 03b4b90b8e265158ac3529428f7aaf5f3b0f8a7a Mon Sep 17 00:00:00 2001
+From ef7adf5749220e6d03f2a49ae87e0246990d7318 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 23 Oct 2015 14:57:22 +0100
-Subject: [PATCH 100/232] drm/vc4: Fix a typo in a V3D debug register.
+Subject: [PATCH 100/304] drm/vc4: Fix a typo in a V3D debug register.
Signed-off-by: Eric Anholt <eric@anholt.net>
---
-From a5b0c616e9b40bd7907c5157700661004a8ef331 Mon Sep 17 00:00:00 2001
+From 8797031295e4443ed97e368d7fdfac28a2033c5c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 2 Nov 2015 17:07:33 +0000
-Subject: [PATCH 101/232] drm/vc4: Enable VC4 modules, and increase CMA size
+Subject: [PATCH 101/304] 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,
-From 17f4de0c9daea638476ca0f80123d3523e66fdc0 Mon Sep 17 00:00:00 2001
+From af69b8bba233eadb7ea8efafdcb150e5948a30f4 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Nov 2015 18:29:58 +0000
-Subject: [PATCH 102/232] squash: fixups
+Subject: [PATCH 102/304] squash: fixups
---
drivers/gpu/drm/vc4/Kconfig | 2 +-
-From c1834a750441c3ea55f24377e04cf8d1fb66c877 Mon Sep 17 00:00:00 2001
+From ad6efff00c05f8c62f00bbf40f8d1437d8f9a6c4 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Nov 2015 20:26:03 +0000
-Subject: [PATCH 103/232] squash: add missing vc4-kms-v3d-overlay.dtb to
+Subject: [PATCH 103/304] squash: add missing vc4-kms-v3d-overlay.dtb to
makefile
---
-From 084eeec470e76e8c84cda1a31e323610467913bd Mon Sep 17 00:00:00 2001
+From 6787949088d4c06d784b2c647a13fd9e85c5ea1e Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 12 Oct 2015 11:23:34 -0700
-Subject: [PATCH 104/232] clk: bcm2835: Also build the driver for downstream
+Subject: [PATCH 104/304] clk: bcm2835: Also build the driver for downstream
kernels.
Signed-off-by: Eric Anholt <eric@anholt.net>
-From cbb80e24a9db48390c82c7030cc7f7389aee953f Mon Sep 17 00:00:00 2001
+From bee71d721d6f0269a37a3fab61f9af2b47dc32ca Mon Sep 17 00:00:00 2001
From: Holger Steinhaus <hsteinhaus@gmx.de>
Date: Sat, 14 Nov 2015 18:37:43 +0100
-Subject: [PATCH 105/232] dts: Added overlay for gpio_ir_recv driver
+Subject: [PATCH 105/304] dts: Added overlay for gpio_ir_recv driver
---
arch/arm/boot/dts/overlays/Makefile | 1 +
-From c644d7cae9394e209fc2451b91d2852ebfc85a09 Mon Sep 17 00:00:00 2001
+From a94e2448879eea9ae5344862aa091c3009dec805 Mon Sep 17 00:00:00 2001
From: Alistair Buxton <a.j.buxton@gmail.com>
Date: Sun, 1 Nov 2015 22:27:56 +0000
-Subject: [PATCH 106/232] Build i2c_gpio module and add a device tree overlay
+Subject: [PATCH 106/304] Build i2c_gpio module and add a device tree overlay
to configure it.
---
-From a5a974dbeaaf0be8b1fa5d8c6f117b320ea01b44 Mon Sep 17 00:00:00 2001
+From d8b1f87438596cebc2b8e896c2d1a7c58cb14ca1 Mon Sep 17 00:00:00 2001
From: mwilliams03 <mark.mwilliams@gmail.com>
Date: Sun, 18 Oct 2015 17:07:24 -0700
-Subject: [PATCH 107/232] New overlay for PiScreen2r
+Subject: [PATCH 107/304] New overlay for PiScreen2r
---
arch/arm/boot/dts/overlays/Makefile | 1 +
-From 708f013bf40633883113c3fbaca5555b7d115906 Mon Sep 17 00:00:00 2001
+From c036a8544cdc048ae4fa4370a5899447975184d6 Mon Sep 17 00:00:00 2001
From: Ondrej Wisniewski <ondrej.wisniewski@gmail.com>
Date: Fri, 6 Nov 2015 15:01:28 +0100
-Subject: [PATCH 108/232] dts: Added overlay for Adafruit PiTFT 2.8" capacitive
+Subject: [PATCH 108/304] dts: Added overlay for Adafruit PiTFT 2.8" capacitive
touch screen
---
-From b706bc693765cc80c31076e8fa0e35e798c12bbf Mon Sep 17 00:00:00 2001
+From 249509724dc6c5639d9a1fdea1075b65ba4d5efb Mon Sep 17 00:00:00 2001
From: Stuart MacLean <stuart@hifiberry.com>
Date: Fri, 2 Oct 2015 15:12:59 +0100
-Subject: [PATCH 109/232] Add support for the HiFiBerry DAC+ Pro.
+Subject: [PATCH 109/304] 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.
-From 9fa71fbc6193d214f9a5432f85bb17f47016ba65 Mon Sep 17 00:00:00 2001
+From 09c63075be44e53b139d5741f7397f8e8939ae58 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 5 Oct 2015 10:47:45 +0100
-Subject: [PATCH 110/232] BCM270X_DT: Add at86rf233 overlay
+Subject: [PATCH 110/304] BCM270X_DT: Add at86rf233 overlay
Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0.
-From 4df259e844e183bf00e1c5eb8ca25dcf19d396ce Mon Sep 17 00:00:00 2001
+From 8f4163a595499ea2950960eb8a1fd187f28e2617 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Thu, 18 Dec 2014 16:07:15 -0800
-Subject: [PATCH 111/232] mm: Remove the PFN busy warning
+Subject: [PATCH 111/304] mm: Remove the PFN busy warning
See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is
expected sometimes when using CMA. However, that commit still spams
-From b1891f7b0018e7e778f49c1817692e1f85a1f529 Mon Sep 17 00:00:00 2001
+From 0bd7f965ad98ce1304519379ef72ca1a4960483d Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 19 Nov 2014 12:06:38 -0800
-Subject: [PATCH 112/232] drm: Put an optional field in the driver struct for
+Subject: [PATCH 112/304] 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
-From b9e5697fbec13e6203b63649ee5d7c6819a5fb6b Mon Sep 17 00:00:00 2001
+From eb445fa566bd604dd3c0cd5e08e43735ccc149f2 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 30 Oct 2015 10:09:02 -0700
-Subject: [PATCH 113/232] drm/vc4: Add an interface for capturing the GPU state
+Subject: [PATCH 113/304] 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
-From e4058e84edec652f5a7b3e9e4982eac62b22a90c Mon Sep 17 00:00:00 2001
+From ac832d51da00be28cf70a2c33cfb07ef06a7e94c Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 4 Dec 2015 11:35:34 -0800
-Subject: [PATCH 114/232] drm/vc4: Update a bunch of code to match upstream
+Subject: [PATCH 114/304] drm/vc4: Update a bunch of code to match upstream
submission.
This gets almost everything matching, except for the MSAA support and
-From 659b247a25ea9439be74087726d6adfae7570d12 Mon Sep 17 00:00:00 2001
+From 0625c4c03ba8e37d4757a410018c22b5d549036c Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 11 Dec 2015 19:45:03 -0800
-Subject: [PATCH 115/232] drm: Use the driver's gem_object_free function from
+Subject: [PATCH 115/304] 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
-From 878a974dd326f144ba90c1cf018db604bf127835 Mon Sep 17 00:00:00 2001
+From cd77071a812478dd844c4099ddff4022e2ea1ba0 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Fri, 17 Jul 2015 13:15:50 -0700
-Subject: [PATCH 116/232] drm/vc4: Add support for MSAA rendering.
+Subject: [PATCH 116/304] 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
-From 6e271c79f63541cbc2e8101a39aa2b0e8d2634c4 Mon Sep 17 00:00:00 2001
+From 5042cf1359c0e6a3d3bf3c16935495dd7de0d0e4 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Tue, 8 Dec 2015 14:00:43 -0800
-Subject: [PATCH 117/232] drm/vc4: A few more non-functional changes to sync to
+Subject: [PATCH 117/304] 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,
-From 6fa2e872ce528f957b0c3aa735aa46b24ed6601a Mon Sep 17 00:00:00 2001
+From b3d44742ea002847e375285972eaed72e5afcfc6 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Tue, 15 Dec 2015 23:46:32 +0000
-Subject: [PATCH 118/232] drm/vc4: Use "hpd-gpios" for HDMI GPIO, like what
+Subject: [PATCH 118/304] drm/vc4: Use "hpd-gpios" for HDMI GPIO, like what
landed upstream.
Signed-off-by: Eric Anholt <eric@anholt.net>
-From 76172185d9852c3e2bf7ace7c040b62dd220d9aa Mon Sep 17 00:00:00 2001
+From 177e3650535f343b34168fa9c0c5af06127336cc Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 7 Dec 2015 12:35:01 -0800
-Subject: [PATCH 119/232] drm/vc4: Synchronize validation code for v2
+Subject: [PATCH 119/304] drm/vc4: Synchronize validation code for v2
submission upstream.
Signed-off-by: Eric Anholt <eric@anholt.net>
-From f825bd28e15f4a4e653f8a81e2a02ac9da1068ca Mon Sep 17 00:00:00 2001
+From ae003608a7caac62858c99e084f47331a6063552 Mon Sep 17 00:00:00 2001
From: janluca <janluca@zedat.fu-berlin.de>
Date: Sun, 27 Dec 2015 14:34:04 +0100
-Subject: [PATCH 120/232] MMC: Do not use mmc_debug if CONFIG_MMC_BCM2835 is
+Subject: [PATCH 120/304] 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
-From 127a32cdd6005a42f6b5b63de9d7db573d9de184 Mon Sep 17 00:00:00 2001
+From bc370a3ec1d5f04e1d9db30ffc3e5aff2cee7bd7 Mon Sep 17 00:00:00 2001
From: Devon Fyson <devonfyson@gmail.com>
Date: Wed, 30 Dec 2015 16:40:47 -0500
-Subject: [PATCH 121/232] Extend clock timeout, fix modprobe baudrate
+Subject: [PATCH 121/304] 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.
-From bde59419fd4b9dac732341a62159f01094dfe70d Mon Sep 17 00:00:00 2001
+From 8d1dbb024b39e79f2c7abd1d8c3b13ad6f0296b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Thu, 31 Dec 2015 16:44:58 +0100
-Subject: [PATCH 122/232] bcm270x_dt: Add dwc2 and dwc-otg overlays
+Subject: [PATCH 122/304] bcm270x_dt: Add dwc2 and dwc-otg overlays
---
arch/arm/boot/dts/overlays/Makefile | 2 ++
-From 5d03b10c60e70fb5d316706a3777e46dc9dd748e Mon Sep 17 00:00:00 2001
+From f2b8a48896e7f505578083282968c663f7e86acb Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 4 Jan 2016 14:42:17 +0000
-Subject: [PATCH 123/232] BCM270X_DT: Add the sdtweak overlay, for tuning
+Subject: [PATCH 123/304] BCM270X_DT: Add the sdtweak overlay, for tuning
sdhost
The sdhost overlay declares the sdhost interface and allows parameters
-From 17589e37dff9745d9c219973a77031905cb57973 Mon Sep 17 00:00:00 2001
+From 46eadeb2ec2cc6153ee45396dc3c90f85ce79d7e Mon Sep 17 00:00:00 2001
From: Andrew Litt <ajlitt@splunge.net>
Date: Mon, 11 Jan 2016 07:54:21 +0000
-Subject: [PATCH 124/232] bcm2835-mmc: Don't override bus width capabilities
+Subject: [PATCH 124/304] bcm2835-mmc: Don't override bus width capabilities
from devicetree
Take out the force setting of the MMC_CAP_4_BIT_DATA host capability
-From c671b8fada8fe75583e25cd93f9a414c7024e613 Mon Sep 17 00:00:00 2001
+From 99f1bca44186bd6015f93cec4a18594b70a8e0e5 Mon Sep 17 00:00:00 2001
From: Andrew Litt <ajlitt@splunge.net>
Date: Mon, 11 Jan 2016 07:55:54 +0000
-Subject: [PATCH 125/232] SDIO-overlay: add bus_width parameter
+Subject: [PATCH 125/304] 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
-From 688a5f0daa45e0a51b324707768d472e1d715c13 Mon Sep 17 00:00:00 2001
+From e995023b752af4cc6f6863d5beaaf4a3b9144b20 Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:41:45 +0100
-Subject: [PATCH 126/232] bcm2835: extend allowed range of channels and
+Subject: [PATCH 126/304] bcm2835: extend allowed range of channels and
samplerates
Allow everything the videocore accepts.
-From 435962380099cafba4db3d3806b8e03cbcb0774e Mon Sep 17 00:00:00 2001
+From 745dfb0adfc2e3aa4d6c011dd4cb29abeaef8916 Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:42:18 +0100
-Subject: [PATCH 127/232] bcm2835: restrict channels*rate to 8*960000
+Subject: [PATCH 127/304] 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
-From 64fa9f963dffab0145f7960a593422064bb0aa8d Mon Sep 17 00:00:00 2001
+From b94e0945195ad483d345a1d657785d21b85ab246 Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:42:48 +0100
-Subject: [PATCH 128/232] rpi: update vc_vchi_audioserv_defs.h
+Subject: [PATCH 128/304] rpi: update vc_vchi_audioserv_defs.h
Add audioserv 3 extensions. The changes were taken from the paste
linked here:
-From 5efba3f8c180c39609a8d40033ef92046ef0de75 Mon Sep 17 00:00:00 2001
+From eb75f32685cc0bc93053f1acb09e06745d38b60c Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:43:12 +0100
-Subject: [PATCH 129/232] bcm2835: implement channel map API
+Subject: [PATCH 129/304] 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
-From 26e1f66589860cfcc9a6473d705db890e1b8f6c1 Mon Sep 17 00:00:00 2001
+From fb9b7c60bed82b9a4c6ed329b349e6e5b8a60db9 Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:43:35 +0100
-Subject: [PATCH 130/232] bcm2835: access controls under the audio mutex
+Subject: [PATCH 130/304] 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
-From 06931f74092d86087144f070b06a4444df8b444b Mon Sep 17 00:00:00 2001
+From 7223126699f76c76ff770282c5da2395d473014a Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:44:03 +0100
-Subject: [PATCH 131/232] bcm2835: always use 2/4/8 channels for multichannel
+Subject: [PATCH 131/304] bcm2835: always use 2/4/8 channels for multichannel
layouts
Pad the unused channels with NA. This means userspace needs to write
-From 5f7049894f47b3836838cd68e29ee883179c80b3 Mon Sep 17 00:00:00 2001
+From bd016cefc53060ff4c2d00d36be505c263aa3fb3 Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:44:24 +0100
-Subject: [PATCH 132/232] bcm2835: only allow stereo if analogue jack is
+Subject: [PATCH 132/304] bcm2835: only allow stereo if analogue jack is
selected
Sending more than 2 channels to videocore while outputting to analogue
-From 83eca613d0eddd2c8299f114b8fe573ccaffdefc Mon Sep 17 00:00:00 2001
+From 641d7675c007bdf97f10b320fa38d1f089d43d5d Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:44:47 +0100
-Subject: [PATCH 133/232] bcm2835: interpolate audio delay
+Subject: [PATCH 133/304] 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
-From 22a9a698b6cbce7494ea14dce0e784e098c01ecb Mon Sep 17 00:00:00 2001
+From 48d2aa4f18c8e32198136e5aaea252777cfc0490 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 19 Jan 2016 17:16:38 +0000
-Subject: [PATCH 134/232] bcm2835-sdhost: Add workaround for odd behaviour on
+Subject: [PATCH 134/304] bcm2835-sdhost: Add workaround for odd behaviour on
some cards
For reasons not understood, the sdhost driver fails when reading
-From d038f759d55f39c97e4232851e821b5e4b2fe7a2 Mon Sep 17 00:00:00 2001
+From fad42870d095f811114d6bfd6dedf34595e24a23 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 22 Jan 2016 16:03:24 +0000
-Subject: [PATCH 135/232] bcm2835-sdhost: Add debug_flags dtparam
+Subject: [PATCH 135/304] bcm2835-sdhost: Add debug_flags dtparam
Bit zero disables the single-read-sectors map:
-From 3f4c1f041954c21f9f06c7fe7df3d0e5711667e0 Mon Sep 17 00:00:00 2001
+From 9a7e2ae47f11f7ff5cb4dd2b87e9caeb0953b18d Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 25 Jan 2016 09:12:06 +0000
-Subject: [PATCH 136/232] BCM270X_DT: Add sdio_overclock parameter to sdio
+Subject: [PATCH 136/304] BCM270X_DT: Add sdio_overclock parameter to sdio
overlay
The sdio_overclock parameter is like the overclock_50 parameter, i.e.
-From 6f5d0a941a6a084c677a8843207a42f7b6d5a04d Mon Sep 17 00:00:00 2001
+From c460f1c0adf52314689b3ceb4611a03604ddcbb2 Mon Sep 17 00:00:00 2001
From: Michael Lange <linuxstuff@milaw.biz>
Date: Thu, 21 Jan 2016 18:10:16 +0100
-Subject: [PATCH 137/232] rtc: ds1307: add support for the DT property
+Subject: [PATCH 137/304] rtc: ds1307: add support for the DT property
'wakeup-source'
For RTC chips with no IRQ directly connected to the SoC, the RTC chip
-From 873bf69f1f6bf19f2a0c4cec884cb952b2a19e0c Mon Sep 17 00:00:00 2001
+From 705c8908dc07362e5b0ab975d5842a16cc014e1d Mon Sep 17 00:00:00 2001
From: vitalogy <vitalogy_github@milaw.biz>
Date: Tue, 19 Jan 2016 07:02:02 +0100
-Subject: [PATCH 138/232] dt-overlay: add wittypi-overlay.dts
+Subject: [PATCH 138/304] dt-overlay: add wittypi-overlay.dts
---
arch/arm/boot/dts/overlays/wittypi-overlay.dts | 44 ++++++++++++++++++++++++++
-From c74fc12557305b66537dc6e8ed3ab5d27c507de0 Mon Sep 17 00:00:00 2001
+From 8fc1dbc4b294803d2a6794b1ede681641da45711 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 19 Jan 2016 16:28:05 +0000
-Subject: [PATCH 139/232] FIXUP i2c_bcm2708: Don't change module baudrate
+Subject: [PATCH 139/304] FIXUP i2c_bcm2708: Don't change module baudrate
parameter
Overwriting the baudrate module parameter creates an apparent
-From 4593191b7df9439c295a93250a1f1d68d0938822 Mon Sep 17 00:00:00 2001
+From 796cd923dec66639357bf711ae5758d86e8cd3f3 Mon Sep 17 00:00:00 2001
From: Digital Dreamtime <clive.messer@digitaldreamtime.co.uk>
Date: Thu, 4 Feb 2016 14:14:44 +0000
-Subject: [PATCH 140/232] Allow up to 24dB digital gain to be applied when
+Subject: [PATCH 140/304] 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
-From 6fda328fc5613d449641ad6701fe8180e70ec338 Mon Sep 17 00:00:00 2001
+From acea17bbc6dd9aabe2da5c95e21b1fc7406cf1fb Mon Sep 17 00:00:00 2001
From: Digital Dreamtime <clive.messer@digitaldreamtime.co.uk>
Date: Thu, 4 Feb 2016 20:04:00 +0000
-Subject: [PATCH 141/232] Limit PCM512x "Digital" gain to 0dB by default with
+Subject: [PATCH 141/304] Limit PCM512x "Digital" gain to 0dB by default with
HiFiBerry DAC+
24db_digital_gain DT param can be used to specify that PCM512x
-From 1b3fd5b03546474795b7557a04c7c3c5cf162ecb Mon Sep 17 00:00:00 2001
+From 1bf407348eb9be0b793da4350f2daba91db4ea4f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 8 Feb 2016 09:46:33 +0000
-Subject: [PATCH 142/232] BCM270X_DT: Adjust overlay README formatting
+Subject: [PATCH 142/304] BCM270X_DT: Adjust overlay README formatting
---
arch/arm/boot/dts/overlays/README | 414 +++++++++++++++++++-------------------
--- /dev/null
+From 978d4ec47c4a66491140e964939889c427feee64 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 11 Feb 2016 16:51:01 +0000
+Subject: [PATCH 143/304] 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 <phil@raspberrypi.org>
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 1284 ++++++++++++++++++++-----------------
+ 1 file changed, 686 insertions(+), 598 deletions(-)
+
+--- 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 <phil@raspberrypi.org>
+- * 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 <http://www.gnu.org/licenses/>.
+ */
+
+-#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 <linux/delay.h>
+ #include <linux/module.h>
+@@ -48,6 +49,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/of_dma.h>
+ #include <linux/time.h>
++#include <linux/workqueue.h>
+
+ #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(struc
+ 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(struc
+
+ 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_interna
+ temp = bcm2835_sdhost_read(host, SDEDM);
+ temp &= ~((SDEDM_THRESHOLD_MASK<<SDEDM_READ_THRESHOLD_SHIFT) |
+ (SDEDM_THRESHOLD_MASK<<SDEDM_WRITE_THRESHOLD_SHIFT));
+- temp |= (SAFE_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
+- (SAFE_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
++ temp |= (FIFO_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
++ (FIFO_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
+ bcm2835_sdhost_write(host, temp, SDEDM);
+ mdelay(10);
+ 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();
+ }
+
+-
+ 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 b
+ }
+ }
+
+-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);
++ int timediff;
++ u32 alternate_idle;
++ u32 edm;
+
+- 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;
+- }
+- }
++ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ?
++ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1;
+
+- return write_complete;
+-}
++ edm = bcm2835_sdhost_read(host, SDEDM);
+
+-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;
+-
+- 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(s
+ 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_pi
+ 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_p
+ 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;
++ }
+
+- bcm2835_sdhost_write(host, *(buf++), SDDATA);
+- len -= 4;
++ 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;
+ }
+
+@@ -566,12 +728,12 @@ static void bcm2835_sdhost_write_block_p
+ 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(
+ 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);
++ log_event("PRD<", (u32)data, 0);
++ pr_debug("bcm2835_sdhost_prepare_dma()\n");
+
+- if (!host->data)
+- return;
+-
+- 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(
+ 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;
++ }
++
++ 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_
+ 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(
+ 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(
+ 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
+ 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
+ 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
+ }
+
+ 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_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(s
+ 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(s
+ 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(s
+ }
+ 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_comp
+ 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_comp
+ * 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_comman
+ 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_comman
+ 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)
+@@ -1050,6 +1244,7 @@ static void bcm2835_sdhost_finish_comman
+ 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(unsig
+ 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(unsig
+ spin_unlock_irqrestore(&host->lock, flags);
+ }
+
+-static void bcm2835_sdhost_pio_timeout(unsigned long data)
+-{
+- 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)
++static void 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(struc
+ "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(struc
+ } 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(struc
+ 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(stru
+ 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 bcm
+ 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 bcm
+ 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(struc
+ {
+ struct bcm2835_host *host;
+ unsigned long flags;
++ u32 edm, fsm;
+
+ host = mmc_priv(mmc);
+
+@@ -1521,6 +1570,8 @@ static void bcm2835_sdhost_request(struc
+ }
+
+ /* 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(struc
+ 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;
++ }
++
++ 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 (!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, &flags);
++ }
+
+- if (!host->use_busy)
+- bcm2835_sdhost_finish_command(host);
+-}
++ 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(struc
+
+ 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(struc
+ 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.
+- */
++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)
++{
+ 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_finis
+
+ 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 bcm28
+ 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 bcm28
+ 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 bcm28
+ 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 bcm28
+ 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 bcm28
+ 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 p
+ 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 p
+ 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 p
+ 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
+ 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,
--- /dev/null
+From 5920a56447c13b86d073a388be113c28c2a8681d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 12 Feb 2016 15:38:00 +0000
+Subject: [PATCH 144/304] 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(-)
+
+--- 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";
+ };
+ };
+--- 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";
+ };
+ };
+--- 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";
+ };
+ };
+--- 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";
+ };
+ };
+--- 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";
+ };
+
+--- 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";
+ };
+ };
+--- 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 d
+ Load: dtoverlay=mmc,<param>=<val>
+ Params: overclock_50 Clock (in MHz) to use when the MMC framework
+ requests 50MHz
+- force_pio Disable DMA support
+
+
+ Name: mz61581
+--- 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?";
+ };
+ };
+--- 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?";
+ };
+ };
+--- 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?";
+ };
+ };
+++ /dev/null
-From 60425f3b85682fa3378cb6aeecce15a50384b7e2 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 11 Feb 2016 16:51:01 +0000
-Subject: [PATCH 144/232] 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 <phil@raspberrypi.org>
----
- drivers/mmc/host/bcm2835-sdhost.c | 1284 ++++++++++++++++++++-----------------
- 1 file changed, 686 insertions(+), 598 deletions(-)
-
---- 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 <phil@raspberrypi.org>
-- * 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 <http://www.gnu.org/licenses/>.
- */
-
--#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 <linux/delay.h>
- #include <linux/module.h>
-@@ -48,6 +49,7 @@
- #include <linux/dma-mapping.h>
- #include <linux/of_dma.h>
- #include <linux/time.h>
-+#include <linux/workqueue.h>
-
- #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(struc
- 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(struc
-
- 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_interna
- temp = bcm2835_sdhost_read(host, SDEDM);
- temp &= ~((SDEDM_THRESHOLD_MASK<<SDEDM_READ_THRESHOLD_SHIFT) |
- (SDEDM_THRESHOLD_MASK<<SDEDM_WRITE_THRESHOLD_SHIFT));
-- temp |= (SAFE_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
-- (SAFE_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
-+ temp |= (FIFO_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
-+ (FIFO_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
- bcm2835_sdhost_write(host, temp, SDEDM);
- mdelay(10);
- 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();
- }
-
--
- 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 b
- }
- }
-
--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);
-+ int timediff;
-+ u32 alternate_idle;
-+ u32 edm;
-
-- 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;
-- }
-- }
-+ alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ?
-+ SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1;
-
-- return write_complete;
--}
-+ edm = bcm2835_sdhost_read(host, SDEDM);
-
--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;
--
-- 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(s
- 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_pi
- 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_p
- 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;
-+ }
-
-- bcm2835_sdhost_write(host, *(buf++), SDDATA);
-- len -= 4;
-+ 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;
- }
-
-@@ -566,12 +728,12 @@ static void bcm2835_sdhost_write_block_p
- 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(
- 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);
-+ log_event("PRD<", (u32)data, 0);
-+ pr_debug("bcm2835_sdhost_prepare_dma()\n");
-
-- if (!host->data)
-- return;
--
-- 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(
- 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;
-+ }
-+
-+ 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_
- 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(
- 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(
- 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
- 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
- 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
- }
-
- 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_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(s
- 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(s
- 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(s
- }
- 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_comp
- 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_comp
- * 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_comman
- 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_comman
- 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)
-@@ -1050,6 +1244,7 @@ static void bcm2835_sdhost_finish_comman
- 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(unsig
- 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(unsig
- spin_unlock_irqrestore(&host->lock, flags);
- }
-
--static void bcm2835_sdhost_pio_timeout(unsigned long data)
--{
-- 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)
-+static void 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(struc
- "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(struc
- } 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(struc
- 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(stru
- 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 bcm
- 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 bcm
- 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(struc
- {
- struct bcm2835_host *host;
- unsigned long flags;
-+ u32 edm, fsm;
-
- host = mmc_priv(mmc);
-
-@@ -1521,6 +1570,8 @@ static void bcm2835_sdhost_request(struc
- }
-
- /* 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(struc
- 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;
-+ }
-+
-+ 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 (!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, &flags);
-+ }
-
-- if (!host->use_busy)
-- bcm2835_sdhost_finish_command(host);
--}
-+ 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(struc
-
- 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(struc
- 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.
-- */
-+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)
-+{
- 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_finis
-
- 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 bcm28
- 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 bcm28
- 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 bcm28
- 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 bcm28
- 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 bcm28
- 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 p
- 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 p
- 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 p
- 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
- 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,
+++ /dev/null
-From 177ef127e03243ede5b1b00032d5f9fdce94673b Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 12 Feb 2016 15:38:00 +0000
-Subject: [PATCH 145/232] 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(-)
-
---- 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";
- };
- };
---- 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";
- };
- };
---- 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";
- };
- };
---- 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";
- };
- };
---- 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";
- };
-
---- 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";
- };
- };
---- 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 d
- Load: dtoverlay=mmc,<param>=<val>
- Params: overclock_50 Clock (in MHz) to use when the MMC framework
- requests 50MHz
-- force_pio Disable DMA support
-
-
- Name: mz61581
---- 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?";
- };
- };
---- 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?";
- };
- };
---- 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?";
- };
- };
--- /dev/null
+From 9b47d7a9a98af616d910ed6ee561afa39fc41855 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 12 Feb 2016 14:50:25 +0000
+Subject: [PATCH 145/304] 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(+)
+
+--- 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(dw
+ 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(d
+ {
+ 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,
--- /dev/null
+From 1bb1322d03193dc4214b030afad507d0df18e55c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 15 Feb 2016 10:00:27 +0000
+Subject: [PATCH 146/304] 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(-)
+
+--- a/drivers/mmc/host/bcm2835-sdhost.c
++++ b/drivers/mmc/host/bcm2835-sdhost.c
+@@ -874,15 +874,14 @@ static void bcm2835_sdhost_prepare_data(
+ 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;
+ }
+++ /dev/null
-From 63ff907f6e6ab3b93535dc2b5251b7b41eaf7ec2 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Fri, 12 Feb 2016 14:50:25 +0000
-Subject: [PATCH 146/232] 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(+)
-
---- 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(dw
- 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(d
- {
- 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,
--- /dev/null
+From b94760d282632d4542f5b0fa785b8213311b1484 Mon Sep 17 00:00:00 2001
+From: Craig Roberts <cjr@craigroberts.net>
+Date: Tue, 16 Feb 2016 10:03:42 +0000
+Subject: [PATCH 147/304] Updated smsc95xx driver to check for a valid MAC
+ address in eeprom before using smsc95xx.macaddr parameter passed on command
+ line.
+
+The built-in RPi adaptor will still get a MAC address based on the parameter passed on the command line as the RPi hardware does not have an eeprom,
+however usb->ethernet adaptors using the same driver should have an eeprom with MAC address as part of their hardware and therefore will use this
+meaning they don't end up with the same MAC address as the built-in RPi adaptor.
+---
+ drivers/net/usb/smsc95xx.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -817,10 +817,6 @@ static int smsc95xx_is_macaddr_param(str
+
+ static void smsc95xx_init_mac_address(struct usbnet *dev)
+ {
+- /* Check module parameters */
+- if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr))
+- return;
+-
+ /* 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(st
+ }
+ }
+
+- /* no eeprom, or eeprom values are invalid. generate random MAC */
++ /* Check module parameters */
++ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr))
++ return;
++
++ /* no eeprom, or eeprom values are invalid, and no module parameter specified to set MAC. Generate random MAC */
+ eth_hw_addr_random(dev->net);
+ netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n");
+ }
+++ /dev/null
-From ebb44753d0310c6adb03a9b448a4038c3e37e6e0 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 15 Feb 2016 10:00:27 +0000
-Subject: [PATCH 147/232] 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(-)
-
---- a/drivers/mmc/host/bcm2835-sdhost.c
-+++ b/drivers/mmc/host/bcm2835-sdhost.c
-@@ -874,15 +874,14 @@ static void bcm2835_sdhost_prepare_data(
- 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;
- }
+++ /dev/null
-From 55e8519aa4c86b37f1933e8e53c6e97372d61871 Mon Sep 17 00:00:00 2001
-From: Craig Roberts <cjr@craigroberts.net>
-Date: Tue, 16 Feb 2016 10:03:42 +0000
-Subject: [PATCH 148/232] Updated smsc95xx driver to check for a valid MAC
- address in eeprom before using smsc95xx.macaddr parameter passed on command
- line.
-
-The built-in RPi adaptor will still get a MAC address based on the parameter passed on the command line as the RPi hardware does not have an eeprom,
-however usb->ethernet adaptors using the same driver should have an eeprom with MAC address as part of their hardware and therefore will use this
-meaning they don't end up with the same MAC address as the built-in RPi adaptor.
----
- drivers/net/usb/smsc95xx.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/net/usb/smsc95xx.c
-+++ b/drivers/net/usb/smsc95xx.c
-@@ -817,10 +817,6 @@ static int smsc95xx_is_macaddr_param(str
-
- static void smsc95xx_init_mac_address(struct usbnet *dev)
- {
-- /* Check module parameters */
-- if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr))
-- return;
--
- /* 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(st
- }
- }
-
-- /* no eeprom, or eeprom values are invalid. generate random MAC */
-+ /* Check module parameters */
-+ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr))
-+ return;
-+
-+ /* no eeprom, or eeprom values are invalid, and no module parameter specified to set MAC. Generate random MAC */
- eth_hw_addr_random(dev->net);
- netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n");
- }
--- /dev/null
+From 1e2926e39764ae4642df940fa799657c204399a9 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 17 Feb 2016 19:02:31 +0000
+Subject: [PATCH 148/304] 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(-)
+
+--- 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(dw
+ &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(d
+ 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;
+ }
+
--- /dev/null
+From 4d033ce157ae8cce859a038c47aa955d4a5c37cd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 18 Feb 2016 15:28:14 +0000
+Subject: [PATCH 149/304] 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(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -188,7 +188,7 @@ Load: dtoverlay=at86rf233,<param>=<val
+ 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)
+
+--- 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>;
+ };
+ };
+++ /dev/null
-From 3f4cd273dcc578b48783a23fb2cbef50e7fd151d Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Wed, 17 Feb 2016 19:02:31 +0000
-Subject: [PATCH 149/232] 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(-)
-
---- 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(dw
- &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(d
- 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;
- }
-
+++ /dev/null
-From f7f0e8b831ae66fc19c1f9457975d0f8b31ea601 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 18 Feb 2016 15:28:14 +0000
-Subject: [PATCH 150/232] 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(-)
-
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -188,7 +188,7 @@ Load: dtoverlay=at86rf233,<param>=<val
- 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)
-
---- 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>;
- };
- };
--- /dev/null
+From 9d6ac53072ccc9bc93cd5698b62220cf4900a198 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 19 Feb 2016 12:04:48 +0000
+Subject: [PATCH 150/304] bcm2835-sdhost: Downgrade log message status
+
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- 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");
+++ /dev/null
-From 76667f779c11557d7ebc84130619c25f3c1642af Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 19 Feb 2016 12:04:48 +0000
-Subject: [PATCH 151/232] bcm2835-sdhost: Downgrade log message status
-
----
- drivers/mmc/host/bcm2835-sdhost.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- 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");
--- /dev/null
+From ad3ed29f3c3e945a82602cd3623ac53d1cba1999 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 15 Jan 2016 16:48:27 +0000
+Subject: [PATCH 151/304] config: Enable HCI over UARTs
+
+---
+ arch/arm/configs/bcm2709_defconfig | 3 +++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
+ 2 files changed, 5 insertions(+)
+
+--- 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
+--- 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
+++ /dev/null
-From ab8cd307467682fa1df2bfadeb3ac88c086f861c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 15 Jan 2016 16:48:27 +0000
-Subject: [PATCH 152/232] config: Enable HCI over UARTs
-
----
- arch/arm/configs/bcm2709_defconfig | 3 +++
- arch/arm/configs/bcmrpi_defconfig | 2 ++
- 2 files changed, 5 insertions(+)
-
---- 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
---- 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
--- /dev/null
+From d01147893a87ead6e3f129a36f61bcdf34fc588a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 17 Dec 2015 13:37:07 +0000
+Subject: [PATCH 152/304] 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(-)
+
+--- a/drivers/bluetooth/hci_h5.c
++++ b/drivers/bluetooth/hci_h5.c
+@@ -314,7 +314,8 @@ static void h5_handle_internal_rx(struct
+ 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);
--- /dev/null
+From d06dacf300fbd1eee8c8b1e9c916f4856622b9c2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 23 Feb 2016 17:26:48 +0000
+Subject: [PATCH 153/304] amba_pl011: Don't use DT aliases for numbering
+
+The pl011 driver looks for DT aliases of the form "serial<n>",
+and if found uses <n> 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(+)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -2313,7 +2313,12 @@ static int pl011_setup_port(struct devic
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
++ /* Don't use DT serial<n> 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;
+++ /dev/null
-From 85dc4378167d99218df01bb0512a4def9710a0a5 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 17 Dec 2015 13:37:07 +0000
-Subject: [PATCH 153/232] 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(-)
-
---- a/drivers/bluetooth/hci_h5.c
-+++ b/drivers/bluetooth/hci_h5.c
-@@ -314,7 +314,8 @@ static void h5_handle_internal_rx(struct
- 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);
+++ /dev/null
-From e9950fa4e93333baad36537cc46121cc7cecf455 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 23 Feb 2016 17:26:48 +0000
-Subject: [PATCH 154/232] amba_pl011: Don't use DT aliases for numbering
-
-The pl011 driver looks for DT aliases of the form "serial<n>",
-and if found uses <n> 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(+)
-
---- a/drivers/tty/serial/amba-pl011.c
-+++ b/drivers/tty/serial/amba-pl011.c
-@@ -2313,7 +2313,12 @@ static int pl011_setup_port(struct devic
- if (IS_ERR(base))
- return PTR_ERR(base);
-
-+ /* Don't use DT serial<n> 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;
--- /dev/null
+From c866120163103778042130f37cc436e1512030ce Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 15 Dec 2015 15:35:57 -0800
+Subject: [PATCH 154/304] 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 <eric@anholt.net>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Michael Turquette <mturquette@baylibre.com>
+---
+ .../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
+
+--- /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>;
++ };
+--- /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
--- /dev/null
+From 7da110b37747778f802371f41cd1eabc0859354e Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 15 Dec 2015 15:35:58 -0800
+Subject: [PATCH 155/304] 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 <eric@anholt.net>
+Signed-off-by: Michael Turquette <mturquette@baylibre.com>
+
+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
+
+--- a/drivers/clk/bcm/Makefile
++++ b/drivers/clk/bcm/Makefile
+@@ -4,6 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281
+ 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
+--- /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 <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clk/bcm2835.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <dt-bindings/clock/bcm2835-aux.h>
++
++#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 <eric@anholt.net>");
++MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver");
++MODULE_LICENSE("GPL v2");
+++ /dev/null
-From 0316ebbf545738333e188197d196b618c17b171e Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Tue, 15 Dec 2015 15:35:57 -0800
-Subject: [PATCH 155/232] 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 <eric@anholt.net>
-Acked-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Michael Turquette <mturquette@baylibre.com>
----
- .../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
-
---- /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>;
-+ };
---- /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
--- /dev/null
+From b2c4fc29ec059ff82f6f82a2192146aff696a8ef Mon Sep 17 00:00:00 2001
+From: Fraser <github@frasersdev.net>
+Date: Tue, 23 Feb 2016 10:04:37 +1100
+Subject: [PATCH 156/304] 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
+
+--- a/arch/arm/boot/dts/bcm2708_common.dtsi
++++ b/arch/arm/boot/dts/bcm2708_common.dtsi
+@@ -1,3 +1,4 @@
++#include <dt-bindings/clock/bcm2835-aux.h>
+ #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";
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -57,6 +57,12 @@ dtb-$(RPI_DT_OVERLAYS) += sdtweak-overla
+ 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -713,6 +713,105 @@ Load: dtoverlay=spi-gpio35-39
+ Params: <None>
+
+
++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,<param>=<val>
++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,<param>=<val>
++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,<param>=<val>
++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,<param>=<val>
++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,<param>=<val>
++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,<param>=<val>
++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
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+--- 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
+--- 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
+--- a/drivers/clk/bcm/Makefile
++++ b/drivers/clk/bcm/Makefile
+@@ -4,7 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281
+ 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
+--- 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.
+++ /dev/null
-From cfe1737d9aab03ecd152291df704606a7724eb21 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Tue, 15 Dec 2015 15:35:58 -0800
-Subject: [PATCH 156/232] 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 <eric@anholt.net>
-Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-
-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
-
---- a/drivers/clk/bcm/Makefile
-+++ b/drivers/clk/bcm/Makefile
-@@ -4,6 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281
- 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
---- /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 <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clk/bcm2835.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <dt-bindings/clock/bcm2835-aux.h>
-+
-+#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 <eric@anholt.net>");
-+MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver");
-+MODULE_LICENSE("GPL v2");
--- /dev/null
+From 3231b20a0e3b20458c443a0ab91045869cbea06a Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Tue, 23 Feb 2016 17:28:23 +0100
+Subject: [PATCH 157/304] 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 <hias@horus.com>
+---
+ 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(+)
+
+--- 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_h
+
+ 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),
+ };
+--- 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_h
+ /* 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),
+ };
+--- 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_h
+ /* 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),
+ };
+--- 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_h
+ /* 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),
+ };
+--- 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_i
+ /* 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),
+ };
+--- a/sound/soc/bcm/raspidac3.c
++++ b/sound/soc/bcm/raspidac3.c
+@@ -128,6 +128,7 @@ static struct snd_soc_dai_link snd_rpi_r
+ /* 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),
+ };
+--- 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_r
+ /* 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),
+ };
+--- 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_p
+ /* 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),
+ };
+++ /dev/null
-From 2cf8e02af4645b90aa63f8cdbd0cb4403e2bee8f Mon Sep 17 00:00:00 2001
-From: Fraser <github@frasersdev.net>
-Date: Tue, 23 Feb 2016 10:04:37 +1100
-Subject: [PATCH 157/232] 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
-
---- a/arch/arm/boot/dts/bcm2708_common.dtsi
-+++ b/arch/arm/boot/dts/bcm2708_common.dtsi
-@@ -1,3 +1,4 @@
-+#include <dt-bindings/clock/bcm2835-aux.h>
- #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";
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -57,6 +57,12 @@ dtb-$(RPI_DT_OVERLAYS) += sdtweak-overla
- 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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -713,6 +713,105 @@ Load: dtoverlay=spi-gpio35-39
- Params: <None>
-
-
-+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,<param>=<val>
-+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,<param>=<val>
-+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,<param>=<val>
-+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,<param>=<val>
-+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,<param>=<val>
-+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,<param>=<val>
-+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
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
---- 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
---- 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
---- a/drivers/clk/bcm/Makefile
-+++ b/drivers/clk/bcm/Makefile
-@@ -4,7 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281
- 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
---- 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.
+++ /dev/null
-From 29c79ce79c70db703a4621ecc7d24208ca991981 Mon Sep 17 00:00:00 2001
-From: Matthias Reichl <hias@horus.com>
-Date: Tue, 23 Feb 2016 17:28:23 +0100
-Subject: [PATCH 158/232] 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 <hias@horus.com>
----
- 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(+)
-
---- 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_h
-
- 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),
- };
---- 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_h
- /* 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),
- };
---- 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_h
- /* 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),
- };
---- 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_h
- /* 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),
- };
---- 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_i
- /* 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),
- };
---- a/sound/soc/bcm/raspidac3.c
-+++ b/sound/soc/bcm/raspidac3.c
-@@ -128,6 +128,7 @@ static struct snd_soc_dai_link snd_rpi_r
- /* 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),
- };
---- 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_r
- /* 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),
- };
---- 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_p
- /* 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),
- };
--- /dev/null
+From 6c5578bc1a55f862aaac3ad6e1826a0de32f4734 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 20 Jan 2016 17:50:09 +0000
+Subject: [PATCH 158/304] 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
+
+--- 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 usbn
+ 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 usbn
+ 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);
+ }
--- /dev/null
+From 46aa468ca952060fd0f45e7da5b79f656b9d1dc0 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 23 Feb 2016 19:56:04 +0000
+Subject: [PATCH 159/304] 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(+)
+ create mode 100644 drivers/gpio/gpio-bcm-virt.c
+
+--- 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
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -132,6 +132,12 @@ config GPIO_BCM_KONA
+ help
+ Turn on GPIO support for Broadcom "Kona" chips.
+
++config GPIO_BCM_VIRT
++ bool "Broadcom Virt GPIO"
++ depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST)
++ help
++ Turn on virtual GPIO support for Broadcom BCM283X chips.
++
+ config GPIO_BRCMSTB
+ tristate "BRCMSTB GPIO support"
+ default y if ARCH_BRCMSTB
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
+ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
+ obj-$(CONFIG_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
+ obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
+ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
+--- /dev/null
++++ b/drivers/gpio/gpio-bcm-virt.c
+@@ -0,0 +1,180 @@
++/*
++ * brcmvirt GPIO driver
++ *
++ * Copyright (C) 2012,2013 Dom Cobley <popcornmix@gmail.com>
++ * Based on gpio-clps711x.c by Alexander Shiyan <shc_work@mail.ru>
++ *
++ * 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 <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/module.h>
++#include <linux/basic_mmio_gpio.h>
++#include <linux/platform_device.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++#define MODULE_NAME "brcmvirt-gpio"
++#define NUM_GPIO 2
++
++struct brcmvirt_gpio {
++ struct gpio_chip gc;
++ u32 __iomem *ts_base;
++ /* two packed 16-bit counts of enabled and disables
++ Allows host to detect a brief enable that was missed */
++ u32 enables_disables[NUM_GPIO];
++};
++
++static int brcmvirt_gpio_dir_in(struct gpio_chip *gc, unsigned off)
++{
++ struct brcmvirt_gpio *gpio;
++ gpio = container_of(gc, struct brcmvirt_gpio, gc);
++ return -EINVAL;
++}
++
++static int brcmvirt_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val)
++{
++ struct brcmvirt_gpio *gpio;
++ gpio = container_of(gc, struct brcmvirt_gpio, gc);
++ return 0;
++}
++
++static int brcmvirt_gpio_get(struct gpio_chip *gc, unsigned off)
++{
++ struct brcmvirt_gpio *gpio;
++ unsigned v;
++ gpio = container_of(gc, struct brcmvirt_gpio, gc);
++ v = readl(gpio->ts_base + off);
++ return (v >> off) & 1;
++}
++
++static void brcmvirt_gpio_set(struct gpio_chip *gc, unsigned off, int val)
++{
++ struct brcmvirt_gpio *gpio;
++ u16 enables, disables;
++ s16 diff;
++ bool lit;
++ gpio = container_of(gc, struct brcmvirt_gpio, gc);
++ enables = gpio->enables_disables[off] >> 16;
++ disables = gpio->enables_disables[off] >> 0;
++ diff = (s16)(enables - disables);
++ lit = diff > 0;
++ if ((val && lit) || (!val && !lit))
++ return;
++ if (val)
++ enables++;
++ else
++ disables++;
++ diff = (s16)(enables - disables);
++ BUG_ON(diff != 0 && diff != 1);
++ gpio->enables_disables[off] = (enables << 16) | (disables << 0);
++ writel(gpio->enables_disables[off], gpio->ts_base + off);
++}
++
++static int brcmvirt_gpio_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct device_node *fw_node;
++ struct rpi_firmware *fw;
++ struct brcmvirt_gpio *ucb;
++ u32 gpiovirtbuf;
++ int err = 0;
++
++ fw_node = of_parse_phandle(np, "firmware", 0);
++ if (!fw_node) {
++ dev_err(dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ fw = rpi_firmware_get(fw_node);
++ if (!fw)
++ return -EPROBE_DEFER;
++
++ err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF,
++ &gpiovirtbuf, sizeof(gpiovirtbuf));
++
++ if (err) {
++ dev_err(dev, "Failed to get gpiovirtbuf\n");
++ goto err;
++ }
++
++ if (!gpiovirtbuf) {
++ dev_err(dev, "No virtgpio buffer\n");
++ err = -ENOENT;
++ goto err;
++ }
++
++ ucb = devm_kzalloc(dev, sizeof *ucb, GFP_KERNEL);
++ if (!ucb) {
++ err = -EINVAL;
++ goto err;
++ }
++
++ // mmap the physical memory
++ gpiovirtbuf &= ~0xc0000000;
++ ucb->ts_base = ioremap(gpiovirtbuf, 4096);
++ if (ucb->ts_base == NULL) {
++ dev_err(dev, "Failed to map physical address\n");
++ err = -ENOENT;
++ goto err;
++ }
++
++ ucb->gc.label = MODULE_NAME;
++ ucb->gc.owner = THIS_MODULE;
++ ucb->gc.dev = dev;
++ ucb->gc.of_node = np;
++ ucb->gc.base = 100;
++ ucb->gc.ngpio = NUM_GPIO;
++
++ ucb->gc.direction_input = brcmvirt_gpio_dir_in;
++ ucb->gc.direction_output = brcmvirt_gpio_dir_out;
++ ucb->gc.get = brcmvirt_gpio_get;
++ ucb->gc.set = brcmvirt_gpio_set;
++ ucb->gc.can_sleep = true;
++
++ err = gpiochip_add(&ucb->gc);
++ if (err)
++ goto err;
++
++ platform_set_drvdata(pdev, ucb);
++
++err:
++ return err;
++
++}
++
++static int brcmvirt_gpio_remove(struct platform_device *pdev)
++{
++ int err = 0;
++ struct brcmvirt_gpio *ucb = platform_get_drvdata(pdev);
++
++ gpiochip_remove(&ucb->gc);
++ iounmap(ucb->ts_base);
++ return err;
++}
++
++static const struct of_device_id __maybe_unused brcmvirt_gpio_ids[] = {
++ { .compatible = "brcm,bcm2835-virtgpio" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, brcmvirt_gpio_ids);
++
++static struct platform_driver brcmvirt_gpio_driver = {
++ .driver = {
++ .name = MODULE_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(brcmvirt_gpio_ids),
++ },
++ .probe = brcmvirt_gpio_probe,
++ .remove = brcmvirt_gpio_remove,
++};
++module_platform_driver(brcmvirt_gpio_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Dom Cobley <popcornmix@gmail.com>");
++MODULE_DESCRIPTION("brcmvirt GPIO driver");
++MODULE_ALIAS("platform:brcmvirt-gpio");
+--- 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,
+++ /dev/null
-From edd0a6e9b22c8edad94b9e8a6ca370912fbeb642 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Wed, 20 Jan 2016 17:50:09 +0000
-Subject: [PATCH 159/232] 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
-
---- 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 usbn
- 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 usbn
- 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);
- }
--- /dev/null
+From 043927e5556d65b6e40d21a0b53bca06aa9b2d43 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 21 Jan 2016 17:57:49 +0000
+Subject: [PATCH 160/304] BCM270X_DT: Add Pi3 support
+
+---
+ 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
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rp
+ 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)
+--- /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";
++ };
++};
+--- /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>;
++};
+++ /dev/null
-From e1024a4269e314d45522f24b0ac86c77675e7909 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 23 Feb 2016 19:56:04 +0000
-Subject: [PATCH 160/232] 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(+)
- create mode 100644 drivers/gpio/gpio-bcm-virt.c
-
---- 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
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -132,6 +132,12 @@ config GPIO_BCM_KONA
- help
- Turn on GPIO support for Broadcom "Kona" chips.
-
-+config GPIO_BCM_VIRT
-+ bool "Broadcom Virt GPIO"
-+ depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST)
-+ help
-+ Turn on virtual GPIO support for Broadcom BCM283X chips.
-+
- config GPIO_BRCMSTB
- tristate "BRCMSTB GPIO support"
- default y if ARCH_BRCMSTB
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
- obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
- obj-$(CONFIG_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
- obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
- obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
---- /dev/null
-+++ b/drivers/gpio/gpio-bcm-virt.c
-@@ -0,0 +1,180 @@
-+/*
-+ * brcmvirt GPIO driver
-+ *
-+ * Copyright (C) 2012,2013 Dom Cobley <popcornmix@gmail.com>
-+ * Based on gpio-clps711x.c by Alexander Shiyan <shc_work@mail.ru>
-+ *
-+ * 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 <linux/err.h>
-+#include <linux/gpio.h>
-+#include <linux/module.h>
-+#include <linux/basic_mmio_gpio.h>
-+#include <linux/platform_device.h>
-+#include <soc/bcm2835/raspberrypi-firmware.h>
-+
-+#define MODULE_NAME "brcmvirt-gpio"
-+#define NUM_GPIO 2
-+
-+struct brcmvirt_gpio {
-+ struct gpio_chip gc;
-+ u32 __iomem *ts_base;
-+ /* two packed 16-bit counts of enabled and disables
-+ Allows host to detect a brief enable that was missed */
-+ u32 enables_disables[NUM_GPIO];
-+};
-+
-+static int brcmvirt_gpio_dir_in(struct gpio_chip *gc, unsigned off)
-+{
-+ struct brcmvirt_gpio *gpio;
-+ gpio = container_of(gc, struct brcmvirt_gpio, gc);
-+ return -EINVAL;
-+}
-+
-+static int brcmvirt_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val)
-+{
-+ struct brcmvirt_gpio *gpio;
-+ gpio = container_of(gc, struct brcmvirt_gpio, gc);
-+ return 0;
-+}
-+
-+static int brcmvirt_gpio_get(struct gpio_chip *gc, unsigned off)
-+{
-+ struct brcmvirt_gpio *gpio;
-+ unsigned v;
-+ gpio = container_of(gc, struct brcmvirt_gpio, gc);
-+ v = readl(gpio->ts_base + off);
-+ return (v >> off) & 1;
-+}
-+
-+static void brcmvirt_gpio_set(struct gpio_chip *gc, unsigned off, int val)
-+{
-+ struct brcmvirt_gpio *gpio;
-+ u16 enables, disables;
-+ s16 diff;
-+ bool lit;
-+ gpio = container_of(gc, struct brcmvirt_gpio, gc);
-+ enables = gpio->enables_disables[off] >> 16;
-+ disables = gpio->enables_disables[off] >> 0;
-+ diff = (s16)(enables - disables);
-+ lit = diff > 0;
-+ if ((val && lit) || (!val && !lit))
-+ return;
-+ if (val)
-+ enables++;
-+ else
-+ disables++;
-+ diff = (s16)(enables - disables);
-+ BUG_ON(diff != 0 && diff != 1);
-+ gpio->enables_disables[off] = (enables << 16) | (disables << 0);
-+ writel(gpio->enables_disables[off], gpio->ts_base + off);
-+}
-+
-+static int brcmvirt_gpio_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct device_node *fw_node;
-+ struct rpi_firmware *fw;
-+ struct brcmvirt_gpio *ucb;
-+ u32 gpiovirtbuf;
-+ int err = 0;
-+
-+ fw_node = of_parse_phandle(np, "firmware", 0);
-+ if (!fw_node) {
-+ dev_err(dev, "Missing firmware node\n");
-+ return -ENOENT;
-+ }
-+
-+ fw = rpi_firmware_get(fw_node);
-+ if (!fw)
-+ return -EPROBE_DEFER;
-+
-+ err = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF,
-+ &gpiovirtbuf, sizeof(gpiovirtbuf));
-+
-+ if (err) {
-+ dev_err(dev, "Failed to get gpiovirtbuf\n");
-+ goto err;
-+ }
-+
-+ if (!gpiovirtbuf) {
-+ dev_err(dev, "No virtgpio buffer\n");
-+ err = -ENOENT;
-+ goto err;
-+ }
-+
-+ ucb = devm_kzalloc(dev, sizeof *ucb, GFP_KERNEL);
-+ if (!ucb) {
-+ err = -EINVAL;
-+ goto err;
-+ }
-+
-+ // mmap the physical memory
-+ gpiovirtbuf &= ~0xc0000000;
-+ ucb->ts_base = ioremap(gpiovirtbuf, 4096);
-+ if (ucb->ts_base == NULL) {
-+ dev_err(dev, "Failed to map physical address\n");
-+ err = -ENOENT;
-+ goto err;
-+ }
-+
-+ ucb->gc.label = MODULE_NAME;
-+ ucb->gc.owner = THIS_MODULE;
-+ ucb->gc.dev = dev;
-+ ucb->gc.of_node = np;
-+ ucb->gc.base = 100;
-+ ucb->gc.ngpio = NUM_GPIO;
-+
-+ ucb->gc.direction_input = brcmvirt_gpio_dir_in;
-+ ucb->gc.direction_output = brcmvirt_gpio_dir_out;
-+ ucb->gc.get = brcmvirt_gpio_get;
-+ ucb->gc.set = brcmvirt_gpio_set;
-+ ucb->gc.can_sleep = true;
-+
-+ err = gpiochip_add(&ucb->gc);
-+ if (err)
-+ goto err;
-+
-+ platform_set_drvdata(pdev, ucb);
-+
-+err:
-+ return err;
-+
-+}
-+
-+static int brcmvirt_gpio_remove(struct platform_device *pdev)
-+{
-+ int err = 0;
-+ struct brcmvirt_gpio *ucb = platform_get_drvdata(pdev);
-+
-+ gpiochip_remove(&ucb->gc);
-+ iounmap(ucb->ts_base);
-+ return err;
-+}
-+
-+static const struct of_device_id __maybe_unused brcmvirt_gpio_ids[] = {
-+ { .compatible = "brcm,bcm2835-virtgpio" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, brcmvirt_gpio_ids);
-+
-+static struct platform_driver brcmvirt_gpio_driver = {
-+ .driver = {
-+ .name = MODULE_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(brcmvirt_gpio_ids),
-+ },
-+ .probe = brcmvirt_gpio_probe,
-+ .remove = brcmvirt_gpio_remove,
-+};
-+module_platform_driver(brcmvirt_gpio_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Dom Cobley <popcornmix@gmail.com>");
-+MODULE_DESCRIPTION("brcmvirt GPIO driver");
-+MODULE_ALIAS("platform:brcmvirt-gpio");
---- 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,
+++ /dev/null
-From 4aa902b37606ca425a2d1dedd400347b11a0e61d Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 21 Jan 2016 17:57:49 +0000
-Subject: [PATCH 161/232] BCM270X_DT: Add Pi3 support
-
----
- 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
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_BCM2708) += bcm2708-rp
- 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)
---- /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";
-+ };
-+};
---- /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>;
-+};
--- /dev/null
+From 2d787b8c422a777f688b185420268dc618d995e4 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 161/304] 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
+
+--- 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-$(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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -371,6 +371,22 @@ Params: ds1307 Select t
+ pcf8563 Select the PCF8563 device
+
+
++Name: i2c0-bcm2708
++Info: Enable the i2c_bcm2708 driver for the i2c0 bus
++Load: dtoverlay=i2c0-bcm2708,<param>=<val>
++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,<param>=<val>
++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
+--- /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";
++ };
++};
+--- /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";
++ };
++};
+++ /dev/null
-From 6014b99c7f39813c76b51e940677219c7dd41041 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 162/232] 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
-
---- 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-$(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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -371,6 +371,22 @@ Params: ds1307 Select t
- pcf8563 Select the PCF8563 device
-
-
-+Name: i2c0-bcm2708
-+Info: Enable the i2c_bcm2708 driver for the i2c0 bus
-+Load: dtoverlay=i2c0-bcm2708,<param>=<val>
-+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,<param>=<val>
-+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
---- /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";
-+ };
-+};
---- /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";
-+ };
-+};
--- /dev/null
+From 52697652d41b7947e2ed1c45a954f426a4135441 Mon Sep 17 00:00:00 2001
+From: Dhiraj Goel <dhiraj.goel@gmail.com>
+Date: Thu, 3 Mar 2016 21:10:50 -0800
+Subject: [PATCH 162/304] 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(-)
+
+--- 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_
+ 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;
+
--- /dev/null
+From 235eb2e7b520269614b4a91d15d22eef7923a4fb Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 2 Mar 2016 10:59:05 +0000
+Subject: [PATCH 163/304] BCM270X_DT: Add pi3-disable-bt overlay
+
+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 <phil@raspberrypi.org>
+---
+ 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
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-o
+ 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -496,6 +496,14 @@ Params: speed Display
+ [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ]
+
+
++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: <None>
++
++
+ Name: piscreen
+ Info: PiScreen display by OzzMaker.com
+ Load: dtoverlay=piscreen,<param>=<val>
+--- /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";
++ };
++ };
++};
+++ /dev/null
-From f22f155684481bb96748677bc58705d27bf4f06b Mon Sep 17 00:00:00 2001
-From: Dhiraj Goel <dhiraj.goel@gmail.com>
-Date: Thu, 3 Mar 2016 21:10:50 -0800
-Subject: [PATCH 163/232] 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(-)
-
---- 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_
- 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;
-
+++ /dev/null
-From 1807dd78b1af8eff8976f3431e4bf98dccd2113d Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 2 Mar 2016 10:59:05 +0000
-Subject: [PATCH 164/232] BCM270X_DT: Add pi3-disable-bt overlay
-
-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 <phil@raspberrypi.org>
----
- 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
-
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -39,6 +39,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-o
- 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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -496,6 +496,14 @@ Params: speed Display
- [ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ]
-
-
-+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: <None>
-+
-+
- Name: piscreen
- Info: PiScreen display by OzzMaker.com
- Load: dtoverlay=piscreen,<param>=<val>
---- /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";
-+ };
-+ };
-+};
--- /dev/null
+From fd6395774b0b0adfafcb3ef11c5055f85e8896dd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 7 Mar 2016 09:53:03 +0000
+Subject: [PATCH 164/304] BCM270X_DT: Add pi3-miniuart-bt DT overlay
+
+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.server and
+replace ttyAMA0 with ttyS0.
+
+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.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -40,6 +40,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-o
+ 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -504,6 +504,16 @@ Load: dtoverlay=pi3-disable-bt
+ Params: <None>
+
+
++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: <None>
++
++
+ Name: piscreen
+ Info: PiScreen display by OzzMaker.com
+ Load: dtoverlay=piscreen,<param>=<val>
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts
+@@ -0,0 +1,61 @@
++/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.server and
++ replace ttyAMA0 with ttyS0.
++
++ 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>;
++ 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";
++ };
++ };
++};
+++ /dev/null
-From 4adf0d94785a304b51f8205ecade7bc97b26a00b Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 7 Mar 2016 09:53:03 +0000
-Subject: [PATCH 165/232] BCM270X_DT: Add pi3-miniuart-bt DT overlay
-
-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.server and
-replace ttyAMA0 with ttyS0.
-
-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.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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
-
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -40,6 +40,7 @@ dtb-$(RPI_DT_OVERLAYS) += mcp2515-can1-o
- 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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -504,6 +504,16 @@ Load: dtoverlay=pi3-disable-bt
- Params: <None>
-
-
-+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: <None>
-+
-+
- Name: piscreen
- Info: PiScreen display by OzzMaker.com
- Load: dtoverlay=piscreen,<param>=<val>
---- /dev/null
-+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts
-@@ -0,0 +1,61 @@
-+/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.server and
-+ replace ttyAMA0 with ttyS0.
-+
-+ 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>;
-+ 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";
-+ };
-+ };
-+};
--- /dev/null
+From 3d4b13cc4a0dbea19ba73d9a0c7e785e1d963d55 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 7 Mar 2016 13:38:39 +0000
+Subject: [PATCH 165/304] 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 <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- 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";
+ };
+ };
+++ /dev/null
-From 2efc547c5e535a2061312e63a459cdee9635cdf9 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 7 Mar 2016 13:38:39 +0000
-Subject: [PATCH 166/232] 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 <phil@raspberrypi.org>
----
- arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- 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";
- };
- };
--- /dev/null
+From 9a9ac626fd93632c3bacf9f61b758262d98a260c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 7 Mar 2016 15:05:11 +0000
+Subject: [PATCH 166/304] vchiq_arm: Tweak the logging output
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++-------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+--- 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, VCHI
+ 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++;
+
+@@ -1039,16 +1037,13 @@ queue_message_sync(VCHIQ_STATE_T *state,
+ 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 {
+@@ -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) {
--- /dev/null
+From d6b47c6dc22a1fbe2fcb5c742936a32baad60409 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 7 Mar 2016 16:46:39 +0000
+Subject: [PATCH 167/304] 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 <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2708_common.dtsi | 5 +--
+ drivers/mmc/host/bcm2835-sdhost.c | 70 ++++++++++++++++++++++++-----------
+ 2 files changed, 50 insertions(+), 25 deletions(-)
+
+--- 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";
+--- 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(s
+ 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;
+ }
+@@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(s
+ 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);
+
+@@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm28
+ 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->use_dma = false;
+ } else {
+- host->use_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->use_dma = false;
+@@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct p
+
+ 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);
+ }
+ }
+++ /dev/null
-From 68c89607e3451adc83a158e99a582be85f047465 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 7 Mar 2016 15:05:11 +0000
-Subject: [PATCH 167/232] vchiq_arm: Tweak the logging output
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++-------------
- 1 file changed, 13 insertions(+), 18 deletions(-)
-
---- 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, VCHI
- 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++;
-
-@@ -1039,16 +1037,13 @@ queue_message_sync(VCHIQ_STATE_T *state,
- 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 {
-@@ -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) {
--- /dev/null
+From ade651419c0a60756b12bde37270de3aaede1545 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 8 Mar 2016 09:49:16 +0000
+Subject: [PATCH 168/304] 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 <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2708_common.dtsi | 5 +--
+ drivers/mmc/host/bcm2835-mmc.c | 69 +++++++++++++++++++++++++----------
+ 2 files changed, 51 insertions(+), 23 deletions(-)
+
+--- 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";
+ };
+--- a/drivers/mmc/host/bcm2835-mmc.c
++++ b/drivers/mmc/host/bcm2835-mmc.c
+@@ -108,8 +108,9 @@ struct bcm2835_host {
+ 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;
+@@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(voi
+
+ 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(str
+ 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
+ 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 b
+ 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 plat
+
+ #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);
+++ /dev/null
-From 1131510a589ae7262b8861af8d2f4a000710d59c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 7 Mar 2016 16:46:39 +0000
-Subject: [PATCH 168/232] 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 <phil@raspberrypi.org>
----
- arch/arm/boot/dts/bcm2708_common.dtsi | 5 +--
- drivers/mmc/host/bcm2835-sdhost.c | 70 ++++++++++++++++++++++++-----------
- 2 files changed, 50 insertions(+), 25 deletions(-)
-
---- 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";
---- 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(s
- 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;
- }
-@@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(s
- 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);
-
-@@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm28
- 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->use_dma = false;
- } else {
-- host->use_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->use_dma = false;
-@@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct p
-
- 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);
- }
- }
+++ /dev/null
-From ea4b1c5c2ddbb6caba43ab9b0103542a4ca7e1f0 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 8 Mar 2016 09:49:16 +0000
-Subject: [PATCH 169/232] 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 <phil@raspberrypi.org>
----
- arch/arm/boot/dts/bcm2708_common.dtsi | 5 +--
- drivers/mmc/host/bcm2835-mmc.c | 69 +++++++++++++++++++++++++----------
- 2 files changed, 51 insertions(+), 23 deletions(-)
-
---- 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";
- };
---- a/drivers/mmc/host/bcm2835-mmc.c
-+++ b/drivers/mmc/host/bcm2835-mmc.c
-@@ -108,8 +108,9 @@ struct bcm2835_host {
- 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;
-@@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(voi
-
- 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(str
- 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
- 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 b
- 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 plat
-
- #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);
--- /dev/null
+From 1054095c79084b44a5245ff2d8fc38aa82d1afd8 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 8 Mar 2016 17:08:39 +0000
+Subject: [PATCH 169/304] config: rebuild with savedefconfig
+
+---
+ arch/arm/configs/bcm2709_defconfig | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- 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
--- /dev/null
+From c7834c34977089c45c3614ce531142258f088eee Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 8 Mar 2016 17:06:33 +0000
+Subject: [PATCH 170/304] config: Add module for mcp3422 ADC
+
+---
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- 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
+--- 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
+++ /dev/null
-From 83428789f8b11c2caf2b85998db0f0874cd3e896 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 8 Mar 2016 17:08:39 +0000
-Subject: [PATCH 170/232] config: rebuild with savedefconfig
-
----
- arch/arm/configs/bcm2709_defconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- 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
--- /dev/null
+From 9a54d9b11416f92d09656f342d3d7ae495876dcd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 8 Mar 2016 16:18:57 +0000
+Subject: [PATCH 171/304] Pi3 DT: Add pull-ups on the UART RX lines
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(-)
+
+--- 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>;
+ };
+
+ uart1_pins: uart1_pins {
+ brcm,pins = <14 15>;
+ brcm,function = <2>; /* alt5=UART1 */
+- brcm,pull = <0 0>;
++ brcm,pull = <0 2>;
+ };
+ };
+
+--- 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>;
+ };
+ };
+ };
+++ /dev/null
-From b704288cc9104b018bebf77528f9ff74b6c355a4 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 8 Mar 2016 17:06:33 +0000
-Subject: [PATCH 171/232] config: Add module for mcp3422 ADC
-
----
- arch/arm/configs/bcm2709_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 1 +
- 2 files changed, 2 insertions(+)
-
---- 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
---- 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
+++ /dev/null
-From a25355e1fe4284b87170bec5d2ee77f90a62602c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 8 Mar 2016 16:18:57 +0000
-Subject: [PATCH 172/232] Pi3 DT: Add pull-ups on the UART RX lines
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(-)
-
---- 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>;
- };
-
- uart1_pins: uart1_pins {
- brcm,pins = <14 15>;
- brcm,function = <2>; /* alt5=UART1 */
-- brcm,pull = <0 0>;
-+ brcm,pull = <0 2>;
- };
- };
-
---- 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>;
- };
- };
- };
--- /dev/null
+From 67c1b07aca518f756140a682d0e6fe383e293515 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 9 Mar 2016 21:28:52 +0000
+Subject: [PATCH 173/304] BCM270X_DT: rpi-display overlay - add swapxy param
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/overlays/README | 5 +----
+ arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 1 +
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- 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,<param>=<val>
+ 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
+--- 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?";
+ };
+ };
+++ /dev/null
-From 209d0307ba01e0f15f5e75bc77d8edaa51aa91ab Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 9 Mar 2016 21:28:52 +0000
-Subject: [PATCH 174/232] BCM270X_DT: rpi-display overlay - add swapxy param
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- arch/arm/boot/dts/overlays/README | 5 +----
- arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 1 +
- 2 files changed, 2 insertions(+), 4 deletions(-)
-
---- 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,<param>=<val>
- 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
---- 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?";
- };
- };
--- /dev/null
+From db1f9419a8d30e9a861ac63889f0b7845c3310f1 Mon Sep 17 00:00:00 2001
+From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
+Date: Fri, 11 Mar 2016 11:44:35 +0000
+Subject: [PATCH 174/304] 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(-)
+
+--- 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 {
+--- 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";
+ };
+ };
+++ /dev/null
-From eb4d55c34018bbb92808264217a0b2857d2b2ae6 Mon Sep 17 00:00:00 2001
-From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
-Date: Fri, 11 Mar 2016 11:44:35 +0000
-Subject: [PATCH 175/232] 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(-)
-
---- 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 {
---- 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";
- };
- };
--- /dev/null
+From de37d281502aff4e4a88872cf0a6ef5e36b7484d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 10 Aug 2015 09:44:59 +0100
+Subject: [PATCH 175/304] 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(-)
+
+--- a/scripts/dtc/checks.c
++++ b/scripts/dtc/checks.c
+@@ -458,91 +458,21 @@ static void fixup_phandle_references(str
+ 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_interr
+ }
+ 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,
+ };
+
+--- a/scripts/dtc/dtc-lexer.l
++++ b/scripts/dtc/dtc-lexer.l
+@@ -113,11 +113,6 @@ static void lexical_error(const char *fm
+ return DT_V1;
+ }
+
+-<*>"/plugin/" {
+- DPRINT("Keyword: /plugin/\n");
+- return DT_PLUGIN;
+- }
+-
+ <*>"/memreserve/" {
+ DPRINT("Keyword: /memreserve/\n");
+ BEGIN_DEFAULT();
+--- 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
+
+ /* 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_ST
+
+ 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
+ *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("<PROPNODENAME>\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("<PROPNODENAME>\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
+ *
+ * @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"
+
+
+
+--- 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 <http://www.gnu.org/licenses/>. */
+
+@@ -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 <stdio.h>
+-#include <inttypes.h>
+
+ #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 */
+
++/* Copy the second part of user declarations. */
+
+-/* Line 343 of yacc.c */
+-#line 198 "dtc-parser.tab.c"
++#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 <stddef.h> /* INFRINGES ON USER NAME SPACE */
+ # define YYSIZE_T size_t
+ # else
+@@ -247,39 +241,68 @@ typedef short int yytype_int16;
+ # if defined YYENABLE_NLS && YYENABLE_NLS
+ # if ENABLE_NLS
+ # include <libintl.h> /* 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
+
+ /* The parser invokes alloca or malloc; define the necessary symbols. */
+@@ -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 <stdlib.h> /* 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 <stdlib.h> /* 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
+
+ #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 YYRECOVERING() (!!yyerrstatus)
++#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 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 (YYID (0))
+
++#define YYRECOVERING() (!!yyerrstatus)
+
+-#define YYTERROR 1
+-#define YYERRCODE 256
++#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 (0)
++
++/* 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 <stdio.h> /* 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 <stdio.h> /* 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. |
+-`--------------------------------*/
+
+-/*ARGSUSED*/
+-#if (defined __STDC__ || defined __C99__FUNC__ \
+- || defined __cplusplus || defined _MSC_VER)
++/*----------------------------------------.
++| Print this symbol's value on YYOUTPUT. |
++`----------------------------------------*/
++
+ 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,
+ | 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, yyval
+ | 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 *yyst
+ 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, c
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+- - Assume YYFAIL is not used. It's too flawed to consider. See
+- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+- 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, c
+ 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, c
+ # 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, c
+ | 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"
+- {
+- (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"
++#line 235 "dtc-parser.y" /* yacc.c:1646 */
+ {
+- 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);
+ }
+-
+--- 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 <http://www.gnu.org/licenses/>. */
+
+@@ -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 */
+--- a/scripts/dtc/dtc-parser.y
++++ b/scripts/dtc/dtc-parser.y
+@@ -19,7 +19,6 @@
+ */
+ %{
+ #include <stdio.h>
+-#include <inttypes.h>
+
+ #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 <data> propdata
+ %type <data> propdataprefix
+-%type <is_plugin> plugindecl
+ %type <re> memreserve
+ %type <re> memreserves
+ %type <array> 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));
+ }
+ ;
+
+--- a/scripts/dtc/dtc.c
++++ b/scripts/dtc/dtc.c
+@@ -29,7 +29,6 @@ int reservenum; /* Number of memory res
+ 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 *
+ #define FDT_VERSION(version) _FDT_VERSION(version)
+ #define _FDT_VERSION(version) #version
+ static const char usage_synopsis[] = "dtc [options] <input file>";
+-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_op
+ {"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_hel
+ "\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:
+--- a/scripts/dtc/dtc.h
++++ b/scripts/dtc/dtc.h
+@@ -54,7 +54,6 @@ extern int reservenum; /* Number of mem
+ 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);
+
+--- a/scripts/dtc/flattree.c
++++ b/scripts/dtc/flattree.c
+@@ -262,12 +262,6 @@ static void flatten_tree(struct node *tr
+ 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 *tr
+ 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 *tr
+ 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 :<number> + '\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 :<number> + '\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);
+ }
+
+--- 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"
+++ /dev/null
-From fa95cd11c54c77d6151b7588b1f41457d8775c60 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 10 Aug 2015 09:44:59 +0100
-Subject: [PATCH 176/232] 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(-)
-
---- a/scripts/dtc/checks.c
-+++ b/scripts/dtc/checks.c
-@@ -458,91 +458,21 @@ static void fixup_phandle_references(str
- 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_interr
- }
- 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,
- };
-
---- a/scripts/dtc/dtc-lexer.l
-+++ b/scripts/dtc/dtc-lexer.l
-@@ -113,11 +113,6 @@ static void lexical_error(const char *fm
- return DT_V1;
- }
-
--<*>"/plugin/" {
-- DPRINT("Keyword: /plugin/\n");
-- return DT_PLUGIN;
-- }
--
- <*>"/memreserve/" {
- DPRINT("Keyword: /memreserve/\n");
- BEGIN_DEFAULT();
---- 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
-
- /* 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_ST
-
- 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
- *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("<PROPNODENAME>\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("<PROPNODENAME>\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
- *
- * @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"
-
-
-
---- 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 <http://www.gnu.org/licenses/>. */
-
-@@ -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 <stdio.h>
--#include <inttypes.h>
-
- #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 */
-
-+/* Copy the second part of user declarations. */
-
--/* Line 343 of yacc.c */
--#line 198 "dtc-parser.tab.c"
-+#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 <stddef.h> /* INFRINGES ON USER NAME SPACE */
- # define YYSIZE_T size_t
- # else
-@@ -247,39 +241,68 @@ typedef short int yytype_int16;
- # if defined YYENABLE_NLS && YYENABLE_NLS
- # if ENABLE_NLS
- # include <libintl.h> /* 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
-
- /* The parser invokes alloca or malloc; define the necessary symbols. */
-@@ -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 <stdlib.h> /* 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 <stdlib.h> /* 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
-
- #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 YYRECOVERING() (!!yyerrstatus)
-+#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 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 (YYID (0))
-
-+#define YYRECOVERING() (!!yyerrstatus)
-
--#define YYTERROR 1
--#define YYERRCODE 256
-+#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 (0)
-+
-+/* 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 <stdio.h> /* 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 <stdio.h> /* 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. |
--`--------------------------------*/
-
--/*ARGSUSED*/
--#if (defined __STDC__ || defined __C99__FUNC__ \
-- || defined __cplusplus || defined _MSC_VER)
-+/*----------------------------------------.
-+| Print this symbol's value on YYOUTPUT. |
-+`----------------------------------------*/
-+
- 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,
- | 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, yyval
- | 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 *yyst
- 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, c
- int yycount = 0;
-
- /* There are many possibilities here to consider:
-- - Assume YYFAIL is not used. It's too flawed to consider. See
-- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-- 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, c
- 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, c
- # 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, c
- | 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"
-- {
-- (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"
-+#line 235 "dtc-parser.y" /* yacc.c:1646 */
- {
-- 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);
- }
--
---- 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 <http://www.gnu.org/licenses/>. */
-
-@@ -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 */
---- a/scripts/dtc/dtc-parser.y
-+++ b/scripts/dtc/dtc-parser.y
-@@ -19,7 +19,6 @@
- */
- %{
- #include <stdio.h>
--#include <inttypes.h>
-
- #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 <data> propdata
- %type <data> propdataprefix
--%type <is_plugin> plugindecl
- %type <re> memreserve
- %type <re> memreserves
- %type <array> 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));
- }
- ;
-
---- a/scripts/dtc/dtc.c
-+++ b/scripts/dtc/dtc.c
-@@ -29,7 +29,6 @@ int reservenum; /* Number of memory res
- 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 *
- #define FDT_VERSION(version) _FDT_VERSION(version)
- #define _FDT_VERSION(version) #version
- static const char usage_synopsis[] = "dtc [options] <input file>";
--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_op
- {"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_hel
- "\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:
---- a/scripts/dtc/dtc.h
-+++ b/scripts/dtc/dtc.h
-@@ -54,7 +54,6 @@ extern int reservenum; /* Number of mem
- 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);
-
---- a/scripts/dtc/flattree.c
-+++ b/scripts/dtc/flattree.c
-@@ -262,12 +262,6 @@ static void flatten_tree(struct node *tr
- 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 *tr
- 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 *tr
- 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 :<number> + '\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 :<number> + '\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);
- }
-
---- 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"
--- /dev/null
+From 8560a09e578580fa46d649e5b15a3779968007f6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 10 Aug 2015 09:49:15 +0100
+Subject: [PATCH 176/304] scripts/dtc: Update to upstream version 1.4.1
+
+Includes the new localfixups format.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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-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(-)
+
+--- a/scripts/dtc/checks.c
++++ b/scripts/dtc/checks.c
+@@ -458,6 +458,8 @@ static void fixup_phandle_references(str
+ 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;
+
+@@ -466,11 +468,69 @@ static void fixup_phandle_references(str
+
+ refnode = get_node_by_ref(dt, m->ref);
+ if (! refnode) {
+- FAIL(c, "Reference to non-existent node or label \"%s\"\n",
+- m->ref);
++ if (!dt->is_plugin) {
++ FAIL(c, "Reference to non-existent node or label \"%s\"\n",
++ m->ref);
++ continue;
++ }
++
++ /* 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 */
++ *((cell_t *)(prop->val.val + m->offset)) =
++ cpu_to_fdt32(0xdeadbeef);
+ continue;
+ }
+
++ /* if it's a local reference, we need to record it */
++ if (symbol_fixup_support) {
++
++ /* 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;
++ }
++
+ phandle = get_node_phandle(dt, refnode);
+ *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+ }
+@@ -652,6 +712,45 @@ static void check_obsolete_chosen_interr
+ }
+ 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 +769,8 @@ static struct check *check_table[] = {
+ &avoid_default_addr_size,
+ &obsolete_chosen_interrupt_controller,
+
++ &auto_label_phandles,
++
+ &always_fail,
+ };
+
+--- a/scripts/dtc/dtc-lexer.l
++++ b/scripts/dtc/dtc-lexer.l
+@@ -113,6 +113,11 @@ static void lexical_error(const char *fm
+ return DT_V1;
+ }
+
++<*>"/plugin/" {
++ DPRINT("Keyword: /plugin/\n");
++ return DT_PLUGIN;
++ }
++
+ <*>"/memreserve/" {
+ DPRINT("Keyword: /memreserve/\n");
+ BEGIN_DEFAULT();
+--- 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
+
+ /* 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_ST
+
+ 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
+ *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("<PROPNODENAME>\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("<PROPNODENAME>\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
+ *
+ * @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"
+
+
+
+--- a/scripts/dtc/dtc-parser.tab.c_shipped
++++ b/scripts/dtc/dtc-parser.tab.c_shipped
+@@ -65,6 +65,7 @@
+ #line 20 "dtc-parser.y" /* yacc.c:339 */
+
+ #include <stdio.h>
++#include <inttypes.h>
+
+ #include "dtc.h"
+ #include "srcpos.h"
+@@ -80,7 +81,7 @@ 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 85 "dtc-parser.tab.c" /* yacc.c:339 */
+
+ # ifndef YY_NULLPTR
+ # if defined __cplusplus && 201103L <= __cplusplus
+@@ -116,26 +117,27 @@ extern int yydebug;
+ 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
++ 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
+
+@@ -144,7 +146,7 @@ extern int yydebug;
+ typedef union YYSTYPE YYSTYPE;
+ union YYSTYPE
+ {
+-#line 38 "dtc-parser.y" /* yacc.c:355 */
++#line 39 "dtc-parser.y" /* yacc.c:355 */
+
+ char *propnodename;
+ char *labelref;
+@@ -162,8 +164,9 @@ union YYSTYPE
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
++ bool is_plugin;
+
+-#line 167 "dtc-parser.tab.c" /* yacc.c:355 */
++#line 170 "dtc-parser.tab.c" /* yacc.c:355 */
+ };
+ # define YYSTYPE_IS_TRIVIAL 1
+ # define YYSTYPE_IS_DECLARED 1
+@@ -192,7 +195,7 @@ int yyparse (void);
+
+ /* Copy the second part of user declarations. */
+
+-#line 196 "dtc-parser.tab.c" /* yacc.c:358 */
++#line 199 "dtc-parser.tab.c" /* yacc.c:358 */
+
+ #ifdef short
+ # undef short
+@@ -439,18 +442,18 @@ 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
++#define YYNRULES 82
+ /* YYNSTATES -- Number of states. */
+-#define YYNSTATES 144
++#define YYNSTATES 147
+
+ /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+ #define YYUNDEFTOK 2
+-#define YYMAXUTOK 278
++#define YYMAXUTOK 279
+
+ #define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+@@ -462,16 +465,16 @@ 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,22 +489,22 @@ 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. */
+ 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, 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,
++ 291, 298, 314, 319, 338, 352, 359, 360, 361, 368,
++ 372, 373, 377, 378, 382, 383, 387, 388, 392, 393,
++ 397, 398, 402, 403, 404, 408, 409, 410, 411, 412,
++ 416, 417, 418, 422, 423, 424, 428, 429, 430, 431,
++ 435, 436, 437, 438, 443, 446, 450, 458, 461, 465,
++ 473, 477, 481
+ };
+ #endif
+
+@@ -510,19 +513,19 @@ static const yytype_uint16 yyrline[] =
+ 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", YY_NULLPTR
+ };
+ #endif
+
+@@ -533,16 +536,16 @@ 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_NINF -84
+
+ #define yypact_value_is_default(Yystate) \
+- (!!((Yystate) == (-81)))
++ (!!((Yystate) == (-84)))
+
+ #define YYTABLE_NINF -1
+
+@@ -553,21 +556,21 @@ static const yytype_uint16 yytoknum[] =
+ STATE-NUM. */
+ static const yytype_int8 yypact[] =
+ {
+- 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
++ 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
+ };
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+@@ -575,37 +578,37 @@ static const yytype_int8 yypact[] =
+ means the default is an error. */
+ static const yytype_uint8 yydefact[] =
+ {
+- 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, 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, 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, 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
+ };
+
+ /* YYPGOTO[NTERM-NUM]. */
+ static const yytype_int8 yypgoto[] =
+ {
+- -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
++ -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
+ };
+
+ /* 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
+@@ -613,87 +616,87 @@ static const yytype_int16 yydefgoto[] =
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+ static const yytype_uint8 yytable[] =
+ {
+- 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, 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
+ };
+
+ static const yytype_int16 yycheck[] =
+ {
+- 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
++ 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
+ };
+
+ /* 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
++ 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
+ };
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+ static const yytype_uint8 yyr1[] =
+ {
+- 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
++ 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
+ };
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+ static const yytype_uint8 yyr2[] =
+ {
+- 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, 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
+ };
+
+
+@@ -1463,65 +1466,82 @@ yyreduce:
+ switch (yyn)
+ {
+ case 2:
+-#line 105 "dtc-parser.y" /* yacc.c:1646 */
++#line 109 "dtc-parser.y" /* yacc.c:1646 */
+ {
++ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin);
+ 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 */
++#line 1476 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 3:
+-#line 113 "dtc-parser.y" /* yacc.c:1646 */
++#line 118 "dtc-parser.y" /* yacc.c:1646 */
+ {
+- (yyval.re) = NULL;
++ (yyval.is_plugin) = false;
+ }
+-#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1484 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 4:
+-#line 117 "dtc-parser.y" /* yacc.c:1646 */
++#line 122 "dtc-parser.y" /* yacc.c:1646 */
+ {
+- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
++ (yyval.is_plugin) = true;
+ }
+-#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1492 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 5:
+-#line 124 "dtc-parser.y" /* yacc.c:1646 */
++#line 129 "dtc-parser.y" /* yacc.c:1646 */
+ {
+- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
++ (yyval.re) = NULL;
+ }
+-#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1500 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 6:
+-#line 128 "dtc-parser.y" /* yacc.c:1646 */
++#line 133 "dtc-parser.y" /* yacc.c:1646 */
++ {
++ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
++ }
++#line 1508 "dtc-parser.tab.c" /* yacc.c:1646 */
++ break;
++
++ case 7:
++#line 140 "dtc-parser.y" /* yacc.c:1646 */
++ {
++ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
++ }
++#line 1516 "dtc-parser.tab.c" /* yacc.c:1646 */
++ break;
++
++ case 8:
++#line 144 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
+ (yyval.re) = (yyvsp[0].re);
+ }
+-#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1525 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 7:
+-#line 136 "dtc-parser.y" /* yacc.c:1646 */
++ case 9:
++#line 152 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = name_node((yyvsp[0].node), "");
+ }
+-#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1533 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 8:
+-#line 140 "dtc-parser.y" /* yacc.c:1646 */
++ case 10:
++#line 156 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
+ }
+-#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1541 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 9:
+-#line 145 "dtc-parser.y" /* yacc.c:1646 */
++ case 11:
++#line 161 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
+
+@@ -1532,11 +1552,11 @@ yyreduce:
+ 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 */
++#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 10:
+-#line 156 "dtc-parser.y" /* yacc.c:1646 */
++ case 12:
++#line 172 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
+
+@@ -1546,11 +1566,11 @@ yyreduce:
+ 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 */
++#line 1570 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 11:
+-#line 166 "dtc-parser.y" /* yacc.c:1646 */
++ case 13:
++#line 182 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
+
+@@ -1562,100 +1582,100 @@ yyreduce:
+
+ (yyval.node) = (yyvsp[-3].node);
+ }
+-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1586 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 12:
+-#line 181 "dtc-parser.y" /* yacc.c:1646 */
++ case 14:
++#line 197 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
+ }
+-#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1594 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 13:
+-#line 188 "dtc-parser.y" /* yacc.c:1646 */
++ case 15:
++#line 204 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.proplist) = NULL;
+ }
+-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1602 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 14:
+-#line 192 "dtc-parser.y" /* yacc.c:1646 */
++ case 16:
++#line 208 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
+ }
+-#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1610 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 15:
+-#line 199 "dtc-parser.y" /* yacc.c:1646 */
++ case 17:
++#line 215 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
+ }
+-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1618 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 16:
+-#line 203 "dtc-parser.y" /* yacc.c:1646 */
++ case 18:
++#line 219 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
+ }
+-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1626 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 17:
+-#line 207 "dtc-parser.y" /* yacc.c:1646 */
++ case 19:
++#line 223 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ }
+-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1634 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 18:
+-#line 211 "dtc-parser.y" /* yacc.c:1646 */
++ case 20:
++#line 227 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
+ (yyval.prop) = (yyvsp[0].prop);
+ }
+-#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1643 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 19:
+-#line 219 "dtc-parser.y" /* yacc.c:1646 */
++ case 21:
++#line 235 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
+ }
+-#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1651 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 20:
+-#line 223 "dtc-parser.y" /* yacc.c:1646 */
++ case 22:
++#line 239 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
+ }
+-#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1659 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 21:
+-#line 227 "dtc-parser.y" /* yacc.c:1646 */
++ case 23:
++#line 243 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
+ }
+-#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1667 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 22:
+-#line 231 "dtc-parser.y" /* yacc.c:1646 */
++ case 24:
++#line 247 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
+ }
+-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 23:
+-#line 235 "dtc-parser.y" /* yacc.c:1646 */
++ case 25:
++#line 251 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
+ struct data d;
+@@ -1671,11 +1691,11 @@ yyreduce:
+ (yyval.data) = data_merge((yyvsp[-8].data), d);
+ fclose(f);
+ }
+-#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 24:
+-#line 251 "dtc-parser.y" /* yacc.c:1646 */
++ case 26:
++#line 267 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
+ struct data d = empty_data;
+@@ -1685,43 +1705,43 @@ yyreduce:
+ (yyval.data) = data_merge((yyvsp[-4].data), d);
+ fclose(f);
+ }
+-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1709 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 25:
+-#line 261 "dtc-parser.y" /* yacc.c:1646 */
++ case 27:
++#line 277 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1717 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 26:
+-#line 268 "dtc-parser.y" /* yacc.c:1646 */
++ case 28:
++#line 284 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = empty_data;
+ }
+-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 27:
+-#line 272 "dtc-parser.y" /* yacc.c:1646 */
++ case 29:
++#line 288 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = (yyvsp[-1].data);
+ }
+-#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1733 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 28:
+-#line 276 "dtc-parser.y" /* yacc.c:1646 */
++ case 30:
++#line 292 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 29:
+-#line 283 "dtc-parser.y" /* yacc.c:1646 */
++ case 31:
++#line 299 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ unsigned long long bits;
+
+@@ -1737,20 +1757,20 @@ yyreduce:
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = bits;
+ }
+-#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1761 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 30:
+-#line 299 "dtc-parser.y" /* yacc.c:1646 */
++ case 32:
++#line 315 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.array).data = empty_data;
+ (yyval.array).bits = 32;
+ }
+-#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1770 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 31:
+-#line 304 "dtc-parser.y" /* yacc.c:1646 */
++ case 33:
++#line 320 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[-1].array).bits < 64) {
+ uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
+@@ -1769,11 +1789,11 @@ yyreduce:
+
+ (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 */
++#line 1793 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 32:
+-#line 323 "dtc-parser.y" /* yacc.c:1646 */
++ case 34:
++#line 339 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
+
+@@ -1787,233 +1807,233 @@ yyreduce:
+
+ (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
+ }
+-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1811 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 33:
+-#line 337 "dtc-parser.y" /* yacc.c:1646 */
++ case 35:
++#line 353 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
+ }
+-#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 36:
+-#line 346 "dtc-parser.y" /* yacc.c:1646 */
++ case 38:
++#line 362 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.integer) = (yyvsp[-1].integer);
+ }
+-#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1827 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 39:
+-#line 357 "dtc-parser.y" /* yacc.c:1646 */
++ case 41:
++#line 373 "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 */
++#line 1833 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 41:
+-#line 362 "dtc-parser.y" /* yacc.c:1646 */
++ case 43:
++#line 378 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
+-#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 43:
+-#line 367 "dtc-parser.y" /* yacc.c:1646 */
++ case 45:
++#line 383 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
+-#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 45:
+-#line 372 "dtc-parser.y" /* yacc.c:1646 */
++ case 47:
++#line 388 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
+-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 47:
+-#line 377 "dtc-parser.y" /* yacc.c:1646 */
++ case 49:
++#line 393 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
+-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 49:
+-#line 382 "dtc-parser.y" /* yacc.c:1646 */
++ case 51:
++#line 398 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
+-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 51:
+-#line 387 "dtc-parser.y" /* yacc.c:1646 */
++ case 53:
++#line 403 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
+-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 52:
+-#line 388 "dtc-parser.y" /* yacc.c:1646 */
++ case 54:
++#line 404 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
+-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 54:
+-#line 393 "dtc-parser.y" /* yacc.c:1646 */
++ case 56:
++#line 409 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
+-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 55:
+-#line 394 "dtc-parser.y" /* yacc.c:1646 */
++ case 57:
++#line 410 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
+-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 56:
+-#line 395 "dtc-parser.y" /* yacc.c:1646 */
++ case 58:
++#line 411 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
+-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 57:
+-#line 396 "dtc-parser.y" /* yacc.c:1646 */
++ case 59:
++#line 412 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
+-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 58:
+-#line 400 "dtc-parser.y" /* yacc.c:1646 */
++ case 60:
++#line 416 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
+-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 59:
+-#line 401 "dtc-parser.y" /* yacc.c:1646 */
++ case 61:
++#line 417 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
+-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 61:
+-#line 406 "dtc-parser.y" /* yacc.c:1646 */
++ case 63:
++#line 422 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
+-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 62:
+-#line 407 "dtc-parser.y" /* yacc.c:1646 */
++ case 64:
++#line 423 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
+-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 64:
+-#line 412 "dtc-parser.y" /* yacc.c:1646 */
++ case 66:
++#line 428 "dtc-parser.y" /* yacc.c:1646 */
+ { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
+-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */
++#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 65:
+-#line 413 "dtc-parser.y" /* 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 */
++#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+- case 66:
+-#line 414 "dtc-parser.y" /* 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 */
++#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 */
+ { (yyval.integer) = -(yyvsp[0].integer); }
+-#line 1927 "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 */
+ { (yyval.integer) = ~(yyvsp[0].integer); }
+-#line 1933 "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 */
+ { (yyval.integer) = !(yyvsp[0].integer); }
+-#line 1939 "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 */
+ {
+ (yyval.data) = empty_data;
+ }
+-#line 1947 "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 */
+ {
+ (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
+ }
+-#line 1955 "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 */
+ {
+ (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
+ }
+-#line 1963 "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 */
+ {
+ (yyval.nodelist) = NULL;
+ }
+-#line 1971 "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 */
+ {
+ (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
+ }
+-#line 1979 "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 */
+ {
+ ERROR(&(yylsp[0]), "Properties must precede subnodes");
+ YYERROR;
+ }
+-#line 1988 "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 */
+ {
+ (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
+ }
+-#line 1996 "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 */
+ {
+ (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
+ }
+-#line 2004 "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 */
+ {
+ add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
+ (yyval.node) = (yyvsp[0].node);
+ }
+-#line 2013 "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 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)
+--- a/scripts/dtc/dtc-parser.tab.h_shipped
++++ b/scripts/dtc/dtc-parser.tab.h_shipped
+@@ -46,26 +46,27 @@ extern int yydebug;
+ 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
++ 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
+
+@@ -74,7 +75,7 @@ extern int yydebug;
+ typedef union YYSTYPE YYSTYPE;
+ union YYSTYPE
+ {
+-#line 38 "dtc-parser.y" /* yacc.c:1909 */
++#line 39 "dtc-parser.y" /* yacc.c:1909 */
+
+ char *propnodename;
+ char *labelref;
+@@ -92,8 +93,9 @@ union YYSTYPE
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
++ bool is_plugin;
+
+-#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */
++#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */
+ };
+ # define YYSTYPE_IS_TRIVIAL 1
+ # define YYSTYPE_IS_DECLARED 1
+--- a/scripts/dtc/dtc-parser.y
++++ b/scripts/dtc/dtc-parser.y
+@@ -19,6 +19,7 @@
+ */
+ %{
+ #include <stdio.h>
++#include <inttypes.h>
+
+ #include "dtc.h"
+ #include "srcpos.h"
+@@ -52,9 +53,11 @@ extern bool treesource_error;
+ struct node *nodelist;
+ struct reserve_info *re;
+ uint64_t integer;
++ bool 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 <data> propdata
+ %type <data> propdataprefix
++%type <is_plugin> plugindecl
+ %type <re> memreserve
+ %type <re> memreserves
+ %type <array> arrayprefix
+@@ -101,10 +105,22 @@ 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;
++ the_boot_info = build_boot_info($4, $5,
++ guess_boot_cpuid($5));
++ }
++ ;
++
++plugindecl:
++ /* empty */
++ {
++ $$ = false;
++ }
++ | DT_PLUGIN ';'
++ {
++ $$ = true;
+ }
+ ;
+
+--- a/scripts/dtc/dtc.c
++++ b/scripts/dtc/dtc.c
+@@ -29,6 +29,7 @@ int reservenum; /* Number of memory res
+ 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 *
+ #define FDT_VERSION(version) _FDT_VERSION(version)
+ #define _FDT_VERSION(version) #version
+ static const char usage_synopsis[] = "dtc [options] <input file>";
+-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_op
+ {"phandle", a_argument, NULL, 'H'},
+ {"warning", a_argument, NULL, 'W'},
+ {"error", a_argument, NULL, 'E'},
++ {"symbols", no_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_hel
+ "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
+ "\n\tEnable/disable warnings (prefix with \"no-\")",
+ "\n\tEnable/disable errors (prefix with \"no-\")",
++ "\n\tEnable symbols/fixup 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:
+--- a/scripts/dtc/dtc.h
++++ b/scripts/dtc/dtc.h
+@@ -54,6 +54,7 @@ extern int reservenum; /* Number of mem
+ 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,26 @@ struct label {
+ struct label *next;
+ };
+
++struct fixup_entry {
++ int offset;
++ struct node *node;
++ struct property *prop;
++ struct fixup_entry *next;
++ bool local_fixup_generated;
++};
++
++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 +179,13 @@ struct node {
+ int addr_cells, size_cells;
+
+ struct label *labels;
++
++ struct symbol *symbols;
++ struct fixup_entry *local_fixups;
++ bool emit_local_fixup_node;
++
++ bool is_plugin;
++ struct fixup *fixups;
+ };
+
+ #define for_each_label_withdel(l0, l) \
+@@ -181,6 +209,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);
+
+--- a/scripts/dtc/flattree.c
++++ b/scripts/dtc/flattree.c
+@@ -255,6 +255,204 @@ static int stringtable_insert(struct dat
+ return i;
+ }
+
++static void emit_local_fixups(struct node *tree, struct emitter *emit,
++ void *etarget, struct data *strbuf, struct version_info *vi,
++ struct node *node)
++{
++ struct fixup_entry *fe, *fen;
++ struct node *child;
++ int nameoff, count;
++ cell_t *buf;
++ struct data d;
++
++ if (node->emit_local_fixup_node) {
++
++ /* emit the external fixups (do not emit /) */
++ if (node != tree) {
++ emit->beginnode(etarget, NULL);
++ emit->string(etarget, node->name, 0);
++ emit->align(etarget, sizeof(cell_t));
++ }
++
++ for_each_local_fixup_entry(tree, fe) {
++ if (fe->node != node || fe->local_fixup_generated)
++ continue;
++
++ /* count the number of fixup entries */
++ count = 0;
++ for_each_local_fixup_entry(tree, fen) {
++ if (fen->prop != fe->prop)
++ continue;
++ fen->local_fixup_generated = true;
++ count++;
++ }
++
++ /* allocate buffer */
++ buf = xmalloc(count * sizeof(cell_t));
++
++ /* collect all the offsets in buffer */
++ count = 0;
++ for_each_local_fixup_entry(tree, fen) {
++ if (fen->prop != fe->prop)
++ continue;
++ fen->local_fixup_generated = true;
++ buf[count++] = cpu_to_fdt32(fen->offset);
++ }
++ d = empty_data;
++ d.len = count * sizeof(cell_t);
++ d.val = (char *)buf;
++
++ nameoff = stringtable_insert(strbuf, fe->prop->name);
++ emit->property(etarget, fe->prop->labels);
++ emit->cell(etarget, count * sizeof(cell_t));
++ emit->cell(etarget, nameoff);
++
++ if ((vi->flags & FTF_VARALIGN) &&
++ (count * sizeof(cell_t)) >= 8)
++ emit->align(etarget, 8);
++
++ emit->data(etarget, d);
++ emit->align(etarget, sizeof(cell_t));
++
++ free(buf);
++ }
++ }
++
++ for_each_child(node, child)
++ emit_local_fixups(tree, emit, etarget, strbuf, vi, child);
++
++ if (node->emit_local_fixup_node && node != tree)
++ emit->endnode(etarget, tree->labels);
++}
++
++static void emit_symbols_node(struct node *tree, struct emitter *emit,
++ void *etarget, struct data *strbuf,
++ struct version_info *vi)
++{
++ struct symbol *sym;
++ int nameoff, vallen;
++
++ /* do nothing if no symbols */
++ if (!tree->symbols)
++ return;
++
++ 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);
++}
++
++static void emit_local_fixups_node(struct node *tree, struct emitter *emit,
++ void *etarget, struct data *strbuf,
++ struct version_info *vi)
++{
++ struct fixup_entry *fe;
++ struct node *node;
++
++ /* do nothing if no local fixups */
++ if (!tree->local_fixups)
++ return;
++
++ /* mark all nodes that need a local fixup generated (and parents) */
++ for_each_local_fixup_entry(tree, fe) {
++ node = fe->node;
++ while (node != NULL && !node->emit_local_fixup_node) {
++ node->emit_local_fixup_node = true;
++ node = node->parent;
++ }
++ }
++
++ /* emit the local fixups node now */
++ emit->beginnode(etarget, NULL);
++ emit->string(etarget, "__local_fixups__", 0);
++ emit->align(etarget, sizeof(cell_t));
++
++ emit_local_fixups(tree, emit, etarget, strbuf, vi, tree);
++
++ emit->endnode(etarget, tree->labels);
++}
++
++static void emit_fixups_node(struct node *tree, struct emitter *emit,
++ void *etarget, struct data *strbuf,
++ struct version_info *vi)
++{
++ struct fixup *f;
++ struct fixup_entry *fe;
++ char *name, *s;
++ const char *fullpath;
++ int namesz, nameoff, vallen;
++
++ /* do nothing if no fixups */
++ if (!tree->fixups)
++ return;
++
++ /* 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 :<number> + '\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);
++}
++
+ static void flatten_tree(struct node *tree, struct emitter *emit,
+ void *etarget, struct data *strbuf,
+ struct version_info *vi)
+@@ -310,6 +508,10 @@ static void flatten_tree(struct node *tr
+ flatten_tree(child, emit, etarget, strbuf, vi);
+ }
+
++ emit_symbols_node(tree, emit, etarget, strbuf, vi);
++ emit_local_fixups_node(tree, emit, etarget, strbuf, vi);
++ emit_fixups_node(tree, emit, etarget, strbuf, vi);
++
+ emit->endnode(etarget, tree->labels);
+ }
+
+--- 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-g25efc119"
--- /dev/null
+From 28059745722d31f48971035bbca98d689adb41f6 Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Date: Thu, 22 Oct 2015 23:30:04 +0300
+Subject: [PATCH 177/304] 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 <pantelis.antoniou@konsulko.com>
+[hch: folded a fix from Geert Uytterhoeven <geert+renesas@glider.be>]
+[hch: a few tiny updates based on review feedback]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ 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(-)
+
+--- a/Documentation/filesystems/configfs/configfs.txt
++++ b/Documentation/filesystems/configfs/configfs.txt
+@@ -51,15 +51,27 @@ configfs tree is always there, whether m
+ 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
+ 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
+ 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
+--- 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
+ 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
+ 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;
+--- a/fs/configfs/dir.c
++++ b/fs/configfs/dir.c
+@@ -255,6 +255,12 @@ static void configfs_init_file(struct in
+ 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 c
+ 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_
+ {
+ 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_
+ 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);
+--- a/fs/configfs/file.c
++++ b/fs/configfs/file.c
+@@ -28,6 +28,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/mutex.h>
++#include <linux/vmalloc.h>
+ #include <asm/uaccess.h>
+
+ #include <linux/configfs.h>
+@@ -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, c
+ 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 * ino
+ 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 * ino
+ * 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 * ino
+ * 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 * ino
+ }
+ 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 * ino
+ 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
+ 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_fi
+ .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_i
+ 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;
++}
+--- a/fs/configfs/inode.c
++++ b/fs/configfs/inode.c
+@@ -218,7 +218,7 @@ const unsigned char * configfs_get_name(
+ 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;
+ }
+--- 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##a
+ .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).
+++ /dev/null
-From 8ed747466ab2fac41d870582b149385d3e8c2d43 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 10 Aug 2015 09:49:15 +0100
-Subject: [PATCH 177/232] scripts/dtc: Update to upstream version 1.4.1
-
-Includes the new localfixups format.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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-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(-)
-
---- a/scripts/dtc/checks.c
-+++ b/scripts/dtc/checks.c
-@@ -458,6 +458,8 @@ static void fixup_phandle_references(str
- 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;
-
-@@ -466,11 +468,69 @@ static void fixup_phandle_references(str
-
- refnode = get_node_by_ref(dt, m->ref);
- if (! refnode) {
-- FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-- m->ref);
-+ if (!dt->is_plugin) {
-+ FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-+ m->ref);
-+ continue;
-+ }
-+
-+ /* 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 */
-+ *((cell_t *)(prop->val.val + m->offset)) =
-+ cpu_to_fdt32(0xdeadbeef);
- continue;
- }
-
-+ /* if it's a local reference, we need to record it */
-+ if (symbol_fixup_support) {
-+
-+ /* 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;
-+ }
-+
- phandle = get_node_phandle(dt, refnode);
- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
- }
-@@ -652,6 +712,45 @@ static void check_obsolete_chosen_interr
- }
- 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 +769,8 @@ static struct check *check_table[] = {
- &avoid_default_addr_size,
- &obsolete_chosen_interrupt_controller,
-
-+ &auto_label_phandles,
-+
- &always_fail,
- };
-
---- a/scripts/dtc/dtc-lexer.l
-+++ b/scripts/dtc/dtc-lexer.l
-@@ -113,6 +113,11 @@ static void lexical_error(const char *fm
- return DT_V1;
- }
-
-+<*>"/plugin/" {
-+ DPRINT("Keyword: /plugin/\n");
-+ return DT_PLUGIN;
-+ }
-+
- <*>"/memreserve/" {
- DPRINT("Keyword: /memreserve/\n");
- BEGIN_DEFAULT();
---- 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
-
- /* 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_ST
-
- 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
- *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("<PROPNODENAME>\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("<PROPNODENAME>\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
- *
- * @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"
-
-
-
---- a/scripts/dtc/dtc-parser.tab.c_shipped
-+++ b/scripts/dtc/dtc-parser.tab.c_shipped
-@@ -65,6 +65,7 @@
- #line 20 "dtc-parser.y" /* yacc.c:339 */
-
- #include <stdio.h>
-+#include <inttypes.h>
-
- #include "dtc.h"
- #include "srcpos.h"
-@@ -80,7 +81,7 @@ 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 85 "dtc-parser.tab.c" /* yacc.c:339 */
-
- # ifndef YY_NULLPTR
- # if defined __cplusplus && 201103L <= __cplusplus
-@@ -116,26 +117,27 @@ extern int yydebug;
- 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
-+ 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
-
-@@ -144,7 +146,7 @@ extern int yydebug;
- typedef union YYSTYPE YYSTYPE;
- union YYSTYPE
- {
--#line 38 "dtc-parser.y" /* yacc.c:355 */
-+#line 39 "dtc-parser.y" /* yacc.c:355 */
-
- char *propnodename;
- char *labelref;
-@@ -162,8 +164,9 @@ union YYSTYPE
- struct node *nodelist;
- struct reserve_info *re;
- uint64_t integer;
-+ bool is_plugin;
-
--#line 167 "dtc-parser.tab.c" /* yacc.c:355 */
-+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */
- };
- # define YYSTYPE_IS_TRIVIAL 1
- # define YYSTYPE_IS_DECLARED 1
-@@ -192,7 +195,7 @@ int yyparse (void);
-
- /* Copy the second part of user declarations. */
-
--#line 196 "dtc-parser.tab.c" /* yacc.c:358 */
-+#line 199 "dtc-parser.tab.c" /* yacc.c:358 */
-
- #ifdef short
- # undef short
-@@ -439,18 +442,18 @@ 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
-+#define YYNRULES 82
- /* YYNSTATES -- Number of states. */
--#define YYNSTATES 144
-+#define YYNSTATES 147
-
- /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
- #define YYUNDEFTOK 2
--#define YYMAXUTOK 278
-+#define YYMAXUTOK 279
-
- #define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-@@ -462,16 +465,16 @@ 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,22 +489,22 @@ 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. */
- 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, 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,
-+ 291, 298, 314, 319, 338, 352, 359, 360, 361, 368,
-+ 372, 373, 377, 378, 382, 383, 387, 388, 392, 393,
-+ 397, 398, 402, 403, 404, 408, 409, 410, 411, 412,
-+ 416, 417, 418, 422, 423, 424, 428, 429, 430, 431,
-+ 435, 436, 437, 438, 443, 446, 450, 458, 461, 465,
-+ 473, 477, 481
- };
- #endif
-
-@@ -510,19 +513,19 @@ static const yytype_uint16 yyrline[] =
- 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", YY_NULLPTR
- };
- #endif
-
-@@ -533,16 +536,16 @@ 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_NINF -84
-
- #define yypact_value_is_default(Yystate) \
-- (!!((Yystate) == (-81)))
-+ (!!((Yystate) == (-84)))
-
- #define YYTABLE_NINF -1
-
-@@ -553,21 +556,21 @@ static const yytype_uint16 yytoknum[] =
- STATE-NUM. */
- static const yytype_int8 yypact[] =
- {
-- 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
-+ 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
- };
-
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-@@ -575,37 +578,37 @@ static const yytype_int8 yypact[] =
- means the default is an error. */
- static const yytype_uint8 yydefact[] =
- {
-- 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, 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, 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, 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
- };
-
- /* YYPGOTO[NTERM-NUM]. */
- static const yytype_int8 yypgoto[] =
- {
-- -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
-+ -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
- };
-
- /* 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
-@@ -613,87 +616,87 @@ static const yytype_int16 yydefgoto[] =
- number is the opposite. If YYTABLE_NINF, syntax error. */
- static const yytype_uint8 yytable[] =
- {
-- 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, 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
- };
-
- static const yytype_int16 yycheck[] =
- {
-- 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
-+ 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
- };
-
- /* 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
-+ 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
- };
-
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
- static const yytype_uint8 yyr1[] =
- {
-- 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
-+ 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
- };
-
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
- static const yytype_uint8 yyr2[] =
- {
-- 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, 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
- };
-
-
-@@ -1463,65 +1466,82 @@ yyreduce:
- switch (yyn)
- {
- case 2:
--#line 105 "dtc-parser.y" /* yacc.c:1646 */
-+#line 109 "dtc-parser.y" /* yacc.c:1646 */
- {
-+ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin);
- 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 */
-+#line 1476 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 3:
--#line 113 "dtc-parser.y" /* yacc.c:1646 */
-+#line 118 "dtc-parser.y" /* yacc.c:1646 */
- {
-- (yyval.re) = NULL;
-+ (yyval.is_plugin) = false;
- }
--#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1484 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 4:
--#line 117 "dtc-parser.y" /* yacc.c:1646 */
-+#line 122 "dtc-parser.y" /* yacc.c:1646 */
- {
-- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
-+ (yyval.is_plugin) = true;
- }
--#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1492 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 5:
--#line 124 "dtc-parser.y" /* yacc.c:1646 */
-+#line 129 "dtc-parser.y" /* yacc.c:1646 */
- {
-- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
-+ (yyval.re) = NULL;
- }
--#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1500 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 6:
--#line 128 "dtc-parser.y" /* yacc.c:1646 */
-+#line 133 "dtc-parser.y" /* yacc.c:1646 */
-+ {
-+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
-+ }
-+#line 1508 "dtc-parser.tab.c" /* yacc.c:1646 */
-+ break;
-+
-+ case 7:
-+#line 140 "dtc-parser.y" /* yacc.c:1646 */
-+ {
-+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
-+ }
-+#line 1516 "dtc-parser.tab.c" /* yacc.c:1646 */
-+ break;
-+
-+ case 8:
-+#line 144 "dtc-parser.y" /* yacc.c:1646 */
- {
- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
- (yyval.re) = (yyvsp[0].re);
- }
--#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1525 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 7:
--#line 136 "dtc-parser.y" /* yacc.c:1646 */
-+ case 9:
-+#line 152 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.node) = name_node((yyvsp[0].node), "");
- }
--#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1533 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 8:
--#line 140 "dtc-parser.y" /* yacc.c:1646 */
-+ case 10:
-+#line 156 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
- }
--#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1541 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 9:
--#line 145 "dtc-parser.y" /* yacc.c:1646 */
-+ case 11:
-+#line 161 "dtc-parser.y" /* yacc.c:1646 */
- {
- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-@@ -1532,11 +1552,11 @@ yyreduce:
- 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 */
-+#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 10:
--#line 156 "dtc-parser.y" /* yacc.c:1646 */
-+ case 12:
-+#line 172 "dtc-parser.y" /* yacc.c:1646 */
- {
- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
-
-@@ -1546,11 +1566,11 @@ yyreduce:
- 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 */
-+#line 1570 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 11:
--#line 166 "dtc-parser.y" /* yacc.c:1646 */
-+ case 13:
-+#line 182 "dtc-parser.y" /* yacc.c:1646 */
- {
- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
-
-@@ -1562,100 +1582,100 @@ yyreduce:
-
- (yyval.node) = (yyvsp[-3].node);
- }
--#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1586 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 12:
--#line 181 "dtc-parser.y" /* yacc.c:1646 */
-+ case 14:
-+#line 197 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
- }
--#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1594 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 13:
--#line 188 "dtc-parser.y" /* yacc.c:1646 */
-+ case 15:
-+#line 204 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.proplist) = NULL;
- }
--#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1602 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 14:
--#line 192 "dtc-parser.y" /* yacc.c:1646 */
-+ case 16:
-+#line 208 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
- }
--#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1610 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 15:
--#line 199 "dtc-parser.y" /* yacc.c:1646 */
-+ case 17:
-+#line 215 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
- }
--#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1618 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 16:
--#line 203 "dtc-parser.y" /* yacc.c:1646 */
-+ case 18:
-+#line 219 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
- }
--#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1626 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 17:
--#line 207 "dtc-parser.y" /* yacc.c:1646 */
-+ case 19:
-+#line 223 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
- }
--#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1634 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 18:
--#line 211 "dtc-parser.y" /* yacc.c:1646 */
-+ case 20:
-+#line 227 "dtc-parser.y" /* yacc.c:1646 */
- {
- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
- (yyval.prop) = (yyvsp[0].prop);
- }
--#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1643 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 19:
--#line 219 "dtc-parser.y" /* yacc.c:1646 */
-+ case 21:
-+#line 235 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
- }
--#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1651 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 20:
--#line 223 "dtc-parser.y" /* yacc.c:1646 */
-+ case 22:
-+#line 239 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
- }
--#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1659 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 21:
--#line 227 "dtc-parser.y" /* yacc.c:1646 */
-+ case 23:
-+#line 243 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
- }
--#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1667 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 22:
--#line 231 "dtc-parser.y" /* yacc.c:1646 */
-+ case 24:
-+#line 247 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
- }
--#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 23:
--#line 235 "dtc-parser.y" /* yacc.c:1646 */
-+ case 25:
-+#line 251 "dtc-parser.y" /* yacc.c:1646 */
- {
- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
- struct data d;
-@@ -1671,11 +1691,11 @@ yyreduce:
- (yyval.data) = data_merge((yyvsp[-8].data), d);
- fclose(f);
- }
--#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 24:
--#line 251 "dtc-parser.y" /* yacc.c:1646 */
-+ case 26:
-+#line 267 "dtc-parser.y" /* yacc.c:1646 */
- {
- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
- struct data d = empty_data;
-@@ -1685,43 +1705,43 @@ yyreduce:
- (yyval.data) = data_merge((yyvsp[-4].data), d);
- fclose(f);
- }
--#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1709 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 25:
--#line 261 "dtc-parser.y" /* yacc.c:1646 */
-+ case 27:
-+#line 277 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
- }
--#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1717 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 26:
--#line 268 "dtc-parser.y" /* yacc.c:1646 */
-+ case 28:
-+#line 284 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = empty_data;
- }
--#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 27:
--#line 272 "dtc-parser.y" /* yacc.c:1646 */
-+ case 29:
-+#line 288 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = (yyvsp[-1].data);
- }
--#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1733 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 28:
--#line 276 "dtc-parser.y" /* yacc.c:1646 */
-+ case 30:
-+#line 292 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
- }
--#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 29:
--#line 283 "dtc-parser.y" /* yacc.c:1646 */
-+ case 31:
-+#line 299 "dtc-parser.y" /* yacc.c:1646 */
- {
- unsigned long long bits;
-
-@@ -1737,20 +1757,20 @@ yyreduce:
- (yyval.array).data = empty_data;
- (yyval.array).bits = bits;
- }
--#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1761 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 30:
--#line 299 "dtc-parser.y" /* yacc.c:1646 */
-+ case 32:
-+#line 315 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.array).data = empty_data;
- (yyval.array).bits = 32;
- }
--#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1770 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 31:
--#line 304 "dtc-parser.y" /* yacc.c:1646 */
-+ case 33:
-+#line 320 "dtc-parser.y" /* yacc.c:1646 */
- {
- if ((yyvsp[-1].array).bits < 64) {
- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
-@@ -1769,11 +1789,11 @@ yyreduce:
-
- (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 */
-+#line 1793 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 32:
--#line 323 "dtc-parser.y" /* yacc.c:1646 */
-+ case 34:
-+#line 339 "dtc-parser.y" /* yacc.c:1646 */
- {
- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
-
-@@ -1787,233 +1807,233 @@ yyreduce:
-
- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
- }
--#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1811 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 33:
--#line 337 "dtc-parser.y" /* yacc.c:1646 */
-+ case 35:
-+#line 353 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
- }
--#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 36:
--#line 346 "dtc-parser.y" /* yacc.c:1646 */
-+ case 38:
-+#line 362 "dtc-parser.y" /* yacc.c:1646 */
- {
- (yyval.integer) = (yyvsp[-1].integer);
- }
--#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1827 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 39:
--#line 357 "dtc-parser.y" /* yacc.c:1646 */
-+ case 41:
-+#line 373 "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 */
-+#line 1833 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 41:
--#line 362 "dtc-parser.y" /* yacc.c:1646 */
-+ case 43:
-+#line 378 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
--#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 43:
--#line 367 "dtc-parser.y" /* yacc.c:1646 */
-+ case 45:
-+#line 383 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
--#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 45:
--#line 372 "dtc-parser.y" /* yacc.c:1646 */
-+ case 47:
-+#line 388 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
--#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 47:
--#line 377 "dtc-parser.y" /* yacc.c:1646 */
-+ case 49:
-+#line 393 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
--#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 49:
--#line 382 "dtc-parser.y" /* yacc.c:1646 */
-+ case 51:
-+#line 398 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
--#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 51:
--#line 387 "dtc-parser.y" /* yacc.c:1646 */
-+ case 53:
-+#line 403 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
--#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 52:
--#line 388 "dtc-parser.y" /* yacc.c:1646 */
-+ case 54:
-+#line 404 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
--#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 54:
--#line 393 "dtc-parser.y" /* yacc.c:1646 */
-+ case 56:
-+#line 409 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
--#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 55:
--#line 394 "dtc-parser.y" /* yacc.c:1646 */
-+ case 57:
-+#line 410 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
--#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 56:
--#line 395 "dtc-parser.y" /* yacc.c:1646 */
-+ case 58:
-+#line 411 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
--#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 57:
--#line 396 "dtc-parser.y" /* yacc.c:1646 */
-+ case 59:
-+#line 412 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
--#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 58:
--#line 400 "dtc-parser.y" /* yacc.c:1646 */
-+ case 60:
-+#line 416 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
--#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 59:
--#line 401 "dtc-parser.y" /* yacc.c:1646 */
-+ case 61:
-+#line 417 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
--#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 61:
--#line 406 "dtc-parser.y" /* yacc.c:1646 */
-+ case 63:
-+#line 422 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
--#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 62:
--#line 407 "dtc-parser.y" /* yacc.c:1646 */
-+ case 64:
-+#line 423 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
--#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 64:
--#line 412 "dtc-parser.y" /* yacc.c:1646 */
-+ case 66:
-+#line 428 "dtc-parser.y" /* yacc.c:1646 */
- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
--#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */
-+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 65:
--#line 413 "dtc-parser.y" /* 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 */
-+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
- break;
-
-- case 66:
--#line 414 "dtc-parser.y" /* 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 */
-+#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 */
- { (yyval.integer) = -(yyvsp[0].integer); }
--#line 1927 "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 */
- { (yyval.integer) = ~(yyvsp[0].integer); }
--#line 1933 "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 */
- { (yyval.integer) = !(yyvsp[0].integer); }
--#line 1939 "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 */
- {
- (yyval.data) = empty_data;
- }
--#line 1947 "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 */
- {
- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
- }
--#line 1955 "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 */
- {
- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
- }
--#line 1963 "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 */
- {
- (yyval.nodelist) = NULL;
- }
--#line 1971 "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 */
- {
- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
- }
--#line 1979 "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 */
- {
- ERROR(&(yylsp[0]), "Properties must precede subnodes");
- YYERROR;
- }
--#line 1988 "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 */
- {
- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
- }
--#line 1996 "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 */
- {
- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
- }
--#line 2004 "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 */
- {
- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
- (yyval.node) = (yyvsp[0].node);
- }
--#line 2013 "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 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)
---- a/scripts/dtc/dtc-parser.tab.h_shipped
-+++ b/scripts/dtc/dtc-parser.tab.h_shipped
-@@ -46,26 +46,27 @@ extern int yydebug;
- 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
-+ 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
-
-@@ -74,7 +75,7 @@ extern int yydebug;
- typedef union YYSTYPE YYSTYPE;
- union YYSTYPE
- {
--#line 38 "dtc-parser.y" /* yacc.c:1909 */
-+#line 39 "dtc-parser.y" /* yacc.c:1909 */
-
- char *propnodename;
- char *labelref;
-@@ -92,8 +93,9 @@ union YYSTYPE
- struct node *nodelist;
- struct reserve_info *re;
- uint64_t integer;
-+ bool is_plugin;
-
--#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */
-+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */
- };
- # define YYSTYPE_IS_TRIVIAL 1
- # define YYSTYPE_IS_DECLARED 1
---- a/scripts/dtc/dtc-parser.y
-+++ b/scripts/dtc/dtc-parser.y
-@@ -19,6 +19,7 @@
- */
- %{
- #include <stdio.h>
-+#include <inttypes.h>
-
- #include "dtc.h"
- #include "srcpos.h"
-@@ -52,9 +53,11 @@ extern bool treesource_error;
- struct node *nodelist;
- struct reserve_info *re;
- uint64_t integer;
-+ bool 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 <data> propdata
- %type <data> propdataprefix
-+%type <is_plugin> plugindecl
- %type <re> memreserve
- %type <re> memreserves
- %type <array> arrayprefix
-@@ -101,10 +105,22 @@ 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;
-+ the_boot_info = build_boot_info($4, $5,
-+ guess_boot_cpuid($5));
-+ }
-+ ;
-+
-+plugindecl:
-+ /* empty */
-+ {
-+ $$ = false;
-+ }
-+ | DT_PLUGIN ';'
-+ {
-+ $$ = true;
- }
- ;
-
---- a/scripts/dtc/dtc.c
-+++ b/scripts/dtc/dtc.c
-@@ -29,6 +29,7 @@ int reservenum; /* Number of memory res
- 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 *
- #define FDT_VERSION(version) _FDT_VERSION(version)
- #define _FDT_VERSION(version) #version
- static const char usage_synopsis[] = "dtc [options] <input file>";
--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_op
- {"phandle", a_argument, NULL, 'H'},
- {"warning", a_argument, NULL, 'W'},
- {"error", a_argument, NULL, 'E'},
-+ {"symbols", no_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_hel
- "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
- "\n\tEnable/disable warnings (prefix with \"no-\")",
- "\n\tEnable/disable errors (prefix with \"no-\")",
-+ "\n\tEnable symbols/fixup 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:
---- a/scripts/dtc/dtc.h
-+++ b/scripts/dtc/dtc.h
-@@ -54,6 +54,7 @@ extern int reservenum; /* Number of mem
- 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,26 @@ struct label {
- struct label *next;
- };
-
-+struct fixup_entry {
-+ int offset;
-+ struct node *node;
-+ struct property *prop;
-+ struct fixup_entry *next;
-+ bool local_fixup_generated;
-+};
-+
-+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 +179,13 @@ struct node {
- int addr_cells, size_cells;
-
- struct label *labels;
-+
-+ struct symbol *symbols;
-+ struct fixup_entry *local_fixups;
-+ bool emit_local_fixup_node;
-+
-+ bool is_plugin;
-+ struct fixup *fixups;
- };
-
- #define for_each_label_withdel(l0, l) \
-@@ -181,6 +209,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);
-
---- a/scripts/dtc/flattree.c
-+++ b/scripts/dtc/flattree.c
-@@ -255,6 +255,204 @@ static int stringtable_insert(struct dat
- return i;
- }
-
-+static void emit_local_fixups(struct node *tree, struct emitter *emit,
-+ void *etarget, struct data *strbuf, struct version_info *vi,
-+ struct node *node)
-+{
-+ struct fixup_entry *fe, *fen;
-+ struct node *child;
-+ int nameoff, count;
-+ cell_t *buf;
-+ struct data d;
-+
-+ if (node->emit_local_fixup_node) {
-+
-+ /* emit the external fixups (do not emit /) */
-+ if (node != tree) {
-+ emit->beginnode(etarget, NULL);
-+ emit->string(etarget, node->name, 0);
-+ emit->align(etarget, sizeof(cell_t));
-+ }
-+
-+ for_each_local_fixup_entry(tree, fe) {
-+ if (fe->node != node || fe->local_fixup_generated)
-+ continue;
-+
-+ /* count the number of fixup entries */
-+ count = 0;
-+ for_each_local_fixup_entry(tree, fen) {
-+ if (fen->prop != fe->prop)
-+ continue;
-+ fen->local_fixup_generated = true;
-+ count++;
-+ }
-+
-+ /* allocate buffer */
-+ buf = xmalloc(count * sizeof(cell_t));
-+
-+ /* collect all the offsets in buffer */
-+ count = 0;
-+ for_each_local_fixup_entry(tree, fen) {
-+ if (fen->prop != fe->prop)
-+ continue;
-+ fen->local_fixup_generated = true;
-+ buf[count++] = cpu_to_fdt32(fen->offset);
-+ }
-+ d = empty_data;
-+ d.len = count * sizeof(cell_t);
-+ d.val = (char *)buf;
-+
-+ nameoff = stringtable_insert(strbuf, fe->prop->name);
-+ emit->property(etarget, fe->prop->labels);
-+ emit->cell(etarget, count * sizeof(cell_t));
-+ emit->cell(etarget, nameoff);
-+
-+ if ((vi->flags & FTF_VARALIGN) &&
-+ (count * sizeof(cell_t)) >= 8)
-+ emit->align(etarget, 8);
-+
-+ emit->data(etarget, d);
-+ emit->align(etarget, sizeof(cell_t));
-+
-+ free(buf);
-+ }
-+ }
-+
-+ for_each_child(node, child)
-+ emit_local_fixups(tree, emit, etarget, strbuf, vi, child);
-+
-+ if (node->emit_local_fixup_node && node != tree)
-+ emit->endnode(etarget, tree->labels);
-+}
-+
-+static void emit_symbols_node(struct node *tree, struct emitter *emit,
-+ void *etarget, struct data *strbuf,
-+ struct version_info *vi)
-+{
-+ struct symbol *sym;
-+ int nameoff, vallen;
-+
-+ /* do nothing if no symbols */
-+ if (!tree->symbols)
-+ return;
-+
-+ 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);
-+}
-+
-+static void emit_local_fixups_node(struct node *tree, struct emitter *emit,
-+ void *etarget, struct data *strbuf,
-+ struct version_info *vi)
-+{
-+ struct fixup_entry *fe;
-+ struct node *node;
-+
-+ /* do nothing if no local fixups */
-+ if (!tree->local_fixups)
-+ return;
-+
-+ /* mark all nodes that need a local fixup generated (and parents) */
-+ for_each_local_fixup_entry(tree, fe) {
-+ node = fe->node;
-+ while (node != NULL && !node->emit_local_fixup_node) {
-+ node->emit_local_fixup_node = true;
-+ node = node->parent;
-+ }
-+ }
-+
-+ /* emit the local fixups node now */
-+ emit->beginnode(etarget, NULL);
-+ emit->string(etarget, "__local_fixups__", 0);
-+ emit->align(etarget, sizeof(cell_t));
-+
-+ emit_local_fixups(tree, emit, etarget, strbuf, vi, tree);
-+
-+ emit->endnode(etarget, tree->labels);
-+}
-+
-+static void emit_fixups_node(struct node *tree, struct emitter *emit,
-+ void *etarget, struct data *strbuf,
-+ struct version_info *vi)
-+{
-+ struct fixup *f;
-+ struct fixup_entry *fe;
-+ char *name, *s;
-+ const char *fullpath;
-+ int namesz, nameoff, vallen;
-+
-+ /* do nothing if no fixups */
-+ if (!tree->fixups)
-+ return;
-+
-+ /* 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 :<number> + '\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);
-+}
-+
- static void flatten_tree(struct node *tree, struct emitter *emit,
- void *etarget, struct data *strbuf,
- struct version_info *vi)
-@@ -310,6 +508,10 @@ static void flatten_tree(struct node *tr
- flatten_tree(child, emit, etarget, strbuf, vi);
- }
-
-+ emit_symbols_node(tree, emit, etarget, strbuf, vi);
-+ emit_local_fixups_node(tree, emit, etarget, strbuf, vi);
-+ emit_fixups_node(tree, emit, etarget, strbuf, vi);
-+
- emit->endnode(etarget, tree->labels);
- }
-
---- 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-g25efc119"
--- /dev/null
+From 46852dc03df7e271cedafb6405ab3b47fa57fc1f Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+Date: Wed, 3 Dec 2014 13:23:28 +0200
+Subject: [PATCH 178/304] 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 <pantelis.antoniou@konsulko.com>
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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
+
+--- /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).
+--- 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
+--- 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
+--- /dev/null
++++ b/drivers/of/configfs.c
+@@ -0,0 +1,314 @@
++/*
++ * Configfs entries for device-tree
++ *
++ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * 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 <linux/ctype.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/configfs.h>
++#include <linux/types.h>
++#include <linux/stat.h>
++#include <linux/limits.h>
++#include <linux/file.h>
++#include <linux/vmalloc.h>
++#include <linux/firmware.h>
++
++#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);
+++ /dev/null
-From 7499c16ca9e47899ff65070af57588a8f541f707 Mon Sep 17 00:00:00 2001
-From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
-Date: Thu, 22 Oct 2015 23:30:04 +0300
-Subject: [PATCH 178/232] 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 <pantelis.antoniou@konsulko.com>
-[hch: folded a fix from Geert Uytterhoeven <geert+renesas@glider.be>]
-[hch: a few tiny updates based on review feedback]
-Signed-off-by: Christoph Hellwig <hch@lst.de>
----
- 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(-)
-
---- a/Documentation/filesystems/configfs/configfs.txt
-+++ b/Documentation/filesystems/configfs/configfs.txt
-@@ -51,15 +51,27 @@ configfs tree is always there, whether m
- 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
- 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
- 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
---- 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
- 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
- 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;
---- a/fs/configfs/dir.c
-+++ b/fs/configfs/dir.c
-@@ -255,6 +255,12 @@ static void configfs_init_file(struct in
- 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 c
- 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_
- {
- 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_
- 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);
---- a/fs/configfs/file.c
-+++ b/fs/configfs/file.c
-@@ -28,6 +28,7 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/mutex.h>
-+#include <linux/vmalloc.h>
- #include <asm/uaccess.h>
-
- #include <linux/configfs.h>
-@@ -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, c
- 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 * ino
- 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 * ino
- * 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 * ino
- * 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 * ino
- }
- 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 * ino
- 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
- 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_fi
- .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_i
- 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;
-+}
---- a/fs/configfs/inode.c
-+++ b/fs/configfs/inode.c
-@@ -218,7 +218,7 @@ const unsigned char * configfs_get_name(
- 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;
- }
---- 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##a
- .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).
+++ /dev/null
-From 54ca6e08ce89f5e33de78db7deff727c12513397 Mon Sep 17 00:00:00 2001
-From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
-Date: Wed, 3 Dec 2014 13:23:28 +0200
-Subject: [PATCH 179/232] 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 <pantelis.antoniou@konsulko.com>
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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
-
---- /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).
---- 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
---- 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
---- /dev/null
-+++ b/drivers/of/configfs.c
-@@ -0,0 +1,314 @@
-+/*
-+ * Configfs entries for device-tree
-+ *
-+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
-+ *
-+ * 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 <linux/ctype.h>
-+#include <linux/cpu.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_fdt.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/configfs.h>
-+#include <linux/types.h>
-+#include <linux/stat.h>
-+#include <linux/limits.h>
-+#include <linux/file.h>
-+#include <linux/vmalloc.h>
-+#include <linux/firmware.h>
-+
-+#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);
--- /dev/null
+From 3006a98a1fe05d8a9ed22c5ffa3387bcffd3e6e7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 13 Mar 2015 12:43:36 +0000
+Subject: [PATCH 179/304] Protect __release_resource against resources without
+ parents
+
+Without this patch, removing a device tree overlay can crash here.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ kernel/resource.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -237,6 +237,12 @@ static int __release_resource(struct res
+ {
+ 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;
--- /dev/null
+From 37896fb199519698fe090107f60013158738ea4a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 13 Mar 2015 20:00:21 +0000
+Subject: [PATCH 180/304] BCM270X_DT: Add a .dtbo target, use for overlays
+
+Change the filenames and extensions to keep the pre-DDT style of
+overlay (<name>-overlay.dtb) distinct from new ones that use a
+different style of local fixups (<name>.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 <phil@raspberrypi.org>
+---
+ arch/arm/boot/.gitignore | 2 +-
+ arch/arm/boot/dts/overlays/Makefile | 135 +++++++++++++++++-------------------
+ scripts/Makefile.lib | 10 +++
+ 3 files changed, 76 insertions(+), 71 deletions(-)
+
+--- a/arch/arm/boot/.gitignore
++++ b/arch/arm/boot/.gitignore
+@@ -3,4 +3,4 @@ zImage
+ xipImage
+ bootpImage
+ uImage
+-*.dtb
++*.dtb*
+--- 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
+--- 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
+++ /dev/null
-From c841449374b2acd024ae8971bbd2474c6ba27309 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 13 Mar 2015 12:43:36 +0000
-Subject: [PATCH 180/232] Protect __release_resource against resources without
- parents
-
-Without this patch, removing a device tree overlay can crash here.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- kernel/resource.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/kernel/resource.c
-+++ b/kernel/resource.c
-@@ -237,6 +237,12 @@ static int __release_resource(struct res
- {
- 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;
+++ /dev/null
-From 420e1b8c5cec3bbccd4c260ff836a71e54df084e Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 13 Mar 2015 20:00:21 +0000
-Subject: [PATCH 181/232] BCM270X_DT: Add a .dtbo target, use for overlays
-
-Change the filenames and extensions to keep the pre-DDT style of
-overlay (<name>-overlay.dtb) distinct from new ones that use a
-different style of local fixups (<name>.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 <phil@raspberrypi.org>
----
- arch/arm/boot/.gitignore | 2 +-
- arch/arm/boot/dts/overlays/Makefile | 135 +++++++++++++++++-------------------
- scripts/Makefile.lib | 10 +++
- 3 files changed, 76 insertions(+), 71 deletions(-)
-
---- a/arch/arm/boot/.gitignore
-+++ b/arch/arm/boot/.gitignore
-@@ -3,4 +3,4 @@ zImage
- xipImage
- bootpImage
- uImage
--*.dtb
-+*.dtb*
---- 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
---- 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
--- /dev/null
+From c5a86acf2f24c46c59eb5290c45cee0893b6bbb9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 29 May 2015 11:18:58 +0100
+Subject: [PATCH 181/304] scripts/knlinfo: Decode DDTK atom
+
+Show the DDTK atom as being a boolean.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ scripts/knlinfo | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- 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
--- /dev/null
+From e942b566a2a1d3b104fcbaa1af2613bae32ed80a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 29 May 2015 11:48:59 +0100
+Subject: [PATCH 182/304] Enable Dynamic Device Tree for bcmrpi_defconfig and
+ bcm2709_defconfig
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/configs/bcm2709_defconfig | 2 +-
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- 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
+--- 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
+++ /dev/null
-From e56b2ead4021e94eb15f8dd7240c607fe61ce57f Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 29 May 2015 11:18:58 +0100
-Subject: [PATCH 182/232] scripts/knlinfo: Decode DDTK atom
-
-Show the DDTK atom as being a boolean.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- scripts/knlinfo | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- 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
+++ /dev/null
-From aa7d45428dba9267190fa17a424db693628856f6 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 29 May 2015 11:48:59 +0100
-Subject: [PATCH 183/232] Enable Dynamic Device Tree for bcmrpi_defconfig and
- bcm2709_defconfig
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- arch/arm/configs/bcm2709_defconfig | 2 +-
- arch/arm/configs/bcmrpi_defconfig | 1 +
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
---- 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
---- 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
--- /dev/null
+From 5db216e0816c390542f813c0b3f6fbcc1c4e63c8 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Sun, 13 Mar 2016 16:14:44 +0000
+Subject: [PATCH 183/304] SQUASH: Add CONFIG_OF_CONFIGFS to bcmrpi_defconfig
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/configs/bcmrpi_defconfig | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- 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
+++ /dev/null
-From 293a0e05a554b39c3d3587f0631c495485ec903b Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Sun, 13 Mar 2016 16:14:44 +0000
-Subject: [PATCH 184/232] SQUASH: Add CONFIG_OF_CONFIGFS to bcmrpi_defconfig
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- arch/arm/configs/bcmrpi_defconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- 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
--- /dev/null
+From 987d8a609678ea5c04664d02adb1f408e5b62a8b Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 14 Mar 2016 16:56:54 +0000
+Subject: [PATCH 184/304] dts, kbuild: dtbs_install installs .dtbo files too
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ scripts/Makefile.dtbinst | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- 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)
--- /dev/null
+From 8a55d01fb0245d518898960123c3cb1b96dd9080 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Mar 2016 14:10:29 +0000
+Subject: [PATCH 185/304] 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 <phil@raspberrypi.org>
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 50 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 46 insertions(+), 4 deletions(-)
+
+--- 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_interna
+ 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(
+ 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
+
+ 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
+ /* 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_comp
+ 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 {
+++ /dev/null
-From e948b371fbb724b7d715dee41c0db5ef5a028a13 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 14 Mar 2016 16:56:54 +0000
-Subject: [PATCH 185/232] dts, kbuild: dtbs_install installs .dtbo files too
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- scripts/Makefile.dtbinst | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
---- 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)
--- /dev/null
+From 7066f3b1bf7ddf5bf68815e8a53bef8ecf8e0e52 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Mar 2016 15:49:16 +0000
+Subject: [PATCH 186/304] BCM270X_DT: Add labels to spidev nodes
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(-)
+
+--- 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>;
+--- 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>;
+--- 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>;
+--- 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>;
+--- 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>;
+++ /dev/null
-From c215c0d855343400b53ae2ec8b015a3f4a3eb27e Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Mar 2016 14:10:29 +0000
-Subject: [PATCH 186/232] 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 <phil@raspberrypi.org>
----
- drivers/mmc/host/bcm2835-sdhost.c | 50 +++++++++++++++++++++++++++++++++++----
- 1 file changed, 46 insertions(+), 4 deletions(-)
-
---- 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_interna
- 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(
- 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
-
- 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
- /* 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_comp
- 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 {
+++ /dev/null
-From 605effb19bd81578339b66e642ff5e5d4f86babd Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Mar 2016 15:49:16 +0000
-Subject: [PATCH 187/232] BCM270X_DT: Add labels to spidev nodes
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(-)
-
---- 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>;
---- 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>;
---- 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>;
---- 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>;
---- 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>;
--- /dev/null
+From 33de40886f08899a438a12e26c50d0e6d025775e Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Mar 2016 16:27:26 +0000
+Subject: [PATCH 187/304] 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(-)
+
+--- 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 */
+--- 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 {
+--- 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 {
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 */
+--- 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 {
+--- 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 */
+--- 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 {
--- /dev/null
+From fd1aeca317a5c84e700ca5198e8759e9063661a6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 15 Mar 2016 16:41:37 +0000
+Subject: [PATCH 188/304] BCM270X_DT: Build and document the wittypi overlay
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(-)
+
+--- 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.d
+ 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)
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -920,6 +920,14 @@ Params: gpiopin GPIO for
+ extpullup GPIO for external pullup (default "5")
+
+
++Name: wittypi
++Info: Configures the wittypi RTC module.
++Load: dtoverlay=wittypi,<param>=<val>
++Params: led_gpio GPIO for LED (default "17")
++ led_trigger Choose which activity the LED tracks (default
++ "default-on")
++
++
+ Troubleshooting
+ ===============
+
+--- 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";
+ };
+
+++ /dev/null
-From 666d717a56639ca89b6bba18a325b1c530683fac Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Mar 2016 16:27:26 +0000
-Subject: [PATCH 188/232] 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(-)
-
---- 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 */
---- 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 {
---- 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 {
---- 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 */
---- 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 */
---- 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 */
---- 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 */
---- 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 */
---- 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 */
---- 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 */
---- 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 */
---- 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 {
---- 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 */
---- 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 {
+++ /dev/null
-From 3259cf06132d0987314a37f39b0b18750b127eba Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 15 Mar 2016 16:41:37 +0000
-Subject: [PATCH 189/232] BCM270X_DT: Build and document the wittypi overlay
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(-)
-
---- 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.d
- 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)
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -920,6 +920,14 @@ Params: gpiopin GPIO for
- extpullup GPIO for external pullup (default "5")
-
-
-+Name: wittypi
-+Info: Configures the wittypi RTC module.
-+Load: dtoverlay=wittypi,<param>=<val>
-+Params: led_gpio GPIO for LED (default "17")
-+ led_trigger Choose which activity the LED tracks (default
-+ "default-on")
-+
-+
- Troubleshooting
- ===============
-
---- 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";
- };
-
--- /dev/null
+From 438d786eb8499167a46ca9736e470d1943d272b8 Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Tue, 15 Mar 2016 21:13:39 +0100
+Subject: [PATCH 189/304] 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 <hias@horus.com>
+---
+ scripts/dtc/checks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/scripts/dtc/checks.c
++++ b/scripts/dtc/checks.c
+@@ -523,6 +523,7 @@ static void fixup_phandle_references(str
+ 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;
--- /dev/null
+From 061113506e00c7a93a98c6b50c6a811e6dfe329b Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 16 Mar 2016 08:35:06 +0000
+Subject: [PATCH 190/304] BCM270X_DT: Add dtparam for uart1
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(+)
+
+--- 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";
+--- 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";
+--- 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";
+--- 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";
+--- 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";
+--- 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")
+
+++ /dev/null
-From cd57bc1baa3d03746b6bf78996cbd46460558c28 Mon Sep 17 00:00:00 2001
-From: Matthias Reichl <hias@horus.com>
-Date: Tue, 15 Mar 2016 21:13:39 +0100
-Subject: [PATCH 190/232] 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 <hias@horus.com>
----
- scripts/dtc/checks.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/scripts/dtc/checks.c
-+++ b/scripts/dtc/checks.c
-@@ -523,6 +523,7 @@ static void fixup_phandle_references(str
- 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;
+++ /dev/null
-From d171758951c497d0cd557040884ffb4efd231c3c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 16 Mar 2016 08:35:06 +0000
-Subject: [PATCH 191/232] BCM270X_DT: Add dtparam for uart1
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(+)
-
---- 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";
---- 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";
---- 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";
---- 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";
---- 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";
---- 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")
-
--- /dev/null
+From 2c9f391fa4dd8b666fe66ba961b29bd2b0a645d5 Mon Sep 17 00:00:00 2001
+From: Przemek Rudy <prudy1@o2.pl>
+Date: Fri, 11 Mar 2016 22:41:26 +0100
+Subject: [PATCH 191/304] dwc-overlay: Use label so overrides can apply.
+
+---
+ arch/arm/boot/dts/overlays/dwc2-overlay.dts | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- 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";
+ };
+ };
--- /dev/null
+From 1b6ead4b4b409136e21beed9b2c51ce71b348cf6 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 22 Jan 2016 13:06:39 -0800
+Subject: [PATCH 192/304] drm/vc4: Add a debugfs node for tracking execution
+ state.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ 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(+)
+
+--- 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},
+--- 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
+ 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;
+--- 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)
+ {
+++ /dev/null
-From 916634f9a59abd7f0de793ac5b523a89c882dbdf Mon Sep 17 00:00:00 2001
-From: Przemek Rudy <prudy1@o2.pl>
-Date: Fri, 11 Mar 2016 22:41:26 +0100
-Subject: [PATCH 192/232] dwc-overlay: Use label so overrides can apply.
-
----
- arch/arm/boot/dts/overlays/dwc2-overlay.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- 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";
- };
- };
+++ /dev/null
-From b30fecff47b19f93b4d20706bc6c6e6c0b972344 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Fri, 22 Jan 2016 13:06:39 -0800
-Subject: [PATCH 193/232] drm/vc4: Add a debugfs node for tracking execution
- state.
-
-Signed-off-by: Eric Anholt <eric@anholt.net>
----
- 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(+)
-
---- 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},
---- 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
- 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;
---- 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)
- {
--- /dev/null
+From 072d5f91f60b8732af5c3529cbad1cad0eda798f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 13:03:33 -0800
+Subject: [PATCH 193/304] drm/vc4: Include vc4_drm.h in uapi in downstream
+ build.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ include/uapi/drm/Kbuild | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- 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
+++ /dev/null
-From 64da292638fcacae979a5e8b3239969ec4275eb9 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 13:03:33 -0800
-Subject: [PATCH 194/232] drm/vc4: Include vc4_drm.h in uapi in downstream
- build.
-
-Signed-off-by: Eric Anholt <eric@anholt.net>
----
- include/uapi/drm/Kbuild | 1 +
- 1 file changed, 1 insertion(+)
-
---- 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
--- /dev/null
+From 12ddf64c85deb1d1261bdde36c128cd1a178a4d7 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 13:05:00 -0800
+Subject: [PATCH 194/304] 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 <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- 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
+ 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);
--- /dev/null
+From 0361731aa4eddac6e10bad6aa0386bb10ae7c221 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 13:52:41 -0800
+Subject: [PATCH 195/304] 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 <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_render_cl.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- 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_
+ 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_
+ 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);
+++ /dev/null
-From 4b02ed240cad8575c197d01d083a10e398f768bd Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 13:05:00 -0800
-Subject: [PATCH 195/232] 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 <eric@anholt.net>
----
- drivers/gpu/drm/vc4/vc4_gem.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- 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
- 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);
+++ /dev/null
-From 7ff02c91259682b40b5ce8a90f114925d71572c0 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 13:52:41 -0800
-Subject: [PATCH 196/232] 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 <eric@anholt.net>
----
- drivers/gpu/drm/vc4/vc4_render_cl.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
---- 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_
- 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_
- 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);
--- /dev/null
+From f832d2e9a9b142e2bf7ab5de8154aa6f992651a0 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 14:13:12 -0800
+Subject: [PATCH 196/304] 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 <eric@anholt.net>
+---
+ 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(-)
+
+--- 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_
+ 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_
+ * 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 *fil
+ 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_devic
+ * 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_de
+ }
+
+ 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,
+--- 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, stru
+ }
+
+ 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;
+--- 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
+ 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;
+ }
+--- 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_
+ 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);
+
+--- 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_AR
+ 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. */
--- /dev/null
+From 516e9685df7152891b08710c8722cbfe5257b8b9 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 14:32:41 -0800
+Subject: [PATCH 197/304] 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 <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- 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 *de
+ 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
+++ /dev/null
-From d6211c47e6671faf74389dbcbe29454c5997defb Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 14:13:12 -0800
-Subject: [PATCH 197/232] 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 <eric@anholt.net>
----
- 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(-)
-
---- 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_
- 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_
- * 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 *fil
- 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_devic
- * 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_de
- }
-
- 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,
---- 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, stru
- }
-
- 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;
---- 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
- 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;
- }
---- 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_
- 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);
-
---- 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_AR
- 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. */
--- /dev/null
+From ed499ca6841fc64d564d100cb31b30aba9b4d40f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 25 Jan 2016 14:33:50 -0800
+Subject: [PATCH 198/304] 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 <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- 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 *de
+ 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;
+ }
+
+++ /dev/null
-From 39e77e9d67511ac9bfbb00ab471fc7b0374dcdf6 Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 14:32:41 -0800
-Subject: [PATCH 198/232] 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 <eric@anholt.net>
----
- drivers/gpu/drm/vc4/vc4_gem.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- 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 *de
- 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
--- /dev/null
+From 5304c73254ae50ae4dbd06938e5d594516742930 Mon Sep 17 00:00:00 2001
+From: campag <dave-lowe@ntlworld.com>
+Date: Wed, 24 Feb 2016 16:45:42 +0000
+Subject: [PATCH 199/304] 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
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -709,6 +709,27 @@ Params: overclock_50 SD Clock
+ 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,<param>=<val>
++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,<param>=<val>
+--- /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";
++ };
++};
+++ /dev/null
-From a9221f160c28301850d5368d283c751b18950f2a Mon Sep 17 00:00:00 2001
-From: Eric Anholt <eric@anholt.net>
-Date: Mon, 25 Jan 2016 14:33:50 -0800
-Subject: [PATCH 199/232] 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 <eric@anholt.net>
----
- drivers/gpu/drm/vc4/vc4_gem.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- 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 *de
- 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;
- }
-
+++ /dev/null
-From 19d839cafdd5ddb1233df5be821d702e655d2d16 Mon Sep 17 00:00:00 2001
-From: campag <dave-lowe@ntlworld.com>
-Date: Wed, 24 Feb 2016 16:45:42 +0000
-Subject: [PATCH 200/232] 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
-
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -709,6 +709,27 @@ Params: overclock_50 SD Clock
- 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,<param>=<val>
-+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,<param>=<val>
---- /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";
-+ };
-+};
--- /dev/null
+From b23b33abf4487eb6008994f3cf5a3f39841add70 Mon Sep 17 00:00:00 2001
+From: Michael Heimpold <michael.heimpold@i2se.com>
+Date: Fri, 29 Jan 2016 12:00:37 +0100
+Subject: [PATCH 201/304] 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 <stefan.wahren@i2se.com>
+Signed-off-by: Michael Heimpold <michael.heimpold@i2se.com>
+---
+ 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
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -48,6 +48,7 @@ dtbo-$(RPI_DT_OVERLAYS) += pitft28-resis
+ 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -625,6 +625,14 @@ Params: pin Output p
+ clock PWM clock frequency (informational)
+
+
++Name: qca7000
++Info: I2SE's Evaluation Board for PLC Stamp micro
++Load: dtoverlay=qca7000,<param>=<val>
++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
+--- /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";
++ };
++};
+--- 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
+--- 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
+++ /dev/null
-From 76d3e26b821b2490619f4762b5f604e77636fdb1 Mon Sep 17 00:00:00 2001
-From: Michael Heimpold <michael.heimpold@i2se.com>
-Date: Fri, 29 Jan 2016 12:00:37 +0100
-Subject: [PATCH 202/232] 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 <stefan.wahren@i2se.com>
-Signed-off-by: Michael Heimpold <michael.heimpold@i2se.com>
----
- 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
-
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -48,6 +48,7 @@ dtbo-$(RPI_DT_OVERLAYS) += pitft28-resis
- 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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -625,6 +625,14 @@ Params: pin Output p
- clock PWM clock frequency (informational)
-
-
-+Name: qca7000
-+Info: I2SE's Evaluation Board for PLC Stamp micro
-+Load: dtoverlay=qca7000,<param>=<val>
-+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
---- /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";
-+ };
-+};
---- 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
---- 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
--- /dev/null
+From abd2da573a492fe1c64fa7a269b121046b2f3acf Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 9 Mar 2016 13:28:24 +0000
+Subject: [PATCH 202/304] 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 <phil@raspberrypi.org>
+---
+ include/linux/serial_core.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -397,7 +397,7 @@ int uart_resume_port(struct uart_driver
+ 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;
+ }
--- /dev/null
+From 067bdb295322ba1ba0288e36a8e5db0935f384c1 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 17 Mar 2016 10:16:16 +0000
+Subject: [PATCH 203/304] pi3-miniuart-bt-overlay: Correct and clarify info
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(-)
+
+--- 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: <None>
+
+--- 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
+++ /dev/null
-From c9276ae7cfecbd1df477ff31116682e72dd6d8f7 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 9 Mar 2016 13:28:24 +0000
-Subject: [PATCH 203/232] 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 <phil@raspberrypi.org>
----
- include/linux/serial_core.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/include/linux/serial_core.h
-+++ b/include/linux/serial_core.h
-@@ -397,7 +397,7 @@ int uart_resume_port(struct uart_driver
- 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;
- }
+++ /dev/null
-From b7bbcabcce3f31bca25f17d68fb9eb0e2e045184 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 17 Mar 2016 10:16:16 +0000
-Subject: [PATCH 204/232] pi3-miniuart-bt-overlay: Correct and clarify info
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(-)
-
---- 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: <None>
-
---- 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
--- /dev/null
+From cbce83f2cade68b80c6004e97135d37728d9c30f Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 17 Mar 2016 10:41:56 +0000
+Subject: [PATCH 204/304] 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(-)
+
+--- 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";
+ };
+ };
+--- 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";
+ };
+ };
--- /dev/null
+From 5c6d93ef128041a46ceb25a3c458a60405e9c60d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 18 Mar 2016 13:06:29 +0000
+Subject: [PATCH 205/304] BCM270X_DT: Switch Compute Module to MMC
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- 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";
+ };
+ };
+++ /dev/null
-From 05a2610389127e4cfcc2b9afdec83e1176b205bc Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 17 Mar 2016 10:41:56 +0000
-Subject: [PATCH 205/232] 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(-)
-
---- 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";
- };
- };
---- 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";
- };
- };
+++ /dev/null
-From 985c06bd528e49fd44155c3da0c6107c46d947cc Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Fri, 18 Mar 2016 13:06:29 +0000
-Subject: [PATCH 206/232] BCM270X_DT: Switch Compute Module to MMC
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 17 ++++++++---------
- 1 file changed, 8 insertions(+), 9 deletions(-)
-
---- 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";
- };
- };
--- /dev/null
+From d23d96422dd69238fa10d24ecb0323427359ef30 Mon Sep 17 00:00:00 2001
+From: P33M <P33M@github.com>
+Date: Fri, 18 Mar 2016 17:38:37 +0000
+Subject: [PATCH 206/304] 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(-)
+
+--- 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 *
+ {
+ 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 *
+ 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;
+ }
+
+++ /dev/null
-From 4558f488edf41daddd4bceed975f3af8cee89033 Mon Sep 17 00:00:00 2001
-From: P33M <P33M@github.com>
-Date: Fri, 18 Mar 2016 17:38:37 +0000
-Subject: [PATCH 207/232] 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(-)
-
---- 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 *
- {
- 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 *
- 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;
- }
-
--- /dev/null
+From cd141372388a05c228ce0552cfc6edc3bf3b65d6 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 21 Mar 2016 15:38:38 +0000
+Subject: [PATCH 207/304] 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 <popcornmix@gmail.com>
+---
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- 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;
+
+-unsigned short fiq_fsm_mask = 0x07;
++unsigned short fiq_fsm_mask = 0x0F;
+
+ /**
+ * This function shows the Driver Version.
--- /dev/null
+From f26e0311778ed510125e3d83ebf22109dc986835 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Sat, 19 Mar 2016 16:51:37 +0000
+Subject: [PATCH 208/304] BCM270X_DT: Remove explicit claiming of UART pins
+
+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.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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(-)
+
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -57,9 +57,9 @@
+ };
+
+ uart1_pins: uart1_pins {
+- brcm,pins = <14 15>;
+- brcm,function = <2>; /* alt5=UART1 */
+- brcm,pull = <0 2>;
++ brcm,pins;
++ brcm,function;
++ brcm,pull;
+ };
+ };
+
+--- 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;
+ };
+ };
+
+--- 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>;
+- };
+-
+- uart1_pins: uart1_pins {
+- brcm,pins = <32 33>;
+- brcm,function = <2>; /* alt5=UART1 */
+- brcm,pull = <0 2>;
+- };
++ 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";
+++ /dev/null
-From 7956536a3d78ba0ef8ec990651b315664ed70f90 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Mon, 21 Mar 2016 15:38:38 +0000
-Subject: [PATCH 208/232] 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 <popcornmix@gmail.com>
----
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- 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;
-
--unsigned short fiq_fsm_mask = 0x07;
-+unsigned short fiq_fsm_mask = 0x0F;
-
- /**
- * This function shows the Driver Version.
+++ /dev/null
-From adc10c5da2b83bbc8c893e3a745b43890f27e2ac Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Sat, 19 Mar 2016 16:51:37 +0000
-Subject: [PATCH 209/232] BCM270X_DT: Remove explicit claiming of UART pins
-
-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.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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(-)
-
---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
-+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
-@@ -57,9 +57,9 @@
- };
-
- uart1_pins: uart1_pins {
-- brcm,pins = <14 15>;
-- brcm,function = <2>; /* alt5=UART1 */
-- brcm,pull = <0 2>;
-+ brcm,pins;
-+ brcm,function;
-+ brcm,pull;
- };
- };
-
---- 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;
- };
- };
-
---- 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>;
-- };
--
-- uart1_pins: uart1_pins {
-- brcm,pins = <32 33>;
-- brcm,function = <2>; /* alt5=UART1 */
-- brcm,pull = <0 2>;
-- };
-+ 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";
--- /dev/null
+From da94c9df9e9b77422bdecfb2af64a8c10061d206 Mon Sep 17 00:00:00 2001
+From: Rodrigo Freire <rfreire@rf.usersys.redhat.com>
+Date: Tue, 22 Mar 2016 12:40:33 -0300
+Subject: [PATCH 209/304] lirc_rpi: Lower IR reception error to debug
+
+Lowers a IR reception error condition message to KERNEL_DEBUG
+---
+ drivers/staging/media/lirc/lirc_rpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- 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, vo
+ 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);
+++ /dev/null
-From 79e3ee1d325bf1aea9e255127dd132265b734efe Mon Sep 17 00:00:00 2001
-From: Rodrigo Freire <rfreire@rf.usersys.redhat.com>
-Date: Tue, 22 Mar 2016 12:40:33 -0300
-Subject: [PATCH 210/232] lirc_rpi: Lower IR reception error to debug
-
-Lowers a IR reception error condition message to KERNEL_DEBUG
----
- drivers/staging/media/lirc/lirc_rpi.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- 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, vo
- 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);
--- /dev/null
+From 397f801c082178a6df9ca198d2143f2f4bd0a275 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 23 Mar 2016 14:16:25 +0000
+Subject: [PATCH 210/304] 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 <phil@raspberrypi.org>
+---
+ .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- 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,
+ 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);
+@@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason,
+ 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,
+ 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,
--- /dev/null
+From 500de79a1d1785b7d7b189897412ce17f3c34869 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 23 Mar 2016 15:57:14 +0000
+Subject: [PATCH 211/304] BCM270X_DT: Add pi3-act-led overlay
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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
+
+--- 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-$(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
+--- 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
+ [ 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,<param>=<val>
++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
+--- /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";
++ };
++};
+++ /dev/null
-From 26eb219f0645eb9848887ca25c0a073a9a40d852 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 23 Mar 2016 14:16:25 +0000
-Subject: [PATCH 211/232] 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 <phil@raspberrypi.org>
----
- .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
---- 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,
- 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);
-@@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason,
- 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,
- 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,
+++ /dev/null
-From 10cd986960d2ad1fd881fa3338af40e612076ba4 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 23 Mar 2016 15:57:14 +0000
-Subject: [PATCH 212/232] BCM270X_DT: Add pi3-act-led overlay
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- 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
-
---- 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-$(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
---- 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
- [ 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,<param>=<val>
-+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
---- /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";
-+ };
-+};
--- /dev/null
+From 523feff6ae02ad31e7d35aa07685ea1d37eae9f1 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 23 Mar 2016 20:53:47 +0000
+Subject: [PATCH 212/304] 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 <phil@raspberrypi.org>
+---
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- 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
+ } 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);
+ }
--- /dev/null
+From 031f69058a890ac8df5834cde9e0f6301b9a75d3 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 213/304] 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
+
+--- 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -360,6 +360,12 @@ Params: i2c_gpio_sda GPIO use
+ (default "2" = ~100kHz)
+
+
++Name: i2c-mux-pca9548a
++Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm
++Load: dtoverlay=i2c-mux-pca9548a,<param>=<val>
++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,<param>=<val>
+--- /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";
++ };
++};
+--- 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
+--- 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
+++ /dev/null
-From 2faaa2ccef9e4c595bd26f14285c225ceea6097e Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 23 Mar 2016 20:53:47 +0000
-Subject: [PATCH 213/232] 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 <phil@raspberrypi.org>
----
- drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- 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
- } 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);
- }
+++ /dev/null
-From 09e64d48934eb812bab8667dcce81d0387092644 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 214/232] 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
-
---- 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
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -360,6 +360,12 @@ Params: i2c_gpio_sda GPIO use
- (default "2" = ~100kHz)
-
-
-+Name: i2c-mux-pca9548a
-+Info: Adds support for an NXP PCA9548A I2C multiplexer on i2c_arm
-+Load: dtoverlay=i2c-mux-pca9548a,<param>=<val>
-+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,<param>=<val>
---- /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";
-+ };
-+};
---- 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
---- 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
--- /dev/null
+From b36d418b125935c8dcdb51b129fb3ec4c0e2658c Mon Sep 17 00:00:00 2001
+From: Nicolas Boullis <nboullis@debian.org>
+Date: Wed, 23 Mar 2016 23:40:15 +0100
+Subject: [PATCH 214/304] 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(+)
+
+--- 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
+ Load: dtoverlay=i2c-rtc,<param>=<val>
+ 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 t
+
+ 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
+--- 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";
+ };
+ };
+++ /dev/null
-From 6ec2115ccc87288132b345ab2cd05aed2d3beb97 Mon Sep 17 00:00:00 2001
-From: Nicolas Boullis <nboullis@debian.org>
-Date: Wed, 23 Mar 2016 23:40:15 +0100
-Subject: [PATCH 215/232] 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(+)
-
---- 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
- Load: dtoverlay=i2c-rtc,<param>=<val>
- 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 t
-
- 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
---- 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";
- };
- };
--- /dev/null
+From 250a9cb281e520a1c22ff9dd86d2fb44fddb4fe9 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 29 Mar 2016 15:32:30 +0100
+Subject: [PATCH 215/304] 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 <phil@raspberrypi.org>
+---
+ arch/arm/lib/uaccess_with_memcpy.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- 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;
+
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+@@ -217,7 +218,9 @@ __copy_from_user_memcpy(void *to, const
+ 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;
+@@ -261,9 +264,14 @@ arm_copy_from_user(void *to, const void
+ * 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
--- /dev/null
+From 13a986c782983be4fcc2c780dd73bfd428cc82b3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 30 Mar 2016 16:33:09 +0100
+Subject: [PATCH 216/304] 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 <phil@raspberrypi.org>
+---
+ drivers/mmc/host/Kconfig | 1 +
+ drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++++++++++++++++++++++++++++------
+ 2 files changed, 119 insertions(+), 22 deletions(-)
+
+--- 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.
+
+--- a/drivers/mmc/host/bcm2835-sdhost.c
++++ b/drivers/mmc/host/bcm2835-sdhost.c
+@@ -50,6 +50,10 @@
+ #include <linux/of_dma.h>
+ #include <linux/time.h>
+ #include <linux/workqueue.h>
++#include <linux/cpufreq.h>
++#include <linux/semaphore.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
+
+ #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
+
+ 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(in
+ 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 bcm
+ 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 bcm
+ 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 bcm
+ 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(struc
+ (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(struc
+ 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(struc
+ 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_finis
+ 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_finis
+
+ 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 bcm28
+ 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 p
+ 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 p
+ 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
+
+ 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);
+++ /dev/null
-From a160443a0d967ea6394cd0d1b7a0ab8ef2da3ff1 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Tue, 29 Mar 2016 15:32:30 +0100
-Subject: [PATCH 216/232] 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 <phil@raspberrypi.org>
----
- arch/arm/lib/uaccess_with_memcpy.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
---- 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;
-
- if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
-@@ -217,7 +218,9 @@ __copy_from_user_memcpy(void *to, const
- 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;
-@@ -261,9 +264,14 @@ arm_copy_from_user(void *to, const void
- * 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
--- /dev/null
+From 83d447c00bc185c49b621aebc850abab989c96ef Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 30 Mar 2016 17:07:15 +0100
+Subject: [PATCH 217/304] BCM270X_DT: Document hazards of sdhost overlay
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/overlays/README | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -712,7 +712,11 @@ Params: <None>
+
+
+ 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,<param>=<val>
+ Params: overclock_50 Clock (in MHz) to use when the MMC framework
+ requests 50MHz
+@@ -771,6 +775,8 @@ Params: overclock_50 SD Clock
+
+ 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,<param>=<val>
+ Params: overclock_50 Clock (in MHz) to use when the MMC framework
+ requests 50MHz
+++ /dev/null
-From 4b89d07fd299a0f4e25321920cb74416ba2e638e Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 30 Mar 2016 16:33:09 +0100
-Subject: [PATCH 217/232] 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 <phil@raspberrypi.org>
----
- drivers/mmc/host/Kconfig | 1 +
- drivers/mmc/host/bcm2835-sdhost.c | 140 ++++++++++++++++++++++++++++++++------
- 2 files changed, 119 insertions(+), 22 deletions(-)
-
---- 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.
-
---- a/drivers/mmc/host/bcm2835-sdhost.c
-+++ b/drivers/mmc/host/bcm2835-sdhost.c
-@@ -50,6 +50,10 @@
- #include <linux/of_dma.h>
- #include <linux/time.h>
- #include <linux/workqueue.h>
-+#include <linux/cpufreq.h>
-+#include <linux/semaphore.h>
-+#include <soc/bcm2835/raspberrypi-firmware.h>
-+
-
- #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
-
- 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(in
- 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 bcm
- 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 bcm
- 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 bcm
- 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(struc
- (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(struc
- 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(struc
- 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_finis
- 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_finis
-
- 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 bcm28
- 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 p
- 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 p
- 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
-
- 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);
+++ /dev/null
-From 73f4b796019a7e9b7314851657aebd5f92f3ff75 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 30 Mar 2016 17:07:15 +0100
-Subject: [PATCH 218/232] BCM270X_DT: Document hazards of sdhost overlay
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- arch/arm/boot/dts/overlays/README | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -712,7 +712,11 @@ Params: <None>
-
-
- 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,<param>=<val>
- Params: overclock_50 Clock (in MHz) to use when the MMC framework
- requests 50MHz
-@@ -771,6 +775,8 @@ Params: overclock_50 SD Clock
-
- 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,<param>=<val>
- Params: overclock_50 Clock (in MHz) to use when the MMC framework
- requests 50MHz
--- /dev/null
+From 65d0fed05912509d60d94fdba8debe1a095c73a6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 30 Mar 2016 17:23:15 +0100
+Subject: [PATCH 218/304] 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 <phil@raspberrypi.org>
+---
+ drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct d
+ 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) {
--- /dev/null
+From c486342fb4b09f5d676a213cdf7e366b72e528f3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 30 Mar 2016 20:18:38 +0100
+Subject: [PATCH 219/304] 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(-)
+
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -307,12 +307,7 @@ static ssize_t store_io_is_busy(struct d
+ 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) {
+++ /dev/null
-From 2af1218a8a0220fec526f64d03977b8451afb4c8 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 30 Mar 2016 17:23:15 +0100
-Subject: [PATCH 219/232] 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 <phil@raspberrypi.org>
----
- drivers/cpufreq/cpufreq_ondemand.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/cpufreq/cpufreq_ondemand.c
-+++ b/drivers/cpufreq/cpufreq_ondemand.c
-@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct d
- 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) {
+++ /dev/null
-From c353af0f83220068c10f6593b1767576b9b6cc18 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 30 Mar 2016 20:18:38 +0100
-Subject: [PATCH 220/232] 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(-)
-
---- a/drivers/cpufreq/cpufreq_ondemand.c
-+++ b/drivers/cpufreq/cpufreq_ondemand.c
-@@ -307,12 +307,7 @@ static ssize_t store_io_is_busy(struct d
- 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) {
--- /dev/null
+From 645e1a7bb2e9ab5d3a12fd8eac7b553ee8122ba9 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Thu, 7 Jan 2016 15:50:22 +0100
+Subject: [PATCH 220/304] 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 <daniel@iogearbox.net>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/sch_generic.h | 9 +++++++++
+ net/sched/cls_bpf.c | 6 +-----
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -408,6 +408,15 @@ bool tcf_destroy(struct tcf_proto *tp, b
+ 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)
+ {
+--- a/net/sched/cls_bpf.c
++++ b/net/sched/cls_bpf.c
+@@ -79,12 +79,8 @@ static int cls_bpf_classify(struct sk_bu
+ 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)))
+++ /dev/null
-From a436f21ba8e57517734c24d2b571d5aed888be36 Mon Sep 17 00:00:00 2001
-From: Daniel Borkmann <daniel@iogearbox.net>
-Date: Thu, 7 Jan 2016 15:50:22 +0100
-Subject: [PATCH 221/232] 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 <daniel@iogearbox.net>
-Acked-by: Alexei Starovoitov <ast@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- include/net/sch_generic.h | 9 +++++++++
- net/sched/cls_bpf.c | 6 +-----
- 2 files changed, 10 insertions(+), 5 deletions(-)
-
---- a/include/net/sch_generic.h
-+++ b/include/net/sch_generic.h
-@@ -408,6 +408,15 @@ bool tcf_destroy(struct tcf_proto *tp, b
- 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)
- {
---- a/net/sched/cls_bpf.c
-+++ b/net/sched/cls_bpf.c
-@@ -79,12 +79,8 @@ static int cls_bpf_classify(struct sk_bu
- 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)))
--- /dev/null
+From d2b23892c9f7b04b68280889bea7823ba555b325 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 31 Mar 2016 15:44:53 +0100
+Subject: [PATCH 222/304] 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 <phil@raspberrypi.org>
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++++++++----------------
+ 1 file changed, 88 insertions(+), 64 deletions(-)
+
+--- 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(in
+ 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 bcm
+ 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);
++ /* 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;
+
+- 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;
++ 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" : "");
+ }
+ }
+- 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);
+-
+- 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(struc
+
+ 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_callba
+ 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(struc
+ 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_finis
+
+ /* 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 p
+ 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 p
+ 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 p
+ 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");
--- /dev/null
+From 829cedfe9323ee329b031ac23efd913a586ae7bb Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 4 Apr 2016 12:35:32 +0100
+Subject: [PATCH 223/304] 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(-)
+
+--- 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(in
+ 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 bcm
+ 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 = 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);
+
+- 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" : "");
++ 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));
++ }
+
+- if (host->clock == 50*MHZ)
+- host->prev_overclock_50 = host->overclock_50;
++ host->cdiv = div;
++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
+
+- bcm2835_sdhost_select_clock(host, host->cur_clk_idx);
++ /* Set the timeout to 500ms */
++ 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);
+ }
+
+ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -1677,9 +1657,6 @@ static void bcm2835_sdhost_request(struc
+
+ 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_callba
+ 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(struc
+ 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_finis
+
+ /* 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 p
+ 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 p
+ 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 p
+ 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");
--- /dev/null
+From bfe59970666dc1035c2cf79967de51df9ecf734a Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 4 Apr 2016 12:35:51 +0100
+Subject: [PATCH 224/304] 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(-)
+
+--- 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.
+
+--- a/drivers/mmc/host/bcm2835-sdhost.c
++++ b/drivers/mmc/host/bcm2835-sdhost.c
+@@ -50,10 +50,6 @@
+ #include <linux/of_dma.h>
+ #include <linux/time.h>
+ #include <linux/workqueue.h>
+-#include <linux/cpufreq.h>
+-#include <linux/semaphore.h>
+-#include <soc/bcm2835/raspberrypi-firmware.h>
+-
+
+ #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
+
+ 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(in
+ 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 bcm
+ 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 bcm
+ 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 bcm
+ 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(struc
+ (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(struc
+ 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(struc
+ 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_finis
+ 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_finis
+
+ 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 bcm28
+ 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 p
+ 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 p
+ 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
+
+ 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);
+++ /dev/null
-From 20260462773366a5734e5268dae0a4c179a21a2d Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 31 Mar 2016 15:44:53 +0100
-Subject: [PATCH 224/232] 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 <phil@raspberrypi.org>
----
- drivers/mmc/host/bcm2835-sdhost.c | 152 ++++++++++++++++++++++----------------
- 1 file changed, 88 insertions(+), 64 deletions(-)
-
---- 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(in
- 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 bcm
- 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);
-+ /* 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;
-
-- 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;
-+ 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" : "");
- }
- }
-- 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);
--
-- 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(struc
-
- 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_callba
- 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(struc
- 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_finis
-
- /* 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 p
- 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 p
- 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 p
- 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");
+++ /dev/null
-From 9524a87ecce1788c8f77d2b86deee65d11b4190d Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 4 Apr 2016 12:35:32 +0100
-Subject: [PATCH 225/232] 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(-)
-
---- 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(in
- 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 bcm
- 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 = 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);
-
-- 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" : "");
-+ 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));
-+ }
-
-- if (host->clock == 50*MHZ)
-- host->prev_overclock_50 = host->overclock_50;
-+ host->cdiv = div;
-+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
-
-- bcm2835_sdhost_select_clock(host, host->cur_clk_idx);
-+ /* Set the timeout to 500ms */
-+ 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);
- }
-
- static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
-@@ -1677,9 +1657,6 @@ static void bcm2835_sdhost_request(struc
-
- 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_callba
- 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(struc
- 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_finis
-
- /* 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 p
- 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 p
- 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 p
- 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");
--- /dev/null
+From c249254c1a0195566538a15dbfe2459da2f16643 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 4 Apr 2016 16:03:18 +0100
+Subject: [PATCH 225/304] 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
+core clock. This removes the need to use the performance governor or
+to enable io_is_busy on the on-demand governor in order to get the
+best SD performance.
+
+N.B. As SD clocks must be an integer divisor of the core clock, it is
+possible that the SD clock for "turbo" mode can be different (even
+lower) than "normal" mode.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 120 ++++++++++++++++++-----------
+ include/soc/bcm2835/raspberrypi-firmware.h | 1 +
+ 2 files changed, 74 insertions(+), 47 deletions(-)
+
+--- a/drivers/mmc/host/bcm2835-sdhost.c
++++ b/drivers/mmc/host/bcm2835-sdhost.c
+@@ -50,6 +50,7 @@
+ #include <linux/of_dma.h>
+ #include <linux/time.h>
+ #include <linux/workqueue.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
+
+ #define DRIVER_NAME "sdhost-bcm2835"
+
+@@ -183,6 +184,7 @@ struct bcm2835_host {
+ unsigned int use_sbc:1; /* Send CMD23 */
+
+ unsigned int debug:1; /* Enable debug output */
++ unsigned int firmware_sets_cdiv:1; /* Let the firmware manage the clock */
+
+ /*DMA part*/
+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
+@@ -430,7 +432,7 @@ static void bcm2835_sdhost_reset_interna
+ host->clock = 0;
+ host->sectors = 0;
+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
+- bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
++ bcm2835_sdhost_write(host, SDCDIV_MAX_CDIV, SDCDIV);
+ mmiowb();
+ }
+
+@@ -1534,62 +1536,75 @@ void bcm2835_sdhost_set_clock(struct bcm
+
+ host->mmc->actual_clock = 0;
+
+- if (clock < 100000) {
+- /* Can't stop the clock, but make it as slow as possible
+- * to show willing
+- */
+- host->cdiv = SDCDIV_MAX_CDIV;
+- bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
+- return;
+- }
+-
+- div = host->max_clk / clock;
+- if (div < 2)
+- div = 2;
+- if ((host->max_clk / div) > clock)
+- div++;
+- div -= 2;
++ if (host->firmware_sets_cdiv) {
++ u32 msg[3] = { clock, 0, 0 };
+
+- if (div > SDCDIV_MAX_CDIV)
+- div = SDCDIV_MAX_CDIV;
++ rpi_firmware_property(rpi_firmware_get(NULL),
++ RPI_FIRMWARE_SET_SDHOST_CLOCK,
++ &msg, sizeof(msg));
+
+- clock = host->max_clk / (div + 2);
+- host->mmc->actual_clock = clock;
++ clock = max(msg[1], msg[2]);
++ } else {
++ if (clock < 100000) {
++ /* Can't stop the clock, but make it as slow as
++ * possible to show willing
++ */
++ host->cdiv = SDCDIV_MAX_CDIV;
++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
++ return;
++ }
++
++ div = host->max_clk / clock;
++ if (div < 2)
++ div = 2;
++ if ((host->max_clk / div) > clock)
++ div++;
++ div -= 2;
++
++ if (div > SDCDIV_MAX_CDIV)
++ div = SDCDIV_MAX_CDIV;
++
++ clock = host->max_clk / (div + 2);
++
++ host->cdiv = div;
++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
++
++ 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,
++ 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 */
+- host->overclock_50 = (clock/MHZ);
+-
+- if (clock != host->overclock) {
+- pr_warn("%s: overclocking to %dHz\n",
+- mmc_hostname(host->mmc), clock);
+- host->overclock = clock;
++ if (input_clock == 50 * MHZ) {
++ if (clock > input_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));
+ }
+ }
+- 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);
+
+ /* Set the timeout to 500ms */
+- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT);
++ bcm2835_sdhost_write(host, 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);
++ host->mmc->actual_clock = clock;
+ }
+
+ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -1704,11 +1719,6 @@ static void bcm2835_sdhost_set_ios(struc
+
+ log_event("IOS<", ios->clock, 0);
+
+- if (!ios->clock || ios->clock != host->clock) {
+- bcm2835_sdhost_set_clock(host, ios->clock);
+- host->clock = ios->clock;
+- }
+-
+ /* set bus width */
+ host->hcfg &= ~SDHCFG_WIDE_EXT_BUS;
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+@@ -1721,6 +1731,11 @@ static void bcm2835_sdhost_set_ios(struc
+
+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
+
++ if (!ios->clock || ios->clock != host->clock) {
++ bcm2835_sdhost_set_clock(host, ios->clock);
++ host->clock = ios->clock;
++ }
++
+ mmiowb();
+
+ spin_unlock_irqrestore(&host->lock, flags);
+@@ -1953,6 +1968,7 @@ static int bcm2835_sdhost_probe(struct p
+ struct bcm2835_host *host;
+ struct mmc_host *mmc;
+ const __be32 *addr;
++ u32 msg[3];
+ int ret;
+
+ pr_debug("bcm2835_sdhost_probe\n");
+@@ -2058,6 +2074,16 @@ static int bcm2835_sdhost_probe(struct p
+ else
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+
++ msg[0] = 0;
++ msg[1] = ~0;
++ msg[2] = ~0;
++
++ rpi_firmware_property(rpi_firmware_get(NULL),
++ RPI_FIRMWARE_SET_SDHOST_CLOCK,
++ &msg, sizeof(msg));
++
++ host->firmware_sets_cdiv = (msg[1] != ~0);
++
+ ret = bcm2835_sdhost_add_host(host);
+ if (ret)
+ goto err;
+--- 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,
--- /dev/null
+From 274a8e5251c2c12345b3069a3539ff27b220cb2a Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 4 Apr 2016 19:52:27 +0100
+Subject: [PATCH 226/304] 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(-)
+
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct d
+ 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) {
+++ /dev/null
-From 28035a98dc9820c065dc64ad3016a1f71a9911f2 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 4 Apr 2016 12:35:51 +0100
-Subject: [PATCH 226/232] 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(-)
-
---- 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.
-
---- a/drivers/mmc/host/bcm2835-sdhost.c
-+++ b/drivers/mmc/host/bcm2835-sdhost.c
-@@ -50,10 +50,6 @@
- #include <linux/of_dma.h>
- #include <linux/time.h>
- #include <linux/workqueue.h>
--#include <linux/cpufreq.h>
--#include <linux/semaphore.h>
--#include <soc/bcm2835/raspberrypi-firmware.h>
--
-
- #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
-
- 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(in
- 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 bcm
- 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 bcm
- 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 bcm
- 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(struc
- (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(struc
- 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(struc
- 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_finis
- 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_finis
-
- 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 bcm28
- 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 p
- 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 p
- 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
-
- 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);
+++ /dev/null
-From 08532d242d7702ae0add95096aa49c5e96e066e2 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 4 Apr 2016 16:03:18 +0100
-Subject: [PATCH 227/232] 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
-core clock. This removes the need to use the performance governor or
-to enable io_is_busy on the on-demand governor in order to get the
-best SD performance.
-
-N.B. As SD clocks must be an integer divisor of the core clock, it is
-possible that the SD clock for "turbo" mode can be different (even
-lower) than "normal" mode.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- drivers/mmc/host/bcm2835-sdhost.c | 120 ++++++++++++++++++-----------
- include/soc/bcm2835/raspberrypi-firmware.h | 1 +
- 2 files changed, 74 insertions(+), 47 deletions(-)
-
---- a/drivers/mmc/host/bcm2835-sdhost.c
-+++ b/drivers/mmc/host/bcm2835-sdhost.c
-@@ -50,6 +50,7 @@
- #include <linux/of_dma.h>
- #include <linux/time.h>
- #include <linux/workqueue.h>
-+#include <soc/bcm2835/raspberrypi-firmware.h>
-
- #define DRIVER_NAME "sdhost-bcm2835"
-
-@@ -183,6 +184,7 @@ struct bcm2835_host {
- unsigned int use_sbc:1; /* Send CMD23 */
-
- unsigned int debug:1; /* Enable debug output */
-+ unsigned int firmware_sets_cdiv:1; /* Let the firmware manage the clock */
-
- /*DMA part*/
- struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
-@@ -430,7 +432,7 @@ static void bcm2835_sdhost_reset_interna
- host->clock = 0;
- host->sectors = 0;
- bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
-- bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
-+ bcm2835_sdhost_write(host, SDCDIV_MAX_CDIV, SDCDIV);
- mmiowb();
- }
-
-@@ -1534,62 +1536,75 @@ void bcm2835_sdhost_set_clock(struct bcm
-
- host->mmc->actual_clock = 0;
-
-- if (clock < 100000) {
-- /* Can't stop the clock, but make it as slow as possible
-- * to show willing
-- */
-- host->cdiv = SDCDIV_MAX_CDIV;
-- bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
-- return;
-- }
--
-- div = host->max_clk / clock;
-- if (div < 2)
-- div = 2;
-- if ((host->max_clk / div) > clock)
-- div++;
-- div -= 2;
-+ if (host->firmware_sets_cdiv) {
-+ u32 msg[3] = { clock, 0, 0 };
-
-- if (div > SDCDIV_MAX_CDIV)
-- div = SDCDIV_MAX_CDIV;
-+ rpi_firmware_property(rpi_firmware_get(NULL),
-+ RPI_FIRMWARE_SET_SDHOST_CLOCK,
-+ &msg, sizeof(msg));
-
-- clock = host->max_clk / (div + 2);
-- host->mmc->actual_clock = clock;
-+ clock = max(msg[1], msg[2]);
-+ } else {
-+ if (clock < 100000) {
-+ /* Can't stop the clock, but make it as slow as
-+ * possible to show willing
-+ */
-+ host->cdiv = SDCDIV_MAX_CDIV;
-+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
-+ return;
-+ }
-+
-+ div = host->max_clk / clock;
-+ if (div < 2)
-+ div = 2;
-+ if ((host->max_clk / div) > clock)
-+ div++;
-+ div -= 2;
-+
-+ if (div > SDCDIV_MAX_CDIV)
-+ div = SDCDIV_MAX_CDIV;
-+
-+ clock = host->max_clk / (div + 2);
-+
-+ host->cdiv = div;
-+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
-+
-+ 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,
-+ 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 */
-- host->overclock_50 = (clock/MHZ);
--
-- if (clock != host->overclock) {
-- pr_warn("%s: overclocking to %dHz\n",
-- mmc_hostname(host->mmc), clock);
-- host->overclock = clock;
-+ if (input_clock == 50 * MHZ) {
-+ if (clock > input_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));
- }
- }
-- 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);
-
- /* Set the timeout to 500ms */
-- bcm2835_sdhost_write(host, host->mmc->actual_clock/2, SDTOUT);
-+ bcm2835_sdhost_write(host, 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);
-+ host->mmc->actual_clock = clock;
- }
-
- static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
-@@ -1704,11 +1719,6 @@ static void bcm2835_sdhost_set_ios(struc
-
- log_event("IOS<", ios->clock, 0);
-
-- if (!ios->clock || ios->clock != host->clock) {
-- bcm2835_sdhost_set_clock(host, ios->clock);
-- host->clock = ios->clock;
-- }
--
- /* set bus width */
- host->hcfg &= ~SDHCFG_WIDE_EXT_BUS;
- if (ios->bus_width == MMC_BUS_WIDTH_4)
-@@ -1721,6 +1731,11 @@ static void bcm2835_sdhost_set_ios(struc
-
- bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
-
-+ if (!ios->clock || ios->clock != host->clock) {
-+ bcm2835_sdhost_set_clock(host, ios->clock);
-+ host->clock = ios->clock;
-+ }
-+
- mmiowb();
-
- spin_unlock_irqrestore(&host->lock, flags);
-@@ -1953,6 +1968,7 @@ static int bcm2835_sdhost_probe(struct p
- struct bcm2835_host *host;
- struct mmc_host *mmc;
- const __be32 *addr;
-+ u32 msg[3];
- int ret;
-
- pr_debug("bcm2835_sdhost_probe\n");
-@@ -2058,6 +2074,16 @@ static int bcm2835_sdhost_probe(struct p
- else
- mmc->caps |= MMC_CAP_4_BIT_DATA;
-
-+ msg[0] = 0;
-+ msg[1] = ~0;
-+ msg[2] = ~0;
-+
-+ rpi_firmware_property(rpi_firmware_get(NULL),
-+ RPI_FIRMWARE_SET_SDHOST_CLOCK,
-+ &msg, sizeof(msg));
-+
-+ host->firmware_sets_cdiv = (msg[1] != ~0);
-+
- ret = bcm2835_sdhost_add_host(host);
- if (ret)
- goto err;
---- 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,
--- /dev/null
+From acf428e77480d8c4fa0f13959fd347e45e7b2d1a Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 31 Mar 2016 16:49:52 +0100
+Subject: [PATCH 227/304] config: Enabled IPV6_SUBTREES
+
+---
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- 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
+--- 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
+++ /dev/null
-From 9f0a3f09ec2d80fed2781b341527ae6bd5666cd8 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Mon, 4 Apr 2016 19:52:27 +0100
-Subject: [PATCH 228/232] 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(-)
-
---- a/drivers/cpufreq/cpufreq_ondemand.c
-+++ b/drivers/cpufreq/cpufreq_ondemand.c
-@@ -307,7 +307,12 @@ static ssize_t store_io_is_busy(struct d
- 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) {
--- /dev/null
+From e27f96aeb0f516b87a284993951c2366ef24914d Mon Sep 17 00:00:00 2001
+From: Sam Nazarko <email@samnazarko.co.uk>
+Date: Fri, 1 Apr 2016 17:27:21 +0100
+Subject: [PATCH 228/304] add smsc95xx packetsize module_param
+
+Signed-off-by: Sam Nazarko <email@samnazarko.co.uk>
+---
+ drivers/net/usb/smsc95xx.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- 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
+
+ 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",
+++ /dev/null
-From ed825c0f1cfce352d446f33ef7f798134b8d6cb6 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Thu, 31 Mar 2016 16:49:52 +0100
-Subject: [PATCH 229/232] config: Enabled IPV6_SUBTREES
-
----
- arch/arm/configs/bcm2709_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 1 +
- 2 files changed, 2 insertions(+)
-
---- 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
---- 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
--- /dev/null
+From 45746412917e5d7f8298a6642788c9487737e25a Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 5 Apr 2016 19:40:12 +0100
+Subject: [PATCH 229/304] 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(-)
+
+--- 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();
+ }
+
+ /*
--- /dev/null
+From 893c530176f330b10ada8d8468788020bb8e2070 Mon Sep 17 00:00:00 2001
+From: HiassofT <github@hias.horus.com>
+Date: Wed, 6 Apr 2016 21:45:01 +0200
+Subject: [PATCH 230/304] 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 <hias@horus.com>
+---
+ drivers/dma/bcm2835-dma.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/dma/bcm2835-dma.c
++++ b/drivers/dma/bcm2835-dma.c
+@@ -679,8 +679,6 @@ static int bcm2835_dma_slave_config(stru
+ }
+
+ c->cfg = *cfg;
+- if (!c->dreq)
+- c->dreq = cfg->slave_id;
+
+ return 0;
+ }
+++ /dev/null
-From 3cea4c3fef10a33547949610d9a81ac9950b5be9 Mon Sep 17 00:00:00 2001
-From: Sam Nazarko <email@samnazarko.co.uk>
-Date: Fri, 1 Apr 2016 17:27:21 +0100
-Subject: [PATCH 230/232] add smsc95xx packetsize module_param
-
-Signed-off-by: Sam Nazarko <email@samnazarko.co.uk>
----
- drivers/net/usb/smsc95xx.c | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
---- 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
-
- 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",
--- /dev/null
+From 6273867fcddb010a62be4d1d5dcba124b1661681 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 231/304] 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
+
+--- 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -366,6 +366,12 @@ Load: dtoverlay=i2c-mux-pca9548a,<para
+ 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,<param>=<val>
++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,<param>=<val>
+--- /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";
++ };
++};
+--- 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
+--- 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
+++ /dev/null
-From 3ce05d6e2e4994e06ec73ff95969ae189681a8e8 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 5 Apr 2016 19:40:12 +0100
-Subject: [PATCH 231/232] 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(-)
-
---- 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();
- }
-
- /*
--- /dev/null
+From 6d33c5dd29d06ef631215ccf48d02592b227e103 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 8 Apr 2016 17:43:27 +0100
+Subject: [PATCH 232/304] 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 <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/Makefile | 2 +-
+ scripts/Makefile.lib | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- 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
+--- 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)
+++ /dev/null
-From ccb9ab7ba94d7b005f4fd820f1cb91caf73dbf89 Mon Sep 17 00:00:00 2001
-From: HiassofT <github@hias.horus.com>
-Date: Wed, 6 Apr 2016 21:45:01 +0200
-Subject: [PATCH 232/232] 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 <hias@horus.com>
----
- drivers/dma/bcm2835-dma.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/dma/bcm2835-dma.c
-+++ b/drivers/dma/bcm2835-dma.c
-@@ -679,8 +679,6 @@ static int bcm2835_dma_slave_config(stru
- }
-
- c->cfg = *cfg;
-- if (!c->dreq)
-- c->dreq = cfg->slave_id;
-
- return 0;
- }
--- /dev/null
+From 12b8bcf4d6d4a188ad2bcbae564f32fba4166f71 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 233/304] 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(-)
+
+--- 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, "Thre
+ * 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_m
+ {
+ 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_
+ 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(stru
+ 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(stru
+ 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 *f
+ 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 *f
+ 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 *fi
+ 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_devic
+ /* 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_devic
+ 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);
+- if (ret < 0)
+- goto unreg_dev;
+- dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
+-
+- /* mmal init */
+- ret = mmal_init(dev);
++ ret = vchiq_mmal_init(&instance);
+ if (ret < 0)
+- goto unreg_dev;
++ return ret;
+
+- /* 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;
++
++ for (camera = 0; camera < num_cameras; camera++) {
++ dev = kzalloc(sizeof(struct bm2835_mmal_dev), GFP_KERNEL);
++ if (!dev)
++ return -ENOMEM;
++
++ dev->camera_num = camera;
++
++ /* 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;
++
++ 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;
+
+- /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
+- mutex_init(&dev->mutex);
++ /* 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;
++ }
+
+- /* initialise video devices */
+- ret = bm2835_mmal_init_device(dev, &dev->vdev);
+- if (ret < 0)
+- goto unreg_dev;
++ v4l2_info(&dev->v4l2_dev,
++ "Broadcom 2835 MMAL video capture ver %s loaded.\n",
++ BM2835_MMAL_VERSION);
+
+- /* 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[camera] = dev;
+ }
+-
+- v4l2_info(&dev->v4l2_dev,
+- "Broadcom 2835 MMAL video capture ver %s loaded.\n",
+- BM2835_MMAL_VERSION);
+-
+- gdev = 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);
+--- 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_m
+ (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); \
++}
+--- 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_
+ &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 bm
+ 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_ctr
+ 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
+ },
+ {
+--- 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];
++};
--- /dev/null
+From 6a5e76800cf6d16d01b8e186806decc047590e46 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 11 Apr 2016 12:50:58 +0100
+Subject: [PATCH 234/304] 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
+is not a task.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/mmc/host/bcm2835-sdhost.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/host/bcm2835-sdhost.c
++++ b/drivers/mmc/host/bcm2835-sdhost.c
+@@ -185,6 +185,7 @@ struct bcm2835_host {
+
+ unsigned int debug:1; /* Enable debug output */
+ unsigned int firmware_sets_cdiv:1; /* Let the firmware manage the clock */
++ unsigned int reset_clock:1; /* Reset the clock fore the next request */
+
+ /*DMA part*/
+ struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
+@@ -1505,6 +1506,7 @@ void bcm2835_sdhost_set_clock(struct bcm
+ {
+ int div = 0; /* Initialized for compiler warning */
+ unsigned int input_clock = clock;
++ unsigned long flags;
+
+ if (host->debug)
+ pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock);
+@@ -1544,13 +1546,17 @@ void bcm2835_sdhost_set_clock(struct bcm
+ &msg, sizeof(msg));
+
+ clock = max(msg[1], msg[2]);
++ spin_lock_irqsave(&host->lock, flags);
+ } else {
++ spin_lock_irqsave(&host->lock, flags);
+ if (clock < 100000) {
+ /* Can't stop the clock, but make it as slow as
+ * possible to show willing
+ */
+ host->cdiv = SDCDIV_MAX_CDIV;
+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
+ return;
+ }
+
+@@ -1605,6 +1611,11 @@ void bcm2835_sdhost_set_clock(struct bcm
+ bcm2835_sdhost_write(host, clock/2, SDTOUT);
+
+ host->mmc->actual_clock = clock;
++ host->clock = input_clock;
++ host->reset_clock = 0;
++
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
+ }
+
+ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -1653,6 +1664,9 @@ static void bcm2835_sdhost_request(struc
+ (mrq->data->blocks > host->pio_limit))
+ bcm2835_sdhost_prepare_dma(host, mrq->data);
+
++ if (host->reset_clock)
++ bcm2835_sdhost_set_clock(host, host->clock);
++
+ spin_lock_irqsave(&host->lock, flags);
+
+ WARN_ON(host->mrq != NULL);
+@@ -1731,14 +1745,12 @@ static void bcm2835_sdhost_set_ios(struc
+
+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
+
+- if (!ios->clock || ios->clock != host->clock) {
+- bcm2835_sdhost_set_clock(host, ios->clock);
+- host->clock = ios->clock;
+- }
+-
+ mmiowb();
+
+ spin_unlock_irqrestore(&host->lock, flags);
++
++ if (!ios->clock || ios->clock != host->clock)
++ bcm2835_sdhost_set_clock(host, ios->clock);
+ }
+
+ static struct mmc_host_ops bcm2835_sdhost_ops = {
+@@ -1810,7 +1822,7 @@ static void bcm2835_sdhost_tasklet_finis
+ host->overclock_50--;
+ pr_warn("%s: reducing overclock due to errors\n",
+ mmc_hostname(host->mmc));
+- bcm2835_sdhost_set_clock(host,50*MHZ);
++ host->reset_clock = 1;
+ mrq->cmd->error = -EILSEQ;
+ mrq->cmd->retries = 1;
+ }
+@@ -1979,7 +1991,6 @@ static int bcm2835_sdhost_probe(struct p
+ 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 */
--- /dev/null
+From c4297390ed5ba3e78012fdc4d688710dc610dfe6 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 7 Apr 2016 12:44:24 +0100
+Subject: [PATCH 235/304] config: Enable CONFIG_IPV6_ROUTER_PREF for networks
+ with multiple routers
+
+---
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- 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
+--- 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
--- /dev/null
+From 4ccd590e7579d86778b73d381dfe9082e5df7518 Mon Sep 17 00:00:00 2001
+From: jochenberger <fooberger@gmail.com>
+Date: Thu, 7 Apr 2016 21:38:46 +0200
+Subject: [PATCH 236/304] 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(+)
+
+--- 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
+--- 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
--- /dev/null
+From bf0e127060951623a842c078b18585afff833227 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 12 Apr 2016 12:45:16 +0100
+Subject: [PATCH 237/304] 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(-)
+
+--- 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
+--- 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
--- /dev/null
+From 3533e797aaf506f1e81a3b53bf04ce9592005756 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 5 Apr 2016 13:01:54 +0100
+Subject: [PATCH 238/304] BCM270X_DT: Add dpi24 overlay
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ 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
+
+--- 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -213,6 +213,14 @@ Params: gpiopin GPIO con
+ (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: <None>
++
++
+ 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.
+--- /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 */
++ };
++ };
++ };
++};
--- /dev/null
+From 9f531cf57594be3a2d0eb4502c301ceadcc612cd Mon Sep 17 00:00:00 2001
+From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
+Date: Thu, 14 Apr 2016 00:57:33 +0100
+Subject: [PATCH 239/304] 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 <clive.messer@digitaldreamtime.co.uk>
+---
+ sound/soc/bcm/iqaudio-dac.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- 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_iqaudi
+
+ static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = {
+ {
+- .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_i
+
+ /* 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(str
+
+ 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(str
+
+ 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";
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
--- /dev/null
+From ddef7a853652982c2796db7f43d067d8487bc7e9 Mon Sep 17 00:00:00 2001
+From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
+Date: Thu, 14 Apr 2016 01:00:58 +0100
+Subject: [PATCH 240/304] 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 <clive.messer@digitaldreamtime.co.uk>
+---
+ 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
+
+--- 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -186,6 +186,26 @@ Params: cs SPI bus
+ 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,<param>=<val>
++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
+--- /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?";
++ };
++};
--- /dev/null
+From e064c9d7ec3c51b79c6fdb7f1ff3a07b246ea774 Mon Sep 17 00:00:00 2001
+From: Aaron Shaw <shawaj@gmail.com>
+Date: Thu, 7 Apr 2016 21:26:21 +0100
+Subject: [PATCH 241/304] 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
+
+--- 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -225,6 +225,32 @@ Load: dtoverlay=bmp085_i2c-sensor
+ Params: <None>
+
+
++Name: boomberry-dac
++Info: Configures the BoomBerry DAC HAT, Amp HAT, DAC Zero and Amp Zero audio
++ cards
++Load: dtoverlay=boomberry-dac,<param>=<val>
++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: <None>
++
++
+ Name: dht11
+ Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors
+ Also sometimes found with the part number(s) AM230x.
+--- /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?";
++ };
++};
+--- /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";
++ };
++ };
++ };
++};
+--- 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
+--- 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
+--- 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
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -8,6 +8,8 @@ snd-soc-hifiberry-dac-objs := hifiberry_
+ 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_D
+ 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
+--- /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 <info@crazy-audio.com>
++ * based on code by Florian Meier <florian.meier@koalo.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * 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 <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/jack.h>
++
++#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 <info@boomberry.co>");
++MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI DAC HAT Sound Card");
++MODULE_LICENSE("GPL v2");
+--- /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 <info@crazy-audio.com>
++ * based on code by Florian Meier <florian.meier@koalo.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * 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 <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/jack.h>
++
++#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 <info@boomberry.co>");
++MODULE_DESCRIPTION("ASoC Driver for BoomBerry PI Digi HAT Sound Card");
++MODULE_LICENSE("GPL v2");
--- /dev/null
+From 51fa2dcacc44cddf74afa790dd5ffbfbbbfe0afc Mon Sep 17 00:00:00 2001
+From: Aaron Shaw <shawaj@gmail.com>
+Date: Fri, 8 Apr 2016 00:06:00 +0100
+Subject: [PATCH 242/304] 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(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -435,6 +435,8 @@ Params: ds1307 Select t
+
+ ds3231 Select the DS3231 device
+
++ mcp7940x Select the MCP7940x device
++
+ mcp7941x Select the MCP7941x device
+
+ pcf2127 Select the PCF2127 device
+--- 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";
--- /dev/null
+From 162793500abf0310b5c9f2cf2bb3cf077390c065 Mon Sep 17 00:00:00 2001
+From: Jeremy McDermond <nh6z@nh6z.net>
+Date: Thu, 14 Apr 2016 09:39:20 -0700
+Subject: [PATCH 243/304] 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(-)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -854,7 +854,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS
+ 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
--- /dev/null
+From 62d7072d90d111836b7fcc57c3c2ff27faeeaee1 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 15 Apr 2016 10:48:39 +0100
+Subject: [PATCH 244/304] 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 <phil@raspberrypi.org>
+---
+ sound/soc/bcm/boomberry-dac.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- 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(st
+ {
+ 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);
+ }
--- /dev/null
+From e513a9bd4cd878b982ee8ac9dd6942e550c77307 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sun, 17 Apr 2016 04:44:47 -0700
+Subject: [PATCH 245/304] 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 <raj.khem@gmail.com>
+---
+ drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- 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 -------------------------------------- */
+
--- /dev/null
+From 3c64edb93a4702adc85dc1284a83d8c66ad850bf Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 18 Apr 2016 11:56:53 +0100
+Subject: [PATCH 246/304] 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 <phil@raspberrypi.org>
+---
+ scripts/mkknlimg | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- 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) ];
--- /dev/null
+From 16dced270b5dbcafa2d26096733c64a2f3e75071 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 19 Apr 2016 12:57:52 +0100
+Subject: [PATCH 247/304] bcm2835_thermal: Don't report unsupported trip type
+
+---
+ drivers/thermal/bcm2835-thermal.c | 34 +---------------------------------
+ 1 file changed, 1 insertion(+), 33 deletions(-)
+
+--- a/drivers/thermal/bcm2835-thermal.c
++++ b/drivers/thermal/bcm2835-thermal.c
+@@ -49,38 +49,8 @@ static int bcm2835_thermal_get_temp(stru
+ RPI_FIRMWARE_GET_TEMPERATURE);
+ }
+
+-static int bcm2835_thermal_get_max_temp(struct thermal_zone_device *tz,
+- int trip, int *temp)
+-{
+- /*
+- * The maximum safe temperature of the SoC.
+- * Overclock may be disabled above this temperature.
+- */
+- return bcm2835_thermal_get_property(tz, temp,
+- RPI_FIRMWARE_GET_MAX_TEMPERATURE);
+-}
+-
+-static int bcm2835_thermal_get_trip_type(struct thermal_zone_device *tz,
+- int trip, enum thermal_trip_type *type)
+-{
+- *type = THERMAL_TRIP_HOT;
+-
+- return 0;
+-}
+-
+-static int bcm2835_thermal_get_mode(struct thermal_zone_device *tz,
+- enum thermal_device_mode *mode)
+-{
+- *mode = THERMAL_DEVICE_ENABLED;
+-
+- return 0;
+-}
+-
+ static struct thermal_zone_device_ops ops = {
+ .get_temp = bcm2835_thermal_get_temp,
+- .get_trip_temp = bcm2835_thermal_get_max_temp,
+- .get_trip_type = bcm2835_thermal_get_trip_type,
+- .get_mode = bcm2835_thermal_get_mode,
+ };
+
+ static int bcm2835_thermal_probe(struct platform_device *pdev)
+@@ -90,17 +60,15 @@ static int bcm2835_thermal_probe(struct
+ struct thermal_zone_device *tz;
+
+ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
+-/* Remove comment when booting without Device Tree is no longer supported
+ if (!fw_np) {
+ dev_err(&pdev->dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+-*/
+ fw = rpi_firmware_get(fw_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
+- tz = thermal_zone_device_register("bcm2835_thermal", 1, 0, fw, &ops,
++ tz = thermal_zone_device_register("bcm2835_thermal", 0, 0, fw, &ops,
+ NULL, 0, 0);
+ if (IS_ERR(tz)) {
+ dev_err(&pdev->dev, "Failed to register the thermal device\n");
--- /dev/null
+From b617c25e48308f1901af150a9bc544254416d3c8 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 19 Apr 2016 13:55:29 +0100
+Subject: [PATCH 248/304] scripts/dtc: Only emit local fixups for overlays
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ scripts/dtc/checks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/scripts/dtc/checks.c
++++ b/scripts/dtc/checks.c
+@@ -514,7 +514,7 @@ static void fixup_phandle_references(str
+ }
+
+ /* 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));
--- /dev/null
+From 74f05075c9f20865651019acc76ac0cf957eebbf Mon Sep 17 00:00:00 2001
+From: wm4 <wm4@nowhere>
+Date: Tue, 19 Apr 2016 16:08:35 +0200
+Subject: [PATCH 249/304] bcm2835: do not require substream for accessing chmap
+ ctl
+
+Fixes alsasctl store/restore operation.
+---
+ sound/arm/bcm2835-ctl.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+--- a/sound/arm/bcm2835-ctl.c
++++ b/sound/arm/bcm2835-ctl.c
+@@ -489,8 +489,6 @@ static int snd_bcm2835_chmap_ctl_get(str
+ {
+ 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(str
+ 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];
+@@ -521,7 +514,6 @@ static int snd_bcm2835_chmap_ctl_get(str
+ while (cur < 8)
+ ucontrol->value.integer.value[cur++] = SNDRV_CHMAP_NA;
+
+-unlock:
+ mutex_unlock(&chip->audio_mutex);
+ return res;
+ }
+@@ -541,7 +533,7 @@ static int snd_bcm2835_chmap_ctl_put(str
+ return -EINTR;
+
+ if (!substream || !substream->runtime) {
+- res = -ENODEV;
++ /* ignore and return success for the sake of alsactl */
+ goto unlock;
+ }
+
--- /dev/null
+From 15d5b6a4a03c90b653719978831dc97633c6e332 Mon Sep 17 00:00:00 2001
+From: wm4 <wm4@nowhere>
+Date: Tue, 19 Apr 2016 16:29:41 +0200
+Subject: [PATCH 250/304] 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(-)
+
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -598,7 +598,16 @@ int bcm2835_audio_set_params(bcm2835_als
+ 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;
+ }
--- /dev/null
+From 0307b1dc72eb904e3e81b82050070e8bcfec6e01 Mon Sep 17 00:00:00 2001
+From: wm4 <wm4@nowhere>
+Date: Tue, 19 Apr 2016 16:38:03 +0200
+Subject: [PATCH 251/304] bcm2835: log which channel map is set
+
+---
+ sound/arm/bcm2835-vchiq.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -596,8 +596,11 @@ int bcm2835_audio_set_params(bcm2835_als
+ 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_als
+ 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;
--- /dev/null
+From 78c280c96a984805dfa19969e927c17ccada808f Mon Sep 17 00:00:00 2001
+From: Remi Pommarel <repk@triplefau.lt>
+Date: Sun, 6 Dec 2015 17:22:46 +0100
+Subject: [PATCH 252/304] clk: bcm2835: add a round up ability to the clock
+ divisor
+
+Make bcm2835_clock_choose_div to optionally round up the chosen MASH divisor
+so that the resulting average rate will not be higher than the requested one.
+
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Michael Turquette <mturquette@baylibre.com>
+(cherry picked from commit 9c95b32ca09364e4687b72c4e17b78dc1c420026)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1150,22 +1150,24 @@ static int bcm2835_clock_is_on(struct cl
+
+ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+ unsigned long rate,
+- unsigned long parent_rate)
++ unsigned long parent_rate,
++ bool round_up)
+ {
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ const struct bcm2835_clock_data *data = clock->data;
+- u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0);
++ u32 unused_frac_mask =
++ GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
+ u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
++ u64 rem;
+ u32 div;
+
+- do_div(temp, rate);
++ rem = do_div(temp, rate);
+ div = temp;
+
+- /* Round and mask off the unused bits */
+- if (unused_frac_mask != 0) {
+- div += unused_frac_mask >> 1;
+- div &= ~unused_frac_mask;
+- }
++ /* Round up and mask off the unused bits */
++ if (round_up && ((div & unused_frac_mask) != 0 || rem != 0))
++ div += unused_frac_mask + 1;
++ div &= ~unused_frac_mask;
+
+ /* Clamp to the limits. */
+ div = max(div, unused_frac_mask + 1);
+@@ -1204,7 +1206,7 @@ static long bcm2835_clock_round_rate(str
+ unsigned long *parent_rate)
+ {
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+- u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate);
++ u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate, false);
+
+ return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
+ }
+@@ -1273,7 +1275,7 @@ static int bcm2835_clock_set_rate(struct
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct bcm2835_cprman *cprman = clock->cprman;
+ const struct bcm2835_clock_data *data = clock->data;
+- u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate);
++ u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
+
+ cprman_write(cprman, data->div_reg, div);
+
--- /dev/null
+From f875d2424d83a76d4b3942263291917853d56158 Mon Sep 17 00:00:00 2001
+From: Remi Pommarel <repk@triplefau.lt>
+Date: Sun, 6 Dec 2015 17:22:47 +0100
+Subject: [PATCH 253/304] clk: bcm2835: Support for clock parent selection
+
+Some bcm2835 clocks used by hardware (like "PWM" or "H264") can have multiple
+parent clocks. These clocks divide the rate of a parent which can be selected by
+setting the proper bits in the clock control register.
+
+Previously all these parents where handled by a mux clock. But a mux clock
+cannot be used because updating clock control register to select parent needs a
+password to be xor'd with the parent index.
+
+This patch get rid of mux clock and make these clocks handle their own parent,
+allowing them to select the one to use.
+
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Michael Turquette <mturquette@baylibre.com>
+(cherry picked from commit 6d18b8adbe679b5947aa822b676efff230acc5f6)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 122 ++++++++++++++++++++++++++----------------
+ 1 file changed, 77 insertions(+), 45 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1201,16 +1201,6 @@ static long bcm2835_clock_rate_from_divi
+ return temp;
+ }
+
+-static long bcm2835_clock_round_rate(struct clk_hw *hw,
+- unsigned long rate,
+- unsigned long *parent_rate)
+-{
+- struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+- u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate, false);
+-
+- return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
+-}
+-
+ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+ {
+@@ -1282,13 +1272,75 @@ static int bcm2835_clock_set_rate(struct
+ return 0;
+ }
+
++static int bcm2835_clock_determine_rate(struct clk_hw *hw,
++ struct clk_rate_request *req)
++{
++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
++ struct clk_hw *parent, *best_parent = NULL;
++ unsigned long rate, best_rate = 0;
++ unsigned long prate, best_prate = 0;
++ size_t i;
++ u32 div;
++
++ /*
++ * Select parent clock that results in the closest but lower rate
++ */
++ for (i = 0; i < clk_hw_get_num_parents(hw); ++i) {
++ parent = clk_hw_get_parent_by_index(hw, i);
++ if (!parent)
++ continue;
++ prate = clk_hw_get_rate(parent);
++ div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
++ rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
++ if (rate > best_rate && rate <= req->rate) {
++ best_parent = parent;
++ best_prate = prate;
++ best_rate = rate;
++ }
++ }
++
++ if (!best_parent)
++ return -EINVAL;
++
++ req->best_parent_hw = best_parent;
++ req->best_parent_rate = best_prate;
++
++ req->rate = best_rate;
++
++ return 0;
++}
++
++static int bcm2835_clock_set_parent(struct clk_hw *hw, u8 index)
++{
++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
++ struct bcm2835_cprman *cprman = clock->cprman;
++ const struct bcm2835_clock_data *data = clock->data;
++ u8 src = (index << CM_SRC_SHIFT) & CM_SRC_MASK;
++
++ cprman_write(cprman, data->ctl_reg, src);
++ return 0;
++}
++
++static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
++{
++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
++ struct bcm2835_cprman *cprman = clock->cprman;
++ const struct bcm2835_clock_data *data = clock->data;
++ u32 src = cprman_read(cprman, data->ctl_reg);
++
++ return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
++}
++
++
+ static const struct clk_ops bcm2835_clock_clk_ops = {
+ .is_prepared = bcm2835_clock_is_on,
+ .prepare = bcm2835_clock_on,
+ .unprepare = bcm2835_clock_off,
+ .recalc_rate = bcm2835_clock_get_rate,
+ .set_rate = bcm2835_clock_set_rate,
+- .round_rate = bcm2835_clock_round_rate,
++ .determine_rate = bcm2835_clock_determine_rate,
++ .set_parent = bcm2835_clock_set_parent,
++ .get_parent = bcm2835_clock_get_parent,
+ };
+
+ static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
+@@ -1304,7 +1356,9 @@ static const struct clk_ops bcm2835_vpu_
+ .is_prepared = bcm2835_vpu_clock_is_on,
+ .recalc_rate = bcm2835_clock_get_rate,
+ .set_rate = bcm2835_clock_set_rate,
+- .round_rate = bcm2835_clock_round_rate,
++ .determine_rate = bcm2835_clock_determine_rate,
++ .set_parent = bcm2835_clock_set_parent,
++ .get_parent = bcm2835_clock_get_parent,
+ };
+
+ static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
+@@ -1398,45 +1452,23 @@ static struct clk *bcm2835_register_cloc
+ {
+ struct bcm2835_clock *clock;
+ struct clk_init_data init;
+- const char *parent;
++ const char *parents[1 << CM_SRC_BITS];
++ size_t i;
+
+ /*
+- * Most of the clock generators have a mux field, so we
+- * instantiate a generic mux as our parent to handle it.
++ * Replace our "xosc" references with the oscillator's
++ * actual name.
+ */
+- if (data->num_mux_parents) {
+- const char *parents[1 << CM_SRC_BITS];
+- int i;
+-
+- parent = devm_kasprintf(cprman->dev, GFP_KERNEL,
+- "mux_%s", data->name);
+- if (!parent)
+- return NULL;
+-
+- /*
+- * Replace our "xosc" references with the oscillator's
+- * actual name.
+- */
+- for (i = 0; i < data->num_mux_parents; i++) {
+- if (strcmp(data->parents[i], "xosc") == 0)
+- parents[i] = cprman->osc_name;
+- else
+- parents[i] = data->parents[i];
+- }
+-
+- clk_register_mux(cprman->dev, parent,
+- parents, data->num_mux_parents,
+- CLK_SET_RATE_PARENT,
+- cprman->regs + data->ctl_reg,
+- CM_SRC_SHIFT, CM_SRC_BITS,
+- 0, &cprman->regs_lock);
+- } else {
+- parent = data->parents[0];
++ for (i = 0; i < data->num_mux_parents; i++) {
++ if (strcmp(data->parents[i], "xosc") == 0)
++ parents[i] = cprman->osc_name;
++ else
++ parents[i] = data->parents[i];
+ }
+
+ memset(&init, 0, sizeof(init));
+- init.parent_names = &parent;
+- init.num_parents = 1;
++ init.parent_names = parents;
++ init.num_parents = data->num_mux_parents;
+ init.name = data->name;
+ init.flags = CLK_IGNORE_UNUSED;
+
--- /dev/null
+From 356488d8d56d35fe7316d829d1bfc7a7ec362d6c Mon Sep 17 00:00:00 2001
+From: Remi Pommarel <repk@triplefau.lt>
+Date: Sun, 6 Dec 2015 17:22:48 +0100
+Subject: [PATCH 254/304] clk: bcm2835: Add PWM clock support
+
+Register the pwm clock for bcm2835.
+
+Signed-off-by: Remi Pommarel <repk@triplefau.lt>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Michael Turquette <mturquette@baylibre.com>
+(cherry picked from commit cfbab8fbab9c330aca963095a439c451ac97c0dd)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 13 +++++++++++++
+ include/dt-bindings/clock/bcm2835.h | 3 ++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -807,6 +807,16 @@ static const struct bcm2835_clock_data b
+ .frac_bits = 8,
+ };
+
++static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
++ .name = "pwm",
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
++ .parents = bcm2835_clock_per_parents,
++ .ctl_reg = CM_PWMCTL,
++ .div_reg = CM_PWMDIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++};
++
+ struct bcm2835_pll {
+ struct clk_hw hw;
+ struct bcm2835_cprman *cprman;
+@@ -1586,6 +1596,9 @@ static int bcm2835_clk_probe(struct plat
+ cprman->regs + CM_PERIICTL, CM_GATE_BIT,
+ 0, &cprman->regs_lock);
+
++ clks[BCM2835_CLOCK_PWM] =
++ bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
++
+ return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+ &cprman->onecell);
+ }
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -43,5 +43,6 @@
+ #define BCM2835_CLOCK_TSENS 27
+ #define BCM2835_CLOCK_EMMC 28
+ #define BCM2835_CLOCK_PERI_IMAGE 29
++#define BCM2835_CLOCK_PWM 30
+
+-#define BCM2835_CLOCK_COUNT 30
++#define BCM2835_CLOCK_COUNT 31
--- /dev/null
+From de5c22eb349acaa6772dec9c0d56faa1d53932c1 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Tue, 22 Dec 2015 20:13:08 +0000
+Subject: [PATCH 255/304] clk: bcm2835: added missing clock register
+ definitions
+
+Added missing CTRL and DIV clock register definitions for:
+PCM, SLIM, TCNT, TEC, TD0, TD1
+
+Register information taken from:
+https://rawgit.com/msperl/rpi-registers/master/rpi-registers.html#CM
+which extracted the information from the header files shared by
+Broadcom/rpi foundation in this file:
+http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 2103a2156119b30f5924af2a1094227954be4617)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -88,10 +88,23 @@
+ #define CM_HSMDIV 0x08c
+ #define CM_OTPCTL 0x090
+ #define CM_OTPDIV 0x094
++#define CM_PCMCTL 0x098
++#define CM_PCMDIV 0x09c
+ #define CM_PWMCTL 0x0a0
+ #define CM_PWMDIV 0x0a4
++#define CM_SLIMCTL 0x0a8
++#define CM_SLIMDIV 0x0ac
+ #define CM_SMICTL 0x0b0
+ #define CM_SMIDIV 0x0b4
++/* no definition for 0x0b8 and 0x0bc */
++#define CM_TCNTCTL 0x0c0
++#define CM_TCNTDIV 0x0c4
++#define CM_TECCTL 0x0c8
++#define CM_TECDIV 0x0cc
++#define CM_TD0CTL 0x0d0
++#define CM_TD0DIV 0x0d4
++#define CM_TD1CTL 0x0d8
++#define CM_TD1DIV 0x0dc
+ #define CM_TSENSCTL 0x0e0
+ #define CM_TSENSDIV 0x0e4
+ #define CM_TIMERCTL 0x0e8
--- /dev/null
+From 2083f21dc65df8ce4fd887acd815551058b23e3e Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:17 +0000
+Subject: [PATCH 256/304] clk: bcm2835: pll_off should only update
+ CM_PLL_ANARST
+
+bcm2835_pll_off is currently assigning CM_PLL_ANARST to the control
+register, which may lose the other bits that are currently set by the
+clock dividers.
+
+It also now locks during the read/modify/write cycle of both
+registers.
+
+Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
+audio domain clocks")
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 6727f086cfe4ddcc651eb2bf4301abfcf619be06)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -913,8 +913,14 @@ static void bcm2835_pll_off(struct clk_h
+ struct bcm2835_cprman *cprman = pll->cprman;
+ const struct bcm2835_pll_data *data = pll->data;
+
+- cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
+- cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
++ spin_lock(&cprman->regs_lock);
++ cprman_write(cprman, data->cm_ctrl_reg,
++ cprman_read(cprman, data->cm_ctrl_reg) |
++ CM_PLL_ANARST);
++ cprman_write(cprman, data->a2w_ctrl_reg,
++ cprman_read(cprman, data->a2w_ctrl_reg) |
++ A2W_PLL_CTRL_PWRDN);
++ spin_unlock(&cprman->regs_lock);
+ }
+
+ static int bcm2835_pll_on(struct clk_hw *hw)
--- /dev/null
+From 39c3c0d0a8d038a692b95cc13e7d6acf2d04cf14 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:18 +0000
+Subject: [PATCH 257/304] clk: bcm2835: add locking to pll*_on/off methods
+
+Add missing locking to:
+* bcm2835_pll_divider_on
+* bcm2835_pll_divider_off
+to protect the read modify write cycle for the
+register access protecting both cm_reg and a2w_reg
+registers.
+
+Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
+audio domain clocks")
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit ec36a5c6682fdd5328abf15c3c67281bed0241d7)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1097,10 +1097,12 @@ static void bcm2835_pll_divider_off(stru
+ struct bcm2835_cprman *cprman = divider->cprman;
+ const struct bcm2835_pll_divider_data *data = divider->data;
+
++ spin_lock(&cprman->regs_lock);
+ cprman_write(cprman, data->cm_reg,
+ (cprman_read(cprman, data->cm_reg) &
+ ~data->load_mask) | data->hold_mask);
+ cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
++ spin_unlock(&cprman->regs_lock);
+ }
+
+ static int bcm2835_pll_divider_on(struct clk_hw *hw)
+@@ -1109,12 +1111,14 @@ static int bcm2835_pll_divider_on(struct
+ struct bcm2835_cprman *cprman = divider->cprman;
+ const struct bcm2835_pll_divider_data *data = divider->data;
+
++ spin_lock(&cprman->regs_lock);
+ cprman_write(cprman, data->a2w_reg,
+ cprman_read(cprman, data->a2w_reg) &
+ ~A2W_PLL_CHANNEL_DISABLE);
+
+ cprman_write(cprman, data->cm_reg,
+ cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
++ spin_unlock(&cprman->regs_lock);
+
+ return 0;
+ }
--- /dev/null
+From 54eece496d38fb701d9719169d9270d8798191cc Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:20 +0000
+Subject: [PATCH 258/304] clk: bcm2835: divider value has to be 1 or more
+
+Current clamping of a normal divider allows a value < 1 to be valid.
+
+A divider of < 1 would actually only be possible if we had a PLL...
+
+So this patch clamps the divider to 1.
+
+Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
+audio domain clocks")
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 997f16bd5d2e9b3456027f96fcadfe1e2bf12f4e)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1202,8 +1202,9 @@ static u32 bcm2835_clock_choose_div(stru
+ div += unused_frac_mask + 1;
+ div &= ~unused_frac_mask;
+
+- /* Clamp to the limits. */
+- div = max(div, unused_frac_mask + 1);
++ /* clamp to min divider of 1 */
++ div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS);
++ /* clamp to the highest possible fractional divider */
+ div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+ CM_DIV_FRAC_BITS - data->frac_bits));
+
--- /dev/null
+From c69411a2204c088d6a695c00a7e09fac0f8c0b89 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:21 +0000
+Subject: [PATCH 259/304] clk: bcm2835: correctly enable fractional clock
+ support
+
+The current driver calculates the clock divider with
+fractional support enabled.
+
+But it does not enable fractional support in the
+control register itself resulting in an integer only divider,
+but in clk_set_rate responds back the fractionally divided
+clock frequency.
+
+This patch enables fractional support in the control register
+whenever there is a fractional bit set in the requested clock divider.
+
+Mash clock limits are are also handled for the PWM clock
+applying the correct divider limits (2 and max_int) applicable to
+basic fractional divider support (mash order of 1).
+
+It also adds locking to protect the read/modify/write cycle of
+the register modification.
+
+Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
+audio domain clocks")
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 959ca92a3235fc4b17c1e18483fc390b3d612254)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 45 +++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 39 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -51,6 +51,7 @@
+ #define CM_GNRICCTL 0x000
+ #define CM_GNRICDIV 0x004
+ # define CM_DIV_FRAC_BITS 12
++# define CM_DIV_FRAC_MASK GENMASK(CM_DIV_FRAC_BITS - 1, 0)
+
+ #define CM_VPUCTL 0x008
+ #define CM_VPUDIV 0x00c
+@@ -128,6 +129,7 @@
+ # define CM_GATE BIT(CM_GATE_BIT)
+ # define CM_BUSY BIT(7)
+ # define CM_BUSYD BIT(8)
++# define CM_FRAC BIT(9)
+ # define CM_SRC_SHIFT 0
+ # define CM_SRC_BITS 4
+ # define CM_SRC_MASK 0xf
+@@ -647,6 +649,7 @@ struct bcm2835_clock_data {
+ u32 frac_bits;
+
+ bool is_vpu_clock;
++ bool is_mash_clock;
+ };
+
+ static const char *const bcm2835_clock_per_parents[] = {
+@@ -828,6 +831,7 @@ static const struct bcm2835_clock_data b
+ .div_reg = CM_PWMDIV,
+ .int_bits = 12,
+ .frac_bits = 12,
++ .is_mash_clock = true,
+ };
+
+ struct bcm2835_pll {
+@@ -1192,7 +1196,7 @@ static u32 bcm2835_clock_choose_div(stru
+ GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
+ u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
+ u64 rem;
+- u32 div;
++ u32 div, mindiv, maxdiv;
+
+ rem = do_div(temp, rate);
+ div = temp;
+@@ -1202,11 +1206,23 @@ static u32 bcm2835_clock_choose_div(stru
+ div += unused_frac_mask + 1;
+ div &= ~unused_frac_mask;
+
+- /* clamp to min divider of 1 */
+- div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS);
+- /* clamp to the highest possible fractional divider */
+- div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+- CM_DIV_FRAC_BITS - data->frac_bits));
++ /* different clamping limits apply for a mash clock */
++ if (data->is_mash_clock) {
++ /* clamp to min divider of 2 */
++ mindiv = 2 << CM_DIV_FRAC_BITS;
++ /* clamp to the highest possible integer divider */
++ maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS;
++ } else {
++ /* clamp to min divider of 1 */
++ mindiv = 1 << CM_DIV_FRAC_BITS;
++ /* clamp to the highest possible fractional divider */
++ maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
++ CM_DIV_FRAC_BITS - data->frac_bits);
++ }
++
++ /* apply the clamping limits */
++ div = max_t(u32, div, mindiv);
++ div = min_t(u32, div, maxdiv);
+
+ return div;
+ }
+@@ -1300,9 +1316,26 @@ static int bcm2835_clock_set_rate(struct
+ struct bcm2835_cprman *cprman = clock->cprman;
+ const struct bcm2835_clock_data *data = clock->data;
+ u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
++ u32 ctl;
++
++ spin_lock(&cprman->regs_lock);
++
++ /*
++ * Setting up frac support
++ *
++ * In principle it is recommended to stop/start the clock first,
++ * but as we set CLK_SET_RATE_GATE during registration of the
++ * clock this requirement should be take care of by the
++ * clk-framework.
++ */
++ ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
++ ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
++ cprman_write(cprman, data->ctl_reg, ctl);
+
+ cprman_write(cprman, data->div_reg, div);
+
++ spin_unlock(&cprman->regs_lock);
++
+ return 0;
+ }
+
--- /dev/null
+From 6bdeaf1c6d46819acb01de258574759e21f021d1 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:22 +0000
+Subject: [PATCH 260/304] clk: bcm2835: clean up coding style issues
+
+Fix all the checkpatch complaints for clk-bcm2835.c
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 6e1e60dacee7b32aef1468ea461b02e4c7a90a45)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -12,9 +12,6 @@
+ * 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, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ /**
+@@ -299,7 +296,7 @@
+ struct bcm2835_cprman {
+ struct device *dev;
+ void __iomem *regs;
+- spinlock_t regs_lock;
++ spinlock_t regs_lock; /* spinlock for all clocks */
+ const char *osc_name;
+
+ struct clk_onecell_data onecell;
+@@ -1340,7 +1337,7 @@ static int bcm2835_clock_set_rate(struct
+ }
+
+ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
+- struct clk_rate_request *req)
++ struct clk_rate_request *req)
+ {
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct clk_hw *parent, *best_parent = NULL;
+@@ -1398,7 +1395,6 @@ static u8 bcm2835_clock_get_parent(struc
+ return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
+ }
+
+-
+ static const struct clk_ops bcm2835_clock_clk_ops = {
+ .is_prepared = bcm2835_clock_is_on,
+ .prepare = bcm2835_clock_on,
--- /dev/null
+From 4da1c0d401cb719b7347117c226f4d4d95797972 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 14:20:15 +0000
+Subject: [PATCH 261/304] clk: bcm2835: expose raw clock-registers via debugfs
+
+For debugging purposes under some circumstance
+it helps to be able to see the actual clock registers.
+
+E.g: when looking at the clock divider it is helpful to
+see what the actual clock divider is.
+
+This patch exposes all the clock registers specific to each
+clock/pll/pll-divider via debugfs.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Acked-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 96bf9c69d5729781018a00f08e2ae395ec3346b4)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 101 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 101 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -37,6 +37,7 @@
+ #include <linux/clk-provider.h>
+ #include <linux/clkdev.h>
+ #include <linux/clk/bcm2835.h>
++#include <linux/debugfs.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+@@ -313,6 +314,27 @@ static inline u32 cprman_read(struct bcm
+ return readl(cprman->regs + reg);
+ }
+
++static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
++ struct debugfs_reg32 *regs, size_t nregs,
++ struct dentry *dentry)
++{
++ struct dentry *regdump;
++ struct debugfs_regset32 *regset;
++
++ regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL);
++ if (!regset)
++ return -ENOMEM;
++
++ regset->regs = regs;
++ regset->nregs = nregs;
++ regset->base = cprman->regs + base;
++
++ regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry,
++ regset);
++
++ return regdump ? 0 : -ENOMEM;
++}
++
+ /*
+ * These are fixed clocks. They're probably not all root clocks and it may
+ * be possible to turn them on and off but until this is mapped out better
+@@ -1040,6 +1062,36 @@ static int bcm2835_pll_set_rate(struct c
+ return 0;
+ }
+
++static int bcm2835_pll_debug_init(struct clk_hw *hw,
++ struct dentry *dentry)
++{
++ struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
++ struct bcm2835_cprman *cprman = pll->cprman;
++ const struct bcm2835_pll_data *data = pll->data;
++ struct debugfs_reg32 *regs;
++
++ regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
++ if (!regs)
++ return -ENOMEM;
++
++ regs[0].name = "cm_ctrl";
++ regs[0].offset = data->cm_ctrl_reg;
++ regs[1].name = "a2w_ctrl";
++ regs[1].offset = data->a2w_ctrl_reg;
++ regs[2].name = "frac";
++ regs[2].offset = data->frac_reg;
++ regs[3].name = "ana0";
++ regs[3].offset = data->ana_reg_base + 0 * 4;
++ regs[4].name = "ana1";
++ regs[4].offset = data->ana_reg_base + 1 * 4;
++ regs[5].name = "ana2";
++ regs[5].offset = data->ana_reg_base + 2 * 4;
++ regs[6].name = "ana3";
++ regs[6].offset = data->ana_reg_base + 3 * 4;
++
++ return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry);
++}
++
+ static const struct clk_ops bcm2835_pll_clk_ops = {
+ .is_prepared = bcm2835_pll_is_on,
+ .prepare = bcm2835_pll_on,
+@@ -1047,6 +1099,7 @@ static const struct clk_ops bcm2835_pll_
+ .recalc_rate = bcm2835_pll_get_rate,
+ .set_rate = bcm2835_pll_set_rate,
+ .round_rate = bcm2835_pll_round_rate,
++ .debug_init = bcm2835_pll_debug_init,
+ };
+
+ struct bcm2835_pll_divider {
+@@ -1147,6 +1200,26 @@ static int bcm2835_pll_divider_set_rate(
+ return 0;
+ }
+
++static int bcm2835_pll_divider_debug_init(struct clk_hw *hw,
++ struct dentry *dentry)
++{
++ struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
++ struct bcm2835_cprman *cprman = divider->cprman;
++ const struct bcm2835_pll_divider_data *data = divider->data;
++ struct debugfs_reg32 *regs;
++
++ regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
++ if (!regs)
++ return -ENOMEM;
++
++ regs[0].name = "cm";
++ regs[0].offset = data->cm_reg;
++ regs[1].name = "a2w";
++ regs[1].offset = data->a2w_reg;
++
++ return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry);
++}
++
+ static const struct clk_ops bcm2835_pll_divider_clk_ops = {
+ .is_prepared = bcm2835_pll_divider_is_on,
+ .prepare = bcm2835_pll_divider_on,
+@@ -1154,6 +1227,7 @@ static const struct clk_ops bcm2835_pll_
+ .recalc_rate = bcm2835_pll_divider_get_rate,
+ .set_rate = bcm2835_pll_divider_set_rate,
+ .round_rate = bcm2835_pll_divider_round_rate,
++ .debug_init = bcm2835_pll_divider_debug_init,
+ };
+
+ /*
+@@ -1395,6 +1469,31 @@ static u8 bcm2835_clock_get_parent(struc
+ return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
+ }
+
++static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
++ {
++ .name = "ctl",
++ .offset = 0,
++ },
++ {
++ .name = "div",
++ .offset = 4,
++ },
++};
++
++static int bcm2835_clock_debug_init(struct clk_hw *hw,
++ struct dentry *dentry)
++{
++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
++ struct bcm2835_cprman *cprman = clock->cprman;
++ const struct bcm2835_clock_data *data = clock->data;
++
++ return bcm2835_debugfs_regset(
++ cprman, data->ctl_reg,
++ bcm2835_debugfs_clock_reg32,
++ ARRAY_SIZE(bcm2835_debugfs_clock_reg32),
++ dentry);
++}
++
+ static const struct clk_ops bcm2835_clock_clk_ops = {
+ .is_prepared = bcm2835_clock_is_on,
+ .prepare = bcm2835_clock_on,
+@@ -1404,6 +1503,7 @@ static const struct clk_ops bcm2835_cloc
+ .determine_rate = bcm2835_clock_determine_rate,
+ .set_parent = bcm2835_clock_set_parent,
+ .get_parent = bcm2835_clock_get_parent,
++ .debug_init = bcm2835_clock_debug_init,
+ };
+
+ static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
+@@ -1422,6 +1522,7 @@ static const struct clk_ops bcm2835_vpu_
+ .determine_rate = bcm2835_clock_determine_rate,
+ .set_parent = bcm2835_clock_set_parent,
+ .get_parent = bcm2835_clock_get_parent,
++ .debug_init = bcm2835_clock_debug_init,
+ };
+
+ static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
--- /dev/null
+From 63ebb7d70e33861f5f00dd57dcf5e99088d385ab Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 12:51:41 +0000
+Subject: [PATCH 262/304] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in
+ driver
+
+As the use of BCM2835_CLOCK_COUNT in
+include/dt-bindings/clock/bcm2835.h is frowned upon as
+it needs to get modified every time a new clock gets introduced
+this patch changes the clk-bcm2835 driver to use a different
+scheme for registration of clocks and pll, so that there
+is no more need for BCM2835_CLOCK_COUNT to be defined.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 56eb3a2ed9726961e1bcfa69d4a3f86d68f0eb52)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 167 ++++++++++++++++++++----------------
+ include/dt-bindings/clock/bcm2835.h | 2 -
+ 2 files changed, 94 insertions(+), 75 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -301,7 +301,7 @@ struct bcm2835_cprman {
+ const char *osc_name;
+
+ struct clk_onecell_data onecell;
+- struct clk *clks[BCM2835_CLOCK_COUNT];
++ struct clk *clks[];
+ };
+
+ static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
+@@ -853,6 +853,25 @@ static const struct bcm2835_clock_data b
+ .is_mash_clock = true,
+ };
+
++struct bcm2835_gate_data {
++ const char *name;
++ const char *parent;
++
++ u32 ctl_reg;
++};
++
++/*
++ * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
++ * you have the debug bit set in the power manager, which we
++ * don't bother exposing) are individual gates off of the
++ * non-stop vpu clock.
++ */
++static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
++ .name = "peri_image",
++ .parent = "vpu",
++ .ctl_reg = CM_PERIICTL,
++};
++
+ struct bcm2835_pll {
+ struct clk_hw hw;
+ struct bcm2835_cprman *cprman;
+@@ -1654,14 +1673,81 @@ static struct clk *bcm2835_register_cloc
+ return devm_clk_register(cprman->dev, &clock->hw);
+ }
+
++static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
++ const struct bcm2835_gate_data *data)
++{
++ return clk_register_gate(cprman->dev, data->name, data->parent,
++ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
++ cprman->regs + data->ctl_reg,
++ CM_GATE_BIT, 0, &cprman->regs_lock);
++}
++
++typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
++ const void *data);
++struct bcm2835_clk_desc {
++ bcm2835_clk_register clk_register;
++ const void *data;
++};
++
++#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
++ .data = d }
++#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d)
++#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d)
++#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d)
++#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d)
++
++static const struct bcm2835_clk_desc clk_desc_array[] = {
++ /* register PLL */
++ [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data),
++ [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data),
++ [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data),
++ [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data),
++ [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data),
++ /* the PLL dividers */
++ [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data),
++ [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data),
++ [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
++ [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
++ [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
++ [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
++ [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data),
++ [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data),
++ [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
++ [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
++ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
++ /* the clocks */
++ [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data),
++ [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data),
++ [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data),
++ [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data),
++ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
++ [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data),
++ [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data),
++ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
++ [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data),
++ [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data),
++ [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data),
++ [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data),
++ [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data),
++ [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data),
++ /* the gates */
++ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
++ &bcm2835_clock_peri_image_data),
++};
++
+ static int bcm2835_clk_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+ struct clk **clks;
+ struct bcm2835_cprman *cprman;
+ struct resource *res;
++ const struct bcm2835_clk_desc *desc;
++ const size_t asize = ARRAY_SIZE(clk_desc_array);
++ size_t i;
+
+- cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
++ cprman = devm_kzalloc(dev,
++ sizeof(*cprman) + asize * sizeof(*clks),
++ GFP_KERNEL);
+ if (!cprman)
+ return -ENOMEM;
+
+@@ -1678,80 +1764,15 @@ static int bcm2835_clk_probe(struct plat
+
+ platform_set_drvdata(pdev, cprman);
+
+- cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
++ cprman->onecell.clk_num = asize;
+ cprman->onecell.clks = cprman->clks;
+ clks = cprman->clks;
+
+- clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
+- clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
+- clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
+- clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
+- clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
+-
+- clks[BCM2835_PLLA_CORE] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
+- clks[BCM2835_PLLA_PER] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
+- clks[BCM2835_PLLC_CORE0] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
+- clks[BCM2835_PLLC_CORE1] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
+- clks[BCM2835_PLLC_CORE2] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
+- clks[BCM2835_PLLC_PER] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
+- clks[BCM2835_PLLD_CORE] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
+- clks[BCM2835_PLLD_PER] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
+- clks[BCM2835_PLLH_RCAL] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
+- clks[BCM2835_PLLH_AUX] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
+- clks[BCM2835_PLLH_PIX] =
+- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
+-
+- clks[BCM2835_CLOCK_TIMER] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
+- clks[BCM2835_CLOCK_OTP] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
+- clks[BCM2835_CLOCK_TSENS] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
+- clks[BCM2835_CLOCK_VPU] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
+- clks[BCM2835_CLOCK_V3D] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
+- clks[BCM2835_CLOCK_ISP] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
+- clks[BCM2835_CLOCK_H264] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
+- clks[BCM2835_CLOCK_V3D] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
+- clks[BCM2835_CLOCK_SDRAM] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
+- clks[BCM2835_CLOCK_UART] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
+- clks[BCM2835_CLOCK_VEC] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
+- clks[BCM2835_CLOCK_HSM] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
+- clks[BCM2835_CLOCK_EMMC] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
+-
+- /*
+- * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+- * you have the debug bit set in the power manager, which we
+- * don't bother exposing) are individual gates off of the
+- * non-stop vpu clock.
+- */
+- clks[BCM2835_CLOCK_PERI_IMAGE] =
+- clk_register_gate(dev, "peri_image", "vpu",
+- CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+- cprman->regs + CM_PERIICTL, CM_GATE_BIT,
+- 0, &cprman->regs_lock);
+-
+- clks[BCM2835_CLOCK_PWM] =
+- bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
++ for (i = 0; i < asize; i++) {
++ desc = &clk_desc_array[i];
++ if (desc->clk_register && desc->data)
++ clks[i] = desc->clk_register(cprman, desc->data);
++ }
+
+ return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
+ &cprman->onecell);
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -44,5 +44,3 @@
+ #define BCM2835_CLOCK_EMMC 28
+ #define BCM2835_CLOCK_PERI_IMAGE 29
+ #define BCM2835_CLOCK_PWM 30
+-
+-#define BCM2835_CLOCK_COUNT 31
--- /dev/null
+From 760cf54c7a5a8627555a9adbf96e8aae0fcfd790 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 12:51:42 +0000
+Subject: [PATCH 263/304] clk: bcm2835: reorganize bcm2835_clock_array
+ assignment
+
+Reorganize bcm2835_clock_array so that there is no more
+need for separate bcm2835_*_data structures to be defined.
+Instead the required structures are generated inline via
+helper macros.
+
+To allow this to also work for pll alone it was required that
+the parent_pll was changed from a pointer to bcm2835_pll_data
+to the name of the pll instead.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 3b15afefbef9b5952e3d68ad73d93f981b9faca8)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 852 +++++++++++++++++++-----------------------
+ 1 file changed, 393 insertions(+), 459 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -418,115 +418,10 @@ static const struct bcm2835_pll_ana_bits
+ .fb_prediv_mask = BIT(11),
+ };
+
+-/*
+- * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
+- * Port 2) transmitter clock.
+- *
+- * It is in the PX LDO power domain, which is on when the AUDIO domain
+- * is on.
+- */
+-static const struct bcm2835_pll_data bcm2835_plla_data = {
+- .name = "plla",
+- .cm_ctrl_reg = CM_PLLA,
+- .a2w_ctrl_reg = A2W_PLLA_CTRL,
+- .frac_reg = A2W_PLLA_FRAC,
+- .ana_reg_base = A2W_PLLA_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKA,
+-
+- .ana = &bcm2835_ana_default,
+-
+- .min_rate = 600000000u,
+- .max_rate = 2400000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE,
+-};
+-
+-/* PLLB is used for the ARM's clock. */
+-static const struct bcm2835_pll_data bcm2835_pllb_data = {
+- .name = "pllb",
+- .cm_ctrl_reg = CM_PLLB,
+- .a2w_ctrl_reg = A2W_PLLB_CTRL,
+- .frac_reg = A2W_PLLB_FRAC,
+- .ana_reg_base = A2W_PLLB_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKB,
+-
+- .ana = &bcm2835_ana_default,
+-
+- .min_rate = 600000000u,
+- .max_rate = 3000000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE,
+-};
+-
+-/*
+- * PLLC is the core PLL, used to drive the core VPU clock.
+- *
+- * It is in the PX LDO power domain, which is on when the AUDIO domain
+- * is on.
+-*/
+-static const struct bcm2835_pll_data bcm2835_pllc_data = {
+- .name = "pllc",
+- .cm_ctrl_reg = CM_PLLC,
+- .a2w_ctrl_reg = A2W_PLLC_CTRL,
+- .frac_reg = A2W_PLLC_FRAC,
+- .ana_reg_base = A2W_PLLC_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKC,
+-
+- .ana = &bcm2835_ana_default,
+-
+- .min_rate = 600000000u,
+- .max_rate = 3000000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE,
+-};
+-
+-/*
+- * PLLD is the display PLL, used to drive DSI display panels.
+- *
+- * It is in the PX LDO power domain, which is on when the AUDIO domain
+- * is on.
+- */
+-static const struct bcm2835_pll_data bcm2835_plld_data = {
+- .name = "plld",
+- .cm_ctrl_reg = CM_PLLD,
+- .a2w_ctrl_reg = A2W_PLLD_CTRL,
+- .frac_reg = A2W_PLLD_FRAC,
+- .ana_reg_base = A2W_PLLD_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKD,
+-
+- .ana = &bcm2835_ana_default,
+-
+- .min_rate = 600000000u,
+- .max_rate = 2400000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE,
+-};
+-
+-/*
+- * PLLH is used to supply the pixel clock or the AUX clock for the TV
+- * encoder.
+- *
+- * It is in the HDMI power domain.
+- */
+-static const struct bcm2835_pll_data bcm2835_pllh_data = {
+- "pllh",
+- .cm_ctrl_reg = CM_PLLH,
+- .a2w_ctrl_reg = A2W_PLLH_CTRL,
+- .frac_reg = A2W_PLLH_FRAC,
+- .ana_reg_base = A2W_PLLH_ANA0,
+- .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+- .lock_mask = CM_LOCK_FLOCKH,
+-
+- .ana = &bcm2835_ana_pllh,
+-
+- .min_rate = 600000000u,
+- .max_rate = 3000000000u,
+- .max_fb_rate = BCM2835_MAX_FB_RATE,
+-};
+-
+ struct bcm2835_pll_divider_data {
+ const char *name;
+- const struct bcm2835_pll_data *source_pll;
++ const char *source_pll;
++
+ u32 cm_reg;
+ u32 a2w_reg;
+
+@@ -535,124 +430,6 @@ struct bcm2835_pll_divider_data {
+ u32 fixed_divider;
+ };
+
+-static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
+- .name = "plla_core",
+- .source_pll = &bcm2835_plla_data,
+- .cm_reg = CM_PLLA,
+- .a2w_reg = A2W_PLLA_CORE,
+- .load_mask = CM_PLLA_LOADCORE,
+- .hold_mask = CM_PLLA_HOLDCORE,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
+- .name = "plla_per",
+- .source_pll = &bcm2835_plla_data,
+- .cm_reg = CM_PLLA,
+- .a2w_reg = A2W_PLLA_PER,
+- .load_mask = CM_PLLA_LOADPER,
+- .hold_mask = CM_PLLA_HOLDPER,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
+- .name = "pllb_arm",
+- .source_pll = &bcm2835_pllb_data,
+- .cm_reg = CM_PLLB,
+- .a2w_reg = A2W_PLLB_ARM,
+- .load_mask = CM_PLLB_LOADARM,
+- .hold_mask = CM_PLLB_HOLDARM,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
+- .name = "pllc_core0",
+- .source_pll = &bcm2835_pllc_data,
+- .cm_reg = CM_PLLC,
+- .a2w_reg = A2W_PLLC_CORE0,
+- .load_mask = CM_PLLC_LOADCORE0,
+- .hold_mask = CM_PLLC_HOLDCORE0,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
+- .name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
+- .cm_reg = CM_PLLC, A2W_PLLC_CORE1,
+- .load_mask = CM_PLLC_LOADCORE1,
+- .hold_mask = CM_PLLC_HOLDCORE1,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
+- .name = "pllc_core2",
+- .source_pll = &bcm2835_pllc_data,
+- .cm_reg = CM_PLLC,
+- .a2w_reg = A2W_PLLC_CORE2,
+- .load_mask = CM_PLLC_LOADCORE2,
+- .hold_mask = CM_PLLC_HOLDCORE2,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
+- .name = "pllc_per",
+- .source_pll = &bcm2835_pllc_data,
+- .cm_reg = CM_PLLC,
+- .a2w_reg = A2W_PLLC_PER,
+- .load_mask = CM_PLLC_LOADPER,
+- .hold_mask = CM_PLLC_HOLDPER,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
+- .name = "plld_core",
+- .source_pll = &bcm2835_plld_data,
+- .cm_reg = CM_PLLD,
+- .a2w_reg = A2W_PLLD_CORE,
+- .load_mask = CM_PLLD_LOADCORE,
+- .hold_mask = CM_PLLD_HOLDCORE,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
+- .name = "plld_per",
+- .source_pll = &bcm2835_plld_data,
+- .cm_reg = CM_PLLD,
+- .a2w_reg = A2W_PLLD_PER,
+- .load_mask = CM_PLLD_LOADPER,
+- .hold_mask = CM_PLLD_HOLDPER,
+- .fixed_divider = 1,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
+- .name = "pllh_rcal",
+- .source_pll = &bcm2835_pllh_data,
+- .cm_reg = CM_PLLH,
+- .a2w_reg = A2W_PLLH_RCAL,
+- .load_mask = CM_PLLH_LOADRCAL,
+- .hold_mask = 0,
+- .fixed_divider = 10,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
+- .name = "pllh_aux",
+- .source_pll = &bcm2835_pllh_data,
+- .cm_reg = CM_PLLH,
+- .a2w_reg = A2W_PLLH_AUX,
+- .load_mask = CM_PLLH_LOADAUX,
+- .hold_mask = 0,
+- .fixed_divider = 10,
+-};
+-
+-static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
+- .name = "pllh_pix",
+- .source_pll = &bcm2835_pllh_data,
+- .cm_reg = CM_PLLH,
+- .a2w_reg = A2W_PLLH_PIX,
+- .load_mask = CM_PLLH_LOADPIX,
+- .hold_mask = 0,
+- .fixed_divider = 10,
+-};
+-
+ struct bcm2835_clock_data {
+ const char *name;
+
+@@ -671,188 +448,6 @@ struct bcm2835_clock_data {
+ bool is_mash_clock;
+ };
+
+-static const char *const bcm2835_clock_per_parents[] = {
+- "gnd",
+- "xosc",
+- "testdebug0",
+- "testdebug1",
+- "plla_per",
+- "pllc_per",
+- "plld_per",
+- "pllh_aux",
+-};
+-
+-static const char *const bcm2835_clock_vpu_parents[] = {
+- "gnd",
+- "xosc",
+- "testdebug0",
+- "testdebug1",
+- "plla_core",
+- "pllc_core0",
+- "plld_core",
+- "pllh_aux",
+- "pllc_core1",
+- "pllc_core2",
+-};
+-
+-static const char *const bcm2835_clock_osc_parents[] = {
+- "gnd",
+- "xosc",
+- "testdebug0",
+- "testdebug1"
+-};
+-
+-/*
+- * Used for a 1Mhz clock for the system clocksource, and also used by
+- * the watchdog timer and the camera pulse generator.
+- */
+-static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
+- .name = "timer",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+- .parents = bcm2835_clock_osc_parents,
+- .ctl_reg = CM_TIMERCTL,
+- .div_reg = CM_TIMERDIV,
+- .int_bits = 6,
+- .frac_bits = 12,
+-};
+-
+-/* One Time Programmable Memory clock. Maximum 10Mhz. */
+-static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
+- .name = "otp",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+- .parents = bcm2835_clock_osc_parents,
+- .ctl_reg = CM_OTPCTL,
+- .div_reg = CM_OTPDIV,
+- .int_bits = 4,
+- .frac_bits = 0,
+-};
+-
+-/*
+- * VPU clock. This doesn't have an enable bit, since it drives the
+- * bus for everything else, and is special so it doesn't need to be
+- * gated for rate changes. It is also known as "clk_audio" in various
+- * hardware documentation.
+- */
+-static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
+- .name = "vpu",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+- .parents = bcm2835_clock_vpu_parents,
+- .ctl_reg = CM_VPUCTL,
+- .div_reg = CM_VPUDIV,
+- .int_bits = 12,
+- .frac_bits = 8,
+- .is_vpu_clock = true,
+-};
+-
+-static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
+- .name = "v3d",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+- .parents = bcm2835_clock_vpu_parents,
+- .ctl_reg = CM_V3DCTL,
+- .div_reg = CM_V3DDIV,
+- .int_bits = 4,
+- .frac_bits = 8,
+-};
+-
+-static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
+- .name = "isp",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+- .parents = bcm2835_clock_vpu_parents,
+- .ctl_reg = CM_ISPCTL,
+- .div_reg = CM_ISPDIV,
+- .int_bits = 4,
+- .frac_bits = 8,
+-};
+-
+-static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
+- .name = "h264",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+- .parents = bcm2835_clock_vpu_parents,
+- .ctl_reg = CM_H264CTL,
+- .div_reg = CM_H264DIV,
+- .int_bits = 4,
+- .frac_bits = 8,
+-};
+-
+-/* TV encoder clock. Only operating frequency is 108Mhz. */
+-static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
+- .name = "vec",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+- .parents = bcm2835_clock_per_parents,
+- .ctl_reg = CM_VECCTL,
+- .div_reg = CM_VECDIV,
+- .int_bits = 4,
+- .frac_bits = 0,
+-};
+-
+-static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
+- .name = "uart",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+- .parents = bcm2835_clock_per_parents,
+- .ctl_reg = CM_UARTCTL,
+- .div_reg = CM_UARTDIV,
+- .int_bits = 10,
+- .frac_bits = 12,
+-};
+-
+-/* HDMI state machine */
+-static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
+- .name = "hsm",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+- .parents = bcm2835_clock_per_parents,
+- .ctl_reg = CM_HSMCTL,
+- .div_reg = CM_HSMDIV,
+- .int_bits = 4,
+- .frac_bits = 8,
+-};
+-
+-/*
+- * Secondary SDRAM clock. Used for low-voltage modes when the PLL in
+- * the SDRAM controller can't be used.
+- */
+-static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
+- .name = "sdram",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
+- .parents = bcm2835_clock_vpu_parents,
+- .ctl_reg = CM_SDCCTL,
+- .div_reg = CM_SDCDIV,
+- .int_bits = 6,
+- .frac_bits = 0,
+-};
+-
+-/* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */
+-static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
+- .name = "tsens",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
+- .parents = bcm2835_clock_osc_parents,
+- .ctl_reg = CM_TSENSCTL,
+- .div_reg = CM_TSENSDIV,
+- .int_bits = 5,
+- .frac_bits = 0,
+-};
+-
+-/* Arasan EMMC clock */
+-static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
+- .name = "emmc",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+- .parents = bcm2835_clock_per_parents,
+- .ctl_reg = CM_EMMCCTL,
+- .div_reg = CM_EMMCDIV,
+- .int_bits = 4,
+- .frac_bits = 8,
+-};
+-
+-static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
+- .name = "pwm",
+- .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
+- .parents = bcm2835_clock_per_parents,
+- .ctl_reg = CM_PWMCTL,
+- .div_reg = CM_PWMDIV,
+- .int_bits = 12,
+- .frac_bits = 12,
+- .is_mash_clock = true,
+-};
+-
+ struct bcm2835_gate_data {
+ const char *name;
+ const char *parent;
+@@ -860,18 +455,6 @@ struct bcm2835_gate_data {
+ u32 ctl_reg;
+ };
+
+-/*
+- * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+- * you have the debug bit set in the power manager, which we
+- * don't bother exposing) are individual gates off of the
+- * non-stop vpu clock.
+- */
+-static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
+- .name = "peri_image",
+- .parent = "vpu",
+- .ctl_reg = CM_PERIICTL,
+-};
+-
+ struct bcm2835_pll {
+ struct clk_hw hw;
+ struct bcm2835_cprman *cprman;
+@@ -1590,7 +1173,7 @@ bcm2835_register_pll_divider(struct bcm2
+
+ memset(&init, 0, sizeof(init));
+
+- init.parent_names = &data->source_pll->name;
++ init.parent_names = &data->source_pll;
+ init.num_parents = 1;
+ init.name = divider_name;
+ init.ops = &bcm2835_pll_divider_clk_ops;
+@@ -1689,50 +1272,401 @@ struct bcm2835_clk_desc {
+ const void *data;
+ };
+
+-#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
+- .data = d }
+-#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d)
+-#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d)
+-#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d)
+-#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d)
++/* assignment helper macros for different clock types */
++#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
++ .data = __VA_ARGS__ }
++#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \
++ &(struct bcm2835_pll_data) \
++ {__VA_ARGS__})
++#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \
++ &(struct bcm2835_pll_divider_data) \
++ {__VA_ARGS__})
++#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \
++ &(struct bcm2835_clock_data) \
++ {__VA_ARGS__})
++#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \
++ &(struct bcm2835_gate_data) \
++ {__VA_ARGS__})
++
++/* parent mux arrays plus helper macros */
++
++/* main oscillator parent mux */
++static const char *const bcm2835_clock_osc_parents[] = {
++ "gnd",
++ "xosc",
++ "testdebug0",
++ "testdebug1"
++};
++
++#define REGISTER_OSC_CLK(...) REGISTER_CLK( \
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \
++ .parents = bcm2835_clock_osc_parents, \
++ __VA_ARGS__)
++
++/* main peripherial parent mux */
++static const char *const bcm2835_clock_per_parents[] = {
++ "gnd",
++ "xosc",
++ "testdebug0",
++ "testdebug1",
++ "plla_per",
++ "pllc_per",
++ "plld_per",
++ "pllh_aux",
++};
++
++#define REGISTER_PER_CLK(...) REGISTER_CLK( \
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \
++ .parents = bcm2835_clock_per_parents, \
++ __VA_ARGS__)
++
++/* main vpu parent mux */
++static const char *const bcm2835_clock_vpu_parents[] = {
++ "gnd",
++ "xosc",
++ "testdebug0",
++ "testdebug1",
++ "plla_core",
++ "pllc_core0",
++ "plld_core",
++ "pllh_aux",
++ "pllc_core1",
++ "pllc_core2",
++};
++
++#define REGISTER_VPU_CLK(...) REGISTER_CLK( \
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \
++ .parents = bcm2835_clock_vpu_parents, \
++ __VA_ARGS__)
+
++/*
++ * the real definition of all the pll, pll_dividers and clocks
++ * these make use of the above REGISTER_* macros
++ */
+ static const struct bcm2835_clk_desc clk_desc_array[] = {
+- /* register PLL */
+- [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data),
+- [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data),
+- [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data),
+- [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data),
+- [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data),
+- /* the PLL dividers */
+- [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data),
+- [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data),
+- [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
+- [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
+- [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
+- [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
+- [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data),
+- [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data),
+- [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
+- [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
+- [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
++ /* the PLL + PLL dividers */
++
++ /*
++ * PLLA is the auxiliary PLL, used to drive the CCP2
++ * (Compact Camera Port 2) transmitter clock.
++ *
++ * It is in the PX LDO power domain, which is on when the
++ * AUDIO domain is on.
++ */
++ [BCM2835_PLLA] = REGISTER_PLL(
++ .name = "plla",
++ .cm_ctrl_reg = CM_PLLA,
++ .a2w_ctrl_reg = A2W_PLLA_CTRL,
++ .frac_reg = A2W_PLLA_FRAC,
++ .ana_reg_base = A2W_PLLA_ANA0,
++ .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
++ .lock_mask = CM_LOCK_FLOCKA,
++
++ .ana = &bcm2835_ana_default,
++
++ .min_rate = 600000000u,
++ .max_rate = 2400000000u,
++ .max_fb_rate = BCM2835_MAX_FB_RATE),
++ [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(
++ .name = "plla_core",
++ .source_pll = "plla",
++ .cm_reg = CM_PLLA,
++ .a2w_reg = A2W_PLLA_CORE,
++ .load_mask = CM_PLLA_LOADCORE,
++ .hold_mask = CM_PLLA_HOLDCORE,
++ .fixed_divider = 1),
++ [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
++ .name = "plla_per",
++ .source_pll = "plla",
++ .cm_reg = CM_PLLA,
++ .a2w_reg = A2W_PLLA_PER,
++ .load_mask = CM_PLLA_LOADPER,
++ .hold_mask = CM_PLLA_HOLDPER,
++ .fixed_divider = 1),
++
++ /* PLLB is used for the ARM's clock. */
++ [BCM2835_PLLB] = REGISTER_PLL(
++ .name = "pllb",
++ .cm_ctrl_reg = CM_PLLB,
++ .a2w_ctrl_reg = A2W_PLLB_CTRL,
++ .frac_reg = A2W_PLLB_FRAC,
++ .ana_reg_base = A2W_PLLB_ANA0,
++ .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
++ .lock_mask = CM_LOCK_FLOCKB,
++
++ .ana = &bcm2835_ana_default,
++
++ .min_rate = 600000000u,
++ .max_rate = 3000000000u,
++ .max_fb_rate = BCM2835_MAX_FB_RATE),
++ [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
++ .name = "pllb_arm",
++ .source_pll = "pllb",
++ .cm_reg = CM_PLLB,
++ .a2w_reg = A2W_PLLB_ARM,
++ .load_mask = CM_PLLB_LOADARM,
++ .hold_mask = CM_PLLB_HOLDARM,
++ .fixed_divider = 1),
++
++ /*
++ * PLLC is the core PLL, used to drive the core VPU clock.
++ *
++ * It is in the PX LDO power domain, which is on when the
++ * AUDIO domain is on.
++ */
++ [BCM2835_PLLC] = REGISTER_PLL(
++ .name = "pllc",
++ .cm_ctrl_reg = CM_PLLC,
++ .a2w_ctrl_reg = A2W_PLLC_CTRL,
++ .frac_reg = A2W_PLLC_FRAC,
++ .ana_reg_base = A2W_PLLC_ANA0,
++ .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
++ .lock_mask = CM_LOCK_FLOCKC,
++
++ .ana = &bcm2835_ana_default,
++
++ .min_rate = 600000000u,
++ .max_rate = 3000000000u,
++ .max_fb_rate = BCM2835_MAX_FB_RATE),
++ [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(
++ .name = "pllc_core0",
++ .source_pll = "pllc",
++ .cm_reg = CM_PLLC,
++ .a2w_reg = A2W_PLLC_CORE0,
++ .load_mask = CM_PLLC_LOADCORE0,
++ .hold_mask = CM_PLLC_HOLDCORE0,
++ .fixed_divider = 1),
++ [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
++ .name = "pllc_core1",
++ .source_pll = "pllc",
++ .cm_reg = CM_PLLC,
++ .a2w_reg = A2W_PLLC_CORE1,
++ .load_mask = CM_PLLC_LOADCORE1,
++ .hold_mask = CM_PLLC_HOLDCORE1,
++ .fixed_divider = 1),
++ [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
++ .name = "pllc_core2",
++ .source_pll = "pllc",
++ .cm_reg = CM_PLLC,
++ .a2w_reg = A2W_PLLC_CORE2,
++ .load_mask = CM_PLLC_LOADCORE2,
++ .hold_mask = CM_PLLC_HOLDCORE2,
++ .fixed_divider = 1),
++ [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
++ .name = "pllc_per",
++ .source_pll = "pllc",
++ .cm_reg = CM_PLLC,
++ .a2w_reg = A2W_PLLC_PER,
++ .load_mask = CM_PLLC_LOADPER,
++ .hold_mask = CM_PLLC_HOLDPER,
++ .fixed_divider = 1),
++
++ /*
++ * PLLD is the display PLL, used to drive DSI display panels.
++ *
++ * It is in the PX LDO power domain, which is on when the
++ * AUDIO domain is on.
++ */
++ [BCM2835_PLLD] = REGISTER_PLL(
++ .name = "plld",
++ .cm_ctrl_reg = CM_PLLD,
++ .a2w_ctrl_reg = A2W_PLLD_CTRL,
++ .frac_reg = A2W_PLLD_FRAC,
++ .ana_reg_base = A2W_PLLD_ANA0,
++ .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
++ .lock_mask = CM_LOCK_FLOCKD,
++
++ .ana = &bcm2835_ana_default,
++
++ .min_rate = 600000000u,
++ .max_rate = 2400000000u,
++ .max_fb_rate = BCM2835_MAX_FB_RATE),
++ [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(
++ .name = "plld_core",
++ .source_pll = "plld",
++ .cm_reg = CM_PLLD,
++ .a2w_reg = A2W_PLLD_CORE,
++ .load_mask = CM_PLLD_LOADCORE,
++ .hold_mask = CM_PLLD_HOLDCORE,
++ .fixed_divider = 1),
++ [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
++ .name = "plld_per",
++ .source_pll = "plld",
++ .cm_reg = CM_PLLD,
++ .a2w_reg = A2W_PLLD_PER,
++ .load_mask = CM_PLLD_LOADPER,
++ .hold_mask = CM_PLLD_HOLDPER,
++ .fixed_divider = 1),
++
++ /*
++ * PLLH is used to supply the pixel clock or the AUX clock for the
++ * TV encoder.
++ *
++ * It is in the HDMI power domain.
++ */
++ [BCM2835_PLLH] = REGISTER_PLL(
++ "pllh",
++ .cm_ctrl_reg = CM_PLLH,
++ .a2w_ctrl_reg = A2W_PLLH_CTRL,
++ .frac_reg = A2W_PLLH_FRAC,
++ .ana_reg_base = A2W_PLLH_ANA0,
++ .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
++ .lock_mask = CM_LOCK_FLOCKH,
++
++ .ana = &bcm2835_ana_pllh,
++
++ .min_rate = 600000000u,
++ .max_rate = 3000000000u,
++ .max_fb_rate = BCM2835_MAX_FB_RATE),
++ [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(
++ .name = "pllh_rcal",
++ .source_pll = "pllh",
++ .cm_reg = CM_PLLH,
++ .a2w_reg = A2W_PLLH_RCAL,
++ .load_mask = CM_PLLH_LOADRCAL,
++ .hold_mask = 0,
++ .fixed_divider = 10),
++ [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
++ .name = "pllh_aux",
++ .source_pll = "pllh",
++ .cm_reg = CM_PLLH,
++ .a2w_reg = A2W_PLLH_AUX,
++ .load_mask = CM_PLLH_LOADAUX,
++ .hold_mask = 0,
++ .fixed_divider = 10),
++ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
++ .name = "pllh_pix",
++ .source_pll = "pllh",
++ .cm_reg = CM_PLLH,
++ .a2w_reg = A2W_PLLH_PIX,
++ .load_mask = CM_PLLH_LOADPIX,
++ .hold_mask = 0,
++ .fixed_divider = 10),
++
+ /* the clocks */
+- [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data),
+- [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data),
+- [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data),
+- [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data),
+- [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
+- [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data),
+- [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data),
+- [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
+- [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data),
+- [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data),
+- [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data),
+- [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data),
+- [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data),
+- [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data),
++
++ /* clocks with oscillator parent mux */
++
++ /* One Time Programmable Memory clock. Maximum 10Mhz. */
++ [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK(
++ .name = "otp",
++ .ctl_reg = CM_OTPCTL,
++ .div_reg = CM_OTPDIV,
++ .int_bits = 4,
++ .frac_bits = 0),
++ /*
++ * Used for a 1Mhz clock for the system clocksource, and also used
++ * bythe watchdog timer and the camera pulse generator.
++ */
++ [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK(
++ .name = "timer",
++ .ctl_reg = CM_TIMERCTL,
++ .div_reg = CM_TIMERDIV,
++ .int_bits = 6,
++ .frac_bits = 12),
++ /*
++ * Clock for the temperature sensor.
++ * Generally run at 2Mhz, max 5Mhz.
++ */
++ [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK(
++ .name = "tsens",
++ .ctl_reg = CM_TSENSCTL,
++ .div_reg = CM_TSENSDIV,
++ .int_bits = 5,
++ .frac_bits = 0),
++
++ /* clocks with vpu parent mux */
++ [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
++ .name = "h264",
++ .ctl_reg = CM_H264CTL,
++ .div_reg = CM_H264DIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
++ .name = "isp",
++ .ctl_reg = CM_ISPCTL,
++ .div_reg = CM_ISPDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ /*
++ * Secondary SDRAM clock. Used for low-voltage modes when the PLL
++ * in the SDRAM controller can't be used.
++ */
++ [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK(
++ .name = "sdram",
++ .ctl_reg = CM_SDCCTL,
++ .div_reg = CM_SDCDIV,
++ .int_bits = 6,
++ .frac_bits = 0),
++ [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
++ .name = "v3d",
++ .ctl_reg = CM_V3DCTL,
++ .div_reg = CM_V3DDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ /*
++ * VPU clock. This doesn't have an enable bit, since it drives
++ * the bus for everything else, and is special so it doesn't need
++ * to be gated for rate changes. It is also known as "clk_audio"
++ * in various hardware documentation.
++ */
++ [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK(
++ .name = "vpu",
++ .ctl_reg = CM_VPUCTL,
++ .div_reg = CM_VPUDIV,
++ .int_bits = 12,
++ .frac_bits = 8,
++ .is_vpu_clock = true),
++
++ /* clocks with per parent mux */
++
++ /* Arasan EMMC clock */
++ [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
++ .name = "emmc",
++ .ctl_reg = CM_EMMCCTL,
++ .div_reg = CM_EMMCDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ /* HDMI state machine */
++ [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
++ .name = "hsm",
++ .ctl_reg = CM_HSMCTL,
++ .div_reg = CM_HSMDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
++ .name = "pwm",
++ .ctl_reg = CM_PWMCTL,
++ .div_reg = CM_PWMDIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++ .is_mash_clock = true),
++ [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
++ .name = "uart",
++ .ctl_reg = CM_UARTCTL,
++ .div_reg = CM_UARTDIV,
++ .int_bits = 10,
++ .frac_bits = 12),
++ /* TV encoder clock. Only operating frequency is 108Mhz. */
++ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
++ .name = "vec",
++ .ctl_reg = CM_VECCTL,
++ .div_reg = CM_VECDIV,
++ .int_bits = 4,
++ .frac_bits = 0),
++
+ /* the gates */
++
++ /*
++ * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
++ * you have the debug bit set in the power manager, which we
++ * don't bother exposing) are individual gates off of the
++ * non-stop vpu clock.
++ */
+ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
+- &bcm2835_clock_peri_image_data),
++ .name = "peri_image",
++ .parent = "vpu",
++ .ctl_reg = CM_PERIICTL),
+ };
+
+ static int bcm2835_clk_probe(struct platform_device *pdev)
--- /dev/null
+From 53b35c410aed20a1bfce25d4bdec7bb1449292ec Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 12:51:43 +0000
+Subject: [PATCH 264/304] clk: bcm2835: enable management of PCM clock
+
+Enable the PCM clock in the SOC, which is used by the
+bcm2835-i2s driver.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 33b689600f43094a9316a1b582f2286d17bc737b)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 7 +++++++
+ include/dt-bindings/clock/bcm2835.h | 1 +
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1634,6 +1634,13 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_HSMDIV,
+ .int_bits = 4,
+ .frac_bits = 8),
++ [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
++ .name = "pcm",
++ .ctl_reg = CM_PCMCTL,
++ .div_reg = CM_PCMDIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++ .is_mash_clock = true),
+ [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
+ .name = "pwm",
+ .ctl_reg = CM_PWMCTL,
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -44,3 +44,4 @@
+ #define BCM2835_CLOCK_EMMC 28
+ #define BCM2835_CLOCK_PERI_IMAGE 29
+ #define BCM2835_CLOCK_PWM 30
++#define BCM2835_CLOCK_PCM 31
--- /dev/null
+From 4f420c264a38a1eaec12a52f99f3b315133bca69 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 15:43:56 +0000
+Subject: [PATCH 265/304] clk: bcm2835: add missing PLL clock dividers
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 728436956aa172b24a3212295f8b53feb6479f32)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 32 ++++++++++++++++++++++++++++++++
+ include/dt-bindings/clock/bcm2835.h | 5 +++++
+ 2 files changed, 37 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1383,6 +1383,22 @@ static const struct bcm2835_clk_desc clk
+ .load_mask = CM_PLLA_LOADPER,
+ .hold_mask = CM_PLLA_HOLDPER,
+ .fixed_divider = 1),
++ [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
++ .name = "plla_dsi0",
++ .source_pll = "plla",
++ .cm_reg = CM_PLLA,
++ .a2w_reg = A2W_PLLA_DSI0,
++ .load_mask = CM_PLLA_LOADDSI0,
++ .hold_mask = CM_PLLA_HOLDDSI0,
++ .fixed_divider = 1),
++ [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV(
++ .name = "plla_ccp2",
++ .source_pll = "plla",
++ .cm_reg = CM_PLLA,
++ .a2w_reg = A2W_PLLA_CCP2,
++ .load_mask = CM_PLLA_LOADCCP2,
++ .hold_mask = CM_PLLA_HOLDCCP2,
++ .fixed_divider = 1),
+
+ /* PLLB is used for the ARM's clock. */
+ [BCM2835_PLLB] = REGISTER_PLL(
+@@ -1497,6 +1513,22 @@ static const struct bcm2835_clk_desc clk
+ .load_mask = CM_PLLD_LOADPER,
+ .hold_mask = CM_PLLD_HOLDPER,
+ .fixed_divider = 1),
++ [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
++ .name = "plld_dsi0",
++ .source_pll = "plld",
++ .cm_reg = CM_PLLD,
++ .a2w_reg = A2W_PLLD_DSI0,
++ .load_mask = CM_PLLD_LOADDSI0,
++ .hold_mask = CM_PLLD_HOLDDSI0,
++ .fixed_divider = 1),
++ [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV(
++ .name = "plld_dsi1",
++ .source_pll = "plld",
++ .cm_reg = CM_PLLD,
++ .a2w_reg = A2W_PLLD_DSI1,
++ .load_mask = CM_PLLD_LOADDSI1,
++ .hold_mask = CM_PLLD_HOLDDSI1,
++ .fixed_divider = 1),
+
+ /*
+ * PLLH is used to supply the pixel clock or the AUX clock for the
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -45,3 +45,8 @@
+ #define BCM2835_CLOCK_PERI_IMAGE 29
+ #define BCM2835_CLOCK_PWM 30
+ #define BCM2835_CLOCK_PCM 31
++
++#define BCM2835_PLLA_DSI0 32
++#define BCM2835_PLLA_CCP2 33
++#define BCM2835_PLLD_DSI0 34
++#define BCM2835_PLLD_DSI1 35
--- /dev/null
+From 104a92cd1a8b6e83fa0b741e0d0cc37928b0f49b Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 15:43:57 +0000
+Subject: [PATCH 266/304] clk: bcm2835: add missing osc and per clocks
+
+Add AVE0, DFT, GP0, GP1, GP2, SLIM, SMI, TEC, DPI, CAM0, CAM1, DSI0E,
+and DSI1E. PULSE is not added because it has an extra divider.
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit d3d6f15fd376e3dbba851724057b112558c70b79)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 90 +++++++++++++++++++++++++++++++++++++
+ include/dt-bindings/clock/bcm2835.h | 14 ++++++
+ 2 files changed, 104 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -117,6 +117,8 @@
+ #define CM_SDCCTL 0x1a8
+ #define CM_SDCDIV 0x1ac
+ #define CM_ARMCTL 0x1b0
++#define CM_AVEOCTL 0x1b8
++#define CM_AVEODIV 0x1bc
+ #define CM_EMMCCTL 0x1c0
+ #define CM_EMMCDIV 0x1c4
+
+@@ -1606,6 +1608,12 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_TSENSDIV,
+ .int_bits = 5,
+ .frac_bits = 0),
++ [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK(
++ .name = "tec",
++ .ctl_reg = CM_TECCTL,
++ .div_reg = CM_TECDIV,
++ .int_bits = 6,
++ .frac_bits = 0),
+
+ /* clocks with vpu parent mux */
+ [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
+@@ -1620,6 +1628,7 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_ISPDIV,
+ .int_bits = 4,
+ .frac_bits = 8),
++
+ /*
+ * Secondary SDRAM clock. Used for low-voltage modes when the PLL
+ * in the SDRAM controller can't be used.
+@@ -1651,6 +1660,36 @@ static const struct bcm2835_clk_desc clk
+ .is_vpu_clock = true),
+
+ /* clocks with per parent mux */
++ [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
++ .name = "aveo",
++ .ctl_reg = CM_AVEOCTL,
++ .div_reg = CM_AVEODIV,
++ .int_bits = 4,
++ .frac_bits = 0),
++ [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
++ .name = "cam0",
++ .ctl_reg = CM_CAM0CTL,
++ .div_reg = CM_CAM0DIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
++ .name = "cam1",
++ .ctl_reg = CM_CAM1CTL,
++ .div_reg = CM_CAM1DIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
++ .name = "dft",
++ .ctl_reg = CM_DFTCTL,
++ .div_reg = CM_DFTDIV,
++ .int_bits = 5,
++ .frac_bits = 0),
++ [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK(
++ .name = "dpi",
++ .ctl_reg = CM_DPICTL,
++ .div_reg = CM_DPIDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
+
+ /* Arasan EMMC clock */
+ [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
+@@ -1659,6 +1698,29 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_EMMCDIV,
+ .int_bits = 4,
+ .frac_bits = 8),
++
++ /* General purpose (GPIO) clocks */
++ [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
++ .name = "gp0",
++ .ctl_reg = CM_GP0CTL,
++ .div_reg = CM_GP0DIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++ .is_mash_clock = true),
++ [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
++ .name = "gp1",
++ .ctl_reg = CM_GP1CTL,
++ .div_reg = CM_GP1DIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++ .is_mash_clock = true),
++ [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
++ .name = "gp2",
++ .ctl_reg = CM_GP2CTL,
++ .div_reg = CM_GP2DIV,
++ .int_bits = 12,
++ .frac_bits = 12),
++
+ /* HDMI state machine */
+ [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
+ .name = "hsm",
+@@ -1680,12 +1742,26 @@ static const struct bcm2835_clk_desc clk
+ .int_bits = 12,
+ .frac_bits = 12,
+ .is_mash_clock = true),
++ [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
++ .name = "slim",
++ .ctl_reg = CM_SLIMCTL,
++ .div_reg = CM_SLIMDIV,
++ .int_bits = 12,
++ .frac_bits = 12,
++ .is_mash_clock = true),
++ [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
++ .name = "smi",
++ .ctl_reg = CM_SMICTL,
++ .div_reg = CM_SMIDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
+ [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
+ .name = "uart",
+ .ctl_reg = CM_UARTCTL,
+ .div_reg = CM_UARTDIV,
+ .int_bits = 10,
+ .frac_bits = 12),
++
+ /* TV encoder clock. Only operating frequency is 108Mhz. */
+ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
+ .name = "vec",
+@@ -1694,6 +1770,20 @@ static const struct bcm2835_clk_desc clk
+ .int_bits = 4,
+ .frac_bits = 0),
+
++ /* dsi clocks */
++ [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
++ .name = "dsi0e",
++ .ctl_reg = CM_DSI0ECTL,
++ .div_reg = CM_DSI0EDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++ [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
++ .name = "dsi1e",
++ .ctl_reg = CM_DSI1ECTL,
++ .div_reg = CM_DSI1EDIV,
++ .int_bits = 4,
++ .frac_bits = 8),
++
+ /* the gates */
+
+ /*
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -50,3 +50,17 @@
+ #define BCM2835_PLLA_CCP2 33
+ #define BCM2835_PLLD_DSI0 34
+ #define BCM2835_PLLD_DSI1 35
++
++#define BCM2835_CLOCK_AVEO 36
++#define BCM2835_CLOCK_DFT 37
++#define BCM2835_CLOCK_GP0 38
++#define BCM2835_CLOCK_GP1 39
++#define BCM2835_CLOCK_GP2 40
++#define BCM2835_CLOCK_SLIM 41
++#define BCM2835_CLOCK_SMI 42
++#define BCM2835_CLOCK_TEC 43
++#define BCM2835_CLOCK_DPI 44
++#define BCM2835_CLOCK_CAM0 45
++#define BCM2835_CLOCK_CAM1 46
++#define BCM2835_CLOCK_DSI0E 47
++#define BCM2835_CLOCK_DSI1E 48
--- /dev/null
+From 66350cdbb13029d143f99c97b0953805afe2f175 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 13 Apr 2016 13:05:03 -0700
+Subject: [PATCH 267/304] clk: bcm2835: Fix PLL poweron
+
+In poweroff, we set the reset bit and the power down bit, but only
+managed to unset the reset bit for poweron. This meant that if HDMI
+did -EPROBE_DEFER after it had grabbed its clocks, we'd power down the
+PLLH (that had been on at boot time) and never recover.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks")
+Cc: stable@vger.kernel.org
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit d794a7b18350b7538e64248adf639f2cb8da5fb7)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -557,6 +557,10 @@ static int bcm2835_pll_on(struct clk_hw
+ const struct bcm2835_pll_data *data = pll->data;
+ ktime_t timeout;
+
++ cprman_write(cprman, data->a2w_ctrl_reg,
++ cprman_read(cprman, data->a2w_ctrl_reg) &
++ ~A2W_PLL_CTRL_PWRDN);
++
+ /* Take the PLL out of reset. */
+ cprman_write(cprman, data->cm_ctrl_reg,
+ cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
--- /dev/null
+From 2a4c0b0a28d07eec49c0388c83958d41d1b96a34 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 1 Dec 2015 16:49:12 -0800
+Subject: [PATCH 268/304] ARM: bcm2835: Define two new packets from the latest
+ firmware.
+
+These packets give us direct access to the firmware's power management
+code, as opposed to GET/SET_POWER_STATE packets that only had a couple
+of domains implemented.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Kevin Hilman <khilman@linaro.org>
+(cherry picked from commit 60d56333e869be6ad6926cdba3ba974512b2183b)
+---
+ include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -74,11 +74,13 @@ enum rpi_firmware_property_tag {
+ RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014,
+ RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020,
+ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021,
++ RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030,
+ RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001,
+ RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002,
+ RPI_FIRMWARE_SET_VOLTAGE = 0x00038003,
+ RPI_FIRMWARE_SET_TURBO = 0x00038009,
+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021,
++ RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030,
+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042,
+
+ /* Dispmanx TAGS */
--- /dev/null
+From efc94d4ff30bdf042aa90239b0e0948282677622 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Wed, 16 Dec 2015 16:26:47 -0800
+Subject: [PATCH 269/304] ARM: bcm2835: add rpi power domain driver
+
+This patch adds support for several power domains on Raspberry Pi,
+including USB (so it can be enabled even if the bootloader didn't do
+it), and graphics.
+
+This patch is the combined work of Eric Anholt (who wrote USB support
+inside of the Raspberry Pi firmware driver, and wrote the non-USB
+domain support) and Alexander Aring (who separated the original USB
+work out from the firmware driver).
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Kevin Hilman <khilman@linaro.org>
+(cherry picked from commit a09cd356586d33f64cbe64ee4f5c1a7c4a6abee5)
+---
+ drivers/soc/Kconfig | 1 +
+ drivers/soc/Makefile | 1 +
+ drivers/soc/bcm/Kconfig | 9 +
+ drivers/soc/bcm/Makefile | 1 +
+ drivers/soc/bcm/raspberrypi-power.c | 247 ++++++++++++++++++++++++++
+ include/dt-bindings/power/raspberrypi-power.h | 41 +++++
+ 6 files changed, 300 insertions(+)
+ create mode 100644 drivers/soc/bcm/Kconfig
+ create mode 100644 drivers/soc/bcm/Makefile
+ create mode 100644 drivers/soc/bcm/raspberrypi-power.c
+ create mode 100644 include/dt-bindings/power/raspberrypi-power.h
+
+--- a/drivers/soc/Kconfig
++++ b/drivers/soc/Kconfig
+@@ -1,5 +1,6 @@
+ menu "SOC (System On Chip) specific Drivers"
+
++source "drivers/soc/bcm/Kconfig"
+ source "drivers/soc/brcmstb/Kconfig"
+ source "drivers/soc/mediatek/Kconfig"
+ source "drivers/soc/qcom/Kconfig"
+--- a/drivers/soc/Makefile
++++ b/drivers/soc/Makefile
+@@ -2,6 +2,7 @@
+ # Makefile for the Linux Kernel SOC specific device drivers.
+ #
+
++obj-y += bcm/
+ obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/
+ obj-$(CONFIG_MACH_DOVE) += dove/
+ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+--- /dev/null
++++ b/drivers/soc/bcm/Kconfig
+@@ -0,0 +1,9 @@
++config RASPBERRYPI_POWER
++ bool "Raspberry Pi power domain driver"
++ depends on ARCH_BCM2835 || COMPILE_TEST
++ depends on RASPBERRYPI_FIRMWARE
++ select PM_GENERIC_DOMAINS if PM
++ select PM_GENERIC_DOMAINS_OF if PM
++ help
++ This enables support for the RPi power domains which can be enabled
++ or disabled via the RPi firmware.
+--- /dev/null
++++ b/drivers/soc/bcm/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o
+--- /dev/null
++++ b/drivers/soc/bcm/raspberrypi-power.c
+@@ -0,0 +1,247 @@
++/* (C) 2015 Pengutronix, Alexander Aring <aar@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Authors:
++ * Alexander Aring <aar@pengutronix.de>
++ * Eric Anholt <eric@anholt.net>
++ */
++
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/platform_device.h>
++#include <linux/pm_domain.h>
++#include <dt-bindings/power/raspberrypi-power.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++/*
++ * Firmware indices for the old power domains interface. Only a few
++ * of them were actually implemented.
++ */
++#define RPI_OLD_POWER_DOMAIN_USB 3
++#define RPI_OLD_POWER_DOMAIN_V3D 10
++
++struct rpi_power_domain {
++ u32 domain;
++ bool enabled;
++ bool old_interface;
++ struct generic_pm_domain base;
++ struct rpi_firmware *fw;
++};
++
++struct rpi_power_domains {
++ bool has_new_interface;
++ struct genpd_onecell_data xlate;
++ struct rpi_firmware *fw;
++ struct rpi_power_domain domains[RPI_POWER_DOMAIN_COUNT];
++};
++
++/*
++ * Packet definition used by RPI_FIRMWARE_SET_POWER_STATE and
++ * RPI_FIRMWARE_SET_DOMAIN_STATE
++ */
++struct rpi_power_domain_packet {
++ u32 domain;
++ u32 on;
++} __packet;
++
++/*
++ * Asks the firmware to enable or disable power on a specific power
++ * domain.
++ */
++static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on)
++{
++ struct rpi_power_domain_packet packet;
++
++ packet.domain = rpi_domain->domain;
++ packet.on = on;
++ return rpi_firmware_property(rpi_domain->fw,
++ rpi_domain->old_interface ?
++ RPI_FIRMWARE_SET_POWER_STATE :
++ RPI_FIRMWARE_SET_DOMAIN_STATE,
++ &packet, sizeof(packet));
++}
++
++static int rpi_domain_off(struct generic_pm_domain *domain)
++{
++ struct rpi_power_domain *rpi_domain =
++ container_of(domain, struct rpi_power_domain, base);
++
++ return rpi_firmware_set_power(rpi_domain, false);
++}
++
++static int rpi_domain_on(struct generic_pm_domain *domain)
++{
++ struct rpi_power_domain *rpi_domain =
++ container_of(domain, struct rpi_power_domain, base);
++
++ return rpi_firmware_set_power(rpi_domain, true);
++}
++
++static void rpi_common_init_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ dom->fw = rpi_domains->fw;
++
++ dom->base.name = name;
++ dom->base.power_on = rpi_domain_on;
++ dom->base.power_off = rpi_domain_off;
++
++ /*
++ * Treat all power domains as off at boot.
++ *
++ * The firmware itself may be keeping some domains on, but
++ * from Linux's perspective all we control is the refcounts
++ * that we give to the firmware, and we can't ask the firmware
++ * to turn off something that we haven't ourselves turned on.
++ */
++ pm_genpd_init(&dom->base, NULL, true);
++
++ rpi_domains->xlate.domains[xlate_index] = &dom->base;
++}
++
++static void rpi_init_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ if (!rpi_domains->has_new_interface)
++ return;
++
++ /* The DT binding index is the firmware's domain index minus one. */
++ dom->domain = xlate_index + 1;
++
++ rpi_common_init_power_domain(rpi_domains, xlate_index, name);
++}
++
++static void rpi_init_old_power_domain(struct rpi_power_domains *rpi_domains,
++ int xlate_index, int domain,
++ const char *name)
++{
++ struct rpi_power_domain *dom = &rpi_domains->domains[xlate_index];
++
++ dom->old_interface = true;
++ dom->domain = domain;
++
++ rpi_common_init_power_domain(rpi_domains, xlate_index, name);
++}
++
++/*
++ * Detects whether the firmware supports the new power domains interface.
++ *
++ * The firmware doesn't actually return an error on an unknown tag,
++ * and just skips over it, so we do the detection by putting an
++ * unexpected value in the return field and checking if it was
++ * unchanged.
++ */
++static bool
++rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains)
++{
++ struct rpi_power_domain_packet packet;
++ int ret;
++
++ packet.domain = RPI_POWER_DOMAIN_ARM;
++ packet.on = ~0;
++
++ ret = rpi_firmware_property(rpi_domains->fw,
++ RPI_FIRMWARE_GET_DOMAIN_STATE,
++ &packet, sizeof(packet));
++
++ return ret == 0 && packet.on != ~0;
++}
++
++static int rpi_power_probe(struct platform_device *pdev)
++{
++ struct device_node *fw_np;
++ struct device *dev = &pdev->dev;
++ struct rpi_power_domains *rpi_domains;
++
++ rpi_domains = devm_kzalloc(dev, sizeof(*rpi_domains), GFP_KERNEL);
++ if (!rpi_domains)
++ return -ENOMEM;
++
++ rpi_domains->xlate.domains =
++ devm_kzalloc(dev, sizeof(*rpi_domains->xlate.domains) *
++ RPI_POWER_DOMAIN_COUNT, GFP_KERNEL);
++ if (!rpi_domains->xlate.domains)
++ return -ENOMEM;
++
++ rpi_domains->xlate.num_domains = RPI_POWER_DOMAIN_COUNT;
++
++ fw_np = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
++ if (!fw_np) {
++ dev_err(&pdev->dev, "no firmware node\n");
++ return -ENODEV;
++ }
++
++ rpi_domains->fw = rpi_firmware_get(fw_np);
++ of_node_put(fw_np);
++ if (!rpi_domains->fw)
++ return -EPROBE_DEFER;
++
++ rpi_domains->has_new_interface =
++ rpi_has_new_domain_support(rpi_domains);
++
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C0, "I2C0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C1, "I2C1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_I2C2, "I2C2");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VIDEO_SCALER,
++ "VIDEO_SCALER");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VPU1, "VPU1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_HDMI, "HDMI");
++
++ /*
++ * Use the old firmware interface for USB power, so that we
++ * can turn it on even if the firmware hasn't been updated.
++ */
++ rpi_init_old_power_domain(rpi_domains, RPI_POWER_DOMAIN_USB,
++ RPI_OLD_POWER_DOMAIN_USB, "USB");
++
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_VEC, "VEC");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_JPEG, "JPEG");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_H264, "H264");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_V3D, "V3D");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ISP, "ISP");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM0, "UNICAM0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_UNICAM1, "UNICAM1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2RX, "CCP2RX");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CSI2, "CSI2");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CPI, "CPI");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI0, "DSI0");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_DSI1, "DSI1");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_TRANSPOSER,
++ "TRANSPOSER");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CCP2TX, "CCP2TX");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_CDP, "CDP");
++ rpi_init_power_domain(rpi_domains, RPI_POWER_DOMAIN_ARM, "ARM");
++
++ of_genpd_add_provider_onecell(dev->of_node, &rpi_domains->xlate);
++
++ platform_set_drvdata(pdev, rpi_domains);
++
++ return 0;
++}
++
++static const struct of_device_id rpi_power_of_match[] = {
++ { .compatible = "raspberrypi,bcm2835-power", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rpi_power_of_match);
++
++static struct platform_driver rpi_power_driver = {
++ .driver = {
++ .name = "raspberrypi-power",
++ .of_match_table = rpi_power_of_match,
++ },
++ .probe = rpi_power_probe,
++};
++builtin_platform_driver(rpi_power_driver);
++
++MODULE_AUTHOR("Alexander Aring <aar@pengutronix.de>");
++MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
++MODULE_DESCRIPTION("Raspberry Pi power domain driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/include/dt-bindings/power/raspberrypi-power.h
+@@ -0,0 +1,41 @@
++/*
++ * Copyright © 2015 Broadcom
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
++#define _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H
++
++/* These power domain indices are the firmware interface's indices
++ * minus one.
++ */
++#define RPI_POWER_DOMAIN_I2C0 0
++#define RPI_POWER_DOMAIN_I2C1 1
++#define RPI_POWER_DOMAIN_I2C2 2
++#define RPI_POWER_DOMAIN_VIDEO_SCALER 3
++#define RPI_POWER_DOMAIN_VPU1 4
++#define RPI_POWER_DOMAIN_HDMI 5
++#define RPI_POWER_DOMAIN_USB 6
++#define RPI_POWER_DOMAIN_VEC 7
++#define RPI_POWER_DOMAIN_JPEG 8
++#define RPI_POWER_DOMAIN_H264 9
++#define RPI_POWER_DOMAIN_V3D 10
++#define RPI_POWER_DOMAIN_ISP 11
++#define RPI_POWER_DOMAIN_UNICAM0 12
++#define RPI_POWER_DOMAIN_UNICAM1 13
++#define RPI_POWER_DOMAIN_CCP2RX 14
++#define RPI_POWER_DOMAIN_CSI2 15
++#define RPI_POWER_DOMAIN_CPI 16
++#define RPI_POWER_DOMAIN_DSI0 17
++#define RPI_POWER_DOMAIN_DSI1 18
++#define RPI_POWER_DOMAIN_TRANSPOSER 19
++#define RPI_POWER_DOMAIN_CCP2TX 20
++#define RPI_POWER_DOMAIN_CDP 21
++#define RPI_POWER_DOMAIN_ARM 22
++
++#define RPI_POWER_DOMAIN_COUNT 23
++
++#endif /* _DT_BINDINGS_ARM_BCM2835_RPI_POWER_H */
--- /dev/null
+From ac82db5c0d1e26b32d285100e423a89b35e188da Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 31 Dec 2015 23:39:14 +0100
+Subject: [PATCH 270/304] ARM: bcm2835: clarify RASPBERRYPI_FIRMWARE dependency
+
+The firmware driver can be a loadable module, but the power domain
+can only be built-in, so we get a build error in an allmodconfig
+kernel:
+
+:(.text+0x17e59c): undefined reference to `rpi_firmware_property'
+:(.text+0x17e51c): undefined reference to `rpi_firmware_get'
+:(.text+0x17e244): undefined reference to `rpi_firmware_property'
+
+This changes the dependency to only allow the power domain code
+to be enabled when the firmware driver is built-in. Other users
+of the firmware driver may still be loadable modules and not
+everyone needs the power domains, so we don't change the firmware
+code.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+(cherry picked from commit 22a5b1ddd83b991b96cb635898e011cce48bf6f8)
+---
+ drivers/soc/bcm/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/soc/bcm/Kconfig
++++ b/drivers/soc/bcm/Kconfig
+@@ -1,7 +1,7 @@
+ config RASPBERRYPI_POWER
+ bool "Raspberry Pi power domain driver"
+ depends on ARCH_BCM2835 || COMPILE_TEST
+- depends on RASPBERRYPI_FIRMWARE
++ depends on RASPBERRYPI_FIRMWARE=y
+ select PM_GENERIC_DOMAINS if PM
+ select PM_GENERIC_DOMAINS_OF if PM
+ help
--- /dev/null
+From 7d8d65cfc7508ec01431ead3e830d7d2f3886c05 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 19 Apr 2016 15:55:02 -0700
+Subject: [PATCH 271/304] ARM: bcm2708: Enable building power domain driver.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/soc/bcm/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/soc/bcm/Kconfig
++++ b/drivers/soc/bcm/Kconfig
+@@ -1,6 +1,6 @@
+ config RASPBERRYPI_POWER
+ bool "Raspberry Pi power domain driver"
+- depends on ARCH_BCM2835 || COMPILE_TEST
++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST
+ depends on RASPBERRYPI_FIRMWARE=y
+ select PM_GENERIC_DOMAINS if PM
+ select PM_GENERIC_DOMAINS_OF if PM
--- /dev/null
+From bf75d7a28fc441ac4be06169b3c4cba117e8fe65 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 19 Apr 2016 14:23:30 -0700
+Subject: [PATCH 272/304] bcm2708: Add RASPBERRYPI_POWER to the defconfigs.
+
+This will be used by the GPU driver for powering on HDMI at boot time
+and for 3D hang reset.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/configs/bcm2709_defconfig | 2 ++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -71,6 +71,7 @@ CONFIG_NEON=y
+ CONFIG_KERNEL_MODE_NEON=y
+ CONFIG_BINFMT_MISC=m
+ # CONFIG_SUSPEND is not set
++CONFIG_PM=y
+ CONFIG_NET=y
+ CONFIG_PACKET=y
+ CONFIG_UNIX=y
+@@ -1116,6 +1117,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m
+ CONFIG_MAILBOX=y
+ CONFIG_BCM2835_MBOX=y
+ # CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RASPBERRYPI_POWER=y
+ CONFIG_EXTCON=m
+ CONFIG_EXTCON_ARIZONA=m
+ CONFIG_IIO=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -64,6 +64,7 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+ CONFIG_VFP=y
+ CONFIG_BINFMT_MISC=m
+ # CONFIG_SUSPEND is not set
++CONFIG_PM=y
+ CONFIG_NET=y
+ CONFIG_PACKET=y
+ CONFIG_UNIX=y
+@@ -1123,6 +1124,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m
+ CONFIG_MAILBOX=y
+ CONFIG_BCM2835_MBOX=y
+ # CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RASPBERRYPI_POWER=y
+ CONFIG_EXTCON=m
+ CONFIG_EXTCON_ARIZONA=m
+ CONFIG_IIO=m
--- /dev/null
+From 2a94252c32f0235640f8f38b1222be411b8a43ae Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 19 Apr 2016 14:36:31 -0700
+Subject: [PATCH 273/304] bcm2708: Add the power domain driver to the device
+ tree.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/bcm2708_common.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2708_common.dtsi
++++ b/arch/arm/boot/dts/bcm2708_common.dtsi
+@@ -285,6 +285,12 @@
+ mboxes = <&mailbox>;
+ };
+
++ power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++ };
++
+ leds: leds {
+ compatible = "gpio-leds";
+ };
--- /dev/null
+From c0415cdea10f5e9ab7f01e840500cb4aeb660ee5 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 19 Apr 2016 14:40:08 -0700
+Subject: [PATCH 274/304] bcm2708: Reference the HDMI power domain for the HDMI
+ driver.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -6,6 +6,7 @@
+ /plugin/;
+
+ #include "dt-bindings/clock/bcm2835.h"
++#include "dt-bindings/power/raspberrypi-power.h"
+ #include "dt-bindings/gpio/gpio.h"
+
+ / {
+@@ -72,6 +73,7 @@
+ clocks = <&cprman BCM2835_PLLH_PIX>,
+ <&cprman BCM2835_CLOCK_HSM>;
+ clock-names = "pixel", "hdmi";
++ power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+ };
+
+ v3d@7ec00000 {
--- /dev/null
+From 543efa41ce1be43b927ddbb6c999063f8f4f9caa Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 17 Dec 2015 15:36:28 +0300
+Subject: [PATCH 275/304] drm/vc4: copy_to_user() returns the number of bytes
+ remaining
+
+The copy_to/from_user() functions return the number of bytes remaining
+to be copied. We want to return error codes here.
+
+Also it's a bad idea to print an error message if a copy from user fails
+because users can use that to spam /var/log/messages which is annoying
+so I removed those.
+
+Fixes: 214613656b51 ('drm/vc4: Add an interface for capturing the GPU state after a hang.')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 65c4777de54a39b2722a4b1ff3306d044014d511)
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 37 ++++++++++++++++++-------------------
+ 1 file changed, 18 insertions(+), 19 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -85,7 +85,7 @@ vc4_get_hang_state_ioctl(struct drm_devi
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ unsigned long irqflags;
+ u32 i;
+- int ret;
++ int ret = 0;
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+ kernel_state = vc4->hang_state;
+@@ -133,9 +133,11 @@ vc4_get_hang_state_ioctl(struct drm_devi
+ 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));
++ if (copy_to_user((void __user *)(uintptr_t)get_state->bo,
++ bo_state,
++ state->bo_count * sizeof(*bo_state)))
++ ret = -EFAULT;
++
+ kfree(bo_state);
+
+ err_free:
+@@ -563,27 +565,24 @@ vc4_get_bcl(struct drm_device *dev, stru
+ 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");
++ if (copy_from_user(bin,
++ (void __user *)(uintptr_t)args->bin_cl,
++ args->bin_cl_size)) {
++ ret = -EFAULT;
+ 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");
++ if (copy_from_user(exec->shader_rec_u,
++ (void __user *)(uintptr_t)args->shader_rec,
++ args->shader_rec_size)) {
++ ret = -EFAULT;
+ 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");
++ if (copy_from_user(exec->uniforms_u,
++ (void __user *)(uintptr_t)args->uniforms,
++ args->uniforms_size)) {
++ ret = -EFAULT;
+ goto fail;
+ }
+
--- /dev/null
+From bedbbde45f7c1fce63e5f2c4e21bc9dd4e20f3c0 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 17 Dec 2015 15:39:08 +0300
+Subject: [PATCH 276/304] drm/vc4: allocate enough memory in
+ vc4_save_hang_state()
+
+"state" is smaller than "kernel_state" so we end up corrupting memory.
+
+Fixes: 214613656b51 ('drm/vc4: Add an interface for capturing the GPU state after a hang.')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 7e5082fbc00cc157e57a70cdb6b9bbb21289afb1)
+---
+ drivers/gpu/drm/vc4/vc4_gem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -159,7 +159,7 @@ vc4_save_hang_state(struct drm_device *d
+ unsigned long irqflags;
+ unsigned int i, unref_list_count;
+
+- kernel_state = kcalloc(1, sizeof(*state), GFP_KERNEL);
++ kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL);
+ if (!kernel_state)
+ return;
+
--- /dev/null
+From a9d885719c6b17fe34cf4df2e7754aaeab352b4c Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Mon, 18 Jan 2016 09:10:42 +1000
+Subject: [PATCH 277/304] drm/vc4: fix warning in validate printf.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This just fixes a warning on 64-bit builds:
+
+ drivers/gpu/drm/vc4/vc4_validate.c: In function ‘validate_gl_shader_rec’:
+ drivers/gpu/drm/vc4/vc4_validate.c:864:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
+
+Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+(cherry picked from commit c671e1e30259da587d7a0162895200601979ee65)
+---
+ drivers/gpu/drm/vc4/vc4_validate.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_validate.c
++++ b/drivers/gpu/drm/vc4/vc4_validate.c
+@@ -861,7 +861,7 @@ validate_gl_shader_rec(struct drm_device
+
+ if (vbo->base.size < offset ||
+ vbo->base.size - offset < attr_size) {
+- DRM_ERROR("BO offset overflow (%d + %d > %d)\n",
++ DRM_ERROR("BO offset overflow (%d + %d > %zu)\n",
+ offset, attr_size, vbo->base.size);
+ return -EINVAL;
+ }
--- /dev/null
+From 3049b5e72472a580753328c31e191fac5e3b151b Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 28 Dec 2015 14:14:09 -0800
+Subject: [PATCH 278/304] drm/vc4: Improve comments on vc4_plane_state members.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit f427fb16cf756548c39256b569cf083f39bcc4e9)
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -26,16 +26,19 @@
+
+ struct vc4_plane_state {
+ struct drm_plane_state base;
++ /* System memory copy of the display list for this element, computed
++ * at atomic_check time.
++ */
+ u32 *dlist;
+- u32 dlist_size; /* Number of dwords in allocated for the display list */
++ u32 dlist_size; /* Number of dwords 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.
+- */
++ * hardware at vc4_crtc_atomic_flush() time.
++ */
+ u32 *hw_dlist;
+ };
+
--- /dev/null
+From 3bf29123a33a5f8c786e35e12310d82b61c68237 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 28 Dec 2015 14:14:57 -0800
+Subject: [PATCH 279/304] drm/vc4: Add missing __iomem annotation to hw_dlist.
+
+This is the pointer to the HVS device's memory where we stored the
+contents of *dlist.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 17eac75111ebda33e13d8d8d98aaedfc1a9c2abf)
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -39,7 +39,7 @@ struct vc4_plane_state {
+ /* Offset where the plane's dlist was last stored in the
+ * hardware at vc4_crtc_atomic_flush() time.
+ */
+- u32 *hw_dlist;
++ u32 __iomem *hw_dlist;
+ };
+
+ static inline struct vc4_plane_state *
--- /dev/null
+From 85b7377efcfbf19aa6b0602ba3aa501ce7e7c9bd Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 28 Dec 2015 14:34:44 -0800
+Subject: [PATCH 280/304] drm/vc4: Move the plane clipping/scaling setup to a
+ separate function.
+
+As we add actual scaling, this is going to get way more complicated.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 5c6799942003df91801b1d2277bba34d71f99603)
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 78 +++++++++++++++++++++++++++--------------
+ 1 file changed, 52 insertions(+), 26 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -40,6 +40,14 @@ struct vc4_plane_state {
+ * hardware at vc4_crtc_atomic_flush() time.
+ */
+ u32 __iomem *hw_dlist;
++
++ /* Clipped coordinates of the plane on the display. */
++ int crtc_x, crtc_y, crtc_w, crtc_h;
++
++ /* Offset to start scanning out from the start of the plane's
++ * BO.
++ */
++ u32 offset;
+ };
+
+ static inline struct vc4_plane_state *
+@@ -167,22 +175,17 @@ static void vc4_dlist_write(struct vc4_p
+ vc4_state->dlist[vc4_state->dlist_count++] = val;
+ }
+
+-/* Writes out a full display list for an active plane to the plane's
+- * private dlist state.
+- */
+-static int vc4_plane_mode_set(struct drm_plane *plane,
+- struct drm_plane_state *state)
++static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+ {
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
+- struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+- u32 ctl0_offset = vc4_state->dlist_count;
+- const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
+- uint32_t offset = fb->offsets[0];
+- int crtc_x = state->crtc_x;
+- int crtc_y = state->crtc_y;
+- int crtc_w = state->crtc_w;
+- int crtc_h = state->crtc_h;
++
++ vc4_state->offset = fb->offsets[0];
++
++ vc4_state->crtc_x = state->crtc_x;
++ vc4_state->crtc_y = state->crtc_y;
++ vc4_state->crtc_w = state->crtc_w;
++ vc4_state->crtc_h = state->crtc_h;
+
+ if (state->crtc_w << 16 != state->src_w ||
+ state->crtc_h << 16 != state->src_h) {
+@@ -194,18 +197,41 @@ static int vc4_plane_mode_set(struct drm
+ return -EINVAL;
+ }
+
+- if (crtc_x < 0) {
+- offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
+- crtc_w += crtc_x;
+- crtc_x = 0;
++ if (vc4_state->crtc_x < 0) {
++ vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format,
++ 0) *
++ -vc4_state->crtc_x);
++ vc4_state->crtc_w += vc4_state->crtc_x;
++ vc4_state->crtc_x = 0;
+ }
+
+- if (crtc_y < 0) {
+- offset += fb->pitches[0] * -crtc_y;
+- crtc_h += crtc_y;
+- crtc_y = 0;
++ if (vc4_state->crtc_y < 0) {
++ vc4_state->offset += fb->pitches[0] * -vc4_state->crtc_y;
++ vc4_state->crtc_h += vc4_state->crtc_y;
++ vc4_state->crtc_y = 0;
+ }
+
++ return 0;
++}
++
++
++/* Writes out a full display list for an active plane to the plane's
++ * private dlist state.
++ */
++static int vc4_plane_mode_set(struct drm_plane *plane,
++ struct drm_plane_state *state)
++{
++ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
++ struct drm_framebuffer *fb = state->fb;
++ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
++ u32 ctl0_offset = vc4_state->dlist_count;
++ const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
++ int ret;
++
++ ret = vc4_plane_setup_clipping_and_scaling(state);
++ if (ret)
++ return ret;
++
+ vc4_dlist_write(vc4_state,
+ SCALER_CTL0_VALID |
+ (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
+@@ -215,8 +241,8 @@ static int vc4_plane_mode_set(struct drm
+ /* Position Word 0: Image Positions and Alpha Value */
+ vc4_dlist_write(vc4_state,
+ VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
+- VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
+- VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
++ VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) |
++ VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y));
+
+ /* Position Word 1: Scaled Image Dimensions.
+ * Skipped due to SCALER_CTL0_UNITY scaling.
+@@ -228,8 +254,8 @@ static int vc4_plane_mode_set(struct drm
+ SCALER_POS2_ALPHA_MODE_PIPELINE :
+ SCALER_POS2_ALPHA_MODE_FIXED,
+ SCALER_POS2_ALPHA_MODE) |
+- VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
+- VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
++ VC4_SET_FIELD(vc4_state->crtc_w, SCALER_POS2_WIDTH) |
++ VC4_SET_FIELD(vc4_state->crtc_h, SCALER_POS2_HEIGHT));
+
+ /* Position Word 3: Context. Written by the HVS. */
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+@@ -237,7 +263,7 @@ static int vc4_plane_mode_set(struct drm
+ vc4_state->pw0_offset = vc4_state->dlist_count;
+
+ /* Pointer Word 0: RGB / Y Pointer */
+- vc4_dlist_write(vc4_state, bo->paddr + offset);
++ vc4_dlist_write(vc4_state, bo->paddr + vc4_state->offset);
+
+ /* Pointer Context Word 0: Written by the HVS */
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
--- /dev/null
+From a53e75a061bbfb0bb24128a2a9c9961ec20e22ec Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 30 Dec 2015 11:50:22 -0800
+Subject: [PATCH 281/304] drm/vc4: Add a proper short-circut path for legacy
+ cursor updates.
+
+Previously, on every modeset we would allocate new display list
+memory, recompute changed planes, write all of them to the new memory,
+and pointed scanout at the new list (which will latch approximately at
+the next line of scanout). We let
+drm_atomic_helper_wait_for_vblanks() decide whether we needed to wait
+for a vblank after a modeset before cleaning up the old state and
+letting the next modeset proceed, and on legacy cursor updates we
+wouldn't wait. If you moved the cursor fast enough, we could
+potentially wrap around the display list memory area and overwrite the
+existing display list while it was still being scanned out, resulting
+in the HVS scanning out garbage or just halting.
+
+Instead of making cursor updates wait for scanout to move to the new
+display list area (which introduces significant cursor lag in X), we
+just rewrite our current display list.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 6674a904d68041d982ffb284d2827410765a097a)
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 9 ++++
+ drivers/gpu/drm/vc4/vc4_plane.c | 94 ++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 96 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -49,6 +49,15 @@ vc4_atomic_complete_commit(struct vc4_co
+
+ drm_atomic_helper_commit_modeset_enables(dev, state);
+
++ /* Make sure that drm_atomic_helper_wait_for_vblanks()
++ * actually waits for vblank. If we're doing a full atomic
++ * modeset (as opposed to a vc4_update_plane() short circuit),
++ * then we need to wait for scanout to be done with our
++ * display lists before we free it and potentially reallocate
++ * and overwrite the dlist memory with a new modeset.
++ */
++ state->legacy_cursor_update = false;
++
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -33,8 +33,12 @@ struct vc4_plane_state {
+ u32 dlist_size; /* Number of dwords 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 in the dlist to various words, for pageflip or
++ * cursor updates.
++ */
++ u32 pos0_offset;
++ u32 pos2_offset;
++ u32 ptr0_offset;
+
+ /* Offset where the plane's dlist was last stored in the
+ * hardware at vc4_crtc_atomic_flush() time.
+@@ -239,6 +243,7 @@ static int vc4_plane_mode_set(struct drm
+ SCALER_CTL0_UNITY);
+
+ /* Position Word 0: Image Positions and Alpha Value */
++ vc4_state->pos0_offset = vc4_state->dlist_count;
+ vc4_dlist_write(vc4_state,
+ VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
+ VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) |
+@@ -249,6 +254,7 @@ static int vc4_plane_mode_set(struct drm
+ */
+
+ /* Position Word 2: Source Image Size, Alpha Mode */
++ vc4_state->pos2_offset = vc4_state->dlist_count;
+ vc4_dlist_write(vc4_state,
+ VC4_SET_FIELD(format->has_alpha ?
+ SCALER_POS2_ALPHA_MODE_PIPELINE :
+@@ -260,9 +266,8 @@ static int vc4_plane_mode_set(struct drm
+ /* 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_state->ptr0_offset = vc4_state->dlist_count;
+ vc4_dlist_write(vc4_state, bo->paddr + vc4_state->offset);
+
+ /* Pointer Context Word 0: Written by the HVS */
+@@ -348,13 +353,13 @@ void vc4_plane_async_set_fb(struct drm_p
+ * 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]);
++ writel(addr, &vc4_state->hw_dlist[vc4_state->ptr0_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;
++ vc4_state->dlist[vc4_state->ptr0_offset] = addr;
+ }
+
+ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
+@@ -370,8 +375,83 @@ static void vc4_plane_destroy(struct drm
+ drm_plane_cleanup(plane);
+ }
+
++/* Implements immediate (non-vblank-synced) updates of the cursor
++ * position, or falls back to the atomic helper otherwise.
++ */
++static int
++vc4_update_plane(struct drm_plane *plane,
++ struct drm_crtc *crtc,
++ struct drm_framebuffer *fb,
++ int crtc_x, int crtc_y,
++ unsigned int crtc_w, unsigned int crtc_h,
++ uint32_t src_x, uint32_t src_y,
++ uint32_t src_w, uint32_t src_h)
++{
++ struct drm_plane_state *plane_state;
++ struct vc4_plane_state *vc4_state;
++
++ if (plane != crtc->cursor)
++ goto out;
++
++ plane_state = plane->state;
++ vc4_state = to_vc4_plane_state(plane_state);
++
++ if (!plane_state)
++ goto out;
++
++ /* If we're changing the cursor contents, do that in the
++ * normal vblank-synced atomic path.
++ */
++ if (fb != plane_state->fb)
++ goto out;
++
++ /* No configuring new scaling in the fast path. */
++ if (crtc_w != plane_state->crtc_w ||
++ crtc_h != plane_state->crtc_h ||
++ src_w != plane_state->src_w ||
++ src_h != plane_state->src_h) {
++ goto out;
++ }
++
++ /* Set the cursor's position on the screen. This is the
++ * expected change from the drm_mode_cursor_universal()
++ * helper.
++ */
++ plane_state->crtc_x = crtc_x;
++ plane_state->crtc_y = crtc_y;
++
++ /* Allow changing the start position within the cursor BO, if
++ * that matters.
++ */
++ plane_state->src_x = src_x;
++ plane_state->src_y = src_y;
++
++ /* Update the display list based on the new crtc_x/y. */
++ vc4_plane_atomic_check(plane, plane_state);
++
++ /* Note that we can't just call vc4_plane_write_dlist()
++ * because that would smash the context data that the HVS is
++ * currently using.
++ */
++ writel(vc4_state->dlist[vc4_state->pos0_offset],
++ &vc4_state->hw_dlist[vc4_state->pos0_offset]);
++ writel(vc4_state->dlist[vc4_state->pos2_offset],
++ &vc4_state->hw_dlist[vc4_state->pos2_offset]);
++ writel(vc4_state->dlist[vc4_state->ptr0_offset],
++ &vc4_state->hw_dlist[vc4_state->ptr0_offset]);
++
++ return 0;
++
++out:
++ return drm_atomic_helper_update_plane(plane, crtc, fb,
++ crtc_x, crtc_y,
++ crtc_w, crtc_h,
++ src_x, src_y,
++ src_w, src_h);
++}
++
+ static const struct drm_plane_funcs vc4_plane_funcs = {
+- .update_plane = drm_atomic_helper_update_plane,
++ .update_plane = vc4_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = vc4_plane_destroy,
+ .set_property = NULL,
--- /dev/null
+From 85d92a47f1a200de3ea7cd0a3d790b2a286ade40 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 28 Dec 2015 13:25:41 -0800
+Subject: [PATCH 282/304] drm/vc4: Make the CRTCs cooperate on allocating
+ display lists.
+
+So far, we've only ever lit up one CRTC, so this has been fine. To
+extend to more displays or more planes, we need to make sure we don't
+run our display lists into each other.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit d8dbf44f13b91185c618219d912b246817a8d132)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 115 +++++++++++++++++++++++------------------
+ drivers/gpu/drm/vc4/vc4_drv.h | 8 ++-
+ drivers/gpu/drm/vc4/vc4_hvs.c | 13 +++++
+ 3 files changed, 84 insertions(+), 52 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -49,22 +49,27 @@ struct vc4_crtc {
+ /* Which HVS channel we're using for our CRTC. */
+ int channel;
+
+- /* Pointer to the actual hardware display list memory for the
+- * crtc.
+- */
+- u32 __iomem *dlist;
+-
+- u32 dlist_size; /* in dwords */
+-
+ struct drm_pending_vblank_event *event;
+ };
+
++struct vc4_crtc_state {
++ struct drm_crtc_state base;
++ /* Dlist area for this CRTC configuration. */
++ struct drm_mm_node mm;
++};
++
+ static inline struct vc4_crtc *
+ to_vc4_crtc(struct drm_crtc *crtc)
+ {
+ return (struct vc4_crtc *)crtc;
+ }
+
++static inline struct vc4_crtc_state *
++to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
++{
++ return (struct vc4_crtc_state *)crtc_state;
++}
++
+ struct vc4_crtc_data {
+ /* Which channel of the HVS this pixelvalve sources from. */
+ int hvs_channel;
+@@ -319,11 +324,13 @@ static void vc4_crtc_enable(struct drm_c
+ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+ {
++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct drm_plane *plane;
+- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++ unsigned long flags;
+ u32 dlist_count = 0;
++ int ret;
+
+ /* The pixelvalve can only feed one encoder (and encoders are
+ * 1:1 with connectors.)
+@@ -346,18 +353,12 @@ static int vc4_crtc_atomic_check(struct
+
+ dlist_count++; /* Account for SCALER_CTL0_END. */
+
+- if (!vc4_crtc->dlist || dlist_count > vc4_crtc->dlist_size) {
+- vc4_crtc->dlist = ((u32 __iomem *)vc4->hvs->dlist +
+- HVS_BOOTLOADER_DLIST_END);
+- vc4_crtc->dlist_size = ((SCALER_DLIST_SIZE >> 2) -
+- HVS_BOOTLOADER_DLIST_END);
+-
+- if (dlist_count > vc4_crtc->dlist_size) {
+- DRM_DEBUG_KMS("dlist too large for CRTC (%d > %d).\n",
+- dlist_count, vc4_crtc->dlist_size);
+- return -EINVAL;
+- }
+- }
++ spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
++ ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm,
++ dlist_count, 1, 0);
++ spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags);
++ if (ret)
++ return ret;
+
+ return 0;
+ }
+@@ -368,47 +369,29 @@ static void vc4_crtc_atomic_flush(struct
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+ struct drm_plane *plane;
+ bool debug_dump_regs = false;
+- u32 __iomem *dlist_next = vc4_crtc->dlist;
++ u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
++ u32 __iomem *dlist_next = dlist_start;
+
+ if (debug_dump_regs) {
+ DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
+ vc4_hvs_dump_state(dev);
+ }
+
+- /* Copy all the active planes' dlist contents to the hardware dlist.
+- *
+- * XXX: If the new display list was large enough that it
+- * overlapped a currently-read display list, we need to do
+- * something like disable scanout before putting in the new
+- * list. For now, we're safe because we only have the two
+- * planes.
+- */
++ /* Copy all the active planes' dlist contents to the hardware dlist. */
+ drm_atomic_crtc_for_each_plane(plane, crtc) {
+ dlist_next += vc4_plane_write_dlist(plane, dlist_next);
+ }
+
+- if (dlist_next == vc4_crtc->dlist) {
+- /* If no planes were enabled, use the SCALER_CTL0_END
+- * at the start of the display list memory (in the
+- * bootloader section). We'll rewrite that
+- * SCALER_CTL0_END, just in case, though.
+- */
+- writel(SCALER_CTL0_END, vc4->hvs->dlist);
+- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 0);
+- } else {
+- writel(SCALER_CTL0_END, dlist_next);
+- dlist_next++;
+-
+- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+- (u32 __iomem *)vc4_crtc->dlist -
+- (u32 __iomem *)vc4->hvs->dlist);
+-
+- /* Make the next display list start after ours. */
+- vc4_crtc->dlist_size -= (dlist_next - vc4_crtc->dlist);
+- vc4_crtc->dlist = dlist_next;
+- }
++ writel(SCALER_CTL0_END, dlist_next);
++ dlist_next++;
++
++ WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
++
++ HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
++ vc4_state->mm.start);
+
+ if (debug_dump_regs) {
+ DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
+@@ -573,6 +556,36 @@ static int vc4_page_flip(struct drm_crtc
+ return drm_atomic_helper_page_flip(crtc, fb, event, flags);
+ }
+
++static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
++{
++ struct vc4_crtc_state *vc4_state;
++
++ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
++ if (!vc4_state)
++ return NULL;
++
++ __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
++ return &vc4_state->base;
++}
++
++static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
++ struct drm_crtc_state *state)
++{
++ struct vc4_dev *vc4 = to_vc4_dev(crtc->dev);
++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
++
++ if (vc4_state->mm.allocated) {
++ unsigned long flags;
++
++ spin_lock_irqsave(&vc4->hvs->mm_lock, flags);
++ drm_mm_remove_node(&vc4_state->mm);
++ spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags);
++
++ }
++
++ __drm_atomic_helper_crtc_destroy_state(crtc, state);
++}
++
+ static const struct drm_crtc_funcs vc4_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = vc4_crtc_destroy,
+@@ -581,8 +594,8 @@ static const struct drm_crtc_funcs vc4_c
+ .cursor_set = NULL, /* handled by drm_mode_cursor_universal */
+ .cursor_move = NULL, /* handled by drm_mode_cursor_universal */
+ .reset = drm_atomic_helper_crtc_reset,
+- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+- .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
++ .atomic_duplicate_state = vc4_crtc_duplicate_state,
++ .atomic_destroy_state = vc4_crtc_destroy_state,
+ };
+
+ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -150,7 +150,13 @@ struct vc4_v3d {
+ struct vc4_hvs {
+ struct platform_device *pdev;
+ void __iomem *regs;
+- void __iomem *dlist;
++ u32 __iomem *dlist;
++
++ /* Memory manager for CRTCs to allocate space in the display
++ * list. Units are dwords.
++ */
++ struct drm_mm dlist_mm;
++ spinlock_t mm_lock;
+ };
+
+ struct vc4_plane {
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -119,6 +119,17 @@ static int vc4_hvs_bind(struct device *d
+
+ hvs->dlist = hvs->regs + SCALER_DLIST_START;
+
++ spin_lock_init(&hvs->mm_lock);
++
++ /* Set up the HVS display list memory manager. We never
++ * overwrite the setup from the bootloader (just 128b out of
++ * our 16K), since we don't want to scramble the screen when
++ * transitioning from the firmware's boot setup to runtime.
++ */
++ drm_mm_init(&hvs->dlist_mm,
++ HVS_BOOTLOADER_DLIST_END,
++ (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END);
++
+ vc4->hvs = hvs;
+ return 0;
+ }
+@@ -129,6 +140,8 @@ static void vc4_hvs_unbind(struct device
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dev *vc4 = drm->dev_private;
+
++ drm_mm_takedown(&vc4->hvs->dlist_mm);
++
+ vc4->hvs = NULL;
+ }
+
--- /dev/null
+From 340763d1863fe246b44405edeba01889c81e5cb7 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 20 Oct 2015 14:18:56 +0100
+Subject: [PATCH 283/304] drm/vc4: Add more display planes to each CRTC.
+
+Previously we only did the primary and cursor plane, but overlay
+planes are useful and just require this setup to add, since all planes
+go into the HVS display list in the same way.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit fc2d6f1eabee9d971453da2a27a72471c2a347dd)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 56 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -677,9 +677,9 @@ static int vc4_crtc_bind(struct device *
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct vc4_crtc *vc4_crtc;
+ struct drm_crtc *crtc;
+- struct drm_plane *primary_plane, *cursor_plane;
++ struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp;
+ const struct of_device_id *match;
+- int ret;
++ int ret, i;
+
+ vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+ if (!vc4_crtc)
+@@ -708,27 +708,49 @@ static int vc4_crtc_bind(struct device *
+ goto err;
+ }
+
+- cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
+- if (IS_ERR(cursor_plane)) {
+- dev_err(dev, "failed to construct cursor plane\n");
+- ret = PTR_ERR(cursor_plane);
+- goto err_primary;
+- }
+-
+- drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
++ drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
+ &vc4_crtc_funcs);
+ drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+ primary_plane->crtc = crtc;
+- cursor_plane->crtc = crtc;
+ vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
+ vc4_crtc->channel = vc4_crtc->data->hvs_channel;
+
++ /* Set up some arbitrary number of planes. We're not limited
++ * by a set number of physical registers, just the space in
++ * the HVS (16k) and how small an plane can be (28 bytes).
++ * However, each plane we set up takes up some memory, and
++ * increases the cost of looping over planes, which atomic
++ * modesetting does quite a bit. As a result, we pick a
++ * modest number of planes to expose, that should hopefully
++ * still cover any sane usecase.
++ */
++ for (i = 0; i < 8; i++) {
++ struct drm_plane *plane =
++ vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
++
++ if (IS_ERR(plane))
++ continue;
++
++ plane->possible_crtcs = 1 << drm_crtc_index(crtc);
++ }
++
++ /* Set up the legacy cursor after overlay initialization,
++ * since we overlay planes on the CRTC in the order they were
++ * initialized.
++ */
++ cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
++ if (!IS_ERR(cursor_plane)) {
++ cursor_plane->possible_crtcs = 1 << drm_crtc_index(crtc);
++ cursor_plane->crtc = crtc;
++ crtc->cursor = cursor_plane;
++ }
++
+ CRTC_WRITE(PV_INTEN, 0);
+ CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
+ vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
+ if (ret)
+- goto err_cursor;
++ goto err_destroy_planes;
+
+ vc4_set_crtc_possible_masks(drm, crtc);
+
+@@ -736,10 +758,12 @@ static int vc4_crtc_bind(struct device *
+
+ return 0;
+
+-err_cursor:
+- cursor_plane->funcs->destroy(cursor_plane);
+-err_primary:
+- primary_plane->funcs->destroy(primary_plane);
++err_destroy_planes:
++ list_for_each_entry_safe(destroy_plane, temp,
++ &drm->mode_config.plane_list, head) {
++ if (destroy_plane->possible_crtcs == 1 << drm_crtc_index(crtc))
++ destroy_plane->funcs->destroy(destroy_plane);
++ }
+ err:
+ return ret;
+ }
--- /dev/null
+From 309b7268e9cc7baa21d195cc98387cb984720185 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 28 Dec 2015 14:45:25 -0800
+Subject: [PATCH 284/304] drm/vc4: Fix which value is being used for source
+ image size.
+
+This doesn't matter yet since we only allow 1:1 scaling, but the
+comment clearly says we should be using the source size.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit f863e356013d628fa65b1cd89aa298eed26fc936)
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -47,6 +47,8 @@ struct vc4_plane_state {
+
+ /* Clipped coordinates of the plane on the display. */
+ int crtc_x, crtc_y, crtc_w, crtc_h;
++ /* Clipped size of the area scanned from in the FB. */
++ u32 src_w, src_h;
+
+ /* Offset to start scanning out from the start of the plane's
+ * BO.
+@@ -186,11 +188,6 @@ static int vc4_plane_setup_clipping_and_
+
+ vc4_state->offset = fb->offsets[0];
+
+- vc4_state->crtc_x = state->crtc_x;
+- vc4_state->crtc_y = state->crtc_y;
+- vc4_state->crtc_w = state->crtc_w;
+- vc4_state->crtc_h = state->crtc_h;
+-
+ if (state->crtc_w << 16 != state->src_w ||
+ state->crtc_h << 16 != state->src_h) {
+ /* We don't support scaling yet, which involves
+@@ -201,17 +198,25 @@ static int vc4_plane_setup_clipping_and_
+ return -EINVAL;
+ }
+
++ vc4_state->src_w = state->src_w >> 16;
++ vc4_state->src_h = state->src_h >> 16;
++
++ vc4_state->crtc_x = state->crtc_x;
++ vc4_state->crtc_y = state->crtc_y;
++ vc4_state->crtc_w = state->crtc_w;
++ vc4_state->crtc_h = state->crtc_h;
++
+ if (vc4_state->crtc_x < 0) {
+ vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format,
+ 0) *
+ -vc4_state->crtc_x);
+- vc4_state->crtc_w += vc4_state->crtc_x;
++ vc4_state->src_w += vc4_state->crtc_x;
+ vc4_state->crtc_x = 0;
+ }
+
+ if (vc4_state->crtc_y < 0) {
+ vc4_state->offset += fb->pitches[0] * -vc4_state->crtc_y;
+- vc4_state->crtc_h += vc4_state->crtc_y;
++ vc4_state->src_h += vc4_state->crtc_y;
+ vc4_state->crtc_y = 0;
+ }
+
+@@ -260,8 +265,8 @@ static int vc4_plane_mode_set(struct drm
+ SCALER_POS2_ALPHA_MODE_PIPELINE :
+ SCALER_POS2_ALPHA_MODE_FIXED,
+ SCALER_POS2_ALPHA_MODE) |
+- VC4_SET_FIELD(vc4_state->crtc_w, SCALER_POS2_WIDTH) |
+- VC4_SET_FIELD(vc4_state->crtc_h, SCALER_POS2_HEIGHT));
++ VC4_SET_FIELD(vc4_state->src_w, SCALER_POS2_WIDTH) |
++ VC4_SET_FIELD(vc4_state->src_h, SCALER_POS2_HEIGHT));
+
+ /* Position Word 3: Context. Written by the HVS. */
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
--- /dev/null
+From 82360945a8104336f585180cd8d9c5fe4099d94b Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 20 Oct 2015 16:06:57 +0100
+Subject: [PATCH 285/304] drm/vc4: Add support for scaling of display planes.
+
+This implements a simple policy for choosing scaling modes
+(trapezoidal for decimation, PPF for magnification), and a single PPF
+filter (Mitchell/Netravali's recommendation).
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 21af94cf1a4c2d3450ab7fead58e6e2291ab92a9)
+---
+ drivers/gpu/drm/vc4/vc4_drv.h | 4 +
+ drivers/gpu/drm/vc4/vc4_hvs.c | 84 +++++++++++++
+ drivers/gpu/drm/vc4/vc4_plane.c | 253 +++++++++++++++++++++++++++++++++++++---
+ drivers/gpu/drm/vc4/vc4_regs.h | 46 ++++++++
+ 4 files changed, 374 insertions(+), 13 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -156,7 +156,11 @@ struct vc4_hvs {
+ * list. Units are dwords.
+ */
+ struct drm_mm dlist_mm;
++ /* Memory manager for the LBM memory used by HVS scaling. */
++ struct drm_mm lbm_mm;
+ spinlock_t mm_lock;
++
++ struct drm_mm_node mitchell_netravali_filter;
+ };
+
+ struct vc4_plane {
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -100,12 +100,76 @@ int vc4_hvs_debugfs_regs(struct seq_file
+ }
+ #endif
+
++/* The filter kernel is composed of dwords each containing 3 9-bit
++ * signed integers packed next to each other.
++ */
++#define VC4_INT_TO_COEFF(coeff) (coeff & 0x1ff)
++#define VC4_PPF_FILTER_WORD(c0, c1, c2) \
++ ((((c0) & 0x1ff) << 0) | \
++ (((c1) & 0x1ff) << 9) | \
++ (((c2) & 0x1ff) << 18))
++
++/* The whole filter kernel is arranged as the coefficients 0-16 going
++ * up, then a pad, then 17-31 going down and reversed within the
++ * dwords. This means that a linear phase kernel (where it's
++ * symmetrical at the boundary between 15 and 16) has the last 5
++ * dwords matching the first 5, but reversed.
++ */
++#define VC4_LINEAR_PHASE_KERNEL(c0, c1, c2, c3, c4, c5, c6, c7, c8, \
++ c9, c10, c11, c12, c13, c14, c15) \
++ {VC4_PPF_FILTER_WORD(c0, c1, c2), \
++ VC4_PPF_FILTER_WORD(c3, c4, c5), \
++ VC4_PPF_FILTER_WORD(c6, c7, c8), \
++ VC4_PPF_FILTER_WORD(c9, c10, c11), \
++ VC4_PPF_FILTER_WORD(c12, c13, c14), \
++ VC4_PPF_FILTER_WORD(c15, c15, 0)}
++
++#define VC4_LINEAR_PHASE_KERNEL_DWORDS 6
++#define VC4_KERNEL_DWORDS (VC4_LINEAR_PHASE_KERNEL_DWORDS * 2 - 1)
++
++/* Recommended B=1/3, C=1/3 filter choice from Mitchell/Netravali.
++ * http://www.cs.utexas.edu/~fussell/courses/cs384g/lectures/mitchell/Mitchell.pdf
++ */
++static const u32 mitchell_netravali_1_3_1_3_kernel[] =
++ VC4_LINEAR_PHASE_KERNEL(0, -2, -6, -8, -10, -8, -3, 2, 18,
++ 50, 82, 119, 155, 187, 213, 227);
++
++static int vc4_hvs_upload_linear_kernel(struct vc4_hvs *hvs,
++ struct drm_mm_node *space,
++ const u32 *kernel)
++{
++ int ret, i;
++ u32 __iomem *dst_kernel;
++
++ ret = drm_mm_insert_node(&hvs->dlist_mm, space, VC4_KERNEL_DWORDS, 1,
++ 0);
++ if (ret) {
++ DRM_ERROR("Failed to allocate space for filter kernel: %d\n",
++ ret);
++ return ret;
++ }
++
++ dst_kernel = hvs->dlist + space->start;
++
++ for (i = 0; i < VC4_KERNEL_DWORDS; i++) {
++ if (i < VC4_LINEAR_PHASE_KERNEL_DWORDS)
++ writel(kernel[i], &dst_kernel[i]);
++ else {
++ writel(kernel[VC4_KERNEL_DWORDS - i - 1],
++ &dst_kernel[i]);
++ }
++ }
++
++ return 0;
++}
++
+ static int vc4_hvs_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 = drm->dev_private;
+ struct vc4_hvs *hvs = NULL;
++ int ret;
+
+ hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
+ if (!hvs)
+@@ -130,6 +194,22 @@ static int vc4_hvs_bind(struct device *d
+ HVS_BOOTLOADER_DLIST_END,
+ (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END);
+
++ /* Set up the HVS LBM memory manager. We could have some more
++ * complicated data structure that allowed reuse of LBM areas
++ * between planes when they don't overlap on the screen, but
++ * for now we just allocate globally.
++ */
++ drm_mm_init(&hvs->lbm_mm, 0, 96 * 1024);
++
++ /* Upload filter kernels. We only have the one for now, so we
++ * keep it around for the lifetime of the driver.
++ */
++ ret = vc4_hvs_upload_linear_kernel(hvs,
++ &hvs->mitchell_netravali_filter,
++ mitchell_netravali_1_3_1_3_kernel);
++ if (ret)
++ return ret;
++
+ vc4->hvs = hvs;
+ return 0;
+ }
+@@ -140,7 +220,11 @@ static void vc4_hvs_unbind(struct device
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dev *vc4 = drm->dev_private;
+
++ if (vc4->hvs->mitchell_netravali_filter.allocated)
++ drm_mm_remove_node(&vc4->hvs->mitchell_netravali_filter);
++
+ drm_mm_takedown(&vc4->hvs->dlist_mm);
++ drm_mm_takedown(&vc4->hvs->lbm_mm);
+
+ vc4->hvs = NULL;
+ }
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -24,6 +24,12 @@
+ #include "drm_fb_cma_helper.h"
+ #include "drm_plane_helper.h"
+
++enum vc4_scaling_mode {
++ VC4_SCALING_NONE,
++ VC4_SCALING_TPZ,
++ VC4_SCALING_PPF,
++};
++
+ struct vc4_plane_state {
+ struct drm_plane_state base;
+ /* System memory copy of the display list for this element, computed
+@@ -47,13 +53,19 @@ struct vc4_plane_state {
+
+ /* Clipped coordinates of the plane on the display. */
+ int crtc_x, crtc_y, crtc_w, crtc_h;
+- /* Clipped size of the area scanned from in the FB. */
+- u32 src_w, src_h;
++ /* Clipped area being scanned from in the FB. */
++ u32 src_x, src_y, src_w, src_h;
++
++ enum vc4_scaling_mode x_scaling, y_scaling;
++ bool is_unity;
+
+ /* Offset to start scanning out from the start of the plane's
+ * BO.
+ */
+ u32 offset;
++
++ /* Our allocation in LBM for temporary storage during scaling. */
++ struct drm_mm_node lbm;
+ };
+
+ static inline struct vc4_plane_state *
+@@ -106,6 +118,16 @@ static const struct hvs_format *vc4_get_
+ return NULL;
+ }
+
++static enum vc4_scaling_mode vc4_get_scaling_mode(u32 src, u32 dst)
++{
++ if (dst > src)
++ return VC4_SCALING_PPF;
++ else if (dst < src)
++ return VC4_SCALING_TPZ;
++ else
++ return VC4_SCALING_NONE;
++}
++
+ static bool plane_enabled(struct drm_plane_state *state)
+ {
+ return state->fb && state->crtc;
+@@ -122,6 +144,8 @@ static struct drm_plane_state *vc4_plane
+ if (!vc4_state)
+ return NULL;
+
++ memset(&vc4_state->lbm, 0, sizeof(vc4_state->lbm));
++
+ __drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
+
+ if (vc4_state->dlist) {
+@@ -141,8 +165,17 @@ static struct drm_plane_state *vc4_plane
+ static void vc4_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ {
++ struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
++ if (vc4_state->lbm.allocated) {
++ unsigned long irqflags;
++
++ spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags);
++ drm_mm_remove_node(&vc4_state->lbm);
++ spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags);
++ }
++
+ kfree(vc4_state->dlist);
+ __drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base);
+ kfree(state);
+@@ -181,23 +214,60 @@ static void vc4_dlist_write(struct vc4_p
+ vc4_state->dlist[vc4_state->dlist_count++] = val;
+ }
+
++/* Returns the scl0/scl1 field based on whether the dimensions need to
++ * be up/down/non-scaled.
++ *
++ * This is a replication of a table from the spec.
++ */
++static u32 vc4_get_scl_field(struct drm_plane_state *state)
++{
++ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
++
++ switch (vc4_state->x_scaling << 2 | vc4_state->y_scaling) {
++ case VC4_SCALING_PPF << 2 | VC4_SCALING_PPF:
++ return SCALER_CTL0_SCL_H_PPF_V_PPF;
++ case VC4_SCALING_TPZ << 2 | VC4_SCALING_PPF:
++ return SCALER_CTL0_SCL_H_TPZ_V_PPF;
++ case VC4_SCALING_PPF << 2 | VC4_SCALING_TPZ:
++ return SCALER_CTL0_SCL_H_PPF_V_TPZ;
++ case VC4_SCALING_TPZ << 2 | VC4_SCALING_TPZ:
++ return SCALER_CTL0_SCL_H_TPZ_V_TPZ;
++ case VC4_SCALING_PPF << 2 | VC4_SCALING_NONE:
++ return SCALER_CTL0_SCL_H_PPF_V_NONE;
++ case VC4_SCALING_NONE << 2 | VC4_SCALING_PPF:
++ return SCALER_CTL0_SCL_H_NONE_V_PPF;
++ case VC4_SCALING_NONE << 2 | VC4_SCALING_TPZ:
++ return SCALER_CTL0_SCL_H_NONE_V_TPZ;
++ case VC4_SCALING_TPZ << 2 | VC4_SCALING_NONE:
++ return SCALER_CTL0_SCL_H_TPZ_V_NONE;
++ default:
++ case VC4_SCALING_NONE << 2 | VC4_SCALING_NONE:
++ /* The unity case is independently handled by
++ * SCALER_CTL0_UNITY.
++ */
++ return 0;
++ }
++}
++
+ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+ {
++ struct drm_plane *plane = state->plane;
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
++ u32 subpixel_src_mask = (1 << 16) - 1;
+
+ vc4_state->offset = fb->offsets[0];
+
+- if (state->crtc_w << 16 != state->src_w ||
+- state->crtc_h << 16 != state->src_h) {
+- /* We don't support scaling yet, which involves
+- * allocating the LBM memory for scaling temporary
+- * storage, and putting filter kernels in the HVS
+- * context.
+- */
++ /* We don't support subpixel source positioning for scaling. */
++ if ((state->src_x & subpixel_src_mask) ||
++ (state->src_y & subpixel_src_mask) ||
++ (state->src_w & subpixel_src_mask) ||
++ (state->src_h & subpixel_src_mask)) {
+ return -EINVAL;
+ }
+
++ vc4_state->src_x = state->src_x >> 16;
++ vc4_state->src_y = state->src_y >> 16;
+ vc4_state->src_w = state->src_w >> 16;
+ vc4_state->src_h = state->src_h >> 16;
+
+@@ -206,6 +276,23 @@ static int vc4_plane_setup_clipping_and_
+ vc4_state->crtc_w = state->crtc_w;
+ vc4_state->crtc_h = state->crtc_h;
+
++ vc4_state->x_scaling = vc4_get_scaling_mode(vc4_state->src_w,
++ vc4_state->crtc_w);
++ vc4_state->y_scaling = vc4_get_scaling_mode(vc4_state->src_h,
++ vc4_state->crtc_h);
++ vc4_state->is_unity = (vc4_state->x_scaling == VC4_SCALING_NONE &&
++ vc4_state->y_scaling == VC4_SCALING_NONE);
++
++ /* No configuring scaling on the cursor plane, since it gets
++ non-vblank-synced updates, and scaling requires requires
++ LBM changes which have to be vblank-synced.
++ */
++ if (plane->type == DRM_PLANE_TYPE_CURSOR && !vc4_state->is_unity)
++ return -EINVAL;
++
++ /* Clamp the on-screen start x/y to 0. The hardware doesn't
++ * support negative y, and negative x wastes bandwidth.
++ */
+ if (vc4_state->crtc_x < 0) {
+ vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format,
+ 0) *
+@@ -223,6 +310,87 @@ static int vc4_plane_setup_clipping_and_
+ return 0;
+ }
+
++static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
++{
++ u32 scale, recip;
++
++ scale = (1 << 16) * src / dst;
++
++ /* The specs note that while the reciprocal would be defined
++ * as (1<<32)/scale, ~0 is close enough.
++ */
++ recip = ~0 / scale;
++
++ vc4_dlist_write(vc4_state,
++ VC4_SET_FIELD(scale, SCALER_TPZ0_SCALE) |
++ VC4_SET_FIELD(0, SCALER_TPZ0_IPHASE));
++ vc4_dlist_write(vc4_state,
++ VC4_SET_FIELD(recip, SCALER_TPZ1_RECIP));
++}
++
++static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
++{
++ u32 scale = (1 << 16) * src / dst;
++
++ vc4_dlist_write(vc4_state,
++ SCALER_PPF_AGC |
++ VC4_SET_FIELD(scale, SCALER_PPF_SCALE) |
++ VC4_SET_FIELD(0, SCALER_PPF_IPHASE));
++}
++
++static u32 vc4_lbm_size(struct drm_plane_state *state)
++{
++ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
++ /* This is the worst case number. One of the two sizes will
++ * be used depending on the scaling configuration.
++ */
++ u32 pix_per_line = max(vc4_state->src_w, (u32)vc4_state->crtc_w);
++ u32 lbm;
++
++ if (vc4_state->is_unity)
++ return 0;
++ else if (vc4_state->y_scaling == VC4_SCALING_TPZ)
++ lbm = pix_per_line * 8;
++ else {
++ /* In special cases, this multiplier might be 12. */
++ lbm = pix_per_line * 16;
++ }
++
++ lbm = roundup(lbm, 32);
++
++ return lbm;
++}
++
++static void vc4_write_scaling_parameters(struct drm_plane_state *state)
++{
++ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
++
++ /* Ch0 H-PPF Word 0: Scaling Parameters */
++ if (vc4_state->x_scaling == VC4_SCALING_PPF) {
++ vc4_write_ppf(vc4_state,
++ vc4_state->src_w, vc4_state->crtc_w);
++ }
++
++ /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
++ if (vc4_state->y_scaling == VC4_SCALING_PPF) {
++ vc4_write_ppf(vc4_state,
++ vc4_state->src_h, vc4_state->crtc_h);
++ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
++ }
++
++ /* Ch0 H-TPZ Words 0-1: Scaling Parameters, Recip */
++ if (vc4_state->x_scaling == VC4_SCALING_TPZ) {
++ vc4_write_tpz(vc4_state,
++ vc4_state->src_w, vc4_state->crtc_w);
++ }
++
++ /* Ch0 V-TPZ Words 0-2: Scaling Parameters, Recip, Context */
++ if (vc4_state->y_scaling == VC4_SCALING_TPZ) {
++ vc4_write_tpz(vc4_state,
++ vc4_state->src_h, vc4_state->crtc_h);
++ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
++ }
++}
+
+ /* Writes out a full display list for an active plane to the plane's
+ * private dlist state.
+@@ -230,22 +398,50 @@ static int vc4_plane_setup_clipping_and_
+ static int vc4_plane_mode_set(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ {
++ struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+ u32 ctl0_offset = vc4_state->dlist_count;
+ const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
++ u32 scl;
++ u32 lbm_size;
++ unsigned long irqflags;
+ int ret;
+
+ ret = vc4_plane_setup_clipping_and_scaling(state);
+ if (ret)
+ return ret;
+
++ /* Allocate the LBM memory that the HVS will use for temporary
++ * storage due to our scaling/format conversion.
++ */
++ lbm_size = vc4_lbm_size(state);
++ if (lbm_size) {
++ if (!vc4_state->lbm.allocated) {
++ spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags);
++ ret = drm_mm_insert_node(&vc4->hvs->lbm_mm,
++ &vc4_state->lbm,
++ lbm_size, 32, 0);
++ spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags);
++ } else {
++ WARN_ON_ONCE(lbm_size != vc4_state->lbm.size);
++ }
++ }
++
++ if (ret)
++ return ret;
++
++ scl = vc4_get_scl_field(state);
++
++ /* Control word */
+ vc4_dlist_write(vc4_state,
+ SCALER_CTL0_VALID |
+ (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
+ (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
+- SCALER_CTL0_UNITY);
++ (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
++ VC4_SET_FIELD(scl, SCALER_CTL0_SCL0) |
++ VC4_SET_FIELD(scl, SCALER_CTL0_SCL1));
+
+ /* Position Word 0: Image Positions and Alpha Value */
+ vc4_state->pos0_offset = vc4_state->dlist_count;
+@@ -254,9 +450,14 @@ static int vc4_plane_mode_set(struct drm
+ VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) |
+ VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y));
+
+- /* Position Word 1: Scaled Image Dimensions.
+- * Skipped due to SCALER_CTL0_UNITY scaling.
+- */
++ /* Position Word 1: Scaled Image Dimensions. */
++ if (!vc4_state->is_unity) {
++ vc4_dlist_write(vc4_state,
++ VC4_SET_FIELD(vc4_state->crtc_w,
++ SCALER_POS1_SCL_WIDTH) |
++ VC4_SET_FIELD(vc4_state->crtc_h,
++ SCALER_POS1_SCL_HEIGHT));
++ }
+
+ /* Position Word 2: Source Image Size, Alpha Mode */
+ vc4_state->pos2_offset = vc4_state->dlist_count;
+@@ -282,6 +483,32 @@ static int vc4_plane_mode_set(struct drm
+ vc4_dlist_write(vc4_state,
+ VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
+
++ if (!vc4_state->is_unity) {
++ /* LBM Base Address. */
++ if (vc4_state->y_scaling != VC4_SCALING_NONE)
++ vc4_dlist_write(vc4_state, vc4_state->lbm.start);
++
++ vc4_write_scaling_parameters(state);
++
++ /* If any PPF setup was done, then all the kernel
++ * pointers get uploaded.
++ */
++ if (vc4_state->x_scaling == VC4_SCALING_PPF ||
++ vc4_state->y_scaling == VC4_SCALING_PPF) {
++ u32 kernel = VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start,
++ SCALER_PPF_KERNEL_OFFSET);
++
++ /* HPPF plane 0 */
++ vc4_dlist_write(vc4_state, kernel);
++ /* VPPF plane 0 */
++ vc4_dlist_write(vc4_state, kernel);
++ /* HPPF plane 1 */
++ vc4_dlist_write(vc4_state, kernel);
++ /* VPPF plane 1 */
++ vc4_dlist_write(vc4_state, kernel);
++ }
++ }
++
+ vc4_state->dlist[ctl0_offset] |=
+ VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
+
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -536,6 +536,21 @@ enum hvs_pixel_format {
+ #define SCALER_CTL0_ORDER_MASK VC4_MASK(14, 13)
+ #define SCALER_CTL0_ORDER_SHIFT 13
+
++#define SCALER_CTL0_SCL1_MASK VC4_MASK(10, 8)
++#define SCALER_CTL0_SCL1_SHIFT 8
++
++#define SCALER_CTL0_SCL0_MASK VC4_MASK(7, 5)
++#define SCALER_CTL0_SCL0_SHIFT 5
++
++#define SCALER_CTL0_SCL_H_PPF_V_PPF 0
++#define SCALER_CTL0_SCL_H_TPZ_V_PPF 1
++#define SCALER_CTL0_SCL_H_PPF_V_TPZ 2
++#define SCALER_CTL0_SCL_H_TPZ_V_TPZ 3
++#define SCALER_CTL0_SCL_H_PPF_V_NONE 4
++#define SCALER_CTL0_SCL_H_NONE_V_PPF 5
++#define SCALER_CTL0_SCL_H_NONE_V_TPZ 6
++#define SCALER_CTL0_SCL_H_TPZ_V_NONE 7
++
+ /* Set to indicate no scaling. */
+ #define SCALER_CTL0_UNITY BIT(4)
+
+@@ -551,6 +566,12 @@ enum hvs_pixel_format {
+ #define SCALER_POS0_START_X_MASK VC4_MASK(11, 0)
+ #define SCALER_POS0_START_X_SHIFT 0
+
++#define SCALER_POS1_SCL_HEIGHT_MASK VC4_MASK(27, 16)
++#define SCALER_POS1_SCL_HEIGHT_SHIFT 16
++
++#define SCALER_POS1_SCL_WIDTH_MASK VC4_MASK(11, 0)
++#define SCALER_POS1_SCL_WIDTH_SHIFT 0
++
+ #define SCALER_POS2_ALPHA_MODE_MASK VC4_MASK(31, 30)
+ #define SCALER_POS2_ALPHA_MODE_SHIFT 30
+ #define SCALER_POS2_ALPHA_MODE_PIPELINE 0
+@@ -564,6 +585,31 @@ enum hvs_pixel_format {
+ #define SCALER_POS2_WIDTH_MASK VC4_MASK(11, 0)
+ #define SCALER_POS2_WIDTH_SHIFT 0
+
++#define SCALER_TPZ0_VERT_RECALC BIT(31)
++#define SCALER_TPZ0_SCALE_MASK VC4_MASK(28, 8)
++#define SCALER_TPZ0_SCALE_SHIFT 8
++#define SCALER_TPZ0_IPHASE_MASK VC4_MASK(7, 0)
++#define SCALER_TPZ0_IPHASE_SHIFT 0
++#define SCALER_TPZ1_RECIP_MASK VC4_MASK(15, 0)
++#define SCALER_TPZ1_RECIP_SHIFT 0
++
++/* Skips interpolating coefficients to 64 phases, so just 8 are used.
++ * Required for nearest neighbor.
++ */
++#define SCALER_PPF_NOINTERP BIT(31)
++/* Replaes the highest valued coefficient with one that makes all 4
++ * sum to unity.
++ */
++#define SCALER_PPF_AGC BIT(30)
++#define SCALER_PPF_SCALE_MASK VC4_MASK(24, 8)
++#define SCALER_PPF_SCALE_SHIFT 8
++#define SCALER_PPF_IPHASE_MASK VC4_MASK(6, 0)
++#define SCALER_PPF_IPHASE_SHIFT 0
++
++#define SCALER_PPF_KERNEL_OFFSET_MASK VC4_MASK(13, 0)
++#define SCALER_PPF_KERNEL_OFFSET_SHIFT 0
++#define SCALER_PPF_KERNEL_UNCACHED BIT(31)
++
+ #define SCALER_SRC_PITCH_MASK VC4_MASK(15, 0)
+ #define SCALER_SRC_PITCH_SHIFT 0
+
--- /dev/null
+From 59b40e05378ba51d3e5355f8860fca1341edf0c0 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 30 Dec 2015 12:25:44 -0800
+Subject: [PATCH 286/304] drm/vc4: Add support for YUV planes.
+
+This supports 420 and 422 subsampling with 2 or 3 planes, tested with
+modetest. It doesn't set up chroma subsampling position (which it
+appears KMS doesn't deal with yet).
+
+The LBM memory is overallocated in many cases, but apparently the docs
+aren't quite correct and I'll probably need to look at the hardware
+source to really figure it out.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit fc04023fafecf19ebd09278d8d67dc5ed1f68b46)
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 256 +++++++++++++++++++++++++++++++---------
+ drivers/gpu/drm/vc4/vc4_regs.h | 56 ++++++++-
+ 2 files changed, 253 insertions(+), 59 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -54,15 +54,19 @@ struct vc4_plane_state {
+ /* Clipped coordinates of the plane on the display. */
+ int crtc_x, crtc_y, crtc_w, crtc_h;
+ /* Clipped area being scanned from in the FB. */
+- u32 src_x, src_y, src_w, src_h;
++ u32 src_x, src_y;
+
+- enum vc4_scaling_mode x_scaling, y_scaling;
++ u32 src_w[2], src_h[2];
++
++ /* Scaling selection for the RGB/Y plane and the Cb/Cr planes. */
++ enum vc4_scaling_mode x_scaling[2], y_scaling[2];
+ bool is_unity;
++ bool is_yuv;
+
+ /* Offset to start scanning out from the start of the plane's
+ * BO.
+ */
+- u32 offset;
++ u32 offsets[3];
+
+ /* Our allocation in LBM for temporary storage during scaling. */
+ struct drm_mm_node lbm;
+@@ -79,6 +83,7 @@ static const struct hvs_format {
+ u32 hvs; /* HVS_FORMAT_* */
+ u32 pixel_order;
+ bool has_alpha;
++ bool flip_cbcr;
+ } hvs_formats[] = {
+ {
+ .drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
+@@ -104,6 +109,32 @@ static const struct hvs_format {
+ .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
+ },
++ {
++ .drm = DRM_FORMAT_YUV422,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
++ },
++ {
++ .drm = DRM_FORMAT_YVU422,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
++ .flip_cbcr = true,
++ },
++ {
++ .drm = DRM_FORMAT_YUV420,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
++ },
++ {
++ .drm = DRM_FORMAT_YVU420,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
++ .flip_cbcr = true,
++ },
++ {
++ .drm = DRM_FORMAT_NV12,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE,
++ },
++ {
++ .drm = DRM_FORMAT_NV16,
++ .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
++ },
+ };
+
+ static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
+@@ -219,11 +250,11 @@ static void vc4_dlist_write(struct vc4_p
+ *
+ * This is a replication of a table from the spec.
+ */
+-static u32 vc4_get_scl_field(struct drm_plane_state *state)
++static u32 vc4_get_scl_field(struct drm_plane_state *state, int plane)
+ {
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+- switch (vc4_state->x_scaling << 2 | vc4_state->y_scaling) {
++ switch (vc4_state->x_scaling[plane] << 2 | vc4_state->y_scaling[plane]) {
+ case VC4_SCALING_PPF << 2 | VC4_SCALING_PPF:
+ return SCALER_CTL0_SCL_H_PPF_V_PPF;
+ case VC4_SCALING_TPZ << 2 | VC4_SCALING_PPF:
+@@ -254,9 +285,16 @@ static int vc4_plane_setup_clipping_and_
+ struct drm_plane *plane = state->plane;
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
++ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+ u32 subpixel_src_mask = (1 << 16) - 1;
++ u32 format = fb->pixel_format;
++ int num_planes = drm_format_num_planes(format);
++ u32 h_subsample = 1;
++ u32 v_subsample = 1;
++ int i;
+
+- vc4_state->offset = fb->offsets[0];
++ for (i = 0; i < num_planes; i++)
++ vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
+
+ /* We don't support subpixel source positioning for scaling. */
+ if ((state->src_x & subpixel_src_mask) ||
+@@ -268,20 +306,48 @@ static int vc4_plane_setup_clipping_and_
+
+ vc4_state->src_x = state->src_x >> 16;
+ vc4_state->src_y = state->src_y >> 16;
+- vc4_state->src_w = state->src_w >> 16;
+- vc4_state->src_h = state->src_h >> 16;
++ vc4_state->src_w[0] = state->src_w >> 16;
++ vc4_state->src_h[0] = state->src_h >> 16;
+
+ vc4_state->crtc_x = state->crtc_x;
+ vc4_state->crtc_y = state->crtc_y;
+ vc4_state->crtc_w = state->crtc_w;
+ vc4_state->crtc_h = state->crtc_h;
+
+- vc4_state->x_scaling = vc4_get_scaling_mode(vc4_state->src_w,
+- vc4_state->crtc_w);
+- vc4_state->y_scaling = vc4_get_scaling_mode(vc4_state->src_h,
+- vc4_state->crtc_h);
+- vc4_state->is_unity = (vc4_state->x_scaling == VC4_SCALING_NONE &&
+- vc4_state->y_scaling == VC4_SCALING_NONE);
++ vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0],
++ vc4_state->crtc_w);
++ vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0],
++ vc4_state->crtc_h);
++
++ if (num_planes > 1) {
++ vc4_state->is_yuv = true;
++
++ h_subsample = drm_format_horz_chroma_subsampling(format);
++ v_subsample = drm_format_vert_chroma_subsampling(format);
++ vc4_state->src_w[1] = vc4_state->src_w[0] / h_subsample;
++ vc4_state->src_h[1] = vc4_state->src_h[0] / v_subsample;
++
++ vc4_state->x_scaling[1] =
++ vc4_get_scaling_mode(vc4_state->src_w[1],
++ vc4_state->crtc_w);
++ vc4_state->y_scaling[1] =
++ vc4_get_scaling_mode(vc4_state->src_h[1],
++ vc4_state->crtc_h);
++
++ /* YUV conversion requires that scaling be enabled,
++ * even on a plane that's otherwise 1:1. Choose TPZ
++ * for simplicity.
++ */
++ if (vc4_state->x_scaling[0] == VC4_SCALING_NONE)
++ vc4_state->x_scaling[0] = VC4_SCALING_TPZ;
++ if (vc4_state->y_scaling[0] == VC4_SCALING_NONE)
++ vc4_state->y_scaling[0] = VC4_SCALING_TPZ;
++ }
++
++ vc4_state->is_unity = (vc4_state->x_scaling[0] == VC4_SCALING_NONE &&
++ vc4_state->y_scaling[0] == VC4_SCALING_NONE &&
++ vc4_state->x_scaling[1] == VC4_SCALING_NONE &&
++ vc4_state->y_scaling[1] == VC4_SCALING_NONE);
+
+ /* No configuring scaling on the cursor plane, since it gets
+ non-vblank-synced updates, and scaling requires requires
+@@ -294,16 +360,27 @@ static int vc4_plane_setup_clipping_and_
+ * support negative y, and negative x wastes bandwidth.
+ */
+ if (vc4_state->crtc_x < 0) {
+- vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format,
+- 0) *
+- -vc4_state->crtc_x);
+- vc4_state->src_w += vc4_state->crtc_x;
++ for (i = 0; i < num_planes; i++) {
++ u32 cpp = drm_format_plane_cpp(fb->pixel_format, i);
++ u32 subs = ((i == 0) ? 1 : h_subsample);
++
++ vc4_state->offsets[i] += (cpp *
++ (-vc4_state->crtc_x) / subs);
++ }
++ vc4_state->src_w[0] += vc4_state->crtc_x;
++ vc4_state->src_w[1] += vc4_state->crtc_x / h_subsample;
+ vc4_state->crtc_x = 0;
+ }
+
+ if (vc4_state->crtc_y < 0) {
+- vc4_state->offset += fb->pitches[0] * -vc4_state->crtc_y;
+- vc4_state->src_h += vc4_state->crtc_y;
++ for (i = 0; i < num_planes; i++) {
++ u32 subs = ((i == 0) ? 1 : v_subsample);
++
++ vc4_state->offsets[i] += (fb->pitches[i] *
++ (-vc4_state->crtc_y) / subs);
++ }
++ vc4_state->src_h[0] += vc4_state->crtc_y;
++ vc4_state->src_h[1] += vc4_state->crtc_y / v_subsample;
+ vc4_state->crtc_y = 0;
+ }
+
+@@ -344,15 +421,23 @@ static u32 vc4_lbm_size(struct drm_plane
+ /* This is the worst case number. One of the two sizes will
+ * be used depending on the scaling configuration.
+ */
+- u32 pix_per_line = max(vc4_state->src_w, (u32)vc4_state->crtc_w);
++ u32 pix_per_line = max(vc4_state->src_w[0], (u32)vc4_state->crtc_w);
+ u32 lbm;
+
+- if (vc4_state->is_unity)
+- return 0;
+- else if (vc4_state->y_scaling == VC4_SCALING_TPZ)
+- lbm = pix_per_line * 8;
+- else {
+- /* In special cases, this multiplier might be 12. */
++ if (!vc4_state->is_yuv) {
++ if (vc4_state->is_unity)
++ return 0;
++ else if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ)
++ lbm = pix_per_line * 8;
++ else {
++ /* In special cases, this multiplier might be 12. */
++ lbm = pix_per_line * 16;
++ }
++ } else {
++ /* There are cases for this going down to a multiplier
++ * of 2, but according to the firmware source, the
++ * table in the docs is somewhat wrong.
++ */
+ lbm = pix_per_line * 16;
+ }
+
+@@ -361,33 +446,34 @@ static u32 vc4_lbm_size(struct drm_plane
+ return lbm;
+ }
+
+-static void vc4_write_scaling_parameters(struct drm_plane_state *state)
++static void vc4_write_scaling_parameters(struct drm_plane_state *state,
++ int channel)
+ {
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+ /* Ch0 H-PPF Word 0: Scaling Parameters */
+- if (vc4_state->x_scaling == VC4_SCALING_PPF) {
++ if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) {
+ vc4_write_ppf(vc4_state,
+- vc4_state->src_w, vc4_state->crtc_w);
++ vc4_state->src_w[channel], vc4_state->crtc_w);
+ }
+
+ /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
+- if (vc4_state->y_scaling == VC4_SCALING_PPF) {
++ if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
+ vc4_write_ppf(vc4_state,
+- vc4_state->src_h, vc4_state->crtc_h);
++ vc4_state->src_h[channel], vc4_state->crtc_h);
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+ }
+
+ /* Ch0 H-TPZ Words 0-1: Scaling Parameters, Recip */
+- if (vc4_state->x_scaling == VC4_SCALING_TPZ) {
++ if (vc4_state->x_scaling[channel] == VC4_SCALING_TPZ) {
+ vc4_write_tpz(vc4_state,
+- vc4_state->src_w, vc4_state->crtc_w);
++ vc4_state->src_w[channel], vc4_state->crtc_w);
+ }
+
+ /* Ch0 V-TPZ Words 0-2: Scaling Parameters, Recip, Context */
+- if (vc4_state->y_scaling == VC4_SCALING_TPZ) {
++ if (vc4_state->y_scaling[channel] == VC4_SCALING_TPZ) {
+ vc4_write_tpz(vc4_state,
+- vc4_state->src_h, vc4_state->crtc_h);
++ vc4_state->src_h[channel], vc4_state->crtc_h);
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+ }
+ }
+@@ -401,13 +487,13 @@ static int vc4_plane_mode_set(struct drm
+ struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
+- struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+ u32 ctl0_offset = vc4_state->dlist_count;
+ const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
+- u32 scl;
++ int num_planes = drm_format_num_planes(format->drm);
++ u32 scl0, scl1;
+ u32 lbm_size;
+ unsigned long irqflags;
+- int ret;
++ int ret, i;
+
+ ret = vc4_plane_setup_clipping_and_scaling(state);
+ if (ret)
+@@ -432,7 +518,19 @@ static int vc4_plane_mode_set(struct drm
+ if (ret)
+ return ret;
+
+- scl = vc4_get_scl_field(state);
++ /* SCL1 is used for Cb/Cr scaling of planar formats. For RGB
++ * and 4:4:4, scl1 should be set to scl0 so both channels of
++ * the scaler do the same thing. For YUV, the Y plane needs
++ * to be put in channel 1 and Cb/Cr in channel 0, so we swap
++ * the scl fields here.
++ */
++ if (num_planes == 1) {
++ scl0 = vc4_get_scl_field(state, 1);
++ scl1 = scl0;
++ } else {
++ scl0 = vc4_get_scl_field(state, 1);
++ scl1 = vc4_get_scl_field(state, 0);
++ }
+
+ /* Control word */
+ vc4_dlist_write(vc4_state,
+@@ -440,8 +538,8 @@ static int vc4_plane_mode_set(struct drm
+ (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
+ (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
+ (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
+- VC4_SET_FIELD(scl, SCALER_CTL0_SCL0) |
+- VC4_SET_FIELD(scl, SCALER_CTL0_SCL1));
++ VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
++ VC4_SET_FIELD(scl1, SCALER_CTL0_SCL1));
+
+ /* Position Word 0: Image Positions and Alpha Value */
+ vc4_state->pos0_offset = vc4_state->dlist_count;
+@@ -466,35 +564,68 @@ static int vc4_plane_mode_set(struct drm
+ SCALER_POS2_ALPHA_MODE_PIPELINE :
+ SCALER_POS2_ALPHA_MODE_FIXED,
+ SCALER_POS2_ALPHA_MODE) |
+- VC4_SET_FIELD(vc4_state->src_w, SCALER_POS2_WIDTH) |
+- VC4_SET_FIELD(vc4_state->src_h, SCALER_POS2_HEIGHT));
++ VC4_SET_FIELD(vc4_state->src_w[0], SCALER_POS2_WIDTH) |
++ VC4_SET_FIELD(vc4_state->src_h[0], SCALER_POS2_HEIGHT));
+
+ /* Position Word 3: Context. Written by the HVS. */
+ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+- /* Pointer Word 0: RGB / Y Pointer */
++
++ /* Pointer Word 0/1/2: RGB / Y / Cb / Cr Pointers
++ *
++ * The pointers may be any byte address.
++ */
+ vc4_state->ptr0_offset = vc4_state->dlist_count;
+- vc4_dlist_write(vc4_state, bo->paddr + vc4_state->offset);
++ if (!format->flip_cbcr) {
++ for (i = 0; i < num_planes; i++)
++ vc4_dlist_write(vc4_state, vc4_state->offsets[i]);
++ } else {
++ WARN_ON_ONCE(num_planes != 3);
++ vc4_dlist_write(vc4_state, vc4_state->offsets[0]);
++ vc4_dlist_write(vc4_state, vc4_state->offsets[2]);
++ vc4_dlist_write(vc4_state, vc4_state->offsets[1]);
++ }
+
+- /* Pointer Context Word 0: Written by the HVS */
+- vc4_dlist_write(vc4_state, 0xc0c0c0c0);
++ /* Pointer Context Word 0/1/2: Written by the HVS */
++ for (i = 0; i < num_planes; i++)
++ vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+- /* Pitch word 0: Pointer 0 Pitch */
+- vc4_dlist_write(vc4_state,
+- VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
++ /* Pitch word 0/1/2 */
++ for (i = 0; i < num_planes; i++) {
++ vc4_dlist_write(vc4_state,
++ VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH));
++ }
++
++ /* Colorspace conversion words */
++ if (vc4_state->is_yuv) {
++ vc4_dlist_write(vc4_state, SCALER_CSC0_ITR_R_601_5);
++ vc4_dlist_write(vc4_state, SCALER_CSC1_ITR_R_601_5);
++ vc4_dlist_write(vc4_state, SCALER_CSC2_ITR_R_601_5);
++ }
+
+ if (!vc4_state->is_unity) {
+ /* LBM Base Address. */
+- if (vc4_state->y_scaling != VC4_SCALING_NONE)
++ if (vc4_state->y_scaling[0] != VC4_SCALING_NONE ||
++ vc4_state->y_scaling[1] != VC4_SCALING_NONE) {
+ vc4_dlist_write(vc4_state, vc4_state->lbm.start);
++ }
+
+- vc4_write_scaling_parameters(state);
++ if (num_planes > 1) {
++ /* Emit Cb/Cr as channel 0 and Y as channel
++ * 1. This matches how we set up scl0/scl1
++ * above.
++ */
++ vc4_write_scaling_parameters(state, 1);
++ }
++ vc4_write_scaling_parameters(state, 0);
+
+ /* If any PPF setup was done, then all the kernel
+ * pointers get uploaded.
+ */
+- if (vc4_state->x_scaling == VC4_SCALING_PPF ||
+- vc4_state->y_scaling == VC4_SCALING_PPF) {
++ if (vc4_state->x_scaling[0] == VC4_SCALING_PPF ||
++ vc4_state->y_scaling[0] == VC4_SCALING_PPF ||
++ vc4_state->x_scaling[1] == VC4_SCALING_PPF ||
++ vc4_state->y_scaling[1] == VC4_SCALING_PPF) {
+ u32 kernel = VC4_SET_FIELD(vc4->hvs->mitchell_netravali_filter.start,
+ SCALER_PPF_KERNEL_OFFSET);
+
+@@ -698,6 +829,7 @@ struct drm_plane *vc4_plane_init(struct
+ struct drm_plane *plane = NULL;
+ struct vc4_plane *vc4_plane;
+ u32 formats[ARRAY_SIZE(hvs_formats)];
++ u32 num_formats = 0;
+ int ret = 0;
+ unsigned i;
+
+@@ -708,12 +840,20 @@ struct drm_plane *vc4_plane_init(struct
+ goto fail;
+ }
+
+- for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
+- formats[i] = hvs_formats[i].drm;
++ for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
++ /* Don't allow YUV in cursor planes, since that means
++ * tuning on the scaler, which we don't allow for the
++ * cursor.
++ */
++ if (type != DRM_PLANE_TYPE_CURSOR ||
++ hvs_formats[i].hvs < HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE) {
++ formats[num_formats++] = hvs_formats[i].drm;
++ }
++ }
+ plane = &vc4_plane->base;
+ ret = drm_universal_plane_init(dev, plane, 0xff,
+ &vc4_plane_funcs,
+- formats, ARRAY_SIZE(formats),
++ formats, num_formats,
+ type);
+
+ drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -503,7 +503,12 @@ enum hvs_pixel_format {
+ HVS_PIXEL_FORMAT_RGB888 = 5,
+ HVS_PIXEL_FORMAT_RGBA6666 = 6,
+ /* 32bpp */
+- HVS_PIXEL_FORMAT_RGBA8888 = 7
++ HVS_PIXEL_FORMAT_RGBA8888 = 7,
++
++ HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE = 8,
++ HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE = 9,
++ HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE = 10,
++ HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE = 11,
+ };
+
+ /* Note: the LSB is the rightmost character shown. Only valid for
+@@ -585,6 +590,55 @@ enum hvs_pixel_format {
+ #define SCALER_POS2_WIDTH_MASK VC4_MASK(11, 0)
+ #define SCALER_POS2_WIDTH_SHIFT 0
+
++/* Color Space Conversion words. Some values are S2.8 signed
++ * integers, except that the 2 integer bits map as {0x0: 0, 0x1: 1,
++ * 0x2: 2, 0x3: -1}
++ */
++/* bottom 8 bits of S2.8 contribution of Cr to Blue */
++#define SCALER_CSC0_COEF_CR_BLU_MASK VC4_MASK(31, 24)
++#define SCALER_CSC0_COEF_CR_BLU_SHIFT 24
++/* Signed offset to apply to Y before CSC. (Y' = Y + YY_OFS) */
++#define SCALER_CSC0_COEF_YY_OFS_MASK VC4_MASK(23, 16)
++#define SCALER_CSC0_COEF_YY_OFS_SHIFT 16
++/* Signed offset to apply to CB before CSC (Cb' = Cb - 128 + CB_OFS). */
++#define SCALER_CSC0_COEF_CB_OFS_MASK VC4_MASK(15, 8)
++#define SCALER_CSC0_COEF_CB_OFS_SHIFT 8
++/* Signed offset to apply to CB before CSC (Cr' = Cr - 128 + CR_OFS). */
++#define SCALER_CSC0_COEF_CR_OFS_MASK VC4_MASK(7, 0)
++#define SCALER_CSC0_COEF_CR_OFS_SHIFT 0
++#define SCALER_CSC0_ITR_R_601_5 0x00f00000
++#define SCALER_CSC0_ITR_R_709_3 0x00f00000
++#define SCALER_CSC0_JPEG_JFIF 0x00000000
++
++/* S2.8 contribution of Cb to Green */
++#define SCALER_CSC1_COEF_CB_GRN_MASK VC4_MASK(31, 22)
++#define SCALER_CSC1_COEF_CB_GRN_SHIFT 22
++/* S2.8 contribution of Cr to Green */
++#define SCALER_CSC1_COEF_CR_GRN_MASK VC4_MASK(21, 12)
++#define SCALER_CSC1_COEF_CR_GRN_SHIFT 12
++/* S2.8 contribution of Y to all of RGB */
++#define SCALER_CSC1_COEF_YY_ALL_MASK VC4_MASK(11, 2)
++#define SCALER_CSC1_COEF_YY_ALL_SHIFT 2
++/* top 2 bits of S2.8 contribution of Cr to Blue */
++#define SCALER_CSC1_COEF_CR_BLU_MASK VC4_MASK(1, 0)
++#define SCALER_CSC1_COEF_CR_BLU_SHIFT 0
++#define SCALER_CSC1_ITR_R_601_5 0xe73304a8
++#define SCALER_CSC1_ITR_R_709_3 0xf2b784a8
++#define SCALER_CSC1_JPEG_JFIF 0xea34a400
++
++/* S2.8 contribution of Cb to Red */
++#define SCALER_CSC2_COEF_CB_RED_MASK VC4_MASK(29, 20)
++#define SCALER_CSC2_COEF_CB_RED_SHIFT 20
++/* S2.8 contribution of Cr to Red */
++#define SCALER_CSC2_COEF_CR_RED_MASK VC4_MASK(19, 10)
++#define SCALER_CSC2_COEF_CR_RED_SHIFT 10
++/* S2.8 contribution of Cb to Blue */
++#define SCALER_CSC2_COEF_CB_BLU_MASK VC4_MASK(19, 10)
++#define SCALER_CSC2_COEF_CB_BLU_SHIFT 10
++#define SCALER_CSC2_ITR_R_601_5 0x00066204
++#define SCALER_CSC2_ITR_R_709_3 0x00072a1c
++#define SCALER_CSC2_JPEG_JFIF 0x000599c5
++
+ #define SCALER_TPZ0_VERT_RECALC BIT(31)
+ #define SCALER_TPZ0_SCALE_MASK VC4_MASK(28, 8)
+ #define SCALER_TPZ0_SCALE_SHIFT 8
--- /dev/null
+From 6fde872f91f4ff8dcf1b2c2017c04e4f1dee07f7 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 8 Feb 2016 11:19:14 -0800
+Subject: [PATCH 287/304] drm/vc4: Fix spurious GPU resets due to BO reuse.
+
+We were tracking the "where are the head pointers pointing" globally,
+so if another job reused the same BOs and execution was at the same
+point as last time we checked, we'd stop and trigger a reset even
+though the GPU had made progress.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit c4ce60dc30912df09b2438f1e5594eae1ef64d1e)
+---
+ drivers/gpu/drm/vc4/vc4_drv.h | 6 +++++-
+ drivers/gpu/drm/vc4/vc4_gem.c | 19 ++++++++++++++-----
+ 2 files changed, 19 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -93,7 +93,6 @@ struct vc4_dev {
+ struct work_struct overflow_mem_work;
+
+ struct {
+- uint32_t last_ct0ca, last_ct1ca;
+ struct timer_list timer;
+ struct work_struct reset_work;
+ } hangcheck;
+@@ -203,6 +202,11 @@ struct vc4_exec_info {
+ /* Sequence number for this bin/render job. */
+ uint64_t seqno;
+
++ /* Last current addresses the hardware was processing when the
++ * hangcheck timer checked on us.
++ */
++ uint32_t last_ct0ca, last_ct1ca;
++
+ /* Kernel-space copy of the ioctl arguments */
+ struct drm_vc4_submit_cl *args;
+
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -271,10 +271,17 @@ 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;
++ unsigned long irqflags;
++ struct vc4_exec_info *exec;
++
++ spin_lock_irqsave(&vc4->job_lock, irqflags);
++ exec = vc4_first_job(vc4);
+
+ /* If idle, we can stop watching for hangs. */
+- if (list_empty(&vc4->job_list))
++ if (!exec) {
++ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ return;
++ }
+
+ ct0ca = V3D_READ(V3D_CTNCA(0));
+ ct1ca = V3D_READ(V3D_CTNCA(1));
+@@ -282,14 +289,16 @@ vc4_hangcheck_elapsed(unsigned long data
+ /* 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;
++ if (ct0ca != exec->last_ct0ca || ct1ca != exec->last_ct1ca) {
++ exec->last_ct0ca = ct0ca;
++ exec->last_ct1ca = ct1ca;
++ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ vc4_queue_hangcheck(dev);
+ return;
+ }
+
++ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
++
+ /* 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.
--- /dev/null
+From af6fb397532633e85bb101801d8156b2263aa54f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 5 Feb 2016 15:06:15 -0800
+Subject: [PATCH 288/304] drm/vc4: Fix a framebuffer reference leak on async
+ flip interrupt.
+
+We'd need X to queue up an async pageflip while another is
+outstanding, and then take a SIGIO. I think X actually avoids sending
+out the next pageflip while one's already queued, but I'm not sure.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 48627eb8dc55c60d35794105f6f79fb627347dbd)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -527,6 +527,7 @@ static int vc4_async_page_flip(struct dr
+ /* Make sure all other async modesetes have landed. */
+ ret = down_interruptible(&vc4->async_modeset);
+ if (ret) {
++ drm_framebuffer_unreference(fb);
+ kfree(flip_state);
+ return ret;
+ }
--- /dev/null
+From e25771aa6a4b2b701f3280956d97de4682c54231 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 12 Feb 2016 14:15:14 -0800
+Subject: [PATCH 289/304] drm/vc4: Bring HDMI up from power off if necessary.
+
+If the firmware hadn't brought up HDMI for us, we need to do its
+power-on reset sequence (reset HD and and clear its STANDBY bits,
+reset HDMI, and leave the PHY disabled).
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 851479ad5927b7b1aa141ca9dedb897a7bce2b1d)
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 29 ++++++++++++++++++++++++++++-
+ drivers/gpu/drm/vc4/vc4_regs.h | 2 ++
+ 2 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -497,6 +497,16 @@ static int vc4_hdmi_bind(struct device *
+ goto err_put_i2c;
+ }
+
++ /* This is the rate that is set by the firmware. The number
++ * needs to be a bit higher than the pixel clock rate
++ * (generally 148.5Mhz).
++ */
++ ret = clk_set_rate(hdmi->hsm_clock, 163682864);
++ if (ret) {
++ DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
++ goto err_unprepare_pix;
++ }
++
+ ret = clk_prepare_enable(hdmi->hsm_clock);
+ if (ret) {
+ DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
+@@ -518,7 +528,24 @@ static int vc4_hdmi_bind(struct device *
+ vc4->hdmi = hdmi;
+
+ /* HDMI core must be enabled. */
+- WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
++ if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
++ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
++ udelay(1);
++ HD_WRITE(VC4_HD_M_CTL, 0);
++
++ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
++
++ HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
++ VC4_HDMI_SW_RESET_HDMI |
++ VC4_HDMI_SW_RESET_FORMAT_DETECT);
++
++ HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 0);
++
++ /* PHY should be in reset, like
++ * vc4_hdmi_encoder_disable() does.
++ */
++ HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
++ }
+
+ drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -456,6 +456,8 @@
+ #define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
+
+ #define VC4_HD_M_CTL 0x00c
++# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
++# define VC4_HD_M_RAM_STANDBY (3 << 4)
+ # define VC4_HD_M_SW_RST BIT(2)
+ # define VC4_HD_M_ENABLE BIT(0)
+
--- /dev/null
+From 816b426c27ea90f113f83a7a767e03aa78fbcc03 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 12 Feb 2016 15:16:56 -0800
+Subject: [PATCH 290/304] drm/vc4: Add another reg to HDMI debug dumping.
+
+This is also involved in the HDMI setup sequence so it's nice to see
+it.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 936f1a53f32148cc6164fad7c9a26ebf144e5ffb)
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -95,6 +95,7 @@ static const struct {
+ HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
+ HDMI_REG(VC4_HDMI_HOTPLUG_INT),
+ HDMI_REG(VC4_HDMI_HOTPLUG),
++ HDMI_REG(VC4_HDMI_RAM_PACKET_CONFIG),
+ HDMI_REG(VC4_HDMI_HORZA),
+ HDMI_REG(VC4_HDMI_HORZB),
+ HDMI_REG(VC4_HDMI_FIFO_CTL),
--- /dev/null
+From e3f14344d3d427d0b9cdbf4e3039d88320836471 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 15 Feb 2016 17:06:02 -0800
+Subject: [PATCH 291/304] drm/vc4: Fix the name of the VSYNCD_EVEN register.
+
+It's used for delaying vsync in interlaced mode.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit c31806fbdda910d337b60896040afa708bdfa2bd)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
+ drivers/gpu/drm/vc4/vc4_regs.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -88,7 +88,7 @@ static const struct {
+ } crtc_regs[] = {
+ CRTC_REG(PV_CONTROL),
+ CRTC_REG(PV_V_CONTROL),
+- CRTC_REG(PV_VSYNCD),
++ CRTC_REG(PV_VSYNCD_EVEN),
+ CRTC_REG(PV_HORZA),
+ CRTC_REG(PV_HORZB),
+ CRTC_REG(PV_VERTA),
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -187,7 +187,7 @@
+ # define PV_VCONTROL_CONTINUOUS BIT(1)
+ # define PV_VCONTROL_VIDEN BIT(0)
+
+-#define PV_VSYNCD 0x08
++#define PV_VSYNCD_EVEN 0x08
+
+ #define PV_HORZA 0x0c
+ # define PV_HORZA_HBP_MASK VC4_MASK(31, 16)
--- /dev/null
+From a0d015caa8ddfd37ae8cbfc7aec1d614b5ad3b78 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 15 Feb 2016 17:31:41 -0800
+Subject: [PATCH 292/304] drm/vc4: Fix setting of vertical timings in the CRTC.
+
+It looks like when I went to add the interlaced bits, I just took the
+existing PV_VERT* block and indented it, instead of copy and pasting
+it first. Without this, changing resolution never worked.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit a7c5047d1ce178dd2b1fa577fc8909ad663d56d5)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -217,6 +217,16 @@ static void vc4_crtc_mode_set_nofb(struc
+ PV_HORZB_HFP) |
+ VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
+
++ CRTC_WRITE(PV_VERTA,
++ VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
++ PV_VERTA_VBP) |
++ VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
++ PV_VERTA_VSYNC));
++ CRTC_WRITE(PV_VERTB,
++ VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
++ PV_VERTB_VFP) |
++ VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
++
+ if (interlace) {
+ CRTC_WRITE(PV_VERTA_EVEN,
+ VC4_SET_FIELD(mode->vtotal - mode->vsync_end - 1,
--- /dev/null
+From 072c90e010990be7841b88b268b9fb29806088e0 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 16 Feb 2016 10:24:08 -0800
+Subject: [PATCH 293/304] drm/vc4: Initialize scaler DISPBKGND on modeset.
+
+We weren't updating the interlaced bit, so we'd scan out incorrectly
+if the firmware had brought up the TV encoder and we were switching to
+HDMI.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 6a609209865247cc748e90158c99f374f79b494c)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 6 ++++++
+ drivers/gpu/drm/vc4/vc4_regs.h | 14 ++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -188,6 +188,8 @@ static int vc4_get_clock_select(struct d
+
+ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+ {
++ struct drm_device *dev = crtc->dev;
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct drm_crtc_state *state = crtc->state;
+ struct drm_display_mode *mode = &state->adjusted_mode;
+@@ -256,6 +258,10 @@ static void vc4_crtc_mode_set_nofb(struc
+ PV_CONTROL_FIFO_CLR |
+ PV_CONTROL_EN);
+
++ HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
++ SCALER_DISPBKGND_AUTOHS |
++ (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
++
+ if (debug_dump_regs) {
+ DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
+ vc4_crtc_dump_regs(vc4_crtc);
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -350,6 +350,17 @@
+ # define SCALER_DISPCTRLX_HEIGHT_SHIFT 0
+
+ #define SCALER_DISPBKGND0 0x00000044
++# define SCALER_DISPBKGND_AUTOHS BIT(31)
++# define SCALER_DISPBKGND_INTERLACE BIT(30)
++# define SCALER_DISPBKGND_GAMMA BIT(29)
++# define SCALER_DISPBKGND_TESTMODE_MASK VC4_MASK(28, 25)
++# define SCALER_DISPBKGND_TESTMODE_SHIFT 25
++/* Enables filling the scaler line with the RGB value in the low 24
++ * bits before compositing. Costs cycles, so should be skipped if
++ * opaque display planes will cover everything.
++ */
++# define SCALER_DISPBKGND_FILL BIT(24)
++
+ #define SCALER_DISPSTAT0 0x00000048
+ #define SCALER_DISPBASE0 0x0000004c
+ # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30)
+@@ -362,6 +373,9 @@
+ # define SCALER_DISPSTATX_EMPTY BIT(28)
+ #define SCALER_DISPCTRL1 0x00000050
+ #define SCALER_DISPBKGND1 0x00000054
++#define SCALER_DISPBKGNDX(x) (SCALER_DISPBKGND0 + \
++ (x) * (SCALER_DISPBKGND1 - \
++ SCALER_DISPBKGND0))
+ #define SCALER_DISPSTAT1 0x00000058
+ #define SCALER_DISPSTATX(x) (SCALER_DISPSTAT0 + \
+ (x) * (SCALER_DISPSTAT1 - \
--- /dev/null
+From a2c21b04f340f594c16f9c7235ec7b7f78a96a1f Mon Sep 17 00:00:00 2001
+From: Varad Gautam <varadgautam@gmail.com>
+Date: Wed, 17 Feb 2016 19:08:21 +0530
+Subject: [PATCH 294/304] drm/vc4: improve throughput by pipelining binning and
+ rendering jobs
+
+The hardware provides us with separate threads for binning and
+rendering, and the existing model waits for them both to complete
+before submitting the next job.
+
+Splitting the binning and rendering submissions reduces idle time and
+gives us approx 20-30% speedup with some x11perf tests such as -line10
+and -tilerect1. Improves openarena performance by 1.01897% +/-
+0.247857% (n=16).
+
+Thanks to anholt for suggesting this.
+
+v2: Rebase on the spurious resets fix (change by anholt).
+
+Signed-off-by: Varad Gautam <varadgautam@gmail.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit ca26d28bbaa39f31d5e7e4812603b015c8d54207)
+---
+ drivers/gpu/drm/vc4/vc4_drv.h | 37 +++++++++----
+ drivers/gpu/drm/vc4/vc4_gem.c | 123 ++++++++++++++++++++++++++++++------------
+ drivers/gpu/drm/vc4/vc4_irq.c | 58 ++++++++++++++++----
+ 3 files changed, 166 insertions(+), 52 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -53,7 +53,7 @@ struct vc4_dev {
+ /* Protects bo_cache and the BO stats. */
+ struct mutex bo_lock;
+
+- /* Sequence number for the last job queued in job_list.
++ /* Sequence number for the last job queued in bin_job_list.
+ * Starts at 0 (no jobs emitted).
+ */
+ uint64_t emit_seqno;
+@@ -63,11 +63,19 @@ struct vc4_dev {
+ */
+ 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.
++ /* List of all struct vc4_exec_info for jobs to be executed in
++ * the binner. The first job in the list is the one currently
++ * programmed into ct0ca for execution.
++ */
++ struct list_head bin_job_list;
++
++ /* List of all struct vc4_exec_info for jobs that have
++ * completed binning and are ready for rendering. The first
++ * job in the list is the one currently programmed into ct1ca
++ * for execution.
+ */
+- struct list_head job_list;
++ struct list_head render_job_list;
++
+ /* List of the finished vc4_exec_infos waiting to be freed by
+ * job_done_work.
+ */
+@@ -291,11 +299,20 @@ struct vc4_exec_info {
+ };
+
+ static inline struct vc4_exec_info *
+-vc4_first_job(struct vc4_dev *vc4)
++vc4_first_bin_job(struct vc4_dev *vc4)
++{
++ if (list_empty(&vc4->bin_job_list))
++ return NULL;
++ return list_first_entry(&vc4->bin_job_list, struct vc4_exec_info, head);
++}
++
++static inline struct vc4_exec_info *
++vc4_first_render_job(struct vc4_dev *vc4)
+ {
+- if (list_empty(&vc4->job_list))
++ if (list_empty(&vc4->render_job_list))
+ return NULL;
+- return list_first_entry(&vc4->job_list, struct vc4_exec_info, head);
++ return list_first_entry(&vc4->render_job_list,
++ struct vc4_exec_info, head);
+ }
+
+ /**
+@@ -410,7 +427,9 @@ int vc4_wait_seqno_ioctl(struct drm_devi
+ 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);
++void vc4_submit_next_bin_job(struct drm_device *dev);
++void vc4_submit_next_render_job(struct drm_device *dev);
++void vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec);
+ 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);
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -154,10 +154,10 @@ vc4_save_hang_state(struct drm_device *d
+ 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_exec_info *exec[2];
+ struct vc4_bo *bo;
+ unsigned long irqflags;
+- unsigned int i, unref_list_count;
++ unsigned int i, j, unref_list_count, prev_idx;
+
+ kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL);
+ if (!kernel_state)
+@@ -166,37 +166,55 @@ vc4_save_hang_state(struct drm_device *d
+ state = &kernel_state->user_state;
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+- exec = vc4_first_job(vc4);
+- if (!exec) {
++ exec[0] = vc4_first_bin_job(vc4);
++ exec[1] = vc4_first_render_job(vc4);
++ if (!exec[0] && !exec[1]) {
+ 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);
++ /* Get the bos from both binner and renderer into hang state. */
++ state->bo_count = 0;
++ for (i = 0; i < 2; i++) {
++ if (!exec[i])
++ continue;
++
++ unref_list_count = 0;
++ list_for_each_entry(bo, &exec[i]->unref_list, unref_head)
++ unref_list_count++;
++ state->bo_count += exec[i]->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]->base);
+- kernel_state->bo[i] = &exec->bo[i]->base;
+- }
++ prev_idx = 0;
++ for (i = 0; i < 2; i++) {
++ if (!exec[i])
++ continue;
++
++ for (j = 0; j < exec[i]->bo_count; j++) {
++ drm_gem_object_reference(&exec[i]->bo[j]->base);
++ kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->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++;
++ list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
++ drm_gem_object_reference(&bo->base.base);
++ kernel_state->bo[j + prev_idx] = &bo->base.base;
++ j++;
++ }
++ prev_idx = j + 1;
+ }
+
+- state->start_bin = exec->ct0ca;
+- state->start_render = exec->ct1ca;
++ if (exec[0])
++ state->start_bin = exec[0]->ct0ca;
++ if (exec[1])
++ state->start_render = exec[1]->ct1ca;
+
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+
+@@ -272,13 +290,15 @@ vc4_hangcheck_elapsed(unsigned long data
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ uint32_t ct0ca, ct1ca;
+ unsigned long irqflags;
+- struct vc4_exec_info *exec;
++ struct vc4_exec_info *bin_exec, *render_exec;
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+- exec = vc4_first_job(vc4);
++
++ bin_exec = vc4_first_bin_job(vc4);
++ render_exec = vc4_first_render_job(vc4);
+
+ /* If idle, we can stop watching for hangs. */
+- if (!exec) {
++ if (!bin_exec && !render_exec) {
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ return;
+ }
+@@ -289,9 +309,12 @@ vc4_hangcheck_elapsed(unsigned long data
+ /* If we've made any progress in execution, rearm the timer
+ * and wait.
+ */
+- if (ct0ca != exec->last_ct0ca || ct1ca != exec->last_ct1ca) {
+- exec->last_ct0ca = ct0ca;
+- exec->last_ct1ca = ct1ca;
++ if ((bin_exec && ct0ca != bin_exec->last_ct0ca) ||
++ (render_exec && ct1ca != render_exec->last_ct1ca)) {
++ if (bin_exec)
++ bin_exec->last_ct0ca = ct0ca;
++ if (render_exec)
++ render_exec->last_ct1ca = ct1ca;
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ vc4_queue_hangcheck(dev);
+ return;
+@@ -391,11 +414,13 @@ vc4_flush_caches(struct drm_device *dev)
+ * The job_lock should be held during this.
+ */
+ void
+-vc4_submit_next_job(struct drm_device *dev)
++vc4_submit_next_bin_job(struct drm_device *dev)
+ {
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+- struct vc4_exec_info *exec = vc4_first_job(vc4);
++ struct vc4_exec_info *exec;
+
++again:
++ exec = vc4_first_bin_job(vc4);
+ if (!exec)
+ return;
+
+@@ -405,11 +430,40 @@ vc4_submit_next_job(struct drm_device *d
+ V3D_WRITE(V3D_BPOA, 0);
+ V3D_WRITE(V3D_BPOS, 0);
+
+- if (exec->ct0ca != exec->ct0ea)
++ /* Either put the job in the binner if it uses the binner, or
++ * immediately move it to the to-be-rendered queue.
++ */
++ if (exec->ct0ca != exec->ct0ea) {
+ submit_cl(dev, 0, exec->ct0ca, exec->ct0ea);
++ } else {
++ vc4_move_job_to_render(dev, exec);
++ goto again;
++ }
++}
++
++void
++vc4_submit_next_render_job(struct drm_device *dev)
++{
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ struct vc4_exec_info *exec = vc4_first_render_job(vc4);
++
++ if (!exec)
++ return;
++
+ submit_cl(dev, 1, exec->ct1ca, exec->ct1ea);
+ }
+
++void
++vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec)
++{
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ bool was_empty = list_empty(&vc4->render_job_list);
++
++ list_move_tail(&exec->head, &vc4->render_job_list);
++ if (was_empty)
++ vc4_submit_next_render_job(dev);
++}
++
+ static void
+ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
+ {
+@@ -448,14 +502,14 @@ vc4_queue_submit(struct drm_device *dev,
+ exec->seqno = seqno;
+ vc4_update_bo_seqnos(exec, seqno);
+
+- list_add_tail(&exec->head, &vc4->job_list);
++ list_add_tail(&exec->head, &vc4->bin_job_list);
+
+ /* If no job was executing, kick ours off. Otherwise, it'll
+- * get started when the previous job's frame done interrupt
++ * get started when the previous job's flush done interrupt
+ * occurs.
+ */
+- if (vc4_first_job(vc4) == exec) {
+- vc4_submit_next_job(dev);
++ if (vc4_first_bin_job(vc4) == exec) {
++ vc4_submit_next_bin_job(dev);
+ vc4_queue_hangcheck(dev);
+ }
+
+@@ -849,7 +903,8 @@ 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->bin_job_list);
++ INIT_LIST_HEAD(&vc4->render_job_list);
+ INIT_LIST_HEAD(&vc4->job_done_list);
+ INIT_LIST_HEAD(&vc4->seqno_cb_list);
+ spin_lock_init(&vc4->job_lock);
+--- a/drivers/gpu/drm/vc4/vc4_irq.c
++++ b/drivers/gpu/drm/vc4/vc4_irq.c
+@@ -30,6 +30,10 @@
+ * disables that specific interrupt, and 0s written are ignored
+ * (reading either one returns the set of enabled interrupts).
+ *
++ * When we take a binning flush done interrupt, we need to submit the
++ * next frame for binning and move the finished frame to the render
++ * thread.
++ *
+ * 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
+@@ -44,6 +48,7 @@
+ #include "vc4_regs.h"
+
+ #define V3D_DRIVER_IRQS (V3D_INT_OUTOMEM | \
++ V3D_INT_FLDONE | \
+ V3D_INT_FRDONE)
+
+ DECLARE_WAIT_QUEUE_HEAD(render_wait);
+@@ -77,7 +82,7 @@ vc4_overflow_mem_work(struct work_struct
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+- current_exec = vc4_first_job(vc4);
++ current_exec = vc4_first_bin_job(vc4);
+ if (current_exec) {
+ vc4->overflow_mem->seqno = vc4->finished_seqno + 1;
+ list_add_tail(&vc4->overflow_mem->unref_head,
+@@ -98,17 +103,43 @@ vc4_overflow_mem_work(struct work_struct
+ }
+
+ static void
+-vc4_irq_finish_job(struct drm_device *dev)
++vc4_irq_finish_bin_job(struct drm_device *dev)
++{
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ struct vc4_exec_info *exec = vc4_first_bin_job(vc4);
++
++ if (!exec)
++ return;
++
++ vc4_move_job_to_render(dev, exec);
++ vc4_submit_next_bin_job(dev);
++}
++
++static void
++vc4_cancel_bin_job(struct drm_device *dev)
++{
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ struct vc4_exec_info *exec = vc4_first_bin_job(vc4);
++
++ if (!exec)
++ return;
++
++ list_move_tail(&exec->head, &vc4->bin_job_list);
++ vc4_submit_next_bin_job(dev);
++}
++
++static void
++vc4_irq_finish_render_job(struct drm_device *dev)
+ {
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+- struct vc4_exec_info *exec = vc4_first_job(vc4);
++ struct vc4_exec_info *exec = vc4_first_render_job(vc4);
+
+ if (!exec)
+ return;
+
+ vc4->finished_seqno++;
+ list_move_tail(&exec->head, &vc4->job_done_list);
+- vc4_submit_next_job(dev);
++ vc4_submit_next_render_job(dev);
+
+ wake_up_all(&vc4->job_wait_queue);
+ schedule_work(&vc4->job_done_work);
+@@ -125,9 +156,10 @@ vc4_irq(int irq, void *arg)
+ 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.
++ /* Acknowledge the interrupts we're handling here. The binner
++ * last flush / render frame done interrupt will be cleared,
++ * while OUTOMEM will stay high until the underlying cause is
++ * cleared.
+ */
+ V3D_WRITE(V3D_INTCTL, intctl);
+
+@@ -138,9 +170,16 @@ vc4_irq(int irq, void *arg)
+ status = IRQ_HANDLED;
+ }
+
++ if (intctl & V3D_INT_FLDONE) {
++ spin_lock(&vc4->job_lock);
++ vc4_irq_finish_bin_job(dev);
++ spin_unlock(&vc4->job_lock);
++ status = IRQ_HANDLED;
++ }
++
+ if (intctl & V3D_INT_FRDONE) {
+ spin_lock(&vc4->job_lock);
+- vc4_irq_finish_job(dev);
++ vc4_irq_finish_render_job(dev);
+ spin_unlock(&vc4->job_lock);
+ status = IRQ_HANDLED;
+ }
+@@ -205,6 +244,7 @@ void vc4_irq_reset(struct drm_device *de
+ V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS);
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
+- vc4_irq_finish_job(dev);
++ vc4_cancel_bin_job(dev);
++ vc4_irq_finish_render_job(dev);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ }
--- /dev/null
+From 10f0d3fb0d155b0a6837f56a5e6a663a33d003ba Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 29 Feb 2016 17:53:00 -0800
+Subject: [PATCH 295/304] drm/vc4: Let gpiolib know that we're OK with sleeping
+ for HPD.
+
+Fixes an error thrown every few seconds when we poll HPD when it's on
+a I2C to GPIO expander.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Tested-by: Daniel Stone <daniels@collabora.com>
+(cherry picked from commit 0e60eab57557bc06bb3a5ef8d5d6dcd9ddd47aff)
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -168,7 +168,7 @@ vc4_hdmi_connector_detect(struct drm_con
+ return connector_status_connected;
+
+ if (vc4->hdmi->hpd_gpio) {
+- if (gpio_get_value(vc4->hdmi->hpd_gpio))
++ if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio))
+ return connector_status_connected;
+ else
+ return connector_status_disconnected;
--- /dev/null
+From 4be409839b81a2fd724efc4cda01395130e20910 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 29 Feb 2016 17:53:01 -0800
+Subject: [PATCH 296/304] drm/vc4: Respect GPIO_ACTIVE_LOW on HDMI HPD if set
+ in the devicetree.
+
+The original Raspberry Pi had the GPIO active high, but the later
+models are active low. The DT GPIO bindings allow specifying the
+active flag, except that it doesn't get propagated to the gpiodesc, so
+you have to handle it yourself.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Tested-by: Daniel Stone <daniels@collabora.com>
+(cherry picked from commit 0b06e0a7945130e6a187f7959529cba7725f573a)
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -47,6 +47,7 @@ struct vc4_hdmi {
+ void __iomem *hdmicore_regs;
+ void __iomem *hd_regs;
+ int hpd_gpio;
++ bool hpd_active_low;
+
+ struct clk *pixel_clock;
+ struct clk *hsm_clock;
+@@ -168,7 +169,8 @@ vc4_hdmi_connector_detect(struct drm_con
+ return connector_status_connected;
+
+ if (vc4->hdmi->hpd_gpio) {
+- if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio))
++ if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
++ vc4->hdmi->hpd_active_low)
+ return connector_status_connected;
+ else
+ return connector_status_disconnected;
+@@ -519,11 +521,17 @@ static int vc4_hdmi_bind(struct device *
+ * we'll use the HDMI core's register.
+ */
+ if (of_find_property(dev->of_node, "hpd-gpios", &value)) {
+- hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0);
++ enum of_gpio_flags hpd_gpio_flags;
++
++ hdmi->hpd_gpio = of_get_named_gpio_flags(dev->of_node,
++ "hpd-gpios", 0,
++ &hpd_gpio_flags);
+ if (hdmi->hpd_gpio < 0) {
+ ret = hdmi->hpd_gpio;
+ goto err_unprepare_hsm;
+ }
++
++ hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
+ }
+
+ vc4->hdmi = hdmi;
--- /dev/null
+From 5ae2b2779bed5095268019d56394420e7c751c29 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 8 Mar 2016 15:09:41 +0300
+Subject: [PATCH 297/304] drm/vc4: Return -EFAULT on copy_from_user() failure
+
+The copy_from_user() function returns the number of bytes not copied but
+we want to return a negative error code.
+
+Fixes: 463873d57014 ('drm/vc4: Add an API for creating GPU shaders in GEM BOs.')
+Cc: stable@vger.kernel.org
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 585cb132a48190b554aecda2ebc3e2911fcbb665)
+---
+ drivers/gpu/drm/vc4/vc4_bo.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_bo.c
++++ b/drivers/gpu/drm/vc4/vc4_bo.c
+@@ -519,11 +519,12 @@ vc4_create_shader_bo_ioctl(struct drm_de
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
+- ret = copy_from_user(bo->base.vaddr,
++ if (copy_from_user(bo->base.vaddr,
+ (void __user *)(uintptr_t)args->data,
+- args->size);
+- if (ret != 0)
++ args->size)) {
++ ret = -EFAULT;
+ goto fail;
++ }
+ /* Clear the rest of the memory from allocating from the BO
+ * cache.
+ */
--- /dev/null
+From fc45e6dc816d76b839a6efad3ee5bbb4def966c8 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 4 Mar 2016 12:32:07 -0800
+Subject: [PATCH 298/304] drm/vc4: Recognize a more specific compatible string
+ for V3D.
+
+The Raspberry Pi Foundation's firmware updates are shipping device
+trees using the old string, so we'll keep recognizing that as this rev
+of V3D. Still, we should use a more specific name in the upstream DT
+to clarify which board is being supported, in case we do other revs of
+V3D in the future.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Acked-by: Stephen Warren <swarren@wwwdotorg.org>
+(cherry picked from commit 90d7116061f86c1f8ea460806a0414addea7b58b)
+---
+ drivers/gpu/drm/vc4/vc4_v3d.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_v3d.c
++++ b/drivers/gpu/drm/vc4/vc4_v3d.c
+@@ -256,6 +256,7 @@ static int vc4_v3d_dev_remove(struct pla
+ }
+
+ static const struct of_device_id vc4_v3d_dt_match[] = {
++ { .compatible = "brcm,bcm2835-v3d" },
+ { .compatible = "brcm,vc4-v3d" },
+ {}
+ };
--- /dev/null
+From 08a0e34ea6911206ad18cec68ab1089505b0090a Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 19 Apr 2016 17:21:06 -0700
+Subject: [PATCH 299/304] ARM: bcm2708: Move the CMA range down for kernel 4.4.
+
+The previous area no longer works, for reasons I haven't investigated.
+Just move it somewhere that works.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -91,7 +91,7 @@
+ fragment@4 {
+ target-path = "/chosen";
+ __overlay__ {
+- bootargs = "cma=256M@512M";
++ bootargs = "cma=256M@256M";
+ };
+ };
+ };
--- /dev/null
+From 2b3a67805c0b48fce377b60237ee29edf90996ee Mon Sep 17 00:00:00 2001
+From: Vladimir Zapolskiy <vz@mleia.com>
+Date: Sun, 6 Mar 2016 03:21:35 +0200
+Subject: [PATCH 300/304] clk: bcm2835: fix check of error code returned by
+ devm_ioremap_resource()
+
+The change fixes potential oops while accessing iomem on invalid
+address, if devm_ioremap_resource() fails due to some reason.
+
+The devm_ioremap_resource() function returns ERR_PTR() and never
+returns NULL, which makes useless a following check for NULL.
+
+Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
+Fixes: 5e63dcc74b30 ("clk: bcm2835: Add a driver for the auxiliary peripheral clock gates")
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/bcm/clk-bcm2835-aux.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835-aux.c
++++ b/drivers/clk/bcm/clk-bcm2835-aux.c
+@@ -38,8 +38,8 @@ static int bcm2835_aux_clk_probe(struct
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg = devm_ioremap_resource(dev, res);
+- if (!reg)
+- return -ENODEV;
++ if (IS_ERR(reg))
++ return PTR_ERR(reg);
+
+ onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
+ if (!onecell)
--- /dev/null
+From 48b162fd15cc5a39d244f7c339786df4aa4c2c4d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 21 Apr 2016 13:49:32 +0100
+Subject: [PATCH 301/304] 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 <phil@raspberrypi.org>
+---
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- 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_COMPLETION_DATA_T *completion;
+ DEBUG_INITIALISE(g_state.local)
+
++ 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_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
+ 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;
--- /dev/null
+From cb1ee7f3f3df6a311f2c5c353ae1792c1f9c2881 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 21 Apr 2016 16:07:15 +0100
+Subject: [PATCH 302/304] config: Add DRM_UDL module
+
+See: https://github.com/raspberrypi/linux/issues/1422
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/configs/bcm2709_defconfig | 5 +++--
+ arch/arm/configs/bcmrpi_defconfig | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -815,6 +815,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
+@@ -854,10 +855,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
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -807,6 +807,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
+@@ -846,10 +847,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
--- /dev/null
+From ddb9af17e2f52474d45c0afc04abc2af4510110e Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 21 Apr 2016 15:44:14 +0100
+Subject: [PATCH 303/304] bcm2835-i2s: Reduce the TX DREQ threshold
+
+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 <phil@raspberrypi.org>
+---
+ sound/soc/bcm/bcm2835-i2s.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+--- 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
+
+ /* 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);
--- /dev/null
+From 0a2bdc152d2a9f8e0709fa4bd42fa75190b01e57 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <6by9@users.noreply.github.com>
+Date: Sat, 16 Apr 2016 23:09:54 +0100
+Subject: [PATCH 304/304] V4L2: Request maximum resolution from GPU
+
+Get resolution information about the sensors from the GPU
+and advertise it correctly.
+
+Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
+---
+ drivers/media/platform/bcm2835/bcm2835-camera.c | 59 +++++++++++++++++--------
+ drivers/media/platform/bcm2835/bcm2835-camera.h | 3 +-
+ 2 files changed, 43 insertions(+), 19 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
+@@ -38,8 +38,6 @@
+ #define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
+ #define MIN_WIDTH 16
+ #define MIN_HEIGHT 16
+-#define MAX_WIDTH 2592
+-#define MAX_HEIGHT 1944
+ #define MIN_BUFFER_SIZE (80*1024)
+
+ #define MAX_VIDEO_MODE_WIDTH 1280
+@@ -729,11 +727,11 @@ static int vidioc_try_fmt_vid_overlay(st
+ 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,
++ v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1,
++ &f->fmt.win.w.height, MIN_HEIGHT, dev->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,
++ v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1,
++ &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height,
+ 1, 0);
+
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+@@ -961,8 +959,9 @@ static int vidioc_try_fmt_vid_cap(struct
+ "Clipping/aligning %dx%d format %08X\n",
+ f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
+
+- v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 1,
+- &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 1, 0);
++ v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1,
++ &f->fmt.pix.height, MIN_HEIGHT, dev->max_height,
++ 1, 0);
+ f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp;
+
+ /* Image buffer has to be padded to allow for alignment, even though
+@@ -1301,9 +1300,10 @@ static int vidioc_s_fmt_vid_cap(struct f
+ int vidioc_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+ {
++ struct bm2835_mmal_dev *dev = video_drvdata(file);
+ static const struct v4l2_frmsize_stepwise sizes = {
+- MIN_WIDTH, MAX_WIDTH, 2,
+- MIN_HEIGHT, MAX_HEIGHT, 2
++ MIN_WIDTH, 0, 2,
++ MIN_HEIGHT, 0, 2
+ };
+ int i;
+
+@@ -1316,6 +1316,8 @@ int vidioc_enum_framesizes(struct file *
+ return -EINVAL;
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise = sizes;
++ fsize->stepwise.max_width = dev->max_width;
++ fsize->stepwise.max_height = dev->max_height;
+ return 0;
+ }
+
+@@ -1323,6 +1325,7 @@ int vidioc_enum_framesizes(struct file *
+ static int vidioc_enum_frameintervals(struct file *file, void *priv,
+ struct v4l2_frmivalenum *fival)
+ {
++ struct bm2835_mmal_dev *dev = video_drvdata(file);
+ int i;
+
+ if (fival->index)
+@@ -1335,8 +1338,8 @@ static int vidioc_enum_frameintervals(st
+ return -EINVAL;
+
+ /* regarding width & height - we support any within range */
+- if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH ||
+- fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT)
++ if (fival->width < MIN_WIDTH || fival->width > dev->max_width ||
++ fival->height < MIN_HEIGHT || fival->height > dev->max_height)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
+@@ -1499,12 +1502,17 @@ static struct video_device vdev_template
+ .release = video_device_release_empty,
+ };
+
+-static int get_num_cameras(struct vchiq_mmal_instance *instance)
++/* Returns the number of cameras, and also the max resolution supported
++ * by those cameras.
++ */
++static int get_num_cameras(struct vchiq_mmal_instance *instance,
++ unsigned int resolutions[][2], int num_resolutions)
+ {
+ int ret;
+ struct vchiq_mmal_component *cam_info_component;
+ struct mmal_parameter_camera_info_t cam_info = {0};
+ int param_size = sizeof(cam_info);
++ int i;
+
+ /* create a camera_info component */
+ ret = vchiq_mmal_component_init(instance, "camera_info",
+@@ -1520,6 +1528,14 @@ static int get_num_cameras(struct vchiq_
+ ¶m_size)) {
+ pr_info("Failed to get camera info\n");
+ }
++ for (i = 0;
++ i < (cam_info.num_cameras > num_resolutions ?
++ cam_info.num_cameras :
++ num_resolutions);
++ i++) {
++ resolutions[i][0] = cam_info.cameras[i].max_width;
++ resolutions[i][1] = cam_info.cameras[i].max_height;
++ }
+
+ vchiq_mmal_component_finalise(instance,
+ cam_info_component);
+@@ -1528,12 +1544,13 @@ static int get_num_cameras(struct vchiq_
+ }
+
+ static int set_camera_parameters(struct vchiq_mmal_instance *instance,
+- struct vchiq_mmal_component *camera)
++ struct vchiq_mmal_component *camera,
++ struct bm2835_mmal_dev *dev)
+ {
+ int ret;
+ struct mmal_parameter_camera_config cam_config = {
+- .max_stills_w = MAX_WIDTH,
+- .max_stills_h = MAX_HEIGHT,
++ .max_stills_w = dev->max_width,
++ .max_stills_h = dev->max_height,
+ .stills_yuv422 = 1,
+ .one_shot_stills = 1,
+ .max_preview_video_w = (max_video_width > 1920) ?
+@@ -1576,7 +1593,8 @@ static int __init mmal_init(struct bm283
+ }
+
+ ret = set_camera_parameters(dev->instance,
+- dev->component[MMAL_COMPONENT_CAMERA]);
++ dev->component[MMAL_COMPONENT_CAMERA],
++ dev);
+ if (ret < 0)
+ goto unreg_camera;
+
+@@ -1838,12 +1856,15 @@ static int __init bm2835_mmal_init(void)
+ int camera;
+ unsigned int num_cameras;
+ struct vchiq_mmal_instance *instance;
++ unsigned int resolutions[MAX_BCM2835_CAMERAS][2];
+
+ ret = vchiq_mmal_init(&instance);
+ if (ret < 0)
+ return ret;
+
+- num_cameras = get_num_cameras(instance);
++ num_cameras = get_num_cameras(instance,
++ resolutions,
++ MAX_BCM2835_CAMERAS);
+ if (num_cameras > MAX_BCM2835_CAMERAS)
+ num_cameras = MAX_BCM2835_CAMERAS;
+
+@@ -1853,6 +1874,8 @@ static int __init bm2835_mmal_init(void)
+ return -ENOMEM;
+
+ dev->camera_num = camera;
++ dev->max_width = resolutions[camera][0];
++ dev->max_height = resolutions[camera][1];
+
+ /* setup device defaults */
+ dev->overlay.w.left = 150;
+--- a/drivers/media/platform/bcm2835/bcm2835-camera.h
++++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
+@@ -107,7 +107,8 @@ struct bm2835_mmal_dev {
+ } capture;
+
+ unsigned int camera_num;
+-
++ unsigned int max_width;
++ unsigned int max_height;
+ };
+
+ int bm2835_mmal_init_controls(