From 007a9ca5d4fcd80ccfa5f77bbc42b68a87440312 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 1 Oct 2008 09:01:53 +0000 Subject: linux-omap git: add MUSB patch to fix multiple bulk transfers, drop obsolete patches --- .../linux-omap/010-mru-fix-video-mode-param.diff | 35 --- packages/linux/linux-omap/04-use-pcd.diff | 28 --- packages/linux/linux-omap/16bpp.patch | 137 ---------- packages/linux/linux-omap/4bitmmc.diff | 38 --- packages/linux/linux-omap/musb-dmafix.patch | 275 --------------------- .../musb-fix-multiple-bulk-transfers.diff | 194 +++++++++++++++ .../OMAP3EVM_TWL4030-Keypad-irq-error-fix.patch | 32 --- packages/linux/linux-omap_git.bb | 6 +- 8 files changed, 196 insertions(+), 549 deletions(-) delete mode 100644 packages/linux/linux-omap/010-mru-fix-video-mode-param.diff delete mode 100644 packages/linux/linux-omap/04-use-pcd.diff delete mode 100644 packages/linux/linux-omap/16bpp.patch delete mode 100644 packages/linux/linux-omap/4bitmmc.diff delete mode 100644 packages/linux/linux-omap/musb-dmafix.patch create mode 100644 packages/linux/linux-omap/musb-fix-multiple-bulk-transfers.diff delete mode 100644 packages/linux/linux-omap/omap3evm/OMAP3EVM_TWL4030-Keypad-irq-error-fix.patch (limited to 'packages/linux') diff --git a/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff b/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff deleted file mode 100644 index 50d69b8b75..0000000000 --- a/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff +++ /dev/null @@ -1,35 +0,0 @@ -From: Mans Rullgard -Date: Wed, 3 Sep 2008 23:19:04 +0000 (+0100) -Subject: OMAP: Fix omapfb video mode selection when built as module -X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=9bafff77f3028cd170c605c8d883963522c8546c - -OMAP: Fix omapfb video mode selection when built as module - -This fixes the video_mode parameter when omapfb is built as a module. - -Signed-off-by: Mans Rullgard ---- - -diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c -index 19a1a83..e0b3642 100644 ---- a/drivers/video/omap/omapfb_main.c -+++ b/drivers/video/omap/omapfb_main.c -@@ -54,7 +54,7 @@ static unsigned long def_vxres; - static unsigned long def_vyres; - static unsigned int def_rotate; - static unsigned int def_mirror; --static char def_mode[16] = CONFIG_FB_OMAP_VIDEO_MODE; -+static char def_mode[16]; - - #ifdef CONFIG_FB_OMAP_MANUAL_UPDATE - static int manual_update = 1; -@@ -2143,7 +2143,8 @@ static int __init omapfb_init(void) - omapfb_setup(option); - #endif - -- omapfb_find_mode(def_mode, &video_mode); -+ omapfb_find_mode(def_mode[0]? def_mode : CONFIG_FB_OMAP_VIDEO_MODE, -+ &video_mode); - - /* Register the driver with LDM */ - if (platform_driver_register(&omapfb_driver)) { diff --git a/packages/linux/linux-omap/04-use-pcd.diff b/packages/linux/linux-omap/04-use-pcd.diff deleted file mode 100644 index bdf8ab5f0b..0000000000 --- a/packages/linux/linux-omap/04-use-pcd.diff +++ /dev/null @@ -1,28 +0,0 @@ -From: Mans Rullgard -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/packages/linux/linux-omap/16bpp.patch b/packages/linux/linux-omap/16bpp.patch deleted file mode 100644 index d2bff4b018..0000000000 --- a/packages/linux/linux-omap/16bpp.patch +++ /dev/null @@ -1,137 +0,0 @@ -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..5e098c2 100644 ---- a/drivers/video/omap/lcd_omap3beagle.c -+++ b/drivers/video/omap/lcd_omap3beagle.c -@@ -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, -- .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/packages/linux/linux-omap/4bitmmc.diff b/packages/linux/linux-omap/4bitmmc.diff deleted file mode 100644 index 5cd120c544..0000000000 --- a/packages/linux/linux-omap/4bitmmc.diff +++ /dev/null @@ -1,38 +0,0 @@ -From: Purushotam Kumar -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 -Acked-by: Madhusudhan Chikkature Rajashekar ---- - -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/packages/linux/linux-omap/musb-dmafix.patch b/packages/linux/linux-omap/musb-dmafix.patch deleted file mode 100644 index 259b79be59..0000000000 --- a/packages/linux/linux-omap/musb-dmafix.patch +++ /dev/null @@ -1,275 +0,0 @@ -From: Gadiyar, Anand -Date: Wed, 13 Aug 2008 07:05:29 +0000 (+0530) -Subject: MUSB: Workaround for simultaneous TX and RX usage -X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2e6aa4efb0e14c51ff0427927b1b38136911fa93 - -MUSB: Workaround for simultaneous TX and RX usage - -MUSB: Workaround for simultaneous TX and RX usage - -MUSB RTL V1.4 has a hardware issue which results in a DMA controller -hang when TX and RX DMA channels are simultaneously enabled. This -affects at least OMAP2430 and OMAP34XX. - -Since RX transfers are in Mode 0 and anyway result in one DMA interrupt -per packet, we can use System DMA to unload the RX fifos. MUSB DMA can -be used for all TX channels as before. - -Tested with full-duplex TX and RX transfers using g_ether. Runs for 24 -hours without a hang. Without this patch, the hang occurs within minutes. - -This issue was first reported by Jon Hunter on [1] - -[1] http://marc.info/?l=linux-omap&m=119634480534453&w=2 - -Signed-off-by: Anand Gadiyar ---- - -diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig -index a485a86..8583e54 100644 ---- a/drivers/usb/musb/Kconfig -+++ b/drivers/usb/musb/Kconfig -@@ -150,6 +150,14 @@ config USB_INVENTRA_DMA - help - Enable DMA transfers using Mentor's engine. - -+config MUSB_USE_SYSTEM_DMA_RX -+ bool 'Use System DMA for RX endpoints' -+ depends on USB_MUSB_HDRC && USB_INVENTRA_DMA -+ help -+ MUSB RTL version 1.4 has a hardware issue when TX and RX DMA -+ channels are simultaneously enabled. To work around this issue, -+ you can choose to use System DMA for RX channels. -+ - config USB_TI_CPPI_DMA - bool - depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY -diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c -index 32bb1e2..d1c1ea0 100644 ---- a/drivers/usb/musb/musbhsdma.c -+++ b/drivers/usb/musb/musbhsdma.c -@@ -34,6 +34,7 @@ - #include - #include - #include "musb_core.h" -+#include - - #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) - #include "omap2430.h" -@@ -64,6 +65,9 @@ - - #define MUSB_HSDMA_CHANNELS 8 - -+#define MUSB_FIFO_ADDRESS(epnum) \ -+ ((unsigned long) (OMAP_HSOTG_BASE + MUSB_FIFO_OFFSET(epnum))) -+ - struct musb_dma_controller; - - struct musb_dma_channel { -@@ -75,6 +79,8 @@ struct musb_dma_channel { - u8 bIndex; - u8 epnum; - u8 transmit; -+ -+ int sysdma_channel; - }; - - struct musb_dma_controller { -@@ -93,6 +99,42 @@ static int dma_controller_start(struct dma_controller *c) - return 0; - } - -+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX -+static void musb_sysdma_completion(int lch, u16 ch_status, void *data) -+{ -+ u32 dwAddress; -+ unsigned long flags; -+ -+ struct dma_channel *pChannel; -+ -+ struct musb_dma_channel *pImplChannel = -+ (struct musb_dma_channel *) data; -+ struct musb_dma_controller *controller = pImplChannel->controller; -+ struct musb *musb = controller->pDmaPrivate; -+ pChannel = &pImplChannel->Channel; -+ -+ DBG(2, "lch = 0x%d, ch_status = 0x%x\n", lch, ch_status); -+ spin_lock_irqsave(&musb->lock, flags); -+ -+ dwAddress = (u32) omap_get_dma_dst_pos(pImplChannel->sysdma_channel); -+ pChannel->actual_len = dwAddress - pImplChannel->dwStartAddress; -+ -+ DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", -+ pChannel, pImplChannel->dwStartAddress, dwAddress, -+ pChannel->actual_len, pImplChannel->len, -+ (pChannel->actual_len < pImplChannel->len) ? -+ "=> reconfig 0": "=> complete"); -+ -+ pChannel->status = MUSB_DMA_STATUS_FREE; -+ musb_dma_completion(musb, pImplChannel->epnum, pImplChannel->transmit); -+ -+ spin_unlock_irqrestore(&musb->lock, flags); -+ return; -+} -+#else -+#define musb_sysdma_completion NULL -+#endif -+ - static void dma_channel_release(struct dma_channel *pChannel); - - static int dma_controller_stop(struct dma_controller *c) -@@ -144,6 +186,29 @@ static struct dma_channel *dma_channel_allocate(struct dma_controller *c, - /* Tx => mode 1; Rx => mode 0 */ - pChannel->desired_mode = transmit; - pChannel->actual_len = 0; -+ pImplChannel->sysdma_channel = -1; -+ -+#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX -+ if (!transmit) { -+ int ret; -+ ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, -+ "MUSB SysDMA", musb_sysdma_completion, -+ (void *) pImplChannel, -+ &(pImplChannel->sysdma_channel)); -+ -+ if (ret) { -+ printk(KERN_ERR "request_dma failed:" -+ " %d\n", ret); -+ controller->bmUsedChannels &= -+ ~(1 << bBit); -+ pChannel->status = -+ MUSB_DMA_STATUS_UNKNOWN; -+ pImplChannel->sysdma_channel = -1; -+ pChannel = NULL; -+ } -+ } -+#endif -+ - break; - } - } -@@ -163,6 +228,12 @@ static void dma_channel_release(struct dma_channel *pChannel) - ~(1 << pImplChannel->bIndex); - - pChannel->status = MUSB_DMA_STATUS_UNKNOWN; -+ -+ if (pImplChannel->sysdma_channel != -1) { -+ omap_stop_dma(pImplChannel->sysdma_channel); -+ omap_free_dma(pImplChannel->sysdma_channel); -+ pImplChannel->sysdma_channel = -1; -+ } - } - - static void configure_channel(struct dma_channel *pChannel, -@@ -179,41 +250,69 @@ static void configure_channel(struct dma_channel *pChannel, - DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n", - pChannel, packet_sz, dma_addr, len, mode); - -- if (mode) { -- csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; -- BUG_ON(len < packet_sz); -+ if (pImplChannel->sysdma_channel != -1) { -+ /* System DMA */ -+ /* RX: set src = FIFO */ -+ -+ omap_set_dma_transfer_params(pImplChannel->sysdma_channel, -+ OMAP_DMA_DATA_TYPE_S8, -+ len, 1, /* One frame */ -+ OMAP_DMA_SYNC_ELEMENT, -+ OMAP24XX_DMA_NO_DEVICE, -+ 0); /* Src Sync */ -+ -+ omap_set_dma_src_params(pImplChannel->sysdma_channel, 0, -+ OMAP_DMA_AMODE_CONSTANT, -+ MUSB_FIFO_ADDRESS(pImplChannel->epnum), -+ 0, 0); - -- if (packet_sz >= 64) { -- csr |= MUSB_HSDMA_BURSTMODE_INCR16 -+ omap_set_dma_dest_params(pImplChannel->sysdma_channel, 0, -+ OMAP_DMA_AMODE_POST_INC, dma_addr, -+ 0, 0); -+ -+ omap_set_dma_dest_data_pack(pImplChannel->sysdma_channel, 1); -+ omap_set_dma_dest_burst_mode(pImplChannel->sysdma_channel, -+ OMAP_DMA_DATA_BURST_16); -+ -+ omap_start_dma(pImplChannel->sysdma_channel); -+ -+ } else { /* Mentor DMA */ -+ if (mode) { -+ csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; -+ BUG_ON(len < packet_sz); -+ -+ if (packet_sz >= 64) { -+ csr |= MUSB_HSDMA_BURSTMODE_INCR16 - << MUSB_HSDMA_BURSTMODE_SHIFT; -- } else if (packet_sz >= 32) { -- csr |= MUSB_HSDMA_BURSTMODE_INCR8 -+ } else if (packet_sz >= 32) { -+ csr |= MUSB_HSDMA_BURSTMODE_INCR8 - << MUSB_HSDMA_BURSTMODE_SHIFT; -- } else if (packet_sz >= 16) { -- csr |= MUSB_HSDMA_BURSTMODE_INCR4 -+ } else if (packet_sz >= 16) { -+ csr |= MUSB_HSDMA_BURSTMODE_INCR4 - << MUSB_HSDMA_BURSTMODE_SHIFT; -+ } - } -- } - -- csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) -- | (1 << MUSB_HSDMA_ENABLE_SHIFT) -- | (1 << MUSB_HSDMA_IRQENABLE_SHIFT) -- | (pImplChannel->transmit -- ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT) -- : 0); -- -- /* address/count */ -- musb_writel(mbase, -- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS), -- dma_addr); -- musb_writel(mbase, -- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT), -- len); -- -- /* control (this should start things) */ -- musb_writew(mbase, -- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL), -- csr); -+ csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) -+ | (1 << MUSB_HSDMA_ENABLE_SHIFT) -+ | (1 << MUSB_HSDMA_IRQENABLE_SHIFT) -+ | (pImplChannel->transmit -+ ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT) -+ : 0); -+ -+ /* address/count */ -+ musb_writel(mbase, -+ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS), -+ dma_addr); -+ musb_writel(mbase, -+ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT), -+ len); -+ -+ /* control (this should start things) */ -+ musb_writew(mbase, -+ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL), -+ csr); -+ } /* Mentor DMA */ - } - - static int dma_channel_program(struct dma_channel *pChannel, -@@ -265,6 +364,12 @@ static int dma_channel_abort(struct dma_channel *pChannel) - MUSB_EP_OFFSET(pImplChannel->epnum, MUSB_TXCSR), - csr); - } else { -+ if (pImplChannel->sysdma_channel != -1) { -+ omap_stop_dma(pImplChannel->sysdma_channel); -+ omap_free_dma(pImplChannel->sysdma_channel); -+ pImplChannel->sysdma_channel = -1; -+ } -+ - csr = musb_readw(mbase, - MUSB_EP_OFFSET(pImplChannel->epnum, MUSB_RXCSR)); - csr &= ~(MUSB_RXCSR_AUTOCLEAR | diff --git a/packages/linux/linux-omap/musb-fix-multiple-bulk-transfers.diff b/packages/linux/linux-omap/musb-fix-multiple-bulk-transfers.diff new file mode 100644 index 0000000000..7435a2e413 --- /dev/null +++ b/packages/linux/linux-omap/musb-fix-multiple-bulk-transfers.diff @@ -0,0 +1,194 @@ +From: Ajay Kumar Gupta +To: linux-usb@vger.kernel.org +Cc: linux-omap@vger.kernel.org, felipe.balbi@nokia.com, +Subject: [PATCH] MUSB: Fix for kernel panic with multiple bulk transfer +Date: Wed, 1 Oct 2008 13:08:56 +0530 + +Fixes kernel panic when multiple copy is performed among more than two mass +storage media and transfer is aborted.musb_advance_schedule(), +musb_urb_dequeue(),musb_cleanup_urb() and musb_h_disable() functions have +been modified to correct urb handling associated with bulk and control +endpoints which are multiplexed on one hardware endpoint. + +musb_advance_schedule() has been removed from musb_cleanup_urb() and added +to musb_urb_dequeue(). musb_h_disable() has been modified to take care of +multiple qh on same hw_ep scenario. + +Signed-off-by: Ajay Kumar Gupta +CC: Romit Dasgupta +--- +Suggestions welcome to move while loop doing kfree(qh) from +musb_advance_schedule() and musb_h_disable() to musb_giveback(). + + drivers/usb/musb/musb_host.c | 105 ++++++++++++++++++++++++++++++----------- + 1 files changed, 77 insertions(+), 28 deletions(-) + +diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c +index 8b4be01..c2474de 100644 +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -427,8 +427,17 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, + qh = musb_giveback(qh, urb, 0); + else + qh = musb_giveback(qh, urb, urb->status); ++ while (qh && qh->is_ready && list_empty(&qh->hep->urb_list)) { ++ struct list_head *head; ++ head = qh->ring.prev; ++ list_del(&qh->ring); ++ qh->hep->hcpriv = NULL; ++ kfree(qh); ++ qh = first_qh(head); ++ } + +- if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { ++ ++ if (qh && qh->is_ready) { + DBG(4, "... next ep%d %cX urb %p\n", + hw_ep->epnum, is_in ? 'R' : 'T', + next_urb(qh)); +@@ -1964,8 +1973,6 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) + /* flush cpu writebuffer */ + csr = musb_readw(epio, MUSB_TXCSR); + } +- if (status == 0) +- musb_advance_schedule(ep->musb, urb, ep, is_in); + return status; + } + +@@ -2026,13 +2033,24 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) + /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ + if (ret < 0 || (sched && qh != first_qh(sched))) { + int ready = qh->is_ready; +- ++ int type = urb->pipe; + ret = 0; + qh->is_ready = 0; + __musb_giveback(musb, urb, 0); +- qh->is_ready = ready; +- } else ++ ++ if (list_empty(&qh->hep->urb_list) && list_empty(&qh->ring)) ++ list_del(&qh->ring); ++ else ++ qh->is_ready = ready; ++ if (usb_pipeisoc(type)) ++ musb->periodic[qh->hw_ep->epnum] = NULL; ++ } else { + ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); ++ if (!ret) { ++ musb_advance_schedule(qh->hw_ep->musb, urb, qh->hw_ep, ++ urb->pipe & USB_DIR_IN); ++ } ++ } + done: + spin_unlock_irqrestore(&musb->lock, flags); + return ret; +@@ -2046,14 +2064,17 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) + unsigned long flags; + struct musb *musb = hcd_to_musb(hcd); + u8 is_in = epnum & USB_DIR_IN; +- struct musb_qh *qh = hep->hcpriv; ++ struct musb_qh *qh, *qh_for_curr_urb; + struct urb *urb, *tmp; + struct list_head *sched; +- +- if (!qh) +- return; ++ int i; + + spin_lock_irqsave(&musb->lock, flags); ++ qh = hep->hcpriv; ++ if (!qh) { ++ spin_unlock_irqrestore(&musb->lock, flags); ++ return; ++ } + + switch (qh->type) { + case USB_ENDPOINT_XFER_CONTROL: +@@ -2065,6 +2086,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) + else + sched = &musb->out_bulk; + break; ++ case USB_ENDPOINT_XFER_ISOC: ++ case USB_ENDPOINT_XFER_INT: ++ for (i = 0; i < musb->nr_endpoints; i++) { ++ if (musb->periodic[i] == qh) ++ sched = &qh->ring; ++ break; ++ } + default: + /* REVISIT when we get a schedule tree, periodic transfers + * won't always be at the head of a singleton queue... +@@ -2073,26 +2101,47 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) + break; + } + +- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ +- + /* kick first urb off the hardware, if needed */ +- qh->is_ready = 0; +- if (!sched || qh == first_qh(sched)) { ++ if (sched) { ++ qh_for_curr_urb = qh; + urb = next_urb(qh); +- +- /* make software (then hardware) stop ASAP */ +- if (!urb->unlinked) +- urb->status = -ESHUTDOWN; +- +- /* cleanup */ +- musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); +- } else +- urb = NULL; +- +- /* then just nuke all the others */ +- list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) +- musb_giveback(qh, urb, -ESHUTDOWN); +- ++ if (urb) { ++ /* make software (then hardware) stop ASAP */ ++ if (!urb->unlinked) ++ urb->status = -ESHUTDOWN; ++ /* cleanup first urb of first qh; */ ++ if (qh == first_qh(sched)) { ++ musb_cleanup_urb(urb, qh, ++ urb->pipe & USB_DIR_IN); ++ } ++ qh = musb_giveback(qh, urb, -ESHUTDOWN); ++ if (qh == qh_for_curr_urb) { ++ list_for_each_entry_safe_from(urb, tmp, ++ &hep->urb_list, urb_list) { ++ qh = musb_giveback(qh, tmp, -ESHUTDOWN); ++ if (qh != qh_for_curr_urb) ++ break; ++ } ++ } ++ } ++ /* pick the next candidate and go */ ++ if (qh && qh->is_ready) { ++ while (qh && qh->is_ready && ++ list_empty(&qh->hep->urb_list)) { ++ struct list_head *head; ++ head = qh->ring.prev; ++ list_del(&qh->ring); ++ qh->hep->hcpriv = NULL; ++ kfree(qh); ++ qh = first_qh(head); ++ } ++ if (qh && qh->is_ready) { ++ epnum = qh->hep->desc.bEndpointAddress; ++ is_in = epnum & USB_DIR_IN; ++ musb_start_urb(musb, is_in, qh); ++ } ++ } ++ } + spin_unlock_irqrestore(&musb->lock, flags); + } + +-- +1.5.6 + +-- +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/packages/linux/linux-omap/omap3evm/OMAP3EVM_TWL4030-Keypad-irq-error-fix.patch b/packages/linux/linux-omap/omap3evm/OMAP3EVM_TWL4030-Keypad-irq-error-fix.patch deleted file mode 100644 index aac1151b78..0000000000 --- a/packages/linux/linux-omap/omap3evm/OMAP3EVM_TWL4030-Keypad-irq-error-fix.patch +++ /dev/null @@ -1,32 +0,0 @@ -without this the below error messages were coming continuously - -TWL4030 module irq 369 is disabled but can't be masked! -<2>TWL4030 module irq 369 is disabled but can't be masked! - -Signed-off-by: Arun C ---- - arch/arm/mach-omap2/board-omap3evm.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3evm.c -b/arch/arm/mach-omap2/board-omap3evm.c -index 92f70ce..f9fd06b 100644 ---- a/arch/arm/mach-omap2/board-omap3evm.c -+++ b/arch/arm/mach-omap2/board-omap3evm.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -176,6 +177,7 @@ static struct omap_kp_platform_data omap3evm_kp_data = { - .keymap = omap3evm_keymap, - .keymapsize = ARRAY_SIZE(omap3evm_keymap), - .rep = 1, -+ .irq = TWL4030_MODIRQ_KEYPAD, - }; - - static struct platform_device omap3evm_kp_device = { - diff --git a/packages/linux/linux-omap_git.bb b/packages/linux/linux-omap_git.bb index 54a73b308c..3adc9366ba 100644 --- a/packages/linux/linux-omap_git.bb +++ b/packages/linux/linux-omap_git.bb @@ -9,7 +9,7 @@ COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard| SRCREV = "e1c49d7d22af768188e2a54c167ed79919361e55" PV = "2.6.26+2.6.27-rc7+${PR}+git${SRCREV}" -PR = "r9" +PR = "r10" SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \ file://defconfig" @@ -31,11 +31,9 @@ SRC_URI_append = " \ file://mru-make-video-timings-selectable.diff;patch=1 \ file://mru-enable-overlay-optimalization.diff;patch=1 \ file://musb-fix-ISO-in-unlink.diff;patch=1 \ + file://musb-fix-multiple-bulk-transfers.diff;patch=1 \ " -temporarely-disabled = " \ - file://musb-dmafix.patch;patch=1 \ -" SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ file://beagle-asoc.diff;patch=1 \ -- cgit v1.2.3