diff options
author | Richard Purdie <richard@openedhand.com> | 2008-08-03 11:21:36 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2008-08-03 11:21:36 +0000 |
commit | 5e4da782189840fb87bf4ff2ff689a7278cd75c1 (patch) | |
tree | f707818d7bb3e96031876c651411feb12fa632f9 /meta/packages/linux | |
parent | 6dda6e3c3e1413e08364fdca7496435a894abe5f (diff) | |
download | openembedded-core-5e4da782189840fb87bf4ff2ff689a7278cd75c1.tar.gz openembedded-core-5e4da782189840fb87bf4ff2ff689a7278cd75c1.tar.bz2 openembedded-core-5e4da782189840fb87bf4ff2ff689a7278cd75c1.zip |
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
Diffstat (limited to 'meta/packages/linux')
29 files changed, 2747 insertions, 152 deletions
diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/01-fix-timing-print.diff b/meta/packages/linux/linux-omap2-git/beagleboard/01-fix-timing-print.diff new file mode 100644 index 0000000000..89fbe3a836 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/01-fix-timing-print.diff @@ -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; + diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/02-set-clkseld11.diff b/meta/packages/linux/linux-omap2-git/beagleboard/02-set-clkseld11.diff new file mode 100644 index 0000000000..c437f145d3 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/02-set-clkseld11.diff @@ -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()) { diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/03-enable-overlay-opt.diff b/meta/packages/linux/linux-omap2-git/beagleboard/03-enable-overlay-opt.diff new file mode 100644 index 0000000000..9fa749f5fc --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/03-enable-overlay-opt.diff @@ -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; diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/04-use-pcd.diff b/meta/packages/linux/linux-omap2-git/beagleboard/04-use-pcd.diff new file mode 100644 index 0000000000..bdf8ab5f0b --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/04-use-pcd.diff @@ -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)); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/05-fix-display-panning.diff b/meta/packages/linux/linux-omap2-git/beagleboard/05-fix-display-panning.diff new file mode 100644 index 0000000000..d3c9fffcda --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/05-fix-display-panning.diff @@ -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, diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/06-ensure-fclk.diff b/meta/packages/linux/linux-omap2-git/beagleboard/06-ensure-fclk.diff new file mode 100644 index 0000000000..79871a7208 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/06-ensure-fclk.diff @@ -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); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/07-set-burst-size.diff b/meta/packages/linux/linux-omap2-git/beagleboard/07-set-burst-size.diff new file mode 100644 index 0000000000..99bd80eae0 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/07-set-burst-size.diff @@ -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; diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/16bpp.patch b/meta/packages/linux/linux-omap2-git/beagleboard/16bpp.patch index f1e2181c82..d2bff4b018 100644 --- a/meta/packages/linux/linux-omap2-git/beagleboard/16bpp.patch +++ b/meta/packages/linux/linux-omap2-git/beagleboard/16bpp.patch @@ -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, + diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/400khz-i2c.diff b/meta/packages/linux/linux-omap2-git/beagleboard/400khz-i2c.diff new file mode 100644 index 0000000000..f749dbcf5b --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/400khz-i2c.diff @@ -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; diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/4bitmmc.diff b/meta/packages/linux/linux-omap2-git/beagleboard/4bitmmc.diff new file mode 100644 index 0000000000..5cd120c544 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/4bitmmc.diff @@ -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; diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-01.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-01.patch new file mode 100644 index 0000000000..c361c33d61 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-01.patch @@ -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) { diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-02.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-02.patch new file mode 100644 index 0000000000..48a59b945b --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-02.patch @@ -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); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-03.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-03.patch new file mode 100644 index 0000000000..fe1bea5398 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-03.patch @@ -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; diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-04.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-04.patch new file mode 100644 index 0000000000..fb65ac98bb --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-04.patch @@ -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)); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-05.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-05.patch new file mode 100644 index 0000000000..02a72ed9df --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-05.patch @@ -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++) { diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-06.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-06.patch new file mode 100644 index 0000000000..67b837c454 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-06.patch @@ -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, diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-07.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-07.patch new file mode 100644 index 0000000000..8e4c4d6be4 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-07.patch @@ -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 */ diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-08.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-08.patch new file mode 100644 index 0000000000..9af25a762d --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-08.patch @@ -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++) { diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-09.patch b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-09.patch new file mode 100644 index 0000000000..ab6cc6d87b --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/TWL4030-09.patch @@ -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++) { diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch b/meta/packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch new file mode 100644 index 0000000000..c96b95f2f4 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/cache-display-fix.patch @@ -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 + + diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/defconfig b/meta/packages/linux/linux-omap2-git/beagleboard/defconfig index 87fadae1ec..6381271cf9 100644 --- a/meta/packages/linux/linux-omap2-git/beagleboard/defconfig +++ b/meta/packages/linux/linux-omap2-git/beagleboard/defconfig @@ -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 # diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff b/meta/packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff new file mode 100644 index 0000000000..6eb33f76b7 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/i2c-omap-race-fix.diff @@ -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 + diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks1.diff b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks1.diff new file mode 100644 index 0000000000..d7dadbc85e --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks1.diff @@ -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 */ diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks2.diff b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks2.diff new file mode 100644 index 0000000000..c8b370da03 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks2.diff @@ -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, + }; + diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks3.diff b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks3.diff new file mode 100644 index 0000000000..f8407fc2d5 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/mru-clocks3.diff @@ -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); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/serialfix.diff b/meta/packages/linux/linux-omap2-git/beagleboard/serialfix.diff new file mode 100644 index 0000000000..74c2ebaa69 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/beagleboard/serialfix.diff @@ -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"); diff --git a/meta/packages/linux/linux-omap2-git/beagleboard/soc.patch b/meta/packages/linux/linux-omap2-git/beagleboard/soc.patch index bb97403f29..f4cce21ca7 100644 --- a/meta/packages/linux/linux-omap2-git/beagleboard/soc.patch +++ b/meta/packages/linux/linux-omap2-git/beagleboard/soc.patch @@ -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, +}; + diff --git a/meta/packages/linux/linux-omap2-git/fixes.patch b/meta/packages/linux/linux-omap2-git/fixes.patch new file mode 100644 index 0000000000..8478682787 --- /dev/null +++ b/meta/packages/linux/linux-omap2-git/fixes.patch @@ -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) diff --git a/meta/packages/linux/linux-omap2_git.bb b/meta/packages/linux/linux-omap2_git.bb index c4d67f553c..983678aaad 100644 --- a/meta/packages/linux/linux-omap2_git.bb +++ b/meta/packages/linux/linux-omap2_git.bb @@ -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 \ |