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:
parent
6dda6e3c3e
commit
5e4da78218
|
@ -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;
|
||||
|
|
@ -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()) {
|
|
@ -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;
|
|
@ -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));
|
|
@ -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,
|
|
@ -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);
|
|
@ -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;
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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) {
|
|
@ -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);
|
|
@ -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;
|
|
@ -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));
|
|
@ -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++) {
|
|
@ -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,
|
|
@ -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 */
|
|
@ -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++) {
|
|
@ -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++) {
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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);
|
|
@ -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");
|
|
@ -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,
|
||||
+};
|
||||
+
|
||||
|
|
|
@ -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)
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue