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

This commit is contained in:
Peter Robinson 2013-09-04 07:41:52 +01:00
parent 76b66ee100
commit 1ebcd4a338
20 changed files with 3025 additions and 232 deletions

View File

@ -0,0 +1,724 @@
From da41a8e42998c4bff8b19ee3d9fdfed6a5951c3f Mon Sep 17 00:00:00 2001
From: "Manjunathappa, Prakash" <prakash.pm@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@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@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

View File

@ -0,0 +1,323 @@
From 35bd7cf94f2680c4674c1df72f9ab322f393a9c2 Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@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@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@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@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@44e09000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+
+ status = "okay";
+ };
+
+ i2c0: i2c@44e0b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ };
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ compatible = "gpio-leds";
+
+ led@2 {
+ label = "beaglebone:blue:heartbeat";
+ gpios = <&gpio1 21 0>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "beaglebone:blue:mmc0";
+ gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "beaglebone:blue:usr2";
+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led@5 {
+ label = "beaglebone:blue:usr3";
+ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+ regulators {
+ dcdc1_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@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@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@3 {
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>; /* orig 3.3V*/
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@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

View File

@ -0,0 +1,34 @@
From 9e6eeee6a1e0477f237dee5015c982296a91403f Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@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

View File

@ -0,0 +1,265 @@
From 31bacc8256b3ddb19269a3a1c74b0ba3851d1e19 Mon Sep 17 00:00:00 2001
From: Philipp Zabel <p.zabel@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@pengutronix.de>
Reviewed-by: Stephen Warren <swarren@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@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@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

View File

@ -0,0 +1,76 @@
From 6077fbf31d4263222eb1815f1c4edf67e90a3434 Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@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@ti.com>
Signed-off-by: Joel A Fernandes <joelagnel@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

View File

@ -0,0 +1,142 @@
From e3c9bd680440e6216a86184687968a3939c06160 Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@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@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@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
};
+
+ i2c2: i2c@4819c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
+ clock-frequency = <100000>;
+
+ cape_eeprom0: cape_eeprom0@54 {
+ compatible = "at,24c256";
+ reg = <0x54>;
+ };
+
+ cape_eeprom1: cape_eeprom1@55 {
+ compatible = "at,24c256";
+ reg = <0x55>;
+ };
+
+ cape_eeprom2: cape_eeprom2@56 {
+ compatible = "at,24c256";
+ reg = <0x56>;
+ };
+
+ cape_eeprom3: cape_eeprom3@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@50 {
+ compatible = "at,24c256";
+ reg = <0x50>;
+ };
+ };
+
+ i2c2: i2c@4819c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
+ clock-frequency = <100000>;
+
+ cape_eeprom0: cape_eeprom0@54 {
+ compatible = "at,24c256";
+ reg = <0x54>;
+ };
+
+ cape_eeprom1: cape_eeprom1@55 {
+ compatible = "at,24c256";
+ reg = <0x55>;
+ };
+
+ cape_eeprom2: cape_eeprom2@56 {
+ compatible = "at,24c256";
+ reg = <0x56>;
+ };
+
+ cape_eeprom3: cape_eeprom3@57 {
+ compatible = "at,24c256";
+ reg = <0x57>;
+ };
};
};
--
1.8.2.1

View File

@ -0,0 +1,138 @@
From 364d4535955f21a8ce13e969aedde946a2d566b8 Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@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@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

View File

@ -0,0 +1,94 @@
From c8ff7a795bf883c61b7d7f506b0bb7796db6cb01 Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@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@ti.com>
Signed-off-by: Joel A Fernandes <joelagnel@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

View File

@ -0,0 +1,48 @@
From e1e06db0fb0ae8cfc2b3dc9c08b3237a050e2789 Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@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@ti.com>
Acked-by: Tony Lindgren <tony@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

View File

@ -0,0 +1,33 @@
From bb43e18a5c1626fadb8674b287224905358751be Mon Sep 17 00:00:00 2001
From: Joel A Fernandes <agnel.joel@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@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

View File

@ -0,0 +1,44 @@
From b9e4382015c702fbc1be1753074fce93a0965ac0 Mon Sep 17 00:00:00 2001
From: Matt Porter <mdp@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@ti.com>
Signed-off-by: Joel A Fernandes <joelagnel@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@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@44e07000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio1";
--
1.8.2.1

View File

@ -0,0 +1,44 @@
From 16649496dc8c4334ab72a0a5a407953e3dcf4c83 Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@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@ti.com>
Signed-off-by: Joel A Fernandes <joelagnel@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

View File

@ -0,0 +1,191 @@
From 1aa00b457ea36f6eeb78b66be076e16a2d3fafe0 Mon Sep 17 00:00:00 2001
From: Matt Porter <mporter@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@ti.com>
Compatible added by Balaji TK <balajitk@ti.com>
ti,needs-special-hs-handling added by Gururaja Hebbar <gururaja.hebbar@ti.com>
Signed-off-by: Matt Porter <mporter@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Joel Fernandes <joelf@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@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@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@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@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@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@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@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@47810000 {
+ compatible = "ti,omap4-hsmmc";
+ ti,hwmods = "mmc3";
+ ti,needs-special-reset;
+ interrupts = <29>;
+ interrupt-parent = <&intc>;
+ reg = <0x47810000 0x1000>;
+ status = "disabled";
+ };
+
wdt2: wdt@44e35000 {
compatible = "ti,omap3-wdt";
ti,hwmods = "wd_timer2";
--
1.8.2.1

View File

@ -0,0 +1,271 @@
From 14c120151d8ae2e335dd8728c88d6cd1a52863c8 Mon Sep 17 00:00:00 2001
From: Joel Fernandes <joelf@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@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

View File

@ -0,0 +1,130 @@
From caf38f4702a75c7ba13d5d80d902812c5faa8501 Mon Sep 17 00:00:00 2001
From: Joel Fernandes <joelf@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@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

View File

@ -0,0 +1,60 @@
From e85ad9182c962bb095beb435e98fde612a4ef88d Mon Sep 17 00:00:00 2001
From: Joel Fernandes <joelf@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@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

View File

@ -0,0 +1,303 @@
From b13c0c62ddf7a3a7d5b96fed8ea80f21f3bb2dad Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@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

View File

@ -0,0 +1,65 @@
From c845f409541688e339c6b86b1eeea5f7110821d2 Mon Sep 17 00:00:00 2001
From: Joel Fernandes <joelf@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@ti.com>
Cc: Pantel Antoniou <panto@antoniou-consulting.com>
Signed-off-by: Joel Fernandes <joelf@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

View File

@ -1,230 +0,0 @@
From 227cadff47a2b00e91deb5b54f1fd551808d42ae Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <panto@antoniou-consulting.com>
Date: Fri, 28 Jun 2013 14:18:08 +0300
Subject: [PATCH 1/3] 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@antoniou-consulting.com>
---
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/am335x-boneblack.dts | 196 +++++++++++++++++++++++++++++++++
2 files changed, 198 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
--- a/arch/arm/boot/dts/Makefile.orig 2013-07-17 11:51:55.510389342 +0100
+++ b/arch/arm/boot/dts/Makefile 2013-07-17 11:55:09.492689175 +0100
@@ -172,6 +172,7 @@
am335x-evm.dtb \
am335x-evmsk.dtb \
am335x-bone.dtb \
+ am335x-boneblack.dtb \
am3517-evm.dtb \
am3517_mt_ventoux.dtb \
am43x-epos-evm.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..d21e223
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -0,0 +1,196 @@
+/*
+ * 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@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 0x10000000>; /* 256 MB */
+ };
+
+ am33xx_pinmux: pinmux@44e10800 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_leds_s0>;
+
+ user_leds_s0: user_leds_s0 {
+ pinctrl-single,pins = <
+ 0x54 0x7 /* gpmc_a5.gpio1_21, OUTPUT | MODE7 */
+ 0x58 0x17 /* gpmc_a6.gpio1_22, OUTPUT_PULLUP | MODE7 */
+ 0x5c 0x7 /* gpmc_a7.gpio1_23, OUTPUT | MODE7 */
+ 0x60 0x17 /* gpmc_a8.gpio1_24, OUTPUT_PULLUP | MODE7 */
+ >;
+ };
+
+ emmc2_pins: pinmux_emmc2_pins {
+ pinctrl-single,pins = <
+ 0x80 0x32 /* gpmc_csn1.mmc1_clk, INPUT_PULLUP | MODE2 */
+ 0x84 0x32 /* gpmc_csn2.mmc1_cmd, INPUT_PULLUP | MODE2 */
+ 0x00 0x31 /* gpmc_ad0.mmc1_dat0, INPUT_PULLUP | MODE1 */
+ 0x04 0x31 /* gpmc_ad1.mmc1_dat1, INPUT_PULLUP | MODE1 */
+ 0x08 0x31 /* gpmc_ad2.mmc1_dat2, INPUT_PULLUP | MODE1 */
+ 0x0c 0x31 /* gpmc_ad3.mmc1_dat3, INPUT_PULLUP | MODE1 */
+ 0x10 0x31 /* gpmc_ad4.mmc1_dat4, INPUT_PULLUP | MODE1 */
+ 0x14 0x31 /* gpmc_ad5.mmc1_dat5, INPUT_PULLUP | MODE1 */
+ 0x18 0x31 /* gpmc_ad6.mmc1_dat6, INPUT_PULLUP | MODE1 */
+ 0x1c 0x31 /* gpmc_ad7.mmc1_dat7, INPUT_PULLUP | MODE1 */
+ /* eMMC_RSTn */
+ 0x50 0x17 /* gpmc_a4.gpio1_20, OUTPUT | MODE7 | PULLUP */
+ >;
+ };
+ };
+
+ ocp {
+ uart1: serial@44e09000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@44e0b000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led@2 {
+ label = "beaglebone:green:heartbeat";
+ gpios = <&gpio1 21 0>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+
+ led@3 {
+ label = "beaglebone:green:mmc0";
+ gpios = <&gpio1 22 0>;
+ linux,default-trigger = "mmc0";
+ default-state = "off";
+ };
+
+ led@4 {
+ label = "beaglebone:green:usr2";
+ gpios = <&gpio1 23 0>;
+ default-state = "off";
+ };
+
+ led@5 {
+ label = "beaglebone:green:usr3";
+ gpios = <&gpio1 24 0>;
+ default-state = "off";
+ };
+ };
+
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+ regulators {
+ dcdc1_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@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@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@3 {
+ regulator-always-on;
+ };
+
+ ldo2_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ ldo3_reg: regulator@5 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>; /* orig 3.3V*/
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ regulator-always-on;
+ };
+ };
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmcsd_fixed>;
+ ti,vcc-aux-disable-is-sleep;
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc2_pins>; /* wrong numbering */
+ vmmc-supply = <&ldo3_reg>;
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
+ ti,vcc-aux-disable-is-sleep;
+
+ reset-gpio = <&gpio1 20 0x00>;
+};
--
1.8.2.1

View File

@ -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@fedoraproject.org>
- Add patch set to fix MMC on AM33xx
- Add support for BeagleBone Black (very basic!)
* Tue Sep 03 2013 Josh Boyer <jwboyer@fedoraproject.org> - 3.11.0-3
- Add system_keyring patches back in