# CONFIG_BCM2708_WDT is not set
# CONFIG_BCM2835_DEVGPIOMEM is not set
CONFIG_BCM2835_MBOX=y
+# CONFIG_BCM2835_SMI is not set
CONFIG_BCM2835_WDT=y
CONFIG_BCM_VCIO=y
CONFIG_BCM_VC_CMA=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
CONFIG_BCM2709_DT=y
# CONFIG_BCM2835_DEVGPIOMEM is not set
CONFIG_BCM2835_MBOX=y
+# CONFIG_BCM2835_SMI is not set
CONFIG_BCM2835_WDT=y
CONFIG_BCM_VCIO=y
CONFIG_BCM_VC_CMA=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
-From 401f5d164bd797fe7c1d39fa3edfd0d517edaa62 Mon Sep 17 00:00:00 2001
+From 781a47e405cae18b69f4f76c2d945401366cb81f Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sun, 12 May 2013 12:24:19 +0100
-Subject: [PATCH 001/171] Main bcm2708/bcm2709 linux port
+Subject: [PATCH 001/203] Main bcm2708/bcm2709 linux port
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 26ba306075567b5627c4633f1b9cf1e8be963b08 Mon Sep 17 00:00:00 2001
+From 1b06d065cc1209ff7524486eae5dd9bf00a2db0e Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 Oct 2014 18:50:05 +0100
-Subject: [PATCH 002/171] Add bcm2708_gpio driver
+Subject: [PATCH 002/203] Add bcm2708_gpio driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
-From a198016611e2c5dc9b3867b489eda80d4499f890 Mon Sep 17 00:00:00 2001
+From 0c1382bd36ed3bc31b953028083619990e4dadf6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 1 May 2015 19:11:03 +0200
-Subject: [PATCH 003/171] mailbox: bcm2708: Add bcm2708-vcio
+Subject: [PATCH 003/203] mailbox: bcm2708: Add bcm2708-vcio
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 5a6024182390194a4e0b3f05e20226dd89f7fa9d Mon Sep 17 00:00:00 2001
+From bd316831fe1a05b9306054d48fb48db5226a6c92 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 1 May 2013 19:46:17 +0100
-Subject: [PATCH 004/171] Add dwc_otg driver
+Subject: [PATCH 004/203] Add dwc_otg driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 5ec663250bcf18ee6d5792ab03ca49b15e2ea882 Mon Sep 17 00:00:00 2001
+From 128ae7510c357693222c635d3799b982142eb1b5 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 1 May 2013 19:54:32 +0100
-Subject: [PATCH 005/171] bcm2708 watchdog driver
+Subject: [PATCH 005/203] bcm2708 watchdog driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
-From e41668dfdc984723c914401293db5757f5981330 Mon Sep 17 00:00:00 2001
+From 9c44d34f731221eb1f68a4f5454b33b11116de3d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 17:06:34 +0100
-Subject: [PATCH 006/171] bcm2708 framebuffer driver
+Subject: [PATCH 006/203] bcm2708 framebuffer driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 04a4ceef489437512b4d40071e049950d56fbb27 Mon Sep 17 00:00:00 2001
+From 6ba80b1f7e7404642d3f72203116a7969b4e84ed 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 007/171] dmaengine: Add support for BCM2708
+Subject: [PATCH 007/203] dmaengine: Add support for BCM2708
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 3b0b17e88492b2b230b8ebfbee410f1ce1bd9472 Mon Sep 17 00:00:00 2001
+From f5d5650a56309979ebdd7835396688ef4f7b9625 Mon Sep 17 00:00:00 2001
From: gellert <gellert@raspberrypi.org>
Date: Fri, 15 Aug 2014 16:35:06 +0100
-Subject: [PATCH 008/171] MMC: added alternative MMC driver
+Subject: [PATCH 008/203] MMC: added alternative MMC driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 1f881b06a8bc697d0e662687152fdc9309ff051a Mon Sep 17 00:00:00 2001
+From 8086ce054d96d5a9a2237e5bb1d270dbce759189 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 25 Mar 2015 17:49:47 +0000
-Subject: [PATCH 009/171] Adding bcm2835-sdhost driver, and an overlay to
+Subject: [PATCH 009/203] Adding bcm2835-sdhost driver, and an overlay to
enable it
BCM2835 has two SD card interfaces. This driver uses the other one.
-From 58f193da0a65393b6e4415529c93e443c0218cd1 Mon Sep 17 00:00:00 2001
+From 484bbb300f8c414aa66c555a5887e2e9dbac0cdd Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:31:47 +0100
-Subject: [PATCH 010/171] cma: Add vc_cma driver to enable use of CMA
+Subject: [PATCH 010/203] cma: Add vc_cma driver to enable use of CMA
Signed-off-by: popcornmix <popcornmix@gmail.com>
-From 9479010a140e02e7fadc9d7276368ad31cf09e90 Mon Sep 17 00:00:00 2001
+From 830f064561e1908ba89b9479117b82db07de8c01 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 26 Mar 2012 22:15:50 +0100
-Subject: [PATCH 011/171] bcm2708: alsa sound driver
+Subject: [PATCH 011/203] bcm2708: alsa sound driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 178b1b7f58f59dfa28882c090a5481b01229175c Mon Sep 17 00:00:00 2001
+From a9ec42880d0dfd336819f699cc63dcf13c897286 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 2 Jul 2013 23:42:01 +0100
-Subject: [PATCH 012/171] bcm2708 vchiq driver
+Subject: [PATCH 012/203] bcm2708 vchiq driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 7855d7e7caa631b3070612353b823ac4fafad349 Mon Sep 17 00:00:00 2001
+From c281e92ad16639d2b5bcce1302f78372f29b8cc0 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 16:07:06 +0100
-Subject: [PATCH 013/171] vc_mem: Add vc_mem driver
+Subject: [PATCH 013/203] vc_mem: Add vc_mem driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From a791bc11b84ba34966f21cec50e3bed1a7b5a0f1 Mon Sep 17 00:00:00 2001
+From e56c5f50ab632450c34df97f088f6fe10612ca29 Mon Sep 17 00:00:00 2001
From: Tim Gover <tgover@broadcom.com>
Date: Tue, 22 Jul 2014 15:41:04 +0100
-Subject: [PATCH 014/171] vcsm: VideoCore shared memory service for BCM2835
+Subject: [PATCH 014/203] vcsm: VideoCore shared memory service for BCM2835
Add experimental support for the VideoCore shared memory service.
This allows user processes to allocate memory from VideoCore's
-From 53bbc98101781c4c4a6a26e987439088423e1d5e Mon Sep 17 00:00:00 2001
+From 5922c92d5e4be4c4cc9b59d8a8cd2bfeaebdebbb Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:51:55 +0100
-Subject: [PATCH 015/171] Add hwrng (hardware random number generator) driver
+Subject: [PATCH 015/203] Add hwrng (hardware random number generator) driver
---
drivers/char/hw_random/Kconfig | 13 +++-
-From 152c53ac6dfbebe4702389526cd04a995a20f71a Mon Sep 17 00:00:00 2001
+From a46ef8c727cf42ab2434d5f19eea7b9a88649d22 Mon Sep 17 00:00:00 2001
From: Aron Szabo <aron@aron.ws>
Date: Sat, 16 Jun 2012 12:15:55 +0200
-Subject: [PATCH 016/171] lirc: added support for RaspberryPi GPIO
+Subject: [PATCH 016/203] 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 dd3d655617225b79fe9ae53075800fc05c17afca Mon Sep 17 00:00:00 2001
+From 048e47374e6f6d6f10850316a07159e88b9ed406 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:49:20 +0100
-Subject: [PATCH 017/171] Add cpufreq driver
+Subject: [PATCH 017/203] Add cpufreq driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
-From f9f02cbb208f7b5b91851cbec11202cc2f1e4879 Mon Sep 17 00:00:00 2001
+From 5298ba74d7c98c9b4dcb5eebdb5528fec4512cba Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 19:24:24 +0000
-Subject: [PATCH 018/171] Added hwmon/thermal driver for reporting core
+Subject: [PATCH 018/203] Added hwmon/thermal driver for reporting core
temperature. Thanks Dorian
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From bdf3fc107c0849c132c643f5d88409ab170b06cf Mon Sep 17 00:00:00 2001
+From f5d52c99c98af7b3d50c6c9650422cb9fd8b495e Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 15:41:33 +0100
-Subject: [PATCH 019/171] Add Chris Boot's spi driver.
+Subject: [PATCH 019/203] Add Chris Boot's spi driver.
spi: bcm2708: add device tree support
-From 33747296c5a59d9a21b6721d4bdfd200efcfede8 Mon Sep 17 00:00:00 2001
+From 088993fea0e74f22da3f97c7a3212d0cc9a1afea Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 15:44:08 +0100
-Subject: [PATCH 020/171] Add Chris Boot's i2c driver
+Subject: [PATCH 020/203] Add Chris Boot's i2c driver
i2c-bcm2708: fixed baudrate
-From 9860807d0dfd9ee237618f7bc298337491412c6e Mon Sep 17 00:00:00 2001
+From 0cb249ef323fd1e4f85d88953c61525f10318424 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 021/171] bcm2835: add v4l2 camera device
+Subject: [PATCH 021/203] bcm2835: add v4l2 camera device
- Supports raw YUV capture, preview, JPEG and H264.
- Uses videobuf2 for data transfer, using dma_buf.
-From dc3b7a37d88e3072e1aa50569f8d565325450886 Mon Sep 17 00:00:00 2001
+From ee7658ee2a268e93a57c507cac4bed85b2c7e8f0 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 23 Jan 2015 14:48:55 +0000
-Subject: [PATCH 022/171] scripts/dtc: Update to upstream version with overlay
+Subject: [PATCH 022/203] scripts/dtc: Update to upstream version with overlay
patches
---
-From dbdb2233c99ddb69a4b2143bae3450914d387fc1 Mon Sep 17 00:00:00 2001
+From 59cf4bf51eea78b4314cfabff3023f1a95358fa6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 11 May 2015 09:00:42 +0100
-Subject: [PATCH 023/171] scripts: Add mkknlimg and knlinfo scripts from tools
+Subject: [PATCH 023/203] scripts: Add mkknlimg and knlinfo scripts from tools
repo
The Raspberry Pi firmware looks for a trailer on the kernel image to
-From 451f30961d360c125bb9000e57f59ef3e0569b53 Mon Sep 17 00:00:00 2001
+From e2ca00ccfecacf743841367a3dab7092f2ce3ffc Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 5 Dec 2014 17:26:26 +0000
-Subject: [PATCH 024/171] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
+Subject: [PATCH 024/203] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
---
drivers/of/fdt.c | 29 ++++++++++++++++++++++++-----
-From 5c77587f9e377f9e30dfca468bee4532a3a10229 Mon Sep 17 00:00:00 2001
+From 00bde9c19f378c337830838a67fb9bdf14019ebc Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Wed, 9 Jul 2014 14:46:08 +0200
-Subject: [PATCH 025/171] BCM2708: Add core Device Tree support
+Subject: [PATCH 025/203] BCM2708: Add core Device Tree support
Add the bare minimum needed to boot BCM2708 from a Device Tree.
-From 7099f200c096aaf4cf79e5bfa41ce1e016e607ca Mon Sep 17 00:00:00 2001
+From 968d9983a0ff154cf772006f39d72100b8c3dd79 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 026/171] fbdev: add FBIOCOPYAREA ioctl
+Subject: [PATCH 026/203] fbdev: add FBIOCOPYAREA ioctl
Based on the patch authored by Ali Gholami Rudi at
https://lkml.org/lkml/2009/7/13/153
-From a82f0ad663b1f3964b5011201b23dd129240bf9f Mon Sep 17 00:00:00 2001
+From 00637200a8710623f0514c98765e2c6bc3a34a37 Mon Sep 17 00:00:00 2001
From: Harm Hanemaaijer <fgenfb@yahoo.com>
Date: Thu, 20 Jun 2013 20:21:39 +0200
-Subject: [PATCH 029/171] Speed up console framebuffer imageblit function
+Subject: [PATCH 029/203] 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 f6fffdcafda0f821fea364d437877a9b6d35c3e0 Mon Sep 17 00:00:00 2001
+From 9ac3c3e6aea4f2dccdf5f04b7992e03b58869fd3 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 17:26:38 +0000
-Subject: [PATCH 030/171] Allow mac address to be set in smsc95xx
+Subject: [PATCH 030/203] Allow mac address to be set in smsc95xx
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
-From 8e0d9ff1afc5b595eebf92b305e3e19af3fe06d9 Mon Sep 17 00:00:00 2001
+From ec1be1680332a4676db86178ce9f24917aeeca67 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 May 2013 11:46:50 +0100
-Subject: [PATCH 031/171] enabling the realtime clock 1-wire chip DS1307 and
+Subject: [PATCH 031/203] 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 281e90871309b0d1a113c055c86757027de22c8b Mon Sep 17 00:00:00 2001
+From 37da06d2b47b67624a9f2b8c8eec76429f46f10d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:54:08 +0100
-Subject: [PATCH 032/171] Added Device IDs for August DVB-T 205
+Subject: [PATCH 032/203] Added Device IDs for August DVB-T 205
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++
-From 3af3746a509957ae4a0daa7b4a561c2a97870916 Mon Sep 17 00:00:00 2001
+From efd60949b03b034da398f15fc9b74d3f3a06c48a Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Dec 2013 22:16:19 +0000
-Subject: [PATCH 033/171] config: Enable CONFIG_MEMCG, but leave it disabled
+Subject: [PATCH 033/203] config: Enable CONFIG_MEMCG, but leave it disabled
(due to memory cost). Enable with cgroup_enable=memory.
---
-From b02ef86d5728e7aa67775fc9761f04a2439a6c3a Mon Sep 17 00:00:00 2001
+From 6a93789e8d9296b68c43d10d5ea4a95b73932e44 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:33:38 +0100
-Subject: [PATCH 034/171] ASoC: Add support for BCM2708
+Subject: [PATCH 034/203] ASoC: Add support for BCM2708
This driver adds support for digital audio (I2S)
for the BCM2708 SoC that is used by the
-From 8c94146d33d522d6fbf5d2aff70676494631763b Mon Sep 17 00:00:00 2001
+From f5d02596d7770a458ca6a99e250369fdecfdb763 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 035/171] ASoC: Add support for PCM5102A codec
+Subject: [PATCH 035/203] ASoC: Add support for PCM5102A codec
Some definitions to support the PCM5102A codec
by Texas Instruments.
-From 5e5994dd4630230b7b044e458339180e873857ac Mon Sep 17 00:00:00 2001
+From 272e93911327e40ec57facd1fbc37e98b06c8c79 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:04:54 +0100
-Subject: [PATCH 036/171] BCM2708: Add I2S support to board file
+Subject: [PATCH 036/203] BCM2708: Add I2S support to board file
Adds the required initializations for I2S
to the board file of mach-bcm2708.
-From fe18c4e02b8b0007e110b2029e021154b3ab2dd0 Mon Sep 17 00:00:00 2001
+From 1c2bf7278b4ac192fed80b01b404a2d44b68b124 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 037/171] ASoC: Add support for HifiBerry DAC
+Subject: [PATCH 037/203] ASoC: Add support for HifiBerry DAC
This adds a machine driver for the HifiBerry DAC.
It is a sound card that can
-From e750b2fa5d490c5f0106f654d2270fae20ab7d18 Mon Sep 17 00:00:00 2001
+From 66cb299f5c712d92e1bb69468cdbb7ca481ab777 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 038/171] BCM2708: Add HifiBerry DAC to board file
+Subject: [PATCH 038/203] BCM2708: Add HifiBerry DAC to board file
This adds the initalization of the HifiBerry DAC
to the mach-bcm2708 board file.
-From cebfb216daf7118a86d4b07086baedaa4ee298e7 Mon Sep 17 00:00:00 2001
+From c3a1a7754a288b6c49041fcc69f79c51b36caa73 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 6 Dec 2013 20:50:28 +0100
-Subject: [PATCH 039/171] ASoC: BCM2708: Add support for RPi-DAC
+Subject: [PATCH 039/203] ASoC: BCM2708: Add support for RPi-DAC
This adds a machine driver for the RPi-DAC.
-From 463e74adc05d41470cfecde946f98ebc59d89b4f Mon Sep 17 00:00:00 2001
+From 1000a38e381ea718d8daa07edcd371da44b0b855 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 040/171] ASoC: wm8804: Implement MCLK configuration options,
+Subject: [PATCH 040/203] 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 7bcd053aa8b06e2be569213d0b7d0e72ab8da91e Mon Sep 17 00:00:00 2001
+From dcb8a2f0beafb6bdf057ac2cf51efc9eb12afce5 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 041/171] ASoC: BCM:Add support for HiFiBerry Digi. Driver is
+Subject: [PATCH 041/203] ASoC: BCM:Add support for HiFiBerry Digi. Driver is
based on the patched WM8804 driver.
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
-From e47c3fdeecb7a3e138d44660de5ab2128a34265f Mon Sep 17 00:00:00 2001
+From b6472b32e6f5a3d38a90351b4ccc82f89a5d1167 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Thu, 16 Jan 2014 07:26:08 +0100
-Subject: [PATCH 042/171] BCM2708: Added support for HiFiBerry Digi board Board
+Subject: [PATCH 042/203] BCM2708: Added support for HiFiBerry Digi board Board
initalization by I2C
Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
-From 4e065559dadaff17498a017691adc096e7bbae2e Mon Sep 17 00:00:00 2001
+From 59cdf99d9532afce061f452a14c565e1d4a54a50 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 043/171] ASoC: wm8804: Set idle_bias_off to false Idle bias
+Subject: [PATCH 043/203] 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 070ed9f4445bde2a425c65543278a89cbc68857c Mon Sep 17 00:00:00 2001
+From fc8ea110c58a5bf56acf6465e6b8e170a0035686 Mon Sep 17 00:00:00 2001
From: Gordon Garrity <gordon@iqaudio.com>
Date: Sat, 8 Mar 2014 16:56:57 +0000
-Subject: [PATCH 044/171] Add IQaudIO Sound Card support for Raspberry Pi
+Subject: [PATCH 044/203] Add IQaudIO Sound Card support for Raspberry Pi
Set a limit of 0dB on Digital Volume Control
-From 60c815a4d391146705c0213642be0e3568ea1b7b Mon Sep 17 00:00:00 2001
+From b1ef48d91499449783ae92a90d5234e5fb6c1692 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Jun 2014 13:42:01 +0100
-Subject: [PATCH 045/171] vmstat: Workaround for issue where dirty page count
+Subject: [PATCH 045/203] vmstat: Workaround for issue where dirty page count
goes negative
See:
-From adb07aff7d57f6bf072cb98591015ed6f7556478 Mon Sep 17 00:00:00 2001
+From d2bb9e17cccd1b6d986013538259b90dc199aefb Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 14 Jul 2014 22:02:09 +0100
-Subject: [PATCH 046/171] hid: Reduce default mouse polling interval to 60Hz
+Subject: [PATCH 046/203] hid: Reduce default mouse polling interval to 60Hz
Reduces overhead when using X
---
-From 1408165cd6474613fb414f10d4c9a26f46c07c2b Mon Sep 17 00:00:00 2001
+From 14fd2e85f4a92ef464a7abae5e19b3dd682f5a89 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 047/171] Added support for HiFiBerry DAC+
+Subject: [PATCH 047/203] 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 e4f72f2ce26695642af17308eb52c676aac0cbf8 Mon Sep 17 00:00:00 2001
+From d6f6a3e2752f14210dd13b6d3d19bddc13bd9f79 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 048/171] Added driver for HiFiBerry Amp amplifier add-on board
+Subject: [PATCH 048/203] 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 b70b00c9ffe01ba04c66fac70abdf04ad72ffb1d Mon Sep 17 00:00:00 2001
+From 9791bbe1abe1228c0726314e4e1b8baeff8233ce Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 13 Apr 2015 19:14:18 +0100
-Subject: [PATCH 049/171] bcm2708: Allow option card devices to be configured
+Subject: [PATCH 049/203] bcm2708: Allow option card devices to be configured
via DT
If the kernel is built with Device Tree support, and if a DT blob
-From e5d0825e8b8af3bd83248b5227f819a243dc6e44 Mon Sep 17 00:00:00 2001
+From a6bc94bfd95cb3351ebac3ccff75cd915a8d9e86 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 13 Apr 2015 18:45:39 +0100
-Subject: [PATCH 050/171] Adding Device Tree support for some RPi audio cards
+Subject: [PATCH 050/203] Adding Device Tree support for some RPi audio cards
---
arch/arm/mach-bcm2709/bcm2709.c | 143 ++++++++++++++++++++++++++++++++++++++
-From 9ec46a1866cc3e5f1f672fbf5d8763d28f4eba61 Mon Sep 17 00:00:00 2001
+From 4d818efc09ca08d42fabd91c10c75556b0ab9164 Mon Sep 17 00:00:00 2001
From: Timo Kokkonen <tjko@iki.fi>
Date: Wed, 29 Oct 2014 23:30:30 -0700
-Subject: [PATCH 051/171] Added support to reserve/enable a GPIO pin to be used
+Subject: [PATCH 051/203] Added support to reserve/enable a GPIO pin to be used
from pps-gpio module (LinuxPPS). Enable PPS modules in default config for
RPi.
-From fd5059a51e8a6e1ee8898d441496902ef25aa5d1 Mon Sep 17 00:00:00 2001
+From b6d5a7c02f67e35ff3e56ecbb4ef24e65ffdc5bc Mon Sep 17 00:00:00 2001
From: Ryan Coe <bluemrp9@gmail.com>
Date: Sat, 31 Jan 2015 18:25:49 -0700
-Subject: [PATCH 052/171] Update ds1307 driver for device-tree support
+Subject: [PATCH 052/203] Update ds1307 driver for device-tree support
Signed-off-by: Ryan Coe <bluemrp9@gmail.com>
---
-From ade319d70297e1258ae65ff733ae56b6ad51ec96 Mon Sep 17 00:00:00 2001
+From a4c686a6a8cc5938de37451714add5ea872f67c2 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 6 Feb 2015 13:50:57 +0000
-Subject: [PATCH 053/171] BCM270x_DT: Add pwr_led, and the required "input"
+Subject: [PATCH 053/203] BCM270x_DT: Add pwr_led, and the required "input"
trigger
The "input" trigger makes the associated GPIO an input. This is to support
-From 06384c65ff1a351b024c19d4bc0febaf8fcead5d Mon Sep 17 00:00:00 2001
+From 4427da11c90fced3efd244e90d408d12bfdeb8c2 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 20 Jun 2014 17:19:27 +0100
-Subject: [PATCH 054/171] bcm2709: Simplify and strip down IRQ handler
+Subject: [PATCH 054/203] bcm2709: Simplify and strip down IRQ handler
---
arch/arm/include/asm/entry-macro-multi.S | 2 +
-From 461dee6548a8872f4325c2a5b06be89abec33293 Mon Sep 17 00:00:00 2001
+From 730ac9d3f596df543a2bd15b5b299da977966cc9 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 12 Feb 2015 11:17:53 +0000
-Subject: [PATCH 055/171] Fix LED "input" trigger implementation for 3.19
+Subject: [PATCH 055/203] Fix LED "input" trigger implementation for 3.19
---
drivers/leds/leds-gpio.c | 10 +++++++++-
-From 4c6915169fd00a9e67f75ebb4cd06b857c85e14f Mon Sep 17 00:00:00 2001
+From e338dddb10d7d0b02b123305a31832f8818af000 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Thu, 10 Jul 2014 13:59:47 +0200
-Subject: [PATCH 056/171] pinctrl-bcm2835: Set base to 0 give expected gpio
+Subject: [PATCH 056/203] pinctrl-bcm2835: Set base to 0 give expected gpio
numbering
Signed-off-by: Noralf Tronnes <notro@tronnes.org>
-From 9c59564e8d49582902e182a63eb7874da8bd37ac Mon Sep 17 00:00:00 2001
+From 8eed7ff146c26b290b51011f72b5262909dcd878 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 4 Feb 2015 10:02:24 +0000
-Subject: [PATCH 057/171] pinctrl-bcm2835: bcm2835_gpio_direction_output must
+Subject: [PATCH 057/203] pinctrl-bcm2835: bcm2835_gpio_direction_output must
set the value
---
-From 713683712ac68c709d93bd0f22b3bfb69a5f6f24 Mon Sep 17 00:00:00 2001
+From ac7db17a7b836e64616f6e556b43969f4ed7ace2 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 24 Feb 2015 13:40:50 +0000
-Subject: [PATCH 058/171] pinctrl-bcm2835: Fix interrupt handling for GPIOs
+Subject: [PATCH 058/203] pinctrl-bcm2835: Fix interrupt handling for GPIOs
28-31 and 46-53
Contrary to the documentation, the BCM2835 GPIO controller actually has
-From aed134d5558d95d0dd7e9ed9946469df3aaffc88 Mon Sep 17 00:00:00 2001
+From c8aa040735dccf98d20506578874a9c8fa0a87f4 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 26 Feb 2015 09:58:22 +0000
-Subject: [PATCH 059/171] pinctrl-bcm2835: Only request the interrupts listed
+Subject: [PATCH 059/203] pinctrl-bcm2835: Only request the interrupts listed
in the DTB
Although the GPIO controller can generate three interrupts (four counting
-From 17b8fc6380028724a3c1e67b132818a3ad9d06d3 Mon Sep 17 00:00:00 2001
+From 91ab8311ca5802198aae08730ae4883cabfa6600 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 27 Feb 2015 15:10:24 +0000
-Subject: [PATCH 060/171] enc28j60: Add device tree compatible string and an
+Subject: [PATCH 060/203] enc28j60: Add device tree compatible string and an
overlay
---
-From 45764fde4d7a1651812511d66cb5c888c8f90b1c Mon Sep 17 00:00:00 2001
+From 24580cf7424fd50f99667d7fd74973c6be768835 Mon Sep 17 00:00:00 2001
From: Waldemar Brodkorb <wbrodkorb@conet.de>
Date: Wed, 25 Mar 2015 09:26:17 +0100
-Subject: [PATCH 061/171] Add driver for rpi-proto
+Subject: [PATCH 061/203] 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 4ca7cab423cf8252fd5c3f70e0e172b08f30eab6 Mon Sep 17 00:00:00 2001
+From a7154ea03e9acec217e3d1cb70d0aed869e55669 Mon Sep 17 00:00:00 2001
From: Clive Messer <clive.m.messer@gmail.com>
Date: Thu, 2 Apr 2015 12:22:55 +0100
-Subject: [PATCH 062/171] Add Device Tree support for RPi-DAC.
+Subject: [PATCH 062/203] Add Device Tree support for RPi-DAC.
---
sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++
-From 634fa57de42fce5ed25f81b2e2b59f8edd64620f Mon Sep 17 00:00:00 2001
+From dedcf4042bd975ee5df588f103f7fc5effb61baa Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 13 Apr 2015 17:16:29 +0100
-Subject: [PATCH 063/171] config: Add default configs
+Subject: [PATCH 063/203] config: Add default configs
---
arch/arm/configs/bcm2709_defconfig | 1204 ++++++++++++++++++++++++++++++++++++
-From 0bc4283840ab64da84c8853ffe625f85d4c1ab52 Mon Sep 17 00:00:00 2001
+From df86d2a4a92db44754fa0139b37a197a6d70b107 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 064/171] smsx95xx: fix crimes against truesize
+Subject: [PATCH 064/203] 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 5339a416569f6f751859ca0534e8571f63e88138 Mon Sep 17 00:00:00 2001
+From f55a40b960df22fd85166f0059039415a70893d7 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 17 Apr 2015 16:58:45 +0100
-Subject: [PATCH 065/171] smsc95xx: Disable turbo mode by default
+Subject: [PATCH 065/203] smsc95xx: Disable turbo mode by default
---
drivers/net/usb/smsc95xx.c | 2 +-
-From 15a557851ec3e164a5f766543c133b0bbae1e988 Mon Sep 17 00:00:00 2001
+From 96d14e8df0b8209526f76f890404151d58554ada Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 17 Apr 2015 19:30:22 +0100
-Subject: [PATCH 066/171] Add blk_pos parameter to mmc multi_io_quirk callback
+Subject: [PATCH 066/203] Add blk_pos parameter to mmc multi_io_quirk callback
---
drivers/mmc/card/block.c | 1 +
-From 9ebff814cb85c6a89d814719ddbd8a173ae00096 Mon Sep 17 00:00:00 2001
+From 73e03bc0ad554dbd4e4d040d90e46f3d9d31d3c4 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 067/171] bcm2835: bcm2835_defconfig
+Subject: [PATCH 067/203] bcm2835: bcm2835_defconfig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From ff16594cfebb06205fc70fd8d14de57acae92502 Mon Sep 17 00:00:00 2001
+From edd20d21ede3ec226ef4b93a844e75a758a28daa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 1 May 2015 23:00:15 +0200
-Subject: [PATCH 068/171] BCM270x_DT: Add mailbox bcm2708-vcio
+Subject: [PATCH 068/203] BCM270x_DT: Add mailbox bcm2708-vcio
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 899b0e6b639a2f2ae386ef314a25388903fd40c0 Mon Sep 17 00:00:00 2001
+From 04e299dffec7ed7c7d88fe8568a6833005dd9558 Mon Sep 17 00:00:00 2001
From: Gordon Hollingworth <gordon@raspberrypi.org>
Date: Tue, 12 May 2015 14:47:56 +0100
-Subject: [PATCH 069/171] rpi-ft5406: Add touchscreen driver for pi LCD display
+Subject: [PATCH 069/203] rpi-ft5406: Add touchscreen driver for pi LCD display
---
drivers/input/touchscreen/Kconfig | 7 +
-From 275c3679e7e3be706d11e5b60a1c75249b108343 Mon Sep 17 00:00:00 2001
+From 5929da3d7ce831709884de3e3564de028fafc28c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 13 Oct 2014 11:47:53 +0100
-Subject: [PATCH 070/171] Improve __copy_to_user and __copy_from_user
+Subject: [PATCH 070/203] Improve __copy_to_user and __copy_from_user
performance
Provide a __copy_from_user that uses memcpy. On BCM2708, use
-From 1236bce6c9de357503fc9a8546288c765a94d00c Mon Sep 17 00:00:00 2001
+From b53b8765c5fe676b590ee450756321746fb84813 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 27 May 2015 17:22:15 +0100
-Subject: [PATCH 071/171] bcm2835-audio: Create the platform device if the DT
+Subject: [PATCH 071/203] bcm2835-audio: Create the platform device if the DT
node is disabled
For backwards compatibility, allow the built-in ALSA driver to be enabled
-From ceb4d98acd8bb3f0934c8519769d4b7258b648dd Mon Sep 17 00:00:00 2001
+From 1f410ca7ae3475c5683dc1ae4e8d9837ee4df9cb 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 072/171] ARM: bcm2835: Set Serial number and Revision
+Subject: [PATCH 072/203] ARM: bcm2835: Set Serial number and Revision
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 6c898089019ae79598f0d7608cc63a60c3964aca Mon Sep 17 00:00:00 2001
+From 3d0419451c7e9b5299ab34b856ce5fc6c5188a60 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 16 Jun 2015 17:47:27 +0100
-Subject: [PATCH 073/171] platform: Add force_core command line setting to boot
+Subject: [PATCH 073/203] platform: Add force_core command line setting to boot
from a different core number
---
-From 70bc0daf8746308750f5f50e2b35780af0600064 Mon Sep 17 00:00:00 2001
+From 5711c6e7c1290bca377c8fe624abca2048dabfa2 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 18 Jun 2015 17:46:17 +0100
-Subject: [PATCH 074/171] mach-bcm270x: Enable the building of pinctrl-bcm2835
+Subject: [PATCH 074/203] mach-bcm270x: Enable the building of pinctrl-bcm2835
---
drivers/pinctrl/Makefile | 1 +
-From 4bf502d06dbd4c7f4bb89e3ba1a6306c39d1710a Mon Sep 17 00:00:00 2001
+From 1b19ac4dd61353af67984ca6acc076e88b67f1a6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 19 Jun 2015 16:41:39 +0100
-Subject: [PATCH 075/171] BCM270X_DT: Document the i2s-mmap overlay
+Subject: [PATCH 075/203] BCM270X_DT: Document the i2s-mmap overlay
---
arch/arm/boot/dts/overlays/README | 6 ++++++
-From 16e7c9f047567799b3309217c44ac071b4677c63 Mon Sep 17 00:00:00 2001
+From 59435defecf72f8e5c9f4ee28591df33ffa78939 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 17 Jun 2015 11:36:53 +0100
-Subject: [PATCH 076/171] bcm2835-sdhost: Improve error handling and recovery
+Subject: [PATCH 076/203] bcm2835-sdhost: Improve error handling and recovery
1) Expose the hw_reset method to the MMC framework, removing many
internal calls by the driver.
-From 4a41e2e553ae0fe0766aa54108da5661b305ee05 Mon Sep 17 00:00:00 2001
+From 139af060398effb2c9a9dfd8d4878e4efaf57150 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Thu, 4 Jun 2015 13:11:46 -0700
-Subject: [PATCH 077/171] ARM: bcm2835: Add the Raspberry Pi firmware driver
+Subject: [PATCH 077/203] ARM: bcm2835: Add the Raspberry Pi firmware driver
This gives us a function for making mailbox property channel requests
of the firmware, which is most notable in that it will let us get and
-From b0c824459ac639a528c6d1cfcbafdb9d88ec303b Mon Sep 17 00:00:00 2001
+From 860bf6384964fbbaf4ffddeffe7fc86ecf1b2d3f Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sun, 22 Mar 2015 13:33:23 +0000
-Subject: [PATCH 078/171] config: Enable ZSMALLOC, ZRAM and PGTABLE_MAPPING
+Subject: [PATCH 078/203] config: Enable ZSMALLOC, ZRAM and PGTABLE_MAPPING
---
arch/arm/configs/bcm2709_defconfig | 4 ++++
-From 0d1f25af42a19f652489abfb637a9e05920115fe Mon Sep 17 00:00:00 2001
+From 4cfd7572f78d82a3e30c213f142ecc0d7f7cde7d Mon Sep 17 00:00:00 2001
From: Gordon Hollingworth <gordon@fiveninjas.com>
Date: Mon, 22 Jun 2015 16:27:07 +0100
-Subject: [PATCH 079/171] Add rpi-ft5406 overlay Add rpi-ft5406 driver as
+Subject: [PATCH 079/203] Add rpi-ft5406 overlay Add rpi-ft5406 driver as
module
---
-From 0e76c9361112e7a88d08b3bf3d23c6ba936de01e Mon Sep 17 00:00:00 2001
+From 1cefedfe457ea7c738ab1c10ec88fd8a5632444a Mon Sep 17 00:00:00 2001
From: Gordon Hollingworth <gordon@fiveninjas.com>
Date: Tue, 23 Jun 2015 09:53:40 +0100
-Subject: [PATCH 080/171] Fix driver detection failure Check that the buffer
+Subject: [PATCH 080/203] Fix driver detection failure Check that the buffer
response is non-zero meaning the touchscreen was detected
---
-From 1bf89f45672e473ad8b24207714b1dad0cb6eaf9 Mon Sep 17 00:00:00 2001
+From 35a332275ed70e1740874efbc34b22528995c213 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 23 Jun 2015 13:24:01 +0100
-Subject: [PATCH 081/171] config: Enable 8250 serial port
+Subject: [PATCH 081/203] config: Enable 8250 serial port
---
arch/arm/configs/bcm2709_defconfig | 7 +++++++
-From dd5ba35cd8aa9cda437ea874aaf3f21c7397fb54 Mon Sep 17 00:00:00 2001
+From f8fad3ba247648ef30b116a12a45672fb11e8ade Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 23 Jun 2015 14:10:58 +0100
-Subject: [PATCH 082/171] config: Enable POWER_RESET_GPIO
+Subject: [PATCH 082/203] config: Enable POWER_RESET_GPIO
---
arch/arm/configs/bcm2709_defconfig | 2 ++
-From 4e5881da660ecbdb759d1730defdc091999b1893 Mon Sep 17 00:00:00 2001
+From f789239f3014997243c1f46e74c7f653d3826503 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 26 Jun 2015 17:37:38 +0100
-Subject: [PATCH 083/171] bcm2708-vcio: Remove restriction of only a single
+Subject: [PATCH 083/203] bcm2708-vcio: Remove restriction of only a single
instance being open
We need more than one process to be able to use mailbox interface (e.g. HW cursor in fbturbo and hello_fft).
-From 4a613efefd7ee59661a1f73fd9ebd5656ed33bd2 Mon Sep 17 00:00:00 2001
+From 9e38795e9be092bf1197991af1ab9ea7a511fbad Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 26 Jun 2015 08:39:19 +0100
-Subject: [PATCH 084/171] BCM270X_DT: Create a "core" clock, use it for SPI and
+Subject: [PATCH 084/203] BCM270X_DT: Create a "core" clock, use it for SPI and
sdhost
---
-From 124d2c655233f0b53ec262321586f0500f4eb610 Mon Sep 17 00:00:00 2001
+From 3d715851687737bec0ecee73b8f04d47d7a29bed Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 24 Jun 2015 09:24:31 +0100
-Subject: [PATCH 085/171] BCM270X_DT: Add MCP7941X to i2c-rtc overlay
+Subject: [PATCH 085/203] BCM270X_DT: Add MCP7941X to i2c-rtc overlay
---
arch/arm/boot/dts/overlays/README | 3 +++
-From f820aa6457e3c07a1a994a68c67e044810c482ae Mon Sep 17 00:00:00 2001
+From 243585439bab9e3181082c6422a51bddce2e1535 Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Wed, 24 Jun 2015 11:23:06 +0100
-Subject: [PATCH 086/171] dts/overlays: document DHT11 overlay
+Subject: [PATCH 086/203] dts/overlays: document DHT11 overlay
---
arch/arm/boot/dts/overlays/README | 8 ++++++++
-From 54167a0f6d3ccb6a507eb270a52d17ef9f3723ec Mon Sep 17 00:00:00 2001
+From 1e890a091e0fbd61101fac37c8570c414deda17f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 25 Jun 2015 12:16:11 +0100
-Subject: [PATCH 087/171] gpio-poweroff: Allow it to work on Raspberry Pi
+Subject: [PATCH 087/203] 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 afb4d6a911d50ca4a64371a64650c4a89181fa70 Mon Sep 17 00:00:00 2001
+From 80dc9b95432ba5c368ef61925390c44de4211e83 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 17 Jun 2015 17:10:40 +0100
-Subject: [PATCH 088/171] BCM270x_DT: Default Compute Module i2c, i2s and spi
+Subject: [PATCH 088/203] BCM270x_DT: Default Compute Module i2c, i2s and spi
support
---
-From 0bdd14471d586c546f3bfcbf062fbdbe92500aff Mon Sep 17 00:00:00 2001
+From 63e7ed7e81a19be754aa1515835599b9d97b3467 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 22 Jun 2015 14:21:55 +0100
-Subject: [PATCH 089/171] BCM270X_DT: Sort nodes by bus address, and
+Subject: [PATCH 089/203] BCM270X_DT: Sort nodes by bus address, and
consolidate aliases
---
-From 779a2505afac554e6ebb5d0cd3979df9a10fbba9 Mon Sep 17 00:00:00 2001
+From 5130d7fdc237418537e377b951dd388723de1502 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 22 Jun 2015 14:23:03 +0100
-Subject: [PATCH 090/171] i2c-bcm2708/BCM270X_DT: Add support for I2C2
+Subject: [PATCH 090/203] i2c-bcm2708/BCM270X_DT: Add support for I2C2
The third I2C bus (I2C2) is normally reserved for HDMI use. Careless
use of this bus can break an attached display - use with caution.
-From d4f2ba8b1bb04c7d98c438d1b0fa698c3d15c377 Mon Sep 17 00:00:00 2001
+From 148fa81647d603e3ed8d38f7b9f37b6c04cace24 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 29 Jun 2015 12:14:02 +0100
-Subject: [PATCH 091/171] BCM270X_DT: Correct the lirc-rpi overlay
+Subject: [PATCH 091/203] BCM270X_DT: Correct the lirc-rpi overlay
documentation
The polarity of the "sense" parameter was inverted with respect to reality.
-From da37f481a3f0b884c3ef6dc2a8d57beb85bc9978 Mon Sep 17 00:00:00 2001
+From 8509eb475ed00c7d581cf05866a27fa48c4c007c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 25 Jun 2015 08:47:09 +0100
-Subject: [PATCH 092/171] bcm2835-sdhost: Further improve overclock back-off
+Subject: [PATCH 092/203] bcm2835-sdhost: Further improve overclock back-off
---
drivers/mmc/host/bcm2835-sdhost.c | 144 +++++++++++++++++++++-----------------
-From 1c2ab70602031acf8dee59ab16f46a24b71f5fb0 Mon Sep 17 00:00:00 2001
+From 40a4a1cc61a3e3e7baa9d623d8f4f68ffa815dd6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 10:28:59 +0100
-Subject: [PATCH 093/171] i2c-bcm2708: Increase timeouts to allow larger
+Subject: [PATCH 093/203] i2c-bcm2708: Increase timeouts to allow larger
transfers
Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting
-From 1afcb794cb00c4fffa69f52b303970d785ace445 Mon Sep 17 00:00:00 2001
+From 5b546cecc9b35f45c752c063d43c24dbfcc7328d Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 10:33:52 +0100
-Subject: [PATCH 094/171] spi-bcm2708: Increase timeout from 150ms to 1s
+Subject: [PATCH 094/203] spi-bcm2708: Increase timeout from 150ms to 1s
See: https://github.com/raspberrypi/linux/issues/260
---
-From 569d970e387865052fe7e4c3dc0707efeb916af8 Mon Sep 17 00:00:00 2001
+From 37f8282b8ba61d7f79cb5538d6331a04c6bdf883 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 15 Jun 2015 09:59:38 +0100
-Subject: [PATCH 095/171] bcm2708-spi: Don't use static pin configuration with
+Subject: [PATCH 095/203] bcm2708-spi: Don't use static pin configuration with
DT
Also remove superfluous error checking - the SPI framework ensures the
-From 4d8a21adf20d84a9d5792e2f1fba32ecdd33872a Mon Sep 17 00:00:00 2001
+From f556b04eb5357a2571077799babd135d65f1d7ee Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 15 Jun 2015 10:10:59 +0100
-Subject: [PATCH 096/171] bcm2708-i2s: Don't use static pin configuration with
+Subject: [PATCH 096/203] bcm2708-i2s: Don't use static pin configuration with
DT
---
-From 3e379748c62a7b9b70d790bdd192ac9a3a8b6586 Mon Sep 17 00:00:00 2001
+From 32560a31ee4fc921356d69d8dea4c271781b32df Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 14:12:42 +0100
-Subject: [PATCH 097/171] serial: 8250: Don't crash when nr_uarts is 0
+Subject: [PATCH 097/203] serial: 8250: Don't crash when nr_uarts is 0
---
drivers/tty/serial/8250/8250_core.c | 2 ++
-From 98e84cdbce80fe8a8177fb1f42800af76b3da9ac Mon Sep 17 00:00:00 2001
+From f0ba1d983da479141dc41829d75d68efa446b426 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 26 Jun 2015 08:50:11 +0100
-Subject: [PATCH 098/171] BCM270X_DT: Add overlay to enable uart1
+Subject: [PATCH 098/203] BCM270X_DT: Add overlay to enable uart1
N.B. The UART1 clock is derived from the core clock. The firmware
will update clock-frequency if core_freq is set, but be aware
-From 9ba47405b715872da8e0704767563da5f377f59a Mon Sep 17 00:00:00 2001
+From e3e8ae5998017712471c53db877bd01dd297ad01 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 24 Jun 2015 14:10:44 +0100
-Subject: [PATCH 099/171] spi-bcm2835: Support pin groups other than 7-11
+Subject: [PATCH 099/203] 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 dcdcf9bbe4b8129ec95d3b49469512df565575cb Mon Sep 17 00:00:00 2001
+From 53fadd064d2efab96564df3c50a6f1a9fdf8071a Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 17:37:38 +0100
-Subject: [PATCH 100/171] BCM270X_DT: Change pio_limit of sdhost driver to 1
+Subject: [PATCH 100/203] BCM270X_DT: Change pio_limit of sdhost driver to 1
---
arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 +-
-From c4b4cd3f5e0c6be67124fac4a7bbb5fb45de616c Mon Sep 17 00:00:00 2001
+From b43892ab64a2acc92d25cfd30f0fecba2c925cd2 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 1 Jul 2015 12:51:52 +0100
-Subject: [PATCH 101/171] bcm2835-sdhost: Clear HBLC for PIO mode
+Subject: [PATCH 101/203] bcm2835-sdhost: Clear HBLC for PIO mode
Also update pio_limit default in overlay README.
---
-From 078b8d9d1396bfb7c39b0e6a083ebf4818175f22 Mon Sep 17 00:00:00 2001
+From d81d0b4029bd1b2fb2d9ac65750c3cfa0f243f0c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 3 Jul 2015 12:21:01 +0100
-Subject: [PATCH 102/171] BCM270X_DT: I2S needs function Alt2
+Subject: [PATCH 102/203] BCM270X_DT: I2S needs function Alt2
---
arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 +-
-From 9b4cdc0c703e872255cd735f4ab4d7be10ab5494 Mon Sep 17 00:00:00 2001
+From 735143fada086487577915861a15ed4822caa9db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:16:15 +0200
-Subject: [PATCH 103/171] configs: Incorporate v4.1 dependency changes
+Subject: [PATCH 103/203] configs: Incorporate v4.1 dependency changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 6b3b5732e77d6a36e9b09b59ccac0f63f2fa3ea3 Mon Sep 17 00:00:00 2001
+From 0740517729ffa954f7cde3504c107502a1309e12 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 3 Jul 2015 15:47:33 +0100
-Subject: [PATCH 104/171] bcmrpi_defconfigs: Add SND_SOC_WM8804_I2C (for
+Subject: [PATCH 104/203] bcmrpi_defconfigs: Add SND_SOC_WM8804_I2C (for
HifiBerry Digi)
4.1 has split out support for the I2C and SPI variants, so it now
-From d55d55f560367a7392b531130b87d15ec12576ec Mon Sep 17 00:00:00 2001
+From ca8981f1b4a0c6855240895cb0dfc9fdf2d4b6ba Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Sat, 4 Jul 2015 19:55:23 +0100
-Subject: [PATCH 105/171] squash: BCM270X_DT: I2S only needs Alt2 on 28-31
+Subject: [PATCH 105/203] squash: BCM270X_DT: I2S only needs Alt2 on 28-31
See: https://github.com/raspberrypi/linux/issues/1046
---
-From fa6257d47be3fff4cf93de15a0bb59223d6a81b5 Mon Sep 17 00:00:00 2001
+From e657f5479bc871209287e26432f013fc395336ab Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 8 Jul 2015 14:48:57 +0100
-Subject: [PATCH 106/171] vchiq_arm: Two cacheing fixes
+Subject: [PATCH 106/203] vchiq_arm: Two cacheing fixes
1) Make fragment size vary with cache line size
Without this patch, non-cache-line-aligned transfers may corrupt
-From 4cbd4845d011a08deb7d68956931f26011f3221e Mon Sep 17 00:00:00 2001
+From bb7843be4cd8584ab8d3cfbd209220ccf2499327 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 09:10:36 +0100
-Subject: [PATCH 107/171] BCM270X_DT: Overlay for the Fen Logic VGA666 board
+Subject: [PATCH 107/203] BCM270X_DT: Overlay for the Fen Logic VGA666 board
The VGA666 board requires GPIOs 2-21 (so no I2C or UART). Using the
overlay (instead of a custom dt-blob.bin) has the advantage that it will
-From e3159f966a0094f895f488e799d697110f121f8c Mon Sep 17 00:00:00 2001
+From 585e94da2a9d370fc462c08641dc12adc7d7a641 Mon Sep 17 00:00:00 2001
From: petit-miner <cooker5000@gmail.com>
Date: Fri, 10 Jul 2015 13:59:18 +0200
-Subject: [PATCH 108/171] Added support for 2 mcp2515 CAN Bus IC
+Subject: [PATCH 108/203] Added support for 2 mcp2515 CAN Bus IC
See: https://github.com/raspberrypi/linux/issues/1018
https://github.com/raspberrypi/linux/pull/1049
-From bde9f0667ad91c2846cd1d392b5a653c196d0834 Mon Sep 17 00:00:00 2001
+From 4222b39965e1639c0d7a5b4e8b8c8ee91803f799 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Tue, 5 May 2015 13:27:45 -0700
-Subject: [PATCH 109/171] mailbox: Enable BCM2835 mailbox support
+Subject: [PATCH 109/203] mailbox: Enable BCM2835 mailbox support
This mailbox driver provides a single mailbox channel to write 32-bit
values to the VPU and get a 32-bit response. The Raspberry Pi
-From 012a954f49e5f22ead03df42c2775e2937824462 Mon Sep 17 00:00:00 2001
+From dbacf38b4227ffcd9a7eafdb49d395208229286c Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 13 May 2015 13:10:32 -0700
-Subject: [PATCH 110/171] mailbox/bcm2835: Fix mailbox full detection.
+Subject: [PATCH 110/203] mailbox/bcm2835: Fix mailbox full detection.
With the VC reader blocked and the ARM writing, MAIL0_STA reads empty
permanently while MAIL1_STA goes from empty (0x40000000) to non-empty
-From f4e7bad1fa582b3e9890bc0a2de7696c7df5b9b1 Mon Sep 17 00:00:00 2001
+From 2d03b90e245bb0c556b1e67b2572cb51c114bf5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:19:30 +0200
-Subject: [PATCH 111/171] mailbox: bcm2835: Support ARCH_BCM270x
+Subject: [PATCH 111/203] mailbox: bcm2835: Support ARCH_BCM270x
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From b1dd56c4c3f12e51f68618b1ffe80e6556bfa1bb Mon Sep 17 00:00:00 2001
+From 39394c602fcefa762aa9cd527d0f4afe26245c18 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Thu, 4 Jun 2015 13:11:47 -0700
-Subject: [PATCH 112/171] ARM: bcm2835: Add the firmware driver information to
+Subject: [PATCH 112/203] ARM: bcm2835: Add the firmware driver information to
the RPi DT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From 1bc4dbe1171d83354e7d5148181eeee5f035ae77 Mon Sep 17 00:00:00 2001
+From 4811a6764a8ed78a3917a19bf757659c2ed7e390 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 113/171] firmware: bcm2835: Add missing property tags
+Subject: [PATCH 113/203] firmware: bcm2835: Add missing property tags
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 557c84f3819fd730a006af48f582bc7afd2a7bf6 Mon Sep 17 00:00:00 2001
+From e79b76cd146c42e446b034c7b782569ff2ac9219 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 114/171] firmware: bcm2835: Support ARCH_BCM270x
+Subject: [PATCH 114/203] firmware: bcm2835: Support ARCH_BCM270x
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From cb10982feb7da52315426d1a9980d49482071bb0 Mon Sep 17 00:00:00 2001
+From 24337b253d6911bc1697d107460b4d9837e712f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:26:10 +0200
-Subject: [PATCH 115/171] firmware: bcm2835: Support legacy mailbox API
+Subject: [PATCH 115/203] firmware: bcm2835: Support legacy mailbox API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From b04146cc3b6a76d6ab67068803a86ffdc8dcea0b Mon Sep 17 00:00:00 2001
+From 7de8f9adc447ba0709ad29ad8af13da0085c8491 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 116/171] char: broadcom: Add vcio module
+Subject: [PATCH 116/203] char: broadcom: Add vcio module
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 50b7d8253ebbadbe4358f76f7ace99da821bd14b Mon Sep 17 00:00:00 2001
+From 9b331e3fe3724b92be61ec369c61c5c0b2cfbdbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:37:19 +0200
-Subject: [PATCH 117/171] BCM270x: Switch to firmware driver
+Subject: [PATCH 117/203] BCM270x: Switch to firmware driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From d3412121ceefb00ff13d2f353bd6f5f15c2c3629 Mon Sep 17 00:00:00 2001
+From 60ceda26c37c133a537ed1f64ddb7044732884f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:39:21 +0200
-Subject: [PATCH 118/171] bcm2835: Switch to firmware driver
+Subject: [PATCH 118/203] bcm2835: Switch to firmware driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From ea390b711a1c1ceaf30d7a44a6b1eb59249456b6 Mon Sep 17 00:00:00 2001
+From f58127f1cc42ee92a87fc7a88ea88071f1b48340 Mon Sep 17 00:00:00 2001
From: Phil Elwell <pelwell@users.noreply.github.com>
Date: Mon, 13 Jul 2015 13:25:31 +0100
-Subject: [PATCH 119/171] Merge pull request #1059 from pelwell/rpi-4.0.y
+Subject: [PATCH 119/203] Merge pull request #1059 from pelwell/rpi-4.0.y
w1_therm: Back-port locking improvements from 4.2-rc1
---
-From bf0e599855469ed27afeb8be37b7af8abe12610b Mon Sep 17 00:00:00 2001
+From 2b4d5c82da3850c7bf04c069b8eca966e931512f Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 14 Jul 2015 11:11:51 +0100
-Subject: [PATCH 120/171] vchiq_arm: Sort out the vmalloc case
+Subject: [PATCH 120/203] vchiq_arm: Sort out the vmalloc case
See: https://github.com/raspberrypi/linux/issues/1055
---
-From dcf79d117cc9268217f75b59eda5cfdd9c4a9308 Mon Sep 17 00:00:00 2001
+From 6e185e181f581341f34f7d7d288a2c4204202031 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 14 Jul 2015 10:26:09 +0100
-Subject: [PATCH 121/171] spidev: Add "spidev" compatible string to silence
+Subject: [PATCH 121/203] spidev: Add "spidev" compatible string to silence
warning
See: https://github.com/raspberrypi/linux/issues/1054
-From 78ec7eb29bc516a9489684ff09d716823c9707ea Mon Sep 17 00:00:00 2001
+From aa6bc84a28af9acd24d457944700b7880c86a343 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 122/171] Merge pull request #1043 from XECDesign/sense-4.0
+Subject: [PATCH 122/203] Merge pull request #1043 from XECDesign/sense-4.0
mfd: Add Raspberry Pi Sense HAT core driver
---
-From eb6239a15073913d0e1bdef984f0fc0196d724e6 Mon Sep 17 00:00:00 2001
+From 5a3324e4eb8898d293fdc562117877cb313718a1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 15 Jul 2015 13:46:08 +0100
-Subject: [PATCH 123/171] leds-gpio: Implement the brightness_get method
+Subject: [PATCH 123/203] leds-gpio: Implement the brightness_get method
The power LED uses some clever logic that means it is driven
by a voltage measuring circuit when configured as input, otherwise
-From 641ac228b60a8f279a82302bd21434241c8b5253 Mon Sep 17 00:00:00 2001
+From e5c8a89d140e14ac6d393fd13b7b63ed1c860799 Mon Sep 17 00:00:00 2001
From: Robert Tiemann <rtie@gmx.de>
Date: Fri, 17 Jul 2015 09:50:55 +0200
-Subject: [PATCH 124/171] dmaengine: bcm2708-dmaengine: Fix memory leak when
+Subject: [PATCH 124/203] dmaengine: bcm2708-dmaengine: Fix memory leak when
stopping a running transfer
---
-From 5a632aea29485cab29a3882cdef4840bfea0dfad Mon Sep 17 00:00:00 2001
+From 0e3c310017ae1a6491ac908502ab2999133f9517 Mon Sep 17 00:00:00 2001
From: Robert Tiemann <rtie@gmx.de>
Date: Mon, 20 Jul 2015 11:01:13 +0200
-Subject: [PATCH 125/171] BCM270X_DT: Fix I2S register map
+Subject: [PATCH 125/203] BCM270X_DT: Fix I2S register map
---
arch/arm/boot/dts/bcm2708_common.dtsi | 4 ++--
-From 717b0ba4c783ec760698843cfaca991917a6b018 Mon Sep 17 00:00:00 2001
+From 81e9e11782bc1ed34d1ada5f019aa7baa03ecf29 Mon Sep 17 00:00:00 2001
From: Robert Tiemann <rtie@gmx.de>
Date: Mon, 20 Jul 2015 11:01:25 +0200
-Subject: [PATCH 126/171] BCM2835_DT: Fix I2S register map
+Subject: [PATCH 126/203] BCM2835_DT: Fix I2S register map
---
Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++--
-From 5009252fba13a69b9962a8ac38b909c60ea1af17 Mon Sep 17 00:00:00 2001
+From 8613a587054df5b7932fbe309cd23b9ff0418b2f Mon Sep 17 00:00:00 2001
From: David Frey <david.frey@sensirion.com>
Date: Tue, 14 Jul 2015 15:57:36 +0200
-Subject: [PATCH 127/171] config: Enable SHT drivers for raspberry pi
+Subject: [PATCH 127/203] config: Enable SHT drivers for raspberry pi
The SHT temperature and humidity sensors are often used in weather
station projects.
-From a5a93adfe8a9a39708386e7655e0a34c0a54046b Mon Sep 17 00:00:00 2001
+From 2cad6845b413edda55d780d830d1facaca7406d7 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 20 Jul 2015 14:07:14 +0100
-Subject: [PATCH 128/171] BCM270X_DT: Correct typo in overlays/README
+Subject: [PATCH 128/203] BCM270X_DT: Correct typo in overlays/README
---
arch/arm/boot/dts/overlays/README | 2 +-
-From a87e7abc9818c18b1fddd8748f2d5911392e9f6b Mon Sep 17 00:00:00 2001
+From d9866cb6e1c088b399f9fbe52827499f2d973204 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 20 Jul 2015 10:53:26 +0100
-Subject: [PATCH 129/171] bcm2835-sdhost: Add the ERASE capability
+Subject: [PATCH 129/203] bcm2835-sdhost: Add the ERASE capability
See: https://github.com/raspberrypi/linux/issues/1076
---
-From 0bb775b407dab3bab972663ef47dde38b0d34c24 Mon Sep 17 00:00:00 2001
+From abc4d789f9fd535f05a3dcb08712dfd6bada45b6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 20 Jul 2015 17:32:18 +0100
-Subject: [PATCH 130/171] bcm2835-sdhost: Ignore CRC7 for MMC CMD1
+Subject: [PATCH 130/203] bcm2835-sdhost: Ignore CRC7 for MMC CMD1
It seems that the sdhost interface returns CRC7 errors for CMD1,
which is the MMC-specific SEND_OP_COND. Returning these errors to
-From 35be60b77f30a3714e5cd42108bd819253fa12cd Mon Sep 17 00:00:00 2001
+From 60fce832707c7c02890a8842ae264d27a738c0e7 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 20 Jul 2015 14:48:21 +0100
-Subject: [PATCH 131/171] BCM270X_DT: Add unit address to gpio node name
+Subject: [PATCH 131/203] BCM270X_DT: Add unit address to gpio node name
---
arch/arm/boot/dts/bcm2708_common.dtsi | 2 +-
-From 08b8ff16578a47be720dd09cb7324ff3e40c3caf Mon Sep 17 00:00:00 2001
+From e7827fda51b1e1a87bc749fdd45ecf756efb12d1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 24 Jul 2015 10:36:32 +0100
-Subject: [PATCH 132/171] BCM270X_DT: Use i2c_arm for rtc and bmp085 overlays
+Subject: [PATCH 132/203] BCM270X_DT: Use i2c_arm for rtc and bmp085 overlays
---
arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts | 2 +-
-From 95e74bed83011c25340e8d1b11d5dc95e8ff9bbc Mon Sep 17 00:00:00 2001
+From 80612a8dd0dae6bb6245080d938dc6748e68e6a6 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 24 Jul 2015 12:11:31 +0100
-Subject: [PATCH 133/171] BCM2708_DT: CM dtparams for audio, watchdog and RNG
+Subject: [PATCH 133/203] BCM2708_DT: CM dtparams for audio, watchdog and RNG
---
arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 8 ++++----
-From 91bfc5bf3bfb7830c1c35f8be90dc8c22156502d Mon Sep 17 00:00:00 2001
+From 5334f431eec498e36a589867e73adb36b476fa3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 20 Jul 2015 12:13:18 +0200
-Subject: [PATCH 134/171] vchiq: Use firmware API
+Subject: [PATCH 134/203] vchiq: Use firmware API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From aaff8adb4df57975a4a1334bb274ffce42c071e2 Mon Sep 17 00:00:00 2001
+From fb11a46fed3871b67fcf71631910afba21e6fc22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 20 Jul 2015 12:17:10 +0200
-Subject: [PATCH 135/171] thermal: bcm2835: Use firmware API
+Subject: [PATCH 135/203] thermal: bcm2835: Use firmware API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 020e1720dc926c944479da4ce0edd7508bc82d21 Mon Sep 17 00:00:00 2001
+From 65ae931012f463feeb8cece70dfc829f2cd2b6b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 20 Jul 2015 12:18:36 +0200
-Subject: [PATCH 136/171] cpufreq: bcm2835: Use firmware API
+Subject: [PATCH 136/203] cpufreq: bcm2835: Use firmware API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From f220fe12bab49d45cde9e00cd4aaf2f9bbc5ff5f Mon Sep 17 00:00:00 2001
+From 23f7babfd87a6be47db1e16e1177f5743ddb4ea5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 20 Jul 2015 12:20:59 +0200
-Subject: [PATCH 137/171] fbdev: bcm2708: Use firmware API
+Subject: [PATCH 137/203] fbdev: bcm2708: Use firmware API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 687c5493ee74d58ee1084d3e01a534a1329f5f70 Mon Sep 17 00:00:00 2001
+From 128cfa5445d62b5289ed332c82781ad016aca741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 20 Jul 2015 12:27:17 +0200
-Subject: [PATCH 138/171] bcm2835: Add firmware property to affected devices
+Subject: [PATCH 138/203] bcm2835: Add firmware property to affected devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 1c445d2c28dcbd90be62624bd9ae9bd88e564b96 Mon Sep 17 00:00:00 2001
+From 9be811d63aab0b9840ebfc3a27e59c0a50404b1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Tue, 21 Jul 2015 19:09:39 +0200
-Subject: [PATCH 139/171] rpi-ft5406: Use firmware API
+Subject: [PATCH 139/203] rpi-ft5406: Use firmware API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 0a90a21f533dbbf23a4b219cd9e8f8e3cfe7836a Mon Sep 17 00:00:00 2001
+From 0b5b35852a737361a08e7f6e0a3e6157a15948d9 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 140/171] irqchip: bcm2835: Add FIQ support
+Subject: [PATCH 140/203] irqchip: bcm2835: Add FIQ support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 509544e075da1920294a4e071bf2cc07e4175b25 Mon Sep 17 00:00:00 2001
+From 738dc17aab1f5b18d94533b189e00c5960a0def6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 15:50:04 +0200
-Subject: [PATCH 141/171] dwc_otg: Add ARCH_BCM2835 support
+Subject: [PATCH 141/203] dwc_otg: Add ARCH_BCM2835 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 2a920968d6fe0e8e05664b11fa3185309a15ffc9 Mon Sep 17 00:00:00 2001
+From b7eae04326d84f4b51ccfee02b5fb39500656fa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 15:50:24 +0200
-Subject: [PATCH 142/171] bcm2835: Use DWC_OTG
+Subject: [PATCH 142/203] bcm2835: Use DWC_OTG
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 47b2b8452f63267da699d5ca14fd5d2cec845b08 Mon Sep 17 00:00:00 2001
+From fb25dfd5b7543d9b777239e76ea12f2b64eb2437 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 19:33:16 +0200
-Subject: [PATCH 143/171] Fix RASPBERRYPI_FIRMWARE dependents
+Subject: [PATCH 143/203] Fix RASPBERRYPI_FIRMWARE dependents
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 0ea3178f01b66564c3f68c0a2531e3d00a2ceb36 Mon Sep 17 00:00:00 2001
+From 6c53947855b434549697719a85be14a738a4826d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 19:33:46 +0200
-Subject: [PATCH 144/171] vc_mem: Remove unnecessary include
+Subject: [PATCH 144/203] vc_mem: Remove unnecessary include
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 8486034f0a9ea21a67de2c996dfcf354229d1ef5 Mon Sep 17 00:00:00 2001
+From e04d908da0cea4af59fe4c67fd1684e60efa7c90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 19:34:06 +0200
-Subject: [PATCH 145/171] configs: Remove BCM2708_MBOX
+Subject: [PATCH 145/203] configs: Remove BCM2708_MBOX
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 5df47c75bf7b4f3f913db669ccf5bb6da279751f Mon Sep 17 00:00:00 2001
+From a9b8c66f63005e9d3f4cbd6591874e618492898c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 19:34:31 +0200
-Subject: [PATCH 146/171] bcm2708-vcio: Remove module
+Subject: [PATCH 146/203] bcm2708-vcio: Remove module
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
-From 345d2517a2e371b0b21c17f6667f68de602abdd2 Mon Sep 17 00:00:00 2001
+From 8892c1d6ce14da3baac8512974e20f129bb9a34e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 24 Jul 2015 19:34:55 +0200
-Subject: [PATCH 147/171] Revert "firmware: bcm2835: Support legacy mailbox
+Subject: [PATCH 147/203] Revert "firmware: bcm2835: Support legacy mailbox
API"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From 909e2b2c6b73991394f89769aa3fca05ab146d72 Mon Sep 17 00:00:00 2001
+From 9dabf31b13de7de5742e3f13c0b38fff460b552b Mon Sep 17 00:00:00 2001
From: Jonathan Bell <jonathan@raspberrypi.org>
Date: Tue, 30 Jun 2015 12:35:39 +0100
-Subject: [PATCH 148/171] pinctrl: bcm2835: Clear the event latch register when
+Subject: [PATCH 148/203] pinctrl: bcm2835: Clear the event latch register when
disabling interrupts
It's possible to hit a race condition if interrupts are generated on a GPIO
-From cab5abd144fc154c140f9f522c3c2f81a94aaa74 Mon Sep 17 00:00:00 2001
+From c069d755e30358e19c9c5f93f0e3748827a91c9d Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Tue, 4 Aug 2015 01:15:20 +0100
-Subject: [PATCH 149/171] dwc_otg: fiq_fsm: Make high-speed isochronous strided
+Subject: [PATCH 149/203] dwc_otg: fiq_fsm: Make high-speed isochronous strided
transfers work properly
Certain low-bandwidth high-speed USB devices (specialist audio devices,
-From c7f56b36920e86309a5111c56ae5d0fbb96f1961 Mon Sep 17 00:00:00 2001
+From cb0ceb651b94c8d6a01677f9b277c0d7e8862014 Mon Sep 17 00:00:00 2001
From: Uli Middelberg <uli@middelberg.de>
Date: Wed, 17 Jun 2015 10:36:56 +0200
-Subject: [PATCH 150/171] added basic docker support
+Subject: [PATCH 150/203] added basic docker support
---
arch/arm/configs/bcm2709_defconfig | 3 +++
-From 273b9fb93e4b2cfff7aeff8ea559219c2755ee95 Mon Sep 17 00:00:00 2001
+From 4e2638fe451b09fc2ba0a98b433f06b5a8986093 Mon Sep 17 00:00:00 2001
From: Garrett <g@floft.net>
Date: Thu, 2 Jul 2015 19:32:04 -0500
-Subject: [PATCH 151/171] bcm2835 camera planar/packed stride length
+Subject: [PATCH 151/203] bcm2835 camera planar/packed stride length
Added a field to the mmal_fmt struct used to compute the bytes per line
when using a particular format. This results in the correct stride being
-From 9ace261c44e2a16d13305b34b06a56c1a4838dc5 Mon Sep 17 00:00:00 2001
+From 37e5a9206165377033c020ca15caa23b930c6e73 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 17 Aug 2015 10:49:44 +0100
-Subject: [PATCH 154/171] BCM270X_DT: Add pwm and pwm-2chan overlays
+Subject: [PATCH 154/203] BCM270X_DT: Add pwm and pwm-2chan overlays
From the README entries:
Legal pin,function combinations for each channel:
-From 6b2b193e60989a674562abb13ff8780ca38592f4 Mon Sep 17 00:00:00 2001
+From 0e646de6b27ee8b6631e5cebf8beffeccad8de63 Mon Sep 17 00:00:00 2001
From: Martin Sperl <kernel@martin.sperl.org>
Date: Wed, 22 Apr 2015 07:33:03 +0000
-Subject: [PATCH 155/171] spi: bcm2835: fallback to interrupt for polling
+Subject: [PATCH 155/203] spi: bcm2835: fallback to interrupt for polling
timeouts exceeding 2 jiffies
The polling mode of the driver is designed for transfers that run
-From abff2f91fd0f8163b065b92786be93562c7e67af Mon Sep 17 00:00:00 2001
+From 7f4da26c19a10eea74419d92205886516c7f55cb Mon Sep 17 00:00:00 2001
From: Martin Sperl <kernel@martin.sperl.org>
Date: Sun, 10 May 2015 20:47:28 +0000
-Subject: [PATCH 156/171] spi: bcm2835: enable dma modes for transfers meeting
+Subject: [PATCH 156/203] spi: bcm2835: enable dma modes for transfers meeting
certain conditions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
-From fb89852f9971a3d5f40be06e2d8017b9b9b56e19 Mon Sep 17 00:00:00 2001
+From 3ab28d3476f08708cf2c256dd8a9871583edea00 Mon Sep 17 00:00:00 2001
From: Martin Sperl <kernel@martin.sperl.org>
Date: Tue, 12 May 2015 10:32:08 +0000
-Subject: [PATCH 157/171] spi: bcm2835: fix kbuild compile warnings/errors and
+Subject: [PATCH 157/203] spi: bcm2835: fix kbuild compile warnings/errors and
a typo
fixes several warnings/error emmitted by the kbuild system:
-From 35801a979c9ede9ec11ad6aca777376a337e392e Mon Sep 17 00:00:00 2001
+From 9e0ce86052c88c463ec3f95da35d5633c36894fa Mon Sep 17 00:00:00 2001
From: kbuild test robot <fengguang.wu@intel.com>
Date: Tue, 12 May 2015 19:43:59 +0800
-Subject: [PATCH 158/171] spi: bcm2835: bcm2835_dma_release() can be static
+Subject: [PATCH 158/203] spi: bcm2835: bcm2835_dma_release() can be static
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
--- /dev/null
+From ff9071764e459f0ae477ca1121cb3d225bbab3f8 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Wed, 22 Jul 2015 08:34:41 +0000
+Subject: [PATCH 159/203] dt-overlay to enable dma for spi driver
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/spi-dma-overlay.dts | 20 ++++++++++++++++++++
+ 2 files changed, 21 insertions(+)
+ create mode 100755 arch/arm/boot/dts/overlays/spi-dma-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -45,6 +45,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-sense-over
+ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts
+@@ -0,0 +1,20 @@
++/*
++ * Device tree overlay for spi-bcm2835 to allow dma
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
++
++ fragment@0 {
++ target = <&spi0>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ dmas = <&dma 6>, <&dma 7>;
++ dma-names = "tx", "rx";
++ };
++ };
++ };
+++ /dev/null
-From c36a53b3df68f0311b808f87c186b9623a28ecd9 Mon Sep 17 00:00:00 2001
-From: Martin Sperl <kernel@martin.sperl.org>
-Date: Wed, 22 Jul 2015 07:43:28 +0000
-Subject: [PATCH 159/171] spi: bcm2835: fixed compile issues due to embedded
- comments... replaced with #if to avoid issues in the future.
-
-Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
----
- drivers/spi/spi-bcm2835.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -609,6 +609,7 @@ static int bcm2835_spi_prepare_message(s
- return 0;
- }
-
-+#if 0
- static void bcm2835_spi_handle_err(struct spi_master *master,
- struct spi_message *msg)
- {
-@@ -623,6 +624,7 @@ static void bcm2835_spi_handle_err(struc
- /* and reset */
- bcm2835_spi_reset_hw(master);
- }
-+#endif
-
- static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level)
- {
--- /dev/null
+From ae4577bd4fcc0e9fb9166550433e2b0ee1ece0e1 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Wed, 22 Jul 2015 12:41:54 +0000
+Subject: [PATCH 160/203] dt: overlay: added documentation of spi-dma overlay
+
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+---
+ arch/arm/boot/dts/overlays/README | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -515,6 +515,12 @@ Load: dtoverlay=spi-bcm2835
+ Params: <None>
+
+
++Name: spi-dma
++Info: enables dma modes for spi-bcm2835
++Load: dtoverlay=spi-dma
++Params: <None>
++
++
+ Name: tinylcd35
+ Info: 3.5" Color TFT Display by www.tinylcd.com
+ Options: Touch, RTC, keypad
+++ /dev/null
-From 6d356030061c6e90437dbf4b32f95a1fa36d8868 Mon Sep 17 00:00:00 2001
-From: Martin Sperl <kernel@martin.sperl.org>
-Date: Wed, 22 Jul 2015 08:34:41 +0000
-Subject: [PATCH 160/171] dt-overlay to enable dma for spi driver
-
-Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
----
- arch/arm/boot/dts/overlays/Makefile | 1 +
- arch/arm/boot/dts/overlays/spi-dma-overlay.dts | 20 ++++++++++++++++++++
- 2 files changed, 21 insertions(+)
- create mode 100755 arch/arm/boot/dts/overlays/spi-dma-overlay.dts
-
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -45,6 +45,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-sense-over
- dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb
-+dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += uart1-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/overlays/spi-dma-overlay.dts
-@@ -0,0 +1,20 @@
-+/*
-+ * Device tree overlay for spi-bcm2835 to allow dma
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
-+
-+ fragment@0 {
-+ target = <&spi0>;
-+ __overlay__ {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ dmas = <&dma 6>, <&dma 7>;
-+ dma-names = "tx", "rx";
-+ };
-+ };
-+ };
+++ /dev/null
-From ad7d23327d85897f4c467a3cde377d73a2769ac3 Mon Sep 17 00:00:00 2001
-From: Martin Sperl <kernel@martin.sperl.org>
-Date: Wed, 22 Jul 2015 12:41:54 +0000
-Subject: [PATCH 161/171] dt: overlay: added documentation of spi-dma overlay
-
-Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
----
- arch/arm/boot/dts/overlays/README | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -515,6 +515,12 @@ Load: dtoverlay=spi-bcm2835
- Params: <None>
-
-
-+Name: spi-dma
-+Info: enables dma modes for spi-bcm2835
-+Load: dtoverlay=spi-dma
-+Params: <None>
-+
-+
- Name: tinylcd35
- Info: 3.5" Color TFT Display by www.tinylcd.com
- Options: Touch, RTC, keypad
--- /dev/null
+From 15cf5667c9508d18808e0edf95acbff0313ef954 Mon Sep 17 00:00:00 2001
+From: Serge Schneider <serge@raspberrypi.org>
+Date: Mon, 17 Aug 2015 18:06:16 +0100
+Subject: [PATCH 161/203] rpisense-fb: add low-light mode and gamma control
+
+---
+ drivers/video/fbdev/rpisense-fb.c | 68 +++++++++++++++++++++++++++++---
+ include/linux/mfd/rpisense/framebuffer.h | 6 ++-
+ 2 files changed, 68 insertions(+), 6 deletions(-)
+
+--- a/drivers/video/fbdev/rpisense-fb.c
++++ b/drivers/video/fbdev/rpisense-fb.c
+@@ -19,6 +19,7 @@
+ #include <linux/string.h>
+ #include <linux/mm.h>
+ #include <linux/slab.h>
++#include <linux/uaccess.h>
+ #include <linux/delay.h>
+ #include <linux/fb.h>
+ #include <linux/init.h>
+@@ -26,22 +27,35 @@
+ #include <linux/mfd/rpisense/framebuffer.h>
+ #include <linux/mfd/rpisense/core.h>
+
++static bool lowlight;
++module_param(lowlight, bool, 0);
++MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third");
++
+ struct rpisense *rpisense;
+
+ struct rpisense_fb_param {
+ char __iomem *vmem;
+ u8 *vmem_work;
+ u32 vmemsize;
+- u8 gamma[32];
++ u8 *gamma;
+ };
+
++static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
++ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07,
++ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11,
++ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,};
++
++static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
++ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06,
++ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,};
++
++static u8 gamma_user[32];
++
+ static struct rpisense_fb_param rpisense_fb_param = {
+ .vmem = NULL,
+ .vmemsize = 128,
+- .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+- 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07,
+- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11,
+- 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,},
++ .gamma = gamma_default,
+ };
+
+ static struct fb_deferred_io rpisense_fb_defio;
+@@ -127,6 +141,46 @@ static struct fb_deferred_io rpisense_fb
+ .deferred_io = rpisense_fb_deferred_io,
+ };
+
++static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd,
++ unsigned long arg)
++{
++ switch (cmd) {
++ case SENSEFB_FBIOGET_GAMMA:
++ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma,
++ sizeof(u8[32])))
++ return -EFAULT;
++ return 0;
++ case SENSEFB_FBIOSET_GAMMA:
++ if (copy_from_user(gamma_user, (void __user *)arg,
++ sizeof(u8[32])))
++ return -EFAULT;
++ rpisense_fb_param.gamma = gamma_user;
++ schedule_delayed_work(&info->deferred_work,
++ rpisense_fb_defio.delay);
++ return 0;
++ case SENSEFB_FBIORESET_GAMMA:
++ switch (arg) {
++ case 0:
++ rpisense_fb_param.gamma = gamma_default;
++ break;
++ case 1:
++ rpisense_fb_param.gamma = gamma_low;
++ break;
++ case 2:
++ rpisense_fb_param.gamma = gamma_user;
++ break;
++ default:
++ return -EINVAL;
++ }
++ schedule_delayed_work(&info->deferred_work,
++ rpisense_fb_defio.delay);
++ break;
++ default:
++ return -EINVAL;
++ }
++ return 0;
++}
++
+ static struct fb_ops rpisense_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_read = fb_sys_read,
+@@ -134,6 +188,7 @@ static struct fb_ops rpisense_fb_ops = {
+ .fb_fillrect = rpisense_fb_fillrect,
+ .fb_copyarea = rpisense_fb_copyarea,
+ .fb_imageblit = rpisense_fb_imageblit,
++ .fb_ioctl = rpisense_fb_ioctl,
+ };
+
+ static int rpisense_fb_probe(struct platform_device *pdev)
+@@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct plat
+ info->screen_base = rpisense_fb_param.vmem;
+ info->screen_size = rpisense_fb_param.vmemsize;
+
++ if (lowlight)
++ rpisense_fb_param.gamma = gamma_low;
++
+ fb_deferred_io_init(info);
+
+ ret = register_framebuffer(info);
+--- a/include/linux/mfd/rpisense/framebuffer.h
++++ b/include/linux/mfd/rpisense/framebuffer.h
+@@ -16,7 +16,11 @@
+ #ifndef __LINUX_RPISENSE_FB_H_
+ #define __LINUX_RPISENSE_FB_H_
+
+-#include <linux/platform_device.h>
++#define SENSEFB_FBIO_IOC_MAGIC 0xF1
++
++#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0)
++#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1)
++#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2)
+
+ struct rpisense;
+
--- /dev/null
+From 27932f3c0031925c59b6f6787dbe8c4b379bbb11 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 19 Aug 2015 11:38:10 +0100
+Subject: [PATCH 162/203] BCM270X_DT: README - add note on indentation
+
+---
+ arch/arm/boot/dts/overlays/README | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -74,6 +74,10 @@ behaviour. See the list of overlays belo
+ The Overlay and Parameter Reference
+ ===================================
+
++N.B. When editing this file, please preserve the indentation levels to make it simple to parse
++programmatically. NO HARD TABS.
++
++
+ Name: <The base DTB>
+ Info: Configures the base Raspberry Pi hardware
+ Load: <loaded automatically>
+++ /dev/null
-From a0d9e5b5186d36693a44d5fd85c1fcd43cfeee61 Mon Sep 17 00:00:00 2001
-From: Serge Schneider <serge@raspberrypi.org>
-Date: Mon, 17 Aug 2015 18:06:16 +0100
-Subject: [PATCH 162/171] rpisense-fb: add low-light mode and gamma control
-
----
- drivers/video/fbdev/rpisense-fb.c | 68 +++++++++++++++++++++++++++++---
- include/linux/mfd/rpisense/framebuffer.h | 6 ++-
- 2 files changed, 68 insertions(+), 6 deletions(-)
-
---- a/drivers/video/fbdev/rpisense-fb.c
-+++ b/drivers/video/fbdev/rpisense-fb.c
-@@ -19,6 +19,7 @@
- #include <linux/string.h>
- #include <linux/mm.h>
- #include <linux/slab.h>
-+#include <linux/uaccess.h>
- #include <linux/delay.h>
- #include <linux/fb.h>
- #include <linux/init.h>
-@@ -26,22 +27,35 @@
- #include <linux/mfd/rpisense/framebuffer.h>
- #include <linux/mfd/rpisense/core.h>
-
-+static bool lowlight;
-+module_param(lowlight, bool, 0);
-+MODULE_PARM_DESC(lowlight, "Reduce LED matrix brightness to one third");
-+
- struct rpisense *rpisense;
-
- struct rpisense_fb_param {
- char __iomem *vmem;
- u8 *vmem_work;
- u32 vmemsize;
-- u8 gamma[32];
-+ u8 *gamma;
- };
-
-+static u8 gamma_default[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-+ 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07,
-+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11,
-+ 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,};
-+
-+static u8 gamma_low[32] = {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
-+ 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06,
-+ 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x0A, 0x0A,};
-+
-+static u8 gamma_user[32];
-+
- static struct rpisense_fb_param rpisense_fb_param = {
- .vmem = NULL,
- .vmemsize = 128,
-- .gamma = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-- 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07,
-- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x11,
-- 0x12, 0x14, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,},
-+ .gamma = gamma_default,
- };
-
- static struct fb_deferred_io rpisense_fb_defio;
-@@ -127,6 +141,46 @@ static struct fb_deferred_io rpisense_fb
- .deferred_io = rpisense_fb_deferred_io,
- };
-
-+static int rpisense_fb_ioctl(struct fb_info *info, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ switch (cmd) {
-+ case SENSEFB_FBIOGET_GAMMA:
-+ if (copy_to_user((void __user *) arg, rpisense_fb_param.gamma,
-+ sizeof(u8[32])))
-+ return -EFAULT;
-+ return 0;
-+ case SENSEFB_FBIOSET_GAMMA:
-+ if (copy_from_user(gamma_user, (void __user *)arg,
-+ sizeof(u8[32])))
-+ return -EFAULT;
-+ rpisense_fb_param.gamma = gamma_user;
-+ schedule_delayed_work(&info->deferred_work,
-+ rpisense_fb_defio.delay);
-+ return 0;
-+ case SENSEFB_FBIORESET_GAMMA:
-+ switch (arg) {
-+ case 0:
-+ rpisense_fb_param.gamma = gamma_default;
-+ break;
-+ case 1:
-+ rpisense_fb_param.gamma = gamma_low;
-+ break;
-+ case 2:
-+ rpisense_fb_param.gamma = gamma_user;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ schedule_delayed_work(&info->deferred_work,
-+ rpisense_fb_defio.delay);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
- static struct fb_ops rpisense_fb_ops = {
- .owner = THIS_MODULE,
- .fb_read = fb_sys_read,
-@@ -134,6 +188,7 @@ static struct fb_ops rpisense_fb_ops = {
- .fb_fillrect = rpisense_fb_fillrect,
- .fb_copyarea = rpisense_fb_copyarea,
- .fb_imageblit = rpisense_fb_imageblit,
-+ .fb_ioctl = rpisense_fb_ioctl,
- };
-
- static int rpisense_fb_probe(struct platform_device *pdev)
-@@ -171,6 +226,9 @@ static int rpisense_fb_probe(struct plat
- info->screen_base = rpisense_fb_param.vmem;
- info->screen_size = rpisense_fb_param.vmemsize;
-
-+ if (lowlight)
-+ rpisense_fb_param.gamma = gamma_low;
-+
- fb_deferred_io_init(info);
-
- ret = register_framebuffer(info);
---- a/include/linux/mfd/rpisense/framebuffer.h
-+++ b/include/linux/mfd/rpisense/framebuffer.h
-@@ -16,7 +16,11 @@
- #ifndef __LINUX_RPISENSE_FB_H_
- #define __LINUX_RPISENSE_FB_H_
-
--#include <linux/platform_device.h>
-+#define SENSEFB_FBIO_IOC_MAGIC 0xF1
-+
-+#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0)
-+#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1)
-+#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2)
-
- struct rpisense;
-
--- /dev/null
+From a3414b2d51a0fa2b4cea7886168e5e14013904c8 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 20 Aug 2015 13:50:18 +0100
+Subject: [PATCH 163/203] bcm2708-dmaengine: Use more DMA channels (but not 12)
+
+1) Only the bcm2708_fb drivers uses the legacy DMA API, and
+it requires a BULK-capable channel, so all other types
+(FAST, NORMAL and LITE) can be made available to the regular
+DMA API.
+
+2) DMA channels 11-14 share an interrupt. The driver can't
+handle this, so don't use channels 12-14 (12 was used, probably
+because it appears to have an interrupt, but in reality that
+interrupt is for activity on ANY channel). This may explain
+a lockup encountered when running out of DMA channels.
+
+The combined effect of this patch is to leave 7 DMA channels
+available + channel 0 for bcm2708_fb via the legacy API.
+
+See: https://github.com/raspberrypi/linux/issues/1110
+ https://github.com/raspberrypi/linux/issues/1108
+---
+ arch/arm/boot/dts/bcm2708_common.dtsi | 5 ++--
+ drivers/dma/bcm2708-dmaengine.c | 43 +++++++++++++++++++++++------------
+ 2 files changed, 31 insertions(+), 17 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708_common.dtsi
++++ b/arch/arm/boot/dts/bcm2708_common.dtsi
+@@ -59,11 +59,10 @@
+ <1 24>,
+ <1 25>,
+ <1 26>,
+- <1 27>,
+- <1 28>;
++ <1 27>;
+
+ #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x7f35>;
++ brcm,dma-channel-mask = <0x0f35>;
+ };
+
+ intc: interrupt-controller {
+--- a/drivers/dma/bcm2708-dmaengine.c
++++ b/drivers/dma/bcm2708-dmaengine.c
+@@ -184,7 +184,7 @@ static void vc_dmaman_init(struct vc_dma
+ }
+
+ static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman,
+- unsigned preferred_feature_set)
++ unsigned required_feature_set)
+ {
+ u32 chans;
+ int chan = 0;
+@@ -193,10 +193,8 @@ static int vc_dmaman_chan_alloc(struct v
+ chans = dmaman->chan_available;
+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++)
+ /* select the subset of available channels with the desired
+- feature so long as some of the candidate channels have that
+- feature */
+- if ((preferred_feature_set & (1 << feature)) &&
+- (chans & dmaman->has_feature[feature]))
++ features */
++ if (required_feature_set & (1 << feature))
+ chans &= dmaman->has_feature[feature];
+
+ if (!chans)
+@@ -228,7 +226,7 @@ static int vc_dmaman_chan_free(struct vc
+
+ /* DMA Manager Monitor */
+
+-extern int bcm_dma_chan_alloc(unsigned preferred_feature_set,
++extern int bcm_dma_chan_alloc(unsigned required_feature_set,
+ void __iomem **out_dma_base, int *out_dma_irq)
+ {
+ struct vc_dmaman *dmaman = g_dmaman;
+@@ -240,7 +238,7 @@ extern int bcm_dma_chan_alloc(unsigned p
+ return -ENODEV;
+
+ mutex_lock(&dmaman->lock);
+- chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set);
++ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set);
+ if (chan < 0)
+ goto out;
+
+@@ -442,6 +440,7 @@ static inline struct bcm2835_desc *to_bc
+ return container_of(t, struct bcm2835_desc, vd.tx);
+ }
+
++#if 0
+ static void dma_dumpregs(struct bcm2835_chan *c)
+ {
+ pr_debug("-------------DMA DUMPREGS-------------\n");
+@@ -457,6 +456,7 @@ static void dma_dumpregs(struct bcm2835_
+ readl(c->chan_base + BCM2835_DMA_NEXTCB));
+ pr_debug("--------------------------------------\n");
+ }
++#endif
+
+ static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
+ {
+@@ -862,6 +862,7 @@ static struct dma_async_tx_descriptor *b
+ uint32_t len = sg_dma_len(sgent);
+
+ for (j = 0; j < len; j += max_size) {
++ u32 waits;
+ struct bcm2835_dma_cb *control_block =
+ &d->control_block_base[i+splitct];
+
+@@ -879,7 +880,7 @@ static struct dma_async_tx_descriptor *b
+ }
+
+ /* Common part */
+- u32 waits = SDHCI_BCM_DMA_WAITS;
++ waits = SDHCI_BCM_DMA_WAITS;
+ if ((dma_debug >> 0) & 0x1f)
+ waits = (dma_debug >> 0) & 0x1f;
+ control_block->info |= BCM2835_DMA_WAITS(waits);
+@@ -1074,6 +1075,14 @@ static int bcm2835_dma_probe(struct plat
+ int rc;
+ int i;
+ int irq;
++#ifdef CONFIG_DMA_BCM2708_LEGACY
++ static const u32 wanted_features[] = {
++ BCM_DMA_FEATURE_FAST,
++ BCM_DMA_FEATURE_NORMAL,
++ BCM_DMA_FEATURE_LITE
++ };
++ int j;
++#endif
+
+
+ if (!pdev->dev.dma_mask)
+@@ -1120,20 +1129,24 @@ static int bcm2835_dma_probe(struct plat
+
+ platform_set_drvdata(pdev, od);
+
+- for (i = 0; i < 5; i++) {
++ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) {
++
+ void __iomem *chan_base;
+ int chan_id;
+
+- chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE,
+- &chan_base,
+- &irq);
+-
+- if (chan_id < 0)
+- break;
++ chan_id = bcm_dma_chan_alloc(wanted_features[j],
++ &chan_base,
++ &irq);
++
++ if (chan_id < 0) {
++ j++;
++ continue;
++ }
+
+ rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq);
+ if (rc)
+ goto err_no_dma;
++ i++;
+ }
+
+ if (pdev->dev.of_node) {
+@@ -1146,6 +1159,8 @@ static int bcm2835_dma_probe(struct plat
+ }
+ }
+
++ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i);
++
+ #else
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (rc)
+++ /dev/null
-From e418efa578dab433bf7e25eaaec809b33351792c Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 18 Aug 2015 11:50:03 +0100
-Subject: [PATCH 163/171] spi: bcm2835: Fix buld error from previous commit
-
----
- drivers/spi/spi-bcm2835.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/spi/spi-bcm2835.c
-+++ b/drivers/spi/spi-bcm2835.c
-@@ -609,7 +609,6 @@ static int bcm2835_spi_prepare_message(s
- return 0;
- }
-
--#if 0
- static void bcm2835_spi_handle_err(struct spi_master *master,
- struct spi_message *msg)
- {
-@@ -624,7 +623,6 @@ static void bcm2835_spi_handle_err(struc
- /* and reset */
- bcm2835_spi_reset_hw(master);
- }
--#endif
-
- static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level)
- {
+++ /dev/null
-From a5fcc9f342ed9a3f028b8cbff4a610f1a8816b5d Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Wed, 19 Aug 2015 11:38:10 +0100
-Subject: [PATCH 164/171] BCM270X_DT: README - add note on indentation
-
----
- arch/arm/boot/dts/overlays/README | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -74,6 +74,10 @@ behaviour. See the list of overlays belo
- The Overlay and Parameter Reference
- ===================================
-
-+N.B. When editing this file, please preserve the indentation levels to make it simple to parse
-+programmatically. NO HARD TABS.
-+
-+
- Name: <The base DTB>
- Info: Configures the base Raspberry Pi hardware
- Load: <loaded automatically>
--- /dev/null
+From 82bd9c0d64c76c40bff8c4325df8302c8ffc6945 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
+Date: Sat, 11 Jul 2015 18:48:10 +0200
+Subject: [PATCH 164/203] staging: fbtft: Add reset to fbtft_init_display_dt()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When an init sequence is present in the Device Tree,
+fbtft_init_display_dt() is used to initialize the display.
+Add missing reset function call and activation of
+chip select for parallel bus.
+
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+---
+ drivers/staging/fbtft/fbtft-core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -1074,6 +1074,11 @@ static int fbtft_init_display_dt(struct
+ p = of_prop_next_u32(prop, NULL, &val);
+ if (!p)
+ return -EINVAL;
++
++ par->fbtftops.reset(par);
++ if (par->gpio.cs != -1)
++ gpio_set_value(par->gpio.cs, 0); /* Activate chip */
++
+ while (p) {
+ if (val & FBTFT_OF_INIT_CMD) {
+ val &= 0xFFFF;
--- /dev/null
+From 75cf473165850a8e765eb3a081be50fe7620e16e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
+Date: Sun, 19 Jul 2015 18:57:06 +0200
+Subject: [PATCH 165/203] BCM270X_DT: mz61581: Revert to spi-bcm2708
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The MZ61581 display does not work with spi-bcm2835 and software
+chip select. It works before the commit:
+spi: bcm2835: transform native-cs to gpio-cs on first spi_setup
+
+Revert to spi-bcm2708 until the cause has been detected and the
+issue resolved.
+
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+---
+ arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts
+@@ -12,6 +12,8 @@
+ fragment@0 {
+ target = <&spi0>;
+ __overlay__ {
++ /* does not work with spi-bcm2835 using software chip selects */
++ compatible = "brcm,bcm2708-spi";
+ status = "okay";
+
+ spidev@0{
+++ /dev/null
-From 4e62a443aa8ffecca7918db93329d8bd8210a92c Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Thu, 20 Aug 2015 13:50:18 +0100
-Subject: [PATCH 165/171] bcm2708-dmaengine: Use more DMA channels (but not 12)
-
-1) Only the bcm2708_fb drivers uses the legacy DMA API, and
-it requires a BULK-capable channel, so all other types
-(FAST, NORMAL and LITE) can be made available to the regular
-DMA API.
-
-2) DMA channels 11-14 share an interrupt. The driver can't
-handle this, so don't use channels 12-14 (12 was used, probably
-because it appears to have an interrupt, but in reality that
-interrupt is for activity on ANY channel). This may explain
-a lockup encountered when running out of DMA channels.
-
-The combined effect of this patch is to leave 7 DMA channels
-available + channel 0 for bcm2708_fb via the legacy API.
-
-See: https://github.com/raspberrypi/linux/issues/1110
- https://github.com/raspberrypi/linux/issues/1108
----
- arch/arm/boot/dts/bcm2708_common.dtsi | 5 ++--
- drivers/dma/bcm2708-dmaengine.c | 43 +++++++++++++++++++++++------------
- 2 files changed, 31 insertions(+), 17 deletions(-)
-
---- a/arch/arm/boot/dts/bcm2708_common.dtsi
-+++ b/arch/arm/boot/dts/bcm2708_common.dtsi
-@@ -59,11 +59,10 @@
- <1 24>,
- <1 25>,
- <1 26>,
-- <1 27>,
-- <1 28>;
-+ <1 27>;
-
- #dma-cells = <1>;
-- brcm,dma-channel-mask = <0x7f35>;
-+ brcm,dma-channel-mask = <0x0f35>;
- };
-
- intc: interrupt-controller {
---- a/drivers/dma/bcm2708-dmaengine.c
-+++ b/drivers/dma/bcm2708-dmaengine.c
-@@ -184,7 +184,7 @@ static void vc_dmaman_init(struct vc_dma
- }
-
- static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman,
-- unsigned preferred_feature_set)
-+ unsigned required_feature_set)
- {
- u32 chans;
- int chan = 0;
-@@ -193,10 +193,8 @@ static int vc_dmaman_chan_alloc(struct v
- chans = dmaman->chan_available;
- for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++)
- /* select the subset of available channels with the desired
-- feature so long as some of the candidate channels have that
-- feature */
-- if ((preferred_feature_set & (1 << feature)) &&
-- (chans & dmaman->has_feature[feature]))
-+ features */
-+ if (required_feature_set & (1 << feature))
- chans &= dmaman->has_feature[feature];
-
- if (!chans)
-@@ -228,7 +226,7 @@ static int vc_dmaman_chan_free(struct vc
-
- /* DMA Manager Monitor */
-
--extern int bcm_dma_chan_alloc(unsigned preferred_feature_set,
-+extern int bcm_dma_chan_alloc(unsigned required_feature_set,
- void __iomem **out_dma_base, int *out_dma_irq)
- {
- struct vc_dmaman *dmaman = g_dmaman;
-@@ -240,7 +238,7 @@ extern int bcm_dma_chan_alloc(unsigned p
- return -ENODEV;
-
- mutex_lock(&dmaman->lock);
-- chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set);
-+ chan = vc_dmaman_chan_alloc(dmaman, required_feature_set);
- if (chan < 0)
- goto out;
-
-@@ -442,6 +440,7 @@ static inline struct bcm2835_desc *to_bc
- return container_of(t, struct bcm2835_desc, vd.tx);
- }
-
-+#if 0
- static void dma_dumpregs(struct bcm2835_chan *c)
- {
- pr_debug("-------------DMA DUMPREGS-------------\n");
-@@ -457,6 +456,7 @@ static void dma_dumpregs(struct bcm2835_
- readl(c->chan_base + BCM2835_DMA_NEXTCB));
- pr_debug("--------------------------------------\n");
- }
-+#endif
-
- static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
- {
-@@ -862,6 +862,7 @@ static struct dma_async_tx_descriptor *b
- uint32_t len = sg_dma_len(sgent);
-
- for (j = 0; j < len; j += max_size) {
-+ u32 waits;
- struct bcm2835_dma_cb *control_block =
- &d->control_block_base[i+splitct];
-
-@@ -879,7 +880,7 @@ static struct dma_async_tx_descriptor *b
- }
-
- /* Common part */
-- u32 waits = SDHCI_BCM_DMA_WAITS;
-+ waits = SDHCI_BCM_DMA_WAITS;
- if ((dma_debug >> 0) & 0x1f)
- waits = (dma_debug >> 0) & 0x1f;
- control_block->info |= BCM2835_DMA_WAITS(waits);
-@@ -1074,6 +1075,14 @@ static int bcm2835_dma_probe(struct plat
- int rc;
- int i;
- int irq;
-+#ifdef CONFIG_DMA_BCM2708_LEGACY
-+ static const u32 wanted_features[] = {
-+ BCM_DMA_FEATURE_FAST,
-+ BCM_DMA_FEATURE_NORMAL,
-+ BCM_DMA_FEATURE_LITE
-+ };
-+ int j;
-+#endif
-
-
- if (!pdev->dev.dma_mask)
-@@ -1120,20 +1129,24 @@ static int bcm2835_dma_probe(struct plat
-
- platform_set_drvdata(pdev, od);
-
-- for (i = 0; i < 5; i++) {
-+ for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) {
-+
- void __iomem *chan_base;
- int chan_id;
-
-- chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE,
-- &chan_base,
-- &irq);
--
-- if (chan_id < 0)
-- break;
-+ chan_id = bcm_dma_chan_alloc(wanted_features[j],
-+ &chan_base,
-+ &irq);
-+
-+ if (chan_id < 0) {
-+ j++;
-+ continue;
-+ }
-
- rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq);
- if (rc)
- goto err_no_dma;
-+ i++;
- }
-
- if (pdev->dev.of_node) {
-@@ -1146,6 +1159,8 @@ static int bcm2835_dma_probe(struct plat
- }
- }
-
-+ dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i);
-+
- #else
- rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (rc)
--- /dev/null
+From c69d4dbfcf290abc926a4499a7583b7514726ad1 Mon Sep 17 00:00:00 2001
+From: Luke Wren <luke@raspberrypi.org>
+Date: Fri, 21 Aug 2015 23:14:48 +0100
+Subject: [PATCH 166/203] Add /dev/gpiomem device for rootless user GPIO access
+
+Signed-off-by: Luke Wren <luke@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2708.dtsi | 6 +
+ arch/arm/boot/dts/bcm2709.dtsi | 6 +
+ drivers/char/broadcom/Kconfig | 9 ++
+ drivers/char/broadcom/Makefile | 3 +
+ drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++
+ 5 files changed, 289 insertions(+)
+ create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c
+
+--- a/arch/arm/boot/dts/bcm2708.dtsi
++++ b/arch/arm/boot/dts/bcm2708.dtsi
+@@ -15,5 +15,11 @@
+ arm-pmu {
+ compatible = "arm,arm1176-pmu";
+ };
++
++ gpiomem {
++ compatible = "brcm,bcm2835-gpiomem";
++ reg = <0x7e200000 0x1000>;
++ status = "okay";
++ };
+ };
+ };
+--- a/arch/arm/boot/dts/bcm2709.dtsi
++++ b/arch/arm/boot/dts/bcm2709.dtsi
+@@ -16,6 +16,12 @@
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <3 9>;
+ };
++
++ gpiomem {
++ compatible = "brcm,bcm2835-gpiomem";
++ reg = <0x7e200000 0x1000>;
++ status = "okay";
++ };
+ };
+
+ timer {
+--- a/drivers/char/broadcom/Kconfig
++++ b/drivers/char/broadcom/Kconfig
+@@ -38,3 +38,12 @@ config BCM_VC_SM
+ help
+ Support for the VC shared memory on the Broadcom reference
+ design. Uses the VCHIQ stack.
++
++config BCM2835_DEVGPIOMEM
++ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835"
++ default m
++ help
++ Provides users with root-free access to the GPIO registers
++ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO
++ register page to the user's pointer.
++
+--- a/drivers/char/broadcom/Makefile
++++ b/drivers/char/broadcom/Makefile
+@@ -2,3 +2,6 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/
+ obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
+ obj-$(CONFIG_BCM_VCIO) += vcio.o
+ obj-$(CONFIG_BCM_VC_SM) += vc_sm/
++
++obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o
++
+--- /dev/null
++++ b/drivers/char/broadcom/bcm2835-gpiomem.c
+@@ -0,0 +1,265 @@
++/**
++ * GPIO memory device driver
++ *
++ * Creates a chardev /dev/gpiomem which will provide user access to
++ * the BCM2835's GPIO registers when it is mmap()'d.
++ * No longer need root for user GPIO access, but without relaxing permissions
++ * on /dev/mem.
++ *
++ * Written by Luke Wren <luke@raspberrypi.org>
++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. The names of the above-listed copyright holders may not be used
++ * to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2, as published by the Free
++ * Software Foundation.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/cdev.h>
++#include <linux/pagemap.h>
++#include <linux/io.h>
++
++#define DEVICE_NAME "bcm2835-gpiomem"
++#define DRIVER_NAME "gpiomem-bcm2835"
++#define DEVICE_MINOR 0
++
++struct bcm2835_gpiomem_instance {
++ unsigned long gpio_regs_phys;
++ struct device *dev;
++};
++
++static struct cdev bcm2835_gpiomem_cdev;
++static dev_t bcm2835_gpiomem_devid;
++static struct class *bcm2835_gpiomem_class;
++static struct device *bcm2835_gpiomem_dev;
++static struct bcm2835_gpiomem_instance *inst;
++
++
++/****************************************************************************
++*
++* GPIO mem chardev file ops
++*
++***************************************************************************/
++
++static int bcm2835_gpiomem_open(struct inode *inode, struct file *file)
++{
++ int dev = iminor(inode);
++ int ret = 0;
++
++ dev_info(inst->dev, "gpiomem device opened.");
++
++ if (dev != DEVICE_MINOR) {
++ dev_err(inst->dev, "Unknown minor device: %d", dev);
++ ret = -ENXIO;
++ }
++ return ret;
++}
++
++static int bcm2835_gpiomem_release(struct inode *inode, struct file *file)
++{
++ int dev = iminor(inode);
++ int ret = 0;
++
++ if (dev != DEVICE_MINOR) {
++ dev_err(inst->dev, "Unknown minor device %d", dev);
++ ret = -ENXIO;
++ }
++ return ret;
++}
++
++static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = {
++#ifdef CONFIG_HAVE_IOREMAP_PROT
++ .access = generic_access_phys
++#endif
++};
++
++static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ /* Ignore what the user says - they're getting the GPIO regs
++ whether they like it or not! */
++ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT;
++
++ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page,
++ PAGE_SIZE,
++ vma->vm_page_prot);
++ vma->vm_ops = &bcm2835_gpiomem_vm_ops;
++ if (remap_pfn_range(vma, vma->vm_start,
++ gpio_page,
++ PAGE_SIZE,
++ vma->vm_page_prot)) {
++ return -EAGAIN;
++ }
++ return 0;
++}
++
++static const struct file_operations
++bcm2835_gpiomem_fops = {
++ .owner = THIS_MODULE,
++ .open = bcm2835_gpiomem_open,
++ .release = bcm2835_gpiomem_release,
++ .mmap = bcm2835_gpiomem_mmap,
++};
++
++
++ /****************************************************************************
++*
++* Probe and remove functions
++*
++***************************************************************************/
++
++
++static int bcm2835_gpiomem_probe(struct platform_device *pdev)
++{
++ int err;
++ void *ptr_err;
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ struct resource *ioresource;
++
++ /* Allocate buffers and instance data */
++
++ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL);
++
++ if (!inst) {
++ err = -ENOMEM;
++ goto failed_inst_alloc;
++ }
++
++ inst->dev = dev;
++
++ /* Create character device entries */
++
++ err = alloc_chrdev_region(&bcm2835_gpiomem_devid,
++ DEVICE_MINOR, 1, DEVICE_NAME);
++ if (err != 0) {
++ dev_err(inst->dev, "unable to allocate device number");
++ goto failed_alloc_chrdev;
++ }
++ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops);
++ bcm2835_gpiomem_cdev.owner = THIS_MODULE;
++ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1);
++ if (err != 0) {
++ dev_err(inst->dev, "unable to register device");
++ goto failed_cdev_add;
++ }
++
++ /* Create sysfs entries */
++
++ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME);
++ ptr_err = bcm2835_gpiomem_class;
++ if (IS_ERR(ptr_err))
++ goto failed_class_create;
++
++ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL,
++ bcm2835_gpiomem_devid, NULL,
++ "gpiomem");
++ ptr_err = bcm2835_gpiomem_dev;
++ if (IS_ERR(ptr_err))
++ goto failed_device_create;
++
++ /* Get address from device tree if available (*_resource() correctly
++ converts the bus address in device tree to a physical address),
++ or use hardcoded offset + BCM2708_PERI_BASE if not.
++ (In spite of its name 2708 actually seems to have the correct
++ mach-dependent value on 2709 etc, as it is defined in
++ mach-bcm270x/platform.h) */
++
++ if (node) {
++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ inst->gpio_regs_phys = ioresource->start;
++ } else {
++ inst->gpio_regs_phys = GPIO_BASE;
++ }
++
++ dev_info(inst->dev, "Initialised: Registers at 0x%08lx",
++ inst->gpio_regs_phys);
++
++ return 0;
++
++failed_device_create:
++ class_destroy(bcm2835_gpiomem_class);
++failed_class_create:
++ cdev_del(&bcm2835_gpiomem_cdev);
++ err = PTR_ERR(ptr_err);
++failed_cdev_add:
++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1);
++failed_alloc_chrdev:
++ kfree(inst);
++failed_inst_alloc:
++ dev_err(inst->dev, "could not load bcm2835_gpiomem");
++ return err;
++}
++
++static int bcm2835_gpiomem_remove(struct platform_device *pdev)
++{
++ struct device *dev = inst->dev;
++
++ kfree(inst);
++ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid);
++ class_destroy(bcm2835_gpiomem_class);
++ cdev_del(&bcm2835_gpiomem_cdev);
++ unregister_chrdev_region(bcm2835_gpiomem_devid, 1);
++
++ dev_info(dev, "GPIO mem driver removed - OK");
++ return 0;
++}
++
++ /****************************************************************************
++*
++* Register the driver with device tree
++*
++***************************************************************************/
++
++static const struct of_device_id bcm2835_gpiomem_of_match[] = {
++ {.compatible = "brcm,bcm2835-gpiomem",},
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match);
++
++static struct platform_driver bcm2835_gpiomem_driver = {
++ .probe = bcm2835_gpiomem_probe,
++ .remove = bcm2835_gpiomem_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = bcm2835_gpiomem_of_match,
++ },
++};
++
++module_platform_driver(bcm2835_gpiomem_driver);
++
++MODULE_ALIAS("platform:gpiomem-bcm2835");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace");
++MODULE_AUTHOR("Luke Wren <luke@raspberrypi.org>");
+++ /dev/null
-From 568f8a45569daead5a9474074994a3b1dd8bcfc7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
-Date: Sat, 11 Jul 2015 18:48:10 +0200
-Subject: [PATCH 166/171] staging: fbtft: Add reset to fbtft_init_display_dt()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When an init sequence is present in the Device Tree,
-fbtft_init_display_dt() is used to initialize the display.
-Add missing reset function call and activation of
-chip select for parallel bus.
-
-Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
----
- drivers/staging/fbtft/fbtft-core.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/staging/fbtft/fbtft-core.c
-+++ b/drivers/staging/fbtft/fbtft-core.c
-@@ -1074,6 +1074,11 @@ static int fbtft_init_display_dt(struct
- p = of_prop_next_u32(prop, NULL, &val);
- if (!p)
- return -EINVAL;
-+
-+ par->fbtftops.reset(par);
-+ if (par->gpio.cs != -1)
-+ gpio_set_value(par->gpio.cs, 0); /* Activate chip */
-+
- while (p) {
- if (val & FBTFT_OF_INIT_CMD) {
- val &= 0xFFFF;
+++ /dev/null
-From 79cc7775c324c4dd392d62db7f50c2933d23cf1f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
-Date: Sun, 19 Jul 2015 18:57:06 +0200
-Subject: [PATCH 167/171] BCM270X_DT: mz61581: Revert to spi-bcm2708
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MZ61581 display does not work with spi-bcm2835 and software
-chip select. It works before the commit:
-spi: bcm2835: transform native-cs to gpio-cs on first spi_setup
-
-Revert to spi-bcm2708 until the cause has been detected and the
-issue resolved.
-
-Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
----
- arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts
-+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts
-@@ -12,6 +12,8 @@
- fragment@0 {
- target = <&spi0>;
- __overlay__ {
-+ /* does not work with spi-bcm2835 using software chip selects */
-+ compatible = "brcm,bcm2708-spi";
- status = "okay";
-
- spidev@0{
--- /dev/null
+From 8cbdae16b29ddf95d9eccc74c355d8a37c520bdd Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jan@grulich.eu>
+Date: Mon, 24 Aug 2015 16:02:34 +0100
+Subject: [PATCH 167/203] tpa6130a2: Add headphone switch control
+
+Signed-off-by: Jan Grulich <jan@grulich.eu>
+---
+ sound/soc/codecs/tpa6130a2.c | 29 ++++++++++++++++++++++++++---
+ 1 file changed, 26 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/codecs/tpa6130a2.c
++++ b/sound/soc/codecs/tpa6130a2.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) Nokia Corporation
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
++ * Modified: Jan Grulich <jan@grulich.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -52,6 +53,8 @@ struct tpa6130a2_data {
+ enum tpa_model id;
+ };
+
++static void tpa6130a2_channel_enable(u8 channel, int enable);
++
+ static int tpa6130a2_i2c_read(int reg)
+ {
+ struct tpa6130a2_data *data;
+@@ -189,7 +192,7 @@ exit:
+ }
+
+ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
++ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+@@ -218,7 +221,7 @@ static int tpa6130a2_get_volsw(struct sn
+ }
+
+ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
++ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+@@ -255,8 +258,22 @@ static int tpa6130a2_put_volsw(struct sn
+ return 1;
+ }
+
++static int tpa6130a2_put_hp_sw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ int enable = ucontrol->value.integer.value[0];
++ unsigned int state;
++
++ state = (tpa6130a2_read(TPA6130A2_REG_VOL_MUTE) & 0x80) == 0;
++ if (state == enable)
++ return 0; /* No change */
++
++ tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, enable);
++ return 1; /* Changed */
++}
++
+ /*
+- * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
++ * TPA6130 volume. From -59.5 to +4.0 dB with increasing step size when going
+ * down in gain.
+ */
+ static const unsigned int tpa6130_tlv[] = {
+@@ -278,6 +295,9 @@ static const struct snd_kcontrol_new tpa
+ TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
+ tpa6130a2_get_volsw, tpa6130a2_put_volsw,
+ tpa6130_tlv),
++ SOC_SINGLE_EXT("TPA6130A2 Headphone Playback Switch",
++ TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
++ tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
+ };
+
+ static const unsigned int tpa6140_tlv[] = {
+@@ -292,6 +312,9 @@ static const struct snd_kcontrol_new tpa
+ TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
+ tpa6130a2_get_volsw, tpa6130a2_put_volsw,
+ tpa6140_tlv),
++ SOC_SINGLE_EXT("TPA6140A2 Headphone Playback Switch",
++ TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
++ tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
+ };
+
+ /*
+++ /dev/null
-From ba24fdcd3a1f7282dfba9e5137beaa9d0f999969 Mon Sep 17 00:00:00 2001
-From: Luke Wren <luke@raspberrypi.org>
-Date: Fri, 21 Aug 2015 23:14:48 +0100
-Subject: [PATCH 168/171] Add /dev/gpiomem device for rootless user GPIO access
-
-Signed-off-by: Luke Wren <luke@raspberrypi.org>
----
- arch/arm/boot/dts/bcm2708.dtsi | 6 +
- arch/arm/boot/dts/bcm2709.dtsi | 6 +
- drivers/char/broadcom/Kconfig | 9 ++
- drivers/char/broadcom/Makefile | 3 +
- drivers/char/broadcom/bcm2835-gpiomem.c | 265 ++++++++++++++++++++++++++++++++
- 5 files changed, 289 insertions(+)
- create mode 100644 drivers/char/broadcom/bcm2835-gpiomem.c
-
---- a/arch/arm/boot/dts/bcm2708.dtsi
-+++ b/arch/arm/boot/dts/bcm2708.dtsi
-@@ -15,5 +15,11 @@
- arm-pmu {
- compatible = "arm,arm1176-pmu";
- };
-+
-+ gpiomem {
-+ compatible = "brcm,bcm2835-gpiomem";
-+ reg = <0x7e200000 0x1000>;
-+ status = "okay";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm2709.dtsi
-+++ b/arch/arm/boot/dts/bcm2709.dtsi
-@@ -16,6 +16,12 @@
- compatible = "arm,cortex-a7-pmu";
- interrupts = <3 9>;
- };
-+
-+ gpiomem {
-+ compatible = "brcm,bcm2835-gpiomem";
-+ reg = <0x7e200000 0x1000>;
-+ status = "okay";
-+ };
- };
-
- timer {
---- a/drivers/char/broadcom/Kconfig
-+++ b/drivers/char/broadcom/Kconfig
-@@ -38,3 +38,12 @@ config BCM_VC_SM
- help
- Support for the VC shared memory on the Broadcom reference
- design. Uses the VCHIQ stack.
-+
-+config BCM2835_DEVGPIOMEM
-+ tristate "/dev/gpiomem rootless GPIO access via mmap() on the BCM2835"
-+ default m
-+ help
-+ Provides users with root-free access to the GPIO registers
-+ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO
-+ register page to the user's pointer.
-+
---- a/drivers/char/broadcom/Makefile
-+++ b/drivers/char/broadcom/Makefile
-@@ -2,3 +2,6 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/
- obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
- obj-$(CONFIG_BCM_VCIO) += vcio.o
- obj-$(CONFIG_BCM_VC_SM) += vc_sm/
-+
-+obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o
-+
---- /dev/null
-+++ b/drivers/char/broadcom/bcm2835-gpiomem.c
-@@ -0,0 +1,265 @@
-+/**
-+ * GPIO memory device driver
-+ *
-+ * Creates a chardev /dev/gpiomem which will provide user access to
-+ * the BCM2835's GPIO registers when it is mmap()'d.
-+ * No longer need root for user GPIO access, but without relaxing permissions
-+ * on /dev/mem.
-+ *
-+ * Written by Luke Wren <luke@raspberrypi.org>
-+ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions, and the following disclaimer,
-+ * without modification.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. The names of the above-listed copyright holders may not be used
-+ * to endorse or promote products derived from this software without
-+ * specific prior written permission.
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") version 2, as published by the Free
-+ * Software Foundation.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/cdev.h>
-+#include <linux/pagemap.h>
-+#include <linux/io.h>
-+
-+#define DEVICE_NAME "bcm2835-gpiomem"
-+#define DRIVER_NAME "gpiomem-bcm2835"
-+#define DEVICE_MINOR 0
-+
-+struct bcm2835_gpiomem_instance {
-+ unsigned long gpio_regs_phys;
-+ struct device *dev;
-+};
-+
-+static struct cdev bcm2835_gpiomem_cdev;
-+static dev_t bcm2835_gpiomem_devid;
-+static struct class *bcm2835_gpiomem_class;
-+static struct device *bcm2835_gpiomem_dev;
-+static struct bcm2835_gpiomem_instance *inst;
-+
-+
-+/****************************************************************************
-+*
-+* GPIO mem chardev file ops
-+*
-+***************************************************************************/
-+
-+static int bcm2835_gpiomem_open(struct inode *inode, struct file *file)
-+{
-+ int dev = iminor(inode);
-+ int ret = 0;
-+
-+ dev_info(inst->dev, "gpiomem device opened.");
-+
-+ if (dev != DEVICE_MINOR) {
-+ dev_err(inst->dev, "Unknown minor device: %d", dev);
-+ ret = -ENXIO;
-+ }
-+ return ret;
-+}
-+
-+static int bcm2835_gpiomem_release(struct inode *inode, struct file *file)
-+{
-+ int dev = iminor(inode);
-+ int ret = 0;
-+
-+ if (dev != DEVICE_MINOR) {
-+ dev_err(inst->dev, "Unknown minor device %d", dev);
-+ ret = -ENXIO;
-+ }
-+ return ret;
-+}
-+
-+static const struct vm_operations_struct bcm2835_gpiomem_vm_ops = {
-+#ifdef CONFIG_HAVE_IOREMAP_PROT
-+ .access = generic_access_phys
-+#endif
-+};
-+
-+static int bcm2835_gpiomem_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ /* Ignore what the user says - they're getting the GPIO regs
-+ whether they like it or not! */
-+ unsigned long gpio_page = inst->gpio_regs_phys >> PAGE_SHIFT;
-+
-+ vma->vm_page_prot = phys_mem_access_prot(file, gpio_page,
-+ PAGE_SIZE,
-+ vma->vm_page_prot);
-+ vma->vm_ops = &bcm2835_gpiomem_vm_ops;
-+ if (remap_pfn_range(vma, vma->vm_start,
-+ gpio_page,
-+ PAGE_SIZE,
-+ vma->vm_page_prot)) {
-+ return -EAGAIN;
-+ }
-+ return 0;
-+}
-+
-+static const struct file_operations
-+bcm2835_gpiomem_fops = {
-+ .owner = THIS_MODULE,
-+ .open = bcm2835_gpiomem_open,
-+ .release = bcm2835_gpiomem_release,
-+ .mmap = bcm2835_gpiomem_mmap,
-+};
-+
-+
-+ /****************************************************************************
-+*
-+* Probe and remove functions
-+*
-+***************************************************************************/
-+
-+
-+static int bcm2835_gpiomem_probe(struct platform_device *pdev)
-+{
-+ int err;
-+ void *ptr_err;
-+ struct device *dev = &pdev->dev;
-+ struct device_node *node = dev->of_node;
-+ struct resource *ioresource;
-+
-+ /* Allocate buffers and instance data */
-+
-+ inst = kzalloc(sizeof(struct bcm2835_gpiomem_instance), GFP_KERNEL);
-+
-+ if (!inst) {
-+ err = -ENOMEM;
-+ goto failed_inst_alloc;
-+ }
-+
-+ inst->dev = dev;
-+
-+ /* Create character device entries */
-+
-+ err = alloc_chrdev_region(&bcm2835_gpiomem_devid,
-+ DEVICE_MINOR, 1, DEVICE_NAME);
-+ if (err != 0) {
-+ dev_err(inst->dev, "unable to allocate device number");
-+ goto failed_alloc_chrdev;
-+ }
-+ cdev_init(&bcm2835_gpiomem_cdev, &bcm2835_gpiomem_fops);
-+ bcm2835_gpiomem_cdev.owner = THIS_MODULE;
-+ err = cdev_add(&bcm2835_gpiomem_cdev, bcm2835_gpiomem_devid, 1);
-+ if (err != 0) {
-+ dev_err(inst->dev, "unable to register device");
-+ goto failed_cdev_add;
-+ }
-+
-+ /* Create sysfs entries */
-+
-+ bcm2835_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME);
-+ ptr_err = bcm2835_gpiomem_class;
-+ if (IS_ERR(ptr_err))
-+ goto failed_class_create;
-+
-+ bcm2835_gpiomem_dev = device_create(bcm2835_gpiomem_class, NULL,
-+ bcm2835_gpiomem_devid, NULL,
-+ "gpiomem");
-+ ptr_err = bcm2835_gpiomem_dev;
-+ if (IS_ERR(ptr_err))
-+ goto failed_device_create;
-+
-+ /* Get address from device tree if available (*_resource() correctly
-+ converts the bus address in device tree to a physical address),
-+ or use hardcoded offset + BCM2708_PERI_BASE if not.
-+ (In spite of its name 2708 actually seems to have the correct
-+ mach-dependent value on 2709 etc, as it is defined in
-+ mach-bcm270x/platform.h) */
-+
-+ if (node) {
-+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ inst->gpio_regs_phys = ioresource->start;
-+ } else {
-+ inst->gpio_regs_phys = GPIO_BASE;
-+ }
-+
-+ dev_info(inst->dev, "Initialised: Registers at 0x%08lx",
-+ inst->gpio_regs_phys);
-+
-+ return 0;
-+
-+failed_device_create:
-+ class_destroy(bcm2835_gpiomem_class);
-+failed_class_create:
-+ cdev_del(&bcm2835_gpiomem_cdev);
-+ err = PTR_ERR(ptr_err);
-+failed_cdev_add:
-+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1);
-+failed_alloc_chrdev:
-+ kfree(inst);
-+failed_inst_alloc:
-+ dev_err(inst->dev, "could not load bcm2835_gpiomem");
-+ return err;
-+}
-+
-+static int bcm2835_gpiomem_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = inst->dev;
-+
-+ kfree(inst);
-+ device_destroy(bcm2835_gpiomem_class, bcm2835_gpiomem_devid);
-+ class_destroy(bcm2835_gpiomem_class);
-+ cdev_del(&bcm2835_gpiomem_cdev);
-+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1);
-+
-+ dev_info(dev, "GPIO mem driver removed - OK");
-+ return 0;
-+}
-+
-+ /****************************************************************************
-+*
-+* Register the driver with device tree
-+*
-+***************************************************************************/
-+
-+static const struct of_device_id bcm2835_gpiomem_of_match[] = {
-+ {.compatible = "brcm,bcm2835-gpiomem",},
-+ { /* sentinel */ },
-+};
-+
-+MODULE_DEVICE_TABLE(of, bcm2835_gpiomem_of_match);
-+
-+static struct platform_driver bcm2835_gpiomem_driver = {
-+ .probe = bcm2835_gpiomem_probe,
-+ .remove = bcm2835_gpiomem_remove,
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = bcm2835_gpiomem_of_match,
-+ },
-+};
-+
-+module_platform_driver(bcm2835_gpiomem_driver);
-+
-+MODULE_ALIAS("platform:gpiomem-bcm2835");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace");
-+MODULE_AUTHOR("Luke Wren <luke@raspberrypi.org>");
--- /dev/null
+From a382428726be87f1d848772a4c1a619144a33c98 Mon Sep 17 00:00:00 2001
+From: Jan Grulich <jan@grulich.eu>
+Date: Mon, 24 Aug 2015 16:03:47 +0100
+Subject: [PATCH 168/203] RaspiDAC3 support
+
+Signed-off-by: Jan Grulich <jan@grulich.eu>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 6 +
+ arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++++++
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ sound/soc/bcm/Kconfig | 8 +
+ sound/soc/bcm/Makefile | 2 +
+ sound/soc/bcm/raspidac3.c | 191 +++++++++++++++++++++++
+ 8 files changed, 255 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts
+ create mode 100644 sound/soc/bcm/raspidac3.c
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -37,6 +37,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resist
+ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -455,6 +455,12 @@ Params: pin Output
+ clock PWM clock frequency (informational)
+
+
++Name: raspidac3
++Info: Configures the RaspiDAV Rev.3x audio card
++Load: dtoverlay=raspidac3
++Params: <None>
++
++
+ Name: rpi-dac
+ Info: Configures the RPi DAC audio card
+ Load: dtoverlay=rpi-dac
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts
+@@ -0,0 +1,45 @@
++// Definitions for RaspiDACv3
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&sound>;
++ __overlay__ {
++ compatible = "jg,raspidacv3";
++ 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";
++ };
++
++ tpa6130a2: tpa6130a2@60 {
++ compatible = "ti,tpa6130a2";
++ reg = <0x60>;
++ status = "okay";
++ };
++ };
++ };
++};
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -830,6 +830,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
+ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
+ CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
+ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
+ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -823,6 +823,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
+ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
+ CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
+ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
++CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
+ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -67,3 +67,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
+ select SND_SOC_PCM512x_I2C
+ help
+ Say Y or M if you want to add support for IQaudIO-DAC.
++
++config SND_BCM2708_SOC_RASPIDAC3
++ tristate "Support for RaspiDAC Rev.3x"
++ depends on SND_BCM2708_SOC_I2S
++ select SND_SOC_PCM512x_I2C
++ select SND_SOC_TPA6130A2
++ help
++ Say Y or M if you want to add support for RaspiDAC Rev.3x.
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -16,6 +16,7 @@ snd-soc-hifiberry-amp-objs := hifiberry_
+ snd-soc-rpi-dac-objs := rpi-dac.o
+ snd-soc-rpi-proto-objs := rpi-proto.o
+ snd-soc-iqaudio-dac-objs := iqaudio-dac.o
++snd-soc-raspidac3-objs := raspidac3.o
+
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
+@@ -24,3 +25,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_A
+ 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
++obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
+--- /dev/null
++++ b/sound/soc/bcm/raspidac3.c
+@@ -0,0 +1,191 @@
++/*
++ * ASoC Driver for RaspiDAC v3
++ *
++ * Author: Jan Grulich <jan@grulich.eu>
++ * Copyright 2015
++ * based on code by Daniel Matuschek <daniel@hifiberry.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 <sound/soc-dapm.h>
++
++#include "../codecs/pcm512x.h"
++#include "../codecs/tpa6130a2.h"
++
++/* sound card init */
++static int snd_rpi_raspidac3_init(struct snd_soc_pcm_runtime *rtd)
++{
++ int ret;
++ struct snd_soc_card *card = rtd->card;
++ 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,0x00);
++
++ 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);
++ else {
++ struct snd_kcontrol *kctl;
++
++ ret = tpa6130a2_add_controls(codec);
++ if (ret < 0)
++ dev_warn(card->dev, "Failed to add TPA6130A2 controls: %d\n",
++ ret);
++ ret = snd_soc_limit_volume(codec,
++ "TPA6130A2 Headphone Playback Volume",
++ 54);
++ if (ret < 0)
++ dev_warn(card->dev, "Failed to set TPA6130A2 volume limit: %d\n",
++ ret);
++ kctl = snd_soc_card_get_kcontrol(card,
++ "TPA6130A2 Headphone Playback Volume");
++ if (kctl) {
++ strcpy(kctl->id.name, "Headphones Playback Volume");
++ /* disable the volume dB scale so alsamixer works */
++ kctl->vd[0].access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
++ }
++
++ kctl = snd_soc_card_get_kcontrol(card,
++ "TPA6130A2 Headphone Playback Switch");
++ if (kctl)
++ strcpy(kctl->id.name, "Headphones Playback Switch");
++ }
++
++ return 0;
++}
++
++/* set hw parameters */
++static int snd_rpi_raspidac3_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;
++
++ unsigned int sample_bits =
++ snd_pcm_format_physical_width(params_format(params));
++
++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
++}
++
++/* startup */
++static int snd_rpi_raspidac3_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);
++ tpa6130a2_stereo_enable(codec, 1);
++ return 0;
++}
++
++/* shutdown */
++static void snd_rpi_raspidac3_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);
++ tpa6130a2_stereo_enable(codec, 0);
++}
++
++/* machine stream operations */
++static struct snd_soc_ops snd_rpi_raspidac3_ops = {
++ .hw_params = snd_rpi_raspidac3_hw_params,
++ .startup = snd_rpi_raspidac3_startup,
++ .shutdown = snd_rpi_raspidac3_shutdown,
++};
++
++/* interface setup */
++static struct snd_soc_dai_link snd_rpi_raspidac3_dai[] = {
++{
++ .name = "RaspiDAC Rev.3x",
++ .stream_name = "RaspiDAC HiFi",
++ .cpu_dai_name = "bcm2708-i2s.0",
++ .codec_dai_name = "pcm512x-hifi",
++ .platform_name = "bcm2708-i2s.0",
++ .codec_name = "pcm512x.1-004c",
++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBS_CFS,
++ .ops = &snd_rpi_raspidac3_ops,
++ .init = snd_rpi_raspidac3_init,
++},
++};
++
++/* audio machine driver */
++static struct snd_soc_card snd_rpi_raspidac3 = {
++ .name = "RaspiDAC Rev.3x HiFi Audio Card",
++ .dai_link = snd_rpi_raspidac3_dai,
++ .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai),
++};
++
++/* sound card test */
++static int snd_rpi_raspidac3_probe(struct platform_device *pdev)
++{
++ int ret = 0;
++
++ snd_rpi_raspidac3.dev = &pdev->dev;
++
++ if (pdev->dev.of_node) {
++ struct device_node *i2s_node;
++ struct snd_soc_dai_link *dai = &snd_rpi_raspidac3_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_raspidac3);
++ if (ret)
++ dev_err(&pdev->dev,
++ "snd_soc_register_card() failed: %d\n", ret);
++
++ return ret;
++}
++
++/* sound card disconnect */
++static int snd_rpi_raspidac3_remove(struct platform_device *pdev)
++{
++ return snd_soc_unregister_card(&snd_rpi_raspidac3);
++}
++
++static const struct of_device_id raspidac3_of_match[] = {
++ { .compatible = "jg,raspidacv3", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, raspidac3_of_match);
++
++/* sound card platform driver */
++static struct platform_driver snd_rpi_raspidac3_driver = {
++ .driver = {
++ .name = "snd-rpi-raspidac3",
++ .owner = THIS_MODULE,
++ .of_match_table = raspidac3_of_match,
++ },
++ .probe = snd_rpi_raspidac3_probe,
++ .remove = snd_rpi_raspidac3_remove,
++};
++
++module_platform_driver(snd_rpi_raspidac3_driver);
++
++MODULE_AUTHOR("Jan Grulich <jan@grulich.eu>");
++MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x");
++MODULE_LICENSE("GPL v2");
--- /dev/null
+From 67ab743eaa1c6fc4c82aa7238eb82d0e779869fa Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 14 Jul 2015 16:55:02 +0100
+Subject: [PATCH 169/203] config: Add SND_SOC_ADAU1701 module
+
+---
+ 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
+@@ -831,6 +831,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
+ CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
+ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
+ CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
++CONFIG_SND_SOC_ADAU1701=m
+ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -824,6 +824,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
+ CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
+ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
+ CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
++CONFIG_SND_SOC_ADAU1701=m
+ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+++ /dev/null
-From aa7324f2f5f19ea3b2865897041f5a2838a92ac7 Mon Sep 17 00:00:00 2001
-From: Jan Grulich <jan@grulich.eu>
-Date: Mon, 24 Aug 2015 16:02:34 +0100
-Subject: [PATCH 169/171] tpa6130a2: Add headphone switch control
-
-Signed-off-by: Jan Grulich <jan@grulich.eu>
----
- sound/soc/codecs/tpa6130a2.c | 29 ++++++++++++++++++++++++++---
- 1 file changed, 26 insertions(+), 3 deletions(-)
-
---- a/sound/soc/codecs/tpa6130a2.c
-+++ b/sound/soc/codecs/tpa6130a2.c
-@@ -4,6 +4,7 @@
- * Copyright (C) Nokia Corporation
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
-+ * Modified: Jan Grulich <jan@grulich.eu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
-@@ -52,6 +53,8 @@ struct tpa6130a2_data {
- enum tpa_model id;
- };
-
-+static void tpa6130a2_channel_enable(u8 channel, int enable);
-+
- static int tpa6130a2_i2c_read(int reg)
- {
- struct tpa6130a2_data *data;
-@@ -189,7 +192,7 @@ exit:
- }
-
- static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
-- struct snd_ctl_elem_value *ucontrol)
-+ struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
-@@ -218,7 +221,7 @@ static int tpa6130a2_get_volsw(struct sn
- }
-
- static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
-- struct snd_ctl_elem_value *ucontrol)
-+ struct snd_ctl_elem_value *ucontrol)
- {
- struct soc_mixer_control *mc =
- (struct soc_mixer_control *)kcontrol->private_value;
-@@ -255,8 +258,22 @@ static int tpa6130a2_put_volsw(struct sn
- return 1;
- }
-
-+static int tpa6130a2_put_hp_sw(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ int enable = ucontrol->value.integer.value[0];
-+ unsigned int state;
-+
-+ state = (tpa6130a2_read(TPA6130A2_REG_VOL_MUTE) & 0x80) == 0;
-+ if (state == enable)
-+ return 0; /* No change */
-+
-+ tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, enable);
-+ return 1; /* Changed */
-+}
-+
- /*
-- * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
-+ * TPA6130 volume. From -59.5 to +4.0 dB with increasing step size when going
- * down in gain.
- */
- static const unsigned int tpa6130_tlv[] = {
-@@ -278,6 +295,9 @@ static const struct snd_kcontrol_new tpa
- TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
- tpa6130a2_get_volsw, tpa6130a2_put_volsw,
- tpa6130_tlv),
-+ SOC_SINGLE_EXT("TPA6130A2 Headphone Playback Switch",
-+ TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
-+ tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
- };
-
- static const unsigned int tpa6140_tlv[] = {
-@@ -292,6 +312,9 @@ static const struct snd_kcontrol_new tpa
- TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
- tpa6130a2_get_volsw, tpa6130a2_put_volsw,
- tpa6140_tlv),
-+ SOC_SINGLE_EXT("TPA6140A2 Headphone Playback Switch",
-+ TPA6130A2_REG_VOL_MUTE, 7, 1, 1,
-+ tpa6130a2_get_volsw, tpa6130a2_put_hp_sw),
- };
-
- /*
+++ /dev/null
-From 023b465fbab6f672219706bbe19a9fbfa38c6192 Mon Sep 17 00:00:00 2001
-From: Jan Grulich <jan@grulich.eu>
-Date: Mon, 24 Aug 2015 16:03:47 +0100
-Subject: [PATCH 170/171] RaspiDAC3 support
-
-Signed-off-by: Jan Grulich <jan@grulich.eu>
----
- arch/arm/boot/dts/overlays/Makefile | 1 +
- arch/arm/boot/dts/overlays/README | 6 +
- arch/arm/boot/dts/overlays/raspidac3-overlay.dts | 45 ++++++
- arch/arm/configs/bcm2709_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 1 +
- sound/soc/bcm/Kconfig | 8 +
- sound/soc/bcm/Makefile | 2 +
- sound/soc/bcm/raspidac3.c | 191 +++++++++++++++++++++++
- 8 files changed, 255 insertions(+)
- create mode 100644 arch/arm/boot/dts/overlays/raspidac3-overlay.dts
- create mode 100644 sound/soc/bcm/raspidac3.c
-
---- a/arch/arm/boot/dts/overlays/Makefile
-+++ b/arch/arm/boot/dts/overlays/Makefile
-@@ -37,6 +37,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resist
- dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += pwm-2chan-overlay.dtb
-+dtb-$(RPI_DT_OVERLAYS) += raspidac3-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb
- dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-overlay.dtb
---- a/arch/arm/boot/dts/overlays/README
-+++ b/arch/arm/boot/dts/overlays/README
-@@ -455,6 +455,12 @@ Params: pin Output
- clock PWM clock frequency (informational)
-
-
-+Name: raspidac3
-+Info: Configures the RaspiDAV Rev.3x audio card
-+Load: dtoverlay=raspidac3
-+Params: <None>
-+
-+
- Name: rpi-dac
- Info: Configures the RPi DAC audio card
- Load: dtoverlay=rpi-dac
---- /dev/null
-+++ b/arch/arm/boot/dts/overlays/raspidac3-overlay.dts
-@@ -0,0 +1,45 @@
-+// Definitions for RaspiDACv3
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "brcm,bcm2708";
-+
-+ fragment@0 {
-+ target = <&sound>;
-+ __overlay__ {
-+ compatible = "jg,raspidacv3";
-+ 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";
-+ };
-+
-+ tpa6130a2: tpa6130a2@60 {
-+ compatible = "ti,tpa6130a2";
-+ reg = <0x60>;
-+ status = "okay";
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/configs/bcm2709_defconfig
-+++ b/arch/arm/configs/bcm2709_defconfig
-@@ -830,6 +830,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
- CONFIG_SND_BCM2708_SOC_RPI_DAC=m
- CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
- CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
-+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
- CONFIG_SND_SOC_WM8804_I2C=m
- CONFIG_SND_SIMPLE_CARD=m
- CONFIG_SOUND_PRIME=m
---- a/arch/arm/configs/bcmrpi_defconfig
-+++ b/arch/arm/configs/bcmrpi_defconfig
-@@ -823,6 +823,7 @@ CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m
- CONFIG_SND_BCM2708_SOC_RPI_DAC=m
- CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
- CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
-+CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
- CONFIG_SND_SOC_WM8804_I2C=m
- CONFIG_SND_SIMPLE_CARD=m
- CONFIG_SOUND_PRIME=m
---- a/sound/soc/bcm/Kconfig
-+++ b/sound/soc/bcm/Kconfig
-@@ -67,3 +67,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
- select SND_SOC_PCM512x_I2C
- help
- Say Y or M if you want to add support for IQaudIO-DAC.
-+
-+config SND_BCM2708_SOC_RASPIDAC3
-+ tristate "Support for RaspiDAC Rev.3x"
-+ depends on SND_BCM2708_SOC_I2S
-+ select SND_SOC_PCM512x_I2C
-+ select SND_SOC_TPA6130A2
-+ help
-+ Say Y or M if you want to add support for RaspiDAC Rev.3x.
---- a/sound/soc/bcm/Makefile
-+++ b/sound/soc/bcm/Makefile
-@@ -16,6 +16,7 @@ snd-soc-hifiberry-amp-objs := hifiberry_
- snd-soc-rpi-dac-objs := rpi-dac.o
- snd-soc-rpi-proto-objs := rpi-proto.o
- snd-soc-iqaudio-dac-objs := iqaudio-dac.o
-+snd-soc-raspidac3-objs := raspidac3.o
-
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
-@@ -24,3 +25,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_A
- 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
-+obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
---- /dev/null
-+++ b/sound/soc/bcm/raspidac3.c
-@@ -0,0 +1,191 @@
-+/*
-+ * ASoC Driver for RaspiDAC v3
-+ *
-+ * Author: Jan Grulich <jan@grulich.eu>
-+ * Copyright 2015
-+ * based on code by Daniel Matuschek <daniel@hifiberry.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 <sound/soc-dapm.h>
-+
-+#include "../codecs/pcm512x.h"
-+#include "../codecs/tpa6130a2.h"
-+
-+/* sound card init */
-+static int snd_rpi_raspidac3_init(struct snd_soc_pcm_runtime *rtd)
-+{
-+ int ret;
-+ struct snd_soc_card *card = rtd->card;
-+ 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,0x00);
-+
-+ 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);
-+ else {
-+ struct snd_kcontrol *kctl;
-+
-+ ret = tpa6130a2_add_controls(codec);
-+ if (ret < 0)
-+ dev_warn(card->dev, "Failed to add TPA6130A2 controls: %d\n",
-+ ret);
-+ ret = snd_soc_limit_volume(codec,
-+ "TPA6130A2 Headphone Playback Volume",
-+ 54);
-+ if (ret < 0)
-+ dev_warn(card->dev, "Failed to set TPA6130A2 volume limit: %d\n",
-+ ret);
-+ kctl = snd_soc_card_get_kcontrol(card,
-+ "TPA6130A2 Headphone Playback Volume");
-+ if (kctl) {
-+ strcpy(kctl->id.name, "Headphones Playback Volume");
-+ /* disable the volume dB scale so alsamixer works */
-+ kctl->vd[0].access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
-+ }
-+
-+ kctl = snd_soc_card_get_kcontrol(card,
-+ "TPA6130A2 Headphone Playback Switch");
-+ if (kctl)
-+ strcpy(kctl->id.name, "Headphones Playback Switch");
-+ }
-+
-+ return 0;
-+}
-+
-+/* set hw parameters */
-+static int snd_rpi_raspidac3_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;
-+
-+ unsigned int sample_bits =
-+ snd_pcm_format_physical_width(params_format(params));
-+
-+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
-+}
-+
-+/* startup */
-+static int snd_rpi_raspidac3_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);
-+ tpa6130a2_stereo_enable(codec, 1);
-+ return 0;
-+}
-+
-+/* shutdown */
-+static void snd_rpi_raspidac3_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);
-+ tpa6130a2_stereo_enable(codec, 0);
-+}
-+
-+/* machine stream operations */
-+static struct snd_soc_ops snd_rpi_raspidac3_ops = {
-+ .hw_params = snd_rpi_raspidac3_hw_params,
-+ .startup = snd_rpi_raspidac3_startup,
-+ .shutdown = snd_rpi_raspidac3_shutdown,
-+};
-+
-+/* interface setup */
-+static struct snd_soc_dai_link snd_rpi_raspidac3_dai[] = {
-+{
-+ .name = "RaspiDAC Rev.3x",
-+ .stream_name = "RaspiDAC HiFi",
-+ .cpu_dai_name = "bcm2708-i2s.0",
-+ .codec_dai_name = "pcm512x-hifi",
-+ .platform_name = "bcm2708-i2s.0",
-+ .codec_name = "pcm512x.1-004c",
-+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-+ SND_SOC_DAIFMT_CBS_CFS,
-+ .ops = &snd_rpi_raspidac3_ops,
-+ .init = snd_rpi_raspidac3_init,
-+},
-+};
-+
-+/* audio machine driver */
-+static struct snd_soc_card snd_rpi_raspidac3 = {
-+ .name = "RaspiDAC Rev.3x HiFi Audio Card",
-+ .dai_link = snd_rpi_raspidac3_dai,
-+ .num_links = ARRAY_SIZE(snd_rpi_raspidac3_dai),
-+};
-+
-+/* sound card test */
-+static int snd_rpi_raspidac3_probe(struct platform_device *pdev)
-+{
-+ int ret = 0;
-+
-+ snd_rpi_raspidac3.dev = &pdev->dev;
-+
-+ if (pdev->dev.of_node) {
-+ struct device_node *i2s_node;
-+ struct snd_soc_dai_link *dai = &snd_rpi_raspidac3_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_raspidac3);
-+ if (ret)
-+ dev_err(&pdev->dev,
-+ "snd_soc_register_card() failed: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+/* sound card disconnect */
-+static int snd_rpi_raspidac3_remove(struct platform_device *pdev)
-+{
-+ return snd_soc_unregister_card(&snd_rpi_raspidac3);
-+}
-+
-+static const struct of_device_id raspidac3_of_match[] = {
-+ { .compatible = "jg,raspidacv3", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, raspidac3_of_match);
-+
-+/* sound card platform driver */
-+static struct platform_driver snd_rpi_raspidac3_driver = {
-+ .driver = {
-+ .name = "snd-rpi-raspidac3",
-+ .owner = THIS_MODULE,
-+ .of_match_table = raspidac3_of_match,
-+ },
-+ .probe = snd_rpi_raspidac3_probe,
-+ .remove = snd_rpi_raspidac3_remove,
-+};
-+
-+module_platform_driver(snd_rpi_raspidac3_driver);
-+
-+MODULE_AUTHOR("Jan Grulich <jan@grulich.eu>");
-+MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x");
-+MODULE_LICENSE("GPL v2");
--- /dev/null
+From d3f5bff6c861a3addea60da69196172f2e6d360c Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 1 Sep 2015 16:52:34 +0000
+Subject: [PATCH 170/203] vchiq: fix NULL pointer dereference when closing
+ driver
+
+The following code run as root will cause a null pointer dereference oops:
+
+ int fd = open("/dev/vc-cma", O_RDONLY);
+ if (fd < 0)
+ err(1, "open failed");
+ (void)close(fd);
+
+[ 1704.877721] Unable to handle kernel NULL pointer dereference at virtual address 00000000
+[ 1704.877725] pgd = b899c000
+[ 1704.877736] [00000000] *pgd=37fab831, *pte=00000000, *ppte=00000000
+[ 1704.877748] Internal error: Oops: 817 [#1] PREEMPT SMP ARM
+[ 1704.877765] Modules linked in: evdev i2c_bcm2708 uio_pdrv_genirq uio
+[ 1704.877774] CPU: 2 PID: 3656 Comm: stress-ng-fstat Not tainted 3.19.1-12-generic-bcm2709 #12-Ubuntu
+[ 1704.877777] Hardware name: BCM2709
+[ 1704.877783] task: b8ab9b00 ti: b7e68000 task.ti: b7e68000
+[ 1704.877798] PC is at __down_interruptible+0x50/0xec
+[ 1704.877806] LR is at down_interruptible+0x5c/0x68
+[ 1704.877813] pc : [<80630ee8>] lr : [<800704b0>] psr: 60080093
+sp : b7e69e50 ip : b7e69e88 fp : b7e69e84
+[ 1704.877817] r10: b88123c8 r9 : 00000010 r8 : 00000001
+[ 1704.877822] r7 : b8ab9b00 r6 : 7fffffff r5 : 80a1cc34 r4 : 80a1cc34
+[ 1704.877826] r3 : b7e69e50 r2 : 00000000 r1 : 00000000 r0 : 80a1cc34
+[ 1704.877833] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
+[ 1704.877838] Control: 10c5387d Table: 3899c06a DAC: 00000015
+[ 1704.877843] Process do-oops (pid: 3656, stack limit = 0xb7e68238)
+[ 1704.877848] Stack: (0xb7e69e50 to 0xb7e6a000)
+[ 1704.877856] 9e40: 80a1cc3c 00000000 00000010 b88123c8
+[ 1704.877865] 9e60: b7e69e84 80a1cc34 fff9fee9 ffffffff b7e68000 00000009 b7e69ea4 b7e69e88
+[ 1704.877874] 9e80: 800704b0 80630ea4 fff9fee9 60080013 80a1cc28 fff9fee9 b7e69edc b7e69ea8
+[ 1704.877884] 9ea0: 8040f558 80070460 fff9fee9 ffffffff 00000000 00000000 00000009 80a1cb7c
+[ 1704.877893] 9ec0: 00000000 80a1cb7c 00000000 00000010 b7e69ef4 b7e69ee0 803e1ba4 8040f514
+[ 1704.877902] 9ee0: 00000e48 80a1cb7c b7e69f14 b7e69ef8 803e1c9c 803e1b74 b88123c0 b92acb18
+[ 1704.877911] 9f00: b8812790 b8d815d8 b7e69f24 b7e69f18 803e2250 803e1bc8 b7e69f5c b7e69f28
+[ 1704.877921] 9f20: 80167bac 803e222c 00000000 00000000 b7e69f54 b8ab9ffc 00000000 8098c794
+[ 1704.877930] 9f40: b8ab9b00 8000efc4 b7e68000 00000000 b7e69f6c b7e69f60 80167d6c 80167b28
+[ 1704.877939] 9f60: b7e69f8c b7e69f70 80047d38 80167d60 b7e68000 b7e68010 8000efc4 b7e69fb0
+[ 1704.877949] 9f80: b7e69fac b7e69f90 80012820 80047c84 01155490 011549a8 00000001 00000006
+[ 1704.877957] 9fa0: 00000000 b7e69fb0 8000ee5c 80012790 00000000 353d8c0f 7efc4308 00000000
+[ 1704.877966] 9fc0: 01155490 011549a8 00000001 00000006 00000000 00000000 76cf3ba0 00000003
+[ 1704.877975] 9fe0: 00000000 7efc42e4 0002272f 76e2ed66 60080030 00000003 00000000 00000000
+[ 1704.877998] [<80630ee8>] (__down_interruptible) from [<800704b0>] (down_interruptible+0x5c/0x68)
+[ 1704.878015] [<800704b0>] (down_interruptible) from [<8040f558>] (vchiu_queue_push+0x50/0xd8)
+[ 1704.878032] [<8040f558>] (vchiu_queue_push) from [<803e1ba4>] (send_worker_msg+0x3c/0x54)
+[ 1704.878045] [<803e1ba4>] (send_worker_msg) from [<803e1c9c>] (vc_cma_set_reserve+0xe0/0x1c4)
+[ 1704.878057] [<803e1c9c>] (vc_cma_set_reserve) from [<803e2250>] (vc_cma_release+0x30/0x38)
+[ 1704.878069] [<803e2250>] (vc_cma_release) from [<80167bac>] (__fput+0x90/0x1e0)
+[ 1704.878082] [<80167bac>] (__fput) from [<80167d6c>] (____fput+0x18/0x1c)
+[ 1704.878094] [<80167d6c>] (____fput) from [<80047d38>] (task_work_run+0xc0/0xf8)
+[ 1704.878109] [<80047d38>] (task_work_run) from [<80012820>] (do_work_pending+0x9c/0xc4)
+[ 1704.878123] [<80012820>] (do_work_pending) from [<8000ee5c>] (work_pending+0xc/0x20)
+[ 1704.878133] Code: e50b1034 e3a01000 e50b2030 e580300c (e5823000)
+
+..the fix is to ensure that we have actually initialized the queue before we attempt
+to push any items onto it. This occurs if we do an open() followed by a close() without
+any activity in between.
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c | 4 ++++
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h | 1 +
+ 2 files changed, 5 insertions(+)
+
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
+@@ -46,6 +46,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queu
+ queue->size = size;
+ queue->read = 0;
+ queue->write = 0;
++ queue->initialized = 1;
+
+ sema_init(&queue->pop, 0);
+ sema_init(&queue->push, 0);
+@@ -76,6 +77,9 @@ int vchiu_queue_is_full(VCHIU_QUEUE_T *q
+
+ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
+ {
++ if (!queue->initialized)
++ return;
++
+ while (queue->write == queue->read + queue->size) {
+ if (down_interruptible(&queue->pop) != 0) {
+ flush_signals(current);
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h
+@@ -60,6 +60,7 @@ typedef struct {
+ int size;
+ int read;
+ int write;
++ int initialized;
+
+ struct semaphore pop;
+ struct semaphore push;
--- /dev/null
+From 7e5a9f5063a11fcb006c77ee41584b9cc63a79b5 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 2 Sep 2015 07:13:17 -0400
+Subject: [PATCH 171/203] bcm2708_fb: remove redundant code as detected by
+ static analysis
+
+static analysis with cppcheck detected some redundant code which
+should probably be removed:
+
+[drivers/video/fbdev/bcm2708_fb.c:269]: (style) Variable 'yres'
+ is assigned a value that is never used.
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/video/fbdev/bcm2708_fb.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/video/fbdev/bcm2708_fb.c
++++ b/drivers/video/fbdev/bcm2708_fb.c
+@@ -263,12 +263,6 @@ static int bcm2708_fb_check_var(struct f
+ if (var->yoffset > var->yres_virtual - var->yres)
+ var->yoffset = var->yres_virtual - var->yres - 1;
+
+- yres = var->yres;
+- if (var->vmode & FB_VMODE_DOUBLE)
+- yres *= 2;
+- else if (var->vmode & FB_VMODE_INTERLACED)
+- yres = (yres + 1) / 2;
+-
+ return 0;
+ }
+
+++ /dev/null
-From 75a0d18d0d9f501f4325cf9917cae681d3dd995a Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 14 Jul 2015 16:55:02 +0100
-Subject: [PATCH 171/171] config: Add SND_SOC_ADAU1701 module
-
----
- 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
-@@ -831,6 +831,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
- CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
- CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
- CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
-+CONFIG_SND_SOC_ADAU1701=m
- CONFIG_SND_SOC_WM8804_I2C=m
- CONFIG_SND_SIMPLE_CARD=m
- CONFIG_SOUND_PRIME=m
---- a/arch/arm/configs/bcmrpi_defconfig
-+++ b/arch/arm/configs/bcmrpi_defconfig
-@@ -824,6 +824,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m
- CONFIG_SND_BCM2708_SOC_RPI_PROTO=m
- CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
- CONFIG_SND_BCM2708_SOC_RASPIDAC3=m
-+CONFIG_SND_SOC_ADAU1701=m
- CONFIG_SND_SOC_WM8804_I2C=m
- CONFIG_SND_SIMPLE_CARD=m
- CONFIG_SOUND_PRIME=m
--- /dev/null
+From 8a969160370faf8c7b09959ca36456d5f96a64d7 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 2 Sep 2015 07:15:38 -0400
+Subject: [PATCH 172/203] bcm2708_fb: remove unnecessary initialization of
+ result
+
+static analysis by cppcheck detected an unnecessary initialization
+of variable 'result' which is re-assigned almost immediately after
+the initialization. Remove the redundant initialization.
+
+[drivers/video/fbdev/bcm2708_fb.c:406]: (performance) Variable
+ 'result' is reassigned a value before the old one has been used.
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/video/fbdev/bcm2708_fb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/bcm2708_fb.c
++++ b/drivers/video/fbdev/bcm2708_fb.c
+@@ -420,7 +420,7 @@ static int bcm2708_fb_blank(int blank_mo
+
+ static int bcm2708_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
+- s32 result = -1;
++ s32 result;
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ result = bcm2708_fb_set_par(info);
--- /dev/null
+From d3735e837e3102dfee2d2429c8043c9f4c673383 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 2 Sep 2015 07:27:36 -0400
+Subject: [PATCH 173/203] vcsm: increment res_stats MAP_FAIL stats before we
+ potentially release the resource
+
+resource can be kfree'd when the reference count is zero, so we should
+not bump the res_stats of the resource after the vmcs_sm_release_resource
+call since the resource may have been kfree'd by this call. Instead, bump
+the stats before we call vmcs_sm_release_resource to avoid a potential
+NULL pointer derefernce.
+
+Bug found using cppcheck static analysis:
+
+[drivers/char/broadcom/vc_sm/vmcs_sm.c:1373]: (error) Dereferencing
+ 'resource' after it is deallocated / released
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/char/broadcom/vc_sm/vmcs_sm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c
++++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c
+@@ -1368,8 +1368,8 @@ static int vc_sm_mmap(struct file *file,
+ return 0;
+
+ error:
+- vmcs_sm_release_resource(resource, 0);
+ resource->res_stats[MAP_FAIL]++;
++ vmcs_sm_release_resource(resource, 0);
+ return ret;
+ }
+
--- /dev/null
+From ebdecd6494e5b67306b5e247180f5d5c4b3d8f27 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 2 Sep 2015 07:33:39 -0400
+Subject: [PATCH 174/203] bcm2835: camera: check for scene not being found
+
+static analysis by cppcheck detected some potential NULL pointer
+dereference issues:
+
+[drivers/media/platform/bcm2835/controls.c:854]: (error) Possible null
+ pointer dereference: scene
+ (and lines 858, 859 too)
+
+it is possible that scene is not found because of an invalue ctrl->val
+and is therefore NULL and hence causing a null pointer dereference.
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/media/platform/bcm2835/controls.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/media/platform/bcm2835/controls.c
++++ b/drivers/media/platform/bcm2835/controls.c
+@@ -845,6 +845,8 @@ static int ctrl_set_scene_mode(struct bm
+ break;
+ }
+ }
++ if (!scene)
++ return -EINVAL;
+ if (i >= ARRAY_SIZE(scene_configs))
+ return -EINVAL;
+
--- /dev/null
+From ec31dc882de68b041b6ac36e3de7e17cf256c222 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Wed, 2 Sep 2015 07:47:51 -0400
+Subject: [PATCH 175/203] bcm2835: memcpy port data to m rather than rmsg
+
+static analysis by cppcheck detected a memcpy to rmsg which is
+not actually initialized at that point. The memcpy should be copying
+to variable m instead.
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+---
+ drivers/media/platform/bcm2835/mmal-vchiq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/platform/bcm2835/mmal-vchiq.c
++++ b/drivers/media/platform/bcm2835/mmal-vchiq.c
+@@ -851,7 +851,7 @@ static int port_info_set(struct vchiq_mm
+ sizeof(union mmal_es_specific_format));
+
+ m.u.port_info_set.format.extradata_size = port->format.extradata_size;
+- memcpy(rmsg->u.port_info_set.extradata, port->format.extradata,
++ memcpy(&m.u.port_info_set.extradata, port->format.extradata,
+ port->format.extradata_size);
+
+ ret = send_synchronous_mmal_msg(instance, &m,
--- /dev/null
+From 6e1447aaad894f45595a45fc52ae5f7dbe072b2e Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Wed, 29 Jul 2015 07:34:10 +0000
+Subject: [PATCH 176/203] spi: bcm2835: fix overflow in calculation of transfer
+ time
+
+This resulted in the use of polling mode when other approaches
+(dma or interrupts) would have been more appropriate.
+
+Happened for transfers longer than 477 bytes.
+
+Reported-by: Noralf Tronnes <noralf@tronnes.org>
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+(cherry picked from commit 0122a5183088e3117bb9c8fbe248914efb502f3f)
+---
+ drivers/spi/spi-bcm2835.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -480,7 +480,7 @@ static int bcm2835_spi_transfer_one_poll
+ struct spi_device *spi,
+ struct spi_transfer *tfr,
+ u32 cs,
+- unsigned long xfer_time_us)
++ unsigned long long xfer_time_us)
+ {
+ struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ unsigned long timeout;
+@@ -531,7 +531,8 @@ static int bcm2835_spi_transfer_one(stru
+ {
+ struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ unsigned long spi_hz, clk_hz, cdiv;
+- unsigned long spi_used_hz, xfer_time_us;
++ unsigned long spi_used_hz;
++ unsigned long long xfer_time_us;
+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
+
+ /* set clock */
+@@ -573,9 +574,10 @@ static int bcm2835_spi_transfer_one(stru
+ bs->rx_len = tfr->len;
+
+ /* calculate the estimated time in us the transfer runs */
+- xfer_time_us = tfr->len
++ xfer_time_us = (unsigned long long)tfr->len
+ * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */
+- * 1000000 / spi_used_hz;
++ * 1000000;
++ do_div(xfer_time_us, spi_used_hz);
+
+ /* for short requests run polling*/
+ if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US)
--- /dev/null
+From a0adae0d3e1327dfa796986e45bbe20dee335f2c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 8 Sep 2015 15:14:50 +0100
+Subject: [PATCH 177/203] BCM270X_DT: Add SDIO overlay
+
+Enable SDIO from MMC interface via GPIOs 22-27. Includes the sdhost
+overlay to free up the MMC interface.
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 15 +++++++++++++++
+ arch/arm/boot/dts/overlays/sdio-overlay.dts | 29 +++++++++++++++++++++++++++++
+ 3 files changed, 45 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/sdio-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -44,6 +44,7 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-ft5406-ove
+ 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) += spi-bcm2708-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -513,6 +513,21 @@ Params: overclock_50 Clock (
+ debug Enable debug output (default off)
+
+
++Name: sdio
++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock,
++ and enables SDIO via GPIOs 22-27.
++Load: dtoverlay=sdio,<param>=<val>
++Params: overclock_50 Clock (in MHz) to use when the MMC framework
++ requests 50MHz
++
++ force_pio Disable DMA support (default off)
++
++ pio_limit Number of blocks above which to use DMA
++ (default 1)
++
++ debug Enable debug output (default off)
++
++
+ Name: spi-bcm2708
+ Info: Selects the bcm2708-spi SPI driver
+ Load: dtoverlay=spi-bcm2708
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts
+@@ -0,0 +1,29 @@
++/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */
++
++/include/ "sdhost-overlay.dts"
++
++/{
++ compatible = "brcm,bcm2708";
++
++ fragment@3 {
++ target = <&mmc>;
++ __overlay__ {
++ compatible = "brcm,bcm2835-mmc";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio_pins>;
++ non-removable;
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&gpio>;
++ __overlay__ {
++ sdio_pins: sdio_pins {
++ brcm,pins = <22 23 24 25 26 27>;
++ brcm,function = <7 7 7 7 7 7>; /* ALT3 = SD1 */
++ brcm,pull = <0 2 2 2 2 2>;
++ };
++ };
++ };
++};
--- /dev/null
+From 502a751c5b49d0730f25280345d145e26f0b671d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 11 Sep 2015 09:14:01 +0100
+Subject: [PATCH 178/203] BCM270X_DT: Use fixed-factor-clock for uart1
+
+The BCM2835 mini-UART is almost 8250-compatible, but there is
+a factor-of-two difference in the clock divider for the baud rate.
+The standard 8250 driver can be used unmodified provided we lie to it
+about the clock frequency, pretending it is double the actual value.
+The mini-UART block shares the core clock, and the current firmware
+uses a DT-parameter to update the clock-frequency property. Although it
+works, this isn't ideal because it exposes the firmware to a driver
+problem.
+
+This patch uses the fixed-factor-clock module to create a clock that is
+always twice the frequency of the core clock. (N.B. These "fixed" clocks
+just describe an existing clock, rather than changing any hardware
+settings.)
+---
+ 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/bcm2708_common.dtsi | 10 +++++++++-
+ arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 -
+ 5 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+@@ -103,7 +103,6 @@
+ __overrides__ {
+ uart0 = <&uart0>,"status";
+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0";
+- uart1_clkrate = <&uart1>,"clock-frequency:0";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
+@@ -97,7 +97,6 @@
+ __overrides__ {
+ uart0 = <&uart0>,"status";
+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0";
+- uart1_clkrate = <&uart1>,"clock-frequency:0";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+--- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts
+@@ -79,7 +79,6 @@
+ __overrides__ {
+ uart0 = <&uart0>,"status";
+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0";
+- uart1_clkrate = <&uart1>,"clock-frequency:0";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
+--- a/arch/arm/boot/dts/bcm2708_common.dtsi
++++ b/arch/arm/boot/dts/bcm2708_common.dtsi
+@@ -165,7 +165,7 @@
+ compatible = "brcm,bcm2835-aux-uart", "ns16550";
+ reg = <0x7e215040 0x40>;
+ interrupts = <1 29>;
+- clock-frequency = <500000000>;
++ clocks = <&clk_uart1>;
+ reg-shift = <2>;
+ no-loopback-test;
+ status = "disabled";
+@@ -294,6 +294,14 @@
+ clock-output-names = "pwm";
+ clock-frequency = <100000000>;
+ };
++
++ clk_uart1: clock@6 {
++ compatible = "fixed-factor-clock";
++ clocks = <&clk_core>;
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <2>;
++ };
+ };
+
+ __overrides__ {
+--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
+@@ -103,7 +103,6 @@
+ __overrides__ {
+ uart0 = <&uart0>,"status";
+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0";
+- uart1_clkrate = <&uart1>,"clock-frequency:0";
+ i2s = <&i2s>,"status";
+ spi = <&spi0>,"status";
+ i2c0 = <&i2c0>,"status";
--- /dev/null
+From 1e348feeabfbf0b2628162c2b67a89eeebf8ff7d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 11 Sep 2015 12:10:15 +0100
+Subject: [PATCH 179/203] bcm2835-mmc: Don't overwrite MMC capabilities from DT
+
+---
+ drivers/mmc/host/bcm2835-mmc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/bcm2835-mmc.c
++++ b/drivers/mmc/host/bcm2835-mmc.c
+@@ -1327,8 +1327,9 @@ static int bcm2835_mmc_add_host(struct b
+ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk;
+ #endif
+ /* host controller capabilities */
+- mmc->caps = MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ |
+- MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA;
++ mmc->caps |= MMC_CAP_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL |
++ MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED |
++ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_4_BIT_DATA;
+
+ host->flags = SDHCI_AUTO_CMD23;
+
--- /dev/null
+From 3f2b85d10c701c544516d6a68d36d52dbf967a08 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
+Date: Sun, 13 Sep 2015 15:54:28 +0200
+Subject: [PATCH 180/203] Revert "BCM270X_DT: mz61581: Revert to spi-bcm2708"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit 1820cd05d93b2d465d1616202772efe5bf0d11fe.
+
+The spi-bcm2835 driver has been fixed, so now we can use it again.
+
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+---
+ arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts
+@@ -12,8 +12,6 @@
+ fragment@0 {
+ target = <&spi0>;
+ __overlay__ {
+- /* does not work with spi-bcm2835 using software chip selects */
+- compatible = "brcm,bcm2708-spi";
+ status = "okay";
+
+ spidev@0{
--- /dev/null
+From d9273547c2d4f0d79a3d22324dfc0e125754e6e0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
+Date: Sun, 13 Sep 2015 17:17:14 +0200
+Subject: [PATCH 181/203] BCM270X_DT: mz61581: Set txbuflen to 32k
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Because of the spi dma mapping/engine overhead with spi-bcm2835,
+txbuflen has to be increased from 4096 to 32768 to maximize
+throughput (11MB/s at 128MHz).
+
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+---
+ arch/arm/boot/dts/overlays/README | 2 ++
+ arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -368,6 +368,8 @@ Params: speed Display
+
+ fps Delay between frame updates
+
++ txbuflen Transmit buffer length (default 32768)
++
+ debug Debug output level {0-7}
+
+ xohms Touchpanel sensitivity (X-plate resistance)
+--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts
+@@ -57,6 +57,7 @@
+ bgr;
+ fps = <30>;
+ buswidth = <8>;
++ txbuflen = <32768>;
+
+ reset-gpios = <&gpio 15 0>;
+ dc-gpios = <&gpio 25 0>;
+@@ -103,6 +104,7 @@
+ speed = <&mz61581>, "spi-max-frequency:0";
+ rotate = <&mz61581>, "rotate:0";
+ fps = <&mz61581>, "fps:0";
++ txbuflen = <&mz61581>, "txbuflen:0";
+ debug = <&mz61581>, "debug:0";
+ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0";
+ };
--- /dev/null
+From 6460bf849143979acff90f3664f78bf3907aad0f Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Thu, 10 Sep 2015 09:32:14 +0000
+Subject: [PATCH 182/203] backport: spi: bcm2835: BUG: fix wrong use of
+ PAGE_MASK
+
+There is a bug in the alignment checking of transfers,
+that results in DMA not being used for un-aligned
+transfers that do not cross page-boundries, which is valid.
+
+This is due to a missconception of the meaning PAGE_MASK
+when implementing that check originally - (PAGE_SIZE - 1)
+should have been used instead.
+
+Also fixes a copy/paste error.
+
+Reported-by: <robert@axium.co.nz>
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+---
+ drivers/spi/spi-bcm2835.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct s
+ /* otherwise we only allow transfers within the same page
+ * to avoid wasting time on dma_mapping when it is not practical
+ */
+- if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) {
++ if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
+ dev_warn_once(&spi->dev,
+ "Unaligned spi tx-transfer bridging page\n");
+ return false;
+ }
+- if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) {
++ if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) {
+ dev_warn_once(&spi->dev,
+- "Unaligned spi tx-transfer bridging page\n");
++ "Unaligned spi rx-transfer bridging page\n");
+ return false;
+ }
+
--- /dev/null
+From a025837fe723648981d68e23e53d3c4d7f270c21 Mon Sep 17 00:00:00 2001
+From: David Lechner <david@lechnology.com>
+Date: Mon, 14 Sep 2015 19:08:36 -0500
+Subject: [PATCH 183/203] Use dts-dirs feature for overlays.
+
+The kernel makefiles have a dts-dirs target that is for vendor subdirectories.
+
+Using this fixes the install_dtbs target, which previously did not install the overlays.
+---
+ arch/arm/boot/dts/Makefile | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -15,6 +15,9 @@ endif
+ ifeq ($(CONFIG_ARCH_BCM2835),y)
+ RPI_DT_OVERLAYS=y
+ endif
++ifeq ($(RPI_DT_OVERLAYS),y)
++ dts-dirs += overlays
++endif
+
+ dtb-$(CONFIG_ARCH_ALPINE) += \
+ alpine-db.dtb
+@@ -683,11 +686,10 @@ targets += $(dtb-y)
+ endif
+
+ always := $(dtb-y)
++subdir-y := $(dts-dirs)
+ clean-files := *.dtb
+
+ # Enable fixups to support overlays on BCM2708 platforms
+ ifeq ($(RPI_DT_OVERLAYS),y)
+ DTC_FLAGS ?= -@
+ endif
+-
+-subdir-y += overlays
--- /dev/null
+From 4d8738a3f5befd5487930f5bbe62eb58cf943823 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 15 Sep 2015 15:16:24 +0100
+Subject: [PATCH 188/203] config: Add CIFS_DFS_UPCALL, CIFS_ACL, CIFS_SMB2,
+ CIFS_FSCACHE
+
+---
+ arch/arm/configs/bcm2709_defconfig | 4 ++++
+ arch/arm/configs/bcmrpi_defconfig | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -1158,6 +1158,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y
+ CONFIG_CIFS_UPCALL=y
+ CONFIG_CIFS_XATTR=y
+ CONFIG_CIFS_POSIX=y
++CONFIG_CIFS_ACL=y
++CONFIG_CIFS_DFS_UPCALL=y
++CONFIG_CIFS_SMB2=y
++CONFIG_CIFS_FSCACHE=y
+ CONFIG_9P_FS=m
+ CONFIG_9P_FS_POSIX_ACL=y
+ CONFIG_NLS_DEFAULT="utf8"
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -1151,6 +1151,10 @@ CONFIG_CIFS_WEAK_PW_HASH=y
+ CONFIG_CIFS_UPCALL=y
+ CONFIG_CIFS_XATTR=y
+ CONFIG_CIFS_POSIX=y
++CONFIG_CIFS_ACL=y
++CONFIG_CIFS_DFS_UPCALL=y
++CONFIG_CIFS_SMB2=y
++CONFIG_CIFS_FSCACHE=y
+ CONFIG_9P_FS=m
+ CONFIG_9P_FS_POSIX_ACL=y
+ CONFIG_NLS_DEFAULT="utf8"
--- /dev/null
+From d0576255447f0e2af80396e105f77e4a6fc981e2 Mon Sep 17 00:00:00 2001
+From: Luke Wren <wren6991@gmail.com>
+Date: Sat, 5 Sep 2015 01:14:45 +0100
+Subject: [PATCH 189/203] Add SMI driver
+
+Signed-off-by: Luke Wren <wren6991@gmail.com>
+---
+ .../bindings/misc/brcm,bcm2835-smi-dev.txt | 17 +
+ .../devicetree/bindings/misc/brcm,bcm2835-smi.txt | 48 +
+ arch/arm/boot/dts/bcm2708_common.dtsi | 11 +
+ arch/arm/boot/dts/overlays/Makefile | 2 +
+ arch/arm/boot/dts/overlays/smi-dev-overlay.dts | 18 +
+ arch/arm/boot/dts/overlays/smi-overlay.dts | 37 +
+ drivers/char/broadcom/Kconfig | 8 +
+ drivers/char/broadcom/Makefile | 2 +-
+ drivers/char/broadcom/bcm2835_smi_dev.c | 402 +++++++++
+ drivers/misc/Kconfig | 8 +
+ drivers/misc/Makefile | 1 +
+ drivers/misc/bcm2835_smi.c | 985 +++++++++++++++++++++
+ include/linux/broadcom/bcm2835_smi.h | 391 ++++++++
+ 13 files changed, 1929 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt
+ create mode 100644 Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt
+ create mode 100644 arch/arm/boot/dts/overlays/smi-dev-overlay.dts
+ create mode 100644 arch/arm/boot/dts/overlays/smi-overlay.dts
+ create mode 100644 drivers/char/broadcom/bcm2835_smi_dev.c
+ create mode 100644 drivers/misc/bcm2835_smi.c
+ create mode 100644 include/linux/broadcom/bcm2835_smi.h
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi-dev.txt
+@@ -0,0 +1,17 @@
++* Broadcom BCM2835 SMI character device driver.
++
++SMI or secondary memory interface is a peripheral specific to certain Broadcom
++SOCs, and is helpful for talking to things like parallel-interface displays
++and NAND flashes (in fact, most things with a parallel register interface).
++
++This driver adds a character device which provides a user-space interface to
++an instance of the SMI driver.
++
++Required properties:
++- compatible: "brcm,bcm2835-smi-dev"
++- smi_handle: a phandle to the smi node.
++
++Optional properties:
++- None.
++
++
+--- /dev/null
++++ b/Documentation/devicetree/bindings/misc/brcm,bcm2835-smi.txt
+@@ -0,0 +1,48 @@
++* Broadcom BCM2835 SMI driver.
++
++SMI or secondary memory interface is a peripheral specific to certain Broadcom
++SOCs, and is helpful for talking to things like parallel-interface displays
++and NAND flashes (in fact, most things with a parallel register interface).
++
++Required properties:
++- compatible: "brcm,bcm2835-smi"
++- reg: Should contain location and length of SMI registers and SMI clkman regs
++- interrupts: *the* SMI interrupt.
++- pinctrl-names: should be "default".
++- pinctrl-0: the phandle of the gpio pin node.
++- brcm,smi-clock-source: the clock source for clkman
++- brcm,smi-clock-divisor: the integer clock divisor for clkman
++- dmas: the dma controller phandle and the DREQ number (4 on a 2835)
++- dma-names: the name used by the driver to request its channel.
++ Should be "rx-tx".
++
++Optional properties:
++- None.
++
++Examples:
++
++8 data pin configuration:
++
++smi: smi@7e600000 {
++ compatible = "brcm,bcm2835-smi";
++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>;
++ interrupts = <2 16>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&smi_pins>;
++ brcm,smi-clock-source = <6>;
++ brcm,smi-clock-divisor = <4>;
++ dmas = <&dma 4>;
++ dma-names = "rx-tx";
++
++ status = "okay";
++};
++
++smi_pins: smi_pins {
++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
++ /* Alt 1: SMI */
++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>;
++ /* /CS, /WE and /OE are pulled high, as they are
++ generally active low signals */
++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0>;
++};
++
+--- a/arch/arm/boot/dts/bcm2708_common.dtsi
++++ b/arch/arm/boot/dts/bcm2708_common.dtsi
+@@ -205,6 +205,17 @@
+ status = "disabled";
+ };
+
++ smi: smi@7e600000 {
++ compatible = "brcm,bcm2835-smi";
++ reg = <0x7e600000 0x44>, <0x7e1010b0 0x8>;
++ interrupts = <2 16>;
++ brcm,smi-clock-source = <6>;
++ brcm,smi-clock-divisor = <4>;
++ dmas = <&dma 4>;
++ dma-names = "rx-tx";
++ status = "disabled";
++ };
++
+ usb: usb@7e980000 {
+ compatible = "brcm,bcm2708-usb";
+ reg = <0x7e980000 0x10000>,
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -13,6 +13,8 @@ ifeq ($(CONFIG_ARCH_BCM2835),y)
+ endif
+
+ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/smi-dev-overlay.dts
+@@ -0,0 +1,18 @@
++// Description: Overlay to enable character device interface for SMI.
++// Author: Luke Wren <luke@raspberrypi.org>
++
++/dts-v1/;
++/plugin/;
++
++/{
++ fragment@0 {
++ target = <&soc>;
++ __overlay__ {
++ smi_dev {
++ compatible = "brcm,bcm2835-smi-dev";
++ smi_handle = <&smi>;
++ status = "okay";
++ };
++ };
++ };
++};
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/smi-overlay.dts
+@@ -0,0 +1,37 @@
++// Description: Overlay to enable the secondary memory interface peripheral
++// Author: Luke Wren
++
++/dts-v1/;
++/plugin/;
++
++/{
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&smi>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&smi_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target = <&gpio>;
++ __overlay__ {
++ smi_pins: smi_pins {
++ /* Don't configure the top two address bits, as
++ these are already used as ID_SD and ID_SC */
++ brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15
++ 16 17 18 19 20 21 22 23 24 25>;
++ /* Alt 0: SMI */
++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
++ 5 5 5 5 5 5 5 5 5>;
++ /* /CS, /WE and /OE are pulled high, as they are
++ generally active low signals */
++ brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0
++ 0 0 0 0 0 0 0>;
++ };
++ };
++ };
++};
+--- a/drivers/char/broadcom/Kconfig
++++ b/drivers/char/broadcom/Kconfig
+@@ -47,3 +47,11 @@ config BCM2835_DEVGPIOMEM
+ on the 2835. Calling mmap(/dev/gpiomem) will map the GPIO
+ register page to the user's pointer.
+
++config BCM2835_SMI_DEV
++ tristate "Character device driver for BCM2835 Secondary Memory Interface"
++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI
++ default m
++ help
++ This driver provides a character device interface (ioctl + read/write) to
++ Broadcom's Secondary Memory interface. The low-level functionality is provided
++ by the SMI driver itself.
+--- a/drivers/char/broadcom/Makefile
++++ b/drivers/char/broadcom/Makefile
+@@ -4,4 +4,4 @@ obj-$(CONFIG_BCM_VCIO) += vcio.o
+ obj-$(CONFIG_BCM_VC_SM) += vc_sm/
+
+ obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o
+-
++obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o
+--- /dev/null
++++ b/drivers/char/broadcom/bcm2835_smi_dev.c
+@@ -0,0 +1,402 @@
++/**
++ * Character device driver for Broadcom Secondary Memory Interface
++ *
++ * Written by Luke Wren <luke@raspberrypi.org>
++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. The names of the above-listed copyright holders may not be used
++ * to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2, as published by the Free
++ * Software Foundation.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/pagemap.h>
++#include <linux/fs.h>
++#include <linux/cdev.h>
++#include <linux/fs.h>
++
++#include <linux/broadcom/bcm2835_smi.h>
++
++#define DEVICE_NAME "bcm2835-smi-dev"
++#define DRIVER_NAME "smi-dev-bcm2835"
++#define DEVICE_MINOR 0
++
++static struct cdev bcm2835_smi_cdev;
++static dev_t bcm2835_smi_devid;
++static struct class *bcm2835_smi_class;
++static struct device *bcm2835_smi_dev;
++
++struct bcm2835_smi_dev_instance {
++ struct device *dev;
++};
++
++static struct bcm2835_smi_instance *smi_inst;
++static struct bcm2835_smi_dev_instance *inst;
++
++static const char *const ioctl_names[] = {
++ "READ_SETTINGS",
++ "WRITE_SETTINGS",
++ "ADDRESS"
++};
++
++/****************************************************************************
++*
++* SMI chardev file ops
++*
++***************************************************************************/
++static long
++bcm2835_smi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ long ret = 0;
++
++ dev_info(inst->dev, "serving ioctl...");
++
++ switch (cmd) {
++ case BCM2835_SMI_IOC_GET_SETTINGS:{
++ struct smi_settings *settings;
++
++ dev_info(inst->dev, "Reading SMI settings to user.");
++ settings = bcm2835_smi_get_settings_from_regs(smi_inst);
++ if (copy_to_user((void *)arg, settings,
++ sizeof(struct smi_settings)))
++ dev_err(inst->dev, "settings copy failed.");
++ break;
++ }
++ case BCM2835_SMI_IOC_WRITE_SETTINGS:{
++ struct smi_settings *settings;
++
++ dev_info(inst->dev, "Setting user's SMI settings.");
++ settings = bcm2835_smi_get_settings_from_regs(smi_inst);
++ if (copy_from_user(settings, (void *)arg,
++ sizeof(struct smi_settings)))
++ dev_err(inst->dev, "settings copy failed.");
++ else
++ bcm2835_smi_set_regs_from_settings(smi_inst);
++ break;
++ }
++ case BCM2835_SMI_IOC_ADDRESS:
++ dev_info(inst->dev, "SMI address set: 0x%02x", (int)arg);
++ bcm2835_smi_set_address(smi_inst, arg);
++ break;
++ default:
++ dev_err(inst->dev, "invalid ioctl cmd: %d", cmd);
++ ret = -ENOTTY;
++ break;
++ }
++
++ return ret;
++}
++
++static int bcm2835_smi_open(struct inode *inode, struct file *file)
++{
++ int dev = iminor(inode);
++
++ dev_dbg(inst->dev, "SMI device opened.");
++
++ if (dev != DEVICE_MINOR) {
++ dev_err(inst->dev,
++ "bcm2835_smi_release: Unknown minor device: %d",
++ dev);
++ return -ENXIO;
++ }
++
++ return 0;
++}
++
++static int bcm2835_smi_release(struct inode *inode, struct file *file)
++{
++ int dev = iminor(inode);
++
++ if (dev != DEVICE_MINOR) {
++ dev_err(inst->dev,
++ "bcm2835_smi_release: Unknown minor device %d", dev);
++ return -ENXIO;
++ }
++
++ return 0;
++}
++
++static ssize_t dma_bounce_user(
++ enum dma_transfer_direction dma_dir,
++ char __user *user_ptr,
++ size_t count,
++ struct bcm2835_smi_bounce_info *bounce)
++{
++ int chunk_size;
++ int chunk_no = 0;
++ int count_left = count;
++
++ while (count_left) {
++ int rv;
++ void *buf;
++
++ /* Wait for current chunk to complete: */
++ if (down_timeout(&bounce->callback_sem,
++ msecs_to_jiffies(1000))) {
++ dev_err(inst->dev, "DMA bounce timed out");
++ count -= (count_left);
++ break;
++ }
++
++ if (bounce->callback_sem.count >= DMA_BOUNCE_BUFFER_COUNT - 1)
++ dev_err(inst->dev, "WARNING: Ring buffer overflow");
++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ?
++ DMA_BOUNCE_BUFFER_SIZE : count_left;
++ buf = bounce->buffer[chunk_no % DMA_BOUNCE_BUFFER_COUNT];
++ if (dma_dir == DMA_DEV_TO_MEM)
++ rv = copy_to_user(user_ptr, buf, chunk_size);
++ else
++ rv = copy_from_user(buf, user_ptr, chunk_size);
++ if (rv)
++ dev_err(inst->dev, "copy_*_user() failed!: %d", rv);
++ user_ptr += chunk_size;
++ count_left -= chunk_size;
++ chunk_no++;
++ }
++ return count;
++}
++
++static ssize_t
++bcm2835_read_file(struct file *f, char __user *user_ptr,
++ size_t count, loff_t *offs)
++{
++ int odd_bytes;
++
++ dev_dbg(inst->dev, "User reading %d bytes from SMI.", count);
++ /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */
++ if (count > DMA_THRESHOLD_BYTES)
++ odd_bytes = count & 0x3;
++ else
++ odd_bytes = count;
++ count -= odd_bytes;
++ if (count) {
++ struct bcm2835_smi_bounce_info *bounce;
++
++ count = bcm2835_smi_user_dma(smi_inst,
++ DMA_DEV_TO_MEM, user_ptr, count,
++ &bounce);
++ if (count)
++ count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr,
++ count, bounce);
++ }
++ if (odd_bytes) {
++ /* Read from FIFO directly if not using DMA */
++ uint8_t buf[DMA_THRESHOLD_BYTES];
++
++ bcm2835_smi_read_buf(smi_inst, buf, odd_bytes);
++ if (copy_to_user(user_ptr, buf, odd_bytes))
++ dev_err(inst->dev, "copy_to_user() failed.");
++ count += odd_bytes;
++
++ }
++ return count;
++}
++
++static ssize_t
++bcm2835_write_file(struct file *f, const char __user *user_ptr,
++ size_t count, loff_t *offs)
++{
++ int odd_bytes;
++
++ dev_dbg(inst->dev, "User writing %d bytes to SMI.", count);
++ if (count > DMA_THRESHOLD_BYTES)
++ odd_bytes = count & 0x3;
++ else
++ odd_bytes = count;
++ count -= odd_bytes;
++ if (count) {
++ struct bcm2835_smi_bounce_info *bounce;
++
++ count = bcm2835_smi_user_dma(smi_inst,
++ DMA_MEM_TO_DEV, (char __user *)user_ptr, count,
++ &bounce);
++ if (count)
++ count = dma_bounce_user(DMA_MEM_TO_DEV,
++ (char __user *)user_ptr,
++ count, bounce);
++ }
++ if (odd_bytes) {
++ uint8_t buf[DMA_THRESHOLD_BYTES];
++
++ if (copy_from_user(buf, user_ptr, odd_bytes))
++ dev_err(inst->dev, "copy_from_user() failed.");
++ else
++ bcm2835_smi_write_buf(smi_inst, buf, odd_bytes);
++ count += odd_bytes;
++ }
++ return count;
++}
++
++static const struct file_operations
++bcm2835_smi_fops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = bcm2835_smi_ioctl,
++ .open = bcm2835_smi_open,
++ .release = bcm2835_smi_release,
++ .read = bcm2835_read_file,
++ .write = bcm2835_write_file,
++};
++
++
++/****************************************************************************
++*
++* bcm2835_smi_probe - called when the driver is loaded.
++*
++***************************************************************************/
++
++static int bcm2835_smi_dev_probe(struct platform_device *pdev)
++{
++ int err;
++ void *ptr_err;
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node, *smi_node;
++
++ if (!node) {
++ dev_err(dev, "No device tree node supplied!");
++ return -EINVAL;
++ }
++
++ smi_node = of_parse_phandle(node, "smi_handle", 0);
++
++ if (!smi_node) {
++ dev_err(dev, "No such property: smi_handle");
++ return -ENXIO;
++ }
++
++ smi_inst = bcm2835_smi_get(smi_node);
++
++ if (!smi_inst)
++ return -EPROBE_DEFER;
++
++ /* Allocate buffers and instance data */
++
++ inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL);
++
++ if (!inst)
++ return -ENOMEM;
++
++ inst->dev = dev;
++
++ /* Create character device entries */
++
++ err = alloc_chrdev_region(&bcm2835_smi_devid,
++ DEVICE_MINOR, 1, DEVICE_NAME);
++ if (err != 0) {
++ dev_err(inst->dev, "unable to allocate device number");
++ return -ENOMEM;
++ }
++ cdev_init(&bcm2835_smi_cdev, &bcm2835_smi_fops);
++ bcm2835_smi_cdev.owner = THIS_MODULE;
++ err = cdev_add(&bcm2835_smi_cdev, bcm2835_smi_devid, 1);
++ if (err != 0) {
++ dev_err(inst->dev, "unable to register device");
++ err = -ENOMEM;
++ goto failed_cdev_add;
++ }
++
++ /* Create sysfs entries */
++
++ bcm2835_smi_class = class_create(THIS_MODULE, DEVICE_NAME);
++ ptr_err = bcm2835_smi_class;
++ if (IS_ERR(ptr_err))
++ goto failed_class_create;
++
++ bcm2835_smi_dev = device_create(bcm2835_smi_class, NULL,
++ bcm2835_smi_devid, NULL,
++ "smi");
++ ptr_err = bcm2835_smi_dev;
++ if (IS_ERR(ptr_err))
++ goto failed_device_create;
++
++ dev_info(inst->dev, "initialised");
++
++ return 0;
++
++failed_device_create:
++ class_destroy(bcm2835_smi_class);
++failed_class_create:
++ cdev_del(&bcm2835_smi_cdev);
++ err = PTR_ERR(ptr_err);
++failed_cdev_add:
++ unregister_chrdev_region(bcm2835_smi_devid, 1);
++ dev_err(dev, "could not load bcm2835_smi_dev");
++ return err;
++}
++
++/****************************************************************************
++*
++* bcm2835_smi_remove - called when the driver is unloaded.
++*
++***************************************************************************/
++
++static int bcm2835_smi_dev_remove(struct platform_device *pdev)
++{
++ device_destroy(bcm2835_smi_class, bcm2835_smi_devid);
++ class_destroy(bcm2835_smi_class);
++ cdev_del(&bcm2835_smi_cdev);
++ unregister_chrdev_region(bcm2835_smi_devid, 1);
++
++ dev_info(inst->dev, "SMI character dev removed - OK");
++ return 0;
++}
++
++/****************************************************************************
++*
++* Register the driver with device tree
++*
++***************************************************************************/
++
++static const struct of_device_id bcm2835_smi_dev_of_match[] = {
++ {.compatible = "brcm,bcm2835-smi-dev",},
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, bcm2835_smi_dev_of_match);
++
++static struct platform_driver bcm2835_smi_dev_driver = {
++ .probe = bcm2835_smi_dev_probe,
++ .remove = bcm2835_smi_dev_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = bcm2835_smi_dev_of_match,
++ },
++};
++
++module_platform_driver(bcm2835_smi_dev_driver);
++
++MODULE_ALIAS("platform:smi-dev-bcm2835");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION(
++ "Character device driver for BCM2835's secondary memory interface");
++MODULE_AUTHOR("Luke Wren <luke@raspberrypi.org>");
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -10,6 +10,14 @@ config SENSORS_LIS3LV02D
+ select INPUT_POLLDEV
+ default n
+
++config BCM2835_SMI
++ tristate "Broadcom 283x Secondary Memory Interface driver"
++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
++ default m
++ help
++ Driver for enabling and using Broadcom's Secondary/Slow Memory Interface.
++ Appears as /dev/bcm2835_smi. For ioctl interface see drivers/misc/bcm2835_smi.h
++
+ config AD525X_DPOT
+ tristate "Analog Devices Digital Potentiometers"
+ depends on (I2C || SPI) && SYSFS
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_
+ obj-$(CONFIG_INTEL_MID_PTI) += pti.o
+ obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
+ obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
++obj-$(CONFIG_BCM2835_SMI) += bcm2835_smi.o
+ obj-$(CONFIG_BMP085) += bmp085.o
+ obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o
+ obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o
+--- /dev/null
++++ b/drivers/misc/bcm2835_smi.c
+@@ -0,0 +1,985 @@
++/**
++ * Broadcom Secondary Memory Interface driver
++ *
++ * Written by Luke Wren <luke@raspberrypi.org>
++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. The names of the above-listed copyright holders may not be used
++ * to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2, as published by the Free
++ * Software Foundation.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/of_address.h>
++#include <linux/of_platform.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmaengine.h>
++#include <linux/semaphore.h>
++#include <linux/spinlock.h>
++#include <linux/io.h>
++
++#define BCM2835_SMI_IMPLEMENTATION
++#include <linux/broadcom/bcm2835_smi.h>
++
++#define DRIVER_NAME "smi-bcm2835"
++
++#define N_PAGES_FROM_BYTES(n) ((n + PAGE_SIZE-1) / PAGE_SIZE)
++
++#define DMA_WRITE_TO_MEM true
++#define DMA_READ_FROM_MEM false
++
++struct bcm2835_smi_instance {
++ struct device *dev;
++ struct smi_settings settings;
++ __iomem void *smi_regs_ptr, *cm_smi_regs_ptr;
++ dma_addr_t smi_regs_busaddr;
++
++ struct dma_chan *dma_chan;
++ struct dma_slave_config dma_config;
++
++ struct bcm2835_smi_bounce_info bounce;
++
++ struct scatterlist buffer_sgl;
++
++ int clock_source;
++ int clock_divisor;
++
++ /* Sometimes we are called into in an atomic context (e.g. by
++ JFFS2 + MTD) so we can't use a mutex */
++ spinlock_t transaction_lock;
++};
++
++/****************************************************************************
++*
++* SMI clock manager setup
++*
++***************************************************************************/
++
++static inline void write_smi_cm_reg(struct bcm2835_smi_instance *inst,
++ u32 val, unsigned reg)
++{
++ writel(CM_PWD | val, inst->cm_smi_regs_ptr + reg);
++}
++
++static inline u32 read_smi_cm_reg(struct bcm2835_smi_instance *inst,
++ unsigned reg)
++{
++ return readl(inst->cm_smi_regs_ptr + reg);
++}
++
++static void smi_setup_clock(struct bcm2835_smi_instance *inst)
++{
++ dev_dbg(inst->dev, "Setting up clock...");
++ /* Disable SMI clock and wait for it to stop. */
++ write_smi_cm_reg(inst, 0, CM_SMI_CTL);
++ while (read_smi_cm_reg(inst, CM_SMI_CTL) & CM_SMI_CTL_BUSY)
++ ;
++
++ write_smi_cm_reg(inst, (inst->clock_divisor << CM_SMI_DIV_DIVI_OFFS),
++ CM_SMI_DIV);
++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS),
++ CM_SMI_CTL);
++
++ /* Enable the clock */
++ write_smi_cm_reg(inst, (inst->clock_source << CM_SMI_CTL_SRC_OFFS) |
++ CM_SMI_CTL_ENAB, CM_SMI_CTL);
++}
++
++/****************************************************************************
++*
++* SMI peripheral setup
++*
++***************************************************************************/
++
++static inline void write_smi_reg(struct bcm2835_smi_instance *inst,
++ u32 val, unsigned reg)
++{
++ writel(val, inst->smi_regs_ptr + reg);
++}
++
++static inline u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg)
++{
++ return readl(inst->smi_regs_ptr + reg);
++}
++
++/* Token-paste macro for e.g SMIDSR_RSTROBE -> value of SMIDSR_RSTROBE_MASK */
++#define _CONCAT(x, y) x##y
++#define CONCAT(x, y) _CONCAT(x, y)
++
++#define SET_BIT_FIELD(dest, field, bits) ((dest) = \
++ ((dest) & ~CONCAT(field, _MASK)) | (((bits) << CONCAT(field, _OFFS))& \
++ CONCAT(field, _MASK)))
++#define GET_BIT_FIELD(src, field) (((src) & \
++ CONCAT(field, _MASK)) >> CONCAT(field, _OFFS))
++
++static void smi_dump_context_labelled(struct bcm2835_smi_instance *inst,
++ const char *label)
++{
++ dev_err(inst->dev, "SMI context dump: %s", label);
++ dev_err(inst->dev, "SMICS: 0x%08x", read_smi_reg(inst, SMICS));
++ dev_err(inst->dev, "SMIL: 0x%08x", read_smi_reg(inst, SMIL));
++ dev_err(inst->dev, "SMIDSR: 0x%08x", read_smi_reg(inst, SMIDSR0));
++ dev_err(inst->dev, "SMIDSW: 0x%08x", read_smi_reg(inst, SMIDSW0));
++ dev_err(inst->dev, "SMIDC: 0x%08x", read_smi_reg(inst, SMIDC));
++ dev_err(inst->dev, "SMIFD: 0x%08x", read_smi_reg(inst, SMIFD));
++ dev_err(inst->dev, " ");
++}
++
++static inline void smi_dump_context(struct bcm2835_smi_instance *inst)
++{
++ smi_dump_context_labelled(inst, "");
++}
++
++static void smi_get_default_settings(struct bcm2835_smi_instance *inst)
++{
++ struct smi_settings *settings = &inst->settings;
++
++ settings->data_width = SMI_WIDTH_16BIT;
++ settings->pack_data = true;
++
++ settings->read_setup_time = 1;
++ settings->read_hold_time = 1;
++ settings->read_pace_time = 1;
++ settings->read_strobe_time = 3;
++
++ settings->write_setup_time = settings->read_setup_time;
++ settings->write_hold_time = settings->read_hold_time;
++ settings->write_pace_time = settings->read_pace_time;
++ settings->write_strobe_time = settings->read_strobe_time;
++
++ settings->dma_enable = true;
++ settings->dma_passthrough_enable = false;
++ settings->dma_read_thresh = 0x01;
++ settings->dma_write_thresh = 0x3f;
++ settings->dma_panic_read_thresh = 0x20;
++ settings->dma_panic_write_thresh = 0x20;
++}
++
++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *inst)
++{
++ struct smi_settings *settings = &inst->settings;
++ int smidsr_temp = 0, smidsw_temp = 0, smics_temp,
++ smidcs_temp, smidc_temp = 0;
++
++ spin_lock(&inst->transaction_lock);
++
++ /* temporarily disable the peripheral: */
++ smics_temp = read_smi_reg(inst, SMICS);
++ write_smi_reg(inst, 0, SMICS);
++ smidcs_temp = read_smi_reg(inst, SMIDCS);
++ write_smi_reg(inst, 0, SMIDCS);
++
++ if (settings->pack_data)
++ smics_temp |= SMICS_PXLDAT;
++ else
++ smics_temp &= ~SMICS_PXLDAT;
++
++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RWIDTH, settings->data_width);
++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSETUP, settings->read_setup_time);
++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RHOLD, settings->read_hold_time);
++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RPACE, settings->read_pace_time);
++ SET_BIT_FIELD(smidsr_temp, SMIDSR_RSTROBE, settings->read_strobe_time);
++ write_smi_reg(inst, smidsr_temp, SMIDSR0);
++
++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WWIDTH, settings->data_width);
++ if (settings->data_width == SMI_WIDTH_8BIT)
++ smidsw_temp |= SMIDSW_WSWAP;
++ else
++ smidsw_temp &= ~SMIDSW_WSWAP;
++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSETUP, settings->write_setup_time);
++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WHOLD, settings->write_hold_time);
++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WPACE, settings->write_pace_time);
++ SET_BIT_FIELD(smidsw_temp, SMIDSW_WSTROBE,
++ settings->write_strobe_time);
++ write_smi_reg(inst, smidsw_temp, SMIDSW0);
++
++ SET_BIT_FIELD(smidc_temp, SMIDC_REQR, settings->dma_read_thresh);
++ SET_BIT_FIELD(smidc_temp, SMIDC_REQW, settings->dma_write_thresh);
++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICR,
++ settings->dma_panic_read_thresh);
++ SET_BIT_FIELD(smidc_temp, SMIDC_PANICW,
++ settings->dma_panic_write_thresh);
++ if (settings->dma_passthrough_enable) {
++ smidc_temp |= SMIDC_DMAP;
++ smidsr_temp |= SMIDSR_RDREQ;
++ write_smi_reg(inst, smidsr_temp, SMIDSR0);
++ smidsw_temp |= SMIDSW_WDREQ;
++ write_smi_reg(inst, smidsw_temp, SMIDSW0);
++ } else
++ smidc_temp &= ~SMIDC_DMAP;
++ if (settings->dma_enable)
++ smidc_temp |= SMIDC_DMAEN;
++ else
++ smidc_temp &= ~SMIDC_DMAEN;
++
++ write_smi_reg(inst, smidc_temp, SMIDC);
++
++ /* re-enable (if was previously enabled) */
++ write_smi_reg(inst, smics_temp, SMICS);
++ write_smi_reg(inst, smidcs_temp, SMIDCS);
++
++ spin_unlock(&inst->transaction_lock);
++}
++EXPORT_SYMBOL(bcm2835_smi_set_regs_from_settings);
++
++struct smi_settings *bcm2835_smi_get_settings_from_regs
++ (struct bcm2835_smi_instance *inst)
++{
++ struct smi_settings *settings = &inst->settings;
++ int smidsr, smidsw, smidc;
++
++ spin_lock(&inst->transaction_lock);
++
++ smidsr = read_smi_reg(inst, SMIDSR0);
++ smidsw = read_smi_reg(inst, SMIDSW0);
++ smidc = read_smi_reg(inst, SMIDC);
++
++ settings->pack_data = (read_smi_reg(inst, SMICS) & SMICS_PXLDAT) ?
++ true : false;
++
++ settings->data_width = GET_BIT_FIELD(smidsr, SMIDSR_RWIDTH);
++ settings->read_setup_time = GET_BIT_FIELD(smidsr, SMIDSR_RSETUP);
++ settings->read_hold_time = GET_BIT_FIELD(smidsr, SMIDSR_RHOLD);
++ settings->read_pace_time = GET_BIT_FIELD(smidsr, SMIDSR_RPACE);
++ settings->read_strobe_time = GET_BIT_FIELD(smidsr, SMIDSR_RSTROBE);
++
++ settings->write_setup_time = GET_BIT_FIELD(smidsw, SMIDSW_WSETUP);
++ settings->write_hold_time = GET_BIT_FIELD(smidsw, SMIDSW_WHOLD);
++ settings->write_pace_time = GET_BIT_FIELD(smidsw, SMIDSW_WPACE);
++ settings->write_strobe_time = GET_BIT_FIELD(smidsw, SMIDSW_WSTROBE);
++
++ settings->dma_read_thresh = GET_BIT_FIELD(smidc, SMIDC_REQR);
++ settings->dma_write_thresh = GET_BIT_FIELD(smidc, SMIDC_REQW);
++ settings->dma_panic_read_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICR);
++ settings->dma_panic_write_thresh = GET_BIT_FIELD(smidc, SMIDC_PANICW);
++ settings->dma_passthrough_enable = (smidc & SMIDC_DMAP) ? true : false;
++ settings->dma_enable = (smidc & SMIDC_DMAEN) ? true : false;
++
++ spin_unlock(&inst->transaction_lock);
++
++ return settings;
++}
++EXPORT_SYMBOL(bcm2835_smi_get_settings_from_regs);
++
++static inline void smi_set_address(struct bcm2835_smi_instance *inst,
++ unsigned int address)
++{
++ int smia_temp = 0, smida_temp = 0;
++
++ SET_BIT_FIELD(smia_temp, SMIA_ADDR, address);
++ SET_BIT_FIELD(smida_temp, SMIDA_ADDR, address);
++
++ /* Write to both address registers - user doesn't care whether we're
++ doing programmed or direct transfers. */
++ write_smi_reg(inst, smia_temp, SMIA);
++ write_smi_reg(inst, smida_temp, SMIDA);
++}
++
++static void smi_setup_regs(struct bcm2835_smi_instance *inst)
++{
++
++ dev_dbg(inst->dev, "Initialising SMI registers...");
++ /* Disable the peripheral if already enabled */
++ write_smi_reg(inst, 0, SMICS);
++ write_smi_reg(inst, 0, SMIDCS);
++
++ smi_get_default_settings(inst);
++ bcm2835_smi_set_regs_from_settings(inst);
++ smi_set_address(inst, 0);
++
++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ENABLE, SMICS);
++ write_smi_reg(inst, read_smi_reg(inst, SMIDCS) | SMIDCS_ENABLE,
++ SMIDCS);
++}
++
++/****************************************************************************
++*
++* Low-level SMI access functions
++* Other modules should use the exported higher-level functions e.g.
++* bcm2835_smi_write_buf() unless they have a good reason to use these
++*
++***************************************************************************/
++
++static inline uint32_t smi_read_single_word(struct bcm2835_smi_instance *inst)
++{
++ int timeout = 0;
++
++ write_smi_reg(inst, SMIDCS_ENABLE, SMIDCS);
++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_START, SMIDCS);
++ /* Make sure things happen in the right order...*/
++ mb();
++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) &&
++ ++timeout < 10000)
++ ;
++ if (timeout < 10000)
++ return read_smi_reg(inst, SMIDD);
++
++ dev_err(inst->dev,
++ "SMI direct read timed out (is the clock set up correctly?)");
++ return 0;
++}
++
++static inline void smi_write_single_word(struct bcm2835_smi_instance *inst,
++ uint32_t data)
++{
++ int timeout = 0;
++
++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE, SMIDCS);
++ write_smi_reg(inst, data, SMIDD);
++ write_smi_reg(inst, SMIDCS_ENABLE | SMIDCS_WRITE | SMIDCS_START,
++ SMIDCS);
++
++ while (!(read_smi_reg(inst, SMIDCS) & SMIDCS_DONE) &&
++ ++timeout < 10000)
++ ;
++ if (timeout >= 10000)
++ dev_err(inst->dev,
++ "SMI direct write timed out (is the clock set up correctly?)");
++}
++
++/* Initiates a programmed read into the read FIFO. It is up to the caller to
++ * read data from the FIFO - either via paced DMA transfer,
++ * or polling SMICS_RXD to check whether data is available.
++ * SMICS_ACTIVE will go low upon completion. */
++static void smi_init_programmed_read(struct bcm2835_smi_instance *inst,
++ int num_transfers)
++{
++ int smics_temp;
++
++ /* Disable the peripheral: */
++ smics_temp = read_smi_reg(inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE);
++ write_smi_reg(inst, smics_temp, SMICS);
++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE)
++ ;
++
++ /* Program the transfer count: */
++ write_smi_reg(inst, num_transfers, SMIL);
++
++ /* re-enable and start: */
++ smics_temp |= SMICS_ENABLE;
++ write_smi_reg(inst, smics_temp, SMICS);
++ smics_temp |= SMICS_CLEAR;
++ /* Just to be certain: */
++ mb();
++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE)
++ ;
++ write_smi_reg(inst, smics_temp, SMICS);
++ smics_temp |= SMICS_START;
++ write_smi_reg(inst, smics_temp, SMICS);
++}
++
++/* Initiates a programmed write sequence, using data from the write FIFO.
++ * It is up to the caller to initiate a DMA transfer before calling,
++ * or use another method to keep the write FIFO topped up.
++ * SMICS_ACTIVE will go low upon completion.
++ */
++static void smi_init_programmed_write(struct bcm2835_smi_instance *inst,
++ int num_transfers)
++{
++ int smics_temp;
++
++ /* Disable the peripheral: */
++ smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE;
++ write_smi_reg(inst, smics_temp, SMICS);
++ while (read_smi_reg(inst, SMICS) & SMICS_ENABLE)
++ ;
++
++ /* Program the transfer count: */
++ write_smi_reg(inst, num_transfers, SMIL);
++
++ /* setup, re-enable and start: */
++ smics_temp |= SMICS_WRITE | SMICS_ENABLE;
++ write_smi_reg(inst, smics_temp, SMICS);
++ smics_temp |= SMICS_START;
++ write_smi_reg(inst, smics_temp, SMICS);
++}
++
++/* Initiate a read and then poll FIFO for data, reading out as it appears. */
++static void smi_read_fifo(struct bcm2835_smi_instance *inst,
++ uint32_t *dest, int n_bytes)
++{
++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) {
++ smi_dump_context_labelled(inst,
++ "WARNING: read FIFO not empty at start of read call.");
++ while (read_smi_reg(inst, SMICS))
++ ;
++ }
++
++ /* Dispatch the read: */
++ if (inst->settings.data_width == SMI_WIDTH_8BIT)
++ smi_init_programmed_read(inst, n_bytes);
++ else if (inst->settings.data_width == SMI_WIDTH_16BIT)
++ smi_init_programmed_read(inst, n_bytes / 2);
++ else {
++ dev_err(inst->dev, "Unsupported data width for read.");
++ return;
++ }
++
++ /* Poll FIFO to keep it empty */
++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE))
++ if (read_smi_reg(inst, SMICS) & SMICS_RXD)
++ *dest++ = read_smi_reg(inst, SMID);
++
++ /* Ensure that the FIFO is emptied */
++ if (read_smi_reg(inst, SMICS) & SMICS_RXD) {
++ int fifo_count;
++
++ fifo_count = GET_BIT_FIELD(read_smi_reg(inst, SMIFD),
++ SMIFD_FCNT);
++ while (fifo_count--)
++ *dest++ = read_smi_reg(inst, SMID);
++ }
++
++ if (!(read_smi_reg(inst, SMICS) & SMICS_DONE))
++ smi_dump_context_labelled(inst,
++ "WARNING: transaction finished but done bit not set.");
++
++ if (read_smi_reg(inst, SMICS) & SMICS_RXD)
++ smi_dump_context_labelled(inst,
++ "WARNING: read FIFO not empty at end of read call.");
++
++}
++
++/* Initiate a write, and then keep the FIFO topped up. */
++static void smi_write_fifo(struct bcm2835_smi_instance *inst,
++ uint32_t *src, int n_bytes)
++{
++ int i, timeout = 0;
++
++ /* Empty FIFOs if not already so */
++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE)) {
++ smi_dump_context_labelled(inst,
++ "WARNING: write fifo not empty at start of write call.");
++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_CLEAR,
++ SMICS);
++ }
++
++ /* Initiate the transfer */
++ if (inst->settings.data_width == SMI_WIDTH_8BIT)
++ smi_init_programmed_write(inst, n_bytes);
++ else if (inst->settings.data_width == SMI_WIDTH_16BIT)
++ smi_init_programmed_write(inst, n_bytes / 2);
++ else {
++ dev_err(inst->dev, "Unsupported data width for write.");
++ return;
++ }
++ /* Fill the FIFO: */
++ for (i = 0; i < (n_bytes - 1) / 4 + 1; ++i) {
++ while (!(read_smi_reg(inst, SMICS) & SMICS_TXD))
++ ;
++ write_smi_reg(inst, *src++, SMID);
++ }
++ /* Busy wait... */
++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE) && ++timeout <
++ 1000000)
++ ;
++ if (timeout >= 1000000)
++ smi_dump_context_labelled(inst,
++ "Timed out on write operation!");
++ if (!(read_smi_reg(inst, SMICS) & SMICS_TXE))
++ smi_dump_context_labelled(inst,
++ "WARNING: FIFO not empty at end of write operation.");
++}
++
++/****************************************************************************
++*
++* SMI DMA operations
++*
++***************************************************************************/
++
++/* Disable SMI and put it into the correct direction before doing DMA setup.
++ Stops spurious DREQs during setup. Peripheral is re-enabled by init_*() */
++static void smi_disable(struct bcm2835_smi_instance *inst,
++ enum dma_transfer_direction direction)
++{
++ int smics_temp = read_smi_reg(inst, SMICS) & ~SMICS_ENABLE;
++
++ if (direction == DMA_DEV_TO_MEM)
++ smics_temp &= ~SMICS_WRITE;
++ else
++ smics_temp |= SMICS_WRITE;
++ write_smi_reg(inst, smics_temp, SMICS);
++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE)
++ ;
++}
++
++static struct scatterlist *smi_scatterlist_from_buffer(
++ struct bcm2835_smi_instance *inst,
++ dma_addr_t buf,
++ size_t len,
++ struct scatterlist *sg)
++{
++ sg_init_table(sg, 1);
++ sg_dma_address(sg) = buf;
++ sg_dma_len(sg) = len;
++ return sg;
++}
++
++static void smi_dma_callback_user_copy(void *param)
++{
++ /* Notify the bottom half that a chunk is ready for user copy */
++ struct bcm2835_smi_instance *inst =
++ (struct bcm2835_smi_instance *)param;
++
++ up(&inst->bounce.callback_sem);
++}
++
++/* Creates a descriptor, assigns the given callback, and submits the
++ descriptor to dmaengine. Does not block - can queue up multiple
++ descriptors and then wait for them all to complete.
++ sg_len is the number of control blocks, NOT the number of bytes.
++ dir can be DMA_MEM_TO_DEV or DMA_DEV_TO_MEM.
++ callback can be NULL - in this case it is not called. */
++static inline struct dma_async_tx_descriptor *smi_dma_submit_sgl(
++ struct bcm2835_smi_instance *inst,
++ struct scatterlist *sgl,
++ size_t sg_len,
++ enum dma_transfer_direction dir,
++ dma_async_tx_callback callback)
++{
++ struct dma_async_tx_descriptor *desc;
++
++ desc = dmaengine_prep_slave_sg(inst->dma_chan,
++ sgl,
++ sg_len,
++ dir,
++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK |
++ DMA_PREP_FENCE);
++ if (!desc) {
++ dev_err(inst->dev, "read_sgl: dma slave preparation failed!");
++ write_smi_reg(inst, read_smi_reg(inst, SMICS) & ~SMICS_ACTIVE,
++ SMICS);
++ while (read_smi_reg(inst, SMICS) & SMICS_ACTIVE)
++ cpu_relax();
++ write_smi_reg(inst, read_smi_reg(inst, SMICS) | SMICS_ACTIVE,
++ SMICS);
++ return NULL;
++ }
++ desc->callback = callback;
++ desc->callback_param = inst;
++ if (dmaengine_submit(desc) < 0)
++ return NULL;
++ return desc;
++}
++
++/* NB this function blocks until the transfer is complete */
++static void
++smi_dma_read_sgl(struct bcm2835_smi_instance *inst,
++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes)
++{
++ struct dma_async_tx_descriptor *desc;
++
++ /* Disable SMI and set to read before dispatching DMA - if SMI is in
++ * write mode and TX fifo is empty, it will generate a DREQ which may
++ * cause the read DMA to complete before the SMI read command is even
++ * dispatched! We want to dispatch DMA before SMI read so that reading
++ * is gapless, for logic analyser.
++ */
++
++ smi_disable(inst, DMA_DEV_TO_MEM);
++
++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_DEV_TO_MEM, NULL);
++ dma_async_issue_pending(inst->dma_chan);
++
++ if (inst->settings.data_width == SMI_WIDTH_8BIT)
++ smi_init_programmed_read(inst, n_bytes);
++ else
++ smi_init_programmed_read(inst, n_bytes / 2);
++
++ if (dma_wait_for_async_tx(desc) == DMA_ERROR)
++ smi_dump_context_labelled(inst, "DMA timeout!");
++}
++
++static void
++smi_dma_write_sgl(struct bcm2835_smi_instance *inst,
++ struct scatterlist *sgl, size_t sg_len, size_t n_bytes)
++{
++ struct dma_async_tx_descriptor *desc;
++
++ if (inst->settings.data_width == SMI_WIDTH_8BIT)
++ smi_init_programmed_write(inst, n_bytes);
++ else
++ smi_init_programmed_write(inst, n_bytes / 2);
++
++ desc = smi_dma_submit_sgl(inst, sgl, sg_len, DMA_MEM_TO_DEV, NULL);
++ dma_async_issue_pending(inst->dma_chan);
++
++ if (dma_wait_for_async_tx(desc) == DMA_ERROR)
++ smi_dump_context_labelled(inst, "DMA timeout!");
++ else
++ /* Wait for SMI to finish our writes */
++ while (!(read_smi_reg(inst, SMICS) & SMICS_DONE))
++ cpu_relax();
++}
++
++ssize_t bcm2835_smi_user_dma(
++ struct bcm2835_smi_instance *inst,
++ enum dma_transfer_direction dma_dir,
++ char __user *user_ptr, size_t count,
++ struct bcm2835_smi_bounce_info **bounce)
++{
++ int chunk_no = 0, chunk_size, count_left = count;
++ struct scatterlist *sgl;
++ void (*init_trans_func)(struct bcm2835_smi_instance *, int);
++
++ spin_lock(&inst->transaction_lock);
++
++ if (dma_dir == DMA_DEV_TO_MEM)
++ init_trans_func = smi_init_programmed_read;
++ else
++ init_trans_func = smi_init_programmed_write;
++
++ smi_disable(inst, dma_dir);
++
++ sema_init(&inst->bounce.callback_sem, 0);
++ if (bounce)
++ *bounce = &inst->bounce;
++ while (count_left) {
++ chunk_size = count_left > DMA_BOUNCE_BUFFER_SIZE ?
++ DMA_BOUNCE_BUFFER_SIZE : count_left;
++ if (chunk_size == DMA_BOUNCE_BUFFER_SIZE) {
++ sgl =
++ &inst->bounce.sgl[chunk_no % DMA_BOUNCE_BUFFER_COUNT];
++ } else {
++ sgl = smi_scatterlist_from_buffer(
++ inst,
++ inst->bounce.phys[
++ chunk_no % DMA_BOUNCE_BUFFER_COUNT],
++ chunk_size,
++ &inst->buffer_sgl);
++ }
++
++ if (!smi_dma_submit_sgl(inst, sgl, 1, dma_dir,
++ smi_dma_callback_user_copy
++ )) {
++ dev_err(inst->dev, "sgl submit failed");
++ count = 0;
++ goto out;
++ }
++ count_left -= chunk_size;
++ chunk_no++;
++ }
++ dma_async_issue_pending(inst->dma_chan);
++
++ if (inst->settings.data_width == SMI_WIDTH_8BIT)
++ init_trans_func(inst, count);
++ else if (inst->settings.data_width == SMI_WIDTH_16BIT)
++ init_trans_func(inst, count / 2);
++out:
++ spin_unlock(&inst->transaction_lock);
++ return count;
++}
++EXPORT_SYMBOL(bcm2835_smi_user_dma);
++
++
++/****************************************************************************
++*
++* High level buffer transfer functions - for use by other drivers
++*
++***************************************************************************/
++
++/* Buffer must be physically contiguous - i.e. kmalloc, not vmalloc! */
++void bcm2835_smi_write_buf(
++ struct bcm2835_smi_instance *inst,
++ const void *buf, size_t n_bytes)
++{
++ int odd_bytes = n_bytes & 0x3;
++
++ n_bytes -= odd_bytes;
++
++ spin_lock(&inst->transaction_lock);
++
++ if (n_bytes > DMA_THRESHOLD_BYTES) {
++ dma_addr_t phy_addr = dma_map_single(
++ inst->dev,
++ (void *)buf,
++ n_bytes,
++ DMA_MEM_TO_DEV);
++ struct scatterlist *sgl =
++ smi_scatterlist_from_buffer(inst, phy_addr, n_bytes,
++ &inst->buffer_sgl);
++
++ if (!sgl) {
++ smi_dump_context_labelled(inst,
++ "Error: could not create scatterlist for write!");
++ goto out;
++ }
++ smi_dma_write_sgl(inst, sgl, 1, n_bytes);
++
++ dma_unmap_single
++ (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV);
++ } else if (n_bytes) {
++ smi_write_fifo(inst, (uint32_t *) buf, n_bytes);
++ }
++ buf += n_bytes;
++
++ if (inst->settings.data_width == SMI_WIDTH_8BIT) {
++ while (odd_bytes--)
++ smi_write_single_word(inst, *(uint8_t *) (buf++));
++ } else {
++ while (odd_bytes >= 2) {
++ smi_write_single_word(inst, *(uint16_t *)buf);
++ buf += 2;
++ odd_bytes -= 2;
++ }
++ if (odd_bytes) {
++ /* Reading an odd number of bytes on a 16 bit bus is
++ a user bug. It's kinder to fail early and tell them
++ than to e.g. transparently give them the bottom byte
++ of a 16 bit transfer. */
++ dev_err(inst->dev,
++ "WARNING: odd number of bytes specified for wide transfer.");
++ dev_err(inst->dev,
++ "At least one byte dropped as a result.");
++ dump_stack();
++ }
++ }
++out:
++ spin_unlock(&inst->transaction_lock);
++}
++EXPORT_SYMBOL(bcm2835_smi_write_buf);
++
++void bcm2835_smi_read_buf(struct bcm2835_smi_instance *inst,
++ void *buf, size_t n_bytes)
++{
++
++ /* SMI is inherently 32-bit, which causes surprising amounts of mess
++ for bytes % 4 != 0. Easiest to avoid this mess altogether
++ by handling remainder separately. */
++ int odd_bytes = n_bytes & 0x3;
++
++ spin_lock(&inst->transaction_lock);
++ n_bytes -= odd_bytes;
++ if (n_bytes > DMA_THRESHOLD_BYTES) {
++ dma_addr_t phy_addr = dma_map_single(inst->dev,
++ buf, n_bytes,
++ DMA_DEV_TO_MEM);
++ struct scatterlist *sgl = smi_scatterlist_from_buffer(
++ inst, phy_addr, n_bytes,
++ &inst->buffer_sgl);
++ if (!sgl) {
++ smi_dump_context_labelled(inst,
++ "Error: could not create scatterlist for read!");
++ goto out;
++ }
++ smi_dma_read_sgl(inst, sgl, 1, n_bytes);
++ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM);
++ } else if (n_bytes) {
++ smi_read_fifo(inst, (uint32_t *)buf, n_bytes);
++ }
++ buf += n_bytes;
++
++ if (inst->settings.data_width == SMI_WIDTH_8BIT) {
++ while (odd_bytes--)
++ *((uint8_t *) (buf++)) = smi_read_single_word(inst);
++ } else {
++ while (odd_bytes >= 2) {
++ *(uint16_t *) buf = smi_read_single_word(inst);
++ buf += 2;
++ odd_bytes -= 2;
++ }
++ if (odd_bytes) {
++ dev_err(inst->dev,
++ "WARNING: odd number of bytes specified for wide transfer.");
++ dev_err(inst->dev,
++ "At least one byte dropped as a result.");
++ dump_stack();
++ }
++ }
++out:
++ spin_unlock(&inst->transaction_lock);
++}
++EXPORT_SYMBOL(bcm2835_smi_read_buf);
++
++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst,
++ unsigned int address)
++{
++ spin_lock(&inst->transaction_lock);
++ smi_set_address(inst, address);
++ spin_unlock(&inst->transaction_lock);
++}
++EXPORT_SYMBOL(bcm2835_smi_set_address);
++
++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node)
++{
++ struct platform_device *pdev;
++
++ if (!node)
++ return NULL;
++
++ pdev = of_find_device_by_node(node);
++ if (!pdev)
++ return NULL;
++
++ return platform_get_drvdata(pdev);
++}
++EXPORT_SYMBOL(bcm2835_smi_get);
++
++/****************************************************************************
++*
++* bcm2835_smi_probe - called when the driver is loaded.
++*
++***************************************************************************/
++
++static int bcm2835_smi_dma_setup(struct bcm2835_smi_instance *inst)
++{
++ int i, rv = 0;
++
++ inst->dma_chan = dma_request_slave_channel(inst->dev, "rx-tx");
++
++ inst->dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ inst->dma_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ inst->dma_config.src_addr = inst->smi_regs_busaddr + SMID;
++ inst->dma_config.dst_addr = inst->dma_config.src_addr;
++ /* Direction unimportant - always overridden by prep_slave_sg */
++ inst->dma_config.direction = DMA_DEV_TO_MEM;
++ dmaengine_slave_config(inst->dma_chan, &inst->dma_config);
++ /* Alloc and map bounce buffers */
++ for (i = 0; i < DMA_BOUNCE_BUFFER_COUNT; ++i) {
++ inst->bounce.buffer[i] =
++ dmam_alloc_coherent(inst->dev, DMA_BOUNCE_BUFFER_SIZE,
++ &inst->bounce.phys[i],
++ GFP_KERNEL);
++ if (!inst->bounce.buffer[i]) {
++ dev_err(inst->dev, "Could not allocate buffer!");
++ rv = -ENOMEM;
++ break;
++ }
++ smi_scatterlist_from_buffer(
++ inst,
++ inst->bounce.phys[i],
++ DMA_BOUNCE_BUFFER_SIZE,
++ &inst->bounce.sgl[i]
++ );
++ }
++
++ return rv;
++}
++
++static int bcm2835_smi_probe(struct platform_device *pdev)
++{
++ int err;
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ struct resource *ioresource;
++ struct bcm2835_smi_instance *inst;
++
++ /* Allocate buffers and instance data */
++
++ inst = devm_kzalloc(dev, sizeof(struct bcm2835_smi_instance),
++ GFP_KERNEL);
++
++ if (!inst)
++ return -ENOMEM;
++
++ inst->dev = dev;
++ spin_lock_init(&inst->transaction_lock);
++
++ /* We require device tree support */
++ if (!node)
++ return -EINVAL;
++
++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ inst->smi_regs_ptr = devm_ioremap_resource(dev, ioresource);
++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ inst->cm_smi_regs_ptr = devm_ioremap_resource(dev, ioresource);
++ inst->smi_regs_busaddr = be32_to_cpu(
++ *of_get_address(node, 0, NULL, NULL));
++ of_property_read_u32(node,
++ "brcm,smi-clock-source",
++ &inst->clock_source);
++ of_property_read_u32(node,
++ "brcm,smi-clock-divisor",
++ &inst->clock_divisor);
++
++ err = bcm2835_smi_dma_setup(inst);
++ if (err)
++ return err;
++
++ /* Finally, do peripheral setup */
++
++ smi_setup_clock(inst);
++ smi_setup_regs(inst);
++
++ platform_set_drvdata(pdev, inst);
++
++ dev_info(inst->dev, "initialised");
++
++ return 0;
++}
++
++/****************************************************************************
++*
++* bcm2835_smi_remove - called when the driver is unloaded.
++*
++***************************************************************************/
++
++static int bcm2835_smi_remove(struct platform_device *pdev)
++{
++ struct bcm2835_smi_instance *inst = platform_get_drvdata(pdev);
++ struct device *dev = inst->dev;
++
++ dev_info(dev, "SMI device removed - OK");
++ return 0;
++}
++
++/****************************************************************************
++*
++* Register the driver with device tree
++*
++***************************************************************************/
++
++static const struct of_device_id bcm2835_smi_of_match[] = {
++ {.compatible = "brcm,bcm2835-smi",},
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, bcm2835_smi_of_match);
++
++static struct platform_driver bcm2835_smi_driver = {
++ .probe = bcm2835_smi_probe,
++ .remove = bcm2835_smi_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = bcm2835_smi_of_match,
++ },
++};
++
++module_platform_driver(bcm2835_smi_driver);
++
++MODULE_ALIAS("platform:smi-bcm2835");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Device driver for BCM2835's secondary memory interface");
++MODULE_AUTHOR("Luke Wren <luke@raspberrypi.org>");
+--- /dev/null
++++ b/include/linux/broadcom/bcm2835_smi.h
+@@ -0,0 +1,391 @@
++/**
++ * Declarations and definitions for Broadcom's Secondary Memory Interface
++ *
++ * Written by Luke Wren <luke@raspberrypi.org>
++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. The names of the above-listed copyright holders may not be used
++ * to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2, as published by the Free
++ * Software Foundation.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#ifndef BCM2835_SMI_H
++#define BCM2835_SMI_H
++
++#include <linux/ioctl.h>
++
++#ifndef __KERNEL__
++#include <stdint.h>
++#include <stdbool.h>
++#endif
++
++#define BCM2835_SMI_IOC_MAGIC 0x1
++#define BCM2835_SMI_INVALID_HANDLE (~0)
++
++/* IOCTLs 0x100...0x1ff are not device-specific - we can use them */
++#define BCM2835_SMI_IOC_GET_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 0)
++#define BCM2835_SMI_IOC_WRITE_SETTINGS _IO(BCM2835_SMI_IOC_MAGIC, 1)
++#define BCM2835_SMI_IOC_ADDRESS _IO(BCM2835_SMI_IOC_MAGIC, 2)
++#define BCM2835_SMI_IOC_MAX 2
++
++#define SMI_WIDTH_8BIT 0
++#define SMI_WIDTH_16BIT 1
++#define SMI_WIDTH_9BIT 2
++#define SMI_WIDTH_18BIT 3
++
++/* max number of bytes where DMA will not be used */
++#define DMA_THRESHOLD_BYTES 128
++#define DMA_BOUNCE_BUFFER_SIZE (1024 * 1024 / 2)
++#define DMA_BOUNCE_BUFFER_COUNT 3
++
++
++struct smi_settings {
++ int data_width;
++ /* Whether or not to pack multiple SMI transfers into a
++ single 32 bit FIFO word */
++ bool pack_data;
++
++ /* Timing for reads (writes the same but for WE)
++ *
++ * OE ----------+ +--------------------
++ * | |
++ * +----------+
++ * SD -<==============================>-----------
++ * SA -<=========================================>-
++ * <-setup-> <-strobe -> <-hold -> <- pace ->
++ */
++
++ int read_setup_time;
++ int read_hold_time;
++ int read_pace_time;
++ int read_strobe_time;
++
++ int write_setup_time;
++ int write_hold_time;
++ int write_pace_time;
++ int write_strobe_time;
++
++ bool dma_enable; /* DREQs */
++ bool dma_passthrough_enable; /* External DREQs */
++ int dma_read_thresh;
++ int dma_write_thresh;
++ int dma_panic_read_thresh;
++ int dma_panic_write_thresh;
++};
++
++/****************************************************************************
++*
++* Declare exported SMI functions
++*
++***************************************************************************/
++
++#ifdef __KERNEL__
++
++#include <linux/dmaengine.h> /* for enum dma_transfer_direction */
++#include <linux/of.h>
++#include <linux/semaphore.h>
++
++struct bcm2835_smi_instance;
++
++struct bcm2835_smi_bounce_info {
++ struct semaphore callback_sem;
++ void *buffer[DMA_BOUNCE_BUFFER_COUNT];
++ dma_addr_t phys[DMA_BOUNCE_BUFFER_COUNT];
++ struct scatterlist sgl[DMA_BOUNCE_BUFFER_COUNT];
++};
++
++
++void bcm2835_smi_set_regs_from_settings(struct bcm2835_smi_instance *);
++
++struct smi_settings *bcm2835_smi_get_settings_from_regs(
++ struct bcm2835_smi_instance *inst);
++
++void bcm2835_smi_write_buf(
++ struct bcm2835_smi_instance *inst,
++ const void *buf,
++ size_t n_bytes);
++
++void bcm2835_smi_read_buf(
++ struct bcm2835_smi_instance *inst,
++ void *buf,
++ size_t n_bytes);
++
++void bcm2835_smi_set_address(struct bcm2835_smi_instance *inst,
++ unsigned int address);
++
++ssize_t bcm2835_smi_user_dma(
++ struct bcm2835_smi_instance *inst,
++ enum dma_transfer_direction dma_dir,
++ char __user *user_ptr,
++ size_t count,
++ struct bcm2835_smi_bounce_info **bounce);
++
++struct bcm2835_smi_instance *bcm2835_smi_get(struct device_node *node);
++
++#endif /* __KERNEL__ */
++
++/****************************************************************
++*
++* Implementation-only declarations
++*
++****************************************************************/
++
++#ifdef BCM2835_SMI_IMPLEMENTATION
++
++/* Clock manager registers for SMI clock: */
++#define CM_SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x1010b0)
++/* Clock manager "password" to protect registers from spurious writes */
++#define CM_PWD (0x5a << 24)
++
++#define CM_SMI_CTL 0x00
++#define CM_SMI_DIV 0x04
++
++#define CM_SMI_CTL_FLIP (1 << 8)
++#define CM_SMI_CTL_BUSY (1 << 7)
++#define CM_SMI_CTL_KILL (1 << 5)
++#define CM_SMI_CTL_ENAB (1 << 4)
++#define CM_SMI_CTL_SRC_MASK (0xf)
++#define CM_SMI_CTL_SRC_OFFS (0)
++
++#define CM_SMI_DIV_DIVI_MASK (0xf << 12)
++#define CM_SMI_DIV_DIVI_OFFS (12)
++#define CM_SMI_DIV_DIVF_MASK (0xff << 4)
++#define CM_SMI_DIV_DIVF_OFFS (4)
++
++/* SMI register mapping:*/
++#define SMI_BASE_ADDRESS ((BCM2708_PERI_BASE) + 0x600000)
++
++#define SMICS 0x00 /* control + status register */
++#define SMIL 0x04 /* length/count (n external txfers) */
++#define SMIA 0x08 /* address register */
++#define SMID 0x0c /* data register */
++#define SMIDSR0 0x10 /* device 0 read settings */
++#define SMIDSW0 0x14 /* device 0 write settings */
++#define SMIDSR1 0x18 /* device 1 read settings */
++#define SMIDSW1 0x1c /* device 1 write settings */
++#define SMIDSR2 0x20 /* device 2 read settings */
++#define SMIDSW2 0x24 /* device 2 write settings */
++#define SMIDSR3 0x28 /* device 3 read settings */
++#define SMIDSW3 0x2c /* device 3 write settings */
++#define SMIDC 0x30 /* DMA control registers */
++#define SMIDCS 0x34 /* direct control/status register */
++#define SMIDA 0x38 /* direct address register */
++#define SMIDD 0x3c /* direct data registers */
++#define SMIFD 0x40 /* FIFO debug register */
++
++
++
++/* Control and Status register bits:
++ * SMICS_RXF : RX fifo full: 1 when RX fifo is full
++ * SMICS_TXE : TX fifo empty: 1 when empty.
++ * SMICS_RXD : RX fifo contains data: 1 when there is data.
++ * SMICS_TXD : TX fifo can accept data: 1 when true.
++ * SMICS_RXR : RX fifo needs reading: 1 when fifo more than 3/4 full, or
++ * when "DONE" and fifo not emptied.
++ * SMICS_TXW : TX fifo needs writing: 1 when less than 1/4 full.
++ * SMICS_AFERR : AXI FIFO error: 1 when fifo read when empty or written
++ * when full. Write 1 to clear.
++ * SMICS_EDREQ : 1 when external DREQ received.
++ * SMICS_PXLDAT : Pixel data: write 1 to enable pixel transfer modes.
++ * SMICS_SETERR : 1 if there was an error writing to setup regs (e.g.
++ * tx was in progress). Write 1 to clear.
++ * SMICS_PVMODE : Set to 1 to enable pixel valve mode.
++ * SMICS_INTR : Set to 1 to enable interrupt on RX.
++ * SMICS_INTT : Set to 1 to enable interrupt on TX.
++ * SMICS_INTD : Set to 1 to enable interrupt on DONE condition.
++ * SMICS_TEEN : Tear effect mode enabled: Programmed transfers will wait
++ * for a TE trigger before writing.
++ * SMICS_PAD1 : Padding settings for external transfers. For writes: the
++ * number of bytes initially written to the TX fifo that
++ * SMICS_PAD0 : should be ignored. For reads: the number of bytes that will
++ * be read before the data, and should be dropped.
++ * SMICS_WRITE : Transfer direction: 1 = write to external device, 0 = read
++ * SMICS_CLEAR : Write 1 to clear the FIFOs.
++ * SMICS_START : Write 1 to start the programmed transfer.
++ * SMICS_ACTIVE : Reads as 1 when a programmed transfer is underway.
++ * SMICS_DONE : Reads as 1 when transfer finished. For RX, not set until
++ * FIFO emptied.
++ * SMICS_ENABLE : Set to 1 to enable the SMI peripheral, 0 to disable.
++ */
++
++#define SMICS_RXF (1 << 31)
++#define SMICS_TXE (1 << 30)
++#define SMICS_RXD (1 << 29)
++#define SMICS_TXD (1 << 28)
++#define SMICS_RXR (1 << 27)
++#define SMICS_TXW (1 << 26)
++#define SMICS_AFERR (1 << 25)
++#define SMICS_EDREQ (1 << 15)
++#define SMICS_PXLDAT (1 << 14)
++#define SMICS_SETERR (1 << 13)
++#define SMICS_PVMODE (1 << 12)
++#define SMICS_INTR (1 << 11)
++#define SMICS_INTT (1 << 10)
++#define SMICS_INTD (1 << 9)
++#define SMICS_TEEN (1 << 8)
++#define SMICS_PAD1 (1 << 7)
++#define SMICS_PAD0 (1 << 6)
++#define SMICS_WRITE (1 << 5)
++#define SMICS_CLEAR (1 << 4)
++#define SMICS_START (1 << 3)
++#define SMICS_ACTIVE (1 << 2)
++#define SMICS_DONE (1 << 1)
++#define SMICS_ENABLE (1 << 0)
++
++/* Address register bits: */
++
++#define SMIA_DEVICE_MASK ((1 << 9) | (1 << 8))
++#define SMIA_DEVICE_OFFS (8)
++#define SMIA_ADDR_MASK (0x3f) /* bits 5 -> 0 */
++#define SMIA_ADDR_OFFS (0)
++
++/* DMA control register bits:
++ * SMIDC_DMAEN : DMA enable: set 1: DMA requests will be issued.
++ * SMIDC_DMAP : DMA passthrough: when set to 0, top two data pins are used by
++ * SMI as usual. When set to 1, the top two pins are used for
++ * external DREQs: pin 16 read request, 17 write.
++ * SMIDC_PANIC* : Threshold at which DMA will panic during read/write.
++ * SMIDC_REQ* : Threshold at which DMA will generate a DREQ.
++ */
++
++#define SMIDC_DMAEN (1 << 28)
++#define SMIDC_DMAP (1 << 24)
++#define SMIDC_PANICR_MASK (0x3f << 18)
++#define SMIDC_PANICR_OFFS (18)
++#define SMIDC_PANICW_MASK (0x3f << 12)
++#define SMIDC_PANICW_OFFS (12)
++#define SMIDC_REQR_MASK (0x3f << 6)
++#define SMIDC_REQR_OFFS (6)
++#define SMIDC_REQW_MASK (0x3f)
++#define SMIDC_REQW_OFFS (0)
++
++/* Device settings register bits: same for all 4 (or 3?) device register sets.
++ * Device read settings:
++ * SMIDSR_RWIDTH : Read transfer width. 00 = 8bit, 01 = 16bit,
++ * 10 = 18bit, 11 = 9bit.
++ * SMIDSR_RSETUP : Read setup time: number of core cycles between chip
++ * select/address and read strobe. Min 1, max 64.
++ * SMIDSR_MODE68 : 1 for System 68 mode (i.e. enable + direction pins,
++ * rather than OE + WE pin)
++ * SMIDSR_FSETUP : If set to 1, setup time only applies to first
++ * transfer after address change.
++ * SMIDSR_RHOLD : Number of core cycles between read strobe going
++ * inactive and CS/address going inactive. Min 1, max 64
++ * SMIDSR_RPACEALL : When set to 1, this device's RPACE value will always
++ * be used for the next transaction, even if it is not
++ * to this device.
++ * SMIDSR_RPACE : Number of core cycles spent waiting between CS
++ * deassert and start of next transfer. Min 1, max 128
++ * SMIDSR_RDREQ : 1 = use external DMA request on SD16 to pace reads
++ * from device. Must also set DMAP in SMICS.
++ * SMIDSR_RSTROBE : Number of cycles to assert the read strobe.
++ * min 1, max 128.
++ */
++#define SMIDSR_RWIDTH_MASK ((1<<31)|(1<<30))
++#define SMIDSR_RWIDTH_OFFS (30)
++#define SMIDSR_RSETUP_MASK (0x3f << 24)
++#define SMIDSR_RSETUP_OFFS (24)
++#define SMIDSR_MODE68 (1 << 23)
++#define SMIDSR_FSETUP (1 << 22)
++#define SMIDSR_RHOLD_MASK (0x3f << 16)
++#define SMIDSR_RHOLD_OFFS (16)
++#define SMIDSR_RPACEALL (1 << 15)
++#define SMIDSR_RPACE_MASK (0x7f << 8)
++#define SMIDSR_RPACE_OFFS (8)
++#define SMIDSR_RDREQ (1 << 7)
++#define SMIDSR_RSTROBE_MASK (0x7f)
++#define SMIDSR_RSTROBE_OFFS (0)
++
++/* Device write settings:
++ * SMIDSW_WWIDTH : Write transfer width. 00 = 8bit, 01 = 16bit,
++ * 10= 18bit, 11 = 9bit.
++ * SMIDSW_WSETUP : Number of cycles between CS assert and write strobe.
++ * Min 1, max 64.
++ * SMIDSW_WFORMAT : Pixel format of input. 0 = 16bit RGB 565,
++ * 1 = 32bit RGBA 8888
++ * SMIDSW_WSWAP : 1 = swap pixel data bits. (Use with SMICS_PXLDAT)
++ * SMIDSW_WHOLD : Time between WE deassert and CS deassert. 1 to 64
++ * SMIDSW_WPACEALL : 1: this device's WPACE will be used for the next
++ * transfer, regardless of that transfer's device.
++ * SMIDSW_WPACE : Cycles between CS deassert and next CS assert.
++ * Min 1, max 128
++ * SMIDSW_WDREQ : Use external DREQ on pin 17 to pace writes. DMAP must
++ * be set in SMICS.
++ * SMIDSW_WSTROBE : Number of cycles to assert the write strobe.
++ * Min 1, max 128
++ */
++#define SMIDSW_WWIDTH_MASK ((1<<31)|(1<<30))
++#define SMIDSW_WWIDTH_OFFS (30)
++#define SMIDSW_WSETUP_MASK (0x3f << 24)
++#define SMIDSW_WSETUP_OFFS (24)
++#define SMIDSW_WFORMAT (1 << 23)
++#define SMIDSW_WSWAP (1 << 22)
++#define SMIDSW_WHOLD_MASK (0x3f << 16)
++#define SMIDSW_WHOLD_OFFS (16)
++#define SMIDSW_WPACEALL (1 << 15)
++#define SMIDSW_WPACE_MASK (0x7f << 8)
++#define SMIDSW_WPACE_OFFS (8)
++#define SMIDSW_WDREQ (1 << 7)
++#define SMIDSW_WSTROBE_MASK (0x7f)
++#define SMIDSW_WSTROBE_OFFS (0)
++
++/* Direct transfer control + status register
++ * SMIDCS_WRITE : Direction of transfer: 1 -> write, 0 -> read
++ * SMIDCS_DONE : 1 when a transfer has finished. Write 1 to clear.
++ * SMIDCS_START : Write 1 to start a transfer, if one is not already underway.
++ * SMIDCE_ENABLE: Write 1 to enable SMI in direct mode.
++ */
++
++#define SMIDCS_WRITE (1 << 3)
++#define SMIDCS_DONE (1 << 2)
++#define SMIDCS_START (1 << 1)
++#define SMIDCS_ENABLE (1 << 0)
++
++/* Direct transfer address register
++ * SMIDA_DEVICE : Indicates which of the device settings banks should be used.
++ * SMIDA_ADDR : The value to be asserted on the address pins.
++ */
++
++#define SMIDA_DEVICE_MASK ((1<<9)|(1<<8))
++#define SMIDA_DEVICE_OFFS (8)
++#define SMIDA_ADDR_MASK (0x3f)
++#define SMIDA_ADDR_OFFS (0)
++
++/* FIFO debug register
++ * SMIFD_FLVL : The high-tide mark of FIFO count during the most recent txfer
++ * SMIFD_FCNT : The current FIFO count.
++ */
++#define SMIFD_FLVL_MASK (0x3f << 8)
++#define SMIFD_FLVL_OFFS (8)
++#define SMIFD_FCNT_MASK (0x3f)
++#define SMIFD_FCNT_OFFS (0)
++
++#endif /* BCM2835_SMI_IMPLEMENTATION */
++
++#endif /* BCM2835_SMI_H */
--- /dev/null
+From 3103b6c1b1a881e55421b7463fb76ad7bdf3974a Mon Sep 17 00:00:00 2001
+From: Luke Wren <wren6991@gmail.com>
+Date: Sat, 5 Sep 2015 01:16:10 +0100
+Subject: [PATCH 190/203] Add SMI NAND driver
+
+Signed-off-by: Luke Wren <wren6991@gmail.com>
+---
+ .../bindings/mtd/brcm,bcm2835-smi-nand.txt | 42 ++++
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 69 ++++++
+ arch/arm/configs/bcm2709_defconfig | 7 +
+ arch/arm/configs/bcmrpi_defconfig | 7 +
+ drivers/mtd/nand/Kconfig | 7 +
+ drivers/mtd/nand/Makefile | 1 +
+ drivers/mtd/nand/bcm2835_smi_nand.c | 268 +++++++++++++++++++++
+ 8 files changed, 402 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt
+ create mode 100644 arch/arm/boot/dts/overlays/smi-nand-overlay.dts
+ create mode 100644 drivers/mtd/nand/bcm2835_smi_nand.c
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/brcm,bcm2835-smi-nand.txt
+@@ -0,0 +1,42 @@
++* BCM2835 SMI NAND flash
++
++This driver is a shim between the BCM2835 SMI driver (SMI is a peripheral for
++talking to parallel register interfaces) and Linux's MTD layer.
++
++Required properties:
++- compatible: "brcm,bcm2835-smi-nand"
++- status: "okay"
++
++Optional properties:
++- partition@n, where n is an integer from a consecutive sequence starting at 0
++ - Difficult to store partition table on NAND device - normally put it
++ in the source code, kernel bootparams, or device tree (the best way!)
++ - Sub-properties:
++ - label: the partition name, as shown by mtdinfo /dev/mtd*
++ - reg: the size and offset of this partition.
++ - (optional) read-only: an empty property flagging as read only
++
++Example:
++
++nand: flash@0 {
++ compatible = "brcm,bcm2835-smi-nand";
++ status = "okay";
++
++ partition@0 {
++ label = "stage2";
++ // 128k
++ reg = <0 0x20000>;
++ read-only;
++ };
++ partition@1 {
++ label = "firmware";
++ // 16M
++ reg = <0x20000 0x1000000>;
++ read-only;
++ };
++ partition@2 {
++ label = "root";
++ // 2G
++ reg = <0x1020000 0x80000000>;
++ };
++};
+\ No newline at end of file
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -15,6 +15,7 @@ endif
+ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts
+@@ -0,0 +1,69 @@
++// Description: Overlay to enable NAND flash through
++// the secondary memory interface
++// Author: Luke Wren
++
++/dts-v1/;
++/plugin/;
++
++/{
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&smi>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&smi_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target = <&soc>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ nand: flash@0 {
++ compatible = "brcm,bcm2835-smi-nand";
++ smi_handle = <&smi>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ status = "okay";
++
++ partition@0 {
++ label = "stage2";
++ // 128k
++ reg = <0 0x20000>;
++ read-only;
++ };
++ partition@1 {
++ label = "firmware";
++ // 16M
++ reg = <0x20000 0x1000000>;
++ read-only;
++ };
++ partition@2 {
++ label = "root";
++ // 2G (will need to use 64 bit for >=4G)
++ reg = <0x1020000 0x80000000>;
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&gpio>;
++ __overlay__ {
++ smi_pins: smi_pins {
++ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11
++ 12 13 14 15>;
++ /* Alt 1: SMI */
++ brcm,function = <5 5 5 5 5 5 5 5 5 5 5
++ 5 5 5 5 5>;
++ /* /CS, /WE and /OE are pulled high, as they are
++ generally active low signals */
++ brcm,pull = <2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0>;
++ };
++ };
++ };
++};
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -392,6 +392,10 @@ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
+ CONFIG_DMA_CMA=y
+ CONFIG_CMA_SIZE_MBYTES=5
++CONFIG_MTD=m
++CONFIG_MTD_BLOCK=m
++CONFIG_MTD_NAND=m
++CONFIG_MTD_UBI=m
+ CONFIG_ZRAM=m
+ CONFIG_ZRAM_LZ4_COMPRESS=y
+ CONFIG_BLK_DEV_LOOP=y
+@@ -1140,6 +1144,9 @@ CONFIG_CONFIGFS_FS=y
+ CONFIG_ECRYPT_FS=m
+ CONFIG_HFS_FS=m
+ CONFIG_HFSPLUS_FS=m
++CONFIG_JFFS2_FS=m
++CONFIG_JFFS2_SUMMARY=y
++CONFIG_UBIFS_FS=m
+ CONFIG_SQUASHFS=m
+ CONFIG_SQUASHFS_XATTR=y
+ CONFIG_SQUASHFS_LZO=y
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -385,6 +385,10 @@ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
+ CONFIG_DMA_CMA=y
+ CONFIG_CMA_SIZE_MBYTES=5
++CONFIG_MTD=m
++CONFIG_MTD_BLOCK=m
++CONFIG_MTD_NAND=m
++CONFIG_MTD_UBI=m
+ CONFIG_ZRAM=m
+ CONFIG_ZRAM_LZ4_COMPRESS=y
+ CONFIG_BLK_DEV_LOOP=y
+@@ -1133,6 +1137,9 @@ CONFIG_CONFIGFS_FS=y
+ CONFIG_ECRYPT_FS=m
+ CONFIG_HFS_FS=m
+ CONFIG_HFSPLUS_FS=m
++CONFIG_JFFS2_FS=m
++CONFIG_JFFS2_SUMMARY=y
++CONFIG_UBIFS_FS=m
+ CONFIG_SQUASHFS=m
+ CONFIG_SQUASHFS_XATTR=y
+ CONFIG_SQUASHFS_LZO=y
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -41,6 +41,13 @@ config MTD_SM_COMMON
+ tristate
+ default n
+
++config MTD_NAND_BCM2835_SMI
++ tristate "Use Broadcom's Secondary Memory Interface as a NAND controller (BCM283x)"
++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2835_SMI && MTD_NAND
++ default m
++ help
++ Uses the BCM2835's SMI peripheral as a NAND controller.
++
+ config MTD_NAND_DENALI
+ tristate "Support Denali NAND controller"
+ depends on HAS_DMA
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_DENALI) += denali
+ obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o
+ obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o
+ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
++obj-$(CONFIG_MTD_NAND_BCM2835_SMI) += bcm2835_smi_nand.o
+ obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
+ obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
+ obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
+--- /dev/null
++++ b/drivers/mtd/nand/bcm2835_smi_nand.c
+@@ -0,0 +1,268 @@
++/**
++ * NAND flash driver for Broadcom Secondary Memory Interface
++ *
++ * Written by Luke Wren <luke@raspberrypi.org>
++ * Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. The names of the above-listed copyright holders may not be used
++ * to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2, as published by the Free
++ * Software Foundation.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++#include <linux/broadcom/bcm2835_smi.h>
++
++#define DEVICE_NAME "bcm2835-smi-nand"
++#define DRIVER_NAME "smi-nand-bcm2835"
++
++struct bcm2835_smi_nand_host {
++ struct bcm2835_smi_instance *smi_inst;
++ struct nand_chip nand_chip;
++ struct mtd_info mtd;
++ struct device *dev;
++};
++
++/****************************************************************************
++*
++* NAND functionality implementation
++*
++****************************************************************************/
++
++#define SMI_NAND_CLE_PIN 0x01
++#define SMI_NAND_ALE_PIN 0x02
++
++static inline void bcm2835_smi_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ uint32_t cmd32 = cmd;
++ uint32_t addr = ~(SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN);
++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent);
++ struct bcm2835_smi_instance *inst = host->smi_inst;
++
++ if (ctrl & NAND_CLE)
++ addr |= SMI_NAND_CLE_PIN;
++ if (ctrl & NAND_ALE)
++ addr |= SMI_NAND_ALE_PIN;
++ /* Lower ALL the CS pins! */
++ if (ctrl & NAND_NCE)
++ addr &= (SMI_NAND_CLE_PIN | SMI_NAND_ALE_PIN);
++
++ bcm2835_smi_set_address(inst, addr);
++
++ if (cmd != NAND_CMD_NONE)
++ bcm2835_smi_write_buf(inst, &cmd32, 1);
++}
++
++static inline uint8_t bcm2835_smi_nand_read_byte(struct mtd_info *mtd)
++{
++ uint8_t byte;
++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent);
++ struct bcm2835_smi_instance *inst = host->smi_inst;
++
++ bcm2835_smi_read_buf(inst, &byte, 1);
++ return byte;
++}
++
++static inline void bcm2835_smi_nand_write_byte(struct mtd_info *mtd,
++ uint8_t byte)
++{
++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent);
++ struct bcm2835_smi_instance *inst = host->smi_inst;
++
++ bcm2835_smi_write_buf(inst, &byte, 1);
++}
++
++static inline void bcm2835_smi_nand_write_buf(struct mtd_info *mtd,
++ const uint8_t *buf, int len)
++{
++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent);
++ struct bcm2835_smi_instance *inst = host->smi_inst;
++
++ bcm2835_smi_write_buf(inst, buf, len);
++}
++
++static inline void bcm2835_smi_nand_read_buf(struct mtd_info *mtd,
++ uint8_t *buf, int len)
++{
++ struct bcm2835_smi_nand_host *host = dev_get_drvdata(mtd->dev.parent);
++ struct bcm2835_smi_instance *inst = host->smi_inst;
++
++ bcm2835_smi_read_buf(inst, buf, len);
++}
++
++/****************************************************************************
++*
++* Probe and remove functions
++*
++***************************************************************************/
++
++static int bcm2835_smi_nand_probe(struct platform_device *pdev)
++{
++ struct bcm2835_smi_nand_host *host;
++ struct nand_chip *this;
++ struct mtd_info *mtd;
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node, *smi_node;
++ struct mtd_part_parser_data ppdata;
++ struct smi_settings *smi_settings;
++ struct bcm2835_smi_instance *smi_inst;
++ int ret = -ENXIO;
++
++ if (!node) {
++ dev_err(dev, "No device tree node supplied!");
++ return -EINVAL;
++ }
++
++ smi_node = of_parse_phandle(node, "smi_handle", 0);
++
++ /* Request use of SMI peripheral: */
++ smi_inst = bcm2835_smi_get(smi_node);
++
++ if (!smi_inst) {
++ dev_err(dev, "Could not register with SMI.");
++ return -EPROBE_DEFER;
++ }
++
++ /* Set SMI timing and bus width */
++
++ smi_settings = bcm2835_smi_get_settings_from_regs(smi_inst);
++
++ smi_settings->data_width = SMI_WIDTH_8BIT;
++ smi_settings->read_setup_time = 2;
++ smi_settings->read_hold_time = 1;
++ smi_settings->read_pace_time = 1;
++ smi_settings->read_strobe_time = 3;
++
++ smi_settings->write_setup_time = 2;
++ smi_settings->write_hold_time = 1;
++ smi_settings->write_pace_time = 1;
++ smi_settings->write_strobe_time = 3;
++
++ bcm2835_smi_set_regs_from_settings(smi_inst);
++
++ host = devm_kzalloc(dev, sizeof(struct bcm2835_smi_nand_host),
++ GFP_KERNEL);
++ if (!host)
++ return -ENOMEM;
++
++ host->dev = dev;
++ host->smi_inst = smi_inst;
++
++ platform_set_drvdata(pdev, host);
++
++ /* Link the structures together */
++
++ this = &host->nand_chip;
++ mtd = &host->mtd;
++ mtd->priv = this;
++ mtd->owner = THIS_MODULE;
++ mtd->dev.parent = dev;
++ mtd->name = DRIVER_NAME;
++ ppdata.of_node = node;
++
++ /* 20 us command delay time... */
++ this->chip_delay = 20;
++
++ this->priv = host;
++ this->cmd_ctrl = bcm2835_smi_nand_cmd_ctrl;
++ this->read_byte = bcm2835_smi_nand_read_byte;
++ this->write_byte = bcm2835_smi_nand_write_byte;
++ this->write_buf = bcm2835_smi_nand_write_buf;
++ this->read_buf = bcm2835_smi_nand_read_buf;
++
++ this->ecc.mode = NAND_ECC_SOFT;
++
++ /* Should never be accessed directly: */
++
++ this->IO_ADDR_R = (void *)0xdeadbeef;
++ this->IO_ADDR_W = (void *)0xdeadbeef;
++
++ /* First scan to find the device and get the page size */
++
++ if (nand_scan_ident(mtd, 1, NULL))
++ return -ENXIO;
++
++ /* Second phase scan */
++
++ if (nand_scan_tail(mtd))
++ return -ENXIO;
++
++ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
++ if (!ret)
++ return 0;
++
++ nand_release(mtd);
++ return -EINVAL;
++}
++
++static int bcm2835_smi_nand_remove(struct platform_device *pdev)
++{
++ struct bcm2835_smi_nand_host *host = platform_get_drvdata(pdev);
++
++ nand_release(&host->mtd);
++
++ return 0;
++}
++
++/****************************************************************************
++*
++* Register the driver with device tree
++*
++***************************************************************************/
++
++static const struct of_device_id bcm2835_smi_nand_of_match[] = {
++ {.compatible = "brcm,bcm2835-smi-nand",},
++ { /* sentinel */ }
++};
++
++MODULE_DEVICE_TABLE(of, bcm2835_smi_nand_of_match);
++
++static struct platform_driver bcm2835_smi_nand_driver = {
++ .probe = bcm2835_smi_nand_probe,
++ .remove = bcm2835_smi_nand_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = bcm2835_smi_nand_of_match,
++ },
++};
++
++module_platform_driver(bcm2835_smi_nand_driver);
++
++MODULE_ALIAS("platform:smi-nand-bcm2835");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION
++ ("Driver for NAND chips using Broadcom Secondary Memory Interface");
++MODULE_AUTHOR("Luke Wren <luke@raspberrypi.org>");
--- /dev/null
+From 31c23a1d9ad93cf6795d1fc72f9a254d5bcfc81b Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 16 Sep 2015 17:28:41 +0100
+Subject: [PATCH 191/203] BCM270X_DT: Document SMI overlay
+
+---
+ arch/arm/boot/dts/overlays/Makefile | 6 +++---
+ arch/arm/boot/dts/overlays/README | 18 ++++++++++++++++++
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -13,9 +13,6 @@ ifeq ($(CONFIG_ARCH_BCM2835),y)
+ endif
+
+ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb
+-dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb
+-dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb
+-dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb
+@@ -48,6 +45,9 @@ dtb-$(RPI_DT_OVERLAYS) += rpi-proto-over
+ dtb-$(RPI_DT_OVERLAYS) += rpi-sense-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += sdio-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-dev-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-nand-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += smi-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += spi-dma-overlay.dtb
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -530,6 +530,24 @@ Params: overclock_50 Clock (
+ debug Enable debug output (default off)
+
+
++Name: smi
++Info: Enables the Secondary Memory Interface peripheral. Uses GPIOs 2-25!
++Load: dtoverlay=smi
++Params: <None>
++
++
++Name: smi-dev
++Info: Enables the userspace interface for the SMI driver
++Load: dtoverlay=smi-dev
++Params: <None>
++
++
++Name: smi-nand
++Info: Enables access to NAND flash via the SMI interface
++Load: dtoverlay=smi-nand
++Params: <None>
++
++
+ Name: spi-bcm2708
+ Info: Selects the bcm2708-spi SPI driver
+ Load: dtoverlay=spi-bcm2708
--- /dev/null
+From 140e8eab017a65e70d93dbb651045d0b8a70ff37 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 17 Sep 2015 17:13:42 +0100
+Subject: [PATCH 192/203] dwc_otg: Force host mode to fix incorrect compute
+ module boards
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_cil.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_cil.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
+@@ -192,7 +192,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(cons
+ core_if->hptxfsiz.d32 =
+ DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
+ gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
+- gusbcfg.b.force_host_mode = 0;
++ gusbcfg.b.force_host_mode = 1;
+ DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
+ dwc_mdelay(100);
+ }
--- /dev/null
+From eaa0186f759c047121b38bf43d0ccfeb36fb23da Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 1 Oct 2015 11:49:11 +0100
+Subject: [PATCH 193/203] config: Add CONFIG_UHID
+
+---
+ 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
+@@ -840,6 +840,7 @@ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+ CONFIG_HIDRAW=y
++CONFIG_UHID=m
+ CONFIG_HID_A4TECH=m
+ CONFIG_HID_ACRUX=m
+ CONFIG_HID_APPLE=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -833,6 +833,7 @@ CONFIG_SND_SOC_WM8804_I2C=m
+ CONFIG_SND_SIMPLE_CARD=m
+ CONFIG_SOUND_PRIME=m
+ CONFIG_HIDRAW=y
++CONFIG_UHID=m
+ CONFIG_HID_A4TECH=m
+ CONFIG_HID_ACRUX=m
+ CONFIG_HID_APPLE=m
--- /dev/null
+From d20be432374b0912dfbed90e4235411a44cc8fc0 Mon Sep 17 00:00:00 2001
+From: Stuart MacLean <stuart@hifiberry.com>
+Date: Fri, 2 Oct 2015 15:12:59 +0100
+Subject: [PATCH 194/203] Add support for the HiFiBerry DAC+ Pro.
+
+The HiFiBerry DAC+ and DAC+ Pro products both use the existing bcm sound driver with the DAC+ Pro having a special clock device driver representing the two high precision oscillators.
+
+An addition bug fix is included for the PCM512x codec where by the physical size of the sample frame is used in the calculation of the LRCK divisor as it was found to be wrong when using 24-bit depth sample contained in a little endian 4-byte sample frame.
+---
+ .../dts/overlays/hifiberry-dacplus-overlay.dts | 15 +-
+ drivers/clk/Makefile | 1 +
+ drivers/clk/clk-hifiberry-dacpro.c | 160 ++++++++++++++
+ sound/soc/bcm/hifiberry_dacplus.c | 244 +++++++++++++++++++--
+ sound/soc/codecs/pcm512x.c | 3 +-
+ 5 files changed, 396 insertions(+), 27 deletions(-)
+ create mode 100644 drivers/clk/clk-hifiberry-dacpro.c
+
+--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts
+@@ -6,6 +6,16 @@
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
++ target-path = "/clocks";
++ __overlay__ {
++ dacpro_osc: dacpro_osc {
++ compatible = "hifiberry,dacpro-clk";
++ #clock-cells = <0>;
++ };
++ };
++ };
++
++ fragment@1 {
+ target = <&sound>;
+ __overlay__ {
+ compatible = "hifiberry,hifiberry-dacplus";
+@@ -14,14 +24,14 @@
+ };
+ };
+
+- fragment@1 {
++ fragment@2 {
+ target = <&i2s>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+- fragment@2 {
++ fragment@3 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+@@ -32,6 +42,7 @@
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm5122";
+ reg = <0x4d>;
++ clocks = <&dacpro_osc>;
+ status = "okay";
+ };
+ };
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-
+ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
+ obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
+ obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += clk-hifiberry-dacpro.o
+ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
+ obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
+ obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
+--- /dev/null
++++ b/drivers/clk/clk-hifiberry-dacpro.c
+@@ -0,0 +1,160 @@
++/*
++ * Clock Driver for HiFiBerry DAC Pro
++ *
++ * Author: Stuart MacLean
++ * Copyright 2015
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++
++/* Clock rate of CLK44EN attached to GPIO6 pin */
++#define CLK_44EN_RATE 22579200UL
++/* Clock rate of CLK48EN attached to GPIO3 pin */
++#define CLK_48EN_RATE 24576000UL
++
++/**
++ * struct hifiberry_dacpro_clk - Common struct to the HiFiBerry DAC Pro
++ * @hw: clk_hw for the common clk framework
++ * @mode: 0 => CLK44EN, 1 => CLK48EN
++ */
++struct clk_hifiberry_hw {
++ struct clk_hw hw;
++ uint8_t mode;
++};
++
++#define to_hifiberry_clk(_hw) container_of(_hw, struct clk_hifiberry_hw, hw)
++
++static const struct of_device_id clk_hifiberry_dacpro_dt_ids[] = {
++ { .compatible = "hifiberry,dacpro-clk",},
++ { }
++};
++MODULE_DEVICE_TABLE(of, clk_hifiberry_dacpro_dt_ids);
++
++static unsigned long clk_hifiberry_dacpro_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ return (to_hifiberry_clk(hw)->mode == 0) ? CLK_44EN_RATE :
++ CLK_48EN_RATE;
++}
++
++static long clk_hifiberry_dacpro_round_rate(struct clk_hw *hw,
++ unsigned long rate, unsigned long *parent_rate)
++{
++ long actual_rate;
++
++ if (rate <= CLK_44EN_RATE) {
++ actual_rate = (long)CLK_44EN_RATE;
++ } else if (rate >= CLK_48EN_RATE) {
++ actual_rate = (long)CLK_48EN_RATE;
++ } else {
++ long diff44Rate = (long)(rate - CLK_44EN_RATE);
++ long diff48Rate = (long)(CLK_48EN_RATE - rate);
++
++ if (diff44Rate < diff48Rate)
++ actual_rate = (long)CLK_44EN_RATE;
++ else
++ actual_rate = (long)CLK_48EN_RATE;
++ }
++ return actual_rate;
++}
++
++
++static int clk_hifiberry_dacpro_set_rate(struct clk_hw *hw,
++ unsigned long rate, unsigned long parent_rate)
++{
++ unsigned long actual_rate;
++ struct clk_hifiberry_hw *clk = to_hifiberry_clk(hw);
++
++ actual_rate = (unsigned long)clk_hifiberry_dacpro_round_rate(hw, rate,
++ &parent_rate);
++ clk->mode = (actual_rate == CLK_44EN_RATE) ? 0 : 1;
++ return 0;
++}
++
++
++const struct clk_ops clk_hifiberry_dacpro_rate_ops = {
++ .recalc_rate = clk_hifiberry_dacpro_recalc_rate,
++ .round_rate = clk_hifiberry_dacpro_round_rate,
++ .set_rate = clk_hifiberry_dacpro_set_rate,
++};
++
++static int clk_hifiberry_dacpro_probe(struct platform_device *pdev)
++{
++ int ret;
++ struct clk_hifiberry_hw *proclk;
++ struct clk *clk;
++ struct device *dev;
++ struct clk_init_data init;
++
++ dev = &pdev->dev;
++
++ proclk = kzalloc(sizeof(struct clk_hifiberry_hw), GFP_KERNEL);
++ if (!proclk)
++ return -ENOMEM;
++
++ init.name = "clk-hifiberry-dacpro";
++ init.ops = &clk_hifiberry_dacpro_rate_ops;
++ init.flags = CLK_IS_ROOT | CLK_IS_BASIC;
++ init.parent_names = NULL;
++ init.num_parents = 0;
++
++ proclk->mode = 0;
++ proclk->hw.init = &init;
++
++ clk = devm_clk_register(dev, &proclk->hw);
++ if (!IS_ERR(clk)) {
++ ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
++ clk);
++ } else {
++ dev_err(dev, "Fail to register clock driver\n");
++ kfree(proclk);
++ ret = PTR_ERR(clk);
++ }
++ return ret;
++}
++
++static int clk_hifiberry_dacpro_remove(struct platform_device *pdev)
++{
++ of_clk_del_provider(pdev->dev.of_node);
++ return 0;
++}
++
++static struct platform_driver clk_hifiberry_dacpro_driver = {
++ .probe = clk_hifiberry_dacpro_probe,
++ .remove = clk_hifiberry_dacpro_remove,
++ .driver = {
++ .name = "clk-hifiberry-dacpro",
++ .of_match_table = clk_hifiberry_dacpro_dt_ids,
++ },
++};
++
++static int __init clk_hifiberry_dacpro_init(void)
++{
++ return platform_driver_register(&clk_hifiberry_dacpro_driver);
++}
++core_initcall(clk_hifiberry_dacpro_init);
++
++static void __exit clk_hifiberry_dacpro_exit(void)
++{
++ platform_driver_unregister(&clk_hifiberry_dacpro_driver);
++}
++module_exit(clk_hifiberry_dacpro_exit);
++
++MODULE_DESCRIPTION("HiFiBerry DAC Pro clock driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:clk-hifiberry-dacpro");
+--- a/sound/soc/bcm/hifiberry_dacplus.c
++++ b/sound/soc/bcm/hifiberry_dacplus.c
+@@ -1,8 +1,8 @@
+ /*
+- * ASoC Driver for HiFiBerry DAC+
++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro
+ *
+- * Author: Daniel Matuschek
+- * Copyright 2014
++ * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com>
++ * Copyright 2014-2015
+ * based on code by Florian Meier <florian.meier@koalo.de>
+ *
+ * This program is free software; you can redistribute it and/or
+@@ -17,6 +17,13 @@
+
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/kernel.h>
++#include <linux/clk.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
+
+ #include <sound/core.h>
+ #include <sound/pcm.h>
+@@ -26,34 +33,222 @@
+
+ #include "../codecs/pcm512x.h"
+
++#define HIFIBERRY_DACPRO_NOCLOCK 0
++#define HIFIBERRY_DACPRO_CLK44EN 1
++#define HIFIBERRY_DACPRO_CLK48EN 2
++
++struct pcm512x_priv {
++ struct regmap *regmap;
++ struct clk *sclk;
++};
++
++/* Clock rate of CLK44EN attached to GPIO6 pin */
++#define CLK_44EN_RATE 22579200UL
++/* Clock rate of CLK48EN attached to GPIO3 pin */
++#define CLK_48EN_RATE 24576000UL
++
++static bool snd_rpi_hifiberry_is_dacpro;
++
++static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_codec *codec,
++ int clk_id)
++{
++ switch (clk_id) {
++ case HIFIBERRY_DACPRO_NOCLOCK:
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x00);
++ break;
++ case HIFIBERRY_DACPRO_CLK44EN:
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x20);
++ break;
++ case HIFIBERRY_DACPRO_CLK48EN:
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x24, 0x04);
++ break;
++ }
++}
++
++static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_codec *codec)
++{
++ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x24, 0x24);
++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02);
++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02);
++}
++
++static bool snd_rpi_hifiberry_dacplus_is_sclk(struct snd_soc_codec *codec)
++{
++ int sck;
++
++ sck = snd_soc_read(codec, PCM512x_RATE_DET_4);
++ return (!(sck & 0x40));
++}
++
++static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep(
++ struct snd_soc_codec *codec)
++{
++ msleep(2);
++ return snd_rpi_hifiberry_dacplus_is_sclk(codec);
++}
++
++static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_codec *codec)
++{
++ bool isClk44EN, isClk48En, isNoClk;
++
++ snd_rpi_hifiberry_dacplus_clk_gpio(codec);
++
++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK44EN);
++ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec);
++
++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_NOCLOCK);
++ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec);
++
++ snd_rpi_hifiberry_dacplus_select_clk(codec, HIFIBERRY_DACPRO_CLK48EN);
++ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(codec);
++
++ return (isClk44EN && isClk48En && !isNoClk);
++}
++
++static int snd_rpi_hifiberry_dacplus_clk_for_rate(int sample_rate)
++{
++ int type;
++
++ switch (sample_rate) {
++ case 11025:
++ case 22050:
++ case 44100:
++ case 88200:
++ case 176400:
++ type = HIFIBERRY_DACPRO_CLK44EN;
++ break;
++ default:
++ type = HIFIBERRY_DACPRO_CLK48EN;
++ break;
++ }
++ return type;
++}
++
++static void snd_rpi_hifiberry_dacplus_set_sclk(struct snd_soc_codec *codec,
++ int sample_rate)
++{
++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
++
++ if (!IS_ERR(pcm512x->sclk)) {
++ int ctype;
++
++ ctype = snd_rpi_hifiberry_dacplus_clk_for_rate(sample_rate);
++ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN)
++ ? CLK_44EN_RATE : CLK_48EN_RATE);
++ snd_rpi_hifiberry_dacplus_select_clk(codec, ctype);
++ }
++}
++
+ static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd)
+ {
+ struct snd_soc_codec *codec = rtd->codec;
++ struct pcm512x_priv *priv;
++
++ snd_rpi_hifiberry_is_dacpro
++ = snd_rpi_hifiberry_dacplus_is_pro_card(codec);
++
++ if (snd_rpi_hifiberry_is_dacpro) {
++ struct snd_soc_dai_link *dai = rtd->dai_link;
++
++ dai->name = "HiFiBerry DAC+ Pro";
++ dai->stream_name = "HiFiBerry DAC+ Pro HiFi";
++ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
++ | SND_SOC_DAIFMT_CBM_CFM;
++
++ snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11);
++ snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03);
++ snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63);
++ } else {
++ priv = snd_soc_codec_get_drvdata(codec);
++ priv->sclk = ERR_PTR(-ENOENT);
++ }
++
+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08);
+- snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02);
+- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02);
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
++
++ return 0;
++}
++
++static int snd_rpi_hifiberry_dacplus_update_rate_den(
++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_codec *codec = rtd->codec;
++ struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
++ struct snd_ratnum *rats_no_pll;
++ unsigned int num = 0, den = 0;
++ int err;
++
++ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL);
++ if (!rats_no_pll)
++ return -ENOMEM;
++
++ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64;
++ rats_no_pll->den_min = 1;
++ rats_no_pll->den_max = 128;
++ rats_no_pll->den_step = 1;
++
++ err = snd_interval_ratnum(hw_param_interval(params,
++ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den);
++ if (err >= 0 && den) {
++ params->rate_num = num;
++ params->rate_den = den;
++ }
++
++ devm_kfree(rtd->dev, rats_no_pll);
+ return 0;
+ }
+
+-static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream,
+- struct snd_pcm_hw_params *params)
++static int snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(
++ struct snd_soc_dai *cpu_dai, struct snd_pcm_hw_params *params)
++{
++ int bratio = snd_pcm_format_physical_width(params_format(params))
++ * params_channels(params);
++ return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio);
++}
++
++static int snd_rpi_hifiberry_dacplus_hw_params(
++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
+ {
++ int ret;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
++
++ if (snd_rpi_hifiberry_is_dacpro) {
++ struct snd_soc_codec *codec = rtd->codec;
++
++ snd_rpi_hifiberry_dacplus_set_sclk(codec,
++ params_rate(params));
++
++ ret = snd_rpi_hifiberry_dacplus_set_bclk_ratio_pro(cpu_dai,
++ params);
++ if (!ret)
++ ret = snd_rpi_hifiberry_dacplus_update_rate_den(
++ substream, params);
++ } else {
++ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
++ }
++ return ret;
+ }
+
+-static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) {
++static int snd_rpi_hifiberry_dacplus_startup(
++ struct snd_pcm_substream *substream)
++{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08);
++
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
+ return 0;
+ }
+
+-static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) {
++static void snd_rpi_hifiberry_dacplus_shutdown(
++ struct snd_pcm_substream *substream)
++{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+- snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00);
++
++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00);
+ }
+
+ /* machine stream operations */
+@@ -90,19 +285,20 @@ static int snd_rpi_hifiberry_dacplus_pro
+ int ret = 0;
+
+ snd_rpi_hifiberry_dacplus.dev = &pdev->dev;
+-
+ if (pdev->dev.of_node) {
+- struct device_node *i2s_node;
+- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0];
+- i2s_node = of_parse_phandle(pdev->dev.of_node,
+- "i2s-controller", 0);
+-
+- if (i2s_node) {
+- dai->cpu_dai_name = NULL;
+- dai->cpu_of_node = i2s_node;
+- dai->platform_name = NULL;
+- dai->platform_of_node = i2s_node;
+- }
++ struct device_node *i2s_node;
++ struct snd_soc_dai_link *dai;
++
++ dai = &snd_rpi_hifiberry_dacplus_dai[0];
++ i2s_node = of_parse_phandle(pdev->dev.of_node,
++ "i2s-controller", 0);
++
++ if (i2s_node) {
++ dai->cpu_dai_name = NULL;
++ dai->cpu_of_node = i2s_node;
++ dai->platform_name = NULL;
++ dai->platform_of_node = i2s_node;
++ }
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
+--- a/sound/soc/codecs/pcm512x.c
++++ b/sound/soc/codecs/pcm512x.c
+@@ -856,7 +856,8 @@ static int pcm512x_set_dividers(struct s
+ int fssp;
+ int gpio;
+
+- lrclk_div = snd_soc_params_to_frame_size(params);
++ lrclk_div = snd_pcm_format_physical_width(params_format(params))
++ * params_channels(params);
+ if (lrclk_div == 0) {
+ dev_err(dev, "No LRCLK?\n");
+ return -EINVAL;
--- /dev/null
+From 1e0886a25891d714ffa99cbdd2f68f7e2015a804 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 4 Oct 2015 12:30:01 +0100
+Subject: [PATCH 195/203] config: Add CONFIG_CRYPTO_USER_API_SKCIPHER
+
+---
+ 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
+@@ -1236,6 +1236,7 @@ CONFIG_CRYPTO_WP512=m
+ CONFIG_CRYPTO_CAST5=m
+ CONFIG_CRYPTO_DES=y
+ # CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API_SKCIPHER=m
+ # CONFIG_CRYPTO_HW is not set
+ CONFIG_ARM_CRYPTO=y
+ CONFIG_CRYPTO_SHA1_ARM_NEON=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -1232,6 +1232,7 @@ CONFIG_CRYPTO_WP512=m
+ CONFIG_CRYPTO_CAST5=m
+ CONFIG_CRYPTO_DES=y
+ # CONFIG_CRYPTO_ANSI_CPRNG is not set
++CONFIG_CRYPTO_USER_API_SKCIPHER=m
+ # CONFIG_CRYPTO_HW is not set
+ CONFIG_ARM_CRYPTO=y
+ CONFIG_CRYPTO_SHA1_ARM=m
--- /dev/null
+From 59a7fec4b1798a00025438b88e782ec6b36d5a53 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 4 Oct 2015 12:36:44 +0100
+Subject: [PATCH 196/203] config: Add options for supporting openlabs 802.15.4
+ radio
+
+---
+ arch/arm/configs/bcm2709_defconfig | 6 ++++++
+ arch/arm/configs/bcmrpi_defconfig | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -283,6 +283,9 @@ CONFIG_VLAN_8021Q=m
+ CONFIG_VLAN_8021Q_GVRP=y
+ CONFIG_ATALK=m
+ CONFIG_6LOWPAN=m
++CONFIG_IEEE802154=m
++CONFIG_IEEE802154_6LOWPAN=m
++CONFIG_MAC802154=m
+ CONFIG_NET_SCHED=y
+ CONFIG_NET_SCH_CBQ=m
+ CONFIG_NET_SCH_HTB=m
+@@ -527,6 +530,9 @@ CONFIG_ZD1211RW=m
+ CONFIG_MWIFIEX=m
+ CONFIG_MWIFIEX_SDIO=m
+ CONFIG_WIMAX_I2400M_USB=m
++CONFIG_IEEE802154_AT86RF230=m
++CONFIG_IEEE802154_MRF24J40=m
++CONFIG_IEEE802154_CC2520=m
+ CONFIG_INPUT_POLLDEV=m
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+ CONFIG_INPUT_JOYDEV=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -276,6 +276,9 @@ CONFIG_VLAN_8021Q=m
+ CONFIG_VLAN_8021Q_GVRP=y
+ CONFIG_ATALK=m
+ CONFIG_6LOWPAN=m
++CONFIG_IEEE802154=m
++CONFIG_IEEE802154_6LOWPAN=m
++CONFIG_MAC802154=m
+ CONFIG_NET_SCHED=y
+ CONFIG_NET_SCH_CBQ=m
+ CONFIG_NET_SCH_HTB=m
+@@ -520,6 +523,9 @@ CONFIG_ZD1211RW=m
+ CONFIG_MWIFIEX=m
+ CONFIG_MWIFIEX_SDIO=m
+ CONFIG_WIMAX_I2400M_USB=m
++CONFIG_IEEE802154_AT86RF230=m
++CONFIG_IEEE802154_MRF24J40=m
++CONFIG_IEEE802154_CC2520=m
+ CONFIG_INPUT_POLLDEV=m
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+ CONFIG_INPUT_JOYDEV=m
--- /dev/null
+From 7b82355fa657220c9d5e72f0aa5228f0d76819fa Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 5 Oct 2015 10:47:45 +0100
+Subject: [PATCH 197/203] BCM270X_DT: Add at86rf233 overlay
+
+Add an overlay to support the Atmel AT86RF233 WPAN transceiver on spi0.0.
+
+See: https://github.com/raspberrypi/linux/issues/1151
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 21 +++++++--
+ arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 54 ++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+), 4 deletions(-)
+ create mode 100644 arch/arm/boot/dts/overlays/at86rf233-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -13,6 +13,7 @@ ifeq ($(CONFIG_ARCH_BCM2835),y)
+ endif
+
+ dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += at86rf233-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -69,13 +69,14 @@ DT parameters:
+
+ Parameters always have default values, although in some cases (e.g. "w1-gpio")
+ it is necessary to provided multiple overlays in order to get the desired
+-behaviour. See the list of overlays below for a description of the parameters and their defaults.
++behaviour. See the list of overlays below for a description of the parameters
++and their defaults.
+
+ The Overlay and Parameter Reference
+ ===================================
+
+-N.B. When editing this file, please preserve the indentation levels to make it simple to parse
+-programmatically. NO HARD TABS.
++N.B. When editing this file, please preserve the indentation levels to make it
++simple to parse programmatically. NO HARD TABS.
+
+
+ Name: <The base DTB>
+@@ -149,7 +150,7 @@ Name: ads7846
+ Info: ADS7846 Touch controller
+ Load: dtoverlay=ads7846,<param>=<val>
+ Params: cs SPI bus Chip Select (default 1)
+- speed SPI bus speed (default 2Mhz, max 3.25MHz)
++ speed SPI bus speed (default 2MHz, max 3.25MHz)
+ penirq GPIO used for PENIRQ. REQUIRED
+ penirq_pull Set GPIO pull (default 0=none, 2=pullup)
+ swapxy Swap x and y axis
+@@ -170,6 +171,18 @@ Params: cs SPI bus
+ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt
+
+
++Name: at86rf233
++Info: Configures the Atmel AT86RF233 802.15.4 low-power WPAN transceiver,
++ connected to spi0.0
++Load: dtoverlay=at86rf233,<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 750000)
++ trim Fine tuning of the internal capacitance
++ arrays (0=+0pF, 15=+4.5pF, default 15)
++
++
+ Name: bmp085_i2c-sensor
+ Info: Configures the BMP085/BMP180 digital barometric pressure and temperature
+ sensors from Bosch Sensortec
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts
+@@ -0,0 +1,54 @@
++/dts-v1/;
++/plugin/;
++
++/* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */
++
++/ {
++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
++
++ fragment@0 {
++ target = <&spi0>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ status = "okay";
++
++ spidev@0{
++ status = "disabled";
++ };
++
++ lowpan0: at86rf233@0 {
++ compatible = "atmel,at86rf233";
++ reg = <0>;
++ interrupt-parent = <&gpio>;
++ interrupts = <23 4>; /* active high */
++ reset-gpio = <&gpio 24 1>;
++ sleep-gpio = <&gpio 25 1>;
++ spi-max-frequency = <7500000>;
++ xtal-trim = /bits/ 8 <0xf>;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&gpio>;
++ __overlay__ {
++ lowpan0_pins: lowpan0_pins {
++ brcm,pins = <23 24 25>;
++ brcm,function = <0 1 1>; /* in out out */
++ };
++ };
++ };
++
++ __overrides__ {
++ interrupt = <&lowpan0>, "interrupts:0",
++ <&lowpan0_pins>, "brcm,pins:0";
++ reset = <&lowpan0>, "reset-gpio:4",
++ <&lowpan0_pins>, "brcm,pins:4";
++ sleep = <&lowpan0>, "sleep-gpio:4",
++ <&lowpan0_pins>, "brcm,pins:8";
++ speed = <&lowpan0>, "spi-max-frequency:0";
++ trim = <&lowpan0>, "xtal-trim.0";
++ };
++};
--- /dev/null
+From 6413adc1fbf4c3e9a2bcd707dd7776f419988d7c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 6 Oct 2015 10:16:58 +0100
+Subject: [PATCH 198/203] bcm2835-gpiomem: Fix for ARCH_BCM2835 builds
+
+Build on ARCH_BCM2835, and fail to probe if no IO resource.
+
+See: https://github.com/raspberrypi/linux/issues/1154
+---
+ drivers/char/broadcom/bcm2835-gpiomem.c | 25 ++++++++++---------------
+ 1 file changed, 10 insertions(+), 15 deletions(-)
+
+--- a/drivers/char/broadcom/bcm2835-gpiomem.c
++++ b/drivers/char/broadcom/bcm2835-gpiomem.c
+@@ -143,7 +143,6 @@ static int bcm2835_gpiomem_probe(struct
+ int err;
+ void *ptr_err;
+ struct device *dev = &pdev->dev;
+- struct device_node *node = dev->of_node;
+ struct resource *ioresource;
+
+ /* Allocate buffers and instance data */
+@@ -157,6 +156,15 @@ static int bcm2835_gpiomem_probe(struct
+
+ inst->dev = dev;
+
++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (ioresource) {
++ inst->gpio_regs_phys = ioresource->start;
++ } else {
++ dev_err(inst->dev, "failed to get IO resource");
++ err = -ENOENT;
++ goto failed_get_resource;
++ }
++
+ /* Create character device entries */
+
+ err = alloc_chrdev_region(&bcm2835_gpiomem_devid,
+@@ -187,20 +195,6 @@ static int bcm2835_gpiomem_probe(struct
+ if (IS_ERR(ptr_err))
+ goto failed_device_create;
+
+- /* Get address from device tree if available (*_resource() correctly
+- converts the bus address in device tree to a physical address),
+- or use hardcoded offset + BCM2708_PERI_BASE if not.
+- (In spite of its name 2708 actually seems to have the correct
+- mach-dependent value on 2709 etc, as it is defined in
+- mach-bcm270x/platform.h) */
+-
+- if (node) {
+- ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- inst->gpio_regs_phys = ioresource->start;
+- } else {
+- inst->gpio_regs_phys = GPIO_BASE;
+- }
+-
+ dev_info(inst->dev, "Initialised: Registers at 0x%08lx",
+ inst->gpio_regs_phys);
+
+@@ -214,6 +208,7 @@ failed_class_create:
+ failed_cdev_add:
+ unregister_chrdev_region(bcm2835_gpiomem_devid, 1);
+ failed_alloc_chrdev:
++failed_get_resource:
+ kfree(inst);
+ failed_inst_alloc:
+ dev_err(inst->dev, "could not load bcm2835_gpiomem");
--- /dev/null
+From f578216ec77548da230336549ed488dbdf4a42f3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 8 Oct 2015 13:33:28 +0100
+Subject: [PATCH 199/203] scripts/mkknlimg: Improve ARCH_BCM2835 detection
+
+The board support code contains sufficient strings to be able to
+distinguish 2708 vs. 2835 builds, so remove the check for
+bcm2835-pm-wdt which could exist in either.
+
+Also, since the canned configuration is no longer built in (it's
+a module), remove the config string checking.
+
+See: https://github.com/raspberrypi/linux/issues/1157
+---
+ scripts/mkknlimg | 41 +++++------------------------------------
+ 1 file changed, 5 insertions(+), 36 deletions(-)
+
+--- a/scripts/mkknlimg
++++ b/scripts/mkknlimg
+@@ -50,12 +50,6 @@ if (! -r $kernel_file)
+ usage();
+ }
+
+-my @wanted_config_lines =
+-(
+- 'CONFIG_BCM2708_DT',
+- 'CONFIG_ARCH_BCM2835'
+-);
+-
+ my @wanted_strings =
+ (
+ 'bcm2708_fb',
+@@ -63,7 +57,8 @@ my @wanted_strings =
+ 'brcm,bcm2835-sdhost',
+ 'brcm,bcm2708-pinctrl',
+ 'brcm,bcm2835-gpio',
+- 'brcm,bcm2835-pm-wdt'
++ 'brcm,bcm2835',
++ 'brcm,bcm2836'
+ );
+
+ my $res = try_extract($kernel_file, $tmpfile1);
+@@ -98,12 +93,11 @@ if ($res)
+ config_bool($res, 'brcm,bcm2835-mmc') ||
+ config_bool($res, 'brcm,bcm2835-sdhost'))
+ {
+- $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT');
+- $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835');
+ $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl');
+ $dtok ||= config_bool($res, 'brcm,bcm2835-gpio');
+- $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835');
+- $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt');
++ $is_283x ||= config_bool($res, 'brcm,bcm2835');
++ $is_283x ||= config_bool($res, 'brcm,bcm2836');
++ $dtok ||= $is_283x;
+ $append_trailer = 1;
+ }
+ else
+@@ -205,31 +199,6 @@ sub try_extract
+ $res->{$match} = 1;
+ }
+
+- my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$';
+- my $cf1 = 'IKCFG_ST\037\213\010';
+- my $cf2 = '0123456789';
+-
+- my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`;
+- if ($pos)
+- {
+- $pos =~ s/:.*[\r\n]*$//s;
+- $pos += 8;
+- my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8);
+- if (($err == 0) || ($err == 2))
+- {
+- if (open(my $fh, '<', $tmp))
+- {
+- while (my $line = <$fh>)
+- {
+- chomp($line);
+- $res->{$1} = $2 if ($line =~ /$config_pattern/);
+- }
+-
+- close($fh);
+- }
+- }
+- }
+-
+ return $res;
+ }
+
--- /dev/null
+From f6c213fbd75a2efeb2e8ef0034be7376a306f7fd Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 9 Oct 2015 10:49:00 +0100
+Subject: [PATCH 200/203] BCM270X_DT: Make mmc overlay compatible with current
+ firmware
+
+The original DT overlay logic followed a merge-then-patch procedure,
+i.e. parameters are applied to the loaded overlay before the overlay
+is merged into the base DTB. This sequence has been changed to
+patch-then-merge, in order to support parameterised node names, and
+to protect against bad overlays. As a result, overrides (parameters)
+must only target labels in the overlay, but the overlay can obviously target nodes in the base DTB.
+
+mmc-overlay.dts (that switches back to the original mmc sdcard
+driver) is the only overlay violating that rule, and this patch
+fixes it.
+---
+ arch/arm/boot/dts/overlays/mmc-overlay.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/mmc-overlay.dts
++++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts
+@@ -7,13 +7,13 @@
+ fragment@0 {
+ target = <&mmc>;
+
+- __overlay__ {
++ frag0: __overlay__ {
+ brcm,overclock-50 = <0>;
+ };
+ };
+
+ __overrides__ {
+- overclock_50 = <&mmc>,"brcm,overclock-50:0";
+- force_pio = <&mmc>,"brcm,force-pio?";
++ overclock_50 = <&frag0>,"brcm,overclock-50:0";
++ force_pio = <&frag0>,"brcm,force-pio?";
+ };
+ };
--- /dev/null
+From a78ad9a34f11fecfdcd08675396bf2bf163a3f4d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 12 Oct 2015 08:52:00 +0100
+Subject: [PATCH 201/203] BCM270X_DT: Reduce default at86rf233 SPI frequency
+
+The AT86RF233 has been found to be unreliable on a 7.5MHz SPI bus,
+so reduce the default frequency to 6MHz.
+
+See: 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
+@@ -178,7 +178,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 750000)
++ speed SPI bus speed in Hz (default 6000000)
+ 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 = <7500000>;
++ spi-max-frequency = <6000000>;
+ xtal-trim = /bits/ 8 <0xf>;
+ };
+ };
--- /dev/null
+From 688316bb306e42d224d4922b26cd44d5ff0e64b3 Mon Sep 17 00:00:00 2001
+From: mwilliams03 <mark.mwilliams@gmail.com>
+Date: Sun, 18 Oct 2015 17:07:24 -0700
+Subject: [PATCH 202/203] New overlay for PiScreen2r
+
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 14 +++
+ arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 100 ++++++++++++++++++++++
+ 3 files changed, 115 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/piscreen2r-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -34,6 +34,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) += piscreen-overlay.dtb
++dtb-$(RPI_DT_OVERLAYS) += piscreen2r-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb
+ dtb-$(RPI_DT_OVERLAYS) += pwm-overlay.dtb
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -411,6 +411,20 @@ Params: speed Display
+ xohms Touchpanel sensitivity (X-plate resistance)
+
+
++Name: piscreen2r
++Info: PiScreen 2 with resistive TP display by OzzMaker.com
++Load: dtoverlay=piscreen,<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)
++
++
+ Name: pitft28-resistive
+ Info: Adafruit PiTFT 2.8" resistive touch screen
+ Load: dtoverlay=pitft28-resistive,<param>=<val>
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts
+@@ -0,0 +1,100 @@
++ /*
++ * Device Tree overlay for PiScreen2 3.5" TFT with resistive touch by Ozzmaker.com
++ *
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
++
++ fragment@0 {
++ target = <&spi0>;
++ __overlay__ {
++ status = "okay";
++
++ spidev@0{
++ status = "disabled";
++ };
++
++ spidev@1{
++ status = "disabled";
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&gpio>;
++ __overlay__ {
++ piscreen2_pins: piscreen2_pins {
++ brcm,pins = <17 25 24 22>;
++ brcm,function = <0 1 1 1>; /* in out out out */
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&spi0>;
++ __overlay__ {
++ /* needed to avoid dtc warning */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ piscreen2: piscreen2@0{
++ compatible = "ilitek,ili9486";
++ reg = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&piscreen2_pins>;
++ bgr;
++ spi-max-frequency = <64000000>;
++ rotate = <90>;
++ fps = <30>;
++ buswidth = <8>;
++ regwidth = <16>;
++ txbuflen = <32768>;
++ reset-gpios = <&gpio 25 0>;
++ dc-gpios = <&gpio 24 0>;
++ led-gpios = <&gpio 22 1>;
++ debug = <0>;
++
++ init = <0x10000b0 0x00
++ 0x1000011
++ 0x20000ff
++ 0x100003a 0x55
++ 0x1000036 0x28
++ 0x10000c0 0x11 0x09
++ 0x10000c1 0x41
++ 0x10000c5 0x00 0x00 0x00 0x00
++ 0x10000b6 0x00 0x02
++ 0x10000f7 0xa9 0x51 0x2c 0x2
++ 0x10000be 0x00 0x04
++ 0x10000e9 0x00
++ 0x1000011
++ 0x1000029>;
++
++ };
++
++ piscreen2_ts: piscreen2-ts@1 {
++ compatible = "ti,ads7846";
++ reg = <1>;
++
++ spi-max-frequency = <2000000>;
++ interrupts = <17 2>; /* high-to-low edge triggered */
++ interrupt-parent = <&gpio>;
++ pendown-gpio = <&gpio 17 0>;
++ ti,swap-xy;
++ ti,x-plate-ohms = /bits/ 16 <100>;
++ ti,pressure-max = /bits/ 16 <255>;
++ };
++ };
++ };
++ __overrides__ {
++ speed = <&piscreen2>,"spi-max-frequency:0";
++ rotate = <&piscreen2>,"rotate:0";
++ fps = <&piscreen2>,"fps:0";
++ debug = <&piscreen2>,"debug:0";
++ xohms = <&piscreen2_ts>,"ti,x-plate-ohms;0";
++ };
++};
++
--- /dev/null
+From 7d9db46fa0eb27c0d6df7a3a6ae20da515a20e58 Mon Sep 17 00:00:00 2001
+From: P33M <P33M@github.com>
+Date: Wed, 21 Oct 2015 14:55:21 +0100
+Subject: [PATCH 203/203] 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
+mailbox request.
+
+Signed-off-by: Gordon Hollingworth <gordon@raspberrypi.org>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 6 ++
+ .../boot/dts/overlays/rpi-backlight-overlay.dts | 21 ++++
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ drivers/video/backlight/Kconfig | 6 ++
+ drivers/video/backlight/Makefile | 1 +
+ drivers/video/backlight/rpi_backlight.c | 119 +++++++++++++++++++++
+ include/soc/bcm2835/raspberrypi-firmware.h | 1 +
+ 9 files changed, 157 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts
+ create mode 100644 drivers/video/backlight/rpi_backlight.c
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -40,6 +40,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overl
+ 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
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -490,6 +490,12 @@ Load: dtoverlay=raspidac3
+ Params: <None>
+
+
++Name: rpi-backlight
++Info: Raspberry Pi official display backlight driver
++Load: dtoverlay=rpi-backlight
++Params: <None>
++
++
+ Name: rpi-dac
+ Info: Configures the RPi DAC audio card
+ Load: dtoverlay=rpi-dac
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts
+@@ -0,0 +1,21 @@
++/*
++ * Devicetree overlay for mailbox-driven Raspberry Pi DSI Display
++ * backlight controller
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target-path = "/";
++ __overlay__ {
++ rpi_backlight: rpi_backlight {
++ compatible = "raspberrypi,rpi-backlight";
++ firmware = <&firmware>;
++ status = "okay";
++ };
++ };
++ };
++};
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -806,6 +806,7 @@ CONFIG_FB_BCM2708=y
+ CONFIG_FB_SSD1307=m
+ CONFIG_FB_RPISENSE=m
+ # CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_RPI=m
+ CONFIG_BACKLIGHT_GPIO=m
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+ CONFIG_LOGO=y
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -799,6 +799,7 @@ CONFIG_FB_BCM2708=y
+ CONFIG_FB_SSD1307=m
+ CONFIG_FB_RPISENSE=m
+ # CONFIG_BACKLIGHT_GENERIC is not set
++CONFIG_BACKLIGHT_RPI=m
+ CONFIG_BACKLIGHT_GPIO=m
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+ CONFIG_LOGO=y
+--- a/drivers/video/backlight/Kconfig
++++ b/drivers/video/backlight/Kconfig
+@@ -263,6 +263,12 @@ config BACKLIGHT_PWM
+ If you have a LCD backlight adjustable by PWM, say Y to enable
+ this driver.
+
++config BACKLIGHT_RPI
++ tristate "Raspberry Pi display firmware driven backlight"
++ help
++ If you have the Raspberry Pi DSI touchscreen display, say Y to
++ enable the mailbox-controlled backlight driver.
++
+ config BACKLIGHT_DA903X
+ tristate "Backlight Driver for DA9030/DA9034 using WLED"
+ depends on PMIC_DA903X
+--- a/drivers/video/backlight/Makefile
++++ b/drivers/video/backlight/Makefile
+@@ -49,6 +49,7 @@ obj-$(CONFIG_BACKLIGHT_OT200) += ot200_
+ obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
+ obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
+ obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
++obj-$(CONFIG_BACKLIGHT_RPI) += rpi_backlight.o
+ obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
+ obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
+ obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
+--- /dev/null
++++ b/drivers/video/backlight/rpi_backlight.c
+@@ -0,0 +1,119 @@
++/*
++ * rpi_bl.c - Backlight controller through VPU
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/backlight.h>
++#include <linux/err.h>
++#include <linux/fb.h>
++#include <linux/gpio.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++struct rpi_backlight {
++ struct device *dev;
++ struct device *fbdev;
++ struct rpi_firmware *fw;
++};
++
++static int rpi_backlight_update_status(struct backlight_device *bl)
++{
++ struct rpi_backlight *gbl = bl_get_data(bl);
++ int brightness = bl->props.brightness;
++ int ret;
++
++ if (bl->props.power != FB_BLANK_UNBLANK ||
++ bl->props.fb_blank != FB_BLANK_UNBLANK ||
++ bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
++ brightness = 0;
++
++ ret = rpi_firmware_property(gbl->fw,
++ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT,
++ &brightness, sizeof(brightness));
++ if (ret) {
++ dev_err(gbl->dev, "Failed to set brightness\n");
++ return ret;
++ }
++
++ if (brightness < 0) {
++ dev_err(gbl->dev, "Backlight change failed\n");
++ return -EAGAIN;
++ }
++
++ return 0;
++}
++
++static const struct backlight_ops rpi_backlight_ops = {
++ .options = BL_CORE_SUSPENDRESUME,
++ .update_status = rpi_backlight_update_status,
++};
++
++static int rpi_backlight_probe(struct platform_device *pdev)
++{
++ struct backlight_properties props;
++ struct backlight_device *bl;
++ struct rpi_backlight *gbl;
++ struct device_node *fw_node;
++
++ gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL);
++ if (gbl == NULL)
++ return -ENOMEM;
++
++ gbl->dev = &pdev->dev;
++
++ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
++ if (!fw_node) {
++ dev_err(&pdev->dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ gbl->fw = rpi_firmware_get(fw_node);
++ if (!gbl->fw)
++ return -EPROBE_DEFER;
++
++ memset(&props, 0, sizeof(props));
++ props.type = BACKLIGHT_RAW;
++ props.max_brightness = 255;
++ bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
++ &pdev->dev, gbl, &rpi_backlight_ops,
++ &props);
++ if (IS_ERR(bl)) {
++ dev_err(&pdev->dev, "failed to register backlight\n");
++ return PTR_ERR(bl);
++ }
++
++ bl->props.brightness = 255;
++ backlight_update_status(bl);
++
++ platform_set_drvdata(pdev, bl);
++ return 0;
++}
++
++static const struct of_device_id rpi_backlight_of_match[] = {
++ { .compatible = "raspberrypi,rpi-backlight" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, rpi_backlight_of_match);
++
++static struct platform_driver rpi_backlight_driver = {
++ .driver = {
++ .name = "rpi-backlight",
++ .of_match_table = of_match_ptr(rpi_backlight_of_match),
++ },
++ .probe = rpi_backlight_probe,
++};
++
++module_platform_driver(rpi_backlight_driver);
++
++MODULE_AUTHOR("Gordon Hollingworth <gordon@raspberrypi.org>");
++MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver");
++MODULE_LICENSE("GPL");
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -109,6 +109,7 @@ enum rpi_firmware_property_tag {
+ RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
++ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,
+
+ RPI_FIRMWARE_VCHIQ_INIT = 0x00048010,
+