linux-omap2-git: Sync with OE.dev, add fixes to compile correctly with gcc 4.3.1

git-svn-id: https://svn.o-hand.com/repos/poky/trunk@5009 311d38ba-8fff-0310-9ca6-ca027cbcb966
This commit is contained in:
Richard Purdie 2008-08-03 11:21:36 +00:00
parent 6dda6e3c3e
commit 5e4da78218
29 changed files with 2747 additions and 152 deletions

View File

@ -0,0 +1,23 @@
From: Mans Rullgard <mans@mansr.com>
Date: Sat, 5 Jul 2008 20:31:56 +0000 (+0100)
Subject: omapfb: fix video timings message
X-Git-Tag: beagle-5~3
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2929b75035ebe8702ba2ff2c81b654c487701f64
omapfb: fix video timings message
---
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 418ed9f..1166a01 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -1789,7 +1789,8 @@ static int omapfb_do_probe(struct platform_device *pdev,
vram, fbdev->mem_desc.region_cnt);
pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz "
"vfreq %lu.%lu Hz\n",
- phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10);
+ phz / 1000, hhz / 10000, hhz % 10000,
+ vhz / 10, vhz % 10);
return 0;

View File

@ -0,0 +1,22 @@
From: Mans Rullgard <mans@mansr.com>
Date: Sat, 5 Jul 2008 20:32:38 +0000 (+0100)
Subject: omap: set CLKSEL_DSS1 to 2
X-Git-Tag: beagle-5~2
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=d23f9c3c5c6243b626f7ec4c255469de2536e488
omap: set CLKSEL_DSS1 to 2
---
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 8fdf8f3..04dedec 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -596,6 +596,8 @@ int __init omap2_clk_init(void)
/* u32 clkrate; */
u32 cpu_clkflg;
+ __raw_writel(0x1002, io_p2v(0x48004e40));
+
/* REVISIT: Ultimately this will be used for multiboot */
#if 0
if (cpu_is_omap242x()) {

View File

@ -0,0 +1,27 @@
From: Mans Rullgard <mans@mansr.com>
Date: Sun, 6 Jul 2008 13:15:36 +0000 (+0100)
Subject: omapfb: enable overlay optimisation when possible
X-Git-Tag: beagle-5~1
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=a63ac3abdf6781f863112321260fe7a5da757802
omapfb: enable overlay optimisation when possible
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 6aff476..3b36227 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -582,11 +582,13 @@ static int omap_dispc_enable_plane(int plane, int enable)
const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
+ unsigned overlay_opt = plane & !!enable & !dispc.color_key.key_type;
if ((unsigned int)plane > dispc.mem_desc.region_cnt)
return -EINVAL;
enable_lcd_clocks(1);
MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
+ MOD_REG_FLD(DISPC_CONTROL, 1<<12 | 1<<5, overlay_opt<<12 | 1<<5);
enable_lcd_clocks(0);
return 0;

View File

@ -0,0 +1,28 @@
From: Mans Rullgard <mans@mansr.com>
Date: Sun, 6 Jul 2008 13:22:54 +0000 (+0100)
Subject: omapfb: use PCD if set in panel config
X-Git-Tag: beagle-5
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=c8060d36ae156771f00a7a27cabf1b4435c378bd
omapfb: use PCD if set in panel config
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 3b36227..4e1a8e3 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -798,7 +798,13 @@ static void set_lcd_timings(void)
l |= panel->acb & 0xff;
dispc_write_reg(DISPC_POL_FREQ, l);
- calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
+ if (panel->pcd) {
+ pck_div = panel->pcd;
+ lck_div = 1;
+ } else {
+ calc_ck_div(is_tft, panel->pixel_clock * 1000,
+ &lck_div, &pck_div);
+ }
l = dispc_read_reg(DISPC_DIVISOR);
l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));

View File

@ -0,0 +1,45 @@
From: Mans Rullgard <mans@mansr.com>
Date: Mon, 7 Jul 2008 00:13:00 +0000 (+0100)
Subject: omapfb: fix display panning
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=9fec252c96b0e69bcef0afd9cb9dd72b7179c239
omapfb: fix display panning
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 4e1a8e3..c17371c 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -435,6 +435,8 @@ static inline int _setup_plane(int plane, int channel_out,
dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
+ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5);
+
return height * screen_width * bpp / 8;
}
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 1166a01..3e4959e 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -206,8 +206,8 @@ static int ctrl_change_mode(struct fb_info *fbi)
struct omapfb_device *fbdev = plane->fbdev;
struct fb_var_screeninfo *var = &fbi->var;
- offset = var->yoffset * fbi->fix.line_length +
- var->xoffset * var->bits_per_pixel / 8;
+ offset = (var->yoffset * var->xres_virtual + var->xoffset) *
+ var->bits_per_pixel / 8;
if (fbdev->ctrl->sync)
fbdev->ctrl->sync();
@@ -423,6 +423,8 @@ static void set_fb_fix(struct fb_info *fbi)
}
fix->accel = FB_ACCEL_OMAP1610;
fix->line_length = var->xres_virtual * bpp / 8;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
}
static int set_color_mode(struct omapfb_plane_struct *plane,

View File

@ -0,0 +1,31 @@
From: Mans Rullgard <mans@mansr.com>
Date: Mon, 7 Jul 2008 23:59:08 +0000 (+0100)
Subject: omapfb: ensure fck/lcd < 173MHz
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=0523ece1bad659c48c66aea364d83f7490e7e5ae
omapfb: ensure fck/lcd < 173MHz
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index c17371c..85d6cad 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -738,14 +738,16 @@ static void setup_color_conv_coef(void)
MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
}
+#define MAX_FCK_LCD 173000000
+
static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
{
unsigned long fck, lck;
- *lck_div = 1;
pck = max(1, pck);
fck = clk_get_rate(dispc.dss1_fck);
- lck = fck;
+ *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
+ lck = fck / *lck_div;
*pck_div = (lck + pck - 1) / pck;
if (is_tft)
*pck_div = max(2, *pck_div);

View File

@ -0,0 +1,21 @@
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 8 Jul 2008 18:26:43 +0000 (+0100)
Subject: omapfb: set graphics burst size to 16x32
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=4f9e415dfcd5613a8de973f6c9878cab959c5869
omapfb: set graphics burst size to 16x32
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 85d6cad..fd06ca2 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -409,7 +409,7 @@ static inline int _setup_plane(int plane, int channel_out,
l |= cconv_en << 9;
l &= ~(0x03 << burst_shift);
- l |= DISPC_BURST_8x32 << burst_shift;
+ l |= DISPC_BURST_16x32 << burst_shift;
l &= ~(1 << chout_shift);
l |= chout_val << chout_shift;

View File

@ -1,13 +1,137 @@
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index bdeb8fb..bf256f3 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -7,6 +7,27 @@ config FB_OMAP
help
Frame buffer driver for OMAP based boards.
+choice
+ depends on FB_OMAP && MACH_OMAP3_BEAGLE
+ prompt "Screen resolution"
+ default FB_OMAP_079M3R
+ help
+ Selected desired screen resolution
+
+config FB_OMAP_031M3R
+ boolean "640 x 480 @ 60 Hz Reduced blanking"
+
+config FB_OMAP_048M3R
+ boolean "800 x 600 @ 60 Hz Reduced blanking"
+
+config FB_OMAP_079M3R
+ boolean "1024 x 768 @ 60 Hz Reduced blanking"
+
+config FB_OMAP_092M9R
+ boolean "1280 x 720 @ 60 Hz Reduced blanking"
+
+endchoice
+
config FB_OMAP_LCDC_EXTERNAL
bool "External LCD controller support"
depends on FB_OMAP
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
index 69d4e06..c1c4f4c 100644
index 69d4e06..5e098c2 100644
--- a/drivers/video/omap/lcd_omap3beagle.c
+++ b/drivers/video/omap/lcd_omap3beagle.c
@@ -66,7 +66,7 @@ struct lcd_panel omap3beagle_panel = {
@@ -31,10 +31,6 @@
#define LCD_PANEL_ENABLE_GPIO 170
-#define LCD_XRES 1024
-#define LCD_YRES 768
-#define LCD_PIXCLOCK 64000 /* in kHz */
-
static int omap3beagle_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
@@ -65,19 +61,76 @@ static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
struct lcd_panel omap3beagle_panel = {
.name = "omap3beagle",
.config = OMAP_LCDC_PANEL_TFT,
-
- .bpp = 24,
+ .bpp = 16,
.data_lines = 24,
.x_res = LCD_XRES,
.y_res = LCD_YRES,
- .x_res = LCD_XRES,
- .y_res = LCD_YRES,
- .hsw = 3, /* hsync_len (4) - 1 */
- .hfp = 3, /* right_margin (4) - 1 */
- .hbp = 39, /* left_margin (40) - 1 */
- .vsw = 1, /* vsync_len (2) - 1 */
- .vfp = 2, /* lower_margin */
- .vbp = 7, /* upper_margin (8) - 1 */
-
- .pixel_clock = LCD_PIXCLOCK,
+
+#if defined CONFIG_FB_OMAP_031M3R
+
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
+ .x_res = 640,
+ .y_res = 480,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 7,
+ .pixel_clock = 23500,
+
+#elif defined CONFIG_FB_OMAP_048M3R
+
+ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
+ .x_res = 800,
+ .y_res = 600,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 11,
+ .pixel_clock = 35500,
+
+#elif defined CONFIG_FB_OMAP_079M3R
+
+ /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .x_res = 1024,
+ .y_res = 768,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 15,
+ .pixel_clock = 56000,
+
+#elif defined CONFIG_FB_OMAP_092M9R
+
+ /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
+ .x_res = 1280,
+ .y_res = 720,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 5,
+ .vbp = 13,
+ .pixel_clock = 64000,
+
+#else
+
+ /* use 640 x 480 if no config option */
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
+ .x_res = 640,
+ .y_res = 480,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 7,
+ .pixel_clock = 23500,
+
+#endif
.init = omap3beagle_panel_init,
.cleanup = omap3beagle_panel_cleanup,

View File

@ -0,0 +1,22 @@
From: Steve Sakoman <steve@sakoman.com>
Date: Wed, 16 Jul 2008 19:38:43 +0000 (-0700)
Subject: omap3beagle: set data rate on i2c-1 to 400, since 2600 seems to be
X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=12d6504334a830774ff1d42cee4b7296ac9fb7d2
omap3beagle: set data rate on i2c-1 to 400, since 2600 seems to be
flakey
---
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index fdce787..938ad73 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -39,7 +39,7 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = {
static int __init omap3_beagle_i2c_init(void)
{
- omap_register_i2c_bus(1, 2600, NULL, 0);
+ omap_register_i2c_bus(1, 400, NULL, 0);
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, NULL, 0);
return 0;

View File

@ -0,0 +1,38 @@
From: Purushotam Kumar <purushotam@ti.com>
Date: Fri, 18 Jul 2008 23:28:57 +0000 (-0700)
Subject: OMAP3:devices.c:Enabling 4-bit for SD card
X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=6c4d34031c80ca4b50ffe73a4ef7fe197a760a60
OMAP3:devices.c:Enabling 4-bit for SD card
SD card was working in 1-bit mode.This patch will configure SD card in
4-bit mode and hence performance will increase.
Signed-off-by: Purushotam Kumar <purushotam@ti.com>
Acked-by: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
---
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index b83f9a6..d0cfceb 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -296,13 +296,17 @@ static void __init omap_init_mmc(void)
mmc = &mmc_conf->mmc[0];
if (cpu_is_omap2430() || cpu_is_omap34xx()) {
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc1_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device1);
+ }
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
mmc = &mmc_conf->mmc[1];
- if (mmc->enabled)
+ if (mmc->enabled) {
+ mmc2_data.conf = *mmc;
(void) platform_device_register(&mmc_omap_device2);
+ }
#endif
return;

View File

@ -0,0 +1,43 @@
TWL4030: remove superfluous PWR interrupt status clear before masking
From: Paul Walmsley <paul@pwsan.com>
twl_irq_init() clears PWR interrupt status bits, then masks the interrupts
off, then clears the PWR interrupt status bits again. The first clear
seems unnecessary, so, remove it.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 18 ------------------
1 files changed, 0 insertions(+), 18 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index adc45d4..ff662bc 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -719,24 +719,6 @@ static void twl_init_irq(void)
char *msg = "Unable to register interrupt subsystem";
unsigned int irq_num;
- /*
- * We end up with interrupts from other modules before
- * they get a chance to handle them...
- */
- /* PWR_ISR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
-
- /* PWR_ISR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
-
/* PWR_IMR1 */
res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
if (res < 0) {

View File

@ -0,0 +1,71 @@
TWL4030: clear TWL GPIO interrupt status registers
From: Paul Walmsley <paul@pwsan.com>
twl_init_irq() does not clear the TWL GPIO ISR registers, but the PIH
ISR thinks that it has. This causes any previously-latched GPIO interrupts
to be stuck on until twl4030-gpio.c initializes, often drowning the console in
TWL4030 module irq 368 is disabled but can't be masked!
messages. This seems to be a particular problem when booting on Beagle.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 42 ++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index ff662bc..dfc3805 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -857,6 +857,48 @@ static void twl_init_irq(void)
return;
}
+ /* GPIO_ISR1A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* GPIO_ISR2A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* GPIO_ISR3A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* GPIO_ISR1B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* GPIO_ISR2B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* GPIO_ISR3B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
/* install an irq handler for each of the PIH modules */
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {
set_irq_chip(i, &twl4030_irq_chip);

View File

@ -0,0 +1,82 @@
TWL4030: use correct register addresses for BCI IMR registers
From: Paul Walmsley <paul@pwsan.com>
The existing code to mask and clear BCI interrupts in twl_init_irq() is
wrong. It uses the wrong register offsets, it does not mask all of the
BCI IMR registers, and it does not clear all of the BCI ISR registers.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 40 ++++++++++++++++++++++++++++++++------
1 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index dfc3805..bb0732c 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -750,29 +750,57 @@ static void twl_init_irq(void)
/* POWER HACK (END) */
/* Slave address 0x4A */
- /* BCIIMR1_1 */
+ /* BCIIMR1A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x2);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* BCIIMR2A */
res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x3);
if (res < 0) {
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
return;
}
- /* BCIIMR1_2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
+ /* BCIIMR1B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x6);
if (res < 0) {
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
return;
}
- /* BCIIMR2_1 */
+ /* BCIIMR2B */
res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x7);
if (res < 0) {
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
return;
}
- /* BCIIMR2_2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x8);
+ /* BCIISR1A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* BCIISR2A */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* BCIISR1B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* BCIISR2B */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
if (res < 0) {
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
return;

View File

@ -0,0 +1,38 @@
TWL4030: clear MADC interrupt status registers upon init
From: Paul Walmsley <paul@pwsan.com>
twl_init_irq() does not clear MADC interrupt status registers upon init -
fix.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index bb0732c..9d93524 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -821,6 +821,20 @@ static void twl_init_irq(void)
return;
}
+ /* MADC_ISR1 */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
+ /* MADC_ISR2 */
+ res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
+ if (res < 0) {
+ pr_err("%s[%d][%d]\n", msg, res, __LINE__);
+ return;
+ }
+
/* key Pad */
/* KEYPAD - IMR1 */
res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x12));

View File

@ -0,0 +1,303 @@
TWL4030: use *_SIH_CTRL.COR bit to determine whether to read or write ISR to clear
From: Paul Walmsley <paul@pwsan.com>
TWL4030 interrupt status register bits can be cleared in one of two ways:
either by reading from the register, or by writing a 1 to the
appropriate bit(s) in the register. This behavior can be altered at any
time by the <twlmodule>_SIH_CTRL.COR register bit ("clear-on-read").
The TWL4030 TRM is deeply confused as to whether COR=1 means that the
registers are cleared on reads, or cleared on writes. Peter De
Schrijver <peter.de-schrijver> confirms that COR=1 means that the registers
are cleared on read.
So, for each TWL4030 SIH, check the value of the *_SIH_CTRL.COR bit, and if
it is 1, use reads to clear the ISRs; if it is 0, use writes.
Also, use WARN_ON() to warn if the read/write failed, and don't skip
the rest of the initialization on failure either.
Thanks to Peter for his help with this patch.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 183 ++++++++++++++++++++++----------------
1 files changed, 106 insertions(+), 77 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index 9d93524..eae0634 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -133,6 +133,16 @@
/* on I2C-1 for 2430SDP */
#define CONFIG_I2C_TWL4030_ID 1
+/* SIH_CTRL registers */
+#define TWL4030_INT_PWR_SIH_CTRL 0x07
+#define TWL4030_INTERRUPTS_BCISIHCTRL 0x0d
+#define TWL4030_MADC_MADC_SIH_CTRL 0x67
+#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
+#define TWL4030_GPIO_GPIO_SIH_CTRL 0x2d
+
+#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
+
+
/* Helper functions */
static int
twl4030_detect_client(struct i2c_adapter *adapter, unsigned char sid);
@@ -712,13 +722,61 @@ static int power_companion_init(void)
return e;
}
+/**
+ * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
+ * @mod_no: TWL4030 module number
+ * @reg: register index to clear
+ * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0)
+ *
+ * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt
+ * status register to ensure that any prior interrupts are cleared.
+ * Returns the status from the I2C read operation.
+ */
+static int twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor)
+{
+ u8 tmp;
+
+ return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) :
+ twl4030_i2c_write_u8(mod_no, 0xff, reg);
+}
+
+/**
+ * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes?
+ * @mod_no: TWL4030 module number
+ * @reg: register index to clear
+ *
+ * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for
+ * the specified TWL module are cleared by reads, or 0 if cleared by
+ * writes.
+ */
+static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
+{
+ u8 tmp = 0;
+
+ WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0);
+
+ tmp &= TWL4030_SIH_CTRL_COR_MASK;
+ tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK);
+
+ return tmp;
+}
+
static void twl_init_irq(void)
{
int i = 0;
int res = 0;
+ int cor;
char *msg = "Unable to register interrupt subsystem";
unsigned int irq_num;
+ /*
+ * For each TWL4030 module with ISR/IMR registers, mask all
+ * interrupts and then clear any existing interrupt status bits,
+ * since we initially do not have any TWL4030 module interrupt
+ * handlers present.
+ */
+
+
/* PWR_IMR1 */
res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
if (res < 0) {
@@ -734,20 +792,18 @@ static void twl_init_irq(void)
}
/* Clear off any other pending interrupts on power */
+
+ /* Are PWR interrupt status bits cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
+ TWL4030_INT_PWR_SIH_CTRL);
+ WARN_ON(cor < 0);
+
/* PWR_ISR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x00);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00, cor) < 0);
/* PWR_ISR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x02);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
- /* POWER HACK (END) */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02, cor) < 0);
+
/* Slave address 0x4A */
/* BCIIMR1A */
@@ -778,33 +834,22 @@ static void twl_init_irq(void)
return;
}
+ /* Are BCI interrupt status bits cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
+ TWL4030_INTERRUPTS_BCISIHCTRL);
+ WARN_ON(cor < 0);
+
/* BCIISR1A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x0);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0, cor) < 0);
/* BCIISR2A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x1);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1, cor) < 0);
/* BCIISR1B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x4);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4, cor) < 0);
/* BCIISR2B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x5);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5, cor) < 0);
/* MAD C */
/* MADC_IMR1 */
@@ -821,19 +866,16 @@ static void twl_init_irq(void)
return;
}
+ /* Are MADC interrupt status bits cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
+ TWL4030_MADC_MADC_SIH_CTRL);
+ WARN_ON(cor < 0);
+
/* MADC_ISR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x61);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61, cor) < 0);
/* MADC_ISR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x63);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63, cor) < 0);
/* key Pad */
/* KEYPAD - IMR1 */
@@ -842,12 +884,15 @@ static void twl_init_irq(void)
pr_err("%s[%d][%d]\n", msg, res, __LINE__);
return;
}
- {
- u8 clear;
- /* Clear ISR */
- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
- twl4030_i2c_read_u8(TWL4030_MODULE_KEYPAD, &clear, 0x11);
- }
+
+ /* Are keypad interrupt status bits cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
+ TWL4030_KEYPAD_KEYP_SIH_CTRL);
+ WARN_ON(cor < 0);
+
+ /* KEYPAD - ISR1 */
+ /* XXX does this still need to be done twice for some reason? */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
/* KEYPAD - IMR2 */
res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
@@ -856,6 +901,9 @@ static void twl_init_irq(void)
return;
}
+ /* KEYPAD - ISR2 */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
+
/* Slave address 0x49 */
/* GPIO_IMR1A */
res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
@@ -899,47 +947,28 @@ static void twl_init_irq(void)
return;
}
+ /* Are GPIO interrupt status bits cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
+ TWL4030_GPIO_GPIO_SIH_CTRL);
+ WARN_ON(cor < 0);
+
/* GPIO_ISR1A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x19);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19, cor) < 0);
/* GPIO_ISR2A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1a);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a, cor) < 0);
/* GPIO_ISR3A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1b);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b, cor) < 0);
/* GPIO_ISR1B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1f);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f, cor) < 0);
/* GPIO_ISR2B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x20);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20, cor) < 0);
/* GPIO_ISR3B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x21);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21, cor) < 0);
/* install an irq handler for each of the PIH modules */
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {

View File

@ -0,0 +1,179 @@
TWL4030: change init-time IMR mask code to WARN if error
From: Paul Walmsley <paul@pwsan.com>
twl_init_irq() prints error messages and returns if any interrupt mask
register writes fail. Change this to generate a warning traceback and
to continue execution rather than skipping TWL init. (These mask
writes should not fail at all unless either the I2C bus or the TWL4030
is somehow wedged.)
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 100 +++++++-------------------------------
1 files changed, 18 insertions(+), 82 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index eae0634..99cc143 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -778,18 +778,10 @@ static void twl_init_irq(void)
/* PWR_IMR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x1);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x1) < 0);
/* PWR_IMR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xFF, 0x3);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x3) < 0);
/* Clear off any other pending interrupts on power */
@@ -807,32 +799,16 @@ static void twl_init_irq(void)
/* Slave address 0x4A */
/* BCIIMR1A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x2);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x2) < 0);
- /* BCIIMR2A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x3);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ /* BCIIMR2A */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x3) < 0);
- /* BCIIMR1B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x6);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ /* BCIIMR2A */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x6) < 0);
/* BCIIMR2B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xFF, 0x7);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x7) < 0);
/* Are BCI interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
@@ -853,18 +829,10 @@ static void twl_init_irq(void)
/* MAD C */
/* MADC_IMR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x62);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x62) < 0);
/* MADC_IMR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xFF, 0x64);
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x64) < 0);
/* Are MADC interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
@@ -879,11 +847,7 @@ static void twl_init_irq(void)
/* key Pad */
/* KEYPAD - IMR1 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x12));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x12) < 0);
/* Are keypad interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
@@ -895,57 +859,29 @@ static void twl_init_irq(void)
WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
/* KEYPAD - IMR2 */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xFF, (0x14));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x14) < 0);
/* KEYPAD - ISR2 */
WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
/* Slave address 0x49 */
/* GPIO_IMR1A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1C));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1c) < 0);
/* GPIO_IMR2A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1D));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1d) < 0);
/* GPIO_IMR3A */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x1E));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1e) < 0);
/* GPIO_IMR1B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x22));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x22) < 0);
/* GPIO_IMR2B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x23));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x23) < 0);
/* GPIO_IMR3B */
- res = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xFF, (0x24));
- if (res < 0) {
- pr_err("%s[%d][%d]\n", msg, res, __LINE__);
- return;
- }
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x24) < 0);
/* Are GPIO interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,

View File

@ -0,0 +1,274 @@
TWL4030: move TWL module register defs into separate include files
From: Paul Walmsley <paul@pwsan.com>
twl_init_irq() uses "magic numbers" to access TWL module IMR and ISR
registers. Symbolic constants are definitely preferred.
Rather than duplicating already existing symbolic constants in
twl4030-gpio.c and twl4030-pwrirq.c, move the existing constants out
into include files. This patch should not change kernel behavior.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-gpio.c | 48 -----------------------
drivers/i2c/chips/twl4030-pwrirq.c | 15 +++----
include/linux/i2c/twl4030-gpio.h | 76 ++++++++++++++++++++++++++++++++++++
include/linux/i2c/twl4030-pwrirq.h | 37 ++++++++++++++++++
4 files changed, 121 insertions(+), 55 deletions(-)
create mode 100644 include/linux/i2c/twl4030-gpio.h
create mode 100644 include/linux/i2c/twl4030-pwrirq.h
diff --git a/drivers/i2c/chips/twl4030-gpio.c b/drivers/i2c/chips/twl4030-gpio.c
index f16a48b..9d17f45 100644
--- a/drivers/i2c/chips/twl4030-gpio.c
+++ b/drivers/i2c/chips/twl4030-gpio.c
@@ -38,6 +38,7 @@
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl4030-gpio.h>
#include <linux/slab.h>
#include <asm/arch/irqs.h>
@@ -47,53 +48,6 @@
#include <linux/device.h>
-/*
- * GPIO Block Register definitions
- */
-
-#define REG_GPIODATAIN1 0x0
-#define REG_GPIODATAIN2 0x1
-#define REG_GPIODATAIN3 0x2
-#define REG_GPIODATADIR1 0x3
-#define REG_GPIODATADIR2 0x4
-#define REG_GPIODATADIR3 0x5
-#define REG_GPIODATAOUT1 0x6
-#define REG_GPIODATAOUT2 0x7
-#define REG_GPIODATAOUT3 0x8
-#define REG_CLEARGPIODATAOUT1 0x9
-#define REG_CLEARGPIODATAOUT2 0xA
-#define REG_CLEARGPIODATAOUT3 0xB
-#define REG_SETGPIODATAOUT1 0xC
-#define REG_SETGPIODATAOUT2 0xD
-#define REG_SETGPIODATAOUT3 0xE
-#define REG_GPIO_DEBEN1 0xF
-#define REG_GPIO_DEBEN2 0x10
-#define REG_GPIO_DEBEN3 0x11
-#define REG_GPIO_CTRL 0x12
-#define REG_GPIOPUPDCTR1 0x13
-#define REG_GPIOPUPDCTR2 0x14
-#define REG_GPIOPUPDCTR3 0x15
-#define REG_GPIOPUPDCTR4 0x16
-#define REG_GPIOPUPDCTR5 0x17
-#define REG_GPIO_ISR1A 0x19
-#define REG_GPIO_ISR2A 0x1A
-#define REG_GPIO_ISR3A 0x1B
-#define REG_GPIO_IMR1A 0x1C
-#define REG_GPIO_IMR2A 0x1D
-#define REG_GPIO_IMR3A 0x1E
-#define REG_GPIO_ISR1B 0x1F
-#define REG_GPIO_ISR2B 0x20
-#define REG_GPIO_ISR3B 0x21
-#define REG_GPIO_IMR1B 0x22
-#define REG_GPIO_IMR2B 0x23
-#define REG_GPIO_IMR3B 0x24
-#define REG_GPIO_EDR1 0x28
-#define REG_GPIO_EDR2 0x29
-#define REG_GPIO_EDR3 0x2A
-#define REG_GPIO_EDR4 0x2B
-#define REG_GPIO_EDR5 0x2C
-#define REG_GPIO_SIH_CTRL 0x2D
-
/* BitField Definitions */
/* Data banks : 3 banks for 8 gpios each */
diff --git a/drivers/i2c/chips/twl4030-pwrirq.c b/drivers/i2c/chips/twl4030-pwrirq.c
index a4d2e92..1afdb65 100644
--- a/drivers/i2c/chips/twl4030-pwrirq.c
+++ b/drivers/i2c/chips/twl4030-pwrirq.c
@@ -27,10 +27,8 @@
#include <linux/random.h>
#include <linux/kthread.h>
#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl4030-pwrirq.h>
-#define PWR_ISR1 0
-#define PWR_IMR1 1
-#define PWR_SIH_CTRL 7
#define PWR_SIH_CTRL_COR (1<<2)
static u8 twl4030_pwrirq_mask;
@@ -93,7 +91,8 @@ static void do_twl4030_pwrmodule_irq(unsigned int irq, irq_desc_t *desc)
twl4030_pwrirq_mask |= 1 << (irq - TWL4030_PWR_IRQ_BASE);
local_irq_enable();
twl4030_i2c_write_u8(TWL4030_MODULE_INT,
- twl4030_pwrirq_mask, PWR_IMR1);
+ twl4030_pwrirq_mask,
+ TWL4030_INT_PWR_IMR1);
}
}
}
@@ -115,7 +114,7 @@ static void do_twl4030_pwrirq(unsigned int irq, irq_desc_t *desc)
local_irq_enable();
ret = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &pwr_isr,
- PWR_ISR1);
+ TWL4030_INT_PWR_ISR1);
if (ret) {
printk(KERN_WARNING
"I2C error %d while reading TWL4030"
@@ -151,7 +150,7 @@ static int twl4030_pwrirq_thread(void *data)
twl4030_pwrirq_mask &= ~local_unmask;
twl4030_i2c_write_u8(TWL4030_MODULE_INT, twl4030_pwrirq_mask,
- PWR_IMR1);
+ TWL4030_INT_PWR_IMR1);
local_irq_disable();
if (!twl4030_pwrirq_pending_unmask)
@@ -172,14 +171,14 @@ static int __init twl4030_pwrirq_init(void)
twl4030_pwrirq_pending_unmask = 0;
err = twl4030_i2c_write_u8(TWL4030_MODULE_INT, twl4030_pwrirq_mask,
- PWR_IMR1);
+ TWL4030_INT_PWR_IMR1);
if (err)
return err;
/* Enable clear on read */
err = twl4030_i2c_write_u8(TWL4030_MODULE_INT, PWR_SIH_CTRL_COR,
- PWR_SIH_CTRL);
+ TWL4030_INT_PWR_SIH_CTRL);
if (err)
return err;
diff --git a/include/linux/i2c/twl4030-gpio.h b/include/linux/i2c/twl4030-gpio.h
new file mode 100644
index 0000000..7cbf610
--- /dev/null
+++ b/include/linux/i2c/twl4030-gpio.h
@@ -0,0 +1,76 @@
+/*
+ * twl4030-gpio.h - header for TWL4030 GPIO module
+ *
+ * Copyright (C) 2005-2006, 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __TWL4030_GPIO_H_
+#define __TWL4030_GPIO_H_
+
+/*
+ * GPIO Block Register definitions
+ */
+
+#define REG_GPIODATAIN1 0x0
+#define REG_GPIODATAIN2 0x1
+#define REG_GPIODATAIN3 0x2
+#define REG_GPIODATADIR1 0x3
+#define REG_GPIODATADIR2 0x4
+#define REG_GPIODATADIR3 0x5
+#define REG_GPIODATAOUT1 0x6
+#define REG_GPIODATAOUT2 0x7
+#define REG_GPIODATAOUT3 0x8
+#define REG_CLEARGPIODATAOUT1 0x9
+#define REG_CLEARGPIODATAOUT2 0xA
+#define REG_CLEARGPIODATAOUT3 0xB
+#define REG_SETGPIODATAOUT1 0xC
+#define REG_SETGPIODATAOUT2 0xD
+#define REG_SETGPIODATAOUT3 0xE
+#define REG_GPIO_DEBEN1 0xF
+#define REG_GPIO_DEBEN2 0x10
+#define REG_GPIO_DEBEN3 0x11
+#define REG_GPIO_CTRL 0x12
+#define REG_GPIOPUPDCTR1 0x13
+#define REG_GPIOPUPDCTR2 0x14
+#define REG_GPIOPUPDCTR3 0x15
+#define REG_GPIOPUPDCTR4 0x16
+#define REG_GPIOPUPDCTR5 0x17
+#define REG_GPIO_ISR1A 0x19
+#define REG_GPIO_ISR2A 0x1A
+#define REG_GPIO_ISR3A 0x1B
+#define REG_GPIO_IMR1A 0x1C
+#define REG_GPIO_IMR2A 0x1D
+#define REG_GPIO_IMR3A 0x1E
+#define REG_GPIO_ISR1B 0x1F
+#define REG_GPIO_ISR2B 0x20
+#define REG_GPIO_ISR3B 0x21
+#define REG_GPIO_IMR1B 0x22
+#define REG_GPIO_IMR2B 0x23
+#define REG_GPIO_IMR3B 0x24
+#define REG_GPIO_EDR1 0x28
+#define REG_GPIO_EDR2 0x29
+#define REG_GPIO_EDR3 0x2A
+#define REG_GPIO_EDR4 0x2B
+#define REG_GPIO_EDR5 0x2C
+#define REG_GPIO_SIH_CTRL 0x2D
+
+#endif /* End of __TWL4030_GPIO_H */
diff --git a/include/linux/i2c/twl4030-pwrirq.h b/include/linux/i2c/twl4030-pwrirq.h
new file mode 100644
index 0000000..7a13368
--- /dev/null
+++ b/include/linux/i2c/twl4030-pwrirq.h
@@ -0,0 +1,37 @@
+/*
+ * twl4030-gpio.h - header for TWL4030 GPIO module
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __TWL4030_PWRIRQ_H_
+#define __TWL4030_PWRIRQ_H_
+
+/*
+ * INT Module Register definitions
+ * (not all registers are defined below)
+ */
+
+#define TWL4030_INT_PWR_ISR1 0x0
+#define TWL4030_INT_PWR_IMR1 0x1
+#define TWL4030_INT_PWR_ISR2 0x2
+#define TWL4030_INT_PWR_IMR2 0x3
+#define TWL4030_INT_PWR_SIH_CTRL 0x7
+
+#endif /* End of __TWL4030_PWRIRQ_H */

View File

@ -0,0 +1,278 @@
TWL4030: use symbolic ISR/IMR register names during twl_init_irq()
From: Paul Walmsley <paul@pwsan.com>
twl_init_irq() uses a bunch of magic numbers as register indices; this
has already led to several errors, fixed earlier in this patch series.
Now use descriptive macros instead of magic numbers. This patch should
not change kernel behavior.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 188 +++++++++++++++++++-------------------
1 files changed, 96 insertions(+), 92 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index 99cc143..38c227a 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -40,6 +40,9 @@
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl4030-gpio.h>
+#include <linux/i2c/twl4030-madc.h>
+#include <linux/i2c/twl4030-pwrirq.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/device.h>
@@ -114,6 +117,23 @@
#define TWL4030_BASEADD_RTC 0x001C
#define TWL4030_BASEADD_SECURED_REG 0x0000
+/* TWL4030 BCI registers */
+#define TWL4030_INTERRUPTS_BCIIMR1A 0x2
+#define TWL4030_INTERRUPTS_BCIIMR2A 0x3
+#define TWL4030_INTERRUPTS_BCIIMR1B 0x6
+#define TWL4030_INTERRUPTS_BCIIMR2B 0x7
+#define TWL4030_INTERRUPTS_BCIISR1A 0x0
+#define TWL4030_INTERRUPTS_BCIISR2A 0x1
+#define TWL4030_INTERRUPTS_BCIISR1B 0x4
+#define TWL4030_INTERRUPTS_BCIISR2B 0x5
+
+/* TWL4030 keypad registers */
+#define TWL4030_KEYPAD_KEYP_IMR1 0x12
+#define TWL4030_KEYPAD_KEYP_IMR2 0x14
+#define TWL4030_KEYPAD_KEYP_ISR1 0x11
+#define TWL4030_KEYPAD_KEYP_ISR2 0x13
+
+
/* Triton Core internal information (END) */
/* Few power values */
@@ -133,12 +153,10 @@
/* on I2C-1 for 2430SDP */
#define CONFIG_I2C_TWL4030_ID 1
-/* SIH_CTRL registers */
-#define TWL4030_INT_PWR_SIH_CTRL 0x07
+/* SIH_CTRL registers that aren't defined elsewhere */
#define TWL4030_INTERRUPTS_BCISIHCTRL 0x0d
#define TWL4030_MADC_MADC_SIH_CTRL 0x67
#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
-#define TWL4030_GPIO_GPIO_SIH_CTRL 0x2d
#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
@@ -776,135 +794,121 @@ static void twl_init_irq(void)
* handlers present.
*/
-
- /* PWR_IMR1 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x1) < 0);
-
- /* PWR_IMR2 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff, 0x3) < 0);
-
- /* Clear off any other pending interrupts on power */
+ /* Mask INT (PWR) interrupts at TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
+ TWL4030_INT_PWR_IMR1) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
+ TWL4030_INT_PWR_IMR2) < 0);
/* Are PWR interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
TWL4030_INT_PWR_SIH_CTRL);
WARN_ON(cor < 0);
- /* PWR_ISR1 */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x00, cor) < 0);
-
- /* PWR_ISR2 */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT, 0x02, cor) < 0);
+ /* Clear TWL4030 INT (PWR) ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
+ TWL4030_INT_PWR_ISR1, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
+ TWL4030_INT_PWR_ISR2, cor) < 0);
/* Slave address 0x4A */
- /* BCIIMR1A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x2) < 0);
-
- /* BCIIMR2A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x3) < 0);
-
- /* BCIIMR2A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x6) < 0);
-
- /* BCIIMR2B */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 0x7) < 0);
+ /* Mask BCI interrupts at TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
+ TWL4030_INTERRUPTS_BCIIMR1A) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
+ TWL4030_INTERRUPTS_BCIIMR2A) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
+ TWL4030_INTERRUPTS_BCIIMR1B) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
+ TWL4030_INTERRUPTS_BCIIMR2B) < 0);
/* Are BCI interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
TWL4030_INTERRUPTS_BCISIHCTRL);
WARN_ON(cor < 0);
- /* BCIISR1A */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x0, cor) < 0);
-
- /* BCIISR2A */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x1, cor) < 0);
-
- /* BCIISR1B */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x4, cor) < 0);
-
- /* BCIISR2B */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS, 0x5, cor) < 0);
+ /* Clear TWL4030 BCI ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
+ TWL4030_INTERRUPTS_BCIISR1A, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
+ TWL4030_INTERRUPTS_BCIISR2A, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
+ TWL4030_INTERRUPTS_BCIISR1B, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
+ TWL4030_INTERRUPTS_BCIISR2B, cor) < 0);
/* MAD C */
- /* MADC_IMR1 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x62) < 0);
-
- /* MADC_IMR2 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff, 0x64) < 0);
+ /* Mask MADC interrupts at TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
+ TWL4030_MADC_IMR1) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
+ TWL4030_MADC_IMR2) < 0);
/* Are MADC interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
TWL4030_MADC_MADC_SIH_CTRL);
WARN_ON(cor < 0);
- /* MADC_ISR1 */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x61, cor) < 0);
-
- /* MADC_ISR2 */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC, 0x63, cor) < 0);
+ /* Clear TWL4030 MADC ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
+ TWL4030_MADC_ISR1, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
+ TWL4030_MADC_ISR2, cor) < 0);
/* key Pad */
- /* KEYPAD - IMR1 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x12) < 0);
+ /* Mask keypad interrupts at TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
+ TWL4030_KEYPAD_KEYP_IMR1) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
+ TWL4030_KEYPAD_KEYP_IMR2) < 0);
/* Are keypad interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
TWL4030_KEYPAD_KEYP_SIH_CTRL);
WARN_ON(cor < 0);
- /* KEYPAD - ISR1 */
+ /* Clear TWL4030 keypad ISRs */
/* XXX does this still need to be done twice for some reason? */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x11, cor) < 0);
-
- /* KEYPAD - IMR2 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff, 0x14) < 0);
-
- /* KEYPAD - ISR2 */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD, 0x13, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
+ TWL4030_KEYPAD_KEYP_ISR1, cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
+ TWL4030_KEYPAD_KEYP_ISR2, cor) < 0);
/* Slave address 0x49 */
- /* GPIO_IMR1A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1c) < 0);
-
- /* GPIO_IMR2A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1d) < 0);
-
- /* GPIO_IMR3A */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x1e) < 0);
-
- /* GPIO_IMR1B */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x22) < 0);
- /* GPIO_IMR2B */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x23) < 0);
-
- /* GPIO_IMR3B */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff, 0x24) < 0);
+ /* Mask GPIO interrupts at TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR1A) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR2A) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR3A) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR1B) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR2B) < 0);
+ WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
+ REG_GPIO_IMR3B) < 0);
/* Are GPIO interrupt status bits cleared by reads or writes? */
cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
- TWL4030_GPIO_GPIO_SIH_CTRL);
+ REG_GPIO_SIH_CTRL);
WARN_ON(cor < 0);
- /* GPIO_ISR1A */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x19, cor) < 0);
-
- /* GPIO_ISR2A */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1a, cor) < 0);
-
- /* GPIO_ISR3A */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1b, cor) < 0);
-
- /* GPIO_ISR1B */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x1f, cor) < 0);
-
- /* GPIO_ISR2B */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x20, cor) < 0);
-
- /* GPIO_ISR3B */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, 0x21, cor) < 0);
+ /* Clear TWL4030 GPIO ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1A,
+ cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2A,
+ cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3A,
+ cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1B,
+ cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2B,
+ cor) < 0);
+ WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3B,
+ cor) < 0);
/* install an irq handler for each of the PIH modules */
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {

View File

@ -0,0 +1,341 @@
TWL4030: convert early interrupt mask/clear funcs to use array
From: Paul Walmsley <paul@pwsan.com>
Mask/clear TWL module IMRs/ISRs by iterating through arrays rather than
using a block of cut-and-pasted commands. Removes 1056 bytes of bloat.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/chips/twl4030-core.c | 302 +++++++++++++++++++++++---------------
1 files changed, 180 insertions(+), 122 deletions(-)
diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c
index 38c227a..776b1dd 100644
--- a/drivers/i2c/chips/twl4030-core.c
+++ b/drivers/i2c/chips/twl4030-core.c
@@ -160,6 +160,136 @@
#define TWL4030_SIH_CTRL_COR_MASK (1 << 2)
+/**
+ * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init
+ * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO)
+ * @sih_ctrl: address of module SIH_CTRL register
+ * @reg_cnt: number of IMR/ISR regs
+ * @imrs: pointer to array of TWL module interrupt mask register indices
+ * @isrs: pointer to array of TWL module interrupt status register indices
+ *
+ * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear
+ * during twl_init_irq().
+ */
+struct twl4030_mod_iregs {
+ const u8 mod_no;
+ const u8 sih_ctrl;
+ const u8 reg_cnt;
+ const u8 *imrs;
+ const u8 *isrs;
+};
+
+/* TWL4030 INT module interrupt mask registers */
+static const u8 __initconst twl4030_int_imr_regs[] = {
+ TWL4030_INT_PWR_IMR1,
+ TWL4030_INT_PWR_IMR2,
+};
+
+/* TWL4030 INT module interrupt status registers */
+static const u8 __initconst twl4030_int_isr_regs[] = {
+ TWL4030_INT_PWR_ISR1,
+ TWL4030_INT_PWR_ISR2,
+};
+
+/* TWL4030 INTERRUPTS module interrupt mask registers */
+static const u8 __initconst twl4030_interrupts_imr_regs[] = {
+ TWL4030_INTERRUPTS_BCIIMR1A,
+ TWL4030_INTERRUPTS_BCIIMR1B,
+ TWL4030_INTERRUPTS_BCIIMR2A,
+ TWL4030_INTERRUPTS_BCIIMR2B,
+};
+
+/* TWL4030 INTERRUPTS module interrupt status registers */
+static const u8 __initconst twl4030_interrupts_isr_regs[] = {
+ TWL4030_INTERRUPTS_BCIISR1A,
+ TWL4030_INTERRUPTS_BCIISR1B,
+ TWL4030_INTERRUPTS_BCIISR2A,
+ TWL4030_INTERRUPTS_BCIISR2B,
+};
+
+/* TWL4030 MADC module interrupt mask registers */
+static const u8 __initconst twl4030_madc_imr_regs[] = {
+ TWL4030_MADC_IMR1,
+ TWL4030_MADC_IMR2,
+};
+
+/* TWL4030 MADC module interrupt status registers */
+static const u8 __initconst twl4030_madc_isr_regs[] = {
+ TWL4030_MADC_ISR1,
+ TWL4030_MADC_ISR2,
+};
+
+/* TWL4030 keypad module interrupt mask registers */
+static const u8 __initconst twl4030_keypad_imr_regs[] = {
+ TWL4030_KEYPAD_KEYP_IMR1,
+ TWL4030_KEYPAD_KEYP_IMR2,
+};
+
+/* TWL4030 keypad module interrupt status registers */
+static const u8 __initconst twl4030_keypad_isr_regs[] = {
+ TWL4030_KEYPAD_KEYP_ISR1,
+ TWL4030_KEYPAD_KEYP_ISR2,
+};
+
+/* TWL4030 GPIO module interrupt mask registers */
+static const u8 __initconst twl4030_gpio_imr_regs[] = {
+ REG_GPIO_IMR1A,
+ REG_GPIO_IMR1B,
+ REG_GPIO_IMR2A,
+ REG_GPIO_IMR2B,
+ REG_GPIO_IMR3A,
+ REG_GPIO_IMR3B,
+};
+
+/* TWL4030 GPIO module interrupt status registers */
+static const u8 __initconst twl4030_gpio_isr_regs[] = {
+ REG_GPIO_ISR1A,
+ REG_GPIO_ISR1B,
+ REG_GPIO_ISR2A,
+ REG_GPIO_ISR2B,
+ REG_GPIO_ISR3A,
+ REG_GPIO_ISR3B,
+};
+
+/* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */
+static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = {
+ {
+ .mod_no = TWL4030_MODULE_INT,
+ .sih_ctrl = TWL4030_INT_PWR_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_int_imr_regs),
+ .imrs = twl4030_int_imr_regs,
+ .isrs = twl4030_int_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_INTERRUPTS,
+ .sih_ctrl = TWL4030_INTERRUPTS_BCISIHCTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_interrupts_imr_regs),
+ .imrs = twl4030_interrupts_imr_regs,
+ .isrs = twl4030_interrupts_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_MADC,
+ .sih_ctrl = TWL4030_MADC_MADC_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_madc_imr_regs),
+ .imrs = twl4030_madc_imr_regs,
+ .isrs = twl4030_madc_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_KEYPAD,
+ .sih_ctrl = TWL4030_KEYPAD_KEYP_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_keypad_imr_regs),
+ .imrs = twl4030_keypad_imr_regs,
+ .isrs = twl4030_keypad_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_GPIO,
+ .sih_ctrl = REG_GPIO_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_gpio_imr_regs),
+ .imrs = twl4030_gpio_imr_regs,
+ .isrs = twl4030_gpio_isr_regs,
+ },
+};
+
/* Helper functions */
static int
@@ -779,136 +909,64 @@ static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
return tmp;
}
+/**
+ * twl4030_mask_clear_intrs - mask and clear all TWL4030 interrupts
+ * @t: pointer to twl4030_mod_iregs array
+ * @t_sz: ARRAY_SIZE(t) (starting at 1)
+ *
+ * Mask all TWL4030 interrupt mask registers (IMRs) and clear all
+ * interrupt status registers (ISRs). No return value, but will WARN if
+ * any I2C operations fail.
+ */
+static void __init twl4030_mask_clear_intrs(const struct twl4030_mod_iregs *t,
+ const u8 t_sz)
+{
+ int i, j;
+
+ /*
+ * N.B. - further efficiency is possible here. Eight I2C
+ * operations on BCI and GPIO modules are avoidable if I2C
+ * burst read/write transactions were implemented. Would
+ * probably save about 1ms of boot time and a small amount of
+ * power.
+ */
+ for (i = 0; i < t_sz; i++) {
+ const struct twl4030_mod_iregs tmr = t[i];
+
+ for (j = 0; j < tmr.reg_cnt; j++) {
+ int cor;
+
+ /* Mask interrupts at the TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff,
+ tmr.imrs[j]) < 0);
+
+ /* Are ISRs cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(tmr.mod_no, tmr.sih_ctrl);
+ WARN_ON(cor < 0);
+
+ /* Clear TWL4030 ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no,
+ tmr.isrs[j], cor) < 0);
+ }
+ }
+
+ return;
+}
+
+
static void twl_init_irq(void)
{
- int i = 0;
+ int i;
int res = 0;
- int cor;
char *msg = "Unable to register interrupt subsystem";
unsigned int irq_num;
/*
- * For each TWL4030 module with ISR/IMR registers, mask all
- * interrupts and then clear any existing interrupt status bits,
- * since we initially do not have any TWL4030 module interrupt
- * handlers present.
+ * Mask and clear all TWL4030 interrupts since initially we do
+ * not have any TWL4030 module interrupt handlers present
*/
-
- /* Mask INT (PWR) interrupts at TWL4030 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
- TWL4030_INT_PWR_IMR1) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INT, 0xff,
- TWL4030_INT_PWR_IMR2) < 0);
-
- /* Are PWR interrupt status bits cleared by reads or writes? */
- cor = twl4030_read_cor_bit(TWL4030_MODULE_INT,
- TWL4030_INT_PWR_SIH_CTRL);
- WARN_ON(cor < 0);
-
- /* Clear TWL4030 INT (PWR) ISRs */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
- TWL4030_INT_PWR_ISR1, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INT,
- TWL4030_INT_PWR_ISR2, cor) < 0);
-
- /* Slave address 0x4A */
-
- /* Mask BCI interrupts at TWL4030 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
- TWL4030_INTERRUPTS_BCIIMR1A) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
- TWL4030_INTERRUPTS_BCIIMR2A) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
- TWL4030_INTERRUPTS_BCIIMR1B) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
- TWL4030_INTERRUPTS_BCIIMR2B) < 0);
-
- /* Are BCI interrupt status bits cleared by reads or writes? */
- cor = twl4030_read_cor_bit(TWL4030_MODULE_INTERRUPTS,
- TWL4030_INTERRUPTS_BCISIHCTRL);
- WARN_ON(cor < 0);
-
- /* Clear TWL4030 BCI ISRs */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
- TWL4030_INTERRUPTS_BCIISR1A, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
- TWL4030_INTERRUPTS_BCIISR2A, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
- TWL4030_INTERRUPTS_BCIISR1B, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_INTERRUPTS,
- TWL4030_INTERRUPTS_BCIISR2B, cor) < 0);
-
- /* MAD C */
- /* Mask MADC interrupts at TWL4030 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
- TWL4030_MADC_IMR1) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_MADC, 0xff,
- TWL4030_MADC_IMR2) < 0);
-
- /* Are MADC interrupt status bits cleared by reads or writes? */
- cor = twl4030_read_cor_bit(TWL4030_MODULE_MADC,
- TWL4030_MADC_MADC_SIH_CTRL);
- WARN_ON(cor < 0);
-
- /* Clear TWL4030 MADC ISRs */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
- TWL4030_MADC_ISR1, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_MADC,
- TWL4030_MADC_ISR2, cor) < 0);
-
- /* key Pad */
- /* Mask keypad interrupts at TWL4030 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
- TWL4030_KEYPAD_KEYP_IMR1) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, 0xff,
- TWL4030_KEYPAD_KEYP_IMR2) < 0);
-
- /* Are keypad interrupt status bits cleared by reads or writes? */
- cor = twl4030_read_cor_bit(TWL4030_MODULE_KEYPAD,
- TWL4030_KEYPAD_KEYP_SIH_CTRL);
- WARN_ON(cor < 0);
-
- /* Clear TWL4030 keypad ISRs */
- /* XXX does this still need to be done twice for some reason? */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
- TWL4030_KEYPAD_KEYP_ISR1, cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_KEYPAD,
- TWL4030_KEYPAD_KEYP_ISR2, cor) < 0);
-
- /* Slave address 0x49 */
-
- /* Mask GPIO interrupts at TWL4030 */
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR1A) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR2A) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR3A) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR1B) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR2B) < 0);
- WARN_ON(twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0xff,
- REG_GPIO_IMR3B) < 0);
-
- /* Are GPIO interrupt status bits cleared by reads or writes? */
- cor = twl4030_read_cor_bit(TWL4030_MODULE_GPIO,
- REG_GPIO_SIH_CTRL);
- WARN_ON(cor < 0);
-
- /* Clear TWL4030 GPIO ISRs */
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1A,
- cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2A,
- cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3A,
- cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR1B,
- cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR2B,
- cor) < 0);
- WARN_ON(twl4030_i2c_clear_isr(TWL4030_MODULE_GPIO, REG_GPIO_ISR3B,
- cor) < 0);
+ twl4030_mask_clear_intrs(twl4030_mod_regs,
+ ARRAY_SIZE(twl4030_mod_regs));
/* install an irq handler for each of the PIH modules */
for (i = TWL4030_IRQ_BASE; i < TWL4030_IRQ_END; i++) {

View File

@ -0,0 +1,238 @@
On Tue, 2008-07-01 at 06:23 +0100, Dirk Behme wrote:
> Catalin Marinas wrote:
> > But, anyway, if you want a patch, Harry is updating it to a recent
> > kernel.
>
> Any news on this? I think there are some people wanting a patch ;)
See below for a preliminary patch updated to 2.6.26-rc8. Note that I
don't plan to submit it in its current form but clean it up a bit first.
Show the cache type of ARMv7 CPUs
From: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/kernel/setup.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-
include/asm-arm/system.h | 18 ++++++
2 files changed, 153 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 5ae0eb2..0cd238d 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -256,6 +256,24 @@ static const char *proc_arch[] = {
"?(17)",
};
+static const char *v7_cache_policy[4] = {
+ "reserved",
+ "AVIVT",
+ "VIPT",
+ "PIPT",
+};
+
+static const char *v7_cache_type[8] = {
+ "none",
+ "instruction only",
+ "data only",
+ "separate instruction and data",
+ "unified",
+ "unknown type",
+ "unknown type",
+ "unknown type",
+};
+
#define CACHE_TYPE(x) (((x) >> 25) & 15)
#define CACHE_S(x) ((x) & (1 << 24))
#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
@@ -266,6 +284,22 @@ static const char *proc_arch[] = {
#define CACHE_M(y) ((y) & (1 << 2))
#define CACHE_LINE(y) ((y) & 3)
+#define CACHE_TYPE_V7(x) (((x) >> 14) & 3)
+#define CACHE_UNIFIED(x) ((((x) >> 27) & 7)+1)
+#define CACHE_COHERENT(x) ((((x) >> 24) & 7)+1)
+
+#define CACHE_ID_LEVEL_MASK 7
+#define CACHE_ID_LEVEL_BITS 3
+
+#define CACHE_LINE_V7(v) ((1 << (((v) & 7)+4)))
+#define CACHE_ASSOC_V7(v) ((((v) >> 3) & ((1<<10)-1))+1)
+#define CACHE_SETS_V7(v) ((((v) >> 13) & ((1<<15)-1))+1)
+#define CACHE_SIZE_V7(v) (CACHE_LINE_V7(v)*CACHE_ASSOC_V7(v)*CACHE_SETS_V7(v))
+#define CACHE_WA_V7(v) (((v) & (1<<28)) != 0)
+#define CACHE_RA_V7(v) (((v) & (1<<29)) != 0)
+#define CACHE_WB_V7(v) (((v) & (1<<30)) != 0)
+#define CACHE_WT_V7(v) (((v) & (1<<31)) != 0)
+
static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
{
unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
@@ -279,11 +313,57 @@ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
CACHE_LINE(cache)));
}
+static void dump_v7_cache(const char *type, int cpu, unsigned int level)
+{
+ unsigned int cachesize;
+
+ write_extended_cpuid(2,0,0,0,level); /* Set the cache size selection register */
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
+ cachesize = read_extended_cpuid(1,0,0,0);
+
+ printk("CPU%u: %s cache: %d bytes, associativity %d, %d byte lines, %d sets,\n supports%s%s%s%s\n",
+ cpu, type,
+ CACHE_SIZE_V7(cachesize),CACHE_ASSOC_V7(cachesize),
+ CACHE_LINE_V7(cachesize),CACHE_SETS_V7(cachesize),
+ CACHE_WA_V7(cachesize) ? " WA" : "",
+ CACHE_RA_V7(cachesize) ? " RA" : "",
+ CACHE_WB_V7(cachesize) ? " WB" : "",
+ CACHE_WT_V7(cachesize) ? " WT" : "");
+}
+
static void __init dump_cpu_info(int cpu)
{
unsigned int info = read_cpuid(CPUID_CACHETYPE);
- if (info != processor_id) {
+ if (info != processor_id && (info & (1 << 31))) {
+ /* ARMv7 style of cache info register */
+ unsigned int id = read_extended_cpuid(1,0,0,1);
+ unsigned int level = 0;
+ printk("CPU%u: L1 I %s cache. Caches unified at level %u, coherent at level %u\n",
+ cpu,
+ v7_cache_policy[CACHE_TYPE_V7(info)],
+ CACHE_UNIFIED(id),
+ CACHE_COHERENT(id));
+
+ while (id & CACHE_ID_LEVEL_MASK) {
+ printk("CPU%u: Level %u cache is %s\n",
+ cpu, (level >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
+
+ if (id & 1) {
+ /* Dump I at this level */
+ dump_v7_cache("I", cpu, level | 1);
+ }
+
+ if (id & (4 | 2)) {
+ /* Dump D or unified at this level */
+ dump_v7_cache((id & 4) ? "unified" : "D", cpu, level);
+ }
+
+ /* Next level out */
+ level += 2;
+ id >>= CACHE_ID_LEVEL_BITS;
+ }
+ } else if (info != processor_id) {
printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
cache_types[CACHE_TYPE(info)]);
if (CACHE_S(info)) {
@@ -916,6 +996,30 @@ c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
CACHE_LINE(cache)));
}
+static void c_show_v7_cache(struct seq_file *m, const char *type, unsigned int levelselect)
+{
+ unsigned int cachesize;
+ unsigned int level = (levelselect >> 1) + 1;
+
+ write_extended_cpuid(2,0,0,0,levelselect); /* Set the cache size selection register */
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
+ cachesize = read_extended_cpuid(1,0,0,0);
+
+ seq_printf(m, "L%u %s size\t\t: %d bytes\n"
+ "L%u %s assoc\t\t: %d\n"
+ "L%u %s line length\t: %d\n"
+ "L%u %s sets\t\t: %d\n"
+ "L%u %s supports\t\t:%s%s%s%s\n",
+ level, type, CACHE_SIZE_V7(cachesize),
+ level, type, CACHE_ASSOC_V7(cachesize),
+ level, type, CACHE_LINE_V7(cachesize),
+ level, type, CACHE_SETS_V7(cachesize),
+ level, type, CACHE_WA_V7(cachesize) ? " WA" : "",
+ CACHE_RA_V7(cachesize) ? " RA" : "",
+ CACHE_WB_V7(cachesize) ? " WB" : "",
+ CACHE_WT_V7(cachesize) ? " WT" : "");
+}
+
static int c_show(struct seq_file *m, void *v)
{
int i;
@@ -971,7 +1075,36 @@ static int c_show(struct seq_file *m, void *v)
{
unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
- if (cache_info != processor_id) {
+ if (cache_info != processor_id && (cache_info & (1<<31))) {
+ /* V7 style of cache info register */
+ unsigned int id = read_extended_cpuid(1,0,0,1);
+ unsigned int levelselect = 0;
+ seq_printf(m, "L1 I cache\t:%s\n"
+ "Cache unification level\t: %u\n"
+ "Cache coherency level\t: %u\n",
+ v7_cache_policy[CACHE_TYPE_V7(cache_info)],
+ CACHE_UNIFIED(id),
+ CACHE_COHERENT(id));
+
+ while (id & CACHE_ID_LEVEL_MASK) {
+ seq_printf(m, "Level %u cache\t\t: %s\n",
+ (levelselect >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
+
+ if (id & 1) {
+ /* Dump I at this level */
+ c_show_v7_cache(m, "I", levelselect | 1);
+ }
+
+ if (id & (4 | 2)) {
+ /* Dump D or unified at this level */
+ c_show_v7_cache(m, (id & 4) ? "cache" : "D", levelselect);
+ }
+
+ /* Next level out */
+ levelselect += 2;
+ id >>= CACHE_ID_LEVEL_BITS;
+ }
+ } else if (cache_info != processor_id) {
seq_printf(m, "Cache type\t: %s\n"
"Cache clean\t: %s\n"
"Cache lockdown\t: %s\n"
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 514af79..704738e 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -74,6 +74,24 @@
: "cc"); \
__val; \
})
+#define read_extended_cpuid(op1,op2,op3,op4) \
+ ({ \
+ unsigned int __val; \
+ asm("mrc p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
+ : "=r" (__val) \
+ : \
+ : "cc"); \
+ __val; \
+ })
+
+#define write_extended_cpuid(op1,op2,op3,op4,v) \
+ ({ \
+ unsigned int __val = v; \
+ asm("mcr p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
+ : \
+ : "r" (__val) \
+ : "cc"); \
+ })
#else
extern unsigned int processor_id;
#define read_cpuid(reg) (processor_id)
--
Catalin

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.26-rc8-omap1
# Fri Jul 4 09:57:18 2008
# Linux kernel version: 2.6.26-rc9-omap1
# Tue Jul 8 15:36:02 2008
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@ -1037,6 +1037,7 @@ CONFIG_MEDIA_TUNER=m
# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA18271=m
CONFIG_MEDIA_TUNER_TDA9887=m
CONFIG_MEDIA_TUNER_TEA5761=m
CONFIG_MEDIA_TUNER_TEA5767=m
@ -1048,9 +1049,17 @@ CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC5000=m
CONFIG_VIDEO_V4L2=m
CONFIG_VIDEO_V4L1=m
CONFIG_VIDEO_TVEEPROM=m
CONFIG_VIDEO_TUNER=m
CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_ADV_DEBUG is not set
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_WM8775=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_CX25840=m
CONFIG_VIDEO_CX2341X=m
# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_CPIA2 is not set
@ -1059,23 +1068,29 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_TUNER_3036 is not set
# CONFIG_VIDEO_AU0828 is not set
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_VIDEO_PVRUSB2 is not set
CONFIG_USB_VIDEO_CLASS=m
CONFIG_VIDEO_PVRUSB2=m
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
# CONFIG_VIDEO_EM28XX is not set
# CONFIG_VIDEO_USBVISION is not set
# CONFIG_USB_VICAM is not set
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_KONICAWC is not set
# CONFIG_USB_QUICKCAM_MESSENGER is not set
CONFIG_VIDEO_USBVISION=m
CONFIG_VIDEO_USBVIDEO=m
CONFIG_USB_VICAM=m
CONFIG_USB_IBMCAM=m
CONFIG_USB_KONICAWC=m
CONFIG_USB_QUICKCAM_MESSENGER=m
# CONFIG_USB_ET61X251 is not set
# CONFIG_VIDEO_OVCAMCHIP is not set
# CONFIG_USB_W9968CF is not set
# CONFIG_USB_OV511 is not set
# CONFIG_USB_SE401 is not set
# CONFIG_USB_SN9C102 is not set
# CONFIG_USB_STV680 is not set
CONFIG_VIDEO_OVCAMCHIP=m
CONFIG_USB_W9968CF=m
CONFIG_USB_OV511=m
CONFIG_USB_SE401=m
CONFIG_USB_SN9C102=m
CONFIG_USB_STV680=m
# CONFIG_USB_ZC0301 is not set
# CONFIG_USB_PWC is not set
# CONFIG_USB_ZR364XX is not set
CONFIG_USB_PWC=m
# CONFIG_USB_PWC_DEBUG is not set
CONFIG_USB_ZR364XX=m
# CONFIG_USB_STKWEBCAM is not set
# CONFIG_SOC_CAMERA is not set
CONFIG_RADIO_ADAPTERS=y
@ -1225,9 +1240,13 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_FB_OMAP=y
# CONFIG_FB_OMAP_031M3R is not set
# CONFIG_FB_OMAP_048M3R is not set
CONFIG_FB_OMAP_079M3R=y
# CONFIG_FB_OMAP_092M9R is not set
# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=4
CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=8
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#

View File

@ -0,0 +1,118 @@
From linux-omap-owner@vger.kernel.org Tue Jul 15 21:23:13 2008
Received: from localhost
([127.0.0.1] helo=dominion ident=koen)
by dominion.dominion.void with esmtp (Exim 4.69)
(envelope-from <linux-omap-owner@vger.kernel.org>)
id 1KIq7E-0004FX-VS
for koen@localhost; Tue, 15 Jul 2008 21:23:13 +0200
Received: from xs.service.utwente.nl [130.89.5.250]
by dominion with POP3 (fetchmail-6.3.6)
for <koen@localhost> (single-drop); Tue, 15 Jul 2008 21:23:12 +0200 (CEST)
Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
Tue, 15 Jul 2008 21:01:02 +0200
Received: from mx.utwente.nl ([130.89.2.12]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
Tue, 15 Jul 2008 21:01:01 +0200
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id m6FJ0qDf031889
for <k.kooi@student.utwente.nl>; Tue, 15 Jul 2008 21:00:52 +0200
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1756776AbYGOTAV (ORCPT <rfc822;k.kooi@student.utwente.nl>);
Tue, 15 Jul 2008 15:00:21 -0400
Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755065AbYGOTAV
(ORCPT <rfc822;linux-omap-outgoing>);
Tue, 15 Jul 2008 15:00:21 -0400
Received: from utopia.booyaka.com ([72.9.107.138]:35569 "EHLO
utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1756776AbYGOTAU (ORCPT
<rfc822;linux-omap@vger.kernel.org>); Tue, 15 Jul 2008 15:00:20 -0400
Received: (qmail 2982 invoked by uid 526); 15 Jul 2008 19:00:18 -0000
Date: Tue, 15 Jul 2008 13:00:18 -0600 (MDT)
From: Paul Walmsley <paul@pwsan.com>
To: linux-omap@vger.kernel.org
Subject: [PATCH] i2c-omap: close suspected race between omap_i2c_idle() and
omap_i2c_isr()
Message-ID: <alpine.DEB.1.00.0807151259180.467@utopia.booyaka.com>
User-Agent: Alpine 1.00 (DEB 882 2007-12-20)
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Sender: linux-omap-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-omap.vger.kernel.org>
X-Mailing-List: linux-omap@vger.kernel.org
X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
X-UTwente-MailScanner: Found to be clean
X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
X-Spam-Status: No
X-OriginalArrivalTime: 15 Jul 2008 19:01:01.0610 (UTC) FILETIME=[1FBA68A0:01C8E6AD]
omap_i2c_idle() sets an internal flag, "dev->idle", instructing its
ISR to decline interrupts. It sets this flag before it actually masks
the interrupts on the I2C controller. This is problematic, since an
I2C interrupt could arrive after dev->idle is set, but before the
interrupt source is masked. When this happens, Linux disables the I2C
controller's IRQ, causing all future transactions on the bus to fail.
Symptoms, happening on about 7% of boots:
irq 56: nobody cared (try booting with the "irqpoll" option)
<warning traceback here>
Disabling IRQ #56
i2c_omap i2c_omap.1: controller timed out
In omap_i2c_idle(), this patch sets dev->idle only after the interrupt
mask write to the I2C controller has left the ARM write buffer.
That's probably the major offender. For additional prophylaxis, in
omap_i2c_unidle(), the patch clears the dev->idle flag before
interrupts are enabled, rather than afterwards.
The patch has survived twenty-two reboots on the 3430SDP here without
wedging I2C1. Not absolutely dispositive, but promising!
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
drivers/i2c/busses/i2c-omap.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 55779f5..ed7e9ad 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -209,22 +209,28 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->fclk);
+ dev->idle = 0;
if (dev->iestate)
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
- dev->idle = 0;
}
static void omap_i2c_idle(struct omap_i2c_dev *dev)
{
u16 iv;
- dev->idle = 1;
dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev1)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
else
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
+ /*
+ * The wmb() is to ensure that the I2C interrupt mask write
+ * reaches the I2C controller before the dev->idle store
+ * occurs.
+ */
+ wmb();
+ dev->idle = 1;
clk_disable(dev->fclk);
if (dev->iclk != NULL)
clk_disable(dev->iclk);
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

View File

@ -0,0 +1,25 @@
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 22 Jul 2008 00:31:11 +0000 (+0100)
Subject: ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2b7b958dc79e51127d7a4ecf88ce12dbc6c31426
ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
Filling the set_rate and round_rate fields of dpll4_m4_ck makes
this clock programmable through clk_set_rate(). This is needed
to give omapfb control over the dss1_alwon_fck rate.
---
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 161da12..876eb13 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -815,6 +815,8 @@ static struct clk dpll4_m4_ck = {
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
+ .set_rate = &omap2_clksel_set_rate,
+ .round_rate = &omap2_clksel_round_rate,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */

View File

@ -0,0 +1,62 @@
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 22 Jul 2008 00:58:18 +0000 (+0100)
Subject: ARM: OMAP: add clk_get_parent() for OMAP2/3
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=e2de5e5578fbaa9b4b75074796da0608fc93e6ae
ARM: OMAP: add clk_get_parent() for OMAP2/3
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 577be44..28aec36 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -824,6 +824,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
return 0;
}
+struct clk *omap2_clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+
/* DPLL rate rounding code */
/**
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 49245f7..4aa69d5 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -29,6 +29,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
+struct clk *omap2_clk_get_parent(struct clk *clk);
#ifdef CONFIG_OMAP_RESET_CLOCKS
void omap2_clk_disable_unused(struct clk *clk);
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index 54cc6e1..ed7af21 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -422,6 +422,7 @@ static struct clk_functions omap2_clk_functions = {
.clk_round_rate = omap2_clk_round_rate,
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
+ .clk_get_parent = omap2_clk_get_parent,
.clk_disable_unused = omap2_clk_disable_unused,
#ifdef CONFIG_CPU_FREQ
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 04dedec..08c8c46 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -541,6 +541,7 @@ static struct clk_functions omap2_clk_functions = {
.clk_round_rate = omap2_clk_round_rate,
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
+ .clk_get_parent = omap2_clk_get_parent,
.clk_disable_unused = omap2_clk_disable_unused,
};

View File

@ -0,0 +1,94 @@
From: Mans Rullgard <mans@mansr.com>
Date: Wed, 23 Jul 2008 08:40:07 +0000 (+0100)
Subject: ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=01ee28c50701caa94739e764c3dae9298edd8216
ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
This sets the DSS1_ALWON_FCLK clock as close as possible to a
multiple of the requested pixel clock, while keeping it below
the 173MHz limit.
Due to of the structure of the clock tree, dss1_alwon_fck cannot
be set directly, and we must use dpll4_m4_ck instead.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index fd06ca2..e0e8528 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -176,6 +176,7 @@ static struct {
struct clk *dss_ick, *dss1_fck;
struct clk *dss_54m_fck;
+ struct clk *dpll4_m4_ck;
enum omapfb_update_mode update_mode;
struct omapfb_device *fbdev;
@@ -738,21 +739,34 @@ static void setup_color_conv_coef(void)
MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
}
-#define MAX_FCK_LCD 173000000
+#define MAX_FCK 173000000
static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
{
+ unsigned long prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
+ unsigned long pcd_min = is_tft? 2: 3;
+ unsigned long fck_div;
unsigned long fck, lck;
pck = max(1, pck);
+
+ if (pck * pcd_min > MAX_FCK) {
+ dev_warn(dispc.fbdev->dev, "pixclock %d kHz too high.\n",
+ pck / 1000);
+ pck = MAX_FCK / pcd_min;
+ }
+
+ fck = pck * 2;
+ fck_div = (prate + pck) / fck;
+ if (fck_div > 16)
+ fck_div /= (fck_div + 15) / 16;
+ if (fck_div < 1)
+ fck_div = 1;
+ clk_set_rate(dispc.dpll4_m4_ck, prate / fck_div);
fck = clk_get_rate(dispc.dss1_fck);
- *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
- lck = fck / *lck_div;
- *pck_div = (lck + pck - 1) / pck;
- if (is_tft)
- *pck_div = max(2, *pck_div);
- else
- *pck_div = max(3, *pck_div);
+
+ *lck_div = 1;
+ *pck_div = (fck + pck - 1) / pck;
if (*pck_div > 255) {
*pck_div = 255;
lck = pck * *pck_div;
@@ -914,11 +928,21 @@ static int get_dss_clocks(void)
return PTR_ERR(dispc.dss_54m_fck);
}
+ if (IS_ERR((dispc.dpll4_m4_ck =
+ clk_get(dispc.fbdev->dev, "dpll4_m4_ck")))) {
+ dev_err(dispc.fbdev->dev, "can't get dpll4_m4_ck");
+ clk_put(dispc.dss_ick);
+ clk_put(dispc.dss1_fck);
+ clk_put(dispc.dss_54m_fck);
+ return PTR_ERR(dispc.dss_54m_fck);
+ }
+
return 0;
}
static void put_dss_clocks(void)
{
+ clk_put(dispc.dpll4_m4_ck);
clk_put(dispc.dss_54m_fck);
clk_put(dispc.dss1_fck);
clk_put(dispc.dss_ick);

View File

@ -0,0 +1,18 @@
--- /tmp/pm34xx.c 2008-07-14 18:09:08.000000000 +0200
+++ git/arch/arm/mach-omap2/pm34xx.c 2008-07-14 18:09:42.453198000 +0200
@@ -398,13 +398,13 @@
INT_34XX_PRCM_MPU_IRQ);
goto err1;
}
-
+/*
ret = pwrdm_for_each(pwrdms_setup);
if (ret) {
printk(KERN_ERR "Failed to setup powerdomains\n");
goto err2;
}
-
+*/
mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
if (mpu_pwrdm == NULL) {
printk(KERN_ERR "Failed to get mpu_pwrdm\n");

View File

@ -29,10 +29,10 @@ index 4e1314c..d2c0b12 100644
+obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
new file mode 100644
index 0000000..c9eee19
index 0000000..eb8370c
--- /dev/null
+++ b/sound/soc/codecs/twl4030.c
@@ -0,0 +1,595 @@
@@ -0,0 +1,625 @@
+/*
+ * ALSA SoC TWL4030 codec driver
+ *
@ -196,7 +196,7 @@ index 0000000..c9eee19
+ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ twl4030_reg[REG_CODEC_MODE] & 0xfd, REG_CODEC_MODE);
+
+ udelay(10); /* 10 ms delay for power settling */
+ udelay(10); /* delay for power settling */
+
+ for (i = REG_OPTION; i <= REG_MISC_SET_2; i++) {
+ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl4030_reg[i], i);
@ -205,7 +205,7 @@ index 0000000..c9eee19
+ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ twl4030_reg[REG_CODEC_MODE], REG_CODEC_MODE);
+
+ udelay(10); /* 10 ms delay for power settling */
+ udelay(10); /* delay for power settling */
+
+ /* initiate offset cancellation */
+ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
@ -219,7 +219,6 @@ index 0000000..c9eee19
+ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+ twl4030_reg[REG_MISC_SET_1] | 0x02, REG_MISC_SET_1);
+
+ twl4030_dump_registers();
+}
+
+static const struct snd_kcontrol_new twl4030_snd_controls[] = {
@ -247,8 +246,6 @@ index 0000000..c9eee19
+ return 0;
+}
+
+#define TWL4030_PWR 0
+
+static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("INL"),
+ SND_SOC_DAPM_INPUT("INR"),
@ -314,32 +311,40 @@ index 0000000..c9eee19
+
+static void twl4030_power_up (struct snd_soc_codec *codec, u8 mode)
+{
+ u8 popn, hsgain;
+
+ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ);
+ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ);
+ udelay(10);
+
+ u8 popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET) | (0x40);
+ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
+ popn &= RAMP_DELAY;
+ popn |= VMID_EN | RAMP_DELAY_161MS;
+ twl4030_write(codec, REG_HS_POPN_SET, popn);
+
+ u8 hsgain = twl4030_read_reg_cache(codec, REG_HS_GAIN_SET) | (0x0a);
+ hsgain = HSR_GAIN_0DB| HSL_GAIN_0DB;
+ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
+
+ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET) | (0x02);
+ popn |= RAMP_EN;
+ twl4030_write(codec, REG_HS_POPN_SET, popn);
+}
+
+static void twl4030_power_down (struct snd_soc_codec *codec)
+{
+ u8 popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET) & ~(0x02);
+ u8 popn, hsgain, mode;
+
+ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
+ popn &= ~RAMP_EN;
+ twl4030_write(codec, REG_HS_POPN_SET, popn);
+
+ u8 hsgain = twl4030_read_reg_cache(codec, REG_HS_GAIN_SET) & ~(0x0f);
+ hsgain = HSR_GAIN_PWR_DOWN | HSL_GAIN_PWR_DOWN;
+ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
+
+ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET) & ~(0x40);
+ popn &= ~VMID_EN;
+ twl4030_write(codec, REG_HS_POPN_SET, popn);
+
+ u8 mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE) & ~CODECPDZ;
+ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
+ mode &= ~CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+ udelay(10);
+}
@ -352,19 +357,18 @@ index 0000000..c9eee19
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct twl4030_priv *twl4030 = codec->private_data;
+ u8 mode, old_mode, format, old_format;
+
+ twl4030_power_down(codec);
+
+ u8 mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE) & ~CODECPDZ;
+
+ /* bit rate */
+ old_mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE) & ~CODECPDZ;
+ mode = old_mode;
+ mode &= ~APLL_RATE;
+ switch (params_rate(params)) {
+ case 44100:
+ printk(KERN_INFO "TWL4030 hw params: set rate to 44.1khz\n");
+ mode |= APLL_RATE_44100;
+ break;
+ case 48000:
+ printk(KERN_INFO "TWL4030 hw params: set rate to 48khz\n");
+ mode |= APLL_RATE_48000;
+ break;
+ default:
@ -372,22 +376,43 @@ index 0000000..c9eee19
+ return -EINVAL;
+ }
+
+ /* bit size */
+ if (mode != old_mode) {
+ /* change rate and turn codec back on */
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+ mode |= CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+ }
+
+ /* sample size */
+ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF);
+ format = old_format;
+ format &= ~DATA_WIDTH;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ printk(KERN_INFO "TWL4030 hw params: set format to S16_LE\n");
+ format |= DATA_WIDTH_16S_16W;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ printk(KERN_INFO "TWL4030 hw params: set format to S24_LE\n");
+ format |= DATA_WIDTH_32S_24W;
+ break;
+ default:
+ printk(KERN_INFO "TWL4030 hw params: unknown format %d\n", params_format(params));
+ return -EINVAL;
+ }
+
+ /* change rate and turn codec back on */
+ twl4030_power_up(codec, mode);
+ if (format != old_format) {
+
+ /* turn off codec before changing format */
+ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
+ mode &= ~CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+
+ /* change format */
+ twl4030_write(codec, REG_AUDIO_IF, format);
+
+ /* turn on codec */
+ mode |= CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+ }
+ return 0;
+}
+
@ -399,14 +424,14 @@ index 0000000..c9eee19
+ u8 rdac_reg = twl4030_read_reg_cache(codec, REG_ARXR2PGA);
+
+ if (mute) {
+ printk(KERN_INFO "TWL4030 Audio Codec mute\n");
+ /* printk(KERN_INFO "TWL4030 Audio Codec mute\n"); */
+ twl4030_write(codec, REG_ARXL2PGA, 0x00);
+ twl4030_write(codec, REG_ARXR2PGA, 0x00);
+ twl4030_write_reg_cache(codec, REG_ARXL2PGA, ldac_reg);
+ twl4030_write_reg_cache(codec, REG_ARXR2PGA, rdac_reg);
+ }
+ else {
+ printk(KERN_INFO "TWL4030 Audio Codec unmute: %02x/%02x\n", ldac_reg, rdac_reg);
+ /* printk(KERN_INFO "TWL4030 Audio Codec unmute: %02x/%02x\n", ldac_reg, rdac_reg); */
+ twl4030_write(codec, REG_ARXL2PGA, ldac_reg);
+ twl4030_write(codec, REG_ARXR2PGA, rdac_reg);
+ }
@ -419,19 +444,21 @@ index 0000000..c9eee19
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct twl4030_priv *twl4030 = codec->private_data;
+ u8 mode, old_format, format;
+
+ /* get current format */
+ u8 format = twl4030_read_reg_cache(codec, REG_AUDIO_IF);
+ /* get format */
+ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF);
+ format = old_format;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ printk(KERN_INFO "TWL4030 set dai fmt: master\n");
+ /* printk(KERN_INFO "TWL4030 set dai fmt: master\n"); */
+ format &= ~(AIF_SLAVE_EN);
+ format |= CLK256FS_EN;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ printk(KERN_INFO "TWL4030 set dai fmt: slave\n");
+ /* printk(KERN_INFO "TWL4030 set dai fmt: slave\n"); */
+ format &= ~(CLK256FS_EN);
+ format |= AIF_SLAVE_EN;
+ break;
@ -443,21 +470,26 @@ index 0000000..c9eee19
+ format &= ~AIF_FORMAT;
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ printk(KERN_INFO "TWL4030 set dai fmt: i2s\n");
+ /* printk(KERN_INFO "TWL4030 set dai fmt: i2s\n"); */
+ format |= AIF_FORMAT_CODEC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* turn off codec before changing format */
+ twl4030_power_down(codec);
+ if (format != old_format) {
+
+ /* change format */
+ twl4030_write(codec, REG_AUDIO_IF, format);
+ /* turn off codec before changing format */
+ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
+ mode &= ~CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+
+ u8 mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
+ twl4030_power_up(codec, mode);
+ /* change format */
+ twl4030_write(codec, REG_AUDIO_IF, format);
+
+ mode |= CODECPDZ;
+ twl4030_write(codec, REG_CODEC_MODE, mode);
+ }
+
+ return 0;
+}
@ -530,8 +562,6 @@ index 0000000..c9eee19
+
+ printk(KERN_INFO "TWL4030 Audio Codec init \n");
+
+ twl4030_init_chip();
+
+ codec->name = "twl4030";
+ codec->owner = THIS_MODULE;
+ codec->read = twl4030_read_reg_cache;
@ -560,6 +590,9 @@ index 0000000..c9eee19
+ goto card_err;
+ }
+
+ twl4030_init_chip();
+ twl4030_power_up(codec, APLL_RATE_44100 | OPT_MODE);
+
+ return ret;
+
+card_err:
@ -580,8 +613,6 @@ index 0000000..c9eee19
+ struct snd_soc_codec *codec;
+ struct twl4030_priv *twl4030;
+
+ printk(KERN_INFO "TWL4030 Audio Codec probe\n");
+
+ codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+ if (codec == NULL)
+ return -ENOMEM;
@ -601,7 +632,6 @@ index 0000000..c9eee19
+ twl4030_socdev = socdev;
+ twl4030_init(socdev);
+
+ printk(KERN_INFO "TWL4030 Audio Codec probe exit\n");
+ return 0;
+}
+
@ -630,10 +660,10 @@ index 0000000..c9eee19
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
new file mode 100644
index 0000000..af8eb43
index 0000000..e126f96
--- /dev/null
+++ b/sound/soc/codecs/twl4030.h
@@ -0,0 +1,125 @@
@@ -0,0 +1,152 @@
+/*
+ * ALSA SoC TWL4030 codec driver
+ *
@ -722,7 +752,7 @@ index 0000000..af8eb43
+
+/* Bitfield Definitions */
+
+/* CODEC_MODE Fields */
+/* CODEC_MODE (0x01) Fields */
+
+#define APLL_RATE 0xF0
+#define APLL_RATE_8000 0x00
@ -738,7 +768,7 @@ index 0000000..af8eb43
+#define CODECPDZ 0x02
+#define OPT_MODE 0x01
+
+/* AUDIO_IF Fields */
+/* AUDIO_IF (0x0E) Fields */
+
+#define AIF_SLAVE_EN 0x80
+#define DATA_WIDTH 0x60
@ -754,6 +784,33 @@ index 0000000..af8eb43
+#define CLK256FS_EN 0x02
+#define AIF_EN 0x01
+
+/* HS_GAIN_SET (0x23) Fields */
+
+#define HSR_GAIN 0x0c
+#define HSR_GAIN_PWR_DOWN 0x00
+#define HSR_GAIN_PLUS_6DB 0x04
+#define HSR_GAIN_0DB 0x08
+#define HSR_GAIN_MINUS_6DB 0x0c
+#define HSL_GAIN 0x0c
+#define HSL_GAIN_PWR_DOWN 0x00
+#define HSL_GAIN_PLUS_6DB 0x01
+#define HSL_GAIN_0DB 0x02
+#define HSL_GAIN_MINUS_6DB 0x03
+
+/* HS_POPN_SET (0x24) Fields */
+
+#define VMID_EN 0x40
+#define EXTMUTE 0x20
+#define RAMP_DELAY 0x1C
+#define RAMP_DELAY_20MS 0x00
+#define RAMP_DELAY_40MS 0x04
+#define RAMP_DELAY_81MS 0x08
+#define RAMP_DELAY_161MS 0x0c
+#define RAMP_DELAY_323MS 0x10
+#define RAMP_DELAY_645MS 0x14
+#define RAMP_DELAY_1291MS 0x18
+#define RAMP_DELAY_2581MS 0x1c
+#define RAMP_EN 0x02
+
+extern struct snd_soc_codec_dai twl4030_dai;
+extern struct snd_soc_codec_device soc_codec_dev_twl4030;
@ -801,10 +858,10 @@ index d8d8d58..638a240 100644
+
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
new file mode 100644
index 0000000..fb79938
index 0000000..878f894
--- /dev/null
+++ b/sound/soc/omap/omap3beagle.c
@@ -0,0 +1,180 @@
@@ -0,0 +1,142 @@
+/*
+ * omap3beagle.c -- SoC audio for OMAP3 Beagle
+ *
@ -877,50 +934,12 @@ index 0000000..fb79938
+ .hw_params = omap3beagle_hw_params,
+};
+
+static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static const char *audio_map[][3] = {
+ {"Headphone Jack", NULL, "HPLOUT"},
+ {"Headphone Jack", NULL, "HPROUT"},
+
+ {"Line In", NULL, "Line In"},
+ {"Line In", NULL, "Line In"},
+};
+
+static int omap3beagle_twl4030_init(struct snd_soc_codec *codec)
+{
+ int i;
+
+ printk(KERN_INFO "OMAP3 Beagle TWL4030 SoC init\n");
+
+ /* Add omap3beagle specific widgets */
+ for (i = 0; i < ARRAY_SIZE(twl4030_dapm_widgets); i++)
+ snd_soc_dapm_new_control(codec, &twl4030_dapm_widgets[i]);
+
+ /* Set up omap3beagle specific audio path audio_map */
+ for (i = 0; i < ARRAY_SIZE(audio_map); i++)
+ snd_soc_dapm_connect_input(codec, audio_map[i][0],
+ audio_map[i][1], audio_map[i][2]);
+
+ /* always connected */
+ snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1);
+ snd_soc_dapm_set_endpoint(codec, "Line In", 1);
+
+ snd_soc_dapm_sync_endpoints(codec);
+
+ return 0;
+}
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap3beagle_dai = {
+ .name = "TWL4030",
+ .stream_name = "TWL4030",
+ .cpu_dai = &omap_mcbsp_dai[0],
+ .codec_dai = &twl4030_dai,
+ .init = omap3beagle_twl4030_init,
+ .ops = &omap3beagle_ops,
+};
+
@ -987,10 +1006,10 @@ index 0000000..fb79938
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
new file mode 100644
index 0000000..32d4f5d
index 0000000..a64c788
--- /dev/null
+++ b/sound/soc/omap/omap3evm.c
@@ -0,0 +1,180 @@
@@ -0,0 +1,142 @@
+/*
+ * omap3evm.c -- SoC audio for OMAP3 EVM
+ *
@ -1063,50 +1082,12 @@ index 0000000..32d4f5d
+ .hw_params = omap3evm_hw_params,
+};
+
+static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static const char *audio_map[][3] = {
+ {"Headphone Jack", NULL, "HPLOUT"},
+ {"Headphone Jack", NULL, "HPROUT"},
+
+ {"Line In", NULL, "Line In"},
+ {"Line In", NULL, "Line In"},
+};
+
+static int omap3evm_twl4030_init(struct snd_soc_codec *codec)
+{
+ int i;
+
+ printk(KERN_INFO "OMAP3 EVM TWL4030 SoC init\n");
+
+ /* Add omap3evm specific widgets */
+ for (i = 0; i < ARRAY_SIZE(twl4030_dapm_widgets); i++)
+ snd_soc_dapm_new_control(codec, &twl4030_dapm_widgets[i]);
+
+ /* Set up omap3evm specific audio path audio_map */
+ for (i = 0; i < ARRAY_SIZE(audio_map); i++)
+ snd_soc_dapm_connect_input(codec, audio_map[i][0],
+ audio_map[i][1], audio_map[i][2]);
+
+ /* always connected */
+ snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1);
+ snd_soc_dapm_set_endpoint(codec, "Line In", 1);
+
+ snd_soc_dapm_sync_endpoints(codec);
+
+ return 0;
+}
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap3evm_dai = {
+ .name = "TWL4030",
+ .stream_name = "TWL4030",
+ .cpu_dai = &omap_mcbsp_dai[0],
+ .codec_dai = &twl4030_dai,
+ .init = omap3evm_twl4030_init,
+ .ops = &omap3evm_ops,
+};
+

View File

@ -0,0 +1,25 @@
Index: git/include/asm-arm/processor.h
===================================================================
--- git.orig/include/asm-arm/processor.h 2008-08-03 11:27:02.000000000 +0100
+++ git/include/asm-arm/processor.h 2008-08-03 11:53:22.000000000 +0100
@@ -109,14 +109,16 @@
#if __LINUX_ARM_ARCH__ >= 5
#define ARCH_HAS_PREFETCH
-static inline void prefetch(const void *ptr)
+#define prefetch(ptr) __builtin_prefetch(ptr)
+
+/*static inline void prefetch(const void *ptr)
{
__asm__ __volatile__(
- "pld\t%0"
+ "pld\ta%0"
:
- : "o" (*(char *)ptr)
+ : "p" (ptr)
: "cc");
-}
+}*/
#define ARCH_HAS_PREFETCHW
#define prefetchw(ptr) prefetch(ptr)

View File

@ -1,13 +1,15 @@
require linux-omap2.inc
FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git/${MACHINE}"
FILESPATH = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git/${MACHINE}:${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git"
SRCREV = "c32c81d59d2d8a66e63f82c9732db256d302068e"
SRCREV = "d3b3ae0fe6c71641da19c8de466ec366d39847e3"
PV = "2.6.25+2.6.26-rc8+${PR}+git${SRCREV}"
PR = "r38"
PV = "2.6.26"
#PV = "2.6.25+2.6.26-rc9+${PR}+git${SRCREV}"
PR = "r49"
SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
file://fixes.patch;patch=1 \
file://defconfig"
SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
@ -21,6 +23,29 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
file://no-empty-flash-warnings.patch;patch=1 \
file://logo_linux_clut224.ppm \
file://oprofile-0.9.3.armv7.diff;patch=1 \
file://01-fix-timing-print.diff;patch=1 \
file://03-enable-overlay-opt.diff;patch=1 \
file://04-use-pcd.diff;patch=1 \
file://05-fix-display-panning.diff;patch=1 \
file://06-ensure-fclk.diff;patch=1 \
file://07-set-burst-size.diff;patch=1 \
file://cache-display-fix.patch;patch=1 \
file://serialfix.diff;patch=1 \
file://i2c-omap-race-fix.diff;patch=1 \
file://TWL4030-01.patch;patch=1 \
file://TWL4030-02.patch;patch=1 \
file://TWL4030-03.patch;patch=1 \
file://TWL4030-04.patch;patch=1 \
file://TWL4030-05.patch;patch=1 \
file://TWL4030-06.patch;patch=1 \
file://TWL4030-07.patch;patch=1 \
file://TWL4030-08.patch;patch=1 \
file://TWL4030-09.patch;patch=1 \
file://mru-clocks1.diff;patch=1 \
file://mru-clocks2.diff;patch=1 \
file://mru-clocks3.diff;patch=1 \
file://4bitmmc.diff;patch=1 \
file://400khz-i2c.diff;patch=1 \
"
SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \