From c9fb67d03d94c2f12dbb6d547133079df377334e Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sun, 24 Aug 2014 14:00:25 +0200 Subject: [PATCH] projects/RPi/patches/linux: update RPi support patch Signed-off-by: Stephan Raue --- .../patches/linux/linux-01-RPi_support.patch | 1561 ++++++++++------- 1 file changed, 935 insertions(+), 626 deletions(-) diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index bb0ec0c896..eb2e857d2c 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ From 839892fb323f851df87d53988607afedf3dd830b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 01/73] Main bcm2708 linux port +Subject: [PATCH 01/77] Main bcm2708 linux port Signed-off-by: popcornmix --- @@ -8673,13 +8673,13 @@ index 08abe99..544da76 100644 unsigned int version; /* SDHCI spec. version */ -- -2.0.3 +2.0.4 From da440b37d0d7441018381f8444219096b7b0bb1b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 7 May 2013 22:20:24 +0100 -Subject: [PATCH 02/73] Add quick config. +Subject: [PATCH 02/77] Add quick config. This is designed for quick compiling when developing. No modules are needed and it includes all Pi specific drivers @@ -8892,13 +8892,13 @@ index 0000000..e5efe75 +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -- -2.0.3 +2.0.4 From 902e25dd4eaa08f290dbe28741cfa19f135e9574 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 03/73] Add dwc_otg driver +Subject: [PATCH 03/77] Add dwc_otg driver Signed-off-by: popcornmix --- @@ -65967,13 +65967,13 @@ index 0000000..cdc9963 +test_main(); +0; -- -2.0.3 +2.0.4 From 6b87ca694e19511ee495315977066f3df32cbadc Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 04/73] bcm2708 watchdog driver +Subject: [PATCH 04/77] bcm2708 watchdog driver Signed-off-by: popcornmix --- @@ -66401,13 +66401,13 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -- -2.0.3 +2.0.4 From 75f85908f5c7346bcfae244d2de54469e7a34b98 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:55:09 +0100 -Subject: [PATCH 05/73] bcm2708 framebuffer driver +Subject: [PATCH 05/77] bcm2708 framebuffer driver Signed-off-by: popcornmix --- @@ -69451,13 +69451,13 @@ index 3c14e43..7626beb 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -- -2.0.3 +2.0.4 From 39f45149b0b1b89e9c6e87d79de37b754008c3d3 Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 06/73] Speed up console framebuffer imageblit function +Subject: [PATCH 06/77] 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 @@ -69666,13 +69666,13 @@ index a2bb276..436494f 100644 start_index, pitch_index); } else -- -2.0.3 +2.0.4 From dab41a03d19951dcf0af36647b7bcfc716fa46ce Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 07/73] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 07/77] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -69765,13 +69765,13 @@ index fb795c3..fa72af0 100644 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ -- -2.0.3 +2.0.4 From 5ca156864b2ac966e3d20aa29a3eabab4b559295 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 16:00:25 +0300 -Subject: [PATCH 08/73] bcm2708_fb: DMA acceleration for fb_copyarea +Subject: [PATCH 08/77] bcm2708_fb: DMA acceleration for fb_copyarea Based on http://www.raspberrypi.org/phpBB3/viewtopic.php?p=62425#p62425 Also used Simon's dmaer_master module as a reference for tweaking DMA @@ -70255,13 +70255,13 @@ index 54cd760..b3b1e04 100644 return 0; -- -2.0.3 +2.0.4 From 9e7cf5f765bfaf0412918f84f87f507404928531 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 09/73] bcm2708 vchiq driver +Subject: [PATCH 09/77] bcm2708 vchiq driver Signed-off-by: popcornmix @@ -82810,13 +82810,13 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -- -2.0.3 +2.0.4 From 07e18ad78953ccfa168920bd0cfa95d20d853a0a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 12 May 2014 15:12:02 +0100 -Subject: [PATCH 10/73] vchiq: Avoid high load when blocked and unkillable +Subject: [PATCH 10/77] vchiq: Avoid high load when blocked and unkillable vchiq: Include SIGSTOP and SIGCONT in list of signals not-masked by vchiq to allow gdb to work --- @@ -82978,13 +82978,13 @@ index c2eefef..05e7979 100644 static inline int is_pow2(int i) { -- -2.0.3 +2.0.4 From c156c499b73a549d7bff0d3c991494d11108cd6f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 11/73] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 11/77] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix --- @@ -84273,13 +84273,13 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -- -2.0.3 +2.0.4 From bcd05a294b17945c1992560a04e60d5a75ecd347 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 12/73] bcm2708: alsa sound driver +Subject: [PATCH 12/77] bcm2708: alsa sound driver Signed-off-by: popcornmix @@ -87067,13 +87067,13 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -- -2.0.3 +2.0.4 From afcf0a46aa2ca83398e4be2a0b444dfe82915681 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 13/73] Add hwrng (hardware random number generator) driver +Subject: [PATCH 13/77] Add hwrng (hardware random number generator) driver --- arch/arm/mach-bcm2708/include/mach/platform.h | 1 + @@ -87252,13 +87252,13 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -- -2.0.3 +2.0.4 From e331619637903fb87cf857a2eca13db59c3fb26e Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 14/73] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 14/77] 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 @@ -88000,13 +88000,13 @@ index 0000000..57ffacf +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -- -2.0.3 +2.0.4 From 792da119ecc4c626a203766aaec1e52b2e3a7fab Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 15/73] Add cpufreq driver +Subject: [PATCH 15/77] Add cpufreq driver --- arch/arm/Kconfig | 1 + @@ -88305,13 +88305,13 @@ index 0000000..7bc55bd +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -- -2.0.3 +2.0.4 From 3e47e00f837107aeb880b4ea1712f1a08c27d970 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 16/73] Added hwmon/thermal driver for reporting core +Subject: [PATCH 16/77] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian --- @@ -88833,13 +88833,13 @@ index 0000000..85fceb5 + +module_platform_driver(bcm2835_thermal_driver); -- -2.0.3 +2.0.4 From e611450aaf310a866b42c52a34fc5307d4231046 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 17/73] Allow mac address to be set in smsc95xx +Subject: [PATCH 17/77] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -88930,13 +88930,13 @@ index d07bf4c..5ae60ab 100644 if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { -- -2.0.3 +2.0.4 From cb77c7822b8734fb85c2e0d5fce466b47199969f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 4 Nov 2013 18:56:10 +0000 -Subject: [PATCH 18/73] Add Chris Boot's i2c and spi drivers. +Subject: [PATCH 18/77] Add Chris Boot's i2c and spi drivers. i2c-bcm2708: fixed baudrate @@ -90317,13 +90317,13 @@ index 0000000..b04a57d +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -- -2.0.3 +2.0.4 From b48352e617873908e9eed7c7a0a0274c3154d443 Mon Sep 17 00:00:00 2001 From: cbeytas Date: Mon, 24 Jun 2013 00:05:40 -0400 -Subject: [PATCH 19/73] Perform I2C combined transactions when possible +Subject: [PATCH 19/77] Perform I2C combined transactions when possible Perform I2C combined transactions whenever possible, within the restrictions of the Broadcomm Serial Controller. @@ -90395,13 +90395,13 @@ index f266f10..8750634 100644 } -- -2.0.3 +2.0.4 From a8f2638feb6187f10fe57305790052d7eb5b8864 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 20/73] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 20/77] 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 @@ -90673,13 +90673,13 @@ index 2820924..fd0550f 100644 } } -- -2.0.3 +2.0.4 From bd506122daf1d74245615448bc794c2f64fce271 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 12 Apr 2013 23:58:47 +0100 -Subject: [PATCH 24/73] config: add missing options from 3.6.y kernel +Subject: [PATCH 24/77] config: add missing options from 3.6.y kernel --- arch/arm/configs/bcmrpi_defconfig | 757 ++++++++++++++++++++++++++++++++------ @@ -91728,13 +91728,13 @@ index 31f5afaa..5b69e83 100644 # CONFIG_CRYPTO_HW is not set CONFIG_CRC_ITU_T=y -- -2.0.3 +2.0.4 From 81c9c12a18219e4047e0ce94c903a0d71781005d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 25/73] config: Enable CONFIG_MEMCG, but leave it disabled (due +Subject: [PATCH 25/77] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -91802,13 +91802,13 @@ index 1f14a43..403173e 100644 #ifdef CONFIG_MEMCG_SWAP -- -2.0.3 +2.0.4 From 4419c5e5a7d400cdd45bcb500a91a46853aaac51 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:46:42 +0100 -Subject: [PATCH 26/73] Add FIQ patch to dwc_otg driver. Enable with +Subject: [PATCH 26/77] Add FIQ patch to dwc_otg driver. Enable with dwc_otg.fiq_fix_enable=1. Should give about 10% more ARM performance. Thanks to Gordon and Costas @@ -95127,13 +95127,13 @@ index 1b1f83c..c8590b5 100644 if (status.b.sr) { -- -2.0.3 +2.0.4 From 23139849a415b9f4048fbc2e8f9d9a610cfd6bb6 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 19 Mar 2014 12:58:23 +0000 -Subject: [PATCH 27/73] dwc_otg: fiq_fsm: Base commit for driver rewrite +Subject: [PATCH 27/77] dwc_otg: fiq_fsm: Base commit for driver rewrite This commit removes the previous FIQ fixes entirely and adds fiq_fsm. @@ -100029,13 +100029,13 @@ index 5d310df..4b32941 100644 return -EBUSY; } -- -2.0.3 +2.0.4 From d4a83bcbcb9da2e2da12b9f6c699c4fbba695f94 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 28/73] bcm2835: add v4l2 camera device +Subject: [PATCH 28/77] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -106020,13 +106020,13 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -- -2.0.3 +2.0.4 From ce9099c8d233407393fddc3aac73867919593acf Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 9 Dec 2013 10:58:01 +0000 -Subject: [PATCH 29/73] V4L2: Fixes from 6by9 +Subject: [PATCH 29/77] V4L2: Fixes from 6by9 V4L2: Fix EV values. Add manual shutter speed control @@ -108398,13 +108398,13 @@ index a06fb44..76f249e 100644 release_msg: -- -2.0.3 +2.0.4 From c6bb89322561ea50e609a73ee792020429329472 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 30/73] dmaengine: Add support for BCM2708 +Subject: [PATCH 30/77] dmaengine: Add support for BCM2708 Add support for DMA controller of BCM2708 as used in the Raspberry Pi. Currently it only supports cyclic DMA. @@ -109041,13 +109041,13 @@ index 0000000..b244293 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 9f7b49b82309f6b788c08ffa9cb7bca2f850c375 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 31/73] ASoC: Add support for BCM2708 +Subject: [PATCH 31/77] ASoC: Add support for BCM2708 This driver adds support for digital audio (I2S) for the BCM2708 SoC that is used by the @@ -110042,13 +110042,13 @@ index 0000000..ebaf3d6 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From f2d01e149898dfc5a6ccfd5007bc0ac07caa156f Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:37:51 +0100 -Subject: [PATCH 32/73] BCM2708: Extend mach header +Subject: [PATCH 32/77] BCM2708: Extend mach header Extend the headers of the mach-bcm2708 in order to support I2S and DMA engine. @@ -110090,13 +110090,13 @@ index 992a630..2e7e1bb 100644 #define BSC0_BASE (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */ #define UART1_BASE (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */ -- -2.0.3 +2.0.4 From ba0fd48bfe41f4f12ac70dfbba058afa8f3100fd Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 33/73] ASoC: Add support for PCM5102A codec +Subject: [PATCH 33/77] ASoC: Add support for PCM5102A codec Some definitions to support the PCM5102A codec by Texas Instruments. @@ -110221,13 +110221,13 @@ index 0000000..126f1e9 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 5c220e69598ccc5a4331a4807685b2bee0e7531e Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 34/73] BCM2708: Add I2S support to board file +Subject: [PATCH 34/77] BCM2708: Add I2S support to board file Adds the required initializations for I2S to the board file of mach-bcm2708. @@ -110282,13 +110282,13 @@ index a6eb08e..27e47d5 100644 struct amba_device *d = amba_devs[i]; amba_device_register(d, &iomem_resource); -- -2.0.3 +2.0.4 From 8c4010ef6f120f6f20c3d575600a5b595bbb0994 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 35/73] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 35/77] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -110437,13 +110437,13 @@ index 0000000..4b70b45 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 64aa80c778a2bc0b03e1039f95960243f4201fd7 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 36/73] BCM2708: Add HifiBerry DAC to board file +Subject: [PATCH 36/77] BCM2708: Add HifiBerry DAC to board file This adds the initalization of the HifiBerry DAC to the mach-bcm2708 board file. @@ -110491,13 +110491,13 @@ index 27e47d5..fafd8d0 100644 struct amba_device *d = amba_devs[i]; amba_device_register(d, &iomem_resource); -- -2.0.3 +2.0.4 From 15a789cf4a98f88eb75d553b6caea4f7d1c8de9c Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 6 Dec 2013 18:55:53 +0100 -Subject: [PATCH 37/73] ASoC: BCM2708: Add 24 bit support +Subject: [PATCH 37/77] ASoC: BCM2708: Add 24 bit support This adds 24 bit support to the I2S driver of the BCM2708. Besides enabling the 24 bit flags, it includes two bug fixes: @@ -110569,13 +110569,13 @@ index ebaf3d6..a179216 100644 .period_bytes_min = 32, .period_bytes_max = 64 * PAGE_SIZE, -- -2.0.3 +2.0.4 From e0716a7fa7874757ff01fac80f62e8c99a56f33c Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 2 Dec 2013 20:28:22 +0100 -Subject: [PATCH 38/73] BCM2708: Add I2S and DMA support to default config +Subject: [PATCH 38/77] BCM2708: Add I2S and DMA support to default config This commit adds several modules that are needed for I2S support for the Raspberry Pi to the defconfig. @@ -110615,13 +110615,13 @@ index 0c58172..38ccd22 100644 CONFIG_UIO_PDRV_GENIRQ=m CONFIG_STAGING=y -- -2.0.3 +2.0.4 From 0b2d13950ced9de365af93a96912f8e55271ecf0 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 39/73] ASoC: BCM2708: Add support for RPi-DAC +Subject: [PATCH 39/77] ASoC: BCM2708: Add support for RPi-DAC This adds a machine driver for the RPi-DAC. @@ -110932,13 +110932,13 @@ index 0000000..b4eaa44 +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 66f98a8406804e24ff9fa194ee21a9b961a53b98 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 40/73] ASoC: wm8804: Implement MCLK configuration options, add +Subject: [PATCH 40/77] 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 @@ -110978,13 +110978,13 @@ index d96e5963..9a7a289 100644 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ -- -2.0.3 +2.0.4 From 9903287696cc4f5c070587dd46b2554a3ea771f6 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 41/73] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 41/77] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -111187,13 +111187,13 @@ index 0000000..e4f769d +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 9089eb1c8089f27f0d825594aca55203fe4c2b33 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 42/73] BCM2708: Added support for HiFiBerry Digi board Board +Subject: [PATCH 42/77] BCM2708: Added support for HiFiBerry Digi board Board initalization by I2C Signed-off-by: Daniel Matuschek @@ -111240,13 +111240,13 @@ index 238f165..139045b 100644 bcm_register_device(&snd_rpi_dac_device); bcm_register_device(&snd_pcm1794a_codec_device); -- -2.0.3 +2.0.4 From 2ccbdf72d828bd288256a23e79fa2e660bea9599 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:27:28 +0100 -Subject: [PATCH 43/73] BCM2708: Added HiFiBerry Digi configuration option It +Subject: [PATCH 43/77] BCM2708: Added HiFiBerry Digi configuration option It will be compiled as a module by default. This also includes the WM8804 driver. @@ -111271,13 +111271,13 @@ index 5e049f9..4f6bb90 100644 CONFIG_SND_SOC_I2C_AND_SPI=m CONFIG_SND_SOC_PCM5102A=m -- -2.0.3 +2.0.4 From 8ca488553ca04a621fbee224210872ca64afc55f Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 44/73] ASoC: wm8804: Set idle_bias_off to false Idle bias has +Subject: [PATCH 44/77] ASoC: wm8804: Set idle_bias_off to false Idle bias has been change to remove warning on driver startup Signed-off-by: Daniel Matuschek @@ -111299,13 +111299,13 @@ index 9a7a289..32e199a 100644 .controls = wm8804_snd_controls, .num_controls = ARRAY_SIZE(wm8804_snd_controls), -- -2.0.3 +2.0.4 From 658a1d669499b55d8e733ccb470a003e78149e99 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 12 Mar 2014 11:46:34 +0000 -Subject: [PATCH 45/73] ASoc: Don't report S24_LE support, it produces white +Subject: [PATCH 45/77] ASoc: Don't report S24_LE support, it produces white noise with xbmc --- @@ -111340,13 +111340,13 @@ index 126f1e9..7812d34 100644 }, }; -- -2.0.3 +2.0.4 From 5917c8011a856aa57802508ec7df1ec093ae7553 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 46/73] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 46/77] Add IQaudIO Sound Card support for Raspberry Pi --- arch/arm/configs/bcmrpi_defconfig | 1 + @@ -111556,13 +111556,13 @@ index 0000000..8d0e2ae +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 603b762a6a41f0549462638f4f10d6c82f11d3f1 Mon Sep 17 00:00:00 2001 From: Howard Mitchell Date: Wed, 30 Jul 2014 21:43:37 +0100 -Subject: [PATCH 47/73] soc-core: Fix volsw_range funcs so +Subject: [PATCH 47/77] soc-core: Fix volsw_range funcs so SOC_DOUBLE_R_RANGE_TLV works. This is so that the correct range of values as specified @@ -111636,13 +111636,13 @@ index b87d7d8..1f3d03e 100644 return 0; -- -2.0.3 +2.0.4 From 0b5178b68d7c9f41e0b7fa8eb5e2459d1ef80ebd Mon Sep 17 00:00:00 2001 From: Howard Mitchell Date: Fri, 28 Mar 2014 16:40:31 +0000 -Subject: [PATCH 48/73] pcm512x: Use a range macro for Volume and rename to +Subject: [PATCH 48/77] pcm512x: Use a range macro for Volume and rename to PCM. This allows limiting the output gain to avoid clipping in the @@ -111667,13 +111667,13 @@ index 163ec38..1466955 100644 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, -- -2.0.3 +2.0.4 From b37fad9a65a4e62657fdecb1d5b62b9dd510be90 Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Fri, 2 May 2014 16:13:59 +0100 -Subject: [PATCH 49/73] Move GPIO setup to hw_params. +Subject: [PATCH 49/77] Move GPIO setup to hw_params. This is used to stop the I2S driver from breaking the GPIO setup for other uses of the PCM interface @@ -111769,13 +111769,13 @@ index b25e158..9976571 100644 dev->clk_regmap = regmap[1]; -- -2.0.3 +2.0.4 From e5fb8a6be0d14cadcfb602bf22ea8719088c0053 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 50/73] vmstat: Workaround for issue where dirty page count +Subject: [PATCH 50/77] vmstat: Workaround for issue where dirty page count goes negative See: @@ -111802,13 +111802,13 @@ index 82e7db7..f87d16d 100644 static inline void __inc_zone_page_state(struct page *page, -- -2.0.3 +2.0.4 From ab1b06e206515b2a67e2392aed9a3f87c447fd1a Mon Sep 17 00:00:00 2001 From: P33M Date: Fri, 20 Jun 2014 16:03:12 +0100 -Subject: [PATCH 51/73] dwc_otg: Fix various issues with root port and +Subject: [PATCH 51/77] dwc_otg: Fix various issues with root port and transaction errors Process the host port interrupts correctly (and don't trample them). @@ -111878,13 +111878,13 @@ index d3e2035..6182d3e 100644 fiq_print(FIQDBG_ERR, dwc_otg_hcd->fiq_state, "RESET "); } -- -2.0.3 +2.0.4 From 8a3691d7d3bcefd262cdc2c176cf03c8bbcbf58e Mon Sep 17 00:00:00 2001 From: P33M Date: Fri, 20 Jun 2014 17:23:20 +0100 -Subject: [PATCH 52/73] fiq_fsm: Implement hack for Split Interrupt +Subject: [PATCH 52/77] fiq_fsm: Implement hack for Split Interrupt transactions Hubs aren't too picky about which endpoint we send Control type split @@ -111970,13 +111970,13 @@ index daea770..35721e5 100644 break; } -- -2.0.3 +2.0.4 From a308c1b04aa2590538f3929459464751af4b1afe Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 6 Jul 2014 12:07:25 +0200 -Subject: [PATCH 53/73] spi-bcm2708: Prepare for Common Clock Framework +Subject: [PATCH 53/77] spi-bcm2708: Prepare for Common Clock Framework migration As part of migrating to use the Common Clock Framework, replace clk_enable() @@ -112021,13 +112021,13 @@ index b04a57d..349d21f 100644 free_irq(bs->irq, master); iounmap(bs->base); -- -2.0.3 +2.0.4 From f55cc5f0ad7922b97e46bc594bdf420db2982b04 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 6 Jul 2014 12:09:30 +0200 -Subject: [PATCH 54/73] BCM2708: Migrate to the Common Clock Framework +Subject: [PATCH 54/77] BCM2708: Migrate to the Common Clock Framework As part of moving towards using Device Tree, the Common Clock Framework has to be used instead of the BCM2708 clock implementation. @@ -112297,13 +112297,13 @@ index 5f9d725..0000000 - unsigned long rate; -}; -- -2.0.3 +2.0.4 From 79bacbe9b2bc3aa5742e5e636d8750c57bd4abf7 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 55/73] BCM2708: Add core Device Tree support +Subject: [PATCH 55/77] BCM2708: Add core Device Tree support Add the bare minimum needed to boot BCM2708 from a Device Tree. @@ -112460,13 +112460,13 @@ index 674e5aa..83277d1f 100644 module_param(boardrev, uint, 0644); -- -2.0.3 +2.0.4 From 504175cf2dab09ee2d3a38abda8cd14e946d9a8d Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:47:48 +0200 -Subject: [PATCH 56/73] BCM2708: armctrl: Add IRQ Device Tree support +Subject: [PATCH 56/77] BCM2708: armctrl: Add IRQ Device Tree support Add Device Tree IRQ support for BCM2708. Usage is the same as for irq-bcm2835. @@ -112630,13 +112630,13 @@ index d4c5333..42f5e1c 100644 return 0; } -- -2.0.3 +2.0.4 From 4440f7a92619e12940a7e27f080d11064dc5cc93 Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 57/73] pinctrl: add bcm2708 driver +Subject: [PATCH 57/77] pinctrl: add bcm2708 driver This driver is a verbatim copy of the pinctrl-bcm2835 driver, except for: * changed 2835 to 2708 @@ -113499,13 +113499,13 @@ index 0000000..40d9c86 +MODULE_DESCRIPTION("BCM2708 Pin control driver"); +MODULE_LICENSE("GPL"); -- -2.0.3 +2.0.4 From bef9a66a1a4e952c7d07bf03aa143ed629510152 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 58/73] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 58/77] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -113541,13 +113541,13 @@ index 7b88f4c..016a485 100644 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -- -2.0.3 +2.0.4 From 4a71b12cde3193dbe01492f2f9edff796f2af095 Mon Sep 17 00:00:00 2001 From: notro Date: Fri, 18 Jul 2014 18:15:57 +0200 -Subject: [PATCH 59/73] BCM2708: DT: change 'axi' nodename to 'soc' +Subject: [PATCH 59/77] BCM2708: DT: change 'axi' nodename to 'soc' Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835. The VC4 bootloader fills in certain properties in the 'axi' subtree, @@ -113572,13 +113572,13 @@ index 3f884b3..e02e67b 100644 #address-cells = <1>; #size-cells = <1>; -- -2.0.3 +2.0.4 From e6c0c0c84ded234045eadb9405266010392b4124 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 27 Jul 2014 20:12:58 +0200 -Subject: [PATCH 60/73] spi: bcm2708: add device tree support +Subject: [PATCH 60/77] spi: bcm2708: add device tree support Add DT support to driver and add to .dtsi file. Setup pins and spidev in .dts file. @@ -113697,13 +113697,13 @@ index 349d21f..041b5e2 100644 .probe = bcm2708_spi_probe, .remove = bcm2708_spi_remove, -- -2.0.3 +2.0.4 From bac8143ba837822fe0038a809e23a5c517533c57 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 27 Jul 2014 20:13:44 +0200 -Subject: [PATCH 61/73] BCM2708: don't register SPI controller when using DT +Subject: [PATCH 61/77] BCM2708: don't register SPI controller when using DT The device for the SPI controller is in the Device Tree. Only register the device when not using DT. @@ -113774,13 +113774,13 @@ index 83277d1f..a4286e9 100644 bcm_register_device(&bcm2708_bsc1_device); -- -2.0.3 +2.0.4 From 9ed17623b1346dddcf60f50a5c11eccd77a1d907 Mon Sep 17 00:00:00 2001 From: notro Date: Sun, 27 Jul 2014 20:14:05 +0200 -Subject: [PATCH 62/73] spi: bcm2835: make driver available on ARCH_BCM2708 +Subject: [PATCH 62/77] spi: bcm2835: make driver available on ARCH_BCM2708 Make this driver available on ARCH_BCM2708 @@ -113803,13 +113803,13 @@ index cb20594..54aac0f 100644 This selects a driver for the Broadcom BCM2835 SPI master. -- -2.0.3 +2.0.4 From 4436b5c4aaa78ab523807228efb9e69dcd13837b Mon Sep 17 00:00:00 2001 From: notro Date: Tue, 29 Jul 2014 11:04:49 +0200 -Subject: [PATCH 63/73] i2c: bcm2708: add device tree support +Subject: [PATCH 63/77] i2c: bcm2708: add device tree support Add DT support to driver and add to .dtsi file. Setup pins in .dts file. @@ -113974,13 +113974,13 @@ index 8750634..728cb69 100644 .probe = bcm2708_i2c_probe, .remove = bcm2708_i2c_remove, -- -2.0.3 +2.0.4 From f32f8d0cc79649f78d6b0d60482af0c0cc7fe53e Mon Sep 17 00:00:00 2001 From: notro Date: Tue, 29 Jul 2014 11:05:18 +0200 -Subject: [PATCH 64/73] bcm2708: don't register i2c controllers when using DT +Subject: [PATCH 64/77] bcm2708: don't register i2c controllers when using DT The devices for the i2c controllers are in the Device Tree. Only register devices when not using DT. @@ -114022,13 +114022,13 @@ index a4286e9..a19f54d 100644 bcm_register_device(&bcm2835_hwmon_device); bcm_register_device(&bcm2835_thermal_device); -- -2.0.3 +2.0.4 From 79e54a26c2c8c34bdae2fe2e38670479643e008e Mon Sep 17 00:00:00 2001 From: notro Date: Tue, 29 Jul 2014 11:05:39 +0200 -Subject: [PATCH 65/73] i2c: bcm2835: make driver available on ARCH_BCM2708 +Subject: [PATCH 65/77] i2c: bcm2835: make driver available on ARCH_BCM2708 Make this driver available on ARCH_BCM2708 @@ -114051,13 +114051,13 @@ index 6426811..73c9cfd 100644 If you say yes to this option, support will be included for the BCM2835 I2C controller. -- -2.0.3 +2.0.4 From b4b7637c58d49afd88e39a7a02b99d3b87fb0feb Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Fri, 25 Jul 2014 07:08:09 +0200 -Subject: [PATCH 66/73] Configure GPIOs for I2S based on revision/card settings +Subject: [PATCH 66/77] Configure GPIOs for I2S based on revision/card settings With RPi model B+, assignment of the I2S GPIO pins has changed. This patch uses the board revision to auto-detect the GPIOs used @@ -114212,13 +114212,13 @@ index 0000000..94fed6a + +#endif -- -2.0.3 +2.0.4 From ccc6d36d045acb40043635bd123924ec0a470920 Mon Sep 17 00:00:00 2001 From: P33M Date: Thu, 24 Jul 2014 21:24:03 +0100 -Subject: [PATCH 67/73] usb: core: make overcurrent messages more prominent +Subject: [PATCH 67/77] usb: core: make overcurrent messages more prominent Hub overcurrent messages are more serious than "debug". Increase loglevel. --- @@ -114239,13 +114239,13 @@ index 0e950ad..6b004cf 100644 USB_PORT_FEAT_C_OVER_CURRENT); msleep(100); /* Cool down */ -- -2.0.3 +2.0.4 From ff963183dca11df32ba8ef1c1bfbb732f07a50a8 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 68/73] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 68/77] 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 @@ -118578,13 +118578,13 @@ index 0000000..da1c523 +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 From 0765c9fb777f1b40097b74bbaf1944920ceae0d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 7 Aug 2014 02:03:50 +0100 -Subject: [PATCH 69/73] Revert "ARM: dma: Use dma_pfn_offset for dma address +Subject: [PATCH 69/77] Revert "ARM: dma: Use dma_pfn_offset for dma address translation" This reverts commit 6ce0d20016925d031f1e24d64302e4c976d7cec6. @@ -118636,13 +118636,13 @@ index c45b61a..0af6bd0 100644 } -- -2.0.3 +2.0.4 From e9e133a3ad8d0946a687a3fc0c10aa7648952486 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 8 Aug 2014 16:22:59 +0100 -Subject: [PATCH 70/73] VCHIQ: Make service closure fully synchronous (drv) +Subject: [PATCH 70/77] VCHIQ: Make service closure fully synchronous (drv) This is one half of a two-part patch, the other half of which is to the vchiq_lib user library. With these patches, calls to @@ -118991,118 +118991,22 @@ index e248037..6137ae9 100644 #endif -- -2.0.3 +2.0.4 -From 33f49e8bf532404304798189d98393f6b2b055df Mon Sep 17 00:00:00 2001 +From a3d776fb4bd5f334b87ce1959dfc6a1ff61b1717 Mon Sep 17 00:00:00 2001 From: gellert -Date: Fri, 15 Aug 2014 15:24:58 +0100 -Subject: [PATCH 71/73] Add new bcm2835_mmc (sdcard) driver and dma driver +Date: Tue, 29 Jul 2014 17:43:37 +0100 +Subject: [PATCH 71/77] dmaengine: expand functionality by supporting + scatter/gather transfers sdhci-bcm2708 and dma.c: fix for LITE channels -Enable with bcm2708.bcm2835_mmc=1 --- - arch/arm/configs/bcmrpi_defconfig | 7 +- - arch/arm/mach-bcm2708/bcm2708.c | 35 +- - arch/arm/mach-bcm2708/dma.c | 2 + - arch/arm/mach-bcm2708/include/mach/dma.h | 6 +- - drivers/dma/bcm2708-dmaengine.c | 729 +++++++++++--- - drivers/mmc/host/Kconfig | 29 + - drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1537 ++++++++++++++++++++++++++++++ - drivers/mmc/host/sdhci-bcm2708.c | 116 ++- - 9 files changed, 2275 insertions(+), 187 deletions(-) - create mode 100644 drivers/mmc/host/bcm2835-mmc.c + arch/arm/mach-bcm2708/dma.c | 2 + + arch/arm/mach-bcm2708/include/mach/dma.h | 6 +- + drivers/dma/bcm2708-dmaengine.c | 731 +++++++++++++++++++++++++------ + drivers/mmc/host/sdhci-bcm2708.c | 113 +++-- + 4 files changed, 667 insertions(+), 185 deletions(-) -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 105bcbe..d0f0781 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -894,6 +894,9 @@ CONFIG_USB_ISIGHTFW=m - CONFIG_USB_YUREX=m - CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_PIO_DMA_BARRIER=2 - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2708=y -@@ -944,9 +947,9 @@ CONFIG_RTC_DRV_DS3234=m - CONFIG_RTC_DRV_PCF2123=m - CONFIG_RTC_DRV_RX4581=m - CONFIG_DMADEVICES=y --CONFIG_DMA_BCM2708=m -+CONFIG_DMA_BCM2708=y - CONFIG_DMA_ENGINE=y --CONFIG_DMA_VIRTUAL_CHANNELS=m -+CONFIG_DMA_VIRTUAL_CHANNELS=y - CONFIG_UIO=m - CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a19f54d..a730d5d 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -92,6 +92,7 @@ static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; -+static unsigned bcm2835_mmc = 0; - - static void __init bcm2708_init_led(void); - -@@ -442,6 +443,34 @@ struct platform_device bcm2708_emmc_device = { - }; - #endif /* CONFIG_MMC_SDHCI_BCM2708 */ - -+#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ -+static struct resource bcm2835_emmc_resources[] = { -+ [0] = { -+ .start = EMMC_BASE, -+ .end = EMMC_BASE + SZ_256 - 1, /* we only need this area */ -+ /* the memory map actually makes SZ_4K available */ -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = IRQ_ARASANSDIO, -+ .end = IRQ_ARASANSDIO, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 bcm2835_emmc_dmamask = 0xffffffffUL; -+ -+struct platform_device bcm2835_emmc_device = { -+ .name = "mmc-bcm2835", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), -+ .resource = bcm2835_emmc_resources, -+ .dev = { -+ .dma_mask = &bcm2835_emmc_dmamask, -+ .coherent_dma_mask = 0xffffffffUL}, -+}; -+#endif /* CONFIG_MMC_BCM2835 */ -+ - static struct resource bcm2708_powerman_resources[] = { - [0] = { - .start = PM_BASE, -@@ -823,7 +852,10 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_SDHCI_BCM2708 -- bcm_register_device(&bcm2708_emmc_device); -+ if (!bcm2835_mmc) bcm_register_device(&bcm2708_emmc_device); -+#endif -+#ifdef CONFIG_MMC_BCM2835 -+ if (bcm2835_mmc) bcm_register_device(&bcm2835_emmc_device); - #endif - bcm2708_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -@@ -1053,3 +1085,4 @@ module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); - module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); -+module_param(bcm2835_mmc, uint, 0644); diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c index 1da2413..a5e58d1 100644 --- a/arch/arm/mach-bcm2708/dma.c @@ -119136,7 +119040,7 @@ index a4aac4c..d03e7b5 100644 /* return channel no or -ve error */ extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index b244293..b4c6cce 100644 +index b244293..8996125 100644 --- a/drivers/dma/bcm2708-dmaengine.c +++ b/drivers/dma/bcm2708-dmaengine.c @@ -1,11 +1,11 @@ @@ -119163,7 +119067,7 @@ index b244293..b4c6cce 100644 #include #include #include -@@ -40,21 +41,38 @@ +@@ -40,21 +41,40 @@ #include #include #include @@ -119177,6 +119081,8 @@ index b244293..b4c6cce 100644 -#include -struct bcm2708_dmadev { ++//#define DMA_COMPLETE DMA_SUCCESS ++ +#endif + +#include @@ -119207,7 +119113,7 @@ index b244293..b4c6cce 100644 struct virt_dma_chan vc; struct list_head node; -@@ -62,48 +80,105 @@ struct bcm2708_chan { +@@ -62,48 +82,106 @@ struct bcm2708_chan { bool cyclic; int ch; @@ -119255,18 +119161,19 @@ index b244293..b4c6cce 100644 +#define BCM2835_DMA_RESET BIT(31) /* WO, self clearing */ + +#define BCM2835_DMA_INT_EN BIT(0) ++#define BCM2835_DMA_WAIT_RESP BIT(3) +#define BCM2835_DMA_D_INC BIT(4) +#define BCM2835_DMA_D_WIDTH BIT(5) +#define BCM2835_DMA_D_DREQ BIT(6) +#define BCM2835_DMA_S_INC BIT(8) +#define BCM2835_DMA_S_WIDTH BIT(9) +#define BCM2835_DMA_S_DREQ BIT(10) -+ -+#define BCM2835_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2835_DMA_WAITS(x) (((x)&0x1f) << 21) -static inline struct bcm2708_dmadev *to_bcm2708_dma_dev(struct dma_device *d) -+#define SDHCI_BCM_DMA_WAITS 30 /* delays slowing DMA transfers: 0-31 */ ++#define BCM2835_DMA_PER_MAP(x) ((x) << 16) ++#define BCM2835_DMA_WAITS(x) (((x)&0x1f) << 21) ++ ++#define SDHCI_BCM_DMA_WAITS 0 /* delays slowing DMA transfers: 0-31 */ + +#define BCM2835_DMA_DATA_TYPE_S8 1 +#define BCM2835_DMA_DATA_TYPE_S16 2 @@ -119329,7 +119236,7 @@ index b244293..b4c6cce 100644 dma_free_coherent(desc->vd.tx.chan->device->dev, desc->control_block_size, desc->control_block_base, -@@ -111,10 +186,46 @@ static void bcm2708_dma_desc_free(struct virt_dma_desc *vd) +@@ -111,10 +189,46 @@ static void bcm2708_dma_desc_free(struct virt_dma_desc *vd) kfree(desc); } @@ -119378,7 +119285,7 @@ index b244293..b4c6cce 100644 if (!vd) { c->desc = NULL; -@@ -123,49 +234,62 @@ static void bcm2708_dma_start_desc(struct bcm2708_chan *c) +@@ -123,49 +237,62 @@ static void bcm2708_dma_start_desc(struct bcm2708_chan *c) list_del(&vd->node); @@ -119414,14 +119321,14 @@ index b244293..b4c6cce 100644 - } + if (c->cyclic) { + vchan_cyclic_callback(&d->vd); -+ -+ /* Keep the DMA engine running */ -+ writel(BCM2835_DMA_ACTIVE, -+ c->chan_base + BCM2835_DMA_CS); - /* Keep the DMA engine running */ - dsb(); /* ARM synchronization barrier */ - writel(BCM2708_DMA_ACTIVE, c->chan_base + BCM2708_DMA_CS); ++ /* Keep the DMA engine running */ ++ writel(BCM2835_DMA_ACTIVE, ++ c->chan_base + BCM2835_DMA_CS); ++ + } else { + vchan_cookie_complete(&c->desc->vd); + bcm2835_dma_start_desc(c); @@ -119442,12 +119349,12 @@ index b244293..b4c6cce 100644 + + dev_dbg(c->vc.chan.device->dev, + "Allocating DMA channel %d\n", c->ch); ++ ++ ret = request_irq(c->irq_number, ++ bcm2835_dma_callback, 0, "DMA IRQ", c); - return request_irq(c->irq_number, - bcm2708_dma_callback, 0, "DMA IRQ", c); -+ ret = request_irq(c->irq_number, -+ bcm2835_dma_callback, 0, "DMA IRQ", c); -+ + return ret; } @@ -119459,7 +119366,7 @@ index b244293..b4c6cce 100644 vchan_free_chan_resources(&c->vc); free_irq(c->irq_number, c); -@@ -173,18 +297,18 @@ static void bcm2708_dma_free_chan_resources(struct dma_chan *chan) +@@ -173,18 +300,18 @@ static void bcm2708_dma_free_chan_resources(struct dma_chan *chan) dev_dbg(c->vc.chan.device->dev, "Freeing DMA channel %u\n", c->ch); } @@ -119482,7 +119389,7 @@ index b244293..b4c6cce 100644 &d->control_block_base[i]; size_t this_size = control_block->length; dma_addr_t dma; -@@ -203,13 +327,15 @@ static size_t bcm2708_dma_desc_size_pos(struct bcm2708_desc *d, dma_addr_t addr) +@@ -203,13 +330,15 @@ static size_t bcm2708_dma_desc_size_pos(struct bcm2708_desc *d, dma_addr_t addr) return size; } @@ -119500,7 +119407,7 @@ index b244293..b4c6cce 100644 ret = dma_cookie_status(chan, cookie, txstate); if (ret == DMA_COMPLETE || !txstate) -@@ -219,19 +345,18 @@ static enum dma_status bcm2708_dma_tx_status(struct dma_chan *chan, +@@ -219,19 +348,18 @@ static enum dma_status bcm2708_dma_tx_status(struct dma_chan *chan, vd = vchan_find_desc(&c->vc, cookie); if (vd) { txstate->residue = @@ -119525,7 +119432,7 @@ index b244293..b4c6cce 100644 } else { txstate->residue = 0; } -@@ -241,50 +366,50 @@ static enum dma_status bcm2708_dma_tx_status(struct dma_chan *chan, +@@ -241,50 +369,50 @@ static enum dma_status bcm2708_dma_tx_status(struct dma_chan *chan, return ret; } @@ -119593,7 +119500,7 @@ index b244293..b4c6cce 100644 break; default: return NULL; -@@ -299,7 +424,7 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( +@@ -299,7 +427,7 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( d->frames = buf_len / period_len; /* Allocate memory for control blocks */ @@ -119602,7 +119509,7 @@ index b244293..b4c6cce 100644 d->control_block_base = dma_zalloc_coherent(chan->device->dev, d->control_block_size, &d->control_block_base_phys, GFP_NOWAIT); -@@ -314,22 +439,22 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( +@@ -314,22 +442,22 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( * for each frame and link them together. */ for (frame = 0; frame < d->frames; frame++) { @@ -119629,7 +119536,7 @@ index b244293..b4c6cce 100644 /* Setup synchronization */ if (sync_type != 0) -@@ -338,7 +463,7 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( +@@ -338,7 +466,7 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( /* Setup DREQ channel */ if (c->cfg.slave_id != 0) control_block->info |= @@ -119638,7 +119545,7 @@ index b244293..b4c6cce 100644 /* Length of a frame */ control_block->length = period_len; -@@ -346,18 +471,166 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( +@@ -346,18 +474,166 @@ static struct dma_async_tx_descriptor *bcm2708_dma_prep_dma_cyclic( /* * Next block is the next frame. @@ -119742,8 +119649,7 @@ index b244293..b4c6cce 100644 + dma_addr_t addr = sg_dma_address(sgent); + uint32_t len = sg_dma_len(sgent); + -+ for (j = 0; jcontrol_block_base[i+splitct]; + @@ -119762,9 +119668,10 @@ index b244293..b4c6cce 100644 + + /* Common part */ + control_block->info |= BCM2835_DMA_WAITS(SDHCI_BCM_DMA_WAITS); ++ control_block->info |= BCM2835_DMA_WAIT_RESP; + + /* Enable */ -+ if (i == sg_len-1 && len-j<=max_size) ++ if (i == sg_len-1 && len-j <= max_size) + control_block->info |= BCM2835_DMA_INT_EN; + + /* Setup synchronization */ @@ -119785,7 +119692,7 @@ index b244293..b4c6cce 100644 + /* + * Next block is the next frame. + */ -+ if (i < sg_len-1 || len-j>max_size) { ++ if (i < sg_len-1 || len-j > max_size) { + /* next block is the next frame. */ + control_block->next = d->control_block_base_phys + + sizeof(struct bcm2835_dma_cb) * (i + splitct + 1); @@ -119794,7 +119701,7 @@ index b244293..b4c6cce 100644 + control_block->next = 0; + } + -+ if (len-j>max_size) ++ if (len-j > max_size) + splitct++; + } + } @@ -119808,7 +119715,7 @@ index b244293..b4c6cce 100644 struct dma_slave_config *cfg) { if ((cfg->direction == DMA_DEV_TO_MEM && -@@ -373,9 +646,9 @@ static int bcm2708_dma_slave_config(struct bcm2708_chan *c, +@@ -373,9 +649,9 @@ static int bcm2708_dma_slave_config(struct bcm2708_chan *c, return 0; } @@ -119820,7 +119727,7 @@ index b244293..b4c6cce 100644 unsigned long flags; int timeout = 10000; LIST_HEAD(head); -@@ -394,19 +667,18 @@ static int bcm2708_dma_terminate_all(struct bcm2708_chan *c) +@@ -394,19 +670,18 @@ static int bcm2708_dma_terminate_all(struct bcm2708_chan *c) */ if (c->desc) { c->desc = NULL; @@ -119845,7 +119752,7 @@ index b244293..b4c6cce 100644 dev_err(d->ddev.dev, "DMA transfer could not be terminated\n"); } -@@ -417,34 +689,57 @@ static int bcm2708_dma_terminate_all(struct bcm2708_chan *c) +@@ -417,34 +692,57 @@ static int bcm2708_dma_terminate_all(struct bcm2708_chan *c) return 0; } @@ -119911,7 +119818,7 @@ index b244293..b4c6cce 100644 vchan_init(&c->vc, &d->ddev); INIT_LIST_HEAD(&c->node); -@@ -457,30 +752,81 @@ static int bcm2708_dma_chan_init(struct bcm2708_dmadev *d, void __iomem* chan_ba +@@ -457,30 +755,81 @@ static int bcm2708_dma_chan_init(struct bcm2708_dmadev *d, void __iomem* chan_ba return 0; } @@ -119941,9 +119848,7 @@ index b244293..b4c6cce 100644 +#ifdef CONFIG_OF +static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, + struct of_dma *ofdma) - { -- struct bcm2708_dmadev *od; -- int rc, i; ++{ + struct bcm2835_dmadev *d = ofdma->of_dma_data; + struct dma_chan *chan; + @@ -119960,7 +119865,9 @@ index b244293..b4c6cce 100644 + +static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan, + struct dma_slave_caps *caps) -+{ + { +- struct bcm2708_dmadev *od; +- int rc, i; + caps->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + caps->dstn_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); @@ -120000,7 +119907,7 @@ index b244293..b4c6cce 100644 od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL); if (!od) return -ENOMEM; -@@ -488,25 +834,29 @@ static int bcm2708_dma_probe(struct platform_device *pdev) +@@ -488,25 +837,29 @@ static int bcm2708_dma_probe(struct platform_device *pdev) pdev->dev.dma_parms = &od->dma_parms; dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); @@ -120040,7 +119947,7 @@ index b244293..b4c6cce 100644 &chan_base, &irq); -@@ -514,38 +864,121 @@ static int bcm2708_dma_probe(struct platform_device *pdev) +@@ -514,38 +867,121 @@ static int bcm2708_dma_probe(struct platform_device *pdev) break; rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq); @@ -120174,7 +120081,7 @@ index b244293..b4c6cce 100644 .driver = { .name = "bcm2708-dmaengine", .owner = THIS_MODULE, -@@ -554,35 +987,57 @@ static struct platform_driver bcm2708_dma_driver = { +@@ -554,35 +990,52 @@ static struct platform_driver bcm2708_dma_driver = { static struct platform_device *pdev; @@ -120214,12 +120121,6 @@ index b244293..b4c6cce 100644 } -module_exit(bcm2708_dma_exit); +module_exit(bcm2835_dma_exit); - - MODULE_ALIAS("platform:bcm2708-dma"); - MODULE_DESCRIPTION("BCM2708 DMA engine driver"); - MODULE_AUTHOR("Florian Meier "); - MODULE_LICENSE("GPL v2"); -+ + +#else + @@ -120235,14 +120136,246 @@ index b244293..b4c6cce 100644 + +module_platform_driver(bcm2835_dma_driver); + ++#endif + +-MODULE_ALIAS("platform:bcm2708-dma"); +-MODULE_DESCRIPTION("BCM2708 DMA engine driver"); +MODULE_ALIAS("platform:bcm2835-dma"); +MODULE_DESCRIPTION("BCM2835 DMA engine driver"); + MODULE_AUTHOR("Florian Meier "); +MODULE_AUTHOR("Gellert Weisz "); -+MODULE_LICENSE("GPL v2"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index 6e777f4..15445215 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -69,6 +69,9 @@ + #define DMA_SDHCI_BASE 0x7e300000 /* EMMC register block on Videocore */ + #define DMA_SDHCI_BUFFER (DMA_SDHCI_BASE + SDHCI_BUFFER) + ++#define MAX_LITE_TRANSFER 32768 ++#define MAX_NORMAL_TRANSFER 1073741824 + + #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ + + /* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */ +@@ -444,29 +447,39 @@ static void schci_bcm2708_cb_read(struct sdhci_bcm2708_priv *host, + dma_addr_t dma_addr, unsigned len, + int /*bool*/ is_last) + { +- struct bcm2708_dma_cb *cb = &host->cb_base[ix]; +- unsigned char dmawaits = host->dma_waits; +- +- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | +- BCM2708_DMA_WAITS(dmawaits) | +- BCM2708_DMA_S_DREQ | +- BCM2708_DMA_D_WIDTH | +- BCM2708_DMA_D_INC; +- cb->src = DMA_SDHCI_BUFFER; /* DATA register DMA address */ +- cb->dst = dma_addr; +- cb->length = len; +- cb->stride = 0; +- +- if (is_last) { +- cb->info |= BCM2708_DMA_INT_EN | +- BCM2708_DMA_WAIT_RESP; +- cb->next = 0; +- } else +- cb->next = host->cb_handle + +- (ix+1)*sizeof(struct bcm2708_dma_cb); ++ struct bcm2708_dma_cb *cb; ++ unsigned char dmawaits = host->dma_waits; ++ unsigned i, max_size; + +- cb->pad[0] = 0; +- cb->pad[1] = 0; ++ if (host->dma_chan >= 8) /* we have a LITE channel */ ++ max_size = MAX_LITE_TRANSFER; ++ else ++ max_size = MAX_NORMAL_TRANSFER; ++ ++ for (i = 0; i < len; i += max_size) { ++ cb = &host->cb_base[ix+i/max_size]; ++ ++ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | ++ BCM2708_DMA_WAITS(dmawaits) | ++ BCM2708_DMA_WAIT_RESP | ++ BCM2708_DMA_S_DREQ | ++ BCM2708_DMA_D_WIDTH | ++ BCM2708_DMA_D_INC; ++ cb->src = DMA_SDHCI_BUFFER; /* DATA register DMA address */ ++ cb->dst = dma_addr + (dma_addr_t)i; ++ cb->length = min(len-i, max_size); ++ cb->stride = 0; ++ ++ if (is_last && len-i <= max_size) { ++ cb->info |= BCM2708_DMA_INT_EN; ++ cb->next = 0; ++ } else ++ cb->next = host->cb_handle + ++ (ix+1 + i/max_size)*sizeof(struct bcm2708_dma_cb); ++ ++ cb->pad[0] = 0; ++ cb->pad[1] = 0; ++ } + } + + static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host, +@@ -475,30 +488,42 @@ static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host, + int /*bool*/ is_last) + { + struct bcm2708_dma_cb *cb = &host->cb_base[ix]; +- unsigned char dmawaits = host->dma_waits; ++ unsigned char dmawaits = host->dma_waits; ++ unsigned i, max_size; ++ ++ if (host->dma_chan >= 8) /* we have a LITE channel */ ++ max_size = MAX_LITE_TRANSFER; ++ else ++ max_size = MAX_NORMAL_TRANSFER; + + /* We can make arbitrarily large writes as long as we specify DREQ to +- pace the delivery of bytes to the Arasan hardware */ +- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | +- BCM2708_DMA_WAITS(dmawaits) | +- BCM2708_DMA_D_DREQ | +- BCM2708_DMA_S_WIDTH | +- BCM2708_DMA_S_INC; +- cb->src = dma_addr; +- cb->dst = DMA_SDHCI_BUFFER; /* DATA register DMA address */ +- cb->length = len; +- cb->stride = 0; +- +- if (is_last) { +- cb->info |= BCM2708_DMA_INT_EN | +- BCM2708_DMA_WAIT_RESP; +- cb->next = 0; +- } else +- cb->next = host->cb_handle + +- (ix+1)*sizeof(struct bcm2708_dma_cb); ++ pace the delivery of bytes to the Arasan hardware. However we need ++ to take care when using LITE channels */ ++ ++ for (i = 0; i < len; i += max_size) { ++ cb = &host->cb_base[ix+i/max_size]; ++ ++ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | ++ BCM2708_DMA_WAITS(dmawaits) | ++ BCM2708_DMA_WAIT_RESP | ++ BCM2708_DMA_D_DREQ | ++ BCM2708_DMA_S_WIDTH | ++ BCM2708_DMA_S_INC; ++ cb->src = dma_addr + (dma_addr_t)i; ++ cb->dst = DMA_SDHCI_BUFFER; /* DATA register DMA address */ ++ cb->length = min(len-i, max_size); ++ cb->stride = 0; ++ ++ if (is_last && len-i <= max_size) { ++ cb->info |= BCM2708_DMA_INT_EN; ++ cb->next = 0; ++ } else ++ cb->next = host->cb_handle + ++ (ix+1 + i/max_size)*sizeof(struct bcm2708_dma_cb); + +- cb->pad[0] = 0; +- cb->pad[1] = 0; ++ cb->pad[0] = 0; ++ cb->pad[1] = 0; ++ } + } + + +@@ -1390,5 +1415,3 @@ MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock"); + MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete"); + MODULE_PARM_DESC(missing_status, "Use the missing status quirk"); + MODULE_PARM_DESC(extra_messages, "Enable more sdcard warning messages"); +- +- +-- +2.0.4 + + +From 8988c7b87776c0335fe4df0634c686eec94e7353 Mon Sep 17 00:00:00 2001 +From: gellert +Date: Fri, 15 Aug 2014 16:35:06 +0100 +Subject: [PATCH 72/77] MMC: added alternative MMC driver + +--- + arch/arm/mach-bcm2708/bcm2708.c | 37 +- + drivers/mmc/host/Kconfig | 29 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/bcm2835-mmc.c | 1546 +++++++++++++++++++++++++++++++++++++++ + 4 files changed, 1612 insertions(+), 1 deletion(-) + create mode 100644 drivers/mmc/host/bcm2835-mmc.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index a19f54d..a37ad15 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -92,6 +92,7 @@ static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; ++static unsigned bcm2835_mmc = 0; + + static void __init bcm2708_init_led(void); + +@@ -442,6 +443,34 @@ struct platform_device bcm2708_emmc_device = { + }; + #endif /* CONFIG_MMC_SDHCI_BCM2708 */ + ++#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ ++static struct resource bcm2835_emmc_resources[] = { ++ [0] = { ++ .start = EMMC_BASE, ++ .end = EMMC_BASE + SZ_256 - 1, /* we only need this area */ ++ /* the memory map actually makes SZ_4K available */ ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_ARASANSDIO, ++ .end = IRQ_ARASANSDIO, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 bcm2835_emmc_dmamask = 0xffffffffUL; ++ ++struct platform_device bcm2835_emmc_device = { ++ .name = "mmc-bcm2835", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), ++ .resource = bcm2835_emmc_resources, ++ .dev = { ++ .dma_mask = &bcm2835_emmc_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++#endif /* CONFIG_MMC_BCM2835 */ ++ + static struct resource bcm2708_powerman_resources[] = { + [0] = { + .start = PM_BASE, +@@ -823,7 +852,12 @@ void __init bcm2708_init(void) + bcm_register_device(&bcm2708_powerman_device); + + #ifdef CONFIG_MMC_SDHCI_BCM2708 +- bcm_register_device(&bcm2708_emmc_device); ++ if (!bcm2835_mmc) ++ bcm_register_device(&bcm2708_emmc_device); +#endif ++#ifdef CONFIG_MMC_BCM2835 ++ if (bcm2835_mmc) ++ bcm_register_device(&bcm2835_emmc_device); + #endif + bcm2708_init_led(); + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) +@@ -1053,3 +1087,4 @@ module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); + module_param(w1_gpio_pin, uint, 0644); + module_param(w1_gpio_pullup, uint, 0644); ++module_param(bcm2835_mmc, uint, 0644); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index b152bb3..592dbb2 100644 +index b152bb3..67f409a 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -311,6 +311,35 @@ config MMC_MOXART @@ -120263,12 +120396,12 @@ index b152bb3..592dbb2 100644 + bool "DMA support on BCM2835 Arasan controller" + depends on MMC_BCM2835 + help -+ Enable DMA support on the Arasan SDHCI controller in Broadcom 2708 ++ Enable DMA support on the Arasan SDHCI controller in Broadcom 2708 + based chips. + + If unsure, say N. + -+config MMC_PIO_DMA_BARRIER ++config MMC_BCM2835_PIO_DMA_BARRIER + int "Block count limit for PIO transfers" + depends on MMC_BCM2835 && MMC_BCM2835_DMA + range 0 256 @@ -120295,10 +120428,10 @@ index 635064e..402ded1 100644 obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..684b872 +index 0000000..c50ff43 --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1537 @@ +@@ -0,0 +1,1546 @@ +/* + * BCM2835 MMC host driver. + * @@ -120338,8 +120471,8 @@ index 0000000..684b872 + + +/* the inclusive limit in bytes under which PIO will be used instead of DMA */ -+#ifdef CONFIG_MMC_PIO_DMA_BARRIER -+#define PIO_DMA_BARRIER CONFIG_MMC_PIO_DMA_BARRIER ++#ifdef CONFIG_MMC_BCM2835_PIO_DMA_BARRIER ++#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_PIO_DMA_BARRIER +#else +#define PIO_DMA_BARRIER 00 +#endif @@ -120348,8 +120481,12 @@ index 0000000..684b872 +#define TIMEOUT_VAL 0xE +#define BCM2835_SDHCI_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) + ++#ifndef BCM2708_PERI_BASE ++ #define BCM2708_PERI_BASE 0x20000000 ++#endif ++ +/* FIXME: Needs IOMMU support */ -+#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) ++#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) + +#include +#include @@ -120435,7 +120572,7 @@ index 0000000..684b872 +}; + + -+static inline void mmc_writel(struct bcm2835_host *host, u32 val, int reg) ++static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); + udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); @@ -120446,15 +120583,15 @@ index 0000000..684b872 + writel(val, host->ioaddr + reg); +} + -+static inline u32 mmc_readl(struct bcm2835_host *host, int reg) ++static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} + -+static inline void mmc_writew(struct bcm2835_host *host, u16 val, int reg) ++static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int reg) +{ + u32 oldval = (reg == SDHCI_COMMAND) ? host->shadow : -+ mmc_readl(host, reg & ~3); ++ bcm2835_mmc_readl(host, reg & ~3); + u32 word_num = (reg >> 1) & 1; + u32 word_shift = word_num * 16; + u32 mask = 0xffff << word_shift; @@ -120463,25 +120600,25 @@ index 0000000..684b872 + if (reg == SDHCI_TRANSFER_MODE) + host->shadow = newval; + else -+ mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3); + +} + -+static inline void mmc_writeb(struct bcm2835_host *host, u8 val, int reg) ++static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg) +{ -+ u32 oldval = mmc_readl(host, reg & ~3); ++ u32 oldval = bcm2835_mmc_readl(host, reg & ~3); + u32 byte_num = reg & 3; + u32 byte_shift = byte_num * 8; + u32 mask = 0xff << byte_shift; + u32 newval = (oldval & ~mask) | (val << byte_shift); + -+ mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3); +} + + -+static inline u16 mmc_readw(struct bcm2835_host *host, int reg) ++static inline u16 bcm2835_mmc_readw(struct bcm2835_host *host, int reg) +{ -+ u32 val = mmc_readl(host, (reg & ~3)); ++ u32 val = bcm2835_mmc_readl(host, (reg & ~3)); + u32 word_num = (reg >> 1) & 1; + u32 word_shift = word_num * 16; + u32 word = (val >> word_shift) & 0xffff; @@ -120489,9 +120626,9 @@ index 0000000..684b872 + return word; +} + -+static inline u8 mmc_readb(struct bcm2835_host *host, int reg) ++static inline u8 bcm2835_mmc_readb(struct bcm2835_host *host, int reg) +{ -+ u32 val = mmc_readl(host, (reg & ~3)); ++ u32 val = bcm2835_mmc_readl(host, (reg & ~3)); + u32 byte_num = reg & 3; + u32 byte_shift = byte_num * 8; + u32 byte = (val >> byte_shift) & 0xff; @@ -120499,68 +120636,68 @@ index 0000000..684b872 + return byte; +} + -+static void sdhci_unsignal_irqs(struct bcm2835_host *host, u32 clear) ++static void bcm2835_mmc_unsignal_irqs(struct bcm2835_host *host, u32 clear) +{ + u32 ier; + -+ ier = mmc_readl(host, SDHCI_SIGNAL_ENABLE); ++ ier = bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE); + ier &= ~clear; + /* change which requests generate IRQs - makes no difference to + the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ -+ mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); +} + + -+static void sdhci_dumpregs(struct bcm2835_host *host) ++static void bcm2835_mmc_dumpregs(struct bcm2835_host *host) +{ + pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", + mmc_hostname(host->mmc)); + + pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", -+ mmc_readl(host, SDHCI_DMA_ADDRESS), -+ mmc_readw(host, SDHCI_HOST_VERSION)); ++ bcm2835_mmc_readl(host, SDHCI_DMA_ADDRESS), ++ bcm2835_mmc_readw(host, SDHCI_HOST_VERSION)); + pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", -+ mmc_readw(host, SDHCI_BLOCK_SIZE), -+ mmc_readw(host, SDHCI_BLOCK_COUNT)); ++ bcm2835_mmc_readw(host, SDHCI_BLOCK_SIZE), ++ bcm2835_mmc_readw(host, SDHCI_BLOCK_COUNT)); + pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", -+ mmc_readl(host, SDHCI_ARGUMENT), -+ mmc_readw(host, SDHCI_TRANSFER_MODE)); ++ bcm2835_mmc_readl(host, SDHCI_ARGUMENT), ++ bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE)); + pr_debug(DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", -+ mmc_readl(host, SDHCI_PRESENT_STATE), -+ mmc_readb(host, SDHCI_HOST_CONTROL)); ++ bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE), ++ bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL)); + pr_debug(DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", -+ mmc_readb(host, SDHCI_POWER_CONTROL), -+ mmc_readb(host, SDHCI_BLOCK_GAP_CONTROL)); ++ bcm2835_mmc_readb(host, SDHCI_POWER_CONTROL), ++ bcm2835_mmc_readb(host, SDHCI_BLOCK_GAP_CONTROL)); + pr_debug(DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", -+ mmc_readb(host, SDHCI_WAKE_UP_CONTROL), -+ mmc_readw(host, SDHCI_CLOCK_CONTROL)); ++ bcm2835_mmc_readb(host, SDHCI_WAKE_UP_CONTROL), ++ bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL)); + pr_debug(DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", -+ mmc_readb(host, SDHCI_TIMEOUT_CONTROL), -+ mmc_readl(host, SDHCI_INT_STATUS)); ++ bcm2835_mmc_readb(host, SDHCI_TIMEOUT_CONTROL), ++ bcm2835_mmc_readl(host, SDHCI_INT_STATUS)); + pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", -+ mmc_readl(host, SDHCI_INT_ENABLE), -+ mmc_readl(host, SDHCI_SIGNAL_ENABLE)); ++ bcm2835_mmc_readl(host, SDHCI_INT_ENABLE), ++ bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE)); + pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", -+ mmc_readw(host, SDHCI_ACMD12_ERR), -+ mmc_readw(host, SDHCI_SLOT_INT_STATUS)); ++ bcm2835_mmc_readw(host, SDHCI_ACMD12_ERR), ++ bcm2835_mmc_readw(host, SDHCI_SLOT_INT_STATUS)); + pr_debug(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", -+ mmc_readl(host, SDHCI_CAPABILITIES), -+ mmc_readl(host, SDHCI_CAPABILITIES_1)); ++ bcm2835_mmc_readl(host, SDHCI_CAPABILITIES), ++ bcm2835_mmc_readl(host, SDHCI_CAPABILITIES_1)); + pr_debug(DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", -+ mmc_readw(host, SDHCI_COMMAND), -+ mmc_readl(host, SDHCI_MAX_CURRENT)); ++ bcm2835_mmc_readw(host, SDHCI_COMMAND), ++ bcm2835_mmc_readl(host, SDHCI_MAX_CURRENT)); + pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n", -+ mmc_readw(host, SDHCI_HOST_CONTROL2)); ++ bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2)); + + pr_debug(DRIVER_NAME ": ===========================================\n"); +} + + -+static void bcm2835_reset(struct bcm2835_host *host, u8 mask) ++static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) +{ + unsigned long timeout; + -+ mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); ++ bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; @@ -120569,31 +120706,31 @@ index 0000000..684b872 + timeout = 100; + + /* hw clears the bit when it's done */ -+ while (mmc_readb(host, SDHCI_SOFTWARE_RESET) & mask) { ++ while (bcm2835_mmc_readb(host, SDHCI_SOFTWARE_RESET) & mask) { + if (timeout == 0) { + pr_err("%s: Reset 0x%x never completed.\n", + mmc_hostname(host->mmc), (int)mask); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } + -+ if (100-timeout>10 && 100-timeout>host->max_delay) { ++ if (100-timeout > 10 && 100-timeout > host->max_delay) { + host->max_delay = 100-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } +} + -+static void bcm2835_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); ++static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + -+static void bcm2835_init(struct bcm2835_host *host, int soft) ++static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) +{ + if (soft) -+ bcm2835_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); ++ bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); + else -+ bcm2835_reset(host, SDHCI_RESET_ALL); ++ bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | @@ -120601,21 +120738,21 @@ index 0000000..684b872 + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | + SDHCI_INT_RESPONSE; + -+ mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + + if (soft) { + /* force clock reconfiguration */ + host->clock = 0; -+ bcm2835_set_ios(host->mmc, &host->mmc->ios); ++ bcm2835_mmc_set_ios(host->mmc, &host->mmc->ios); + } +} + + + -+static void bcm2835_finish_data(struct bcm2835_host *host); ++static void bcm2835_mmc_finish_data(struct bcm2835_host *host); + -+static void bcm2835_dma_complete(void *param) ++static void bcm2835_mmc_dma_complete(void *param) +{ + struct bcm2835_host *host = param; + struct dma_chan *dma_chan; @@ -120633,13 +120770,13 @@ index 0000000..684b872 + host->data->sg, host->data->sg_len, + dir_data); + -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + } + + spin_unlock_irqrestore(&host->lock, flags); +} + -+static void bcm2835_read_block_pio(struct bcm2835_host *host) ++static void bcm2835_bcm2835_mmc_read_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len, chunk; @@ -120665,7 +120802,7 @@ index 0000000..684b872 + + while (len) { + if (chunk == 0) { -+ scratch = mmc_readl(host, SDHCI_BUFFER); ++ scratch = bcm2835_mmc_readl(host, SDHCI_BUFFER); + chunk = 4; + } + @@ -120683,7 +120820,7 @@ index 0000000..684b872 + local_irq_restore(flags); +} + -+static void bcm2835_write_block_pio(struct bcm2835_host *host) ++static void bcm2835_bcm2835_mmc_write_block_pio(struct bcm2835_host *host) +{ + unsigned long flags; + size_t blksize, len, chunk; @@ -120729,7 +120866,7 @@ index 0000000..684b872 +} + + -+static void bcm2835_transfer_pio(struct bcm2835_host *host) ++static void bcm2835_mmc_transfer_pio(struct bcm2835_host *host) +{ + u32 mask; + @@ -120743,12 +120880,12 @@ index 0000000..684b872 + else + mask = SDHCI_SPACE_AVAILABLE; + -+ while (mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { ++ while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { + + if (host->data->flags & MMC_DATA_READ) -+ bcm2835_read_block_pio(host); ++ bcm2835_bcm2835_mmc_read_block_pio(host); + else -+ bcm2835_write_block_pio(host); ++ bcm2835_bcm2835_mmc_write_block_pio(host); + + host->blocks--; + @@ -120762,7 +120899,7 @@ index 0000000..684b872 +} + + -+static void bcm2835_transfer_dma(struct bcm2835_host *host) ++static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) +{ + u32 len, dir_data, dir_slave; + struct dma_async_tx_descriptor *desc = NULL; @@ -120801,10 +120938,10 @@ index 0000000..684b872 + dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); + } + if (desc) { -+ sdhci_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | ++ bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL); + host->tx_desc = desc; -+ desc->callback = bcm2835_dma_complete; ++ desc->callback = bcm2835_mmc_dma_complete; + desc->callback_param = host; + dmaengine_submit(desc); + dma_async_issue_pending(dma_chan); @@ -120814,7 +120951,7 @@ index 0000000..684b872 + + + -+static void bcm2835_set_transfer_irqs(struct bcm2835_host *host) ++static void bcm2835_mmc_set_transfer_irqs(struct bcm2835_host *host) +{ + u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; + u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; @@ -120824,12 +120961,12 @@ index 0000000..684b872 + else + host->ier = (host->ier & ~dma_irqs) | pio_irqs; + -+ mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); +} + + -+static void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) ++static void bcm2835_mmc_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) +{ + u8 count; + struct mmc_data *data = cmd->data; @@ -120838,7 +120975,7 @@ index 0000000..684b872 + + if (data || (cmd->flags & MMC_RSP_BUSY)) { + count = TIMEOUT_VAL; -+ mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL); ++ bcm2835_mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL); + } + + if (!data) @@ -120868,17 +121005,17 @@ index 0000000..684b872 + + host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; + -+ bcm2835_set_transfer_irqs(host); ++ bcm2835_mmc_set_transfer_irqs(host); + + /* Set the DMA boundary value and block size */ -+ mmc_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, ++ bcm2835_mmc_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, + data->blksz), SDHCI_BLOCK_SIZE); -+ mmc_writew(host, data->blocks, SDHCI_BLOCK_COUNT); ++ bcm2835_mmc_writew(host, data->blocks, SDHCI_BLOCK_COUNT); + + BUG_ON(!host->data); +} + -+static void bcm2835_set_transfer_mode(struct bcm2835_host *host, ++static void bcm2835_mmc_set_transfer_mode(struct bcm2835_host *host, + struct mmc_command *cmd) +{ + u16 mode; @@ -120886,8 +121023,8 @@ index 0000000..684b872 + + if (data == NULL) { + /* clear Auto CMD settings for no data CMDs */ -+ mode = mmc_readw(host, SDHCI_TRANSFER_MODE); -+ mmc_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | ++ mode = bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE); ++ bcm2835_mmc_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | + SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); + return; + } @@ -120907,7 +121044,7 @@ index 0000000..684b872 + mode |= SDHCI_TRNS_AUTO_CMD12; + else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mode |= SDHCI_TRNS_AUTO_CMD23; -+ mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); ++ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); + } + } + @@ -120916,10 +121053,10 @@ index 0000000..684b872 + if (host->flags & SDHCI_REQ_USE_DMA) + mode |= SDHCI_TRNS_DMA; + -+ mmc_writew(host, mode, SDHCI_TRANSFER_MODE); ++ bcm2835_mmc_writew(host, mode, SDHCI_TRANSFER_MODE); +} + -+void bcm2835_send_command(struct bcm2835_host *host, struct mmc_command *cmd) ++void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd) +{ + int flags; + u32 mask; @@ -120939,11 +121076,11 @@ index 0000000..684b872 + if (host->mrq->data && (cmd == host->mrq->data->stop)) + mask &= ~SDHCI_DATA_INHIBIT; + -+ while (mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { ++ while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) { + if (timeout == 0) { + pr_err("%s: Controller never released inhibit bit(s).\n", + mmc_hostname(host->mmc)); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; @@ -120952,7 +121089,7 @@ index 0000000..684b872 + udelay(10); + } + -+ if ((1000-timeout)/100>1 && (1000-timeout)/100>host->max_delay) { ++ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { + host->max_delay = (1000-timeout)/100; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } @@ -120968,11 +121105,11 @@ index 0000000..684b872 + + host->cmd = cmd; + -+ bcm2835_prepare_data(host, cmd); ++ bcm2835_mmc_prepare_data(host, cmd); + -+ mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); ++ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); + -+ bcm2835_set_transfer_mode(host, cmd); ++ bcm2835_mmc_set_transfer_mode(host, cmd); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + pr_err("%s: Unsupported response type!\n", @@ -120999,11 +121136,11 @@ index 0000000..684b872 + if (cmd->data) + flags |= SDHCI_CMD_DATA; + -+ mmc_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); ++ bcm2835_mmc_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); +} + + -+static void bcm2835_finish_data(struct bcm2835_host *host) ++static void bcm2835_mmc_finish_data(struct bcm2835_host *host) +{ + struct mmc_data *data; + @@ -121031,16 +121168,16 @@ index 0000000..684b872 + * upon error conditions. + */ + if (data->error) { -+ bcm2835_reset(host, SDHCI_RESET_CMD); -+ bcm2835_reset(host, SDHCI_RESET_DATA); ++ bcm2835_mmc_reset(host, SDHCI_RESET_CMD); ++ bcm2835_mmc_reset(host, SDHCI_RESET_DATA); + } + -+ bcm2835_send_command(host, data->stop); ++ bcm2835_mmc_send_command(host, data->stop); + } else + tasklet_schedule(&host->finish_tasklet); +} + -+static void bcm2835_finish_command(struct bcm2835_host *host) ++static void bcm2835_mmc_finish_command(struct bcm2835_host *host) +{ + int i; + @@ -121050,15 +121187,15 @@ index 0000000..684b872 + if (host->cmd->flags & MMC_RSP_136) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++) { -+ host->cmd->resp[i] = mmc_readl(host, ++ host->cmd->resp[i] = bcm2835_mmc_readl(host, + SDHCI_RESPONSE + (3-i)*4) << 8; + if (i != 3) + host->cmd->resp[i] |= -+ mmc_readb(host, ++ bcm2835_mmc_readb(host, + SDHCI_RESPONSE + (3-i)*4-1); + } + } else { -+ host->cmd->resp[0] = mmc_readl(host, SDHCI_RESPONSE); ++ host->cmd->resp[0] = bcm2835_mmc_readl(host, SDHCI_RESPONSE); + } + } + @@ -121067,12 +121204,12 @@ index 0000000..684b872 + /* Finished CMD23, now send actual command. */ + if (host->cmd == host->mrq->sbc) { + host->cmd = NULL; -+ bcm2835_send_command(host, host->mrq->cmd); ++ bcm2835_mmc_send_command(host, host->mrq->cmd); + } else { + + /* Processed actual command. */ + if (host->data && host->data_early) -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + + if (!host->cmd->data) + tasklet_schedule(&host->finish_tasklet); @@ -121082,7 +121219,7 @@ index 0000000..684b872 +} + + -+static void bcm2835_timeout_timer(unsigned long data) ++static void bcm2835_mmc_timeout_timer(unsigned long data) +{ + struct bcm2835_host *host; + unsigned long flags; @@ -121094,11 +121231,11 @@ index 0000000..684b872 + if (host->mrq) { + pr_err("%s: Timeout waiting for hardware interrupt.\n", + mmc_hostname(host->mmc)); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + + if (host->data) { + host->data->error = -ETIMEDOUT; -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; @@ -121114,7 +121251,7 @@ index 0000000..684b872 +} + + -+static void mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) ++static void bcm2835_mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) +{ + if (!(host->flags & SDHCI_DEVICE_DEAD)) { + if (enable) @@ -121122,13 +121259,13 @@ index 0000000..684b872 + else + host->ier &= ~SDHCI_INT_CARD_INT; + -+ mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + mmiowb(); + } +} + -+static void mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) ++static void bcm2835_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct bcm2835_host *host = mmc_priv(mmc); + unsigned long flags; @@ -121139,11 +121276,11 @@ index 0000000..684b872 + else + host->flags &= ~SDHCI_SDIO_IRQ_ENABLED; + -+ mmc_enable_sdio_irq_nolock(host, enable); ++ bcm2835_mmc_enable_sdio_irq_nolock(host, enable); + spin_unlock_irqrestore(&host->lock, flags); +} + -+static void mmc_cmd_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_mmc_cmd_irq(struct bcm2835_host *host, u32 intmask) +{ + + BUG_ON(intmask == 0); @@ -121152,7 +121289,7 @@ index 0000000..684b872 + pr_err("%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + return; + } + @@ -121169,11 +121306,11 @@ index 0000000..684b872 + } + + if (intmask & SDHCI_INT_RESPONSE) -+ bcm2835_finish_command(host); ++ bcm2835_mmc_finish_command(host); + +} + -+static void mmc_data_irq(struct bcm2835_host *host, u32 intmask) ++static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask) +{ + struct dma_chan *dma_chan; + u32 dir_data; @@ -121188,7 +121325,7 @@ index 0000000..684b872 + */ + if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) { + if (intmask & SDHCI_INT_DATA_END) { -+ bcm2835_finish_command(host); ++ bcm2835_mmc_finish_command(host); + return; + } + } @@ -121196,7 +121333,7 @@ index 0000000..684b872 + pr_debug("%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + + return; + } @@ -121206,7 +121343,7 @@ index 0000000..684b872 + else if (intmask & SDHCI_INT_DATA_END_BIT) + host->data->error = -EILSEQ; + else if ((intmask & SDHCI_INT_DATA_CRC) && -+ SDHCI_GET_CMD(mmc_readw(host, SDHCI_COMMAND)) ++ SDHCI_GET_CMD(bcm2835_mmc_readw(host, SDHCI_COMMAND)) + != MMC_BUS_TEST_R) + host->data->error = -EILSEQ; + @@ -121220,15 +121357,15 @@ index 0000000..684b872 + host->data->sg, host->data->sg_len, + dir_data); + -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + } + + } else { + if (host->data->error) -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + else { + if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) -+ bcm2835_transfer_pio(host); ++ bcm2835_mmc_transfer_pio(host); + + if (intmask & SDHCI_INT_DATA_END) { + if (host->cmd) { @@ -121239,7 +121376,7 @@ index 0000000..684b872 + */ + host->data_early = 1; + } else { -+ bcm2835_finish_data(host); ++ bcm2835_mmc_finish_data(host); + } + } + } @@ -121247,17 +121384,19 @@ index 0000000..684b872 +} + + -+static irqreturn_t mmc_irq(int irq, void *dev_id) ++static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) +{ + irqreturn_t result = IRQ_NONE; + struct bcm2835_host *host = dev_id; + u32 intmask, mask, unexpected = 0; + int max_loops = 16; ++#ifndef CONFIG_OF + int cardint = 0; ++#endif + + spin_lock(&host->lock); + -+ intmask = mmc_readl(host, SDHCI_INT_STATUS); ++ intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + + if (!intmask || intmask == 0xffffffff) { + result = IRQ_NONE; @@ -121268,14 +121407,14 @@ index 0000000..684b872 + /* Clear selected interrupts. */ + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_BUS_POWER); -+ mmc_writel(host, mask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS); + + + if (intmask & SDHCI_INT_CMD_MASK) -+ mmc_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); ++ bcm2835_mmc_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + + if (intmask & SDHCI_INT_DATA_MASK) -+ mmc_data_irq(host, intmask & SDHCI_INT_DATA_MASK); ++ bcm2835_mmc_data_irq(host, intmask & SDHCI_INT_DATA_MASK); + + if (intmask & SDHCI_INT_BUS_POWER) + pr_err("%s: Card is consuming too much power!\n", @@ -121285,7 +121424,7 @@ index 0000000..684b872 +#ifndef CONFIG_OF + cardint = 1; +#else -+ mmc_enable_sdio_irq_nolock(host, false); ++ bcm2835_mmc_enable_sdio_irq_nolock(host, false); + host->thread_isr |= SDHCI_INT_CARD_INT; + result = IRQ_WAKE_THREAD; +#endif @@ -121298,13 +121437,13 @@ index 0000000..684b872 + + if (intmask) { + unexpected |= intmask; -+ mmc_writel(host, intmask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS); + } + + if (result == IRQ_NONE) + result = IRQ_HANDLED; + -+ intmask = mmc_readl(host, SDHCI_INT_STATUS); ++ intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + } while (intmask && --max_loops); +out: + spin_unlock(&host->lock); @@ -121312,7 +121451,7 @@ index 0000000..684b872 + if (unexpected) { + pr_err("%s: Unexpected interrupt 0x%08x.\n", + mmc_hostname(host->mmc), unexpected); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + } + +#ifndef CONFIG_OF @@ -121324,7 +121463,7 @@ index 0000000..684b872 +} + +#ifdef CONFIG_OF -+static irqreturn_t mmc_thread_irq(int irq, void *dev_id) ++static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id) +{ + struct bcm2835_host *host = dev_id; + unsigned long flags; @@ -121340,7 +121479,7 @@ index 0000000..684b872 + + spin_lock_irqsave(&host->lock, flags); + if (host->flags & SDHCI_SDIO_IRQ_ENABLED) -+ mmc_enable_sdio_irq_nolock(host, true); ++ bcm2835_mmc_enable_sdio_irq_nolock(host, true); + spin_unlock_irqrestore(&host->lock, flags); + } + @@ -121350,7 +121489,7 @@ index 0000000..684b872 + + + -+void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) ++void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) +{ + int div = 0; /* Initialized for compiler warning */ + int real_div = div, clk_mul = 1; @@ -121360,7 +121499,7 @@ index 0000000..684b872 + + host->mmc->actual_clock = 0; + -+ mmc_writew(host, 0, SDHCI_CLOCK_CONTROL); ++ bcm2835_mmc_writew(host, 0, SDHCI_CLOCK_CONTROL); + + if (clock == 0) + return; @@ -121386,32 +121525,32 @@ index 0000000..684b872 + clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) + << SDHCI_DIVIDER_HI_SHIFT; + clk |= SDHCI_CLOCK_INT_EN; -+ mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Wait max 20 ms */ + timeout = 20; -+ while (!((clk = mmc_readw(host, SDHCI_CLOCK_CONTROL)) ++ while (!((clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL)) + & SDHCI_CLOCK_INT_STABLE)) { + if (timeout == 0) { + pr_err("%s: Internal clock never " + "stabilised.\n", mmc_hostname(host->mmc)); -+ sdhci_dumpregs(host); ++ bcm2835_mmc_dumpregs(host); + return; + } + timeout--; + mdelay(1); + } + -+ if (20-timeout>10 && 20-timeout>host->max_delay) { ++ if (20-timeout > 10 && 20-timeout > host->max_delay) { + host->max_delay = 20-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } + + clk |= SDHCI_CLOCK_CARD_EN; -+ mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); +} + -+static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq) ++static void bcm2835_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct bcm2835_host *host; + unsigned long flags; @@ -121423,18 +121562,18 @@ index 0000000..684b872 + WARN_ON(host->mrq != NULL); + + host->mrq = mrq; -+ bcm2835_send_command(host, mrq->cmd); ++ bcm2835_mmc_send_command(host, mrq->cmd); + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + + if (mrq->cmd->data && host->use_dma) { + /* DMA transfer starts now, PIO starts after interrupt */ -+ bcm2835_transfer_dma(host); ++ bcm2835_mmc_transfer_dma(host); + } +} + + -+static void bcm2835_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + + struct bcm2835_host *host = mmc_priv(mmc); @@ -121446,16 +121585,16 @@ index 0000000..684b872 + spin_lock_irqsave(&host->lock, flags); + + if (!ios->clock || ios->clock != host->clock) { -+ bcm2835_set_clock(host, ios->clock); ++ bcm2835_mmc_set_clock(host, ios->clock); + host->clock = ios->clock; + } + + if (host->pwr != SDHCI_POWER_330) { + host->pwr = SDHCI_POWER_330; -+ mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL); ++ bcm2835_mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL); + } + -+ ctrl = mmc_readb(host, SDHCI_HOST_CONTROL); ++ ctrl = bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL); + + /* set bus width */ + ctrl &= ~SDHCI_CTRL_8BITBUS; @@ -121467,28 +121606,28 @@ index 0000000..684b872 + ctrl &= ~SDHCI_CTRL_HISPD; /* NO_HISPD_BIT */ + + -+ mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); ++ bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); + /* + * We only need to set Driver Strength if the + * preset value enable is not set. + */ -+ ctrl_2 = mmc_readw(host, SDHCI_HOST_CONTROL2); ++ ctrl_2 = bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2); + ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; + if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; + else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) + ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; + -+ mmc_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); ++ bcm2835_mmc_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + + /* Reset SD Clock Enable */ -+ clk = mmc_readw(host, SDHCI_CLOCK_CONTROL); ++ clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL); + clk &= ~SDHCI_CLOCK_CARD_EN; -+ mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Re-enable SD Clock */ -+ bcm2835_set_clock(host, host->clock); -+ mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); ++ bcm2835_mmc_set_clock(host, host->clock); ++ bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL); + + mmiowb(); + @@ -121497,13 +121636,13 @@ index 0000000..684b872 + + +static struct mmc_host_ops bcm2835_ops = { -+ .request = bcm2835_request, -+ .set_ios = bcm2835_set_ios, -+ .enable_sdio_irq = mmc_enable_sdio_irq, ++ .request = bcm2835_mmc_request, ++ .set_ios = bcm2835_mmc_set_ios, ++ .enable_sdio_irq = bcm2835_mmc_enable_sdio_irq, +}; + + -+static void sdhci_tasklet_finish(unsigned long param) ++static void bcm2835_mmc_tasklet_finish(unsigned long param) +{ + struct bcm2835_host *host; + unsigned long flags; @@ -121535,8 +121674,8 @@ index 0000000..684b872 + (mrq->data && (mrq->data->error || + (mrq->data->stop && mrq->data->stop->error))))) { + -+ bcm2835_reset(host, SDHCI_RESET_CMD); -+ bcm2835_reset(host, SDHCI_RESET_DATA); ++ bcm2835_mmc_reset(host, SDHCI_RESET_CMD); ++ bcm2835_mmc_reset(host, SDHCI_RESET_DATA); + } + + host->mrq = NULL; @@ -121551,16 +121690,17 @@ index 0000000..684b872 + + + -+int bcm2835_add_host(struct bcm2835_host *host) ++int bcm2835_mmc_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc; ++#ifndef FORCE_PIO + struct dma_slave_config cfg; -+ ++#endif + int ret; + + mmc = host->mmc; + -+ bcm2835_reset(host, SDHCI_RESET_ALL); ++ bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + host->clk_mul = 0; + @@ -121622,17 +121762,17 @@ index 0000000..684b872 + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + + tasklet_init(&host->finish_tasklet, -+ sdhci_tasklet_finish, (unsigned long)host); ++ bcm2835_mmc_tasklet_finish, (unsigned long)host); + -+ setup_timer(&host->timer, bcm2835_timeout_timer, (unsigned long)host); ++ setup_timer(&host->timer, bcm2835_mmc_timeout_timer, (unsigned long)host); + init_waitqueue_head(&host->buf_ready_int); + -+ bcm2835_init(host, 0); ++ bcm2835_mmc_init(host, 0); +#ifndef CONFIG_OF -+ ret = request_irq(host->irq, mmc_irq, 0 /*IRQF_SHARED*/, ++ ret = request_irq(host->irq, bcm2835_mmc_irq, 0 /*IRQF_SHARED*/, + mmc_hostname(mmc), host); +#else -+ ret = request_threaded_irq(host->irq, mmc_irq, mmc_thread_irq, ++ ret = request_threaded_irq(host->irq, bcm2835_mmc_irq, bcm2835_mmc_thread_irq, + IRQF_SHARED, mmc_hostname(mmc), host); +#endif + if (ret) { @@ -121654,7 +121794,7 @@ index 0000000..684b872 + return ret; +} + -+static int bcm2835_probe(struct platform_device *pdev) ++static int bcm2835_mmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; +#ifdef CONFIG_OF @@ -121666,7 +121806,9 @@ index 0000000..684b872 + + int ret; + struct mmc_host *mmc; ++#if !defined(CONFIG_OF) && !defined(FORCE_PIO) + dma_cap_mask_t mask; ++#endif + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { @@ -121747,7 +121889,7 @@ index 0000000..684b872 + host->timeout = msecs_to_jiffies(1000); + spin_lock_init(&host->lock); + mmc->ops = &bcm2835_ops; -+ return bcm2835_add_host(host); ++ return bcm2835_mmc_add_host(host); + + +err_remap: @@ -121763,7 +121905,7 @@ index 0000000..684b872 + return ret; +} + -+static int bcm2835_remove(struct platform_device *pdev) ++static int bcm2835_mmc_remove(struct platform_device *pdev) +{ + struct bcm2835_host *host = platform_get_drvdata(pdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -121772,7 +121914,7 @@ index 0000000..684b872 + u32 scratch; + + dead = 0; -+ scratch = mmc_readl(host, SDHCI_INT_STATUS); ++ scratch = bcm2835_mmc_readl(host, SDHCI_INT_STATUS); + if (scratch == (u32)-1) + dead = 1; + @@ -121796,7 +121938,7 @@ index 0000000..684b872 + mmc_remove_host(host->mmc); + + if (!dead) -+ bcm2835_reset(host, SDHCI_RESET_ALL); ++ bcm2835_mmc_reset(host, SDHCI_RESET_ALL); + + free_irq(host->irq, host); + @@ -121822,8 +121964,8 @@ index 0000000..684b872 + + +static struct platform_driver bcm2835_mmc_driver = { -+ .probe = bcm2835_probe, -+ .remove = bcm2835_remove, ++ .probe = bcm2835_mmc_probe, ++ .remove = bcm2835_mmc_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, @@ -121836,169 +121978,53 @@ index 0000000..684b872 +MODULE_DESCRIPTION("BCM2835 SDHCI driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c -index 6e777f4..b5f9f162 100644 ---- a/drivers/mmc/host/sdhci-bcm2708.c -+++ b/drivers/mmc/host/sdhci-bcm2708.c -@@ -62,13 +62,16 @@ - #define SOFTWARE_ERASE_TIMEOUT_SEC 30 - - #define SDHCI_BCM_DMA_CHAN 4 /* this default is normally overriden */ --#define SDHCI_BCM_DMA_WAITS 0 /* delays slowing DMA transfers: 0-31 */ -+#define SDHCI_BCM_DMA_WAITS 1 /* delays slowing DMA transfers: 0-31 */ - /* We are worried that SD card DMA use may be blocking the AXI bus for others */ - - /*! TODO: obtain these from the physical address */ - #define DMA_SDHCI_BASE 0x7e300000 /* EMMC register block on Videocore */ - #define DMA_SDHCI_BUFFER (DMA_SDHCI_BASE + SDHCI_BUFFER) - -+#define MAX_LITE_TRANSFER 32768 -+#define MAX_NORMAL_TRANSFER 1073741824 -+ - #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ - - /* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */ -@@ -444,29 +447,40 @@ static void schci_bcm2708_cb_read(struct sdhci_bcm2708_priv *host, - dma_addr_t dma_addr, unsigned len, - int /*bool*/ is_last) - { -- struct bcm2708_dma_cb *cb = &host->cb_base[ix]; -- unsigned char dmawaits = host->dma_waits; -- -- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | -- BCM2708_DMA_WAITS(dmawaits) | -- BCM2708_DMA_S_DREQ | -- BCM2708_DMA_D_WIDTH | -- BCM2708_DMA_D_INC; -- cb->src = DMA_SDHCI_BUFFER; /* DATA register DMA address */ -- cb->dst = dma_addr; -- cb->length = len; -- cb->stride = 0; -- -- if (is_last) { -- cb->info |= BCM2708_DMA_INT_EN | -- BCM2708_DMA_WAIT_RESP; -- cb->next = 0; -- } else -- cb->next = host->cb_handle + -- (ix+1)*sizeof(struct bcm2708_dma_cb); -+ struct bcm2708_dma_cb *cb; -+ unsigned char dmawaits = host->dma_waits; -+ unsigned i, max_size; - -- cb->pad[0] = 0; -- cb->pad[1] = 0; -+ if (host->dma_chan >= 8) /* we have a LITE channel */ -+ max_size = MAX_LITE_TRANSFER; -+ else -+ max_size = MAX_NORMAL_TRANSFER; -+ -+ -+ for (i = 0; icb_base[ix+i/max_size]; -+ -+ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | -+ BCM2708_DMA_WAITS(dmawaits) | -+ BCM2708_DMA_S_DREQ | -+ BCM2708_DMA_D_WIDTH | -+ BCM2708_DMA_D_INC; -+ cb->src = DMA_SDHCI_BUFFER; /* DATA register DMA address */ -+ cb->dst = dma_addr + (dma_addr_t)i; -+ cb->length = min(len-i, max_size); -+ cb->stride = 0; -+ -+ if (is_last && len-i<=max_size) { -+ cb->info |= BCM2708_DMA_INT_EN | -+ BCM2708_DMA_WAIT_RESP; -+ cb->next = 0; -+ } else -+ cb->next = host->cb_handle + -+ (ix+1 + i/max_size)*sizeof(struct bcm2708_dma_cb); -+ -+ cb->pad[0] = 0; -+ cb->pad[1] = 0; -+ } - } - - static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host, -@@ -475,30 +489,42 @@ static void schci_bcm2708_cb_write(struct sdhci_bcm2708_priv *host, - int /*bool*/ is_last) - { - struct bcm2708_dma_cb *cb = &host->cb_base[ix]; -- unsigned char dmawaits = host->dma_waits; -+ unsigned char dmawaits = host->dma_waits; -+ unsigned i, max_size; -+ -+ if (host->dma_chan >= 8) /* we have a LITE channel */ -+ max_size = MAX_LITE_TRANSFER; -+ else -+ max_size = MAX_NORMAL_TRANSFER; - - /* We can make arbitrarily large writes as long as we specify DREQ to -- pace the delivery of bytes to the Arasan hardware */ -- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | -- BCM2708_DMA_WAITS(dmawaits) | -- BCM2708_DMA_D_DREQ | -- BCM2708_DMA_S_WIDTH | -- BCM2708_DMA_S_INC; -- cb->src = dma_addr; -- cb->dst = DMA_SDHCI_BUFFER; /* DATA register DMA address */ -- cb->length = len; -- cb->stride = 0; -- -- if (is_last) { -- cb->info |= BCM2708_DMA_INT_EN | -- BCM2708_DMA_WAIT_RESP; -- cb->next = 0; -- } else -- cb->next = host->cb_handle + -- (ix+1)*sizeof(struct bcm2708_dma_cb); -+ pace the delivery of bytes to the Arasan hardware. However we need -+ to take care when using LITE channels */ -+ -+ for (i = 0; icb_base[ix+i/max_size]; -+ -+ cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_EMMC) | -+ BCM2708_DMA_WAITS(dmawaits) | -+ BCM2708_DMA_D_DREQ | -+ BCM2708_DMA_S_WIDTH | -+ BCM2708_DMA_S_INC; -+ cb->src = dma_addr + (dma_addr_t)i; -+ cb->dst = DMA_SDHCI_BUFFER; /* DATA register DMA address */ -+ cb->length = min(len-i, max_size); -+ cb->stride = 0; -+ -+ if (is_last && len-i<=max_size) { -+ cb->info |= BCM2708_DMA_INT_EN | -+ BCM2708_DMA_WAIT_RESP; -+ cb->next = 0; -+ } else -+ cb->next = host->cb_handle + -+ (ix+1 + i/max_size)*sizeof(struct bcm2708_dma_cb); - -- cb->pad[0] = 0; -- cb->pad[1] = 0; -+ cb->pad[0] = 0; -+ cb->pad[1] = 0; -+ } - } - - -@@ -1390,5 +1416,3 @@ MODULE_PARM_DESC(emmc_clock_freq, "Specify the speed of emmc clock"); - MODULE_PARM_DESC(sync_after_dma, "Block in driver until dma complete"); - MODULE_PARM_DESC(missing_status, "Use the missing status quirk"); - MODULE_PARM_DESC(extra_messages, "Enable more sdcard warning messages"); -- -- -- -2.0.3 +2.0.4 -From fdf1865f73395539c4abdc6929ad34a3ba54d510 Mon Sep 17 00:00:00 2001 +From 4310177a783406d20efaeb01548956ebb5da2ff8 Mon Sep 17 00:00:00 2001 +From: gellert +Date: Fri, 15 Aug 2014 16:35:59 +0100 +Subject: [PATCH 73/77] turn on new MMC driver + +--- + arch/arm/configs/bcmrpi_defconfig | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 105bcbe..1b06882 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -894,6 +894,9 @@ CONFIG_USB_ISIGHTFW=m + CONFIG_USB_YUREX=m + CONFIG_MMC=y + CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 + CONFIG_MMC_SDHCI=y + CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_MMC_SDHCI_BCM2708=y +@@ -944,9 +947,9 @@ CONFIG_RTC_DRV_DS3234=m + CONFIG_RTC_DRV_PCF2123=m + CONFIG_RTC_DRV_RX4581=m + CONFIG_DMADEVICES=y +-CONFIG_DMA_BCM2708=m ++CONFIG_DMA_BCM2708=y + CONFIG_DMA_ENGINE=y +-CONFIG_DMA_VIRTUAL_CHANNELS=m ++CONFIG_DMA_VIRTUAL_CHANNELS=y + CONFIG_UIO=m + CONFIG_UIO_PDRV_GENIRQ=m + CONFIG_STAGING=y +-- +2.0.4 + + +From 640da32da5bccd052eae65f49ad7ca5217d5d0ad Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 72/73] Added support for HiFiBerry DAC+ +Subject: [PATCH 74/77] 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. @@ -122012,7 +122038,7 @@ a different codec chip (PCM5122), therefore a new driver is necessary. create mode 100644 sound/soc/bcm/hifiberry_dacplus.c diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index d0f0781..0bdf36f 100644 +index 1b06882..4d70168 100644 --- a/arch/arm/configs/bcmrpi_defconfig +++ b/arch/arm/configs/bcmrpi_defconfig @@ -747,6 +747,7 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y @@ -122024,7 +122050,7 @@ index d0f0781..0bdf36f 100644 CONFIG_SND_BCM2708_SOC_RPI_DAC=m CONFIG_SND_SOC_I2C_AND_SPI=m diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a730d5d..a90c7f0 100644 +index a37ad15..cf421ee 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c @@ -674,6 +674,20 @@ static struct platform_device snd_pcm5102a_codec_device = { @@ -122048,7 +122074,7 @@ index a730d5d..a90c7f0 100644 #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) static struct platform_device snd_hifiberry_digi_device = { .name = "snd-hifiberry-digi", -@@ -877,6 +891,11 @@ void __init bcm2708_init(void) +@@ -879,6 +893,11 @@ void __init bcm2708_init(void) bcm_register_device(&snd_pcm5102a_codec_device); #endif @@ -122222,13 +122248,13 @@ index 0000000..c63387b +MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); +MODULE_LICENSE("GPL v2"); -- -2.0.3 +2.0.4 -From 82692a293288c334f3da11895e63ea7d066db4f6 Mon Sep 17 00:00:00 2001 +From 504990c26cf6a6e3ed42b5d2f917ff88d0244405 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 4 Aug 2014 16:47:36 +0200 -Subject: [PATCH 73/73] ASoC: BCM: Typo in RPi-DAC driver +Subject: [PATCH 75/77] ASoC: BCM: Typo in RPi-DAC driver This patch corrects a typo that originated from inattentive copy and paste. @@ -122254,5 +122280,288 @@ index ef3cd93..6d6e0ba 100644 .codec_dai_name = "pcm1794a-hifi", .platform_name = "bcm2708-i2s.0", -- -2.0.3 +2.0.4 + + +From 1349a252eb45cc1b8244ab3c882edb2539eb1049 Mon Sep 17 00:00:00 2001 +From: Kari Suvanto +Date: Tue, 19 Aug 2014 14:25:28 +0300 +Subject: [PATCH 76/77] usb: dwc: fix lockdep false positive + +Os wrapper function for spinlock init causes lockdep to show this +false positive splat during boot: +[ 3.789851] ============================================= +[ 3.796603] [ INFO: possible recursive locking detected ] +[ 3.803320] 3.16.1+ #5 Not tainted +[ 3.808015] --------------------------------------------- +[ 3.814730] khubd/18 is trying to acquire lock: +[ 3.820537] (&(sl)->rlock){-.-...}, at: [] DWC_SPINLOCK_IRQSAVE+0xc/0x14 +[ 3.830932] +[ 3.830932] but task is already holding lock: +[ 3.839274] (&(sl)->rlock){-.-...}, at: [] DWC_SPINLOCK_IRQSAVE+0xc/0x14 +[ 3.849704] +[ 3.849704] other info that might help us debug this: +[ 3.858826] Possible unsafe locking scenario: +[ 3.858826] +[ 3.867334] CPU0 +[ 3.871052] ---- +[ 3.874721] lock(&(sl)->rlock); +[ 3.879302] lock(&(sl)->rlock); +[ 3.883815] +[ 3.883815] *** DEADLOCK *** +[ 3.883815] +[ 3.892869] May be due to missing lock nesting notation +[ 3.892869] +[ 3.901736] 4 locks held by khubd/18: +[ 3.906438] #0: (&dev->mutex){......}, at: [] hub_thread+0x98/0x1000 +[ 3.916026] #1: (&port_dev->status_lock){+.+.+.}, at: [] hub_thread+0x63c/0x1000 +[ 3.926847] #2: (&bus->usb_address0_mutex){+.+.+.}, at: [] hub_port_init+0x5c/0xb24 +[ 3.938015] #3: (&(sl)->rlock){-.-...}, at: [] DWC_SPINLOCK_IRQSAVE+0xc/0x14 +[ 3.948730] +[ 3.948730] stack backtrace: +[ 3.955457] CPU: 0 PID: 18 Comm: khubd Not tainted 3.16.1+ #5 +[ 3.962541] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) +[ 3.972998] [] (show_stack) from [] (__lock_acquire+0x1420/0x1ae0) +[ 3.983910] [] (__lock_acquire) from [] (lock_acquire+0x6c/0x8c) +[ 3.994908] [] (lock_acquire) from [] (_raw_spin_lock_irqsave+0x50/0x64) +[ 4.006756] [] (_raw_spin_lock_irqsave) from [] (DWC_SPINLOCK_IRQSAVE+0xc/0x14) +[ 4.019382] [] (DWC_SPINLOCK_IRQSAVE) from [] (dwc_otg_hcd_select_transactions+0x20c/0x368) +[ 4.033064] [] (dwc_otg_hcd_select_transactions) from [] (dwc_otg_hcd_urb_enqueue+0x158/0x1ec) +[ 4.047017] [] (dwc_otg_hcd_urb_enqueue) from [] (dwc_otg_urb_enqueue+0x1a8/0x2e0) +[ 4.059889] [] (dwc_otg_urb_enqueue) from [] (usb_hcd_submit_urb+0xb8/0x870) +[ 4.072316] [] (usb_hcd_submit_urb) from [] (usb_start_wait_urb+0x44/0xbc) +[ 4.084786] [] (usb_start_wait_urb) from [] (usb_control_msg+0xb4/0xec) +[ 4.097045] [] (usb_control_msg) from [] (hub_port_init+0x420/0xb24) +[ 4.109018] [] (hub_port_init) from [] (hub_thread+0x650/0x1000) +[ 4.120667] [] (hub_thread) from [] (kthread+0xc8/0xe4) +[ 4.129668] [] (kthread) from [] (ret_from_fork+0x14/0x2c) + +This is false positive because the lockdep uses the lock variable name +to keep track of locks. To fix this, the spin_lock_init function can't be in a +wrapper function for spinlock name to recorder correctly. I noticed similar fix +was already made for mutex debugging so used similar approach and added extra +macro to be used to spinlock allocation when spinlock debugging is on. + +Signed-off-by: Kari Suvanto +--- + drivers/usb/host/dwc_common_port/dwc_common_linux.c | 8 ++++++++ + drivers/usb/host/dwc_common_port/dwc_os.h | 16 +++++++++++++++- + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 +++++ + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 4 ++++ + 4 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c +index 6d01261..5c50a8b 100644 +--- a/drivers/usb/host/dwc_common_port/dwc_common_linux.c ++++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c +@@ -766,7 +766,11 @@ dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data) + goto no_name; + } + ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK)) ++ DWC_SPINLOCK_ALLOC_LINUX_DEBUG(t->lock); ++#else + t->lock = DWC_SPINLOCK_ALLOC(); ++#endif + if (!t->lock) { + DWC_ERROR("Cannot allocate memory for lock"); + goto no_lock; +@@ -1083,7 +1087,11 @@ dwc_workq_t *DWC_WORKQ_ALLOC(char *name) + + wq->pending = 0; + ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK)) ++ DWC_SPINLOCK_ALLOC_LINUX_DEBUG(wq->lock); ++#else + wq->lock = DWC_SPINLOCK_ALLOC(); ++#endif + if (!wq->lock) { + goto no_lock; + } +diff --git a/drivers/usb/host/dwc_common_port/dwc_os.h b/drivers/usb/host/dwc_common_port/dwc_os.h +index 09ed244..a2bbe23 100644 +--- a/drivers/usb/host/dwc_common_port/dwc_os.h ++++ b/drivers/usb/host/dwc_common_port/dwc_os.h +@@ -59,6 +59,7 @@ extern "C" { + # ifdef CONFIG_DEBUG_MUTEXES + # include + # endif ++# include + # include + # include + #endif +@@ -1039,9 +1040,22 @@ typedef unsigned long dwc_irqflags_t; + /** Returns an initialized lock variable. This function should allocate and + * initialize the OS-specific data structure used for locking. This data + * structure is to be used for the DWC_LOCK and DWC_UNLOCK functions and should +- * be freed by the DWC_FREE_LOCK when it is no longer used. */ ++ * be freed by the DWC_FREE_LOCK when it is no longer used. ++ * ++ * For Linux Spinlock Debugging make it macro because the debugging routines use ++ * the symbol name to determine recursive locking. Using a wrapper function ++ * makes it falsely think recursive locking occurs. */ ++#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK) ++#define DWC_SPINLOCK_ALLOC_LINUX_DEBUG(lock) ({ \ ++ lock = DWC_ALLOC(sizeof(spinlock_t)); \ ++ if (lock) { \ ++ spin_lock_init((spinlock_t *)lock); \ ++ } \ ++}) ++#else + extern dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void); + #define dwc_spinlock_alloc(_ctx_) DWC_SPINLOCK_ALLOC() ++#endif + + /** Frees an initialized lock variable. */ + extern void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock); +diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +index 35721e5..c39ef31 100644 +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -951,8 +951,13 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if) + int i; + dwc_hc_t *channel; + ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK)) ++ DWC_SPINLOCK_ALLOC_LINUX_DEBUG(hcd->lock); ++ DWC_SPINLOCK_ALLOC_LINUX_DEBUG(hcd->channel_lock); ++#else + hcd->lock = DWC_SPINLOCK_ALLOC(); + hcd->channel_lock = DWC_SPINLOCK_ALLOC(); ++#endif + DWC_DEBUGPL(DBG_HCDV, "init of HCD %p given core_if %p\n", + hcd, core_if); + if (!hcd->lock) { +diff --git a/drivers/usb/host/dwc_otg/dwc_otg_pcd.c b/drivers/usb/host/dwc_otg/dwc_otg_pcd.c +index 40fb25c..ae0c72d 100644 +--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd.c +@@ -1120,7 +1120,11 @@ dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if) + return NULL; + } + ++#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK)) ++ DWC_SPINLOCK_ALLOC_LINUX_DEBUG(pcd->lock); ++#else + pcd->lock = DWC_SPINLOCK_ALLOC(); ++#endif + DWC_DEBUGPL(DBG_HCDV, "Init of PCD %p given core_if %p\n", + pcd, core_if);//GRAYG + if (!pcd->lock) { +-- +2.0.4 + + +From 51dd458f1097d92f4731fd497a54954fd8bcc0e5 Mon Sep 17 00:00:00 2001 +From: Kari Suvanto +Date: Tue, 19 Aug 2014 14:38:24 +0300 +Subject: [PATCH 77/77] usb: dwc: fix inconsistent lock state + +Lockdep gives this splat during boot: +[ 4.136748] ================================= +[ 4.145487] [ INFO: inconsistent lock state ] +[ 4.154157] 3.16.1+ #12 Not tainted +[ 4.161852] --------------------------------- +[ 4.170459] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. +[ 4.180776] khubd/18 [HC0[0]:SC0[0]:HE1:SE1] takes: +[ 4.189971] (&((spinlock_t *)hcd->lock)->rlock){?.-...}, at: [] dwc_otg_hcd_qh_free+0x18/0xcc +[ 4.204074] {IN-HARDIRQ-W} state was registered at: +[ 4.213359] [] _raw_spin_lock+0x40/0x50 +[ 4.222743] [] dwc_otg_handle_common_intr+0x44/0xd90 +[ 4.233133] [] dwc_otg_common_irq+0xc/0x18 +[ 4.242739] [] handle_irq_event_percpu+0x34/0x150 +[ 4.252955] [] handle_irq_event+0x3c/0x5c +[ 4.262395] [] handle_level_irq+0x8c/0x130 +[ 4.271972] [] generic_handle_irq+0x28/0x40 +[ 4.281489] [] handle_IRQ+0x30/0x84 +[ 4.290442] [] __irq_svc+0x38/0xd0 +[ 4.299164] [] DWC_MODIFY_REG32+0x64/0x84 +[ 4.308613] [] dwc_otg_driver_probe+0x720/0x7a8 +[ 4.318523] [] platform_drv_probe+0x18/0x48 +[ 4.328141] [] really_probe+0x68/0x200 +[ 4.337334] [] __driver_attach+0xa0/0xa4 +[ 4.346592] [] bus_for_each_dev+0x60/0x94 +[ 4.355998] [] bus_add_driver+0x140/0x1ec +[ 4.365262] [] driver_register+0x78/0xf8 +[ 4.374561] [] dwc_otg_driver_init+0x58/0x114 +[ 4.384271] [] do_one_initcall+0x80/0x1cc +[ 4.393661] [] kernel_init_freeable+0xf0/0x1b0 +[ 4.403501] [] kernel_init+0x8/0xec +[ 4.412308] [] ret_from_fork+0x14/0x2c +[ 4.421444] irq event stamp: 2351 +[ 4.428928] hardirqs last enabled at (2351): [] _raw_spin_unlock_irqrestore+0x7c/0x94 +[ 4.442100] hardirqs last disabled at (2350): [] _raw_spin_lock_irqsave+0x1c/0x64 +[ 4.454802] softirqs last enabled at (2320): [] __do_softirq+0x1ac/0x26c +[ 4.466739] softirqs last disabled at (2297): [] irq_exit+0xac/0x100 +[ 4.478260] +[ 4.478260] other info that might help us debug this: +[ 4.493215] Possible unsafe locking scenario: +[ 4.493215] +[ 4.507451] CPU0 +[ 4.513932] ---- +[ 4.520505] lock(&((spinlock_t *)hcd->lock)->rlock); +[ 4.529767] +[ 4.536515] lock(&((spinlock_t *)hcd->lock)->rlock); +[ 4.545951] +[ 4.545951] *** DEADLOCK *** +[ 4.545951] +[ 4.564132] 3 locks held by khubd/18: +[ 4.571884] #0: (&dev->mutex){......}, at: [] hub_thread+0x98/0x1000 +[ 4.583536] #1: (&port_dev->status_lock){+.+.+.}, at: [] hub_thread+0x63c/0x1000 +[ 4.596241] #2: (&bus->usb_address0_mutex){+.+.+.}, at: [] hub_port_init+0x5c/0xb24 +[ 4.609307] +[ 4.609307] stack backtrace: +[ 4.621705] CPU: 0 PID: 18 Comm: khubd Not tainted 3.16.1+ #12 +[ 4.631643] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) +[ 4.643580] [] (show_stack) from [] (print_usage_bug+0x240/0x2b0) +[ 4.655608] [] (print_usage_bug) from [] (mark_lock+0x1d0/0x67c) +[ 4.667527] [] (mark_lock) from [] (__lock_acquire+0x5d4/0x1ae0) +[ 4.679551] [] (__lock_acquire) from [] (lock_acquire+0x6c/0x8c) +[ 4.691610] [] (lock_acquire) from [] (_raw_spin_lock+0x40/0x50) +[ 4.703584] [] (_raw_spin_lock) from [] (dwc_otg_hcd_qh_free+0x18/0xcc) +[ 4.716305] [] (dwc_otg_hcd_qh_free) from [] (dwc_otg_hcd_endpoint_disable+0x9c/0xb0) +[ 4.730246] [] (dwc_otg_hcd_endpoint_disable) from [] (endpoint_disable+0x18/0x24) +[ 4.743919] [] (endpoint_disable) from [] (usb_ep0_reinit+0x14/0x38) +[ 4.756379] [] (usb_ep0_reinit) from [] (hub_port_init+0x2a4/0xb24) +[ 4.768652] [] (hub_port_init) from [] (hub_thread+0x650/0x1000) +[ 4.780824] [] (hub_thread) from [] (kthread+0xc8/0xe4) +[ 4.792231] [] (kthread) from [] (ret_from_fork+0x14/0x2c) + +This splat shows that the hcd spinlock is used from hard irq context and also from +process context with irqs on. + +To fix this, use spinlock_irqsave instead of spinlock in dwc_otg_hcd_qh_free. + +Signed-off-by: Kari Suvanto +--- + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +index 8706a5c..17d3030 100644 +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +@@ -55,9 +55,10 @@ extern bool microframe_schedule; + void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) + { + dwc_otg_qtd_t *qtd, *qtd_tmp; ++ dwc_irqflags_t flags; + + /* Free each QTD in the QTD list */ +- DWC_SPINLOCK(hcd->lock); ++ DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); + DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { + DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry); + dwc_otg_hcd_qtd_free(qtd); +@@ -76,7 +77,7 @@ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh) + } + + DWC_FREE(qh); +- DWC_SPINUNLOCK(hcd->lock); ++ DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); + return; + } + +-- +2.0.4