[kernel/f20] Add patch set to fix MMC on AM33xx, Add basic support for BeagleBone Black

Peter Robinson pbrobinson at fedoraproject.org
Wed Sep 4 06:42:42 UTC 2013


commit 1ebcd4a33844cb656981f939bba755f3dc6b033f
Author: Peter Robinson <pbrobinson at gmail.com>
Date:   Wed Sep 4 07:41:52 2013 +0100

    Add patch set to fix MMC on AM33xx, Add basic support for BeagleBone Black

 ...-davinci-uart-move-to-devid-based-clk_get.patch |  724 ++++++++++++++++++++
 0001-am335x-dts-Add-beaglebone-black-DTS.patch     |  323 +++++++++
 ...mmc-Correct-usage-of-of_find_node_by_name.patch |   34 +
 ...Add-driver-for-gpio-controlled-reset-pins.patch |  265 +++++++
 ...a-edma-add-device_slave_sg_limits-support.patch |   76 ++
 ...one-Add-I2C-definitions-for-EEPROMs-capes.patch |  142 ++++
 0002-omap_hsmmc-Add-reset-gpio.patch               |  138 ++++
 0003-dmaengine-add-dma_get_slave_sg_limits.patch   |   94 +++
 ...mmc-set-max_segs-based-on-dma-engine-limi.patch |   48 ++
 0005-da8xx-config-Enable-MMC-and-FS-options.patch  |   33 +
 0006-ARM-dts-add-AM33XX-EDMA-support.patch         |   44 ++
 0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch      |   44 ++
 0008-ARM-dts-add-AM33XX-MMC-support.patch          |  191 +++++
 ...lit-out-PaRAM-set-calculations-into-its-o.patch |  271 ++++++++
 0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch     |  130 ++++
 ...oc-dmaengine-pcm-Add-support-for-new-DMAE.patch |   60 ++
 ...mmc-Fix-the-crashes-due-to-the-interrupts.patch |  303 ++++++++
 ...x-clearing-of-unused-list-for-DT-DMA-reso.patch |   65 ++
 arm-am33xx-bbb-dts.patch                           |  230 -------
 kernel.spec                                        |   42 ++-
 20 files changed, 3025 insertions(+), 232 deletions(-)
---
diff --git a/0001-ARM-davinci-uart-move-to-devid-based-clk_get.patch b/0001-ARM-davinci-uart-move-to-devid-based-clk_get.patch
new file mode 100644
index 0000000..0e5b12d
--- /dev/null
+++ b/0001-ARM-davinci-uart-move-to-devid-based-clk_get.patch
@@ -0,0 +1,724 @@
+From da41a8e42998c4bff8b19ee3d9fdfed6a5951c3f Mon Sep 17 00:00:00 2001
+From: "Manjunathappa, Prakash" <prakash.pm at ti.com>
+Date: Wed, 19 Jun 2013 14:45:38 +0530
+Subject: [PATCH 01/13] ARM: davinci: uart: move to devid based clk_get
+
+For modules having single clock, clk_get should be done with dev_id.
+But current davinci implementation handles multiple instances
+of the UART devices with single platform_device_register. Hence clk_get
+is based on con_id rather than dev_id, this is not correct. Do
+platform_device_register for each instance and clk_get on dev_id.
+
+Signed-off-by: Manjunathappa, Prakash <prakash.pm at ti.com>
+Signed-off-by: Sekhar Nori <nsekhar at ti.com>
+---
+ arch/arm/mach-davinci/da830.c                  |  8 ++--
+ arch/arm/mach-davinci/da850.c                  |  8 ++--
+ arch/arm/mach-davinci/devices-da8xx.c          | 42 +++++++++++++++++----
+ arch/arm/mach-davinci/devices-tnetv107x.c      | 37 +++++++++++++++---
+ arch/arm/mach-davinci/dm355.c                  | 52 ++++++++++++++++++++------
+ arch/arm/mach-davinci/dm365.c                  | 38 +++++++++++++------
+ arch/arm/mach-davinci/dm644x.c                 | 52 ++++++++++++++++++++------
+ arch/arm/mach-davinci/dm646x.c                 | 52 ++++++++++++++++++++------
+ arch/arm/mach-davinci/include/mach/da8xx.h     |  2 +-
+ arch/arm/mach-davinci/include/mach/tnetv107x.h |  2 +-
+ arch/arm/mach-davinci/serial.c                 | 19 ++++++----
+ arch/arm/mach-davinci/tnetv107x.c              |  8 ++--
+ 12 files changed, 239 insertions(+), 81 deletions(-)
+
+diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
+index abbaf02..a3ffd52 100644
+--- a/arch/arm/mach-davinci/da830.c
++++ b/arch/arm/mach-davinci/da830.c
+@@ -395,9 +395,9 @@ static struct clk_lookup da830_clks[] = {
+ 	CLK(NULL,		"tptc0",	&tptc0_clk),
+ 	CLK(NULL,		"tptc1",	&tptc1_clk),
+ 	CLK("da830-mmc.0",	NULL,		&mmcsd_clk),
+-	CLK(NULL,		"uart0",	&uart0_clk),
+-	CLK(NULL,		"uart1",	&uart1_clk),
+-	CLK(NULL,		"uart2",	&uart2_clk),
++	CLK("serial8250.0",	NULL,		&uart0_clk),
++	CLK("serial8250.1",	NULL,		&uart1_clk),
++	CLK("serial8250.2",	NULL,		&uart2_clk),
+ 	CLK("spi_davinci.0",	NULL,		&spi0_clk),
+ 	CLK("spi_davinci.1",	NULL,		&spi1_clk),
+ 	CLK(NULL,		"ecap0",	&ecap0_clk),
+@@ -1199,7 +1199,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
+ 	.gpio_base		= DA8XX_GPIO_BASE,
+ 	.gpio_num		= 128,
+ 	.gpio_irq		= IRQ_DA8XX_GPIO0,
+-	.serial_dev		= &da8xx_serial_device,
++	.serial_dev		= da8xx_serial_device,
+ 	.emac_pdata		= &da8xx_emac_pdata,
+ };
+ 
+diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
+index a0d4f60..d4274ab 100644
+--- a/arch/arm/mach-davinci/da850.c
++++ b/arch/arm/mach-davinci/da850.c
+@@ -451,9 +451,9 @@ static struct clk_lookup da850_clks[] = {
+ 	CLK(NULL,		"tpcc1",	&tpcc1_clk),
+ 	CLK(NULL,		"tptc2",	&tptc2_clk),
+ 	CLK("pruss_uio",	"pruss",	&pruss_clk),
+-	CLK(NULL,		"uart0",	&uart0_clk),
+-	CLK(NULL,		"uart1",	&uart1_clk),
+-	CLK(NULL,		"uart2",	&uart2_clk),
++	CLK("serial8250.0",	NULL,		&uart0_clk),
++	CLK("serial8250.1",	NULL,		&uart1_clk),
++	CLK("serial8250.2",	NULL,		&uart2_clk),
+ 	CLK(NULL,		"aintc",	&aintc_clk),
+ 	CLK(NULL,		"gpio",		&gpio_clk),
+ 	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
+@@ -1301,7 +1301,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
+ 	.gpio_base		= DA8XX_GPIO_BASE,
+ 	.gpio_num		= 144,
+ 	.gpio_irq		= IRQ_DA8XX_GPIO0,
+-	.serial_dev		= &da8xx_serial_device,
++	.serial_dev		= da8xx_serial_device,
+ 	.emac_pdata		= &da8xx_emac_pdata,
+ 	.sram_dma		= DA8XX_SHARED_RAM_BASE,
+ 	.sram_len		= SZ_128K,
+diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
+index 71a46a3..280f67d 100644
+--- a/arch/arm/mach-davinci/devices-da8xx.c
++++ b/arch/arm/mach-davinci/devices-da8xx.c
+@@ -68,7 +68,7 @@
+ void __iomem *da8xx_syscfg0_base;
+ void __iomem *da8xx_syscfg1_base;
+ 
+-static struct plat_serial8250_port da8xx_serial_pdata[] = {
++static struct plat_serial8250_port da8xx_serial0_pdata[] = {
+ 	{
+ 		.mapbase	= DA8XX_UART0_BASE,
+ 		.irq		= IRQ_DA8XX_UARTINT0,
+@@ -78,6 +78,11 @@ static struct plat_serial8250_port da8xx_serial_pdata[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port da8xx_serial1_pdata[] = {
++	{
+ 		.mapbase	= DA8XX_UART1_BASE,
+ 		.irq		= IRQ_DA8XX_UARTINT1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -86,6 +91,11 @@ static struct plat_serial8250_port da8xx_serial_pdata[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port da8xx_serial2_pdata[] = {
++	{
+ 		.mapbase	= DA8XX_UART2_BASE,
+ 		.irq		= IRQ_DA8XX_UARTINT2,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -95,15 +105,33 @@ static struct plat_serial8250_port da8xx_serial_pdata[] = {
+ 	},
+ 	{
+ 		.flags	= 0,
+-	},
++	}
+ };
+ 
+-struct platform_device da8xx_serial_device = {
+-	.name	= "serial8250",
+-	.id	= PLAT8250_DEV_PLATFORM,
+-	.dev	= {
+-		.platform_data	= da8xx_serial_pdata,
++struct platform_device da8xx_serial_device[] = {
++	{
++		.name	= "serial8250",
++		.id	= PLAT8250_DEV_PLATFORM,
++		.dev	= {
++			.platform_data	= da8xx_serial0_pdata,
++		}
++	},
++	{
++		.name	= "serial8250",
++		.id	= PLAT8250_DEV_PLATFORM1,
++		.dev	= {
++			.platform_data	= da8xx_serial1_pdata,
++		}
+ 	},
++	{
++		.name	= "serial8250",
++		.id	= PLAT8250_DEV_PLATFORM2,
++		.dev	= {
++			.platform_data	= da8xx_serial2_pdata,
++		}
++	},
++	{
++	}
+ };
+ 
+ static s8 da8xx_queue_tc_mapping[][2] = {
+diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
+index 128cb9a..fc4a0fe 100644
+--- a/arch/arm/mach-davinci/devices-tnetv107x.c
++++ b/arch/arm/mach-davinci/devices-tnetv107x.c
+@@ -126,7 +126,7 @@ static struct platform_device edma_device = {
+ 	.dev.platform_data = tnetv107x_edma_info,
+ };
+ 
+-static struct plat_serial8250_port serial_data[] = {
++static struct plat_serial8250_port serial0_platform_data[] = {
+ 	{
+ 		.mapbase	= TNETV107X_UART0_BASE,
+ 		.irq		= IRQ_TNETV107X_UART0,
+@@ -137,6 +137,11 @@ static struct plat_serial8250_port serial_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port serial1_platform_data[] = {
++	{
+ 		.mapbase	= TNETV107X_UART1_BASE,
+ 		.irq		= IRQ_TNETV107X_UART1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -146,6 +151,11 @@ static struct plat_serial8250_port serial_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port serial2_platform_data[] = {
++	{
+ 		.mapbase	= TNETV107X_UART2_BASE,
+ 		.irq		= IRQ_TNETV107X_UART2,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -156,13 +166,28 @@ static struct plat_serial8250_port serial_data[] = {
+ 	},
+ 	{
+ 		.flags	= 0,
+-	},
++	}
+ };
+ 
+-struct platform_device tnetv107x_serial_device = {
+-	.name			= "serial8250",
+-	.id			= PLAT8250_DEV_PLATFORM,
+-	.dev.platform_data	= serial_data,
++
++struct platform_device tnetv107x_serial_device[] = {
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM,
++		.dev.platform_data	= serial0_platform_data,
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM1,
++		.dev.platform_data	= serial1_platform_data,
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM2,
++		.dev.platform_data	= serial2_platform_data,
++	},
++	{
++	}
+ };
+ 
+ static struct resource mmc0_resources[] = {
+diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
+index 86100d1..1701a2d 100644
+--- a/arch/arm/mach-davinci/dm355.c
++++ b/arch/arm/mach-davinci/dm355.c
+@@ -357,9 +357,9 @@ static struct clk_lookup dm355_clks[] = {
+ 	CLK(NULL, "clkout3", &clkout3_clk),
+ 	CLK(NULL, "arm", &arm_clk),
+ 	CLK(NULL, "mjcp", &mjcp_clk),
+-	CLK(NULL, "uart0", &uart0_clk),
+-	CLK(NULL, "uart1", &uart1_clk),
+-	CLK(NULL, "uart2", &uart2_clk),
++	CLK("serial8250.0", NULL, &uart0_clk),
++	CLK("serial8250.1", NULL, &uart1_clk),
++	CLK("serial8250.2", NULL, &uart2_clk),
+ 	CLK("i2c_davinci.1", NULL, &i2c_clk),
+ 	CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+ 	CLK("davinci-mcbsp.1", NULL, &asp1_clk),
+@@ -922,7 +922,7 @@ static struct davinci_timer_info dm355_timer_info = {
+ 	.clocksource_id	= T0_TOP,
+ };
+ 
+-static struct plat_serial8250_port dm355_serial_platform_data[] = {
++static struct plat_serial8250_port dm355_serial0_platform_data[] = {
+ 	{
+ 		.mapbase	= DAVINCI_UART0_BASE,
+ 		.irq		= IRQ_UARTINT0,
+@@ -932,6 +932,11 @@ static struct plat_serial8250_port dm355_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm355_serial1_platform_data[] = {
++	{
+ 		.mapbase	= DAVINCI_UART1_BASE,
+ 		.irq		= IRQ_UARTINT1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -940,6 +945,11 @@ static struct plat_serial8250_port dm355_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm355_serial2_platform_data[] = {
++	{
+ 		.mapbase	= DM355_UART2_BASE,
+ 		.irq		= IRQ_DM355_UARTINT2,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -948,16 +958,34 @@ static struct plat_serial8250_port dm355_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
+-		.flags		= 0
+-	},
++		.flags	= 0,
++	}
+ };
+ 
+-static struct platform_device dm355_serial_device = {
+-	.name			= "serial8250",
+-	.id			= PLAT8250_DEV_PLATFORM,
+-	.dev			= {
+-		.platform_data	= dm355_serial_platform_data,
++static struct platform_device dm355_serial_device[] = {
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM,
++		.dev			= {
++			.platform_data	= dm355_serial0_platform_data,
++		}
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM1,
++		.dev			= {
++			.platform_data	= dm355_serial1_platform_data,
++		}
+ 	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM2,
++		.dev			= {
++			.platform_data	= dm355_serial2_platform_data,
++		}
++	},
++	{
++	}
+ };
+ 
+ static struct davinci_soc_info davinci_soc_info_dm355 = {
+@@ -981,7 +1009,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
+ 	.gpio_base		= DAVINCI_GPIO_BASE,
+ 	.gpio_num		= 104,
+ 	.gpio_irq		= IRQ_DM355_GPIOBNK0,
+-	.serial_dev		= &dm355_serial_device,
++	.serial_dev		= dm355_serial_device,
+ 	.sram_dma		= 0x00010000,
+ 	.sram_len		= SZ_32K,
+ };
+diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
+index dad2802..5b3a1bc 100644
+--- a/arch/arm/mach-davinci/dm365.c
++++ b/arch/arm/mach-davinci/dm365.c
+@@ -455,8 +455,8 @@ static struct clk_lookup dm365_clks[] = {
+ 	CLK("vpss", "master", &vpss_master_clk),
+ 	CLK("vpss", "slave", &vpss_slave_clk),
+ 	CLK(NULL, "arm", &arm_clk),
+-	CLK(NULL, "uart0", &uart0_clk),
+-	CLK(NULL, "uart1", &uart1_clk),
++	CLK("serial8250.0", NULL, &uart0_clk),
++	CLK("serial8250.1", NULL, &uart1_clk),
+ 	CLK("i2c_davinci.1", NULL, &i2c_clk),
+ 	CLK("da830-mmc.0", NULL, &mmcsd0_clk),
+ 	CLK("da830-mmc.1", NULL, &mmcsd1_clk),
+@@ -1041,7 +1041,7 @@ static struct davinci_timer_info dm365_timer_info = {
+ 
+ #define DM365_UART1_BASE	(IO_PHYS + 0x106000)
+ 
+-static struct plat_serial8250_port dm365_serial_platform_data[] = {
++static struct plat_serial8250_port dm365_serial0_platform_data[] = {
+ 	{
+ 		.mapbase	= DAVINCI_UART0_BASE,
+ 		.irq		= IRQ_UARTINT0,
+@@ -1051,6 +1051,11 @@ static struct plat_serial8250_port dm365_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm365_serial1_platform_data[] = {
++	{
+ 		.mapbase	= DM365_UART1_BASE,
+ 		.irq		= IRQ_UARTINT1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -1059,16 +1064,27 @@ static struct plat_serial8250_port dm365_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
+-		.flags		= 0
+-	},
++		.flags	= 0,
++	}
+ };
+ 
+-static struct platform_device dm365_serial_device = {
+-	.name			= "serial8250",
+-	.id			= PLAT8250_DEV_PLATFORM,
+-	.dev			= {
+-		.platform_data	= dm365_serial_platform_data,
++static struct platform_device dm365_serial_device[] = {
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM,
++		.dev			= {
++			.platform_data	= dm365_serial0_platform_data,
++		}
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM1,
++		.dev			= {
++			.platform_data	= dm365_serial1_platform_data,
++		}
+ 	},
++	{
++	}
+ };
+ 
+ static struct davinci_soc_info davinci_soc_info_dm365 = {
+@@ -1093,7 +1109,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
+ 	.gpio_num		= 104,
+ 	.gpio_irq		= IRQ_DM365_GPIO0,
+ 	.gpio_unbanked		= 8,	/* really 16 ... skip muxed GPIOs */
+-	.serial_dev		= &dm365_serial_device,
++	.serial_dev		= dm365_serial_device,
+ 	.emac_pdata		= &dm365_emac_pdata,
+ 	.sram_dma		= 0x00010000,
+ 	.sram_len		= SZ_32K,
+diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
+index a49d182..490eb8c 100644
+--- a/arch/arm/mach-davinci/dm644x.c
++++ b/arch/arm/mach-davinci/dm644x.c
+@@ -303,9 +303,9 @@ static struct clk_lookup dm644x_clks[] = {
+ 	CLK("vpss", "master", &vpss_master_clk),
+ 	CLK("vpss", "slave", &vpss_slave_clk),
+ 	CLK(NULL, "arm", &arm_clk),
+-	CLK(NULL, "uart0", &uart0_clk),
+-	CLK(NULL, "uart1", &uart1_clk),
+-	CLK(NULL, "uart2", &uart2_clk),
++	CLK("serial8250.0", NULL, &uart0_clk),
++	CLK("serial8250.1", NULL, &uart1_clk),
++	CLK("serial8250.2", NULL, &uart2_clk),
+ 	CLK("davinci_emac.1", NULL, &emac_clk),
+ 	CLK("i2c_davinci.1", NULL, &i2c_clk),
+ 	CLK("palm_bk3710", NULL, &ide_clk),
+@@ -813,7 +813,7 @@ static struct davinci_timer_info dm644x_timer_info = {
+ 	.clocksource_id	= T0_TOP,
+ };
+ 
+-static struct plat_serial8250_port dm644x_serial_platform_data[] = {
++static struct plat_serial8250_port dm644x_serial0_platform_data[] = {
+ 	{
+ 		.mapbase	= DAVINCI_UART0_BASE,
+ 		.irq		= IRQ_UARTINT0,
+@@ -823,6 +823,11 @@ static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm644x_serial1_platform_data[] = {
++	{
+ 		.mapbase	= DAVINCI_UART1_BASE,
+ 		.irq		= IRQ_UARTINT1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -831,6 +836,11 @@ static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm644x_serial2_platform_data[] = {
++	{
+ 		.mapbase	= DAVINCI_UART2_BASE,
+ 		.irq		= IRQ_UARTINT2,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -839,16 +849,34 @@ static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
+-		.flags		= 0
+-	},
++		.flags	= 0,
++	}
+ };
+ 
+-static struct platform_device dm644x_serial_device = {
+-	.name			= "serial8250",
+-	.id			= PLAT8250_DEV_PLATFORM,
+-	.dev			= {
+-		.platform_data	= dm644x_serial_platform_data,
++static struct platform_device dm644x_serial_device[] = {
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM,
++		.dev			= {
++			.platform_data	= dm644x_serial0_platform_data,
++		}
+ 	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM1,
++		.dev			= {
++			.platform_data	= dm644x_serial1_platform_data,
++		}
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM2,
++		.dev			= {
++			.platform_data	= dm644x_serial2_platform_data,
++		}
++	},
++	{
++	}
+ };
+ 
+ static struct davinci_soc_info davinci_soc_info_dm644x = {
+@@ -872,7 +900,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
+ 	.gpio_base		= DAVINCI_GPIO_BASE,
+ 	.gpio_num		= 71,
+ 	.gpio_irq		= IRQ_GPIOBNK0,
+-	.serial_dev		= &dm644x_serial_device,
++	.serial_dev		= dm644x_serial_device,
+ 	.emac_pdata		= &dm644x_emac_pdata,
+ 	.sram_dma		= 0x00008000,
+ 	.sram_len		= SZ_16K,
+diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
+index d1259e8..23609b1 100644
+--- a/arch/arm/mach-davinci/dm646x.c
++++ b/arch/arm/mach-davinci/dm646x.c
+@@ -342,9 +342,9 @@ static struct clk_lookup dm646x_clks[] = {
+ 	CLK(NULL, "edma_tc1", &edma_tc1_clk),
+ 	CLK(NULL, "edma_tc2", &edma_tc2_clk),
+ 	CLK(NULL, "edma_tc3", &edma_tc3_clk),
+-	CLK(NULL, "uart0", &uart0_clk),
+-	CLK(NULL, "uart1", &uart1_clk),
+-	CLK(NULL, "uart2", &uart2_clk),
++	CLK("serial8250.0", NULL, &uart0_clk),
++	CLK("serial8250.1", NULL, &uart1_clk),
++	CLK("serial8250.2", NULL, &uart2_clk),
+ 	CLK("i2c_davinci.1", NULL, &i2c_clk),
+ 	CLK(NULL, "gpio", &gpio_clk),
+ 	CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+@@ -790,7 +790,7 @@ static struct davinci_timer_info dm646x_timer_info = {
+ 	.clocksource_id	= T0_TOP,
+ };
+ 
+-static struct plat_serial8250_port dm646x_serial_platform_data[] = {
++static struct plat_serial8250_port dm646x_serial0_platform_data[] = {
+ 	{
+ 		.mapbase	= DAVINCI_UART0_BASE,
+ 		.irq		= IRQ_UARTINT0,
+@@ -800,6 +800,11 @@ static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm646x_serial1_platform_data[] = {
++	{
+ 		.mapbase	= DAVINCI_UART1_BASE,
+ 		.irq		= IRQ_UARTINT1,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -808,6 +813,11 @@ static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
++		.flags	= 0,
++	}
++};
++static struct plat_serial8250_port dm646x_serial2_platform_data[] = {
++	{
+ 		.mapbase	= DAVINCI_UART2_BASE,
+ 		.irq		= IRQ_DM646X_UARTINT2,
+ 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+@@ -816,16 +826,34 @@ static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+ 		.regshift	= 2,
+ 	},
+ 	{
+-		.flags		= 0
+-	},
++		.flags	= 0,
++	}
+ };
+ 
+-static struct platform_device dm646x_serial_device = {
+-	.name			= "serial8250",
+-	.id			= PLAT8250_DEV_PLATFORM,
+-	.dev			= {
+-		.platform_data	= dm646x_serial_platform_data,
++static struct platform_device dm646x_serial_device[] = {
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM,
++		.dev			= {
++			.platform_data	= dm646x_serial0_platform_data,
++		}
++	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM1,
++		.dev			= {
++			.platform_data	= dm646x_serial1_platform_data,
++		}
+ 	},
++	{
++		.name			= "serial8250",
++		.id			= PLAT8250_DEV_PLATFORM2,
++		.dev			= {
++			.platform_data	= dm646x_serial2_platform_data,
++		}
++	},
++	{
++	}
+ };
+ 
+ static struct davinci_soc_info davinci_soc_info_dm646x = {
+@@ -849,7 +877,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
+ 	.gpio_base		= DAVINCI_GPIO_BASE,
+ 	.gpio_num		= 43, /* Only 33 usable */
+ 	.gpio_irq		= IRQ_DM646X_GPIOBNK0,
+-	.serial_dev		= &dm646x_serial_device,
++	.serial_dev		= dm646x_serial_device,
+ 	.emac_pdata		= &dm646x_emac_pdata,
+ 	.sram_dma		= 0x10010000,
+ 	.sram_len		= SZ_32K,
+diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
+index 7b41a5e..aae5307 100644
+--- a/arch/arm/mach-davinci/include/mach/da8xx.h
++++ b/arch/arm/mach-davinci/include/mach/da8xx.h
+@@ -111,7 +111,7 @@ void da8xx_restart(enum reboot_mode mode, const char *cmd);
+ void da8xx_rproc_reserve_cma(void);
+ int da8xx_register_rproc(void);
+ 
+-extern struct platform_device da8xx_serial_device;
++extern struct platform_device da8xx_serial_device[];
+ extern struct emac_platform_data da8xx_emac_pdata;
+ extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
+ extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
+diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
+index 16314c6..beb7c0e 100644
+--- a/arch/arm/mach-davinci/include/mach/tnetv107x.h
++++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h
+@@ -50,7 +50,7 @@ struct tnetv107x_device_info {
+ };
+ 
+ extern struct platform_device tnetv107x_wdt_device;
+-extern struct platform_device tnetv107x_serial_device;
++extern struct platform_device tnetv107x_serial_device[];
+ 
+ extern void tnetv107x_init(void);
+ extern void tnetv107x_devices_init(struct tnetv107x_device_info *);
+diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
+index f262581..57e6150 100644
+--- a/arch/arm/mach-davinci/serial.c
++++ b/arch/arm/mach-davinci/serial.c
+@@ -76,7 +76,7 @@ int __init davinci_serial_setup_clk(unsigned instance, unsigned int *rate)
+ 	char name[16];
+ 	struct clk *clk;
+ 	struct davinci_soc_info *soc_info = &davinci_soc_info;
+-	struct device *dev = &soc_info->serial_dev->dev;
++	struct device *dev = &soc_info->serial_dev[instance].dev;
+ 
+ 	sprintf(name, "uart%d", instance);
+ 	clk = clk_get(dev, name);
+@@ -96,19 +96,25 @@ int __init davinci_serial_setup_clk(unsigned instance, unsigned int *rate)
+ 
+ int __init davinci_serial_init(struct davinci_uart_config *info)
+ {
+-	int i, ret;
++	int i, ret = 0;
+ 	struct davinci_soc_info *soc_info = &davinci_soc_info;
+-	struct device *dev = &soc_info->serial_dev->dev;
+-	struct plat_serial8250_port *p = dev->platform_data;
++	struct device *dev;
++	struct plat_serial8250_port *p;
+ 
+ 	/*
+ 	 * Make sure the serial ports are muxed on at this point.
+ 	 * You have to mux them off in device drivers later on if not needed.
+ 	 */
+-	for (i = 0; p->flags; i++, p++) {
++	for (i = 0; soc_info->serial_dev[i].dev.platform_data != NULL; i++) {
++		dev = &soc_info->serial_dev[i].dev;
++		p = dev->platform_data;
+ 		if (!(info->enabled_uarts & (1 << i)))
+ 			continue;
+ 
++		ret = platform_device_register(&soc_info->serial_dev[i]);
++		if (ret)
++			continue;
++
+ 		ret = davinci_serial_setup_clk(i, &p->uartclk);
+ 		if (ret)
+ 			continue;
+@@ -125,6 +131,5 @@ int __init davinci_serial_init(struct davinci_uart_config *info)
+ 		if (p->membase && p->type != PORT_AR7)
+ 			davinci_serial_reset(p);
+ 	}
+-
+-	return platform_device_register(soc_info->serial_dev);
++	return ret;
+ }
+diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
+index 4545667..f4d7fbb 100644
+--- a/arch/arm/mach-davinci/tnetv107x.c
++++ b/arch/arm/mach-davinci/tnetv107x.c
+@@ -264,7 +264,7 @@ static struct clk_lookup clks[] = {
+ 	CLK(NULL,		"clk_chipcfg",		&clk_chipcfg),
+ 	CLK("tnetv107x-ts.0",	NULL,			&clk_tsc),
+ 	CLK(NULL,		"clk_rom",		&clk_rom),
+-	CLK(NULL,		"uart2",		&clk_uart2),
++	CLK("serial8250.2",     NULL,			&clk_uart2),
+ 	CLK(NULL,		"clk_pktsec",		&clk_pktsec),
+ 	CLK("tnetv107x-rng.0",	NULL,			&clk_rng),
+ 	CLK("tnetv107x-pka.0",	NULL,			&clk_pka),
+@@ -274,8 +274,8 @@ static struct clk_lookup clks[] = {
+ 	CLK(NULL,		"clk_gpio",		&clk_gpio),
+ 	CLK(NULL,		"clk_mdio",		&clk_mdio),
+ 	CLK("dm6441-mmc.0",	NULL,			&clk_sdio0),
+-	CLK(NULL,		"uart0",		&clk_uart0),
+-	CLK(NULL,		"uart1",		&clk_uart1),
++	CLK("serial8250.0",	NULL,			&clk_uart0),
++	CLK("serial8250.1",	NULL,			&clk_uart1),
+ 	CLK(NULL,		"timer0",		&clk_timer0),
+ 	CLK(NULL,		"timer1",		&clk_timer1),
+ 	CLK("tnetv107x_wdt.0",	NULL,			&clk_wdt_arm),
+@@ -757,7 +757,7 @@ static struct davinci_soc_info tnetv107x_soc_info = {
+ 	.gpio_type		= GPIO_TYPE_TNETV107X,
+ 	.gpio_num		= TNETV107X_N_GPIO,
+ 	.timer_info		= &timer_info,
+-	.serial_dev		= &tnetv107x_serial_device,
++	.serial_dev		= tnetv107x_serial_device,
+ };
+ 
+ void __init tnetv107x_init(void)
+-- 
+1.8.2.1
+
diff --git a/0001-am335x-dts-Add-beaglebone-black-DTS.patch b/0001-am335x-dts-Add-beaglebone-black-DTS.patch
new file mode 100644
index 0000000..f104432
--- /dev/null
+++ b/0001-am335x-dts-Add-beaglebone-black-DTS.patch
@@ -0,0 +1,323 @@
+From 35bd7cf94f2680c4674c1df72f9ab322f393a9c2 Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <panto at antoniou-consulting.com>
+Date: Fri, 28 Jun 2013 14:18:08 +0300
+Subject: [PATCH 1/4] am335x: dts: Add beaglebone black DTS
+
+Added the beaglebone black's DTS file. Note that at some point in
+time we'll switch to using a common black.dtsi file.
+
+Signed-off-by: Pantelis Antoniou <panto at antoniou-consulting.com>
+---
+ arch/arm/boot/dts/Makefile             |   3 +-
+ arch/arm/boot/dts/am335x-boneblack.dts | 285 +++++++++++++++++++++++++++++++++
+ 2 files changed, 287 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/am335x-boneblack.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 641b3c9a..1b60731 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -173,7 +173,8 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
+ 	am335x-bone.dtb \
+ 	am3517-evm.dtb \
+ 	am3517_mt_ventoux.dtb \
+-	am43x-epos-evm.dtb
++	am43x-epos-evm.dtb \
++	am335x-boneblack.dtb
+ dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
+ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+ dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+new file mode 100644
+index 0000000..75a924d
+--- /dev/null
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -0,0 +1,285 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++
++#include "am33xx.dtsi"
++
++/ {
++	model = "TI AM335x BeagleBone";
++	compatible = "ti,am335x-bone", "ti,am33xx";
++
++	cpus {
++		cpu at 0 {
++			cpu0-supply = <&dcdc2_reg>;
++
++			/*
++			 * To consider voltage drop between PMIC and SoC,
++			 * tolerance value is reduced to 2% from 4% and
++			 * voltage value is increased as a precaution.
++			 */
++			operating-points = <
++				/* kHz    uV */
++				1000000	1350000
++				800000	1300000
++				600000  1112000
++				300000   969000
++			>;
++		};
++	};
++
++	memory {
++		device_type = "memory";
++		reg = <0x80000000 0x20000000>; /* 512 MB */
++	};
++
++	am33xx_pinmux: pinmux at 44e10800 {
++		pinctrl-names = "default";
++		pinctrl-0 = <&clkout2_pin>;
++
++		user_leds_s0: user_leds_s0 {
++			pinctrl-single,pins = <
++				0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a5.gpio1_21 */
++				0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a6.gpio1_22 */
++				0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a7.gpio1_23 */
++				0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a8.gpio1_24 */
++			>;
++		};
++
++		i2c0_pins: pinmux_i2c0_pins {
++			pinctrl-single,pins = <
++				0x188 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
++				0x18c (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
++			>;
++		};
++
++		uart0_pins: pinmux_uart0_pins {
++			pinctrl-single,pins = <
++				0x170 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
++				0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
++			>;
++		};
++
++		clkout2_pin: pinmux_clkout2_pin {
++			pinctrl-single,pins = <
++				0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* xdma_event_intr1.clkout2 */
++			>;
++		};
++
++		cpsw_default: cpsw_default {
++			pinctrl-single,pins = <
++				/* Slave 1 */
++				0x110 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxerr.mii1_rxerr */
++				0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txen.mii1_txen */
++				0x118 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxdv.mii1_rxdv */
++				0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd3.mii1_txd3 */
++				0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd2.mii1_txd2 */
++				0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd1.mii1_txd1 */
++				0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd0.mii1_txd0 */
++				0x12c (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_txclk.mii1_txclk */
++				0x130 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxclk.mii1_rxclk */
++				0x134 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd3.mii1_rxd3 */
++				0x138 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd2.mii1_rxd2 */
++				0x13c (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd1.mii1_rxd1 */
++				0x140 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd0.mii1_rxd0 */
++			>;
++		};
++
++		cpsw_sleep: cpsw_sleep {
++			pinctrl-single,pins = <
++				/* Slave 1 reset value */
++				0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++			>;
++		};
++
++		davinci_mdio_default: davinci_mdio_default {
++			pinctrl-single,pins = <
++				/* MDIO */
++				0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
++				0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
++			>;
++		};
++
++		davinci_mdio_sleep: davinci_mdio_sleep {
++			pinctrl-single,pins = <
++				/* MDIO reset value */
++				0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
++				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
++			>;
++		};
++
++		emmc_pins: pinmux_emmc_pins {
++			pinctrl-single,pins = <
++				0x80 (PIN_INPUT_PULLUP | MUX_MODE2)	/* gpmc_csn1.mmc1_clk */
++				0x84 (PIN_INPUT_PULLUP | MUX_MODE2)	/* gpmc_csn2.mmc1_cmd */
++				0x00 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad0.mmc1_dat0 */
++				0x04 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad1.mmc1_dat1 */
++				0x08 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad2.mmc1_dat2 */
++				0x0c (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad3.mmc1_dat3 */
++				0x10 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad4.mmc1_dat4 */
++				0x14 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad5.mmc1_dat5 */
++				0x18 (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad6.mmc1_dat6 */
++				0x1c (PIN_INPUT_PULLUP | MUX_MODE1)	/* gpmc_ad7.mmc1_dat7 */
++				/* eMMC_RSTn */
++				0x50 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a4.gpio1_20 */
++			>;
++		};
++	};
++
++	ocp {
++		uart0: serial at 44e09000 {
++			pinctrl-names = "default";
++			pinctrl-0 = <&uart0_pins>;
++
++			status = "okay";
++		};
++
++		i2c0: i2c at 44e0b000 {
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c0_pins>;
++
++			status = "okay";
++			clock-frequency = <400000>;
++
++			tps: tps at 24 {
++				reg = <0x24>;
++			};
++
++		};
++	};
++
++	leds {
++		pinctrl-names = "default";
++		pinctrl-0 = <&user_leds_s0>;
++
++		compatible = "gpio-leds";
++
++		led at 2 {
++			label = "beaglebone:blue:heartbeat";
++			gpios = <&gpio1 21 0>;
++			linux,default-trigger = "heartbeat";
++			default-state = "off";
++		};
++
++		led at 3 {
++			label = "beaglebone:blue:mmc0";
++			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
++			linux,default-trigger = "mmc0";
++			default-state = "off";
++		};
++
++		led at 4 {
++			label = "beaglebone:blue:usr2";
++			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
++			default-state = "off";
++		};
++
++		led at 5 {
++			label = "beaglebone:blue:usr3";
++			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
++			default-state = "off";
++		};
++	};
++
++	vmmcsd_fixed: fixedregulator at 0 {
++		compatible = "regulator-fixed";
++		regulator-name = "vmmcsd_fixed";
++		regulator-min-microvolt = <3300000>;
++		regulator-max-microvolt = <3300000>;
++	};
++
++};
++
++/include/ "tps65217.dtsi"
++
++&tps {
++	regulators {
++		dcdc1_reg: regulator at 0 {
++			regulator-always-on;
++		};
++
++		dcdc2_reg: regulator at 1 {
++			/* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
++			regulator-name = "vdd_mpu";
++			regulator-min-microvolt = <925000>;
++			regulator-max-microvolt = <1325000>;
++			regulator-boot-on;
++			regulator-always-on;
++		};
++
++		dcdc3_reg: regulator at 2 {
++			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
++			regulator-name = "vdd_core";
++			regulator-min-microvolt = <925000>;
++			regulator-max-microvolt = <1150000>;
++			regulator-boot-on;
++			regulator-always-on;
++		};
++
++		ldo1_reg: regulator at 3 {
++			regulator-always-on;
++		};
++
++		ldo2_reg: regulator at 4 {
++			regulator-always-on;
++		};
++
++		ldo3_reg: regulator at 5 {
++			regulator-min-microvolt = <1800000>;
++			regulator-max-microvolt = <1800000>;	/* orig 3.3V*/
++			regulator-always-on;
++		};
++
++		ldo4_reg: regulator at 6 {
++			regulator-always-on;
++		};
++	};
++};
++
++&cpsw_emac0 {
++	phy_id = <&davinci_mdio>, <0>;
++};
++
++&cpsw_emac1 {
++	phy_id = <&davinci_mdio>, <1>;
++};
++
++&mac {
++	pinctrl-names = "default", "sleep";
++	pinctrl-0 = <&cpsw_default>;
++	pinctrl-1 = <&cpsw_sleep>;
++};
++
++&mmc1 {
++	status = "okay";
++	vmmc-supply = <&vmmcsd_fixed>;
++	ti,vcc-aux-disable-is-sleep;
++};
++
++&mmc2 {
++	pinctrl-names = "default";
++	pinctrl-0 = <&emmc_pins>;
++	vmmc-supply = <&ldo3_reg>;
++	bus-width = <8>;
++	ti,non-removable;
++	status = "okay";
++	ti,vcc-aux-disable-is-sleep;
++
++	reset-gpio = <&gpio1 20 GPIO_ACTIVE_HIGH>;
++};
+-- 
+1.8.2.1
+
diff --git a/0001-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch b/0001-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
new file mode 100644
index 0000000..2c7bc63
--- /dev/null
+++ b/0001-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
@@ -0,0 +1,34 @@
+From 9e6eeee6a1e0477f237dee5015c982296a91403f Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <panto at antoniou-consulting.com>
+Date: Fri, 26 Oct 2012 15:48:00 +0300
+Subject: [PATCH 1/2] omap-hsmmc: Correct usage of of_find_node_by_name
+
+of_find_node_by_name expect to have the parent node reference taken.
+---
+ drivers/mmc/host/omap_hsmmc.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index 91e2954..8ab4a93 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1949,6 +1949,16 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 	 * as we want. */
+ 	mmc->max_segs = 1024;
+ 
++	/* Eventually we should get our max_segs limitation for EDMA by
++	 * querying the dmaengine API */
++	if (pdev->dev.of_node) {
++		struct device_node *parent = of_node_get(pdev->dev.of_node->parent);
++		struct device_node *node;
++		node = of_find_node_by_name(parent, "edma");
++		if (node)
++			mmc->max_segs = 16;
++	}
++
+ 	mmc->max_blk_size = 512;       /* Block Length at max can be 1024 */
+ 	mmc->max_blk_count = 0xFFFF;    /* No. of Blocks is 16 bits */
+ 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+-- 
+1.8.2.1
+
diff --git a/0001-reset-Add-driver-for-gpio-controlled-reset-pins.patch b/0001-reset-Add-driver-for-gpio-controlled-reset-pins.patch
new file mode 100644
index 0000000..e5661ae
--- /dev/null
+++ b/0001-reset-Add-driver-for-gpio-controlled-reset-pins.patch
@@ -0,0 +1,265 @@
+From 31bacc8256b3ddb19269a3a1c74b0ba3851d1e19 Mon Sep 17 00:00:00 2001
+From: Philipp Zabel <p.zabel at pengutronix.de>
+Date: Tue, 28 May 2013 17:06:15 +0200
+Subject: [PATCH] reset: Add driver for gpio-controlled reset pins
+
+This driver implements a reset controller device that toggle a gpio
+connected to a reset pin of a peripheral IC. The delay between assertion
+and de-assertion of the reset signal can be configured via device tree.
+
+Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
+Reviewed-by: Stephen Warren <swarren at nvidia.com>
+---
+ .../devicetree/bindings/reset/gpio-reset.txt       |  35 +++++
+ drivers/reset/Kconfig                              |  11 ++
+ drivers/reset/Makefile                             |   1 +
+ drivers/reset/gpio-reset.c                         | 169 +++++++++++++++++++++
+ 4 files changed, 216 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/reset/gpio-reset.txt
+ create mode 100644 drivers/reset/gpio-reset.c
+
+diff --git a/Documentation/devicetree/bindings/reset/gpio-reset.txt b/Documentation/devicetree/bindings/reset/gpio-reset.txt
+new file mode 100644
+index 0000000..bca5348
+--- /dev/null
++++ b/Documentation/devicetree/bindings/reset/gpio-reset.txt
+@@ -0,0 +1,35 @@
++GPIO reset controller
++=====================
++
++A GPIO reset controller controls a single GPIO that is connected to the reset
++pin of a peripheral IC. Please also refer to reset.txt in this directory for
++common reset controller binding usage.
++
++Required properties:
++- compatible: Should be "gpio-reset"
++- reset-gpios: A gpio used as reset line. The gpio specifier for this property
++               depends on the gpio controller that provides the gpio.
++- #reset-cells: 0, see below
++
++Optional properties:
++- reset-delay-us: delay in microseconds. The gpio reset line will be asserted for
++                  this duration to reset.
++- initially-in-reset: boolean. If not set, the initial state should be a
++                      deasserted reset line. If this property exists, the
++                      reset line should be kept in reset.
++
++example:
++
++sii902x_reset: gpio-reset {
++	compatible = "gpio-reset";
++	reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
++	reset-delay-us = <10000>;
++	initially-in-reset;
++	#reset-cells = <0>;
++};
++
++/* Device with nRESET pin connected to GPIO5_0 */
++sii902x at 39 {
++	/* ... */
++	resets = <&sii902x_reset>; /* active-low GPIO5_0, 10 ms delay */
++};
+diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
+index c9d04f7..1a862df 100644
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -11,3 +11,14 @@ menuconfig RESET_CONTROLLER
+ 	  via GPIOs or SoC-internal reset controller modules.
+ 
+ 	  If unsure, say no.
++
++if RESET_CONTROLLER
++
++config RESET_GPIO
++	tristate "GPIO reset controller support"
++	depends on GPIOLIB && OF
++	help
++	  This driver provides support for reset lines that are controlled
++	  directly by GPIOs.
++
++endif
+diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
+index 1e2d83f..b854f20 100644
+--- a/drivers/reset/Makefile
++++ b/drivers/reset/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_RESET_CONTROLLER) += core.o
++obj-$(CONFIG_RESET_GPIO) += gpio-reset.o
+diff --git a/drivers/reset/gpio-reset.c b/drivers/reset/gpio-reset.c
+new file mode 100644
+index 0000000..acc1076
+--- /dev/null
++++ b/drivers/reset/gpio-reset.c
+@@ -0,0 +1,169 @@
++/*
++ * GPIO Reset Controller driver
++ *
++ * Copyright 2013 Philipp Zabel, Pengutronix
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/reset-controller.h>
++
++struct gpio_reset_data {
++	struct reset_controller_dev rcdev;
++	unsigned int gpio;
++	bool active_low;
++	u32 delay_us;
++};
++
++static void __gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
++{
++	struct gpio_reset_data *drvdata = container_of(rcdev,
++			struct gpio_reset_data, rcdev);
++	int value = asserted;
++
++	if (drvdata->active_low)
++		value = !value;
++
++	gpio_set_value(drvdata->gpio, value);
++}
++
++static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
++{
++	struct gpio_reset_data *drvdata = container_of(rcdev,
++			struct gpio_reset_data, rcdev);
++
++	if (drvdata->delay_us < 0)
++		return -ENOSYS;
++
++	__gpio_reset_set(rcdev, 1);
++	udelay(drvdata->delay_us);
++	__gpio_reset_set(rcdev, 0);
++
++	return 0;
++}
++
++static int gpio_reset_assert(struct reset_controller_dev *rcdev,
++		unsigned long id)
++{
++	__gpio_reset_set(rcdev, 1);
++
++	return 0;
++}
++
++static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
++		unsigned long id)
++{
++	__gpio_reset_set(rcdev, 0);
++
++	return 0;
++}
++
++static struct reset_control_ops gpio_reset_ops = {
++	.reset = gpio_reset,
++	.assert = gpio_reset_assert,
++	.deassert = gpio_reset_deassert,
++};
++
++static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
++			       const struct of_phandle_args *reset_spec)
++{
++	if (WARN_ON(reset_spec->args_count != 0))
++		return -EINVAL;
++
++	return 0;
++}
++
++static int gpio_reset_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct gpio_reset_data *drvdata;
++	enum of_gpio_flags flags;
++	unsigned long gpio_flags;
++	bool initially_in_reset;
++	int ret;
++
++	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
++	if (drvdata == NULL)
++		return -ENOMEM;
++
++	if (of_gpio_named_count(np, "reset-gpios") != 1)
++		return -EINVAL;
++
++	drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
++	if (drvdata->gpio == -EPROBE_DEFER) {
++		return drvdata->gpio;
++	} else if (!gpio_is_valid(drvdata->gpio)) {
++		dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
++		return drvdata->gpio;
++	}
++
++	drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;
++
++	ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
++	if (ret < 0)
++		return ret;
++
++	initially_in_reset = of_property_read_bool(np, "initially-in-reset");
++	if (drvdata->active_low ^ initially_in_reset)
++		gpio_flags = GPIOF_OUT_INIT_HIGH;
++	else
++		gpio_flags = GPIOF_OUT_INIT_LOW;
++
++	ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
++			drvdata->gpio, ret);
++		return ret;
++	}
++
++	drvdata->rcdev.of_node = np;
++	drvdata->rcdev.owner = THIS_MODULE;
++	drvdata->rcdev.nr_resets = 1;
++	drvdata->rcdev.ops = &gpio_reset_ops;
++	drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
++	reset_controller_register(&drvdata->rcdev);
++
++	platform_set_drvdata(pdev, drvdata);
++
++	return 0;
++}
++
++static int gpio_reset_remove(struct platform_device *pdev)
++{
++	struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);
++
++	reset_controller_unregister(&drvdata->rcdev);
++
++	return 0;
++}
++
++static struct of_device_id gpio_reset_dt_ids[] = {
++	{ .compatible = "gpio-reset" },
++	{ }
++};
++
++static struct platform_driver gpio_reset_driver = {
++	.probe = gpio_reset_probe,
++	.remove = gpio_reset_remove,
++	.driver = {
++		.name = "gpio-reset",
++		.owner = THIS_MODULE,
++		.of_match_table = of_match_ptr(gpio_reset_dt_ids),
++	},
++};
++
++module_platform_driver(gpio_reset_driver);
++
++MODULE_AUTHOR("Philipp Zabel <p.zabel at pengutronix.de>");
++MODULE_DESCRIPTION("gpio reset controller");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:gpio-reset");
++MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
+-- 
+1.8.2.1
+
diff --git a/0002-dma-edma-add-device_slave_sg_limits-support.patch b/0002-dma-edma-add-device_slave_sg_limits-support.patch
new file mode 100644
index 0000000..419b320
--- /dev/null
+++ b/0002-dma-edma-add-device_slave_sg_limits-support.patch
@@ -0,0 +1,76 @@
+From 6077fbf31d4263222eb1815f1c4edf67e90a3434 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter at ti.com>
+Date: Wed, 6 Mar 2013 19:56:06 +0000
+Subject: [PATCH 02/13] dma: edma: add device_slave_sg_limits() support
+
+Implement device_slave_sg_limits().
+
+EDMA has a finite set of PaRAM slots available for linking a
+multi-segment SG transfer. In order to prevent any one channel
+from consuming all PaRAM slots to fulfill a large SG transfer,
+the driver reports a static per-channel max number of SG segments
+it will handle.
+
+The maximum size of an SG segment is limited by the addr_width
+and maxburst of a given transfer request. These values are
+provided by the client driver and used to calculate and return
+the maximum segment length.
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Signed-off-by: Joel A Fernandes <joelagnel at ti.com>
+---
+ drivers/dma/edma.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
+index 5f3e532..e008ed2 100644
+--- a/drivers/dma/edma.c
++++ b/drivers/dma/edma.c
+@@ -70,6 +70,7 @@ struct edma_chan {
+ 	bool				alloced;
+ 	int				slot[EDMA_MAX_SLOTS];
+ 	struct dma_slave_config		cfg;
++	struct dma_slave_sg_limits	sg_limits;
+ };
+ 
+ struct edma_cc {
+@@ -462,6 +463,20 @@ static void edma_issue_pending(struct dma_chan *chan)
+ 	spin_unlock_irqrestore(&echan->vchan.lock, flags);
+ }
+ 
++static struct dma_slave_sg_limits
++*edma_get_slave_sg_limits(struct dma_chan *chan,
++			enum dma_slave_buswidth addr_width,
++			u32 maxburst)
++{
++	struct edma_chan *echan;
++
++	echan = to_edma_chan(chan);
++	echan->sg_limits.max_seg_len =
++		(SZ_64K - 1) * addr_width * maxburst;
++
++	return &echan->sg_limits;
++}
++
+ static size_t edma_desc_size(struct edma_desc *edesc)
+ {
+ 	int i;
+@@ -521,6 +536,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
+ 		echan->ch_num = EDMA_CTLR_CHAN(ecc->ctlr, i);
+ 		echan->ecc = ecc;
+ 		echan->vchan.desc_free = edma_desc_free;
++		echan->sg_limits.max_seg_nr = MAX_NR_SG;
+ 
+ 		vchan_init(&echan->vchan, dma);
+ 
+@@ -537,6 +553,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
+ 	dma->device_alloc_chan_resources = edma_alloc_chan_resources;
+ 	dma->device_free_chan_resources = edma_free_chan_resources;
+ 	dma->device_issue_pending = edma_issue_pending;
++	dma->device_slave_sg_limits = edma_get_slave_sg_limits;
+ 	dma->device_tx_status = edma_tx_status;
+ 	dma->device_control = edma_control;
+ 	dma->dev = dev;
+-- 
+1.8.2.1
+
diff --git a/0002-dts-beaglebone-Add-I2C-definitions-for-EEPROMs-capes.patch b/0002-dts-beaglebone-Add-I2C-definitions-for-EEPROMs-capes.patch
new file mode 100644
index 0000000..8493d16
--- /dev/null
+++ b/0002-dts-beaglebone-Add-I2C-definitions-for-EEPROMs-capes.patch
@@ -0,0 +1,142 @@
+From e3c9bd680440e6216a86184687968a3939c06160 Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <panto at antoniou-consulting.com>
+Date: Fri, 28 Jun 2013 18:39:55 +0300
+Subject: [PATCH 2/4] dts: beaglebone: Add I2C definitions for EEPROMs & capes
+
+Add the I2C definitions for the EEPROM devices on the baseboard
+and on the possibly connected capes.
+
+Signed-off-by: Pantelis Antoniou <panto at antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-bone.dts      | 44 ++++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/am335x-boneblack.dts | 44 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 88 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
+index b8debea..15c9643 100644
+--- a/arch/arm/boot/dts/am335x-bone.dts
++++ b/arch/arm/boot/dts/am335x-bone.dts
+@@ -110,6 +110,18 @@
+ 				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 			>;
+ 		};
++		i2c0_pins: pinmux_i2c0_pins {
++			pinctrl-single,pins = <
++				0x188 0x70 	/* i2c0_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
++				0x18c 0x70	/* i2c0_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
++			>;
++		};
++		i2c2_pins: pinmux_i2c2_pins {
++			pinctrl-single,pins = <
++				0x178 0x73 	/* uart1_ctsn.i2c2_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++				0x17c 0x73	/* uart1_rtsn.i2c2_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++			>;
++		};
+ 	};
+ 
+ 	ocp {
+@@ -131,7 +143,39 @@
+ 				reg = <0x24>;
+ 			};
+ 
++			baseboard_eeprom: baseboard_eeprom at 50 {
++				compatible = "at,24c256";
++				reg = <0x50>;
++			};
+ 		};
++
++		i2c2: i2c at 4819c000 {
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			status = "okay";
++			clock-frequency = <100000>;
++
++			cape_eeprom0: cape_eeprom0 at 54 {
++				compatible = "at,24c256";
++				reg = <0x54>;
++			};
++
++			cape_eeprom1: cape_eeprom1 at 55 {
++				compatible = "at,24c256";
++				reg = <0x55>;
++			};
++
++			cape_eeprom2: cape_eeprom2 at 56 {
++				compatible = "at,24c256";
++				reg = <0x56>;
++			};
++
++			cape_eeprom3: cape_eeprom3 at 57 {
++				compatible = "at,24c256";
++				reg = <0x57>;
++			};
++		};
++
+ 	};
+ 
+ 	leds {
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index 75a924d..9e453b6 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -140,6 +140,19 @@
+ 				0x50 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a4.gpio1_20 */
+ 			>;
+ 		};
++
++		i2c0_pins: pinmux_i2c0_pins {
++			pinctrl-single,pins = <
++				0x188 0x70 	/* i2c0_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
++				0x18c 0x70	/* i2c0_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE0 */
++			>;
++		};
++		i2c2_pins: pinmux_i2c2_pins {
++			pinctrl-single,pins = <
++				0x178 0x73 	/* uart1_ctsn.i2c2_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++				0x17c 0x73	/* uart1_rtsn.i2c2_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++			>;
++		};
+ 	};
+ 
+ 	ocp {
+@@ -161,6 +174,37 @@
+ 				reg = <0x24>;
+ 			};
+ 
++			baseboard_eeprom: baseboard_eeprom at 50 {
++				compatible = "at,24c256";
++				reg = <0x50>;
++			};
++		};
++
++		i2c2: i2c at 4819c000 {
++			pinctrl-names = "default";
++			pinctrl-0 = <&i2c2_pins>;
++			status = "okay";
++			clock-frequency = <100000>;
++
++			cape_eeprom0: cape_eeprom0 at 54 {
++				compatible = "at,24c256";
++				reg = <0x54>;
++			};
++
++			cape_eeprom1: cape_eeprom1 at 55 {
++				compatible = "at,24c256";
++				reg = <0x55>;
++			};
++
++			cape_eeprom2: cape_eeprom2 at 56 {
++				compatible = "at,24c256";
++				reg = <0x56>;
++			};
++
++			cape_eeprom3: cape_eeprom3 at 57 {
++				compatible = "at,24c256";
++				reg = <0x57>;
++			};
+ 		};
+ 	};
+ 
+-- 
+1.8.2.1
+
diff --git a/0002-omap_hsmmc-Add-reset-gpio.patch b/0002-omap_hsmmc-Add-reset-gpio.patch
new file mode 100644
index 0000000..ea686e7
--- /dev/null
+++ b/0002-omap_hsmmc-Add-reset-gpio.patch
@@ -0,0 +1,138 @@
+From 364d4535955f21a8ce13e969aedde946a2d566b8 Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <panto at antoniou-consulting.com>
+Date: Fri, 30 Nov 2012 12:18:16 +0200
+Subject: [PATCH 2/2] omap_hsmmc: Add reset gpio
+
+Add a gpio property for controlling reset of the mmc device.
+eMMC on the beaglebone black requires it.
+
+Signed-off-by: Pantelis Antoniou <panto at antoniou-consulting.com>
+---
+ drivers/mmc/host/omap_hsmmc.c          | 40 +++++++++++++++++++++++++++++++++-
+ include/linux/platform_data/mmc-omap.h |  3 +++
+ 2 files changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index 8ab4a93..1fe7469 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -40,6 +40,8 @@
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/platform_data/mmc-omap.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/err.h>
+ 
+ /* OMAP HSMMC Host Controller Registers */
+ #define OMAP_HSMMC_SYSSTATUS	0x0014
+@@ -396,6 +398,7 @@ static inline int omap_hsmmc_have_reg(void)
+ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+ {
+ 	int ret;
++	unsigned long flags;
+ 
+ 	if (gpio_is_valid(pdata->slots[0].switch_pin)) {
+ 		if (pdata->slots[0].cover)
+@@ -425,6 +428,24 @@ static int omap_hsmmc_gpio_init(struct omap_mmc_platform_data *pdata)
+ 	} else
+ 		pdata->slots[0].gpio_wp = -EINVAL;
+ 
++	if (gpio_is_valid(pdata->slots[0].gpio_reset)) {
++		flags = pdata->slots[0].gpio_reset_active_low ?
++				GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++		ret = gpio_request_one(pdata->slots[0].gpio_reset, flags,
++				"mmc_reset");
++		if (ret)
++			goto err_free_wp;
++
++		/* hold reset */
++		udelay(pdata->slots[0].gpio_reset_hold_us);
++
++		gpio_set_value(pdata->slots[0].gpio_reset,
++				!pdata->slots[0].gpio_reset_active_low);
++
++	} else
++		pdata->slots[0].gpio_reset = -EINVAL;
++
++
+ 	return 0;
+ 
+ err_free_wp:
+@@ -438,6 +459,8 @@ err_free_sp:
+ 
+ static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
+ {
++	if (gpio_is_valid(pdata->slots[0].gpio_reset))
++		gpio_free(pdata->slots[0].gpio_reset);
+ 	if (gpio_is_valid(pdata->slots[0].gpio_wp))
+ 		gpio_free(pdata->slots[0].gpio_wp);
+ 	if (gpio_is_valid(pdata->slots[0].switch_pin))
+@@ -792,7 +815,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
+ 	 * ac, bc, adtc, bcr. Only commands ending an open ended transfer need
+ 	 * a val of 0x3, rest 0x0.
+ 	 */
+-	if (cmd == host->mrq->stop)
++	if (host->mrq && cmd == host->mrq->stop)
+ 		cmdtype = 0x3;
+ 
+ 	cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
+@@ -835,6 +858,8 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_req
+ 	int completed;
+ 	unsigned long flags;
+ 
++	BUG_ON(mrq == NULL);
++
+ 	spin_lock_irqsave(&host->irq_lock, flags);
+ 
+ 	host->req_flags &= ~RQF_REQ_IN_PROGRESS;
+@@ -1775,6 +1800,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
+ 	struct device_node *np = dev->of_node;
+ 	u32 bus_width, max_freq;
+ 	int cd_gpio, wp_gpio;
++	enum of_gpio_flags reset_flags;
+ 
+ 	cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+ 	wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+@@ -1792,6 +1818,14 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
+ 	pdata->nr_slots = 1;
+ 	pdata->slots[0].switch_pin = cd_gpio;
+ 	pdata->slots[0].gpio_wp = wp_gpio;
++	reset_flags = 0;
++	pdata->slots[0].gpio_reset = of_get_named_gpio_flags(np,
++			"reset-gpios", 0, &reset_flags);
++	pdata->slots[0].gpio_reset_active_low =
++		(reset_flags & OF_GPIO_ACTIVE_LOW) != 0;
++	pdata->slots[0].gpio_reset_hold_us = 100;	/* default */
++	of_property_read_u32(np, "reset-gpio-hold-us",
++			&pdata->slots[0].gpio_reset_hold_us);
+ 
+ 	if (of_find_property(np, "ti,non-removable", NULL)) {
+ 		pdata->slots[0].nonremovable = true;
+@@ -1858,6 +1892,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 		return -ENXIO;
+ 	}
+ 
++	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++	if (IS_ERR(pinctrl))
++		dev_warn(&pdev->dev, "unable to select pin group\n");
++
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	irq = platform_get_irq(pdev, 0);
+ 	if (res == NULL || irq < 0)
+diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h
+index 2bf1b30..d548994 100644
+--- a/include/linux/platform_data/mmc-omap.h
++++ b/include/linux/platform_data/mmc-omap.h
+@@ -115,6 +115,9 @@ struct omap_mmc_platform_data {
+ 
+ 		int switch_pin;			/* gpio (card detect) */
+ 		int gpio_wp;			/* gpio (write protect) */
++		int gpio_reset;			/* gpio (reset) */
++		int gpio_reset_active_low;	/* 1 if reset is active low */
++		u32 gpio_reset_hold_us;		/* time to hold in us */
+ 
+ 		int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
+ 		int (*set_power)(struct device *dev, int slot,
+-- 
+1.8.2.1
+
diff --git a/0003-dmaengine-add-dma_get_slave_sg_limits.patch b/0003-dmaengine-add-dma_get_slave_sg_limits.patch
new file mode 100644
index 0000000..61bcdb3
--- /dev/null
+++ b/0003-dmaengine-add-dma_get_slave_sg_limits.patch
@@ -0,0 +1,94 @@
+From c8ff7a795bf883c61b7d7f506b0bb7796db6cb01 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter at ti.com>
+Date: Wed, 6 Mar 2013 19:56:05 +0000
+Subject: [PATCH 03/13] dmaengine: add dma_get_slave_sg_limits()
+
+Add a dmaengine API to retrieve slave SG transfer limits.
+
+The API is optionally implemented by dmaengine drivers and when
+unimplemented will return a NULL pointer. A client driver using
+this API provides the required dma channel, address width, and
+burst size of the transfer. dma_get_slave_sg_limits() returns an
+SG limits structure with the maximum number and size of SG segments
+that the given channel can handle.
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Signed-off-by: Joel A Fernandes <joelagnel at ti.com>
+---
+ include/linux/dmaengine.h | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index cb286b1..d71fe5d 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -370,6 +370,18 @@ struct dma_slave_config {
+ 	unsigned int slave_id;
+ };
+ 
++/* struct dma_slave_sg_limits - expose SG transfer limits of a channel
++ *
++ * @max_seg_nr: maximum number of SG segments supported on a SG/SLAVE
++ *	    channel (0 for no maximum or not a SG/SLAVE channel)
++ * @max_seg_len: maximum length of SG segments supported on a SG/SLAVE
++ *	     channel (0 for no maximum or not a SG/SLAVE channel)
++ */
++struct dma_slave_sg_limits {
++	u32 max_seg_nr;
++	u32 max_seg_len;
++};
++
+ static inline const char *dma_chan_name(struct dma_chan *chan)
+ {
+ 	return dev_name(&chan->dev->device);
+@@ -532,6 +544,7 @@ struct dma_tx_state {
+  *	struct with auxiliary transfer status information, otherwise the call
+  *	will just return a simple status code
+  * @device_issue_pending: push pending transactions to hardware
++ * @device_slave_sg_limits: return the slave SG capabilities
+  */
+ struct dma_device {
+ 
+@@ -597,6 +610,9 @@ struct dma_device {
+ 					    dma_cookie_t cookie,
+ 					    struct dma_tx_state *txstate);
+ 	void (*device_issue_pending)(struct dma_chan *chan);
++	struct dma_slave_sg_limits *(*device_slave_sg_limits)(
++		struct dma_chan *chan, enum dma_slave_buswidth addr_width,
++		u32 maxburst);
+ };
+ 
+ static inline int dmaengine_device_control(struct dma_chan *chan,
+@@ -958,6 +974,29 @@ dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used,
+ 	}
+ }
+ 
++/**
++ * dma_get_slave_sg_limits - get DMAC SG transfer capabilities
++ * @chan: target DMA channel
++ * @addr_width: address width of the DMA transfer
++ * @maxburst: maximum DMA transfer burst size
++ *
++ * Get SG transfer capabilities for a specified channel. If the dmaengine
++ * driver does not implement SG transfer capabilities then NULL is
++ * returned.
++ */
++static inline struct dma_slave_sg_limits
++*dma_get_slave_sg_limits(struct dma_chan *chan,
++		       enum dma_slave_buswidth addr_width,
++		       u32 maxburst)
++{
++	if (chan->device->device_slave_sg_limits)
++		return chan->device->device_slave_sg_limits(chan,
++							  addr_width,
++							  maxburst);
++
++	return NULL;
++}
++
+ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie);
+ #ifdef CONFIG_DMA_ENGINE
+ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
+-- 
+1.8.2.1
+
diff --git a/0004-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch b/0004-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
new file mode 100644
index 0000000..d6f98e1
--- /dev/null
+++ b/0004-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
@@ -0,0 +1,48 @@
+From e1e06db0fb0ae8cfc2b3dc9c08b3237a050e2789 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter at ti.com>
+Date: Thu, 7 Mar 2013 04:16:38 +0000
+Subject: [PATCH 04/13] mmc: omap_hsmmc: set max_segs based on dma engine
+ limits
+
+The EDMA DMAC has a hardware limitation that prevents supporting
+scatter gather lists with any number of segments. The DMA Engine
+API reports the maximum number of segments a channel can support
+via the optional dma_get_slave_sg_limits() API. If the max_nr_segs
+limit is present, the value is used to configure mmc->max_segs
+appropriately.
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Acked-by: Tony Lindgren <tony at atomide.com>
+---
+ drivers/mmc/host/omap_hsmmc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index 1865321..1f9ff97 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1776,6 +1776,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 	const struct of_device_id *match;
+ 	dma_cap_mask_t mask;
+ 	unsigned tx_req, rx_req;
++	struct dma_slave_sg_limits *dma_sg_limits;
+ 	struct pinctrl *pinctrl;
+ 
+ 	match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
+@@ -1952,6 +1953,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 		goto err_irq;
+ 	}
+ 
++	/* Some DMA Engines only handle a limited number of SG segments */
++	dma_sg_limits = dma_get_slave_sg_limits(host->rx_chan,
++						DMA_SLAVE_BUSWIDTH_4_BYTES,
++						mmc->max_blk_size / 4);
++	if (dma_sg_limits && dma_sg_limits->max_seg_nr)
++		mmc->max_segs = dma_sg_limits->max_seg_nr;
++
+ 	/* Request IRQ for MMC operations */
+ 	ret = request_irq(host->irq, omap_hsmmc_irq, 0,
+ 			mmc_hostname(mmc), host);
+-- 
+1.8.2.1
+
diff --git a/0005-da8xx-config-Enable-MMC-and-FS-options.patch b/0005-da8xx-config-Enable-MMC-and-FS-options.patch
new file mode 100644
index 0000000..d94e500
--- /dev/null
+++ b/0005-da8xx-config-Enable-MMC-and-FS-options.patch
@@ -0,0 +1,33 @@
+From bb43e18a5c1626fadb8674b287224905358751be Mon Sep 17 00:00:00 2001
+From: Joel A Fernandes <agnel.joel at gmail.com>
+Date: Thu, 20 Jun 2013 15:07:40 -0500
+Subject: [PATCH 05/13] da8xx: config: Enable MMC and FS options
+
+Required to get OMAP-L1 EVM access MMC and mount rootfs
+
+Signed-off-by: Joel A Fernandes <joelagnel at ti.com>
+---
+ arch/arm/configs/da8xx_omapl_defconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig
+index 1571bea..9b50e6c 100644
+--- a/arch/arm/configs/da8xx_omapl_defconfig
++++ b/arch/arm/configs/da8xx_omapl_defconfig
+@@ -106,6 +106,7 @@ CONFIG_DMADEVICES=y
+ CONFIG_TI_EDMA=y
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT3_FS=y
++CONFIG_EXT4_FS=y
+ CONFIG_XFS_FS=m
+ CONFIG_INOTIFY=y
+ CONFIG_AUTOFS4_FS=m
+@@ -137,3 +138,5 @@ CONFIG_DEBUG_ERRORS=y
+ # CONFIG_CRYPTO_HW is not set
+ CONFIG_CRC_CCITT=m
+ CONFIG_CRC_T10DIF=m
++CONFIG_MMC=y
++CONFIG_MMC_DAVINCI=y
+-- 
+1.8.2.1
+
diff --git a/0006-ARM-dts-add-AM33XX-EDMA-support.patch b/0006-ARM-dts-add-AM33XX-EDMA-support.patch
new file mode 100644
index 0000000..c5c4266
--- /dev/null
+++ b/0006-ARM-dts-add-AM33XX-EDMA-support.patch
@@ -0,0 +1,44 @@
+From b9e4382015c702fbc1be1753074fce93a0965ac0 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mdp at ti.com>
+Date: Mon, 27 May 2013 21:52:12 -0500
+Subject: [PATCH 06/13] ARM: dts: add AM33XX EDMA support
+
+Adds AM33XX EDMA support to the am33xx.dtsi as documented in
+Documentation/devicetree/bindings/dma/ti-edma.txt
+
+Joel: Drop DT entries that are non-hardware-description for now as discussed in [1]
+
+[1] https://patchwork.kernel.org/patch/2226761/
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Signed-off-by: Joel A Fernandes <joelagnel at ti.com>
+---
+ arch/arm/boot/dts/am33xx.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 38b446b..784f774 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -96,6 +96,18 @@
+ 			reg = <0x48200000 0x1000>;
+ 		};
+ 
++		edma: edma at 49000000 {
++			compatible = "ti,edma3";
++			ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
++			reg =	<0x49000000 0x10000>,
++				<0x44e10f90 0x10>;
++			interrupts = <12 13 14>;
++			#dma-cells = <1>;
++			dma-channels = <64>;
++			ti,edma-regions = <4>;
++			ti,edma-slots = <256>;
++		};
++
+ 		gpio0: gpio at 44e07000 {
+ 			compatible = "ti,omap4-gpio";
+ 			ti,hwmods = "gpio1";
+-- 
+1.8.2.1
+
diff --git a/0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch b/0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch
new file mode 100644
index 0000000..6716bfb
--- /dev/null
+++ b/0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch
@@ -0,0 +1,44 @@
+From 16649496dc8c4334ab72a0a5a407953e3dcf4c83 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter at ti.com>
+Date: Thu, 10 Jan 2013 19:09:50 -0500
+Subject: [PATCH 07/13] ARM: dts: add AM33XX SPI DMA support
+
+Adds DMA resources to the AM33XX SPI nodes.
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Signed-off-by: Joel A Fernandes <joelagnel at ti.com>
+---
+ arch/arm/boot/dts/am33xx.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 784f774..0fdb949 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -331,6 +331,11 @@
+ 			interrupts = <65>;
+ 			ti,spi-num-cs = <2>;
+ 			ti,hwmods = "spi0";
++			dmas = <&edma 16
++				&edma 17
++				&edma 18
++				&edma 19>;
++			dma-names = "tx0", "rx0", "tx1", "rx1";
+ 			status = "disabled";
+ 		};
+ 
+@@ -342,6 +347,11 @@
+ 			interrupts = <125>;
+ 			ti,spi-num-cs = <2>;
+ 			ti,hwmods = "spi1";
++			dmas = <&edma 42
++				&edma 43
++				&edma 44
++				&edma 45>;
++			dma-names = "tx0", "rx0", "tx1", "rx1";
+ 			status = "disabled";
+ 		};
+ 
+-- 
+1.8.2.1
+
diff --git a/0008-ARM-dts-add-AM33XX-MMC-support.patch b/0008-ARM-dts-add-AM33XX-MMC-support.patch
new file mode 100644
index 0000000..23c2244
--- /dev/null
+++ b/0008-ARM-dts-add-AM33XX-MMC-support.patch
@@ -0,0 +1,191 @@
+From 1aa00b457ea36f6eeb78b66be076e16a2d3fafe0 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter at ti.com>
+Date: Thu, 7 Mar 2013 04:16:39 +0000
+Subject: [PATCH 08/13] ARM: dts: add AM33XX MMC support
+
+Adds AM33XX MMC support for am335x-bone, am335x-evm, and
+am335x-evmsk.
+
+Also added is the DMA binding definitions based on the generic
+DMA request binding.
+
+Changes to DTS:
+Interrupt and reg added by: Joel Fernandes <joelf at ti.com>
+Compatible added by Balaji TK <balajitk at ti.com>
+ti,needs-special-hs-handling added by Gururaja Hebbar <gururaja.hebbar at ti.com>
+
+Signed-off-by: Matt Porter <mporter at ti.com>
+Acked-by: Tony Lindgren <tony at atomide.com>
+Signed-off-by: Joel Fernandes <joelf at ti.com>
+
+Conflicts:
+	arch/arm/boot/dts/am335x-evmsk.dts
+---
+ .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      | 26 ++++++++++++++-
+ arch/arm/boot/dts/am335x-bone.dts                  |  7 ++++
+ arch/arm/boot/dts/am335x-evm.dts                   |  7 ++++
+ arch/arm/boot/dts/am335x-evmsk.dts                 |  7 ++++
+ arch/arm/boot/dts/am33xx.dtsi                      | 38 ++++++++++++++++++++++
+ 5 files changed, 84 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+index ed271fc..8c8908a 100644
+--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
++++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+@@ -20,8 +20,29 @@ ti,dual-volt: boolean, supports dual voltage cards
+ ti,non-removable: non-removable slot (like eMMC)
+ ti,needs-special-reset: Requires a special softreset sequence
+ ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed
++dmas: List of DMA specifiers with the controller specific format
++as described in the generic DMA client binding. A tx and rx
++specifier is required.
++dma-names: List of DMA request names. These strings correspond
++1:1 with the DMA specifiers listed in dmas. The string naming is
++to be "rx" and "tx" for RX and TX DMA requests, respectively.
++
++Examples:
++
++[hwmod populated DMA resources]
++
++	mmc1: mmc at 0x4809c000 {
++		compatible = "ti,omap4-hsmmc";
++		reg = <0x4809c000 0x400>;
++		ti,hwmods = "mmc1";
++		ti,dual-volt;
++		bus-width = <4>;
++		vmmc-supply = <&vmmc>; /* phandle to regulator node */
++		ti,non-removable;
++	};
++
++[generic DMA request binding]
+ 
+-Example:
+ 	mmc1: mmc at 0x4809c000 {
+ 		compatible = "ti,omap4-hsmmc";
+ 		reg = <0x4809c000 0x400>;
+@@ -30,4 +51,7 @@ Example:
+ 		bus-width = <4>;
+ 		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+ 		ti,non-removable;
++		dmas = <&edma 24
++			&edma 25>;
++		dma-names = "tx", "rx";
+ 	};
+diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
+index 444b4ed..b8debea 100644
+--- a/arch/arm/boot/dts/am335x-bone.dts
++++ b/arch/arm/boot/dts/am335x-bone.dts
+@@ -203,6 +203,8 @@
+ 		};
+ 
+ 		ldo3_reg: regulator at 5 {
++			regulator-min-microvolt = <1800000>;
++			regulator-max-microvolt = <3300000>;
+ 			regulator-always-on;
+ 		};
+ 
+@@ -234,3 +236,8 @@
+ 	pinctrl-0 = <&davinci_mdio_default>;
+ 	pinctrl-1 = <&davinci_mdio_sleep>;
+ };
++
++&mmc1 {
++	status = "okay";
++	vmmc-supply = <&ldo3_reg>;
++};
+diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
+index 3aee1a4..44e69d9 100644
+--- a/arch/arm/boot/dts/am335x-evm.dts
++++ b/arch/arm/boot/dts/am335x-evm.dts
+@@ -448,6 +448,8 @@
+ 		};
+ 
+ 		vmmc_reg: regulator at 12 {
++			regulator-min-microvolt = <1800000>;
++			regulator-max-microvolt = <3300000>;
+ 			regulator-always-on;
+ 		};
+ 	};
+@@ -488,3 +490,8 @@
+ 		ti,adc-channels = <4 5 6 7>;
+ 	};
+ };
++
++&mmc1 {
++	status = "okay";
++	vmmc-supply = <&vmmc_reg>;
++};
+diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
+index 0c8ad17..4e355d6 100644
+--- a/arch/arm/boot/dts/am335x-evmsk.dts
++++ b/arch/arm/boot/dts/am335x-evmsk.dts
+@@ -376,6 +376,8 @@
+ 		};
+ 
+ 		vmmc_reg: regulator at 12 {
++			regulator-min-microvolt = <1800000>;
++			regulator-max-microvolt = <3300000>;
+ 			regulator-always-on;
+ 		};
+ 	};
+@@ -402,3 +404,8 @@
+ 	phy_id = <&davinci_mdio>, <1>;
+ 	phy-mode = "rgmii-txid";
+ };
++
++&mmc1 {
++	status = "okay";
++	vmmc-supply = <&vmmc_reg>;
++};
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 0fdb949..969c81b 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -236,6 +236,44 @@
+ 			status = "disabled";
+ 		};
+ 
++		mmc1: mmc at 48060000 {
++			compatible = "ti,omap4-hsmmc";
++			ti,hwmods = "mmc1";
++			ti,dual-volt;
++			ti,needs-special-reset;
++			ti,needs-special-hs-handling;
++			dmas = <&edma 24
++				&edma 25>;
++			dma-names = "tx", "rx";
++			interrupts = <64>;
++			interrupt-parent = <&intc>;
++			reg = <0x48060000 0x1000>;
++			status = "disabled";
++		};
++
++		mmc2: mmc at 481d8000 {
++			compatible = "ti,omap4-hsmmc";
++			ti,hwmods = "mmc2";
++			ti,needs-special-reset;
++			dmas = <&edma 2
++				&edma 3>;
++			dma-names = "tx", "rx";
++			interrupts = <28>;
++			interrupt-parent = <&intc>;
++			reg = <0x481d8000 0x1000>;
++			status = "disabled";
++		};
++
++		mmc3: mmc at 47810000 {
++			compatible = "ti,omap4-hsmmc";
++			ti,hwmods = "mmc3";
++			ti,needs-special-reset;
++			interrupts = <29>;
++			interrupt-parent = <&intc>;
++			reg = <0x47810000 0x1000>;
++			status = "disabled";
++		};
++
+ 		wdt2: wdt at 44e35000 {
+ 			compatible = "ti,omap3-wdt";
+ 			ti,hwmods = "wd_timer2";
+-- 
+1.8.2.1
+
diff --git a/0009-DMA-EDMA-Split-out-PaRAM-set-calculations-into-its-o.patch b/0009-DMA-EDMA-Split-out-PaRAM-set-calculations-into-its-o.patch
new file mode 100644
index 0000000..8bef684
--- /dev/null
+++ b/0009-DMA-EDMA-Split-out-PaRAM-set-calculations-into-its-o.patch
@@ -0,0 +1,271 @@
+From 14c120151d8ae2e335dd8728c88d6cd1a52863c8 Mon Sep 17 00:00:00 2001
+From: Joel Fernandes <joelf at ti.com>
+Date: Tue, 25 Jun 2013 09:35:33 -0500
+Subject: [PATCH 09/13] DMA: EDMA: Split out PaRAM set calculations into its
+ own function
+
+PaRAM set calculation is abstracted into its own function to
+enable better reuse for other DMA cases. Currently it only
+implements the Slave case.
+
+This provides a much cleaner abstraction to the internals of the
+PaRAM set. However, any PaRAM attributes that are not common to
+all DMA types must be set separately. This function only calculates
+the most-common attributes.
+
+Also added comments clarifying A-sync case calculations.
+
+Signed-off-by: Joel Fernandes <joelf at ti.com>
+---
+ drivers/dma/edma.c | 197 ++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 126 insertions(+), 71 deletions(-)
+
+diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
+index e008ed2..87b7e2b 100644
+--- a/drivers/dma/edma.c
++++ b/drivers/dma/edma.c
+@@ -211,6 +211,116 @@ static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ 	return ret;
+ }
+ 
++/*
++ * A clean implementation of a PaRAM set configuration abstraction
++ * @chan: Channel who's PaRAM set we're configuring
++ * @src_addr: Source address of the DMA
++ * @dst_addr: Destination address of the DMA
++ * @burst: In units of dev_width, how much to send
++ * @dev_width: How much is the dev_width
++ * @dma_length: Total length of the DMA transfer
++ * @direction: Direction of the transfer
++ */
++static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset,
++	dma_addr_t src_addr, dma_addr_t dst_addr, u32 burst,
++	enum dma_slave_buswidth dev_width, unsigned int dma_length,
++	enum dma_transfer_direction direction)
++{
++	struct edma_chan *echan = to_edma_chan(chan);
++	struct device *dev = chan->device->dev;
++	int acnt, bcnt, ccnt, cidx;
++	int src_bidx, dst_bidx, src_cidx, dst_cidx;
++	int absync;
++
++	acnt = dev_width;
++	/*
++	 * If the maxburst is equal to the fifo width, use
++	 * A-synced transfers. This allows for large contiguous
++	 * buffer transfers using only one PaRAM set.
++	 */
++	if (burst == 1) {
++		absync = false;
++		/*
++		 * For the A-sync case, bcnt and ccnt are the remainder
++		 * and quotient respectively of the division of:
++		 * (dma_length / acnt) by (SZ_64K -1). This is so
++		 * that in case bcnt over flows, we have ccnt to use.
++		 * Note: In A-sync tranfer only, bcntrld is used, but it
++		 * only applies for sg_dma_len(sg) >= SZ_64K.
++		 * In this case, the best way adopted is- bccnt for the
++		 * first frame will be the remainder below. Then for
++		 * every successive frame, bcnt will be SZ_64K-1. This
++		 * is assured as bcntrld = 0xffff in end of function.
++		 */
++		ccnt = dma_length / acnt / (SZ_64K - 1);
++		bcnt = dma_length / acnt - ccnt * (SZ_64K - 1);
++		/*
++		 * If bcnt is non-zero, we have a remainder and hence an
++		 * extra frame to transfer, so increment ccnt.
++		 */
++		if (bcnt)
++			ccnt++;
++		else
++			bcnt = SZ_64K - 1;
++		cidx = acnt;
++	/*
++	 * If maxburst is greater than the fifo address_width,
++	 * use AB-synced transfers where A count is the fifo
++	 * address_width and B count is the maxburst. In this
++	 * case, we are limited to transfers of C count frames
++	 * of (address_width * maxburst) where C count is limited
++	 * to SZ_64K-1. This places an upper bound on the length
++	 * of an SG segment that can be handled.
++	 */
++	} else {
++		absync = true;
++		bcnt = burst;
++		ccnt = dma_length / (acnt * bcnt);
++		if (ccnt > (SZ_64K - 1)) {
++			dev_err(dev, "Exceeded max SG segment size\n");
++			return -EINVAL;
++		}
++		cidx = acnt * bcnt;
++	}
++
++	if (direction == DMA_MEM_TO_DEV) {
++		src_bidx = acnt;
++		src_cidx = cidx;
++		dst_bidx = 0;
++		dst_cidx = 0;
++	} else if (direction == DMA_DEV_TO_MEM)  {
++		src_bidx = 0;
++		src_cidx = 0;
++		dst_bidx = acnt;
++		dst_cidx = cidx;
++	} else {
++		dev_err(dev, "%s: direction not implemented yet\n", __func__);
++		return -EINVAL;
++	}
++
++	pset->opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
++	/* Configure A or AB synchronized transfers */
++	if (absync)
++		pset->opt |= SYNCDIM;
++	
++	pset->src = src_addr;
++	pset->dst = dst_addr;
++
++	pset->src_dst_bidx = (dst_bidx << 16) | src_bidx;
++	pset->src_dst_cidx = (dst_cidx << 16) | src_cidx;
++
++	pset->a_b_cnt = bcnt << 16 | acnt;
++	pset->ccnt = ccnt;
++	/*
++	 * Only time when (bcntrld) auto reload is required is for
++	 * A-sync case, and in this case, a requirement of reload value
++	 * of SZ_64K-1 only is assured. 'link' is initially set to NULL
++	 * and then later will be populated by edma_execute.
++	 */
++	pset->link_bcntrld = 0xffffffff;
++	return absync;
++}
++
+ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ 	struct dma_chan *chan, struct scatterlist *sgl,
+ 	unsigned int sg_len, enum dma_transfer_direction direction,
+@@ -219,23 +329,21 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ 	struct edma_chan *echan = to_edma_chan(chan);
+ 	struct device *dev = chan->device->dev;
+ 	struct edma_desc *edesc;
+-	dma_addr_t dev_addr;
++	dma_addr_t src_addr = 0, dst_addr = 0;
+ 	enum dma_slave_buswidth dev_width;
+ 	u32 burst;
+ 	struct scatterlist *sg;
+-	int i;
+-	int acnt, bcnt, ccnt, src, dst, cidx;
+-	int src_bidx, dst_bidx, src_cidx, dst_cidx;
++	int i, ret;
+ 
+ 	if (unlikely(!echan || !sgl || !sg_len))
+ 		return NULL;
+ 
+ 	if (direction == DMA_DEV_TO_MEM) {
+-		dev_addr = echan->cfg.src_addr;
++		src_addr = echan->cfg.src_addr;
+ 		dev_width = echan->cfg.src_addr_width;
+ 		burst = echan->cfg.src_maxburst;
+ 	} else if (direction == DMA_MEM_TO_DEV) {
+-		dev_addr = echan->cfg.dst_addr;
++		dst_addr = echan->cfg.dst_addr;
+ 		dev_width = echan->cfg.dst_addr_width;
+ 		burst = echan->cfg.dst_maxburst;
+ 	} else {
+@@ -263,7 +371,14 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ 
+ 	edesc->pset_nr = sg_len;
+ 
++	/* Configure PaRAM sets for each SG */
+ 	for_each_sg(sgl, sg, sg_len, i) {
++		/* Get address for each SG */
++		if (direction == DMA_DEV_TO_MEM)
++			dst_addr = sg_dma_address(sg);
++		else
++			src_addr = sg_dma_address(sg);
++
+ 		/* Allocate a PaRAM slot, if needed */
+ 		if (echan->slot[i] < 0) {
+ 			echan->slot[i] =
+@@ -275,76 +390,16 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ 			}
+ 		}
+ 
+-		acnt = dev_width;
++		ret = edma_config_pset(chan, &edesc->pset[i], src_addr, dst_addr,
++				      burst, dev_width, sg_dma_len(sg), direction);
++		if(ret < 0)
++			return NULL;
+ 
+-		/*
+-		 * If the maxburst is equal to the fifo width, use
+-		 * A-synced transfers. This allows for large contiguous
+-		 * buffer transfers using only one PaRAM set.
+-		 */
+-		if (burst == 1) {
+-			edesc->absync = false;
+-			ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
+-			bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
+-			if (bcnt)
+-				ccnt++;
+-			else
+-				bcnt = SZ_64K - 1;
+-			cidx = acnt;
+-		/*
+-		 * If maxburst is greater than the fifo address_width,
+-		 * use AB-synced transfers where A count is the fifo
+-		 * address_width and B count is the maxburst. In this
+-		 * case, we are limited to transfers of C count frames
+-		 * of (address_width * maxburst) where C count is limited
+-		 * to SZ_64K-1. This places an upper bound on the length
+-		 * of an SG segment that can be handled.
+-		 */
+-		} else {
+-			edesc->absync = true;
+-			bcnt = burst;
+-			ccnt = sg_dma_len(sg) / (acnt * bcnt);
+-			if (ccnt > (SZ_64K - 1)) {
+-				dev_err(dev, "Exceeded max SG segment size\n");
+-				return NULL;
+-			}
+-			cidx = acnt * bcnt;
+-		}
++		edesc->absync = ret;
+ 
+-		if (direction == DMA_MEM_TO_DEV) {
+-			src = sg_dma_address(sg);
+-			dst = dev_addr;
+-			src_bidx = acnt;
+-			src_cidx = cidx;
+-			dst_bidx = 0;
+-			dst_cidx = 0;
+-		} else {
+-			src = dev_addr;
+-			dst = sg_dma_address(sg);
+-			src_bidx = 0;
+-			src_cidx = 0;
+-			dst_bidx = acnt;
+-			dst_cidx = cidx;
+-		}
+-
+-		edesc->pset[i].opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
+-		/* Configure A or AB synchronized transfers */
+-		if (edesc->absync)
+-			edesc->pset[i].opt |= SYNCDIM;
+ 		/* If this is the last set, enable completion interrupt flag */
+ 		if (i == sg_len - 1)
+ 			edesc->pset[i].opt |= TCINTEN;
+-
+-		edesc->pset[i].src = src;
+-		edesc->pset[i].dst = dst;
+-
+-		edesc->pset[i].src_dst_bidx = (dst_bidx << 16) | src_bidx;
+-		edesc->pset[i].src_dst_cidx = (dst_cidx << 16) | src_cidx;
+-
+-		edesc->pset[i].a_b_cnt = bcnt << 16 | acnt;
+-		edesc->pset[i].ccnt = ccnt;
+-		edesc->pset[i].link_bcntrld = 0xffffffff;
+-
+ 	}
+ 
+ 	return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
+-- 
+1.8.2.1
+
diff --git a/0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch b/0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch
new file mode 100644
index 0000000..4c98194
--- /dev/null
+++ b/0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch
@@ -0,0 +1,130 @@
+From caf38f4702a75c7ba13d5d80d902812c5faa8501 Mon Sep 17 00:00:00 2001
+From: Joel Fernandes <joelf at ti.com>
+Date: Thu, 27 Jun 2013 20:18:52 -0500
+Subject: [PATCH 10/13] DMA: EDMA: Add support for Cyclic DMA
+
+Using the PaRAM configuration function that we split for reuse by the
+different DMA types, we implement Cyclic DMA support.
+For the cyclic case, we pass different configuration paramters to this
+function, and add all the Cyclic-specific code separately.
+Callbacks are handled transparently as usual by the virt-dma layer.
+Linking is handled the same way as the slave SG case.
+
+Signed-off-by: Joel Fernandes <joelf at ti.com>
+---
+ drivers/dma/edma.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 85 insertions(+)
+
+diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
+index 87b7e2b..cec9a12 100644
+--- a/drivers/dma/edma.c
++++ b/drivers/dma/edma.c
+@@ -321,6 +321,88 @@ static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset,
+ 	return absync;
+ }
+ 
++static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
++	struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
++	size_t period_len, enum dma_transfer_direction direction, unsigned long flags,
++	void *context)
++{
++	struct edma_chan *echan = to_edma_chan(chan);
++	struct device *dev = chan->device->dev;
++	struct edma_desc *edesc;
++	dma_addr_t src_addr, dst_addr;
++	enum dma_slave_buswidth dev_width;
++	u32 burst;
++	int i, ret, nr_periods;
++
++	if (unlikely(!echan || !buf_len || !period_len))
++		return NULL;
++
++	if (direction == DMA_DEV_TO_MEM) {
++		src_addr = echan->cfg.src_addr;
++		dst_addr = buf_addr;
++		dev_width = echan->cfg.src_addr_width;
++		burst = echan->cfg.src_maxburst;
++	} else if (direction == DMA_MEM_TO_DEV) {
++		src_addr = buf_addr;
++		dst_addr = echan->cfg.dst_addr;
++		dev_width = echan->cfg.dst_addr_width;
++		burst = echan->cfg.dst_maxburst;
++	} else {
++		dev_err(dev, "%s: bad direction?\n", __func__);
++		return NULL;
++	}
++
++	if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
++		dev_err(dev, "Undefined slave buswidth\n");
++		return NULL;
++	}
++
++	if(unlikely(period_len % buf_len)) {
++		dev_err(dev, "Period should be multiple of Buf length\n");
++		return NULL;
++	}
++
++	nr_periods = period_len / buf_len;
++
++	edesc = kzalloc(sizeof(*edesc) + nr_periods *
++		sizeof(edesc->pset[0]), GFP_ATOMIC);
++	if (!edesc) {
++		dev_dbg(dev, "Failed to allocate a descriptor\n");
++		return NULL;
++	}
++
++	edesc->pset_nr = nr_periods;
++
++	for(i = 0; i < nr_periods; i++) {
++		/* Allocate a PaRAM slot, if needed */
++		if (echan->slot[i] < 0) {
++			echan->slot[i] =
++				edma_alloc_slot(EDMA_CTLR(echan->ch_num),
++						EDMA_SLOT_ANY);
++			if (echan->slot[i] < 0) {
++				dev_err(dev, "Failed to allocate slot\n");
++				return NULL;
++			}
++		}
++
++		if (direction == DMA_DEV_TO_MEM)
++			dst_addr += period_len;
++		else
++			src_addr += period_len;
++
++		ret = edma_config_pset(chan, &edesc->pset[i], src_addr, dst_addr,
++					      burst, dev_width, period_len, direction);
++		if(ret < 0)
++			return NULL;
++
++		edesc->absync = ret;
++		if (i == nr_periods - 1)
++			edesc->pset[i].opt |= TCINTEN;
++	}
++	/* TODO tx_flags (last parameter) needs to be investigated...\n" */
++	return vchan_tx_prep(&echan->vchan, &edesc->vdesc, 0);
++}
++
+ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+ 	struct dma_chan *chan, struct scatterlist *sgl,
+ 	unsigned int sg_len, enum dma_transfer_direction direction,
+@@ -424,6 +506,8 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
+ 		edesc = echan->edesc;
+ 		if (edesc) {
+ 			edma_execute(echan);
++			/* Note: that desc->callback must be setup by EDMA users so that
++			the virt-dma layer calls their callback on vchan_cookie_complete() */
+ 			vchan_cookie_complete(&edesc->vdesc);
+ 		}
+ 
+@@ -605,6 +689,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
+ 			  struct device *dev)
+ {
+ 	dma->device_prep_slave_sg = edma_prep_slave_sg;
++	dma->device_prep_dma_cyclic = edma_prep_dma_cyclic;
+ 	dma->device_alloc_chan_resources = edma_alloc_chan_resources;
+ 	dma->device_free_chan_resources = edma_free_chan_resources;
+ 	dma->device_issue_pending = edma_issue_pending;
+-- 
+1.8.2.1
+
diff --git a/0011-sound-soc-soc-dmaengine-pcm-Add-support-for-new-DMAE.patch b/0011-sound-soc-soc-dmaengine-pcm-Add-support-for-new-DMAE.patch
new file mode 100644
index 0000000..f5f7ce8
--- /dev/null
+++ b/0011-sound-soc-soc-dmaengine-pcm-Add-support-for-new-DMAE.patch
@@ -0,0 +1,60 @@
+From e85ad9182c962bb095beb435e98fde612a4ef88d Mon Sep 17 00:00:00 2001
+From: Joel Fernandes <joelf at ti.com>
+Date: Wed, 3 Jul 2013 17:29:44 -0500
+Subject: [PATCH 11/13] sound: soc: soc-dmaengine-pcm: Add support for new
+ DMAEngine request API
+
+Formerly these resources were coming HWMOD on OMAP-like SoCs. With the
+impending removal of HWMOD data, drivers are being converted to use the
+"of-dma" method of requesting DMA channels which from DT and can be obtained
+using the dma_request_slave_channel API. Add support to the soc-dmaengine-pcm
+helpers so that we can fetch and open channels using this method.
+
+Signed-off-by: Joel Fernandes <joelf at ti.com>
+---
+ sound/soc/soc-dmaengine-pcm.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
+index aa924d9..461fe4f 100644
+--- a/sound/soc/soc-dmaengine-pcm.c
++++ b/sound/soc/soc-dmaengine-pcm.c
+@@ -276,6 +276,16 @@ struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
+ }
+ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_channel);
+ 
++struct dma_chan *snd_dmaengine_pcm_request_slave_channel(
++	struct snd_pcm_substream *substream, char *name)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct device *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
++
++	return dma_request_slave_channel(dev, name);
++}
++EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_slave_channel);
++
+ /**
+  * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
+  * @substream: PCM substream
+@@ -334,6 +344,18 @@ int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
+ }
+ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
+ 
++int snd_dmaengine_pcm_open_request_slave_chan(struct snd_pcm_substream *substream, char *name)
++{
++	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		return snd_dmaengine_pcm_open(substream,
++			    snd_dmaengine_pcm_request_slave_channel(substream, "tx"));
++	} else {
++		return snd_dmaengine_pcm_open(substream,
++			    snd_dmaengine_pcm_request_slave_channel(substream, "rx"));
++	}
++}
++EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_slave_chan);
++
+ /**
+  * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
+  * @substream: PCM substream
+-- 
+1.8.2.1
+
diff --git a/0012-mmc-omap_hsmmc-Fix-the-crashes-due-to-the-interrupts.patch b/0012-mmc-omap_hsmmc-Fix-the-crashes-due-to-the-interrupts.patch
new file mode 100644
index 0000000..1c83398
--- /dev/null
+++ b/0012-mmc-omap_hsmmc-Fix-the-crashes-due-to-the-interrupts.patch
@@ -0,0 +1,303 @@
+From b13c0c62ddf7a3a7d5b96fed8ea80f21f3bb2dad Mon Sep 17 00:00:00 2001
+From: Pantelis Antoniou <panto at antoniou-consulting.com>
+Date: Wed, 17 Jul 2013 20:00:13 +0300
+Subject: [PATCH 12/13] mmc: omap_hsmmc: Fix the crashes due to the interrupts
+ racing
+
+---
+ drivers/mmc/host/omap_hsmmc.c | 120 +++++++++++++++++++++++++++++++-----------
+ 1 file changed, 88 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index 1f9ff97..91e2954 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -171,7 +171,7 @@ struct omap_hsmmc_host {
+ 	unsigned char		power_mode;
+ 	int			suspended;
+ 	int			irq;
+-	int			use_dma, dma_ch;
++	int			use_dma;
+ 	struct dma_chan		*tx_chan;
+ 	struct dma_chan		*rx_chan;
+ 	int			slot_id;
+@@ -180,10 +180,15 @@ struct omap_hsmmc_host {
+ 	int			protect_card;
+ 	int			reqs_blocked;
+ 	int			use_reg;
+-	int			req_in_progress;
+ 	struct omap_hsmmc_next	next_data;
+ 
+ 	struct	omap_mmc_platform_data	*pdata;
++
++	unsigned int		req_flags;
++#define RQF_REQ_IN_PROGRESS	(1 << 0)
++#define RQF_DMA_IN_PROGRESS	(1 << 1)
++#define RQF_REQ_DONE		(1 << 2)
++#define RQF_DMA_DONE		(1 << 3)
+ };
+ 
+ static int omap_hsmmc_card_detect(struct device *dev, int slot)
+@@ -803,7 +808,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
+ 	if (host->use_dma)
+ 		cmdreg |= DMAE;
+ 
+-	host->req_in_progress = 1;
++	host->req_flags |=  RQF_REQ_IN_PROGRESS;
++	host->req_flags &= ~RQF_REQ_DONE;
+ 
+ 	OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg);
+ 	OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
+@@ -826,19 +832,34 @@ static struct dma_chan *omap_hsmmc_get_dma_chan(struct omap_hsmmc_host *host,
+ 
+ static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq)
+ {
+-	int dma_ch;
++	int completed;
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&host->irq_lock, flags);
+-	host->req_in_progress = 0;
+-	dma_ch = host->dma_ch;
+-	spin_unlock_irqrestore(&host->irq_lock, flags);
++
++	host->req_flags &= ~RQF_REQ_IN_PROGRESS;
++	host->req_flags |=  RQF_REQ_DONE;
++
++	/* completed? */
++	if (mrq->data && host->use_dma)
++		completed = (host->req_flags & RQF_DMA_DONE) == RQF_DMA_DONE;
++	else
++		completed = 1;
+ 
+ 	omap_hsmmc_disable_irq(host);
++
+ 	/* Do not complete the request if DMA is still in progress */
+-	if (mrq->data && host->use_dma && dma_ch != -1)
++	if (!completed) {
++		spin_unlock_irqrestore(&host->irq_lock, flags);
++		pr_debug("%s: not completed!\n", __func__);
+ 		return;
++	}
++
++	/* clear the flags now */
++	host->req_flags &= ~(RQF_REQ_DONE | RQF_DMA_DONE);
+ 	host->mrq = NULL;
++	spin_unlock_irqrestore(&host->irq_lock, flags);
++
+ 	mmc_request_done(host->mmc, mrq);
+ }
+ 
+@@ -855,6 +876,7 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
+ 		if (host->cmd && host->cmd->opcode == 6 &&
+ 		    host->response_busy) {
+ 			host->response_busy = 0;
++			pr_debug("%s: response_busy = 0\n", __func__);
+ 			return;
+ 		}
+ 
+@@ -870,9 +892,11 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
+ 		data->bytes_xfered = 0;
+ 
+ 	if (!data->stop) {
++		pr_debug("%s: calling omap_hsmmc_request_done\n", __func__);
+ 		omap_hsmmc_request_done(host, data->mrq);
+ 		return;
+ 	}
++	pr_debug("%s: calling omap_hsmmc_start_command\n", __func__);
+ 	omap_hsmmc_start_command(host, data->stop, NULL);
+ }
+ 
+@@ -882,6 +906,8 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
+ static void
+ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd)
+ {
++	unsigned long flags;
++
+ 	host->cmd = NULL;
+ 
+ 	if (cmd->flags & MMC_RSP_PRESENT) {
+@@ -898,6 +924,18 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd)
+ 	}
+ 	if ((host->data == NULL && !host->response_busy) || cmd->error)
+ 		omap_hsmmc_request_done(host, cmd->mrq);
++	else {
++		spin_lock_irqsave(&host->irq_lock, flags);
++		/* we use DMA, and DMA is completed - kick the can */
++		if ((host->req_flags & RQF_DMA_DONE) != 0) {
++			host->req_flags &= ~(RQF_REQ_IN_PROGRESS | RQF_REQ_DONE | RQF_DMA_DONE);
++			host->mrq = NULL;
++			mmc_request_done(host->mmc, cmd->mrq);
++		} else {
++			pr_debug("%s: not calling omap_hsmmc_request_done!\n", __func__);
++		}
++		spin_unlock_irqrestore(&host->irq_lock, flags);
++	}
+ }
+ 
+ /*
+@@ -905,17 +943,19 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd)
+  */
+ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
+ {
+-	int dma_ch;
++	int dma_in_progress;
+ 	unsigned long flags;
+ 
+ 	host->data->error = errno;
+ 
+ 	spin_lock_irqsave(&host->irq_lock, flags);
+-	dma_ch = host->dma_ch;
+-	host->dma_ch = -1;
++	dma_in_progress = host->use_dma &&
++			(host->req_flags & RQF_DMA_IN_PROGRESS) != 0;
++	host->req_flags &= ~RQF_DMA_IN_PROGRESS;
++	host->req_flags |=  RQF_DMA_DONE;
+ 	spin_unlock_irqrestore(&host->irq_lock, flags);
+ 
+-	if (host->use_dma && dma_ch != -1) {
++	if (dma_in_progress) {
+ 		struct dma_chan *chan = omap_hsmmc_get_dma_chan(host, host->data);
+ 
+ 		dmaengine_terminate_all(chan);
+@@ -1005,16 +1045,22 @@ static void hsmmc_command_incomplete(struct omap_hsmmc_host *host,
+ 					int err, int end_cmd)
+ {
+ 	if (end_cmd) {
++		pr_debug("%s end_cmd\n", __func__);
+ 		omap_hsmmc_reset_controller_fsm(host, SRC);
+ 		if (host->cmd)
+ 			host->cmd->error = err;
+ 	}
+ 
+ 	if (host->data) {
++		pr_debug("%s host->data; resetting dma\n", __func__);
+ 		omap_hsmmc_reset_controller_fsm(host, SRD);
+ 		omap_hsmmc_dma_cleanup(host, err);
+-	} else if (host->mrq && host->mrq->cmd)
++	} else if (host->mrq && host->mrq->cmd) {
++		pr_debug("%s error\n", __func__);
+ 		host->mrq->cmd->error = err;
++	} else {
++		pr_debug("%s nothing\n", __func__);
++	}
+ }
+ 
+ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
+@@ -1055,13 +1101,13 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
+ 	struct omap_hsmmc_host *host = dev_id;
+ 	int status;
+ 
+-	status = OMAP_HSMMC_READ(host->base, STAT);
+-	while (status & INT_EN_MASK && host->req_in_progress) {
+-		omap_hsmmc_do_irq(host, status);
++	while ((status = OMAP_HSMMC_READ(host->base, STAT)) & INT_EN_MASK) {
++
++		if (host->req_flags & RQF_REQ_IN_PROGRESS)
++			omap_hsmmc_do_irq(host, status);
+ 
+ 		/* Flush posted write */
+ 		OMAP_HSMMC_WRITE(host->base, STAT, status);
+-		status = OMAP_HSMMC_READ(host->base, STAT);
+ 	}
+ 
+ 	return IRQ_HANDLED;
+@@ -1199,13 +1245,15 @@ static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+ static void omap_hsmmc_dma_callback(void *param)
+ {
+ 	struct omap_hsmmc_host *host = param;
++	struct mmc_request *mrq = host->mrq;
+ 	struct dma_chan *chan;
+ 	struct mmc_data *data;
+-	int req_in_progress;
++	int completed;
+ 
+ 	spin_lock_irq(&host->irq_lock);
+-	if (host->dma_ch < 0) {
++	if ((host->req_flags & RQF_DMA_IN_PROGRESS) == 0) {
+ 		spin_unlock_irq(&host->irq_lock);
++		pr_debug("%s: No DMA in progress!\n", __func__);
+ 		return;
+ 	}
+ 
+@@ -1216,17 +1264,22 @@ static void omap_hsmmc_dma_callback(void *param)
+ 			     data->sg, data->sg_len,
+ 			     omap_hsmmc_get_dma_dir(host, data));
+ 
+-	req_in_progress = host->req_in_progress;
+-	host->dma_ch = -1;
+-	spin_unlock_irq(&host->irq_lock);
++	host->req_flags &= ~RQF_DMA_IN_PROGRESS;
++	host->req_flags |= RQF_DMA_DONE;
+ 
+-	/* If DMA has finished after TC, complete the request */
+-	if (!req_in_progress) {
+-		struct mmc_request *mrq = host->mrq;
++	completed = (host->req_flags & RQF_REQ_DONE) != 0;
+ 
+-		host->mrq = NULL;
+-		mmc_request_done(host->mmc, mrq);
++	if (!completed) {
++		spin_unlock_irq(&host->irq_lock);
++		pr_debug("%s: not completed\n", __func__);
++		return;
+ 	}
++
++	host->req_flags &= ~(RQF_REQ_DONE | RQF_DMA_DONE);
++	host->mrq = NULL;
++	spin_unlock_irq(&host->irq_lock);
++
++	mmc_request_done(host->mmc, mrq);
+ }
+ 
+ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host,
+@@ -1294,7 +1347,7 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
+ 		 */
+ 		return -EINVAL;
+ 
+-	BUG_ON(host->dma_ch != -1);
++	BUG_ON((host->req_flags & RQF_DMA_IN_PROGRESS) != 0);
+ 
+ 	chan = omap_hsmmc_get_dma_chan(host, data);
+ 
+@@ -1328,7 +1381,7 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
+ 	/* Does not fail */
+ 	dmaengine_submit(tx);
+ 
+-	host->dma_ch = 1;
++	host->req_flags |= RQF_DMA_IN_PROGRESS;
+ 
+ 	dma_async_issue_pending(chan);
+ 
+@@ -1448,8 +1501,11 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
+ 	struct omap_hsmmc_host *host = mmc_priv(mmc);
+ 	int err;
+ 
+-	BUG_ON(host->req_in_progress);
+-	BUG_ON(host->dma_ch != -1);
++	BUG_ON((host->req_flags & RQF_REQ_IN_PROGRESS) != 0);
++	BUG_ON((host->req_flags & RQF_REQ_DONE) != 0);
++	BUG_ON((host->req_flags & RQF_DMA_IN_PROGRESS) != 0);
++	BUG_ON((host->req_flags & RQF_DMA_DONE) != 0);
++
+ 	if (host->protect_card) {
+ 		if (host->reqs_blocked < 3) {
+ 			/*
+@@ -1826,13 +1882,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 	host->pdata	= pdata;
+ 	host->dev	= &pdev->dev;
+ 	host->use_dma	= 1;
+-	host->dma_ch	= -1;
+ 	host->irq	= irq;
+ 	host->slot_id	= 0;
+ 	host->mapbase	= res->start + pdata->reg_offset;
+ 	host->base	= ioremap(host->mapbase, SZ_4K);
+ 	host->power_mode = MMC_POWER_OFF;
+ 	host->next_data.cookie = 1;
++	host->req_flags	= 0;
+ 
+ 	platform_set_drvdata(pdev, host);
+ 
+-- 
+1.8.2.1
+
diff --git a/0013-ARM-EDMA-Fix-clearing-of-unused-list-for-DT-DMA-reso.patch b/0013-ARM-EDMA-Fix-clearing-of-unused-list-for-DT-DMA-reso.patch
new file mode 100644
index 0000000..50d2218
--- /dev/null
+++ b/0013-ARM-EDMA-Fix-clearing-of-unused-list-for-DT-DMA-reso.patch
@@ -0,0 +1,65 @@
+From c845f409541688e339c6b86b1eeea5f7110821d2 Mon Sep 17 00:00:00 2001
+From: Joel Fernandes <joelf at ti.com>
+Date: Mon, 22 Jul 2013 12:49:17 -0500
+Subject: [PATCH 13/13] ARM: EDMA: Fix clearing of unused list for DT DMA
+ resources
+
+HWMOD removal for MMC is breaking edma_start as the events are being manually
+triggered due to unused channel list not being clear, Thanks to Balaji TK for
+finding this issue.
+
+This patch fixes the issue, by reading the "dmas" property from the DT node if
+it exists and clearing the bits in the unused channel list.
+
+Cc: Balaji T K <balajitk at ti.com>
+Cc: Pantel Antoniou <panto at antoniou-consulting.com>
+Signed-off-by: Joel Fernandes <joelf at ti.com>
+---
+ arch/arm/common/edma.c | 31 +++++++++++++++++++++++--------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
+index 39ad030..18159d7 100644
+--- a/arch/arm/common/edma.c
++++ b/arch/arm/common/edma.c
+@@ -560,14 +560,29 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
+ static int prepare_unused_channel_list(struct device *dev, void *data)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+-	int i, ctlr;
+-
+-	for (i = 0; i < pdev->num_resources; i++) {
+-		if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
+-				(int)pdev->resource[i].start >= 0) {
+-			ctlr = EDMA_CTLR(pdev->resource[i].start);
+-			clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
+-					edma_cc[ctlr]->edma_unused);
++	int i = 0, ctlr;
++	u32 dma_chan;
++	__be32 *dma_chan_p;
++	struct property *prop;
++
++	if (dev->of_node) {
++		of_property_for_each_u32(dev->of_node, "dmas", prop, \
++					 dma_chan_p, dma_chan) {
++			if (i++ & 1) {
++				ctlr = EDMA_CTLR(dma_chan);
++				clear_bit(EDMA_CHAN_SLOT(dma_chan),
++						edma_cc[ctlr]->edma_unused);
++			}
++		}
++	} else {
++		for (; i < pdev->num_resources; i++) {
++			if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
++			    (int)pdev->resource[i].start >= 0) {
++				ctlr = EDMA_CTLR(pdev->resource[i].start);
++				clear_bit(EDMA_CHAN_SLOT(
++					  pdev->resource[i].start),
++					  edma_cc[ctlr]->edma_unused);
++			}
+ 		}
+ 	}
+ 
+-- 
+1.8.2.1
+
diff --git a/kernel.spec b/kernel.spec
index e04bd73..f73b99c 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -719,7 +719,24 @@ Patch21030: arm-wandboard-quad.patch
 Patch21031: arm-imx-fixsound.patch
 
 # AM33xx
-Patch21040: arm-am33xx-bbb-dts.patch
+Patch21040: 0001-reset-Add-driver-for-gpio-controlled-reset-pins.patch
+Patch21041: 0001-ARM-davinci-uart-move-to-devid-based-clk_get.patch
+Patch21042: 0002-dma-edma-add-device_slave_sg_limits-support.patch
+Patch21043: 0003-dmaengine-add-dma_get_slave_sg_limits.patch
+Patch21044: 0004-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
+Patch21045: 0005-da8xx-config-Enable-MMC-and-FS-options.patch
+Patch21046: 0006-ARM-dts-add-AM33XX-EDMA-support.patch
+Patch21047: 0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch
+Patch21048: 0008-ARM-dts-add-AM33XX-MMC-support.patch
+Patch21049: 0009-DMA-EDMA-Split-out-PaRAM-set-calculations-into-its-o.patch
+Patch21050: 0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch
+Patch21051: 0011-sound-soc-soc-dmaengine-pcm-Add-support-for-new-DMAE.patch
+Patch21052: 0012-mmc-omap_hsmmc-Fix-the-crashes-due-to-the-interrupts.patch
+Patch21053: 0013-ARM-EDMA-Fix-clearing-of-unused-list-for-DT-DMA-reso.patch
+Patch21054: 0001-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
+Patch21055: 0002-omap_hsmmc-Add-reset-gpio.patch
+Patch21056: 0001-am335x-dts-Add-beaglebone-black-DTS.patch
+Patch21057: 0002-dts-beaglebone-Add-I2C-definitions-for-EEPROMs-capes.patch
 
 #rhbz 754518
 Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
@@ -1328,7 +1345,24 @@ ApplyPatch arm-wandboard-quad.patch
 ApplyPatch arm-imx-fixsound.patch
 
 # Fix OMAP and AM33xx (BeagleBone)
-#pplyPatch arm-am33xx-bbb-dts.patch
+ApplyPatch 0001-reset-Add-driver-for-gpio-controlled-reset-pins.patch
+ApplyPatch 0001-ARM-davinci-uart-move-to-devid-based-clk_get.patch
+ApplyPatch 0002-dma-edma-add-device_slave_sg_limits-support.patch
+ApplyPatch 0003-dmaengine-add-dma_get_slave_sg_limits.patch
+ApplyPatch 0004-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
+ApplyPatch 0005-da8xx-config-Enable-MMC-and-FS-options.patch
+ApplyPatch 0006-ARM-dts-add-AM33XX-EDMA-support.patch
+ApplyPatch 0007-ARM-dts-add-AM33XX-SPI-DMA-support.patch
+ApplyPatch 0008-ARM-dts-add-AM33XX-MMC-support.patch
+ApplyPatch 0009-DMA-EDMA-Split-out-PaRAM-set-calculations-into-its-o.patch
+ApplyPatch 0010-DMA-EDMA-Add-support-for-Cyclic-DMA.patch
+ApplyPatch 0011-sound-soc-soc-dmaengine-pcm-Add-support-for-new-DMAE.patch
+ApplyPatch 0012-mmc-omap_hsmmc-Fix-the-crashes-due-to-the-interrupts.patch
+ApplyPatch 0013-ARM-EDMA-Fix-clearing-of-unused-list-for-DT-DMA-reso.patch
+ApplyPatch 0001-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
+ApplyPatch 0002-omap_hsmmc-Add-reset-gpio.patch
+ApplyPatch 0001-am335x-dts-Add-beaglebone-black-DTS.patch
+ApplyPatch 0002-dts-beaglebone-Add-I2C-definitions-for-EEPROMs-capes.patch
 
 #
 # bugfixes to drivers and filesystems
@@ -2281,6 +2315,10 @@ fi
 #                 ||----w |
 #                 ||     ||
 %changelog
+* Wed Sep  4 2013 Peter Robinson <pbrobinson at fedoraproject.org>
+- Add patch set to fix MMC on AM33xx
+- Add support for BeagleBone Black (very basic!)
+
 * Tue Sep 03 2013 Josh Boyer <jwboyer at fedoraproject.org> - 3.11.0-3
 - Add system_keyring patches back in
 


More information about the scm-commits mailing list