1
0
mirror of https://git.yoctoproject.org/meta-ti synced 2026-01-12 01:20:20 +00:00

linux-omap 2.6.39: import from OE

Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
Koen Kooi
2011-05-21 10:55:49 +02:00
parent 07e8c30da9
commit 1735237550
33 changed files with 20970 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
From 6597e99e0b74076530e34608e2d9a7b86a694b8e Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Fri, 20 May 2011 12:48:37 +0200
Subject: [PATCH 1/2] OMAP3: beagle: add support for beagleboard xM revision C
The USB enable GPIO has been inverted and the USER button moved.
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm/mach-omap2/board-omap3beagle.c | 32 +++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2de4b02..1eb1e8e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -62,7 +62,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -70,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};
static u8 omap3_beagle_version;
@@ -124,9 +127,17 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ case 1:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
return;
@@ -278,7 +289,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -298,7 +309,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -320,7 +331,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -334,7 +345,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -625,7 +636,7 @@ static void __init beagle_opp_init(void)
}
/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -665,6 +676,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
1.6.6.1

View File

@@ -0,0 +1,354 @@
From 70b4b60b198137ca8aebd577142ea3bb6c273a55 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Fri, 20 May 2011 13:06:24 +0200
Subject: [PATCH 2/2] OMAP3: beagle: add support for expansionboards
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
arch/arm/mach-omap2/board-omap3beagle.c | 267 ++++++++++++++++++++++++++++++-
1 files changed, 264 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 1eb1e8e..40e54f2 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/gpio.h>
+#include <linux/irq.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/opp.h>
@@ -153,6 +154,162 @@ fail0:
return;
}
+char expansionboard_name[16];
+
+#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+
+#define OMAP_BEAGLE_WLAN_EN_GPIO (139)
+#define OMAP_BEAGLE_BT_EN_GPIO (138)
+#define OMAP_BEAGLE_WLAN_IRQ_GPIO (137)
+#define OMAP_BEAGLE_FM_EN_BT_WU (136)
+
+struct wl12xx_platform_data omap_beagle_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_BEAGLE_WLAN_IRQ_GPIO),
+ .board_ref_clock = 2, /* 38.4 MHz */
+};
+
+static int gpios[] = {OMAP_BEAGLE_BT_EN_GPIO, OMAP_BEAGLE_FM_EN_BT_WU, -1};
+static struct platform_device wl12xx_device = {
+ .name = "kim",
+ .id = -1,
+ .dev.platform_data = &gpios,
+};
+
+static struct omap2_hsmmc_info mmcbbt[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+ };
+
+static struct regulator_consumer_supply beagle_vmmc2_supply = {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.1",
+};
+
+static struct regulator_init_data beagle_vmmc2 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &beagle_vmmc2_supply,
+};
+
+static struct fixed_voltage_config beagle_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_BEAGLE_WLAN_EN_GPIO,
+ .startup_delay = 70000, /* 70ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &beagle_vmmc2,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &beagle_vwlan,
+ },
+};
+#endif
+
+#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#define OMAP3BEAGLE_GPIO_ENC28J60_IRQ 157
+
+static struct omap2_mcspi_device_config enc28j60_spi_chip_info = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info omap3beagle_zippy_spi_board_info[] __initdata = {
+ {
+ .modalias = "enc28j60",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 20000000,
+ .controller_data = &enc28j60_spi_chip_info,
+ },
+};
+
+static void __init omap3beagle_enc28j60_init(void)
+{
+ if ((gpio_request(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, "ENC28J60_IRQ") == 0) &&
+ (gpio_direction_input(OMAP3BEAGLE_GPIO_ENC28J60_IRQ) == 0)) {
+ gpio_export(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, 0);
+ omap3beagle_zippy_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ);
+ irq_set_irq_type(omap3beagle_zippy_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for ENC28J60_IRQ\n");
+ return;
+ }
+
+ spi_register_board_info(omap3beagle_zippy_spi_board_info,
+ ARRAY_SIZE(omap3beagle_zippy_spi_board_info));
+}
+
+#else
+static inline void __init omap3beagle_enc28j60_init(void) { return; }
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#define OMAP3BEAGLE_GPIO_KS8851_IRQ 157
+
+static struct omap2_mcspi_device_config ks8851_spi_chip_info = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info omap3beagle_zippy2_spi_board_info[] __initdata = {
+ {
+ .modalias = "ks8851",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 36000000,
+ .controller_data = &ks8851_spi_chip_info,
+ },
+};
+
+static void __init omap3beagle_ks8851_init(void)
+{
+ if ((gpio_request(OMAP3BEAGLE_GPIO_KS8851_IRQ, "KS8851_IRQ") == 0) &&
+ (gpio_direction_input(OMAP3BEAGLE_GPIO_KS8851_IRQ) == 0)) {
+ gpio_export(OMAP3BEAGLE_GPIO_KS8851_IRQ, 0);
+ omap3beagle_zippy2_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_KS8851_IRQ);
+ irq_set_irq_type(omap3beagle_zippy2_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for KS8851_IRQ\n");
+ return;
+ }
+
+ spi_register_board_info(omap3beagle_zippy2_spi_board_info,
+ ARRAY_SIZE(omap3beagle_zippy2_spi_board_info));
+}
+
+#else
+static inline void __init omap3beagle_ks8851_init(void) { return; }
+#endif
+
static struct mtd_partition omap3beagle_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
@@ -271,6 +428,12 @@ static struct omap2_hsmmc_info mmc[] = {
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.gpio_wp = 29,
},
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .transceiver = true,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
{} /* Terminator */
};
@@ -300,11 +463,25 @@ static int beagle_twl_gpio_setup(struct device *dev,
}
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
mmc[0].gpio_cd = gpio + 0;
+#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
+ if(!strcmp(expansionboard_name, "bbtoys-wifi")) {
+ omap2_hsmmc_init(mmcbbt);
+ /* link regulators to MMC adapters */
+ beagle_vmmc1_supply.dev = mmcbbt[0].dev;
+ beagle_vsim_supply.dev = mmcbbt[0].dev;
+ } else {
+ omap2_hsmmc_init(mmc);
+ /* link regulators to MMC adapters */
+ beagle_vmmc1_supply.dev = mmc[0].dev;
+ beagle_vsim_supply.dev = mmc[0].dev;
+ }
+#else
omap2_hsmmc_init(mmc);
/* link regulators to MMC adapters */
beagle_vmmc1_supply.dev = mmc[0].dev;
beagle_vsim_supply.dev = mmc[0].dev;
+#endif
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
@@ -464,7 +641,7 @@ static struct twl4030_platform_data beagle_twldata = {
.vpll2 = &beagle_vpll2,
};
-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
+static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
@@ -479,10 +656,24 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
},
};
+#if defined(CONFIG_RTC_DRV_DS1307) || \
+ defined(CONFIG_RTC_DRV_DS1307_MODULE)
+
+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("ds1307", 0x68),
+ },
+};
+#else
+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {};
+#endif
+
static int __init omap3_beagle_i2c_init(void)
{
- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
- ARRAY_SIZE(beagle_i2c_boardinfo));
+ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo,
+ ARRAY_SIZE(beagle_i2c1_boardinfo));
+ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo,
+ ARRAY_SIZE(beagle_i2c2_boardinfo));
/* Bus 3 is attached to the DVI port where devices like the pico DLP
* projector don't work reliably with 400kHz */
omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
@@ -625,6 +816,15 @@ static struct omap_musb_board_data musb_board_data = {
.power = 100,
};
+static int __init expansionboard_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+ strncpy(expansionboard_name, str, 16);
+ printk(KERN_INFO "Beagle expansionboard: %s\n", expansionboard_name);
+ return 0;
+}
+
static void __init beagle_opp_init(void)
{
int r = 0;
@@ -691,6 +891,65 @@ static void __init omap3_beagle_init(void)
/* REVISIT leave DVI powered down until it's needed ... */
gpio_direction_output(170, true);
+ if(!strcmp(expansionboard_name, "zippy"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n");
+ omap3beagle_enc28j60_init();
+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n");
+ mmc[1].gpio_wp = 141;
+ mmc[1].gpio_cd = 162;
+ }
+
+ if(!strcmp(expansionboard_name, "zippy2"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n");
+ omap3beagle_ks8851_init();
+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n");
+ mmc[1].gpio_wp = 141;
+ mmc[1].gpio_cd = 162;
+ }
+
+ if(!strcmp(expansionboard_name, "trainer"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: exporting GPIOs 130-141,162 to userspace\n");
+ gpio_request(130, "sysfs");
+ gpio_export(130, 1);
+ gpio_request(131, "sysfs");
+ gpio_export(131, 1);
+ gpio_request(132, "sysfs");
+ gpio_export(132, 1);
+ gpio_request(133, "sysfs");
+ gpio_export(133, 1);
+ gpio_request(134, "sysfs");
+ gpio_export(134, 1);
+ gpio_request(135, "sysfs");
+ gpio_export(135, 1);
+ gpio_request(136, "sysfs");
+ gpio_export(136, 1);
+ gpio_request(137, "sysfs");
+ gpio_export(137, 1);
+ gpio_request(138, "sysfs");
+ gpio_export(138, 1);
+ gpio_request(139, "sysfs");
+ gpio_export(139, 1);
+ gpio_request(140, "sysfs");
+ gpio_export(140, 1);
+ gpio_request(141, "sysfs");
+ gpio_export(141, 1);
+ gpio_request(162, "sysfs");
+ gpio_export(162, 1);
+ }
+
+ if(!strcmp(expansionboard_name, "bbtoys-wifi"))
+ {
+ if (wl12xx_set_platform_data(&omap_beagle_wlan_data))
+ pr_err("error setting wl12xx data\n");
+ printk(KERN_INFO "Beagle expansionboard: registering wl12xx bt platform device\n");
+ platform_device_register(&wl12xx_device);
+ printk(KERN_INFO "Beagle expansionboard: registering wl12xx wifi platform device\n");
+ platform_device_register(&omap_vwlan_device);
+ }
+
usb_musb_init(&musb_board_data);
usbhs_init(&usbhs_bdata);
omap3beagle_flash_init();
@@ -703,6 +962,8 @@ static void __init omap3_beagle_init(void)
beagle_opp_init();
}
+early_param("buddy", expansionboard_setup);
+
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
.boot_params = 0x80000100,
--
1.6.6.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
From 49958f1925489048aa5a6834f61d61c8551f8ec3 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Thu, 7 Apr 2011 15:28:47 +0300
Subject: [PATCH 01/28] OMAP: DSS2: DSI: fix use_sys_clk & highfreq
use_sys_clk and highfreq fields in dsi.current_cinfo were never set.
Luckily they weren't used anywhere so it didn't cause any problems.
This patch fixes those fields and they are now set at the same time as
the rest of the fields.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 0a7f1a4..8604153 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1276,6 +1276,9 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
DSSDBGF();
+ dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk;
+ dsi.current_cinfo.highfreq = cinfo->highfreq;
+
dsi.current_cinfo.fint = cinfo->fint;
dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
--
1.6.6.1

View File

@@ -0,0 +1,49 @@
From ccf7f535d7e809e563812f1c4897bdb9a1ff9233 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Mon, 4 Apr 2011 10:02:53 +0300
Subject: [PATCH 02/28] OMAP: DSS2: DSI: fix dsi_dump_clocks()
On OMAP4, reading DSI_PLL_CONFIGURATION2 register requires the L3 clock
(CIO_CLK_ICG) to PLL. Currently dsi_dump_clocks() tries to read that
register without enabling the L3 clock, leading to crash if DSI is not
in use.
The status of the bit being read from DSI_PLL_CONFIGURATION2 is
available from dsi_clock_info->use_sys_clk, so we can avoid the whole
problem by just using that.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8604153..1464ac4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1491,7 +1491,6 @@ void dsi_pll_uninit(void)
void dsi_dump_clocks(struct seq_file *s)
{
- int clksel;
struct dsi_clock_info *cinfo = &dsi.current_cinfo;
enum dss_clk_source dispc_clk_src, dsi_clk_src;
@@ -1500,13 +1499,10 @@ void dsi_dump_clocks(struct seq_file *s)
enable_clocks(1);
- clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11);
-
seq_printf(s, "- DSI PLL -\n");
seq_printf(s, "dsi pll source = %s\n",
- clksel == 0 ?
- "dss_sys_clk" : "pclkfree");
+ cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree");
seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
--
1.6.6.1

View File

@@ -0,0 +1,43 @@
From 2ffa7a6c3cafb4f2a48ae274b2952ad48ae78eeb Mon Sep 17 00:00:00 2001
From: Archit Taneja <archit@ti.com>
Date: Thu, 31 Mar 2011 13:23:35 +0530
Subject: [PATCH 03/28] OMAP2PLUS: DSS2: Fix: Return correct lcd clock source for OMAP2/3
dss.lcd_clk_source is set to the default value DSS_CLK_SRC_FCK at dss_init.
For OMAP2 and OMAP3, the dss.lcd_clk_source should always be the same as
dss.dispc_clk_source. The function dss_get_lcd_clk_source() always returns the
default value DSS_CLK_SRC_FCK for OMAP2/3. This leads to wrong clock dumps when
dispc_clk_source is not DSS_CLK_SRC_FCK.
Correct this function to always return dss.dispc_clk_source for OMAP2/3.
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dss.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 3f1fee6..c3b48a0 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -385,8 +385,14 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
{
- int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
- return dss.lcd_clk_source[ix];
+ if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
+ return dss.lcd_clk_source[ix];
+ } else {
+ /* LCD_CLK source is the same as DISPC_FCLK source for
+ * OMAP2 and OMAP3 */
+ return dss.dispc_clk_source;
+ }
}
/* calculate clock rates using dividers in cinfo */
--
1.6.6.1

View File

@@ -0,0 +1,64 @@
From ee251e5c35b1325d696df35d297f34a9ccd6f5af Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Fri, 15 Apr 2011 10:42:59 +0300
Subject: [PATCH 04/28] OMAP: DSS: DSI: Fix DSI PLL power bug
OMAP3630 has a HW bug causing DSI PLL power command POWER_ON_DIV (0x3)
to not work properly. The bug prevents us from enabling DSI PLL power
only to HS divider block.
This patch adds a dss feature for the bug and converts POWER_ON_DIV
requests to POWER_ON_ALL (0x2).
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 5 +++++
drivers/video/omap2/dss/dss_features.c | 2 +-
drivers/video/omap2/dss/dss_features.h | 2 ++
3 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 1464ac4..cbd9ca4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1059,6 +1059,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
{
int t = 0;
+ /* DSI-PLL power command 0x3 is not working */
+ if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) &&
+ state == DSI_PLL_POWER_ON_DIV)
+ state = DSI_PLL_POWER_ON_ALL;
+
REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */
/* PLL_PWR_STATUS */
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index aa16222..8c50e18 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -271,7 +271,7 @@ static struct omap_dss_features omap3630_dss_features = {
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
- FEAT_RESIZECONF,
+ FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG,
.num_mgrs = 2,
.num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 12e9c4e..37922ce 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -40,6 +40,8 @@ enum dss_feat_id {
/* Independent core clk divider */
FEAT_CORE_CLK_DIV = 1 << 11,
FEAT_LCD_CLK_SRC = 1 << 12,
+ /* DSI-PLL power command 0x3 is not working */
+ FEAT_DSI_PLL_PWR_BUG = 1 << 13,
};
/* DSS register field id */
--
1.6.6.1

View File

@@ -0,0 +1,61 @@
From c479d815f14b4b5ed7871660027d043a432968a8 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Fri, 8 Apr 2011 09:30:27 +0300
Subject: [PATCH 05/28] OMAP: DSS2: fix panel Kconfig dependencies
All DPI panels were missing dependency to OMAP2_DSS_DPI. Add the
dependency.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/displays/Kconfig | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index d18ad6b..609a280 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -3,6 +3,7 @@ menu "OMAP2/3 Display Device Drivers"
config PANEL_GENERIC_DPI
tristate "Generic DPI Panel"
+ depends on OMAP2_DSS_DPI
help
Generic DPI panel driver.
Supports DVI output for Beagle and OMAP3 SDP.
@@ -11,20 +12,20 @@ config PANEL_GENERIC_DPI
config PANEL_LGPHILIPS_LB035Q02
tristate "LG.Philips LB035Q02 LCD Panel"
- depends on OMAP2_DSS && SPI
+ depends on OMAP2_DSS_DPI && SPI
help
LCD Panel used on the Gumstix Overo Palo35
config PANEL_SHARP_LS037V7DW01
tristate "Sharp LS037V7DW01 LCD Panel"
- depends on OMAP2_DSS
+ depends on OMAP2_DSS_DPI
select BACKLIGHT_CLASS_DEVICE
help
LCD Panel used in TI's SDP3430 and EVM boards
config PANEL_NEC_NL8048HL11_01B
tristate "NEC NL8048HL11-01B Panel"
- depends on OMAP2_DSS
+ depends on OMAP2_DSS_DPI
help
This NEC NL8048HL11-01B panel is TFT LCD
used in the Zoom2/3/3630 sdp boards.
@@ -37,7 +38,7 @@ config PANEL_TAAL
config PANEL_TPO_TD043MTEA1
tristate "TPO TD043MTEA1 LCD Panel"
- depends on OMAP2_DSS && SPI
+ depends on OMAP2_DSS_DPI && SPI
help
LCD Panel used in OMAP3 Pandora
--
1.6.6.1

View File

@@ -0,0 +1,75 @@
From 661c19e763f0bda0a07bc64159c6b0c5f2f52b60 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Tue, 19 Jan 2010 21:19:15 -0800
Subject: [PATCH 06/28] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output
also add pal-16 and ntsc-16 omapfb.mode settings for 16bpp
---
drivers/video/omap2/dss/venc.c | 22 ++++++++++++++++++++++
drivers/video/omap2/omapfb/omapfb-main.c | 10 +++++++++-
2 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 8e35a5b..827723f 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -85,6 +85,11 @@
#define VENC_OUTPUT_TEST 0xC8
#define VENC_DAC_B__DAC_C 0xC8
+static char *tv_connection;
+
+module_param_named(tvcable, tv_connection, charp, 0);
+MODULE_PARM_DESC(tvcable, "TV connection type (svideo, composite)");
+
struct venc_config {
u32 f_control;
u32 vidout_ctrl;
@@ -458,6 +463,23 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
{
dssdev->panel.timings = omap_dss_pal_timings;
+ /* Allow the TV output to be overriden */
+ if (tv_connection) {
+ if (strcmp(tv_connection, "svideo") == 0) {
+ printk(KERN_INFO
+ "omapdss: tv output is svideo.\n");
+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO;
+ } else if (strcmp(tv_connection, "composite") == 0) {
+ printk(KERN_INFO
+ "omapdss: tv output is composite.\n");
+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+ } else {
+ printk(KERN_INFO
+ "omapdss: unsupported output type'%s'.\n",
+ tv_connection);
+ }
+ }
+
return 0;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 505ec66..eaeded5 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2036,7 +2036,15 @@ static int omapfb_mode_to_timings(const char *mode_str,
int r;
#ifdef CONFIG_OMAP2_DSS_VENC
- if (strcmp(mode_str, "pal") == 0) {
+ if (strcmp(mode_str, "pal-16") == 0) {
+ *timings = omap_dss_pal_timings;
+ *bpp = 16;
+ return 0;
+ } else if (strcmp(mode_str, "ntsc-16") == 0) {
+ *timings = omap_dss_ntsc_timings;
+ *bpp = 16;
+ return 0;
+ } else if (strcmp(mode_str, "pal") == 0) {
*timings = omap_dss_pal_timings;
*bpp = 24;
return 0;
--
1.6.6.1

View File

@@ -0,0 +1,27 @@
From 14ea4d9f0f90726b653b42697043e73ef699b4ba Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Sat, 19 Dec 2009 06:52:43 -0800
Subject: [PATCH 07/28] video: add timings for hd720
---
drivers/video/modedb.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 48c3ea8..b320a30 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -103,6 +103,10 @@ static const struct fb_videomode modedb[] = {
{ NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0,
FB_VMODE_NONINTERLACED },
+ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */
+ { "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5, 0,
+ FB_VMODE_NONINTERLACED },
+
/* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
{ NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 0,
FB_VMODE_INTERLACED },
--
1.6.6.1

View File

@@ -0,0 +1,29 @@
From b62ecb49cfe8978390b7c8848e13555c4c699b0f Mon Sep 17 00:00:00 2001
From: Steve Sakoman <sakoman@gmail.com>
Date: Tue, 15 Dec 2009 15:17:44 -0800
Subject: [PATCH 08/28] drivers: net: smsc911x: return ENODEV if device is not found
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
---
drivers/net/smsc911x.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 4b42ecc..5c1202b 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2028,8 +2028,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
}
retval = smsc911x_init(dev);
- if (retval < 0)
+ if (retval < 0) {
+ retval = -ENODEV;
goto out_unmap_io_3;
+ }
/* configure irq polarity and type before connecting isr */
if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH)
--
1.6.6.1

View File

@@ -0,0 +1,47 @@
From b1515f616ee48452a7cb2c5d0f31b1f8f4463f94 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <sakoman@gmail.com>
Date: Tue, 15 Dec 2009 15:24:10 -0800
Subject: [PATCH 09/28] drivers: input: touchscreen: ads7846: return ENODEV if device is not found
Signed-off-by: Steve Sakoman <sakoman@gmail.com>
---
drivers/input/touchscreen/ads7846.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 1de1c19..097db10 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1338,11 +1338,18 @@ static int __devinit ads7846_probe(struct spi_device *spi)
* the touchscreen, in case it's not connected.
*/
if (ts->model == 7845)
- ads7845_read12_ser(&spi->dev, PWRDOWN);
+ err = ads7845_read12_ser(&spi->dev, PWRDOWN);
else
- (void) ads7846_read12_ser(&spi->dev,
+ err = ads7846_read12_ser(&spi->dev,
READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+ /* if sample is all 0's or all 1's then there is no device on spi */
+ if ( (err == 0x000) || (err == 0xfff)) {
+ dev_info(&spi->dev, "no device detected, test read result was 0x%08X\n", err);
+ err = -ENODEV;
+ goto err_free_irq;
+ }
+
err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
if (err)
goto err_remove_hwmon;
@@ -1366,7 +1373,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
err_put_regulator:
regulator_put(ts->reg);
err_free_gpio:
- if (!ts->get_pendown_state)
+ if (!ts->get_pendown_state && ts->gpio_pendown != -1)
gpio_free(ts->gpio_pendown);
err_cleanup_filter:
if (ts->filter_cleanup)
--
1.6.6.1

View File

@@ -0,0 +1,25 @@
From c2b7ff69cae57875b711eeb9cb6c97e7ba090c08 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 3 Mar 2011 13:29:30 -0800
Subject: [PATCH 10/28] Revert "omap2_mcspi: Flush posted writes"
This reverts commit a330ce2001b290c59fe98c37e981683ef0a75fdf.
---
drivers/spi/omap2_mcspi.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 6f86ba0..6094be7 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -195,7 +195,6 @@ static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val)
cs->chconf0 = val;
mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val);
- mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
}
static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
--
1.6.6.1

View File

@@ -0,0 +1,482 @@
From ed9bca69fdaa7edac3573e5ef3f011c7f7dc4898 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Fri, 19 Nov 2010 15:11:19 -0800
Subject: [PATCH 11/28] Revert "omap_hsmmc: improve interrupt synchronisation"
This reverts commit b417577d3b9bbb06a4ddc9aa955af9bd503f7242.
Conflicts:
drivers/mmc/host/omap_hsmmc.c
---
drivers/mmc/host/omap_hsmmc.c | 267 ++++++++++++++++++++---------------------
1 files changed, 128 insertions(+), 139 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 259ece0..15a023b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -159,10 +159,12 @@ struct omap_hsmmc_host {
*/
struct regulator *vcc;
struct regulator *vcc_aux;
+ struct semaphore sem;
struct work_struct mmc_carddetect_work;
void __iomem *base;
resource_size_t mapbase;
spinlock_t irq_lock; /* Prevent races with irq handler */
+ unsigned long flags;
unsigned int id;
unsigned int dma_len;
unsigned int dma_sg_idx;
@@ -183,7 +185,6 @@ struct omap_hsmmc_host {
int protect_card;
int reqs_blocked;
int use_reg;
- int req_in_progress;
struct omap_mmc_platform_data *pdata;
};
@@ -556,32 +557,6 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
}
-static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
- struct mmc_command *cmd)
-{
- unsigned int irq_mask;
-
- if (host->use_dma)
- irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE);
- else
- irq_mask = INT_EN_MASK;
-
- /* Disable timeout for erases */
- if (cmd->opcode == MMC_ERASE)
- irq_mask &= ~DTO_ENABLE;
-
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- OMAP_HSMMC_WRITE(host->base, ISE, irq_mask);
- OMAP_HSMMC_WRITE(host->base, IE, irq_mask);
-}
-
-static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
-{
- OMAP_HSMMC_WRITE(host->base, ISE, 0);
- OMAP_HSMMC_WRITE(host->base, IE, 0);
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
-}
-
#ifdef CONFIG_PM
/*
@@ -650,7 +625,9 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
&& time_before(jiffies, timeout))
;
- omap_hsmmc_disable_irq(host);
+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
/* Do not initialize card-specific things if the power is off */
if (host->power_mode == MMC_POWER_OFF)
@@ -753,8 +730,6 @@ static void send_init_stream(struct omap_hsmmc_host *host)
return;
disable_irq(host->irq);
-
- OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
OMAP_HSMMC_WRITE(host->base, CON,
OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM);
OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
@@ -820,7 +795,17 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
host->cmd = cmd;
- omap_hsmmc_enable_irq(host, cmd);
+ /*
+ * Clear status bits and enable interrupts
+ */
+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+
+ if (host->use_dma)
+ OMAP_HSMMC_WRITE(host->base, IE,
+ INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE));
+ else
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
host->response_busy = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
@@ -854,7 +839,13 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
if (host->use_dma)
cmdreg |= DMA_EN;
- host->req_in_progress = 1;
+ /*
+ * In an interrupt context (i.e. STOP command), the spinlock is unlocked
+ * by the interrupt handler, otherwise (i.e. for a new request) it is
+ * unlocked here.
+ */
+ if (!in_interrupt())
+ spin_unlock_irqrestore(&host->irq_lock, host->flags);
OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg);
OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
@@ -869,23 +860,6 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data)
return DMA_FROM_DEVICE;
}
-static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq)
-{
- int dma_ch;
-
- spin_lock(&host->irq_lock);
- host->req_in_progress = 0;
- dma_ch = host->dma_ch;
- spin_unlock(&host->irq_lock);
-
- 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)
- return;
- host->mrq = NULL;
- mmc_request_done(host->mmc, mrq);
-}
-
/*
* Notify the transfer complete to MMC core
*/
@@ -902,19 +876,25 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
return;
}
- omap_hsmmc_request_done(host, mrq);
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
return;
}
host->data = NULL;
+ if (host->use_dma && host->dma_ch != -1)
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
+ omap_hsmmc_get_dma_dir(host, data));
+
if (!data->error)
data->bytes_xfered += data->blocks * (data->blksz);
else
data->bytes_xfered = 0;
if (!data->stop) {
- omap_hsmmc_request_done(host, data->mrq);
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, data->mrq);
return;
}
omap_hsmmc_start_command(host, data->stop, NULL);
@@ -940,8 +920,10 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd)
cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
}
}
- if ((host->data == NULL && !host->response_busy) || cmd->error)
- omap_hsmmc_request_done(host, cmd->mrq);
+ if ((host->data == NULL && !host->response_busy) || cmd->error) {
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, cmd->mrq);
+ }
}
/*
@@ -949,19 +931,14 @@ 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;
-
host->data->error = errno;
- spin_lock(&host->irq_lock);
- dma_ch = host->dma_ch;
- host->dma_ch = -1;
- spin_unlock(&host->irq_lock);
-
- if (host->use_dma && dma_ch != -1) {
+ if (host->use_dma && host->dma_ch != -1) {
dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
omap_hsmmc_get_dma_dir(host, host->data));
- omap_free_dma(dma_ch);
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
}
host->data = NULL;
}
@@ -1034,21 +1011,28 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
__func__);
}
-static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
+/*
+ * MMC controller IRQ handler
+ */
+static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
{
+ struct omap_hsmmc_host *host = dev_id;
struct mmc_data *data;
- int end_cmd = 0, end_trans = 0;
-
- if (!host->req_in_progress) {
- do {
- OMAP_HSMMC_WRITE(host->base, STAT, status);
- /* Flush posted write */
- status = OMAP_HSMMC_READ(host->base, STAT);
- } while (status & INT_EN_MASK);
- return;
+ int end_cmd = 0, end_trans = 0, status;
+
+ spin_lock(&host->irq_lock);
+
+ if (host->mrq == NULL) {
+ OMAP_HSMMC_WRITE(host->base, STAT,
+ OMAP_HSMMC_READ(host->base, STAT));
+ /* Flush posted write */
+ OMAP_HSMMC_READ(host->base, STAT);
+ spin_unlock(&host->irq_lock);
+ return IRQ_HANDLED;
}
data = host->data;
+ status = OMAP_HSMMC_READ(host->base, STAT);
dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
if (status & ERR) {
@@ -1101,27 +1085,15 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
}
OMAP_HSMMC_WRITE(host->base, STAT, status);
+ /* Flush posted write */
+ OMAP_HSMMC_READ(host->base, STAT);
if (end_cmd || ((status & CC) && host->cmd))
omap_hsmmc_cmd_done(host, host->cmd);
if ((end_trans || (status & TC)) && host->mrq)
omap_hsmmc_xfer_done(host, data);
-}
-
-/*
- * MMC controller IRQ handler
- */
-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);
- do {
- omap_hsmmc_do_irq(host, status);
- /* Flush posted write */
- status = OMAP_HSMMC_READ(host->base, STAT);
- } while (status & INT_EN_MASK);
+ spin_unlock(&host->irq_lock);
return IRQ_HANDLED;
}
@@ -1316,11 +1288,9 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host,
/*
* DMA call back function
*/
-static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
+static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data)
{
- struct omap_hsmmc_host *host = cb_data;
- struct mmc_data *data = host->mrq->data;
- int dma_ch, req_in_progress;
+ struct omap_hsmmc_host *host = data;
if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n",
@@ -1328,38 +1298,24 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
return;
}
- spin_lock(&host->irq_lock);
- if (host->dma_ch < 0) {
- spin_unlock(&host->irq_lock);
+ if (host->dma_ch < 0)
return;
- }
host->dma_sg_idx++;
if (host->dma_sg_idx < host->dma_len) {
/* Fire up the next transfer. */
- omap_hsmmc_config_dma_params(host, data,
- data->sg + host->dma_sg_idx);
- spin_unlock(&host->irq_lock);
+ omap_hsmmc_config_dma_params(host, host->data,
+ host->data->sg + host->dma_sg_idx);
return;
}
- dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
- omap_hsmmc_get_dma_dir(host, data));
-
- req_in_progress = host->req_in_progress;
- dma_ch = host->dma_ch;
+ omap_free_dma(host->dma_ch);
host->dma_ch = -1;
- spin_unlock(&host->irq_lock);
-
- omap_free_dma(dma_ch);
-
- /* If DMA has finished after TC, complete the request */
- if (!req_in_progress) {
- struct mmc_request *mrq = host->mrq;
-
- host->mrq = NULL;
- mmc_request_done(host->mmc, mrq);
- }
+ /*
+ * DMA Callback: run in interrupt context.
+ * mutex_unlock will throw a kernel warning if used.
+ */
+ up(&host->sem);
}
/*
@@ -1368,7 +1324,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
struct mmc_request *req)
{
- int dma_ch = 0, ret = 0, i;
+ int dma_ch = 0, ret = 0, err = 1, i;
struct mmc_data *data = req->data;
/* Sanity check: all the SG entries must be aligned by block size. */
@@ -1385,7 +1341,23 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
*/
return -EINVAL;
- BUG_ON(host->dma_ch != -1);
+ /*
+ * If for some reason the DMA transfer is still active,
+ * we wait for timeout period and free the dma
+ */
+ if (host->dma_ch != -1) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(100);
+ if (down_trylock(&host->sem)) {
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
+ return err;
+ }
+ } else {
+ if (down_trylock(&host->sem))
+ return err;
+ }
ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data),
"MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch);
@@ -1485,27 +1457,37 @@ 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);
- if (host->protect_card) {
- if (host->reqs_blocked < 3) {
- /*
- * Ensure the controller is left in a consistent
- * state by resetting the command and data state
- * machines.
- */
- omap_hsmmc_reset_controller_fsm(host, SRD);
- omap_hsmmc_reset_controller_fsm(host, SRC);
- host->reqs_blocked += 1;
- }
- req->cmd->error = -EBADF;
- if (req->data)
- req->data->error = -EBADF;
- req->cmd->retries = 0;
- mmc_request_done(mmc, req);
- return;
- } else if (host->reqs_blocked)
- host->reqs_blocked = 0;
+ /*
+ * Prevent races with the interrupt handler because of unexpected
+ * interrupts, but not if we are already in interrupt context i.e.
+ * retries.
+ */
+ if (!in_interrupt()) {
+ spin_lock_irqsave(&host->irq_lock, host->flags);
+ /*
+ * Protect the card from I/O if there is a possibility
+ * it can be removed.
+ */
+ if (host->protect_card) {
+ if (host->reqs_blocked < 3) {
+ /*
+ * Ensure the controller is left in a consistent
+ * state by resetting the command and data state
+ * machines.
+ */
+ omap_hsmmc_reset_controller_fsm(host, SRD);
+ omap_hsmmc_reset_controller_fsm(host, SRC);
+ host->reqs_blocked += 1;
+ }
+ req->cmd->error = -EBADF;
+ if (req->data)
+ req->data->error = -EBADF;
+ spin_unlock_irqrestore(&host->irq_lock, host->flags);
+ mmc_request_done(mmc, req);
+ return;
+ } else if (host->reqs_blocked)
+ host->reqs_blocked = 0;
+ }
WARN_ON(host->mrq != NULL);
host->mrq = req;
err = omap_hsmmc_prepare_data(host, req);
@@ -1514,6 +1496,8 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
if (req->data)
req->data->error = err;
host->mrq = NULL;
+ if (!in_interrupt())
+ spin_unlock_irqrestore(&host->irq_lock, host->flags);
mmc_request_done(mmc, req);
return;
}
@@ -2093,6 +2077,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
mmc->f_min = 400000;
mmc->f_max = 52000000;
+ sema_init(&host->sem, 1);
spin_lock_init(&host->irq_lock);
host->iclk = clk_get(&pdev->dev, "ick");
@@ -2235,7 +2220,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
pdata->resume = omap_hsmmc_resume_cdirq;
}
- omap_hsmmc_disable_irq(host);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
mmc_host_lazy_disable(host->mmc);
@@ -2356,7 +2342,10 @@ static int omap_hsmmc_suspend(struct device *dev)
ret = mmc_suspend_host(host->mmc);
mmc_host_enable(host->mmc);
if (ret == 0) {
- omap_hsmmc_disable_irq(host);
+ OMAP_HSMMC_WRITE(host->base, ISE, 0);
+ OMAP_HSMMC_WRITE(host->base, IE, 0);
+
+
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
mmc_host_disable(host->mmc);
--
1.6.6.1

View File

@@ -0,0 +1,52 @@
From 1d73698debdf57f9da6c3312239459c43278e064 Mon Sep 17 00:00:00 2001
From: David Vrabel <david.vrabel@csr.com>
Date: Fri, 2 Apr 2010 08:41:47 -0700
Subject: [PATCH 12/28] Don't turn SDIO cards off to save power. Doing so will lose all
internal state in the card.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
---
drivers/mmc/host/omap_hsmmc.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 15a023b..83f93ab 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -29,6 +29,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/core.h>
#include <linux/mmc/mmc.h>
+#include <linux/mmc/card.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/gpio.h>
@@ -1760,8 +1761,12 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host)
mmc_slot(host).card_detect ||
(mmc_slot(host).get_cover_state &&
mmc_slot(host).get_cover_state(host->dev, host->slot_id)))) {
- mmc_release_host(host->mmc);
- return 0;
+ goto out;
+ }
+
+ /* Don't turn SDIO cards off. */
+ if (host->mmc->card && mmc_card_sdio(host->mmc->card)) {
+ goto out;
}
mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
@@ -1772,9 +1777,8 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host)
host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP");
host->dpm_state = OFF;
-
+out:
mmc_release_host(host->mmc);
-
return 0;
}
--
1.6.6.1

View File

@@ -0,0 +1,288 @@
From bb4c074079c12d808367c8666cedcbba1dc456cc Mon Sep 17 00:00:00 2001
From: David Vrabel <david.vrabel@csr.com>
Date: Fri, 2 Apr 2010 08:42:22 -0700
Subject: [PATCH 13/28] Enable the use of SDIO card interrupts.
FCLK must be enabled while SDIO interrupts are enabled or the MMC
module won't wake-up (even though ENAWAKEUP in SYSCONFIG and IWE in
HTCL have been set). Enabling the MMC module to wake-up would require
configuring the MMC module (and the mmci_dat[1] GPIO when the CORE
power domain is OFF) as wake-up sources in the PRCM.
The writes to STAT and ISE when starting a command are unnecessary and
have been removed.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
---
drivers/mmc/host/omap_hsmmc.c | 118 +++++++++++++++++++++++++++++------------
1 files changed, 83 insertions(+), 35 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 83f93ab..d57686c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -67,6 +67,7 @@
#define SDVS_MASK 0x00000E00
#define SDVSCLR 0xFFFFF1FF
#define SDVSDET 0x00000400
+#define ENAWAKEUP (1 << 2)
#define AUTOIDLE 0x1
#define SDBP (1 << 8)
#define DTO 0xe
@@ -77,10 +78,13 @@
#define CLKD_SHIFT 6
#define DTO_MASK 0x000F0000
#define DTO_SHIFT 16
+#define CIRQ_ENABLE (1 << 8)
#define INT_EN_MASK 0x307F0033
#define BWR_ENABLE (1 << 4)
#define BRR_ENABLE (1 << 5)
#define DTO_ENABLE (1 << 20)
+#define CTPL (1 << 11)
+#define CLKEXTFREE (1 << 16)
#define INIT_STREAM (1 << 1)
#define DP_SELECT (1 << 21)
#define DDIR (1 << 4)
@@ -88,10 +92,12 @@
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define IWE (1 << 24)
#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
#define OD 0x1
+#define CIRQ (1 << 8)
#define ERR (1 << 15)
#define CMD_TIMEOUT (1 << 16)
#define DATA_TIMEOUT (1 << 20)
@@ -186,6 +192,7 @@ struct omap_hsmmc_host {
int protect_card;
int reqs_blocked;
int use_reg;
+ int sdio_int;
struct omap_mmc_platform_data *pdata;
};
@@ -598,7 +605,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
;
OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE | ENAWAKEUP);
if (host->id == OMAP_MMC1_DEVID) {
if (host->power_mode != MMC_POWER_OFF &&
@@ -613,7 +620,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
}
OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | hctl);
+ OMAP_HSMMC_READ(host->base, HCTL) | hctl | IWE);
OMAP_HSMMC_WRITE(host->base, CAPA,
OMAP_HSMMC_READ(host->base, CAPA) | capa);
@@ -627,7 +634,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
;
OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ);
OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
/* Do not initialize card-specific things if the power is off */
@@ -791,22 +798,19 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
struct mmc_data *data)
{
int cmdreg = 0, resptype = 0, cmdtype = 0;
+ int int_en_mask = INT_EN_MASK;
dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
host->cmd = cmd;
- /*
- * Clear status bits and enable interrupts
- */
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
-
if (host->use_dma)
- OMAP_HSMMC_WRITE(host->base, IE,
- INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE));
- else
- OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+ int_en_mask &= ~(BRR_ENABLE | BWR_ENABLE);
+
+ if (host->sdio_int)
+ int_en_mask |= CIRQ;
+
+ OMAP_HSMMC_WRITE(host->base, IE, int_en_mask);
host->response_busy = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
@@ -1019,23 +1023,26 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
{
struct omap_hsmmc_host *host = dev_id;
struct mmc_data *data;
- int end_cmd = 0, end_trans = 0, status;
+ u32 status;
+ int end_cmd = 0, end_trans = 0;
+ bool card_irq = false;
spin_lock(&host->irq_lock);
- if (host->mrq == NULL) {
- OMAP_HSMMC_WRITE(host->base, STAT,
- OMAP_HSMMC_READ(host->base, STAT));
- /* Flush posted write */
- OMAP_HSMMC_READ(host->base, STAT);
- spin_unlock(&host->irq_lock);
- return IRQ_HANDLED;
- }
-
- data = host->data;
status = OMAP_HSMMC_READ(host->base, STAT);
+ OMAP_HSMMC_WRITE(host->base, STAT, status);
+ OMAP_HSMMC_READ(host->base, STAT); /* Flush posted write. */
+
dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+ if (status & CIRQ)
+ card_irq = true;
+
+ if (host->mrq == NULL)
+ goto out;
+
+ data = host->data;
+
if (status & ERR) {
#ifdef CONFIG_MMC_DEBUG
omap_hsmmc_report_irq(host, status);
@@ -1085,17 +1092,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
}
}
- OMAP_HSMMC_WRITE(host->base, STAT, status);
- /* Flush posted write */
- OMAP_HSMMC_READ(host->base, STAT);
-
if (end_cmd || ((status & CC) && host->cmd))
omap_hsmmc_cmd_done(host, host->cmd);
if ((end_trans || (status & TC)) && host->mrq)
omap_hsmmc_xfer_done(host, data);
-
+out:
spin_unlock(&host->irq_lock);
+ if (card_irq)
+ mmc_signal_sdio_irq(host->mmc);
+
return IRQ_HANDLED;
}
@@ -1643,6 +1649,47 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
mmc_slot(host).init_card(card);
}
+static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct omap_hsmmc_host *host = mmc_priv(mmc);
+ u32 ie, con;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->irq_lock, flags);
+
+ /*
+ * When interrupts are enabled, CTPL must be set to enable
+ * DAT1 input buffer (or the card interrupt is always
+ * asserted) and FCLK must be enabled as wake-up does not
+ * work. Take care to disable FCLK after all the register
+ * accesses as they might not complete if FCLK is off.
+ *
+ * FIXME: if the MMC module (and the mmci_dat[1] GPIO when the
+ * CORE power domain is OFF) are configured as a wake-up
+ * sources in the PRCM, then FCLK could be switched off. This
+ * might add too much latency.
+ */
+ con = OMAP_HSMMC_READ(host->base, CON);
+ ie = OMAP_HSMMC_READ(host->base, IE);
+ if (enable) {
+ clk_enable(host->fclk);
+ ie |= CIRQ_ENABLE;
+ con |= CTPL | CLKEXTFREE;
+ host->sdio_int = 1;
+ } else {
+ ie &= ~CIRQ_ENABLE;
+ con &= ~(CTPL | CLKEXTFREE);
+ host->sdio_int = 0;
+ }
+ OMAP_HSMMC_WRITE(host->base, CON, con);
+ OMAP_HSMMC_WRITE(host->base, IE, ie);
+ OMAP_HSMMC_READ(host->base, IE); /* flush posted write */
+ if (!enable)
+ clk_disable(host->fclk);
+
+ spin_unlock_irqrestore(&host->irq_lock, flags);
+}
+
static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
{
u32 hctl, capa, value;
@@ -1657,14 +1704,14 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
}
value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
- OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+ OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl | IWE);
value = OMAP_HSMMC_READ(host->base, CAPA);
OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
/* Set the controller to AUTO IDLE mode */
value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE | ENAWAKEUP);
/* Set SD bus power bit */
set_sd_bus_power(host);
@@ -1918,7 +1965,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = {
.get_cd = omap_hsmmc_get_cd,
.get_ro = omap_hsmmc_get_ro,
.init_card = omap_hsmmc_init_card,
- /* NYET -- enable_sdio_irq */
+ .enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
};
static const struct mmc_host_ops omap_hsmmc_ps_ops = {
@@ -1929,7 +1976,7 @@ static const struct mmc_host_ops omap_hsmmc_ps_ops = {
.get_cd = omap_hsmmc_get_cd,
.get_ro = omap_hsmmc_get_ro,
.init_card = omap_hsmmc_init_card,
- /* NYET -- enable_sdio_irq */
+ .enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
};
#ifdef CONFIG_DEBUG_FS
@@ -2145,7 +2192,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
mmc->max_seg_size = mmc->max_req_size;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
- MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
+ MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE |
+ MMC_CAP_SDIO_IRQ;
mmc->caps |= mmc_slot(host).caps;
if (mmc->caps & MMC_CAP_8_BIT_DATA)
@@ -2224,7 +2272,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
pdata->resume = omap_hsmmc_resume_cdirq;
}
- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ);
OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
mmc_host_lazy_disable(host->mmc);
--
1.6.6.1

View File

@@ -0,0 +1,27 @@
From cee637c9d2b877dd40c5fc8c42dc70a21adb454b Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 12:45:20 -0800
Subject: [PATCH 14/28] soc: codecs: Enable audio capture by default for twl4030
---
sound/soc/codecs/twl4030.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 575238d..bd51f72 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -56,8 +56,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0x00, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
0x00, /* REG_MICBIAS_CTL (0x4) */
- 0x00, /* REG_ANAMICL (0x5) */
- 0x00, /* REG_ANAMICR (0x6) */
+ 0x34, /* REG_ANAMICL (0x5) */
+ 0x14, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
0x00, /* REG_ADCMICSEL (0x8) */
0x00, /* REG_DIGMIXING (0x9) */
--
1.6.6.1

View File

@@ -0,0 +1,25 @@
From 19fbeb71b9576ecdefa7809980aa3f0eecda408c Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Wed, 29 Dec 2010 11:39:16 -0800
Subject: [PATCH 15/28] soc: codecs: twl4030: Turn on mic bias by default
---
sound/soc/codecs/twl4030.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index bd51f72..8949773 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -55,7 +55,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0x00, /* REG_CODEC_MODE (0x1) */
0x00, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
- 0x00, /* REG_MICBIAS_CTL (0x4) */
+ 0x03, /* REG_MICBIAS_CTL (0x4) */
0x34, /* REG_ANAMICL (0x5) */
0x14, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
--
1.6.6.1

View File

@@ -0,0 +1,55 @@
From 1c679da3fc28bd358c79b6fae05de81c9b84a681 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 4 Feb 2010 12:26:22 -0800
Subject: [PATCH 16/28] RTC: add support for backup battery recharge
---
drivers/rtc/rtc-twl.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index f9a2799..713b8ea 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -30,6 +30,23 @@
#include <linux/i2c/twl.h>
+/*
+ * PM_RECEIVER block register offsets (use TWL4030_MODULE_PM_RECEIVER)
+ */
+#define REG_BB_CFG 0x12
+
+/* PM_RECEIVER BB_CFG bitfields */
+#define BIT_PM_RECEIVER_BB_CFG_BBCHEN 0x10
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL 0x0C
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_2V5 0x00
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V0 0x04
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 0x08
+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3v2 0x0c
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL 0x03
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA 0x00
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_150UA 0x01
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_500UA 0x02
+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_1MA 0x03
/*
* RTC block register offsets (use TWL_MODULE_RTC)
@@ -495,6 +512,14 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
if (ret < 0)
goto out2;
+ /* enable backup battery charging */
+ /* use a conservative 25uA @ 3.1V */
+ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ BIT_PM_RECEIVER_BB_CFG_BBCHEN |
+ BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 |
+ BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA,
+ REG_BB_CFG);
+
return ret;
out2:
--
1.6.6.1

View File

@@ -0,0 +1,39 @@
From 83b4a493176cbd50c8d2503440fecfa6e499f30e Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Sun, 24 Jan 2010 09:33:56 -0800
Subject: [PATCH 17/28] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test
otherwise it is not executed on systems that use non-twl regulators
---
arch/arm/mach-omap2/hsmmc.c | 14 ++++++--------
1 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b2f30be..84d5ef6 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -185,15 +185,13 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot,
if (mmc->slots[0].remux)
mmc->slots[0].remux(dev, slot, power_on);
- if (power_on) {
- /* Only MMC2 supports a CLKIN */
- if (mmc->slots[0].internal_clock) {
- u32 reg;
+ /* Only MMC2 supports a CLKIN */
+ if (mmc->slots[0].internal_clock) {
+ u32 reg;
- reg = omap_ctrl_readl(control_devconf1_offset);
- reg |= OMAP2_MMCSDIO2ADPCLKISEL;
- omap_ctrl_writel(reg, control_devconf1_offset);
- }
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
}
}
--
1.6.6.1

View File

@@ -0,0 +1,103 @@
From 890a8385d7f9bee69bf22616d16b225790b1d18c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20W=C3=B6rndl-Aichriedler?= <bwa@xdevelop.at>
Date: Sat, 15 May 2010 16:34:05 +0200
Subject: [PATCH 18/28] Add power-off support for the TWL4030 companion
This patch adds support for the power-off on shutdown feature of the TWL4030
---
drivers/mfd/Kconfig | 6 ++++++
drivers/mfd/twl-core.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3ed3ff0..fe2370a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -210,6 +210,12 @@ config TWL4030_CODEC
select MFD_CORE
default n
+config TWL4030_POWEROFF
+ bool "TWL4030 Allow power-off on shutdown"
+ depends on TWL4030_CORE
+ help
+ Enables the CPU to power-off the system on shutdown
+
config TWL6030_PWM
tristate "TWL6030 PWM (Pulse Width Modulator) Support"
depends on TWL4030_CORE
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 960b5be..8804550 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -122,6 +122,12 @@
#define twl_has_bci() false
#endif
+#if defined (CONFIG_TWL4030_POWEROFF)
+#define twl_has_poweroff() true
+#else
+#define twl_has_poweroff() false
+#endif
+
/* Triton Core internal information (BEGIN) */
/* Last - for index max*/
@@ -224,6 +230,10 @@
#define TWL5031 BIT(2) /* twl5031 has different registers */
#define TWL6030_CLASS BIT(3) /* TWL6030 class */
+/* for pm_power_off */
+#define PWR_P1_SW_EVENTS 0x10
+#define PWR_DEVOFF (1 << 0)
+
/*----------------------------------------------------------------------*/
/* is driver active, bound to a chip? */
@@ -1006,6 +1016,30 @@ static int twl_remove(struct i2c_client *client)
return 0;
}
+static void twl_poweroff(void)
+{
+ int err;
+ u8 val;
+
+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val,
+ PWR_P1_SW_EVENTS);
+ if (err) {
+ pr_err("%s: i2c error %d while reading TWL4030"
+ "PM_MASTER P1_SW_EVENTS\n",
+ DRIVER_NAME, err);
+ return;
+ }
+
+ val |= PWR_DEVOFF;
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val,
+ PWR_P1_SW_EVENTS);
+ if (err)
+ pr_err("%s: i2c error %d while writing TWL4030"
+ "PM_MASTER P1_SW_EVENTS\n",
+ DRIVER_NAME, err);
+}
+
/* NOTE: this driver only handles a single twl4030/tps659x0 chip */
static int __devinit
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -1093,6 +1127,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
}
+ if(twl_has_poweroff())
+ {
+ /* initialize pm_power_off routine */
+ pm_power_off = twl_poweroff;
+ }
+
status = add_children(pdata, id->driver_data);
fail:
if (status < 0)
--
1.6.6.1

View File

@@ -0,0 +1,33 @@
From 5b1ae684aa507a50630555d48c834a6f1fd2d1cf Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Thu, 17 Dec 2009 14:27:15 -0800
Subject: [PATCH 19/28] ARM: OMAP: Add twl4030 madc support to Overo
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
arch/arm/mach-omap2/board-overo.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 59ca333..86f76e9 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -637,10 +637,15 @@ static struct twl4030_codec_data overo_codec_data = {
.audio = &overo_audio_data,
};
+static struct twl4030_madc_platform_data overo_madc_data = {
+ .irq_line = 1,
+};
+
static struct twl4030_platform_data overo_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
.gpio = &overo_gpio_data,
+ .madc = &overo_madc_data,
.usb = &overo_usb_data,
.codec = &overo_codec_data,
.vmmc1 = &overo_vmmc1,
--
1.6.6.1

View File

@@ -0,0 +1,46 @@
From 79dc823c9ce624a2164a01b35a89452b22a7d174 Mon Sep 17 00:00:00 2001
From: Keerthy <j-keerthy@ti.com>
Date: Wed, 4 May 2011 01:14:50 +0530
Subject: [PATCH 20/28] Enabling Hwmon driver for twl4030-madc
Signed-off-by: Keerthy <j-keerthy@ti.com>
---
drivers/mfd/twl-core.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 8804550..d9435e4 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -83,6 +83,13 @@
#define twl_has_madc() false
#endif
+#if defined(CONFIG_SENSORS_TWL4030_MADC) ||\
+ defined(CONFIG_SENSORS_TWL4030_MADC_MODULE)
+#define twl_has_madc_hwmon() true
+#else
+#define twl_has_madc_hwmon() false
+#endif
+
#ifdef CONFIG_TWL4030_POWER
#define twl_has_power() true
#else
@@ -619,6 +626,14 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
return PTR_ERR(child);
}
+if (twl_has_madc_hwmon()) {
+ child = add_child(2, "twl4030_madc_hwmon",
+ NULL, 0,
+ true, pdata->irq_base + MADC_INTR_OFFSET, 0);
+ if (IS_ERR(child))
+ return PTR_ERR(child);
+ }
+
if (twl_has_rtc()) {
/*
* REVISIT platform_data here currently might expose the
--
1.6.6.1

View File

@@ -0,0 +1,54 @@
From 243d5534666eb795815f12d382cfcb77d5a43a8d Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Sat, 23 Jan 2010 06:26:54 -0800
Subject: [PATCH 21/28] mfd: twl-core: enable madc clock
Now that the madc driver has been merged it is also necessary to enable the clock to the madc block
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
drivers/mfd/twl-core.c | 8 ++++++++
include/linux/i2c/twl.h | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index d9435e4..9096d7d 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -222,6 +222,11 @@
/* Few power values */
#define R_CFG_BOOT 0x05
+#define R_GPBR1 0x0C
+
+/* MADC clock values for R_GPBR1 */
+#define MADC_HFCLK_EN 0x80
+#define DEFAULT_MADC_CLK_EN 0x10
/* some fields in R_CFG_BOOT */
#define HFCLK_FREQ_19p2_MHZ (1 << 0)
@@ -992,6 +997,9 @@ static void clocks_init(struct device *dev,
e |= unprotect_pm_master();
/* effect->MADC+USB ck en */
+ if (twl_has_madc())
+ e |= twl_i2c_write_u8(TWL_MODULE_INTBR,
+ MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, R_GPBR1);
e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
e |= protect_pm_master();
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 0c0d1ae..cbbf3b3 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -74,6 +74,7 @@
#define TWL_MODULE_USB TWL4030_MODULE_USB
#define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE
+#define TWL_MODULE_INTBR TWL4030_MODULE_INTBR
#define TWL_MODULE_PIH TWL4030_MODULE_PIH
#define TWL_MODULE_MADC TWL4030_MODULE_MADC
#define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE
--
1.6.6.1

View File

@@ -0,0 +1,49 @@
From df17c7eeca25cd9923828a4732a995e2c37d070b Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Wed, 24 Feb 2010 10:37:22 -0800
Subject: [PATCH 22/28] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options
---
arch/arm/mach-omap2/board-omap3beagle.c | 6 ++++++
arch/arm/mach-omap2/board-overo.c | 6 ++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 33007fd..2de4b02 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -604,7 +604,13 @@ static struct omap_board_mux board_mux[] __initdata = {
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
+#if defined(CONFIG_USB_MUSB_OTG)
.mode = MUSB_OTG,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#else
+ .mode = MUSB_HOST,
+#endif
.power = 100,
};
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 86f76e9..61c59fc 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -729,7 +729,13 @@ static struct omap_board_mux board_mux[] __initdata = {
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
+#if defined(CONFIG_USB_MUSB_OTG)
.mode = MUSB_OTG,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#else
+ .mode = MUSB_HOST,
+#endif
.power = 100,
};
--
1.6.6.1

View File

@@ -0,0 +1,28 @@
From c60f16ec7e69f59b3bef9f9b7041a973d144dc87 Mon Sep 17 00:00:00 2001
From: Steve Sakoman <steve@sakoman.com>
Date: Wed, 12 Jan 2011 05:54:55 -0800
Subject: [PATCH 23/28] omap: mmc: Adjust dto to eliminate timeout errors
A number of SD card types were experiencing timeout errors. This
could also lead to data corruption in some cases.
This fix proposed by Sukumar Ghoral of TI.
---
drivers/mmc/host/omap_hsmmc.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d57686c..7fb03e8 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1400,6 +1400,7 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd);
timeout = timeout_ns / cycle_ns;
timeout += timeout_clks;
+ timeout *= 2;
if (timeout) {
while ((timeout & 0x80000000) == 0) {
dto += 1;
--
1.6.6.1

View File

@@ -0,0 +1,95 @@
From 592fdd511dacc42bf97f249ca596ba28d0c25281 Mon Sep 17 00:00:00 2001
From: Charles Manning <cdhmanning@gmail.com>
Date: Tue, 18 Jan 2011 11:25:25 +1300
Subject: [PATCH 24/28] omap: Fix mtd subpage read alignment
This allows the omap2 prefetch engine to work properly for subpage
reads. Without this ECC errors will stop UBIFS from working.
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
---
drivers/mtd/nand/nand_base.c | 19 +++++++++++++++++++
drivers/mtd/nand/omap2.c | 1 +
include/linux/mtd/nand.h | 3 +++
3 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c54a4cb..6ca7098 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1157,6 +1157,22 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_align_subpage32 - function to align subpage read to 32-bits
+ * @mtd: mtd info structure
+ * @buf: pointer to offset that needs to be aligned
+ * @len: pointer to length that needs to be aligned.
+ */
+
+void nand_align_subpage32(int *offs, int *len)
+{
+ int diff = *offs & 3;
+
+ *offs = *offs - diff;
+ *len = (*len + diff + 3) & ~3;
+}
+EXPORT_SYMBOL(nand_align_subpage32);
+
+/**
* nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1221,6 +1237,9 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
aligned_len++;
+ if(chip->align_subpage)
+ chip->align_subpage(&aligned_pos, &aligned_len);
+
chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
mtd->writesize + aligned_pos, -1);
chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index da9a351..bb89c65 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1069,6 +1069,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
info->nand.ecc.correct = omap_correct_data;
info->nand.ecc.mode = NAND_ECC_HW;
}
+ info->nand.align_subpage = nand_align_subpage32;
/* DIP switches on some boards change between 8 and 16 bit
* bus widths for flash. Try the other width if the first try fails.
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d441927..311f211 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -479,6 +479,7 @@ struct nand_buffers {
* additional error status checks (determine if errors are
* correctable).
* @write_page: [REPLACEABLE] High-level page write function
+ * @align_subpage: [OPTIONAL] Aligns subpage read buffer.
*/
struct nand_chip {
@@ -507,6 +508,7 @@ struct nand_chip {
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int page, int cached, int raw);
+ void (*align_subpage)(int *offs, int *len);
int chip_delay;
unsigned int options;
@@ -602,6 +604,7 @@ extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt);
extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
+extern void nand_align_subpage32(int *offs, int *len);
/**
* struct platform_nand_chip - chip level device structure
--
1.6.6.1

View File

@@ -0,0 +1,35 @@
From 2611e93b57147877fabb181bd86c78fd425a5467 Mon Sep 17 00:00:00 2001
From: Charles Manning <manningc2@actrix.gen.nz>
Date: Thu, 16 Dec 2010 20:35:56 -0800
Subject: [PATCH 25/28] mtd: nand: omap2: Force all buffer reads to u32 alignment
---
drivers/mtd/nand/omap2.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index bb89c65..832f111 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -247,6 +247,18 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
int ret = 0;
u32 *p = (u32 *)buf;
+ /* u32 align the buffer and read */
+ /* NB: This assumes the buf ptr can be aligned *down* which is a valid.
+ * Assumption when dealing with ecc buffers etc.
+ */
+ u32 addr = (u32)p;
+
+ int diff = addr & 3;
+ addr -= diff;
+ len += diff;
+ len = (len + 3) & ~3;
+ p = (u32 *)addr;
+
/* take care of subpage reads */
if (len % 4) {
if (info->nand.options & NAND_BUSWIDTH_16)
--
1.6.6.1

View File

@@ -0,0 +1,63 @@
From 1f0278a4f5475cc9ad67e007763368dfdd7dee29 Mon Sep 17 00:00:00 2001
From: kishore kadiyala <kishore.kadiyala@ti.com>
Date: Mon, 2 May 2011 11:10:38 +0000
Subject: [PATCH 26/28] omap : nand : fix subpage ecc issue with prefetch
For prefetch engine, read and write got broken in commit '2c01946c'.
We never hit a scenario of not getting 'gpmc_prefetch_enable'
call success.
When reading/writing a subpage with a non divisible by 4 ecc number
of bytes, the mis-aligned bytes gets handled first before enabling
the Prefetch engine, then it reads/writes rest of the bytes.
Signed-off-by: Kishore Kadiyala <kishore.kadiyala@ti.com>
Signed-off-by: Vimal Singh <vimal.newwork@gmail.com>
Reported-by: Bryan DE FARIA <bdefaria@adeneo-embedded.com>
---
drivers/mtd/nand/omap2.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 832f111..471a39b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -275,11 +275,10 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
if (ret) {
/* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16)
- omap_read_buf16(mtd, buf, len);
+ omap_read_buf16(mtd, (u_char *)p, len);
else
- omap_read_buf8(mtd, buf, len);
+ omap_read_buf8(mtd, (u_char *)p, len);
} else {
- p = (u32 *) buf;
do {
r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
r_count = r_count >> 2;
@@ -305,7 +304,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
struct omap_nand_info, mtd);
uint32_t w_count = 0;
int i = 0, ret = 0;
- u16 *p;
+ u16 *p = (u16 *)buf;
unsigned long tim, limit;
/* take care of subpage writes */
@@ -321,11 +320,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
if (ret) {
/* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16)
- omap_write_buf16(mtd, buf, len);
+ omap_write_buf16(mtd, (u_char *)p, len);
else
- omap_write_buf8(mtd, buf, len);
+ omap_write_buf8(mtd, (u_char *)p, len);
} else {
- p = (u16 *) buf;
while (len) {
w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
w_count = w_count >> 1;
--
1.6.6.1

View File

@@ -0,0 +1,46 @@
From 61e1cb7dbff3b611644d6ba811f8b83db148c1e1 Mon Sep 17 00:00:00 2001
From: Scott Ellis <scottellis.developer@gmail.com>
Date: Sun, 23 Jan 2011 20:39:35 -0800
Subject: [PATCH 27/28] OMAP: Overo: Add support for spidev
---
arch/arm/mach-omap2/board-overo.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 61c59fc..05dd3eb 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -683,6 +683,14 @@ static struct spi_board_info overo_spi_board_info[] __initdata = {
.irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
.platform_data = &ads7846_config,
},
+#elif defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ {
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 48000000,
+ .mode = SPI_MODE_0,
+ },
#endif
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
@@ -693,6 +701,14 @@ static struct spi_board_info overo_spi_board_info[] __initdata = {
.max_speed_hz = 500000,
.mode = SPI_MODE_3,
},
+#elif defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ {
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 48000000,
+ .mode = SPI_MODE_0,
+ },
#endif
};
--
1.6.6.1

View File

@@ -0,0 +1,54 @@
require multi-kernel.inc
DESCRIPTION = "Linux kernel for OMAP processors"
KERNEL_IMAGETYPE = "uImage"
COMPATIBLE_MACHINE = "(beagleboard)"
# The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc
SRCREV_pn-${PN} = "v2.6.39"
FILESPATHPKG_prepend = "linux-omap-2.6.39:"
SRC_URI += "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \
file://defconfig"
SRC_URI_append = " \
file://sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch \
file://sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch \
file://sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch \
file://sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch \
file://sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch \
file://sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch \
file://sakoman/0007-video-add-timings-for-hd720.patch \
file://sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch \
file://sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch \
file://sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch \
file://sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch \
file://sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch \
file://sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch \
file://sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch \
file://sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch \
file://sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch \
file://sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch \
file://sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch \
file://sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch \
file://sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch \
file://sakoman/0021-mfd-twl-core-enable-madc-clock.patch \
file://sakoman/0022-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch \
file://sakoman/0023-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch \
file://sakoman/0024-omap-Fix-mtd-subpage-read-alignment.patch \
file://sakoman/0025-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch \
file://sakoman/0026-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch \
file://sakoman/0027-OMAP-Overo-Add-support-for-spidev.patch \
file://sakoman/0028-unionfs-Add-support-for-unionfs-2.5.9.patch \
\
file://beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch \
file://beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch \
"
SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \
"
S = "${WORKDIR}/git"