Omap MMC init updates and new controller for 2.6.29 merge window
Subsystems (8)
Tony Lindgren
maintainercover Omap MMC init updates and new controller for 2.6.29 merge window
Hi Pierre & Russell,
This series contains a better platform init for omap MMC as discussed earlier on the linux-omap mailing list. The last patch in the series adds support for a newer omap MMC controller available on 2430 and 34xx omaps.
The first four patches should get merged via Russell. The last one adding the new controller depends on comments from Pierre, so I can separate that out if desired.
The third patch in the series depends on the "Omap3 updates for 2.6.29 merge window" series for the changes to Pandora board support.
Comments welcome as always!
Regards,
Tony
---
Kevin Hilman (1):
omap mmc: force MMC module reset on boot
Madhusudhan Chikkature (1):
omap mmc: Add new omap hsmmc controller for 2430 and 34xx
Tony Lindgren (3):
omap mmc: Add low-level initialization for hsmmc controller omap mmc: Add better MMC low-level init
omap mmc: Remove broken MMC init code
arch/arm/mach-omap1/board-h2-mmc.c | 89 +- arch/arm/mach-omap1/board-h2.c | 25 - arch/arm/mach-omap1/board-h3-mmc.c | 100 +- arch/arm/mach-omap1/board-h3.c | 10 arch/arm/mach-omap1/board-innovator.c | 50 + arch/arm/mach-omap1/board-nokia770.c | 74 +- arch/arm/mach-omap1/board-palmte.c | 1 arch/arm/mach-omap1/board-palmz71.c | 11 arch/arm/mach-omap1/board-sx1-mmc.c | 80 -- arch/arm/mach-omap1/board-sx1.c | 10 arch/arm/mach-omap1/board-voiceblue.c | 10 arch/arm/mach-omap1/clock.h | 3 arch/arm/mach-omap1/devices.c | 90 ++ arch/arm/mach-omap2/Makefile | 15 arch/arm/mach-omap2/board-2430sdp.c | 48 + arch/arm/mach-omap2/board-apollon.c | 11 arch/arm/mach-omap2/board-generic.c | 11 arch/arm/mach-omap2/board-h4.c | 11 arch/arm/mach-omap2/board-ldp.c | 40 + arch/arm/mach-omap2/board-omap3beagle.c | 90 ++ arch/arm/mach-omap2/board-omap3pandora.c | 32 + arch/arm/mach-omap2/board-overo.c | 43 + arch/arm/mach-omap2/clock24xx.h | 9 arch/arm/mach-omap2/clock34xx.h | 10 arch/arm/mach-omap2/devices.c | 169 ++++ arch/arm/mach-omap2/mmc-twl4030.c | 408 +++++++++ arch/arm/mach-omap2/mmc-twl4030.h | 29 + arch/arm/plat-omap/devices.c | 225 +---- arch/arm/plat-omap/include/mach/board-h2.h | 6 arch/arm/plat-omap/include/mach/board.h | 22 arch/arm/plat-omap/include/mach/control.h | 17 arch/arm/plat-omap/include/mach/mmc.h | 74 ++ drivers/mmc/host/Kconfig | 11 drivers/mmc/host/Makefile | 1 drivers/mmc/host/omap.c | 7 drivers/mmc/host/omap_hsmmc.c | 1242 ++++++++++++++++++++++++++++ 36 files changed, 2536 insertions(+), 548 deletions(-) create mode 100644 arch/arm/mach-omap2/mmc-twl4030.c create mode 100644 arch/arm/mach-omap2/mmc-twl4030.h create mode 100644 drivers/mmc/host/omap_hsmmc.c
Signature · 1 line
Signature
Tony Lindgren
maintainerPATCH 1/5 omap mmc: Remove broken MMC init code
Most of the omap1 MMC boards got broken by an earlier patch 138ab9f8321f67c71984ca43222efa71b0a0a0a9. If you look closely, the MMC init funtions are pretty much just stubs.
Remove broken init code to make room for cleaner MMC init code.
--- arch/arm/mach-omap1/board-h2-mmc.c | 86 -------------------------------- arch/arm/mach-omap1/board-h2.c | 10 ---- arch/arm/mach-omap1/board-h3-mmc.c | 90 --------------------------------- arch/arm/mach-omap1/board-h3.c | 10 ---- arch/arm/mach-omap1/board-palmte.c | 1 arch/arm/mach-omap1/board-palmz71.c | 11 ---- arch/arm/mach-omap1/board-sx1-mmc.c | 49 ------------------ arch/arm/mach-omap1/board-sx1.c | 10 ---- arch/arm/mach-omap1/board-voiceblue.c | 10 ---- arch/arm/mach-omap2/board-apollon.c | 11 ---- arch/arm/mach-omap2/board-generic.c | 11 ---- arch/arm/mach-omap2/board-h4.c | 11 ---- 12 files changed, 1 insertions(+), 309 deletions(-)
arch/arm/mach-omap1/board-h2-mmc.c +0 -86
@@ -15,91 +15,6 @@#include <mach/mmc.h> #include <mach/gpio.h> -#ifdef CONFIG_MMC_OMAP -static int slot_cover_open; -static struct device *mmc_device; - -static int h2_mmc_set_power (struct device *dev,int slot,int power_on, -int vdd) -{ -#ifdef CONFIG_MMC_DEBUG -dev_dbg (dev,"Set slot %d power: %s (vdd %d)\n" , slot +1 , - power_on ?"on" :"off" , vdd); -#endif -if (slot !=0 ) { -dev_err (dev,"No such slot %d\n" , slot +1 ); -return -ENODEV ; - } - -return 0 ; -} - -static int h2_mmc_set_bus_mode (struct device *dev,int slot,int bus_mode) -{ -#ifdef CONFIG_MMC_DEBUG -dev_dbg (dev,"Set slot %d bus_mode %s\n" , slot +1 , - bus_mode ==MMC_BUSMODE_OPENDRAIN ?"open-drain" :"push-pull" ); -#endif -if (slot !=0 ) { -dev_err (dev,"No such slot %d\n" , slot +1 ); -return -ENODEV ; - } - -return 0 ; -} - -static int h2_mmc_get_cover_state (struct device *dev,int slot) -{ -BUG_ON (slot !=0 ); - -return slot_cover_open; -} - -void h2_mmc_slot_cover_handler (void *arg,int state) -{ -if (mmc_device ==NULL ) -return ; - - slot_cover_open = state; -omap_mmc_notify_cover_event (mmc_device,0 , state); -} - -static int h2_mmc_late_init (struct device *dev) -{ -int ret =0 ; - - mmc_device = dev; - -return ret; -} - -static void h2_mmc_cleanup (struct device *dev) -{ -} - -static struct omap_mmc_platform_data h2_mmc_data = { - .nr_slots =1 , - .switch_slot =NULL , - .init = h2_mmc_late_init, - .cleanup = h2_mmc_cleanup, - .slots[0 ] = { - .set_power = h2_mmc_set_power, - .set_bus_mode = h2_mmc_set_bus_mode, - .get_ro =NULL , - .get_cover_state = h2_mmc_get_cover_state, - .ocr_mask =MMC_VDD_28_29 |MMC_VDD_30_31 | -MMC_VDD_32_33 |MMC_VDD_33_34 , - .name ="mmcblk" , - }, -}; - -void __init h2_mmc_init (void ) -{ -omap_set_mmc_info (1 , &h2_mmc_data); -} - -#else -void __init h2_mmc_init (void ) { }
@@ -107,4 +22,3 @@ void __init h2_mmc_init(void)void h2_mmc_slot_cover_handler (void *arg,int state) { } -#endif
arch/arm/mach-omap1/board-h2.c +0 -10
@@ -378,15 +378,6 @@ static struct omap_usb_config h2_usb_config __initdata = { .pins[1] = 3, }; -static struct omap_mmc_config h2_mmc_config__initdata = { - .mmc[0 ] = { - .enabled =1 , - .wire4 =1 , - }, -}; - -extern struct omap_mmc_platform_data h2_mmc_data; -static struct omap_uart_config h2_uart_config__initdata = { .enabled_uarts = ((1 <<0 ) | (1 <<1 ) | (1 <<2 )), };
@@ -397,7 +388,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {static struct omap_board_config_kernel h2_config[]__initdata = { {OMAP_TAG_USB , &h2_usb_config }, - {OMAP_TAG_MMC , &h2_mmc_config }, {OMAP_TAG_UART , &h2_uart_config }, {OMAP_TAG_LCD , &h2_lcd_config }, };
arch/arm/mach-omap1/board-h3-mmc.c +0 -90
99 lines not on this page · raw message
arch/arm/mach-omap1/board-h3.c +0 -10
@@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = { .pins[1] = 3, }; -static struct omap_mmc_config h3_mmc_config__initdata = { - .mmc[0 ] = { - .enabled =1 , - .wire4 =1 , - }, -}; - -extern struct omap_mmc_platform_data h3_mmc_data; -static struct omap_uart_config h3_uart_config__initdata = { .enabled_uarts = ((1 <<0 ) | (1 <<1 ) | (1 <<2 )), };
@@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {static struct omap_board_config_kernel h3_config[]__initdata = { {OMAP_TAG_USB , &h3_usb_config }, - {OMAP_TAG_MMC , &h3_mmc_config }, {OMAP_TAG_UART , &h3_uart_config }, {OMAP_TAG_LCD , &h3_lcd_config }, };
arch/arm/mach-omap1/board-palmte.c +0 -1
@@ -316,7 +316,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)static struct omap_board_config_kernel palmte_config[]__initdata = { {OMAP_TAG_USB , &palmte_usb_config }, - {OMAP_TAG_MMC , &palmte_mmc_config }, {OMAP_TAG_LCD , &palmte_lcd_config }, {OMAP_TAG_UART , &palmte_uart_config }, };
arch/arm/mach-omap1/board-palmz71.c +0 -11
@@ -267,16 +267,6 @@ static struct omap_usb_config palmz71_usb_config __initdata = { .pins[0] = 2, }; -static struct omap_mmc_config palmz71_mmc_config__initdata = { - .mmc[0 ] = { - .enabled =1 , - .wire4 =0 , - .wp_pin =PALMZ71_MMC_WP_GPIO , - .power_pin =-1 , - .switch_pin =PALMZ71_MMC_IN_GPIO , - }, -}; -static struct omap_lcd_config palmz71_lcd_config__initdata = { .ctrl_name ="internal" , };
@@ -287,7 +277,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {static struct omap_board_config_kernel palmz71_config[]__initdata = { {OMAP_TAG_USB , &palmz71_usb_config}, - {OMAP_TAG_MMC , &palmz71_mmc_config}, {OMAP_TAG_LCD , &palmz71_lcd_config}, {OMAP_TAG_UART , &palmz71_uart_config}, };
arch/arm/mach-omap1/board-sx1-mmc.c +0 -49
59 lines not on this page · raw message
arch/arm/mach-omap1/board-sx1.c +0 -10
@@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = { .pins[2] = 0, }; -/*----------- MMC -------------------------*/ - -static struct omap_mmc_config sx1_mmc_config__initdata = { - .mmc [0 ] = { - .enabled =1 , - .wire4 =0 , - }, -}; -/*----------- LCD -------------------------*/ static struct platform_device sx1_lcd_device = {
@@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {static struct omap_board_config_kernel sx1_config[]__initdata = { {OMAP_TAG_USB , &sx1_usb_config }, - {OMAP_TAG_MMC , &sx1_mmc_config }, {OMAP_TAG_LCD , &sx1_lcd_config }, {OMAP_TAG_UART , &sx1_uart_config }, };
arch/arm/mach-omap1/board-voiceblue.c +1 -9
@@ -15,6 +15,7 @@#include <linux/delay.h> #include <linux/platform_device.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/notifier.h>
@@ -140,21 +141,12 @@ static struct omap_usb_config voiceblue_usb_config __initdata = { .pins[2] = 6, }; -static struct omap_mmc_config voiceblue_mmc_config__initdata = { - .mmc[0 ] = { - .enabled =1 , - .power_pin =2 , - .switch_pin =-1 , - }, -}; -static struct omap_uart_config voiceblue_uart_config__initdata = { .enabled_uarts = ((1 <<0 ) | (1 <<1 ) | (1 <<2 )), };static struct omap_board_config_kernel voiceblue_config[] = { {OMAP_TAG_USB , &voiceblue_usb_config }, - {OMAP_TAG_MMC , &voiceblue_mmc_config }, {OMAP_TAG_UART , &voiceblue_uart_config }, };
arch/arm/mach-omap2/board-apollon.c +0 -11
@@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = { .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), }; -static struct omap_mmc_config apollon_mmc_config__initdata = { - .mmc [0 ] = { - .enabled =1 , - .wire4 =1 , - .wp_pin =-1 , - .power_pin =-1 , - .switch_pin =-1 , - }, -}; -static struct omap_usb_config apollon_usb_config__initdata = { .register_dev =1 , .hmc_mode =0x14 ,/* 0:dev 1:host1 2:disable */
@@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {static struct omap_board_config_kernel apollon_config[] = { {OMAP_TAG_UART , &apollon_uart_config }, - {OMAP_TAG_MMC , &apollon_mmc_config }, {OMAP_TAG_USB , &apollon_usb_config }, {OMAP_TAG_LCD , &apollon_lcd_config }, };
arch/arm/mach-omap2/board-generic.c +0 -11
@@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; -static struct omap_mmc_config generic_mmc_config__initdata = { - .mmc [0 ] = { - .enabled =0 , - .wire4 =0 , - .wp_pin =-1 , - .power_pin =-1 , - .switch_pin =-1 , - }, -}; -static struct omap_board_config_kernel generic_config[] = { {OMAP_TAG_UART , &generic_uart_config }, - {OMAP_TAG_MMC , &generic_mmc_config }, };static void __init omap_generic_init (void )
arch/arm/mach-omap2/board-h4.c +0 -11
@@ -373,23 +373,12 @@ static struct omap_uart_config h4_uart_config __initdata = { .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), }; -static struct omap_mmc_config h4_mmc_config__initdata = { - .mmc [0 ] = { - .enabled =1 , - .wire4 =1 , - .wp_pin =-1 , - .power_pin =-1 , - .switch_pin =-1 , - }, -}; -static struct omap_lcd_config h4_lcd_config__initdata = { .ctrl_name ="internal" , };static struct omap_board_config_kernel h4_config[] = { {OMAP_TAG_UART , &h4_uart_config }, - {OMAP_TAG_MMC , &h4_mmc_config }, {OMAP_TAG_LCD , &h4_lcd_config }, };
Tony Lindgren
maintainerPATCH 2/5 omap mmc: Add better MMC low-level init
In reply to Tony LindgrenThis will simplify the MMC low-level init, and make it more flexible to add support for a newer MMC controller in the following patches.
The patch rearranges platform data and gets rid of slot vs controller confusion in the old data structures. Also fix device id numbering in the clock code.
Some code snippets are based on an earlier patch by Russell King <[email protected]>.
--- arch/arm/mach-omap1/board-h2-mmc.c | 63 ++++++++ arch/arm/mach-omap1/board-h2.c | 15 ++ arch/arm/mach-omap1/board-h3-mmc.c | 50 ++++++ arch/arm/mach-omap1/board-innovator.c | 50 +++++- arch/arm/mach-omap1/board-nokia770.c | 74 +++++++-- arch/arm/mach-omap1/board-sx1-mmc.c | 31 +--- arch/arm/mach-omap1/clock.h | 3 arch/arm/mach-omap1/devices.c | 90 +++++++++++ arch/arm/mach-omap2/clock24xx.h | 9 - arch/arm/mach-omap2/clock34xx.h | 10 - arch/arm/mach-omap2/devices.c | 83 ++++++++++ arch/arm/plat-omap/devices.c | 225 ++++------------------------ arch/arm/plat-omap/include/mach/board-h2.h | 6 - arch/arm/plat-omap/include/mach/board.h | 22 --- arch/arm/plat-omap/include/mach/mmc.h | 74 ++++++++- drivers/mmc/host/omap.c | 7 - 16 files changed, 529 insertions(+), 283 deletions(-)
arch/arm/mach-omap1/board-h2-mmc.c +62 -1
@@ -12,13 +12,74 @@* published by the Free Software Foundation. */ +#include <linux/platform_device.h> + +#include <linux/i2c/tps65010.h> +#include <mach/mmc.h> #include <mach/gpio.h> +#if defined(CONFIG_MMC_OMAP ) || defined(CONFIG_MMC_OMAP_MODULE ) + +static int mmc_set_power (struct device *dev,int slot,int power_on, +int vdd) +{ +if (power_on) +gpio_direction_output (H2_TPS_GPIO_MMC_PWR_EN ,1 ); +else +gpio_direction_output (H2_TPS_GPIO_MMC_PWR_EN ,0 ); + +return 0 ; +} + +static int mmc_late_init (struct device *dev) +{ +int ret; + + ret =gpio_request (H2_TPS_GPIO_MMC_PWR_EN ,"MMC power" ); +if (ret <0 ) +return ret; + +gpio_direction_output (H2_TPS_GPIO_MMC_PWR_EN ,0 ); + +return ret; +} + +static void mmc_shutdown (struct device *dev) +{ +gpio_free (H2_TPS_GPIO_MMC_PWR_EN ); +} + +/* +* H2 could use the following functions tested: +* - mmc_get_cover_state that uses OMAP_MPUIO(1) +* - mmc_get_wp that uses OMAP_MPUIO(3) +*/ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots =1 , + .init = mmc_late_init, + .shutdown = mmc_shutdown, + .dma_mask =0xffffffff , + .slots[0 ] = { + .set_power = mmc_set_power, + .ocr_mask =MMC_VDD_28_29 |MMC_VDD_30_31 | +MMC_VDD_32_33 |MMC_VDD_33_34 , + .name ="mmcblk" , + }, +}; + +static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC ]; +void __init h2_mmc_init (void ) { + mmc_data[0 ] = &mmc1_data; +omap1_init_mmc (mmc_data,OMAP16XX_NR_MMC ); } -void h2_mmc_slot_cover_handler (void *arg,int state) +#else + +void __init h2_mmc_init (void ) { } + +#endif
arch/arm/mach-omap1/board-h2.c +15 -0
@@ -345,10 +345,25 @@ static void __init h2_init_smc91x(void) } } +static int tps_setup (struct i2c_client *client,void *context) +{ +tps65010_config_vregs1 (TPS_LDO2_ENABLE |TPS_VLDO2_3_0V | +TPS_LDO1_ENABLE |TPS_VLDO1_3_0V ); + +return 0 ; +} + +static struct tps65010_board tps_board = { + .base =H2_TPS_GPIO_BASE , + .outmask =0x0f , + .setup = tps_setup, +}; +static struct i2c_board_info __initdata h2_i2c_board_info[] = { {I2C_BOARD_INFO ("tps65010" ,0x48 ), .irq =OMAP_GPIO_IRQ (58 ), + .platform_data = &tps_board, }, {I2C_BOARD_INFO ("isp1301_omap" ,0x2d ), .irq =OMAP_GPIO_IRQ (2 ),
arch/arm/mach-omap1/board-h3-mmc.c +49 -1
62 lines not on this page · raw message
arch/arm/mach-omap1/board-innovator.c +42 -8
77 lines not on this page · raw message
arch/arm/mach-omap1/board-nokia770.c +59 -15
97 lines not on this page · raw message
arch/arm/mach-omap1/board-sx1-mmc.c +11 -20
@@ -12,30 +12,20 @@* published by the Free Software Foundation. */ +#include <linux/platform_device.h> +#include <mach/hardware.h> #include <mach/mmc.h> #include <mach/gpio.h> -#ifdef CONFIG_MMC_OMAP -static int slot_cover_open; -static struct device *mmc_device; +#if defined(CONFIG_MMC_OMAP ) || defined(CONFIG_MMC_OMAP_MODULE ) -static int sx1_mmc_set_power (struct device *dev,int slot,int power_on, +static int mmc_set_power (struct device *dev,int slot,int power_on,int vdd) {int err;u8 dat =0 ; -#ifdef CONFIG_MMC_DEBUG -dev_dbg (dev,"Set slot %d power: %s (vdd %d)\n" , slot +1 , - power_on ?"on" :"off" , vdd); -#endif - -if (slot !=0 ) { -dev_err (dev,"No such slot %d\n" , slot +1 ); -return -ENODEV ; - } - err =sx1_i2c_read_byte (SOFIA_I2C_ADDR ,SOFIA_POWER1_REG , &dat);if (err <0 )return err;
@@ -48,19 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); } -static struct omap_mmc_platform_data sx1_mmc_data = { +/* Cover switch is at OMAP_MPUIO(3) */ +static struct omap_mmc_platform_data mmc1_data = { .nr_slots =1 , .slots[0 ] = { - .set_power = sx1_mmc_set_power, + .set_power = mmc_set_power, .ocr_mask =MMC_VDD_28_29 |MMC_VDD_30_31 |MMC_VDD_32_33 |MMC_VDD_33_34 , .name ="mmcblk" , }, }; +static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC ]; +void __init sx1_mmc_init (void ) { -omap_set_mmc_info (1 , &sx1_mmc_data); + mmc_data[0 ] = &mmc1_data; +omap1_init_mmc (mmc_data,OMAP15XX_NR_MMC ); }#else
@@ -69,7 +63,4 @@ void __init sx1_mmc_init(void) { } -void sx1_mmc_slot_cover_handler (void *arg,int state) -{ -}#endif
arch/arm/mach-omap1/clock.h +1 -2
@@ -705,7 +705,6 @@ static struct clk bclk_16xx = {static struct clk mmc1_ck = { .name ="mmc_ck" , - .id =1 ,/* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate =48000000 ,
@@ -720,7 +719,7 @@ static struct clk mmc1_ck = {static struct clk mmc2_ck = { .name ="mmc_ck" , - .id =2 , + .id =1 ,/* Functional clock is direct from ULPD, interface clock is ARMPER */ .parent = &armper_ck.clk, .rate =48000000 ,
arch/arm/mach-omap1/devices.c +90 -0
102 lines not on this page · raw message
arch/arm/mach-omap2/clock24xx.h +3 -6
@@ -2522,7 +2522,6 @@ static struct clk usbhs_ick = {static struct clk mmchs1_ick = { .name ="mmchs_ick" , - .id =1 , .parent = &l4_ck, .flags =CLOCK_IN_OMAP243X , .clkdm_name ="core_l4_clkdm" ,
@@ -2533,7 +2532,6 @@ static struct clk mmchs1_ick = {static struct clk mmchs1_fck = { .name ="mmchs_fck" , - .id =1 , .parent = &func_96m_ck, .flags =CLOCK_IN_OMAP243X , .clkdm_name ="core_l3_clkdm" ,
@@ -2544,7 +2542,7 @@ static struct clk mmchs1_fck = {static struct clk mmchs2_ick = { .name ="mmchs_ick" , - .id =2 , + .id =1 , .parent = &l4_ck, .flags =CLOCK_IN_OMAP243X , .clkdm_name ="core_l4_clkdm" ,
@@ -2555,7 +2553,7 @@ static struct clk mmchs2_ick = {static struct clk mmchs2_fck = { .name ="mmchs_fck" , - .id =2 , + .id =1 , .parent = &func_96m_ck, .flags =CLOCK_IN_OMAP243X , .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,OMAP24XX_CM_FCLKEN2 ),
@@ -2595,7 +2593,6 @@ static struct clk mdm_intc_ick = {static struct clk mmchsdb1_fck = { .name ="mmchsdb_fck" , - .id =1 , .parent = &func_32k_ck, .flags =CLOCK_IN_OMAP243X , .clkdm_name ="core_l4_clkdm" ,
@@ -2606,7 +2603,7 @@ static struct clk mmchsdb1_fck = {static struct clk mmchsdb2_fck = { .name ="mmchsdb_fck" , - .id =2 , + .id =1 , .parent = &func_32k_ck, .flags =CLOCK_IN_OMAP243X , .clkdm_name ="core_l4_clkdm" ,
arch/arm/mach-omap2/clock34xx.h +4 -6
@@ -1374,7 +1374,7 @@ static struct clk core_96m_fck = {static struct clk mmchs3_fck = { .name ="mmchs_fck" , - .id =3 , + .id =2 , .parent = &core_96m_fck, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_FCLKEN1 ), .enable_bit =OMAP3430ES2_EN_MMC3_SHIFT ,
@@ -1385,7 +1385,7 @@ static struct clk mmchs3_fck = {static struct clk mmchs2_fck = { .name ="mmchs_fck" , - .id =2 , + .id =1 , .parent = &core_96m_fck, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_FCLKEN1 ), .enable_bit =OMAP3430_EN_MMC2_SHIFT ,
@@ -1406,7 +1406,6 @@ static struct clk mspro_fck = {static struct clk mmchs1_fck = { .name ="mmchs_fck" , - .id =1 , .parent = &core_96m_fck, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_FCLKEN1 ), .enable_bit =OMAP3430_EN_MMC1_SHIFT ,
@@ -1722,7 +1721,7 @@ static struct clk usbtll_ick = {static struct clk mmchs3_ick = { .name ="mmchs_ick" , - .id =3 , + .id =2 , .parent = &core_l4_ick, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_ICLKEN1 ), .enable_bit =OMAP3430ES2_EN_MMC3_SHIFT ,
@@ -1774,7 +1773,7 @@ static struct clk des2_ick = {static struct clk mmchs2_ick = { .name ="mmchs_ick" , - .id =2 , + .id =1 , .parent = &core_l4_ick, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_ICLKEN1 ), .enable_bit =OMAP3430_EN_MMC2_SHIFT ,
@@ -1785,7 +1784,6 @@ static struct clk mmchs2_ick = {static struct clk mmchs1_ick = { .name ="mmchs_ick" , - .id =1 , .parent = &core_l4_ick, .enable_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_ICLKEN1 ), .enable_bit =OMAP3430_EN_MMC1_SHIFT ,
arch/arm/mach-omap2/devices.c +83 -0
95 lines not on this page · raw message
arch/arm/plat-omap/devices.c +35 -190
244 lines not on this page · raw message
arch/arm/plat-omap/include/mach/board-h2.h +3 -3
@@ -29,13 +29,13 @@#ifndef __ASM_ARCH_OMAP_H2_H#define __ASM_ARCH_OMAP_H2_H -/* Placeholder for H2 specific defines */ -/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ #define OMAP1610_ETHR_START 0x04000300 +#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) +# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3) +extern void h2_mmc_init (void ); -extern void h2_mmc_slot_cover_handler (void *arg,int state);#endif /* __ASM_ARCH_OMAP_H2_H */
arch/arm/plat-omap/include/mach/board.h +0 -22
@@ -16,7 +16,6 @@/* Different peripheral ids */ #define OMAP_TAG_CLOCK 0x4f01 -#define OMAP_TAG_MMC 0x4f02#define OMAP_TAG_SERIAL_CONSOLE 0x4f03#define OMAP_TAG_USB 0x4f04#define OMAP_TAG_LCD 0x4f05
@@ -35,27 +34,6 @@ struct omap_clock_config {u8 system_clock_type; }; -struct omap_mmc_conf { -unsigned enabled:1 ; -/* nomux means "standard" muxing is wrong on this board, and that -* board-specific code handled it before common init logic. -*/ -unsigned nomux:1 ; -/* switch pin can be for card detect (default) or card cover */ -unsigned cover:1 ; -/* 4 wire signaling is optional, and is only used for SD/SDIO */ -unsigned wire4:1 ; -/* use the internal clock */ -unsigned internal_clock:1 ; -s16 power_pin; -s16 switch_pin; -s16 wp_pin; -}; - -struct omap_mmc_config { -struct omap_mmc_conf mmc[2 ]; -}; -struct omap_serial_console_config {u8 console_uart;u32 console_speed;
arch/arm/plat-omap/include/mach/mmc.h +68 -6
104 lines not on this page · raw message
drivers/mmc/host/omap.c +4 -3
@@ -1015,7 +1015,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data }if (is_read) { -if (host->id ==1 ) { +if (host->id ==0 ) { sync_dev =OMAP_DMA_MMC_RX ; dma_dev_name ="MMC1 read" ; }else {
@@ -1023,7 +1023,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data dma_dev_name ="MMC2 read" ; } }else { -if (host->id ==1 ) { +if (host->id ==0 ) { sync_dev =OMAP_DMA_MMC_TX ; dma_dev_name ="MMC1 write" ; }else {
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) host->slots[id] = slot; mmc->caps =0 ; -if (host->pdata->conf.wire4) +if (host->pdata->slots[id].wire4) mmc->caps |=MMC_CAP_4_BIT_DATA ; mmc->ops = &mmc_omap_ops;
@@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev) host->irq = irq; host->use_dma =1 ; + host->dev->dma_mask = &pdata->dma_mask; host->dma_ch =-1 ; host->irq = irq;
Re: [PATCH 2/5] omap mmc: Add better MMC low-level init
Quoted 4 lines · Tony Lindgren
arch/arm/mach-omap1/board-h2-mmc.c +0
-0
[snip]
Quoted 4 lines
arch/arm/mach-omap1/board-h2-mmc.c +4
-0+static void mmc_shutdown (struct device *dev) +{ +gpio_free (H2_TPS_GPIO_MMC_PWR_EN ); +}
arch/arm/mach-omap1/board-h2-mmc.c
Quoted 10 lines
arch/arm/mach-omap1/board-h2-mmc.c +10
-0+ +/* +* H2 could use the following functions tested: +* - mmc_get_cover_state that uses OMAP_MPUIO(1) +* - mmc_get_wp that uses OMAP_MPUIO(3) +*/ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots =1 , + .init = mmc_late_init, + .shutdown = mmc_shutdown,
It seems that shutdown is no-op, so what about patch below?
arch/arm/mach-omap1/board-h2-mmc.c +4 -10
@@ -24,19 +24,13 @@static int mmc_set_power (struct device *dev,int slot,int power_on,int vdd) { -if (power_on) -gpio_direction_output (H2_TPS_GPIO_MMC_PWR_EN ,1 ); -else -gpio_direction_output (H2_TPS_GPIO_MMC_PWR_EN ,0 ); - +gpio_set_value (H2_TPS_GPIO_MMC_PWR_EN , power_on);return 0 ; }static int mmc_late_init (struct device *dev) { -int ret; - - ret =gpio_request (H2_TPS_GPIO_MMC_PWR_EN ,"MMC power" ); +int ret =gpio_request (H2_TPS_GPIO_MMC_PWR_EN ,"MMC power" );if (ret <0 )return ret;
@@ -45,7 +39,7 @@ static int mmc_late_init(struct device *dev)return ret; } -static void mmc_shutdown (struct device *dev) +static void mmc_cleanup (struct device *dev) {gpio_free (H2_TPS_GPIO_MMC_PWR_EN ); }
@@ -58,7 +52,7 @@ static void mmc_shutdown(struct device *dev)static struct omap_mmc_platform_data mmc1_data = { .nr_slots =1 , .init = mmc_late_init, - .shutdown = mmc_shutdown, + .cleanup = mmc_cleanup, .dma_mask =0xffffffff , .slots[0 ] = { .set_power = mmc_set_power,
Re: [PATCH 2/5] omap mmc: Add better MMC low-level init
Quoted 6 lines · Ladislav Michl
Quoted 4 lines · Tony Lindgren
arch/arm/mach-omap1/board-h2-mmc.c +0
-0[snip]
Quoted 15 lines
Quoted 4 lines
arch/arm/mach-omap1/board-h2-mmc.c +4
-0+static void mmc_shutdown (struct device *dev) +{ +gpio_free (H2_TPS_GPIO_MMC_PWR_EN ); +}arch/arm/mach-omap1/board-h2-mmc.c
Quoted 10 lines
arch/arm/mach-omap1/board-h2-mmc.c +10
-0+ +/* +* H2 could use the following functions tested: +* - mmc_get_cover_state that uses OMAP_MPUIO(1) +* - mmc_get_wp that uses OMAP_MPUIO(3) +*/ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots =1 , + .init = mmc_late_init, + .shutdown = mmc_shutdown,It seems that shutdown is no-op, so what about patch below?
After all, lets remove some unused fields.
arch/arm/plat-omap/include/mach/mmc.h +0 -5
@@ -51,7 +51,6 @@ struct omap_mmc_platform_data {* not supported */ int (* init)(struct device *dev);void (* cleanup)(struct device *dev); -void (* shutdown)(struct device *dev);/* To handle board related suspend/resume functionality for MMC */ int (*suspend)(struct device *dev,int slot);
@@ -77,10 +76,6 @@ struct omap_mmc_platform_data {/* use the internal clock */ unsigned internal_clock:1; -s16 power_pin; - -int switch_pin;/* gpio (card detect) */ -int gpio_wp;/* gpio (write protect) */ int (* set_bus_mode)(struct device *dev,int slot,int bus_mode);int (* set_power)(struct device *dev,int slot,int power_on,int vdd);
drivers/mmc/host/omap.c +0 -2
@@ -157,8 +157,6 @@ struct mmc_omap_host {struct timer_list dma_timer;unsigned dma_len; -short power_pin; -struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS ];struct mmc_omap_slot *current_slot;spinlock_t slot_lock;
Tony Lindgren
maintainerRe: [PATCH 2/5] omap mmc: Add better MMC low-level init
Quoted 40 lines · Ladislav Michl
Quoted 6 lines · Ladislav Michl
Quoted 4 lines · Tony Lindgren
arch/arm/mach-omap1/board-h2-mmc.c +0
-0[snip]
Quoted 15 lines
Quoted 4 lines
arch/arm/mach-omap1/board-h2-mmc.c +4
-0+static void mmc_shutdown (struct device *dev) +{ +gpio_free (H2_TPS_GPIO_MMC_PWR_EN ); +}arch/arm/mach-omap1/board-h2-mmc.c
Quoted 10 lines
arch/arm/mach-omap1/board-h2-mmc.c +10
-0+ +/* +* H2 could use the following functions tested: +* - mmc_get_cover_state that uses OMAP_MPUIO(1) +* - mmc_get_wp that uses OMAP_MPUIO(3) +*/ +static struct omap_mmc_platform_data mmc1_data = { + .nr_slots =1 , + .init = mmc_late_init, + .shutdown = mmc_shutdown,It seems that shutdown is no-op, so what about patch below?
After all, lets remove some unused fields.
Signed-off-by Ladislav Michl <[email protected]>arch/arm/plat-omap/include/mach/mmc.h +0
-1@@ -51,7 +51,6 @@ struct omap_mmc_platform_data {* not supported */ int (* init)(struct device *dev);void (* cleanup)(struct device *dev); -void (* shutdown)(struct device *dev);/* To handle board related suspend/resume functionality for MMC */ int (*suspend)(struct device *dev,int slot);
arch/arm/plat-omap/include/mach/mmc.h struct omap_mmc_platform_data { · line 81
Quoted 10 lines
arch/arm/plat-omap/include/mach/mmc.h +0
-4@@ -77,10 +76,6 @@ struct omap_mmc_platform_data {/* use the internal clock */ unsigned internal_clock:1; -s16 power_pin; - -int switch_pin;/* gpio (card detect) */ -int gpio_wp;/* gpio (write protect) */ int (* set_bus_mode)(struct device *dev,int slot,int bus_mode);int (* set_power)(struct device *dev,int slot,int power_on,int vdd);
Hmm, aren't switch_pin and gpio_wp used at least in the mmc-twl4030.c?
I guess they could be internal to mmc-twl4030.c if not used in the drivers directly.
Quoted 6 lines
drivers/mmc/host/omap.c +0
-0
drivers/mmc/host/omap.c struct mmc_omap_host { · line 162
Quoted 8 lines
drivers/mmc/host/omap.c +0
-2@@ -157,8 +157,6 @@ struct mmc_omap_host {struct timer_list dma_timer;unsigned dma_len; -short power_pin; -struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS ];struct mmc_omap_slot *current_slot;spinlock_t slot_lock;
Looks like power_pin could go though.
Tony
Re: [PATCH 2/5] omap mmc: Add better MMC low-level init
Quoted 21 lines · Tony Lindgren
Quoted 21 lines
arch/arm/plat-omap/include/mach/mmc.h +0
-5@@ -51,7 +51,6 @@ struct omap_mmc_platform_data {* not supported */ int (* init)(struct device *dev);void (* cleanup)(struct device *dev); -void (* shutdown)(struct device *dev);/* To handle board related suspend/resume functionality for MMC */ int (*suspend)(struct device *dev,int slot);@@ -77,10 +76,6 @@ struct omap_mmc_platform_data {/* use the internal clock */ unsigned internal_clock:1; -s16 power_pin; - -int switch_pin;/* gpio (card detect) */ -int gpio_wp;/* gpio (write protect) */
Quoted 5 lines
arch/arm/plat-omap/include/mach/mmc.h struct omap_mmc_platform_data { · line 81
Quoted 2 lines
arch/arm/plat-omap/include/mach/mmc.h +0
-0int (* set_bus_mode)(struct device *dev,int slot,int bus_mode);int (* set_power)(struct device *dev,int slot,int power_on,int vdd);Hmm, aren't
switch_pinandgpio_wpused at least in themmc-twl4030.c?
Yes, they are. I missed them completely. Sorry.
Quoted 2 lines
I guess they could be internal to
mmc-twl4030.cif not used in the drivers directly.
They could, but that's a bit more complicated. Will look at it later.
Quoted 8 lines
Quoted 8 lines
drivers/mmc/host/omap.c +0
-0@@ -157,8 +157,6 @@ struct mmc_omap_host {struct timer_list dma_timer;unsigned dma_len;
Quoted 8 lines
drivers/mmc/host/omap.c struct mmc_omap_host { · line 162
Quoted 6 lines
drivers/mmc/host/omap.c +0
-2-short power_pin; -struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS ];struct mmc_omap_slot *current_slot;spinlock_t slot_lock;Looks like
power_pincould go though.
Updated patch follows
arch/arm/plat-omap/include/mach/mmc.h +0 -1
@@ -79,7 +79,6 @@ struct omap_mmc_platform_data {/* use the internal clock */ unsigned internal_clock:1; -s16 power_pin;int switch_pin;/* gpio (card detect) */ int gpio_wp;/* gpio (write protect) */
drivers/mmc/host/omap.c +0 -2
@@ -157,8 +157,6 @@ struct mmc_omap_host {struct timer_list dma_timer;unsigned dma_len; -short power_pin; -struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS ];struct mmc_omap_slot *current_slot;spinlock_t slot_lock;
Tony Lindgren
maintainerPATCH 2/5 omap mmc: Add better MMC low-level init
This patch has been applied to the linux-omap
by youw fwiendly patch wobot.
Commit: ed39a47fbc83f2c0d82aaadca7dec9fe8f061f83
PatchWorks
http://patchwork.kernel.org/patch/13766/
Re: [PATCH 2/5] omap mmc: Add better MMC low-level init
In reply to Tony LindgrenQuoted 3 lines · Tony Lindgren
This will simplify the MMC low-level init, and make it more flexible to add support for a newer MMC controller in the following patches.
Simple simplification...
arch/arm/mach-omap1/board-h3-mmc.c +1 -5
@@ -24,11 +24,7 @@static int mmc_set_power (struct device *dev,int slot,int power_on,int vdd) { -if (power_on) -gpio_direction_output (H3_TPS_GPIO_MMC_PWR_EN ,1 ); -else -gpio_direction_output (H3_TPS_GPIO_MMC_PWR_EN ,0 ); - +gpio_set_value (H3_TPS_GPIO_MMC_PWR_EN , power_on);return 0 ; }
arch/arm/mach-omap1/board-nokia770.c +1 -5
@@ -223,11 +223,7 @@ static struct omap_usb_config nokia770_usb_config __initdata = {static int nokia770_mmc_set_power (struct device *dev,int slot,int power_on,int vdd) { -if (power_on) -gpio_set_value (NOKIA770_GPIO_MMC_POWER ,1 ); -else -gpio_set_value (NOKIA770_GPIO_MMC_POWER ,0 ); - +gpio_set_value (NOKIA770_GPIO_MMC_POWER , power_on);return 0 ; }
Tony Lindgren
maintainerPATCH 3/5 omap mmc: Add low-level initialization for hsmmc controller
In reply to Tony LindgrenAdd low-level initialization for hsmmc controller. Merged into this patch patch are various improvments and board support by Grazvydas Ignotas and David Brownell.
Also change wire4 to be wires, as some newer controllers support 8 data lines.
--- arch/arm/mach-omap1/board-innovator.c | 2 arch/arm/mach-omap1/devices.c | 4 arch/arm/mach-omap2/Makefile | 15 + arch/arm/mach-omap2/board-2430sdp.c | 48 +++ arch/arm/mach-omap2/board-ldp.c | 40 +++ arch/arm/mach-omap2/board-omap3beagle.c | 90 ++++++ arch/arm/mach-omap2/board-omap3pandora.c | 32 ++ arch/arm/mach-omap2/board-overo.c | 43 +++ arch/arm/mach-omap2/devices.c | 3 arch/arm/mach-omap2/mmc-twl4030.c | 408 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/mmc-twl4030.h | 29 ++ arch/arm/plat-omap/include/mach/control.h | 17 + arch/arm/plat-omap/include/mach/mmc.h | 16 + drivers/mmc/host/omap.c | 2 14 files changed, 730 insertions(+), 19 deletions(-) create mode 100644 arch/arm/mach-omap2/mmc-twl4030.c create mode 100644 arch/arm/mach-omap2/mmc-twl4030.h
arch/arm/mach-omap1/board-innovator.c +1 -1
@@ -385,7 +385,7 @@ static struct omap_mmc_platform_data mmc1_data = { .nr_slots = 1, .slots[0] = { .set_power = mmc_set_power, - .wire4 = 1, + .wires = 4, .name = "mmcblk", }, };
arch/arm/mach-omap1/devices.c +2 -2
@@ -116,7 +116,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,omap_cfg_reg (P19_1710_MMC_CMDDIR );omap_cfg_reg (P20_1710_MMC_DATDIR0 ); } -if (mmc_controller->slots[0 ].wire4) { +if (mmc_controller->slots[0 ].wires ==4 ) {omap_cfg_reg (MMC_DAT1 );/* NOTE: DAT2 can be on W10 (here) or M15 */ if (!mmc_controller->slots[0 ].nomux)
@@ -132,7 +132,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,omap_cfg_reg (Y10_1610_MMC2_CLK );omap_cfg_reg (R18_1610_MMC2_CLKIN );omap_cfg_reg (W8_1610_MMC2_DAT0 ); -if (mmc_controller->slots[1 ].wire4) { +if (mmc_controller->slots[1 ].wires ==4 ) {omap_cfg_reg (V8_1610_MMC2_DAT1 );omap_cfg_reg (W15_1610_MMC2_DAT2 );omap_cfg_reg (R10_1610_MMC2_DAT3 );
arch/arm/mach-omap2/Makefile +10 -5
@@ -27,10 +27,15 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o +obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ + mmc-twl4030.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o -obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o -obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o -obj-$(CONFIG_MACH_OVERO) += board-overo.o -obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o +obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OVERO) += board-overo.o \ + mmc-twl4030.o +obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ + mmc-twl4030.o
arch/arm/mach-omap2/board-2430sdp.c +48 -0
72 lines not on this page · raw message
arch/arm/mach-omap2/board-ldp.c +39 -1
@@ -21,6 +21,7 @@#include <linux/clk.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> +#include <linux/i2c/twl4030.h> #include <mach/hardware.h> #include <asm/mach-types.h>
@@ -38,6 +39,8 @@#include <asm/delay.h> #include <mach/control.h> +#include "mmc-twl4030.h" +#define SDP3430_SMC91X_CS 3static struct resource ldp_smc911x_resources[] = {
@@ -109,14 +112,48 @@ static struct omap_board_config_kernel ldp_config[] __initdata = { { OMAP_TAG_UART, &ldp_uart_config }, }; +static struct twl4030_gpio_platform_data ldp_gpio_data = { + .gpio_base =OMAP_MAX_GPIO_LINES , + .irq_base =TWL4030_GPIO_IRQ_BASE , + .irq_end =TWL4030_GPIO_IRQ_END , +}; + +static struct twl4030_platform_data ldp_twldata = { + .irq_base =TWL4030_IRQ_BASE , + .irq_end =TWL4030_IRQ_END , + +/* platform_data for children goes here */ + .gpio = &ldp_gpio_data, +}; + +static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { + { +I2C_BOARD_INFO ("twl4030" ,0x48 ), + .flags =I2C_CLIENT_WAKE , + .irq =INT_34XX_SYS_NIRQ , + .platform_data = &ldp_twldata, + }, +}; +static int __init omap_i2c_init (void ) { -omap_register_i2c_bus (1 ,2600 ,NULL ,0 ); +omap_register_i2c_bus (1 ,2600 , ldp_i2c_boardinfo, +ARRAY_SIZE (ldp_i2c_boardinfo));omap_register_i2c_bus (2 ,400 ,NULL ,0 );omap_register_i2c_bus (3 ,400 ,NULL ,0 );return 0 ; } +static struct twl4030_hsmmc_info mmc[]__initdata = { + { + .mmc =1 , + .wires =4 , + .gpio_cd = -EINVAL , + .gpio_wp = -EINVAL , + }, + {}/* Terminator */ +}; +static void __init omap_ldp_init (void ) {omap_i2c_init ();
@@ -124,6 +161,7 @@ static void __init omap_ldp_init(void) omap_board_config = ldp_config; omap_board_config_size =ARRAY_SIZE (ldp_config);omap_serial_init (); +twl4030_mmc_init (mmc); }static void __init omap_ldp_map_io (void )
arch/arm/mach-omap2/board-omap3beagle.c +90 -0
120 lines not on this page · raw message
arch/arm/mach-omap2/board-omap3pandora.c +32 -0
@@ -46,6 +46,8 @@#include <mach/nand.h> #include <mach/mcspi.h> +#include "mmc-twl4030.h" +#define NAND_BLOCK_SIZE SZ_128K#define GPMC_CS0_BASE 0x60#define GPMC_CS_SIZE 0x30
@@ -137,14 +139,44 @@ static void __init omap3pandora_flash_init(void) } } +static struct twl4030_hsmmc_info omap3pandora_mmc[] = { + { + .mmc =1 , + .wires =4 , + .gpio_cd = -EINVAL , + .gpio_wp =126 , + .ext_clock =0 , + }, + { + .mmc =2 , + .wires =4 , + .gpio_cd = -EINVAL , + .gpio_wp =127 , + .ext_clock =1 , + }, + {}/* Terminator */ +}; +static struct omap_uart_config omap3pandora_uart_config__initdata = { .enabled_uarts = (1 <<2 ),/* UART3 */ }; +static int omap3pandora_twl_gpio_setup (struct device *dev, +unsigned gpio,unsigned ngpio) +{ +/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ + omap3pandora_mmc[0 ].gpio_cd = gpio +0 ; + omap3pandora_mmc[1 ].gpio_cd = gpio +1 ; +twl4030_mmc_init (omap3pandora_mmc); + +return 0 ; +} +static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { .gpio_base =OMAP_MAX_GPIO_LINES , .irq_base =TWL4030_GPIO_IRQ_BASE , .irq_end =TWL4030_GPIO_IRQ_END , + .setup = omap3pandora_twl_gpio_setup, };static struct twl4030_usb_data omap3pandora_usb_data = {
arch/arm/mach-omap2/board-overo.c +43 -0
75 lines not on this page · raw message
arch/arm/mach-omap2/devices.c +2 -1
@@ -19,6 +19,7 @@#include <asm/mach-types.h> #include <asm/mach/map.h> +#include <mach/control.h> #include <mach/tc.h> #include <mach/board.h> #include <mach/mux.h>
@@ -311,7 +312,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,omap_cfg_reg (F20_24XX_MMC_DAT0 );omap_cfg_reg (F19_24XX_MMC_DAT_DIR0 );omap_cfg_reg (G18_24XX_MMC_CMD_DIR ); -if (mmc_controller->slots[0 ].wire4) { +if (mmc_controller->slots[0 ].wires ==4 ) {omap_cfg_reg (H14_24XX_MMC_DAT1 );omap_cfg_reg (E19_24XX_MMC_DAT2 );omap_cfg_reg (D19_24XX_MMC_DAT3 );
arch/arm/mach-omap2/mmc-twl4030.c new file +408 -0
408 lines not on this page · raw message
arch/arm/mach-omap2/mmc-twl4030.h new file +29 -0
@@ -0,0 +1,29 @@ +/* +* MMC definitions for OMAP2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +struct twl4030_hsmmc_info { +u8 mmc;/* controller 1/2/3 */ +u8 wires;/* 1/4/8 wires */ +int gpio_cd;/* or -EINVAL */ +int gpio_wp;/* or -EINVAL */ +int ext_clock:1 ;/* use external pin for input clock */ +}; + +#if defined(CONFIG_TWL4030_CORE ) && \ + (defined(CONFIG_MMC_OMAP ) || defined(CONFIG_MMC_OMAP_MODULE ) || \ + defined(CONFIG_MMC_OMAP_HS ) || defined(CONFIG_MMC_OMAP_HS_MODULE )) + +void twl4030_mmc_init (struct twl4030_hsmmc_info *); + +#else + +static inline void twl4030_mmc_init (struct twl4030_hsmmc_info *info) +{ +} + +#endif
arch/arm/plat-omap/include/mach/control.h +17 -0
@@ -74,6 +74,7 @@#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) +#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230)/* 24xx-only CONTROL_GENERAL register offsets */ #define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000)
@@ -140,6 +141,7 @@#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0)#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)/*
@@ -154,11 +156,14 @@* and the security mode (secure, non-secure, don't care) */ /* CONTROL_DEVCONF0 bits */ +#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24)/* MMC1 loop back clock */ #define OMAP24XX_USBSTANDBYCTRL (1 << 15)#define OMAP2_MCBSP2_CLKS_MASK (1 << 6)#define OMAP2_MCBSP1_CLKS_MASK (1 << 2)/* CONTROL_DEVCONF1 bits */ +#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31) +#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6)/* MMC2 loop back clock */ #define OMAP2_MCBSP5_CLKS_MASK (1 << 4)/* > 242x */ #define OMAP2_MCBSP4_CLKS_MASK (1 << 2)/* > 242x */ #define OMAP2_MCBSP3_CLKS_MASK (1 << 0)/* > 242x */
@@ -172,6 +177,18 @@#define OMAP2_SYSBOOT_1_MASK (1 << 1)#define OMAP2_SYSBOOT_0_MASK (1 << 0) +/* CONTROL_PBIAS_LITE bits */ +#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15) +#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11) +#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10) +#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9) +#define OMAP343X_PBIASLITEVMODE1 (1 << 8) +#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7) +#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3) +#define OMAP2_PBIASSPEEDCTRL0 (1 << 2) +#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1) +#define OMAP2_PBIASLITEVMODE0 (1 << 0) +#ifndef __ASSEMBLY__#if defined(CONFIG_ARCH_OMAP2 ) || defined(CONFIG_ARCH_OMAP3 )extern void __iomem *omap_ctrl_base_get (void );
arch/arm/plat-omap/include/mach/mmc.h +8 -8
@@ -61,6 +61,11 @@ struct omap_mmc_platform_data {struct omap_mmc_slot_data { +/* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC; +* 8 wire signaling is also optional, and is used with HSMMC +*/ +u8 wires; +/* * nomux means "standard" muxing is wrong on this board, and * that board-specific code handled it before common init logic.
@@ -70,13 +75,12 @@ struct omap_mmc_platform_data {/* switch pin can be for card detect (default) or card cover */ unsigned cover:1; -/* 4 wire signaling is optional, and is only used for SD/SDIO */ - unsigned wire4:1; -/* use the internal clock */ unsigned internal_clock:1;s16 power_pin; -s16 switch_pin; + +int switch_pin;/* gpio (card detect) */ +int gpio_wp;/* gpio (write protect) */ int (* set_bus_mode)(struct device *dev,int slot,int bus_mode);int (* set_power)(struct device *dev,int slot,int power_on,int vdd);
@@ -111,7 +115,6 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers);void omap2_init_mmc (struct omap_mmc_platform_data **mmc_data,int nr_controllers); -void hsmmc_init (int controller_mask);int omap_mmc_add (int id,unsigned long base,unsigned long size,unsigned int irq,struct omap_mmc_platform_data *data);#else
@@ -123,9 +126,6 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, int nr_controllers) { } -static inline void hsmmc_init (int controller_mask) -{ -}static inline int omap_mmc_add (int id,unsigned long base,unsigned long size,unsigned int irq,struct omap_mmc_platform_data *data) {
drivers/mmc/host/omap.c +1 -1
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) host->slots[id] = slot; mmc->caps =0 ; -if (host->pdata->slots[id].wire4) +if (host->pdata->slots[id].wires >=4 ) mmc->caps |=MMC_CAP_4_BIT_DATA ; mmc->ops = &mmc_omap_ops;
Tony Lindgren
maintainerPATCH 4/5 omap mmc: force MMC module reset on boot
In reply to Tony LindgrenFrom: Kevin Hilman <[email protected]>
The bootloader may leave the MMC in a state which prevents hitting retention. Even when MMC is not compiled in, each MMC module needs to be forced into reset.
--- arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 85 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/devices.c +85 -0
@@ -14,6 +14,7 @@#include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/clk.h> #include <mach/hardware.h> #include <asm/mach-types.h>
@@ -299,6 +300,89 @@ static inline void omap_init_sha1_md5(void) { }/*-------------------------------------------------------------------------*/ +#ifdef CONFIG_ARCH_OMAP3 + +#define MMCHS_SYSCONFIG 0x0010 +#define MMCHS_SYSCONFIG_SWRESET (1 << 1) +#define MMCHS_SYSSTATUS 0x0014 +#define MMCHS_SYSSTATUS_RESETDONE (1 << 0) + +static struct platform_device dummy_pdev = { + .dev = { + .bus = &platform_bus_type, + }, +}; + +/** +* omap_hsmmc_reset() - Full reset of each HS-MMC controller +* +* Ensure that each MMC controller is fully reset. Controllers +* left in an unknown state (by bootloader) may prevent retention +* or OFF-mode. This is especially important in cases where the +* MMC driver is not enabled, _or_ built as a module. +* +* In order for reset to work, interface, functional and debounce +* clocks must be enabled. The debounce clock comes from func_32k_clk +* and is not under SW control, so we only enable i- and f-clocks. +**/ +static void __init omap_hsmmc_reset (void ) +{ +u32 i, nr_controllers =cpu_is_omap34xx () ?OMAP34XX_NR_MMC : +OMAP24XX_NR_MMC ; + +for (i =0 ; i < nr_controllers; i++) { +u32 v, base =0 ; +struct clk *iclk, *fclk; +struct device *dev = &dummy_pdev.dev; + +switch (i) { +case 0 : + base =OMAP2_MMC1_BASE ; +break ; +case 1 : + base =OMAP2_MMC2_BASE ; +break ; +case 2 : + base =OMAP3_MMC3_BASE ; +break ; + } + + dummy_pdev.id = i; + iclk =clk_get (dev,"mmchs_ick" ); +if (iclk &&clk_enable (iclk)) + iclk =NULL ; + + fclk =clk_get (dev,"mmchs_fck" ); +if (fclk &&clk_enable (fclk)) + fclk =NULL ; + +if (!iclk || !fclk) { +printk (KERN_WARNING +"%s: Unable to enable clocks for MMC%d, " +"cannot reset.\n" , __func__, i); +break ; + } + +omap_writel (MMCHS_SYSCONFIG_SWRESET , base +MMCHS_SYSCONFIG ); + v =omap_readl (base +MMCHS_SYSSTATUS ); +while (!(omap_readl (base +MMCHS_SYSSTATUS ) & +MMCHS_SYSSTATUS_RESETDONE )) +cpu_relax (); + +if (fclk) { +clk_disable (fclk); +clk_put (fclk); + } +if (iclk) { +clk_disable (iclk); +clk_put (iclk); + } + } +} +#else +static inline void omap_hsmmc_reset (void ) {} +#endif +#if defined(CONFIG_MMC_OMAP ) || defined(CONFIG_MMC_OMAP_MODULE ) || \ defined(CONFIG_MMC_OMAP_HS ) || defined(CONFIG_MMC_OMAP_HS_MODULE )
@@ -418,6 +502,7 @@ static int __init omap2_init_devices(void)/* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ +omap_hsmmc_reset ();omap_init_mbox ();omap_init_mcspi ();omap_hdq_init ();
Tony Lindgren
maintainerPATCH 5/5 omap mmc: Add new omap hsmmc controller for 2430 and 34xx
In reply to Tony LindgrenFrom: Madhusudhan Chikkature <[email protected]>
Add omap hsmmc controller for 2430 and 34xx.
Note that this controller has different registers compared to the earlier omap MMC controller, so sharing code currently is not possible.
Various updates and fixes from linux-omap list have been merged into this patch.
--- drivers/mmc/host/Kconfig | 11 drivers/mmc/host/Makefile | 1 drivers/mmc/host/omap_hsmmc.c | 1242 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1254 insertions(+), 0 deletions(-) create mode 100644 drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/Kconfig +11 -0
@@ -76,6 +76,17 @@ config MMC_OMAP If unsure, say N. +config MMC_OMAP_HS + tristate "TI OMAP High Speed Multimedia Card Interface support" + depends on (ARCH_OMAP2 && ARCH_OMAP2430) || ARCH_OMAP3 + select TWL4030_CORE + help + This selects the TI OMAP High Speed Multimedia card Interface. + If you have an OMAP2(2430) or OMAP3 board with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on ISA_DMA_API
drivers/mmc/host/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o +obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
drivers/mmc/host/omap_hsmmc.c new file +1242 -0
1,242 lines not on this page · raw message
Re: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx
drivers/mmc/host/omap_hsmmc.c line 254
Quoted 6 lines · On Sun, 07 Dec 2008 13:51:39 -0800 Tony Lindgren <[email protected]> wrote:
drivers/mmc/host/omap_hsmmc.c new file +6
-0+/* +* Unlike OMAP1 controller, the cmdtype does not seem to be based on +* ac, bc, adtc, bcr. Only CMD12 needs a val of 0x3, rest 0x0. +*/ +if (cmd->opcode ==12 ) + cmdtype =0x3 ;
Isn't it more likely that it needs 0x3 for any commands that ends an open ended transfer? I.e. every time cmd == mrq.stop.
drivers/mmc/host/omap_hsmmc.c line 946
Quoted 6 lines
drivers/mmc/host/omap_hsmmc.c new file +6
-0+ host->dbclk =clk_get (&pdev->dev,"mmchsdb_fck" ); +/* +* MMC can still work without debounce clock. +*/ +if (IS_ERR (host->dbclk)) +dev_dbg (mmc_dev (host->mmc),"Failed to get debounce clock\n" );
Perhaps a warning should be printed though, as there could be some problems caused by trying to init a card that is still bouncing.
Quoted 13 lines
drivers/mmc/host/omap_hsmmc.c new file +13
-0+static int omap_mmc_remove (struct platform_device *pdev) +{ +struct mmc_omap_host *host =platform_get_drvdata (pdev); +struct resource *res; +u16 vdd =0 ; + +if (!(OMAP_HSMMC_READ (host->base,HCTL ) &SDVSDET )) { +/* +* Set the vdd back to 3V, +* applicable for dual volt support. +*/ + vdd =fls (host->mmc->ocr_avail) -1 ; +if (omap_mmc_switch_opcond (host, vdd) !=0 )
drivers/mmc/host/omap_hsmmc.c line 1091
Quoted 10 lines
drivers/mmc/host/omap_hsmmc.c new file +10
-0+ host->mmc->ios.vdd = vdd; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (res) +release_mem_region (res->start, res->end - res->start +1 ); + +platform_set_drvdata (pdev,NULL ); +if (host) { +mmc_remove_host (host->mmc);
You can't go fiddling with the voltage and removing the MMIO until you've made sure that there is no more activity on the slot.
Fix the above issues and you can let it go via Russell with a:
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Tony Lindgren
maintainerRe: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx
Hi,
Quoted 12 lines · Pierre Ossman
Review
Quoted 6 lines · On Sun, 07 Dec 2008 13:51:39 -0800 Tony Lindgren <[email protected]> wrote:
(quoted diff) +6
-0+ /* + * Unlike OMAP1 controller, the cmdtype does not seem to be based on + * ac, bc, adtc, bcr. Only CMD12 needs a val of 0x3, rest 0x0. + */ + if (cmd->opcode == 12) + cmdtype = 0x3;Isn't it more likely that it needs
0x3for any commands that ends an open ended transfer? I.e. every time cmd == mrq.stop.
OK, changed and still works :)
Quoted 9 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); + /* + * MMC can still work without debounce clock. + */ + if (IS_ERR(host->dbclk)) + dev_dbg(mmc_dev(host->mmc), "Failed to get debounce clock\n");Perhaps a warning should be printed though, as there could be some problems caused by trying to init a card that is still bouncing.
OK
Quoted 18 lines
Quoted 18 lines
(quoted diff) +18
-0+static int omap_mmc_remove(struct platform_device *pdev) +{ + struct mmc_omap_host *host = platform_get_drvdata(pdev); + struct resource *res; + u16 vdd = 0; + + if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { + /* + * Set the vdd back to 3V, + * applicable for dual volt support. + */ + vdd = fls(host->mmc->ocr_avail) - 1; + if (omap_mmc_switch_opcond(host, vdd) != 0) + host->mmc->ios.vdd = vdd; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res)
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ release_mem_region(res->start, res->end - res->start + 1); + + platform_set_drvdata(pdev, NULL); + if (host) { + mmc_remove_host(host->mmc);You can't go fiddling with the voltage and removing the MMIO until you've made sure that there is no more activity on the slot.
Changed in the attached patch. I've changed the code to reset the controller voltage setting after powering down the socket instead of trying to do it in two earlier places..
Do you have any better suggestions for this? Basically it looks like the controller may fail to detect the next card after unplugging a 1.8V card unless the controller is reset to 3V.
Quoted 3 lines
Fix the above issues and you can let it go via Russell with a:
Acked-by Pierre Ossman <[email protected]>
Thank you for your comments. Care to take a one more look at the attached patch before I add your Ack? I also fixed the remaining checkpatch warnings.
Regards,
Tony
Quoted 1 line
From
f201a545403fdecaf3e2a77359e4adaf803871f5Mon Sep 17 00:00:00 2001
From: Tony Lindgren <[email protected]>
Date: Mon, 29 Dec 2008 16:31:53 +0200
Subject: [PATCH] omap mmc: Add new omap hsmmc controller for 2430 and 34xx, v2
Add omap hsmmc controller for 2430 and 34xx.
Note that this controller has different registers compared to the earlier omap MMC controller, so sharing code currently is not possible.
Various updates and fixes from linux-omap list have been merged into this patch.
drivers/mmc/host/Kconfig +11 -0
@@ -76,6 +76,17 @@ config MMC_OMAP If unsure, say N. +config MMC_OMAP_HS + tristate "TI OMAP High Speed Multimedia Card Interface support" + depends on (ARCH_OMAP2 && ARCH_OMAP2430) || ARCH_OMAP3 + select TWL4030_CORE + help + This selects the TI OMAP High Speed Multimedia card Interface. + If you have an OMAP2(2430) or OMAP3 board with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on ISA_DMA_API
drivers/mmc/host/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o +obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
drivers/mmc/host/omap_hsmmc.c new file +1242 -0
1,242 lines not on this page · raw message
Tony Lindgren
maintainerRe: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx
Quoted 65 lines · Tony Lindgren
Hi,
Quoted 12 lines · Pierre Ossman
Review
Quoted 6 lines · On Sun, 07 Dec 2008 13:51:39 -0800 Tony Lindgren <[email protected]> wrote:
(quoted diff) +6
-0+ /* + * Unlike OMAP1 controller, the cmdtype does not seem to be based on + * ac, bc, adtc, bcr. Only CMD12 needs a val of 0x3, rest 0x0. + */ + if (cmd->opcode == 12) + cmdtype = 0x3;Isn't it more likely that it needs
0x3for any commands that ends an open ended transfer? I.e. every time cmd == mrq.stop.OK, changed and still works :)
Quoted 9 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); + /* + * MMC can still work without debounce clock. + */ + if (IS_ERR(host->dbclk)) + dev_dbg(mmc_dev(host->mmc), "Failed to get debounce clock\n");Perhaps a warning should be printed though, as there could be some problems caused by trying to init a card that is still bouncing.
OK
Quoted 18 lines
Quoted 18 lines
(quoted diff) +18
-0+static int omap_mmc_remove(struct platform_device *pdev) +{ + struct mmc_omap_host *host = platform_get_drvdata(pdev); + struct resource *res; + u16 vdd = 0; + + if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { + /* + * Set the vdd back to 3V, + * applicable for dual volt support. + */ + vdd = fls(host->mmc->ocr_avail) - 1; + if (omap_mmc_switch_opcond(host, vdd) != 0) + host->mmc->ios.vdd = vdd; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res)Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ release_mem_region(res->start, res->end - res->start + 1); + + platform_set_drvdata(pdev, NULL); + if (host) { + mmc_remove_host(host->mmc);You can't go fiddling with the voltage and removing the MMIO until you've made sure that there is no more activity on the slot.
Changed in the attached patch. I've changed the code to reset the controller voltage setting after powering down the socket instead of trying to do it in two earlier places..
Do you have any better suggestions for this? Basically it looks like the controller may fail to detect the next card after unplugging a 1.8V card unless the controller is reset to 3V.
Quoted 7 lines
Quoted 3 lines
Fix the above issues and you can let it go via Russell with a:
Acked-by Pierre Ossman <[email protected]>Thank you for your comments. Care to take a one more look at the attached patch before I add your Ack? I also fixed the remaining checkpatch warnings.
Here's one more version that leaves out the unnecessary TWL4030 dependency in the Kconfig as pointed out by David Brownell.
Quoted 4 lines
Regards,
Tony
Fromce15009433bcc482c439326fd08960e6d1f0eb1aMon Sep 17 00:00:00 2001
From: Tony Lindgren <[email protected]>
Date: Mon, 29 Dec 2008 16:31:53 +0200
Subject: [PATCH] omap mmc: Add new omap hsmmc controller for 2430 and 34xx, v3
Add omap hsmmc controller for 2430 and 34xx.
Note that this controller has different registers compared to the earlier omap MMC controller, so sharing code currently is not possible.
Various updates and fixes from linux-omap list have been merged into this patch.
drivers/mmc/host/Kconfig +10 -0
@@ -76,6 +76,16 @@ config MMC_OMAP If unsure, say N. +config MMC_OMAP_HS + tristate "TI OMAP High Speed Multimedia Card Interface support" + depends on ARCH_OMAP2430 || ARCH_OMAP3 + help + This selects the TI OMAP High Speed Multimedia card Interface. + If you have an OMAP2430 or OMAP3 board with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on ISA_DMA_API
drivers/mmc/host/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o +obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
drivers/mmc/host/omap_hsmmc.c new file +1242 -0
1,242 lines not on this page · raw message
Pierre Ossman
Acked-byRe: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx
Quoted 4 lines · On Tue, 30 Dec 2008 10:36:26 +0200 Tony Lindgren <[email protected]> wrote:
Here's one more version that leaves out the unnecessary TWL4030 dependency in the
Kconfigas pointed out by David Brownell.
Looks ok.
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
Tony Lindgren
maintainerRe: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx
Quoted 11 lines · Pierre Ossman
Quoted 4 lines · On Tue, 30 Dec 2008 10:36:26 +0200 Tony Lindgren <[email protected]> wrote:
Here's one more version that leaves out the unnecessary TWL4030 dependency in the
Kconfigas pointed out by David Brownell.Looks ok.
Acked-by Pierre Ossman <[email protected]>
Thanks, I'll queue it up with Russell with one change to include <mach/dma.h> instead of <asm/dma.h>.
All further patches to this driver will come to you via LKML.
Regards,
Tony
Quoted 16 lines
Signature · 15 lines
-- -- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
PATCH 1/1 OMAP: MMC: recover from transfer failures (was: Re: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx)
Tony, Pierre,
Here is a patch that fixes a MMC host controller deadlock. The problem happens when removing the MMC/SD device when a transfer is on-going.
It has been tested on OMAP3430 but this fix should apply to OMAP2 chips as well, as seen from the TRMs.
What do you think?
Regards,
Jean.
OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Regards,
Jean
From 48a40925a4d57f6e7e45809a4b5c09b20f9314d7 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Tue, 16 Dec 2008 19:44:12 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
--- drivers/mmc/host/omap_hsmmc.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
drivers/mmc/host/omap_hsmmc.c +2 -0
@@ -44,6 +44,7 @@#define OMAP_HSMMC_RSP54 0x0118#define OMAP_HSMMC_RSP76 0x011C#define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124#define OMAP_HSMMC_HCTL 0x0128#define OMAP_HSMMC_SYSCTL 0x012C#define OMAP_HSMMC_STAT 0x0130
@@ -89,6 +90,7 @@#define DUAL_VOLT_OCR_BIT 7#define SRC (1 << 25)#define SRD (1 << 26) +#define DATI (1 << 1)/* * FIXME: Most likely all the data using these _DEVID defines should come
@@ -273,6 +275,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct
mmc_command *cmd,
mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
host->cmd = cmd;+ if (OMAP_HSMMC_READ(host->base, PSTATE) & DATI) {
+ dev_dbg(mmc_dev(host->mmc), "mmc_omap_start_command: "
+ " resetting data state machine\n");
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | SRD);
+ while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)
+ ;
+ }
+
/*
* Clear status bits and enable interrupts
*/Signature · 1 line
1.5.4.4.21.gc4a6c
Quoted 37 lines · On Wednesday 07 January 2009 11:18:13 Tony Lindgren wrote:
Quoted 9 lines · Pierre Ossman
On Tue, 30 Dec 2008 10:36:26 +0200
Quoted 2 lines · Tony Lindgren
Here's one more version that leaves out the unnecessary TWL4030 dependency in the
Kconfigas pointed out by David Brownell.Looks ok.
Acked-by Pierre Ossman <[email protected]>Thanks, I'll queue it up with Russell with one change to include <
mach/dma.h> instead of <asm/dma.h>.All further patches to this driver will come to you via LKML.
Regards,
Tony
Quoted 6 lines
--
-- Pierre OssmanLinux kernel, MMC maintainer http://www.kernel.org
rdesktop, core developer http://www.rdesktop.orgQuoted 9 lines
WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 4 lines
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
From 48a40925a4d57f6e7e45809a4b5c09b20f9314d7 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Tue, 16 Dec 2008 19:44:12 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
--- drivers/mmc/host/omap_hsmmc.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
drivers/mmc/host/omap_hsmmc.c +11 -0
@@ -44,6 +44,7 @@#define OMAP_HSMMC_RSP54 0x0118#define OMAP_HSMMC_RSP76 0x011C#define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124#define OMAP_HSMMC_HCTL 0x0128#define OMAP_HSMMC_SYSCTL 0x012C#define OMAP_HSMMC_STAT 0x0130
@@ -89,6 +90,7 @@#define DUAL_VOLT_OCR_BIT 7#define SRC (1 << 25)#define SRD (1 << 26) +#define DATI (1 << 1)/* * FIXME: Most likely all the data using these _DEVID defines should come
@@ -273,6 +275,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; +if (OMAP_HSMMC_READ (host->base,PSTATE ) &DATI ) { +dev_dbg (mmc_dev (host->mmc),"mmc_omap_start_command: " +" resetting data state machine\n" ); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) + ; + } +/* * Clear status bits and enable interrupts */
Signature · 1 line
1.5.4.4.21.gc4a6c
Tony Lindgren
maintainerRe: [PATCH] OMAP: MMC: recover from transfer failures (was: Re: [PATCH 5/5] omap mmc: Add new omap hsmmc controller for 2430 and 34xx)
Hi,
Quoted 9 lines · Jean Pihet
Tony, Pierre,
Here is a patch that fixes a MMC host controller deadlock. The problem happens when removing the MMC/SD device when a transfer is on-going.
It has been tested on OMAP3430 but this fix should apply to OMAP2 chips as well, as seen from the TRMs.
What do you think?
Looks OK to me, adding Jarkko to Cc.
Tony
Quoted 195 lines
Regards,
Jean.OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Regards,
JeanFrom
48a40925a4d57f6e7e45809a4b5c09b20f9314d7Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Tue, 16 Dec 2008 19:44:12 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)drivers/mmc/host/omap_hsmmc.c +11
-0@@ -44,6 +44,7 @@#define OMAP_HSMMC_RSP54 0x0118#define OMAP_HSMMC_RSP76 0x011C#define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124#define OMAP_HSMMC_HCTL 0x0128#define OMAP_HSMMC_SYSCTL 0x012C#define OMAP_HSMMC_STAT 0x0130@@ -89,6 +90,7 @@#define DUAL_VOLT_OCR_BIT 7#define SRC (1 << 25)#define SRD (1 << 26) +#define DATI (1 << 1)/* * FIXME: Most likely all the data using these _DEVID defines should come @@ -273,6 +275,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; +if (OMAP_HSMMC_READ (host->base,PSTATE ) &DATI ) { +dev_dbg (mmc_dev (host->mmc),"mmc_omap_start_command: " +" resetting data state machine\n" ); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) + ; + } +/* * Clear status bits and enable interrupts */Signature · 1 line
1.5.4.4.21.gc4a6cQuoted 37 lines · On Wednesday 07 January 2009 11:18:13 Tony Lindgren wrote:
Quoted 9 lines · Pierre Ossman
On Tue, 30 Dec 2008 10:36:26 +0200
Quoted 2 lines · Tony Lindgren
Here's one more version that leaves out the unnecessary TWL4030 dependency in the
Kconfigas pointed out by David Brownell.Looks ok.
Acked-by Pierre Ossman <[email protected]>Thanks, I'll queue it up with Russell with one change to include <
mach/dma.h> instead of <asm/dma.h>.All further patches to this driver will come to you via LKML.
Regards,
Tony
Quoted 6 lines
--
-- Pierre OssmanLinux kernel, MMC maintainer http://www.kernel.org
rdesktop, core developer http://www.rdesktop.orgQuoted 9 lines
WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/Quoted 4 lines
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.phpFrom
48a40925a4d57f6e7e45809a4b5c09b20f9314d7Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Tue, 16 Dec 2008 19:44:12 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)drivers/mmc/host/omap_hsmmc.c +11
-0@@ -44,6 +44,7 @@#define OMAP_HSMMC_RSP54 0x0118#define OMAP_HSMMC_RSP76 0x011C#define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124#define OMAP_HSMMC_HCTL 0x0128#define OMAP_HSMMC_SYSCTL 0x012C#define OMAP_HSMMC_STAT 0x0130@@ -89,6 +90,7 @@#define DUAL_VOLT_OCR_BIT 7#define SRC (1 << 25)#define SRD (1 << 26) +#define DATI (1 << 1)/* * FIXME: Most likely all the data using these _DEVID defines should come @@ -273,6 +275,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; +if (OMAP_HSMMC_READ (host->base,PSTATE ) &DATI ) { +dev_dbg (mmc_dev (host->mmc),"mmc_omap_start_command: " +" resetting data state machine\n" ); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) + ; + } +/* * Clear status bits and enable interrupts */ Signature · 1 line
1.5.4.4.21.gc4a6c
Re: [PATCH] OMAP: MMC: recover from transfer failures
In reply to Jean PihetQuoted 90 lines · Jean Pihet
Tony, Pierre,
Here is a patch that fixes a MMC host controller deadlock. The problem happens when removing the MMC/SD device when a transfer is on-going.
It has been tested on OMAP3430 but this fix should apply to OMAP2 chips as well, as seen from the TRMs.
What do you think?
Regards,
Jean.OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Regards,
JeanFrom
48a40925a4d57f6e7e45809a4b5c09b20f9314d7Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Tue, 16 Dec 2008 19:44:12 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
The indication that the mmc host controller is in this error state is that the DATI bit is set in the PSTATE register. This patch checks to see if the DATI bit is set before starting a new command, and if it is set it resets the data state machine to clear the error.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)drivers/mmc/host/omap_hsmmc.c +11
-0@@ -44,6 +44,7 @@#define OMAP_HSMMC_RSP54 0x0118#define OMAP_HSMMC_RSP76 0x011C#define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124#define OMAP_HSMMC_HCTL 0x0128#define OMAP_HSMMC_SYSCTL 0x012C#define OMAP_HSMMC_STAT 0x0130@@ -89,6 +90,7 @@#define DUAL_VOLT_OCR_BIT 7#define SRC (1 << 25)#define SRD (1 << 26) +#define DATI (1 << 1)/* * FIXME: Most likely all the data using these _DEVID defines should come @@ -273,6 +275,15 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; +if (OMAP_HSMMC_READ (host->base,PSTATE ) &DATI ) { +dev_dbg (mmc_dev (host->mmc),"mmc_omap_start_command: " +" resetting data state machine\n" ); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) + ; + } +/* * Clear status bits and enable interrupts
Quoted 2 lines
*/
Why not do the reset in mmc_omap_irq() like the other resets? e.g.
static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
{
struct mmc_omap_host *host = dev_id;
struct mmc_data *data;
int end_cmd = 0, end_trans = 0, status;
if (host->cmd == NULL && host->data == NULL) {
OMAP_HSMMC_WRITE(host->base, STAT,
OMAP_HSMMC_READ(host->base, STAT));
return IRQ_HANDLED;
}
data = host->data;
status = OMAP_HSMMC_READ(host->base, STAT);
dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
if (status & ERR) {
#ifdef CONFIG_MMC_DEBUG
mmc_omap_report_irq(host, status);
#endif
if ((status & CMD_TIMEOUT) ||
(status & CMD_CRC)) {
if (host->cmd) {
if (status & CMD_TIMEOUT) {
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRC);
while (OMAP_HSMMC_READ(host->base,
SYSCTL) & SRC)
;
host->cmd->error = -ETIMEDOUT;
} else {
host->cmd->error = -EILSEQ;
}
end_cmd = 1;
}
- if (host->data)
+ if (host->data) {
mmc_dma_cleanup(host);+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base,
+ SYSCTL) | SRD);
+ while (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ ;
+ }
}
if ((status & DATA_TIMEOUT) ||
(status & DATA_CRC)) {
if (host->data) {
if (status & DATA_TIMEOUT)
mmc_dma_cleanup(host);
else
host->data->error = -EILSEQ;
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRD);
while (OMAP_HSMMC_READ(host->base,
SYSCTL) & SRD)
;
end_trans = 1;
}
}Re: [PATCH] OMAP: MMC: recover from transfer failures
Thanks for the suggestion, it works great (stress tested) and is a cleaner fix.
Here is a patch the latest linux-omap-2.6 tree. Is this OK?
Regards,
Jean
From d143f6b2e705aa4e9d2b032097fd1c82f8163262 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/omap_hsmmc.c +8 -1
@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) {
--
1.5.4.4.21.gc4a6c
Quoted 24 lines · On Thursday 08 January 2009 10:02:24 Adrian Hunter wrote:
Why not do the reset in
mmc_omap_irq()like the other resets? e.g.static
irqreturn_tmmc_omap_irq(int irq, void *dev_id)
...
if ((status &CMD_TIMEOUT) ||
(status &CMD_CRC)) {
if (host->cmd) {
if (status &CMD_TIMEOUT) {OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | SRC); while (OMAP_HSMMC_READ(host->base, SYSCTL)& SRC) ;host->cmd->error =
-ETIMEDOUT; } else {
host->cmd->error =-EILSEQ; }
end_cmd = 1;
}
- if (host->data)
+ if (host->data) {mmc_dma_cleanup(host);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base,
Quoted 8 lines
+ SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRD) + ;
+ }
}
if ((status &DATA_TIMEOUT) ||
(status &DATA_CRC)) {
From d143f6b2e705aa4e9d2b032097fd1c82f8163262 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/omap_hsmmc.c +8 -1
@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) {
Signature · 1 line
1.5.4.4.21.gc4a6c
Re: [PATCH] OMAP: MMC: recover from transfer failures
Quoted 2 lines · Jean Pihet
Thanks for the suggestion, it works great (stress tested) and is a cleaner fix. Here is a patch the latest linux-omap-2.6 tree. Is this OK?
OK by me.
Quoted 87 lines
Regards,
JeanFrom
d143f6b2e705aa4e9d2b032097fd1c82f8163262Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)drivers/mmc/host/omap_hsmmc.c +8
-2@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) { --1.5.4.4.21.gc4a6c
Quoted 32 lines · On Thursday 08 January 2009 10:02:24 Adrian Hunter wrote:
Why not do the reset in
mmc_omap_irq()like the other resets? e.g.static
irqreturn_tmmc_omap_irq(int irq, void *dev_id)
...if ((status & CMD_TIMEOUT) || (status & CMD_CRC)) { if (host->cmd) { if (status & CMD_TIMEOUT) { OMAP_HSMMC_WRITE(host->base,SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL)| SRC); while (OMAP_HSMMC_READ(host->base, SYSCTL)& SRC) ;host->cmd->error = -ETIMEDOUT; } else { host->cmd->error = -EILSEQ; } end_cmd = 1; }drivers/mmc/host/omap_hsmmc.c +8
-1-if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) {
Re: [PATCH] OMAP: MMC: recover from transfer failures
In reply to Jean PihetTony,
Has this patch been applied to the linux-omap tree? Does it need to go the patchwork?
Cf. http://marc.info/?l=linux-omap&m=123141577308177&w=2
Regards,
Jean
Quoted 87 lines · On Thursday 08 January 2009 12:49:19 Jean Pihet wrote:
Thanks for the suggestion, it works great (stress tested) and is a cleaner fix.
Here is a patch the latest linux-omap-2.6 tree. Is this OK?Regards,
JeanFrom
d143f6b2e705aa4e9d2b032097fd1c82f8163262Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)drivers/mmc/host/omap_hsmmc.c +8
-2@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) { --1.5.4.4.21.gc4a6c
Quoted 32 lines · On Thursday 08 January 2009 10:02:24 Adrian Hunter wrote:
Why not do the reset in
mmc_omap_irq()like the other resets? e.g.static
irqreturn_tmmc_omap_irq(int irq, void *dev_id)
...
if ((status &CMD_TIMEOUT) ||
(status &CMD_CRC)) {
if (host->cmd) {
if (status &CMD_TIMEOUT) {OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | SRC); while (OMAP_HSMMC_READ(host->base, SYSCTL)& SRC) ;host->cmd->error =
-ETIMEDOUT; } else {
host->cmd->error =-EILSEQ; }
end_cmd = 1;
}
- if (host->data)
+ if (host->data) {mmc_dma_cleanup(host);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, + SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRD) + ;
+ }
}
if ((status &DATA_TIMEOUT) ||
(status &DATA_CRC)) {
Tony Lindgren
maintainerRe: [PATCH] OMAP: MMC: recover from transfer failures
Hi,
Quoted 6 lines · Jean Pihet
Tony,
Has this patch been applied to the linux-omap tree? Does it need to go the patchwork?
I'm not applying MMC patches, we need to move that discussion to LKML and keep Pierre involved.
Jarkko Lavinen was planning to set up a git branch against the mainline tree for the omap mmc patches, so until we have that, let's just let the patches float on the list for a while.
But yeah, if you want patchwork to pick up your patch so it does not get lost, just please resend it to the linux-omap list and it should get automatically picked up by patchwork.
Regards,
Tony
Quoted 93 lines
Regards,
JeanQuoted 87 lines · On Thursday 08 January 2009 12:49:19 Jean Pihet wrote:
Thanks for the suggestion, it works great (stress tested) and is a cleaner fix.
Here is a patch the latest linux-omap-2.6 tree. Is this OK?Regards,
JeanFrom
d143f6b2e705aa4e9d2b032097fd1c82f8163262Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failuresTimeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
Signed-off-by Andy Lowe <[email protected]>Signed-off-by Jean Pihet <[email protected]>Signed-off-by Adrian Hunter <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)drivers/mmc/host/omap_hsmmc.c +8
-2@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) { --1.5.4.4.21.gc4a6c
Quoted 32 lines · On Thursday 08 January 2009 10:02:24 Adrian Hunter wrote:
Why not do the reset in
mmc_omap_irq()like the other resets? e.g.static
irqreturn_tmmc_omap_irq(int irq, void *dev_id)
...
if ((status &CMD_TIMEOUT) ||
(status &CMD_CRC)) {
if (host->cmd) {
if (status &CMD_TIMEOUT) {OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | SRC); while (OMAP_HSMMC_READ(host->base, SYSCTL)& SRC) ;host->cmd->error =
-ETIMEDOUT; } else {
host->cmd->error =-EILSEQ; }
end_cmd = 1;
}
- if (host->data)
+ if (host->data) {mmc_dma_cleanup(host);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, + SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRD) + ;
+ }
}
if ((status &DATA_TIMEOUT) ||
(status &DATA_CRC)) {
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/1 OMAP: MMC: recover from transfer failures - Resend
Hi,
This is a re-send of the patch that fixes a MMC host controller deadlock. The problem happens when removing the MMC/SD device when a transfer is on-going.
It has been tested on OMAP3430 but this fix should apply to OMAP2 chips as well, as seen from the TRMs.
Regards,
Jean
From d143f6b2e705aa4e9d2b032097fd1c82f8163262 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
---
drivers/mmc/host/omap_hsmmc.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/omap_hsmmc.c +0 -0
@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
end_cmd = 1;
}
- if (host->data)
+ if (host->data) { mmc_dma_cleanup(host);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base,
+ SYSCTL) | SRD);
+ while (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ ;
+ }
}
if ((status & DATA_TIMEOUT) ||
(status & DATA_CRC)) {
--
1.5.4.4.21.gc4a6c
Quoted 17 lines · On Monday 02 February 2009 20:05:06 Tony Lindgren wrote:
Hi,
Quoted 6 lines · Jean Pihet
Tony,
Has this patch been applied to the linux-omap tree? Does it need to go the patchwork?
I'm not applying MMC patches, we need to move that discussion to LKML and keep Pierre involved.
Jarkko Lavinen was planning to set up a git branch against the mainline tree for the omap mmc patches, so until we have that, let's just let the patches float on the list for a while.
Quoted 7 lines
But yeah, if you want patchwork to pick up your patch so it does not get lost, just please resend it to the linux-omap list and it should get automatically picked up by patchwork.
Regards,
Tony
From d143f6b2e705aa4e9d2b032097fd1c82f8163262 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Thu, 8 Jan 2009 12:35:21 +0100
Subject: [PATCH] OMAP: MMC: recover from transfer failures
Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock.
This patch resets the data state machine to clear the error in case of a command timeout.
Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data.
--- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
drivers/mmc/host/omap_hsmmc.c +8 -1
@@ -464,8 +464,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd =1 ; } -if (host->data) +if (host->data) {mmc_dma_cleanup (host); +OMAP_HSMMC_WRITE (host->base,SYSCTL , +OMAP_HSMMC_READ (host->base, +SYSCTL ) |SRD ); +while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ; + } }if ((status &DATA_TIMEOUT ) || (status &DATA_CRC )) {
Signature · 1 line
1.5.4.4.21.gc4a6c
Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend
drivers/mmc/host/omap_hsmmc.c static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · line 474
Quoted 3 lines · On Tue, 3 Feb 2009 15:05:58 +0100 Jean Pihet <[email protected]> wrote:
drivers/mmc/host/omap_hsmmc.c +3
-0+while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ;
Is a __raw_readl() sufficient to prevent the cpu from burning up here, or should we add cpu_relax()?
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Paul Walmsley
maintainerRe: [PATCH] OMAP: MMC: recover from transfer failures - Resend
Quoted 9 lines · Andrew Morton
drivers/mmc/host/omap_hsmmc.c static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · line 474
Quoted 3 lines · On Tue, 3 Feb 2009 15:05:58 +0100 Jean Pihet <[email protected]> wrote:
drivers/mmc/host/omap_hsmmc.c +3
-0+while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ;Is a
__raw_readl()sufficient to prevent the cpu from burning up here, or should we addcpu_relax()?
The __raw_readl() should be sufficient. The MMC controller is located on the L4 CORE interconnect, so the round trip latency for the read from MMC is at least 90 ns, while the CPU cycle time is only about 1 to 2 ns.
Quoted 2 lines
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
- Paul
Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend
Quoted 11 lines · On Thursday 05 February 2009 21:32:03 Paul Walmsley wrote:
Quoted 9 lines · Andrew Morton
On Tue, 3 Feb 2009 15:05:58 +0100
drivers/mmc/host/omap_hsmmc.c static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · line 474
Quoted 3 lines · Jean Pihet
drivers/mmc/host/omap_hsmmc.c +3
-0+while (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + ;Is a
__raw_readl()sufficient to prevent the cpu from burning up here, or should we addcpu_relax()?
Quoted 3 lines
The
__raw_readl()should be sufficient. The MMC controller is located on the L4 CORE interconnect, so the round trip latency for the read from MMC is at least 90 ns, while the CPU cycle time is only about 1 to 2 ns.
Ok.
Quoted 3 lines
Quoted 3 lines
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Quoted 2 lines
- Paul
Regards,
Jean
Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend
Quoted 7 lines · On Fri, 6 Feb 2009 14:22:32 +0100 Jean Pihet <[email protected]> wrote:
Quoted 3 lines · On Thursday 05 February 2009 21:32:03 Paul Walmsley wrote:
Quoted 2 lines · Andrew Morton
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Even if Andrew doesn't, I'd sure like it. (the finite bit at least) :)
Related, who is the maintainer of this driver? Tony? I'd like to have someone who checks patches before I queue them up.
Rgds
Signature · 9 lines
-- Pierre Ossman Linux kernel, MMC maintainer http://www.kernel.org rdesktop, core developer http://www.rdesktop.org WARNING: This correspondence is being monitored by the Swedish government. Make sure your server uses encryption for SMTP traffic and consider using PGP for end-to-end encryption.
PATCH 1/1 OMAP: MMC: replace infinite loops with timeouts (was Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend)
Hi,
Quoted 9 lines
Quoted 7 lines
Quoted 4 lines · Andrew Morton
Quoted 3 lines
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Even if Andrew doesn't, I'd sure like it. (the finite bit at least) :)
Ok here is a patch that replaces the infinite loops with a timeout version. This patch applies on top of the previous one I sent ('[PATCH] OMAP: MMC:
recover from transfer failures - Resend'). Is that OK?
Quoted 5 lines
Related, who is the maintainer of this driver? Tony? I'd like to have someone who checks patches before I queue them up.
Rgds
From 5ee867d09efe22a903ac7373a05e9e047bad6544 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Fri, 6 Feb 2009 16:42:51 +0100
Subject: [PATCH] OMAP: MMC: replace infinite loops with timeouts
Replace the 'while() ;' with a timeout
--- drivers/mmc/host/omap_hsmmc.c | 56 +++++++++++++++++++++++++++++++++-------- 1 files changed, 45 insertions(+), 11 deletions(-)
drivers/mmc/host/omap_hsmmc.c +3 -0
@@ -102,6 +102,8 @@#define OMAP_MMC_DATADIR_READ 1#define OMAP_MMC_DATADIR_WRITE 2#define MMC_TIMEOUT_MS 20 +#define MMC_TIMEOUT_WAIT 100/* Active wait duration, in usec */ +#define MMC_TIMEOUT_WAIT_LOOPS ((MMC_TIMEOUT_MS * 1000) / MMC_TIMEOUT_WAIT)#define OMAP_MMC_MASTER_CLOCK 96000000#define DRIVER_NAME "mmci-omap-hs"
@@ -384,6 +386,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)struct mmc_omap_host *host = dev_id;struct mmc_data *data;int end_cmd =0 , end_trans =0 , status; +unsigned long timeout_counter;if (host->cmd ==NULL && host->data ==NULL ) { OMAP_HSMMC_WRITE(host->base, STAT,
@@ -406,9 +409,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) |
SRC);
- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRC)
- ;
+ timeout_counter = 0;
+ while ((OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRC)
+ && (timeout_counter++ <
+MMC_TIMEOUT_WAIT_LOOPS))
+udelay(MMC_TIMEOUT_WAIT);
+
+ if (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRC)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on
SRC\n");
host->cmd->error = -ETIMEDOUT;
} else {
@@ -421,9 +432,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRD);- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRD)
- ;
+ timeout_counter = 0;
+ while ((OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ && (timeout_counter++ <
+MMC_TIMEOUT_WAIT_LOOPS))
+ udelay(MMC_TIMEOUT_WAIT);
+
+ if (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on SRD\n");
}
}
if ((status & DATA_TIMEOUT) ||
@@ -436,9 +455,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base,
SYSCTL) | SRD);- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRD)
- ;
+ timeout_counter = 0;
+ while ((OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ && (timeout_counter++ <
+MMC_TIMEOUT_WAIT_LOOPS))
+ udelay(MMC_TIMEOUT_WAIT);
+
+ if (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on SRD\n");
end_trans = 1;
}
}@@ -524,6 +551,7 @@ static void mmc_omap_detect(struct work_struct *work)
{
struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
mmc_carddetect_work);
+ unsigned long timeout;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
if (host->carddetect) {
@@ -531,8 +559,14 @@ static void mmc_omap_detect(struct work_struct *work)
} else {
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | SRD);
- while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)
- ;
+ /* Wait till the SRD bit is reset */
+ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)+ && time_before(jiffies, timeout))
+ msleep(1);
+
+ if (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)
+ dev_err(mmc_dev(host->mmc), "Timeout waiting on
SRD\n");
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
}--
1.6.0.1.42.gf8c9c
From 5ee867d09efe22a903ac7373a05e9e047bad6544 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Fri, 6 Feb 2009 16:42:51 +0100
Subject: [PATCH] OMAP: MMC: replace infinite loops with timeouts
Replace the 'while() ;' with a timeout
--- drivers/mmc/host/omap_hsmmc.c | 56 +++++++++++++++++++++++++++++++++-------- 1 files changed, 45 insertions(+), 11 deletions(-)
drivers/mmc/host/omap_hsmmc.c +45 -11
98 lines not on this page · raw message
Signature · 1 line
1.6.0.1.42.gf8c9c
Re: [PATCH] OMAP: MMC: replace infinite loops with timeouts (was Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend)
Quoted 6 lines · Jean Pihet
Hi,
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines · Andrew Morton
Quoted 3 lines
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
Quoted 7 lines
Quoted 3 lines
Quoted 2 lines
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Even if Andrew doesn't, I'd sure like it. (the finite bit at least) :)
Ok here is a patch that replaces the infinite loops with a timeout version. This patch applies on top of the previous one I sent ('[PATCH] OMAP: MMC:
recover from transfer failures - Resend'). Is that OK?
What about making use of a function like this:
static void reset_host_controller(struct mmc_omap_host *host, unsigned bit)
{
unsigned long i, limit = loops_per_jiffy;
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
for (i = 0; i < limit; i++) {
if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
return;
cpu_relax();
}
dev_err(mmc_dev(host->mmc), "%s: timeout waiting on software reset\n",
mmc_hostname(host->mmc));
}And then just put:
reset_host_controller(host, SRD);
and
reset_host_controller(host, SRC);
in the right places.
Quoted 138 lines
Quoted 7 lines
Related, who is the maintainer of this driver? Tony? I'd like to have someone who checks patches before I queue them up.
Rgds
From
5ee867d09efe22a903ac7373a05e9e047bad6544Mon Sep 17 00:00:00 2001From: Jean Pihet <[email protected]>
Date: Fri, 6 Feb 2009 16:42:51 +0100
Subject: [PATCH] OMAP: MMC: replace infinite loops with timeoutsReplace the '
while();' with a timeoutSigned-off-by Jean Pihet <[email protected]>--- drivers/mmc/host/omap_hsmmc.c | 56 +++++++++++++++++++++++++++++++++-------- 1 files changed, 45 insertions(+), 11 deletions(-)drivers/mmc/host/omap_hsmmc.c +14
-3@@ -102,6 +102,8 @@#define OMAP_MMC_DATADIR_READ 1#define OMAP_MMC_DATADIR_WRITE 2#define MMC_TIMEOUT_MS 20 +#define MMC_TIMEOUT_WAIT 100/* Active wait duration, in usec */ +#define MMC_TIMEOUT_WAIT_LOOPS ((MMC_TIMEOUT_MS * 1000) / MMC_TIMEOUT_WAIT)#define OMAP_MMC_MASTER_CLOCK 96000000#define DRIVER_NAME "mmci-omap-hs"@@ -384,6 +386,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)struct mmc_omap_host *host = dev_id;struct mmc_data *data;int end_cmd =0 , end_trans =0 , status; +unsigned long timeout_counter;if (host->cmd ==NULL && host->data ==NULL ) { OMAP_HSMMC_WRITE(host->base, STAT,@@ -406,9 +409,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)OMAP_HSMMC_WRITE (host->base,SYSCTL ,OMAP_HSMMC_READ (host->base,SYSCTL ) |SRC ); -while (OMAP_HSMMC_READ (host->base, -SYSCTL ) &SRC ) - ; + timeout_counter =0 ; +while ((OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRC ) + && (timeout_counter++ < +MMC_TIMEOUT_WAIT_LOOPS )) +udelay (MMC_TIMEOUT_WAIT ); + +if (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRC ) + dev_err(mmc_dev(host->mmc), + "Timeout waiting onSRC\n");
host->cmd->error = -ETIMEDOUT; } else {drivers/mmc/host/omap_hsmmc.c +11
-3@@ -421,9 +432,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)OMAP_HSMMC_WRITE (host->base,SYSCTL ,OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); -while (OMAP_HSMMC_READ (host->base, -SYSCTL ) &SRD ) - ; + timeout_counter =0 ; +while ((OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + && (timeout_counter++ < +MMC_TIMEOUT_WAIT_LOOPS )) +udelay (MMC_TIMEOUT_WAIT ); + +if (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) +dev_err (mmc_dev (host->mmc), +"Timeout waiting on SRD\n" ); } }if ((status & DATA_TIMEOUT) ||drivers/mmc/host/omap_hsmmc.c +11
-3@@ -436,9 +455,17 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)OMAP_HSMMC_WRITE (host->base,SYSCTL ,OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); -while (OMAP_HSMMC_READ (host->base, -SYSCTL ) &SRD ) - ; + timeout_counter =0 ; +while ((OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) + && (timeout_counter++ < +MMC_TIMEOUT_WAIT_LOOPS )) +udelay (MMC_TIMEOUT_WAIT ); + +if (OMAP_HSMMC_READ (host->base, +SYSCTL ) &SRD ) +dev_err (mmc_dev (host->mmc), +"Timeout waiting on SRD\n" ); end_trans =1 ; }}drivers/mmc/host/omap_hsmmc.c +9
-2@@ -524,6 +551,7 @@ static void mmc_omap_detect(struct work_struct *work) { struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, mmc_carddetect_work); +unsigned long timeout;sysfs_notify (&host->mmc->class_dev.kobj,NULL ,"cover_switch" );if (host->carddetect) {@@ -531,8 +559,14 @@ static void mmc_omap_detect(struct work_struct *work) }else {OMAP_HSMMC_WRITE (host->base,SYSCTL ,OMAP_HSMMC_READ (host->base,SYSCTL ) |SRD ); -while (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) - ; +/* Wait till the SRD bit is reset */ + timeout = jiffies +msecs_to_jiffies (MMC_TIMEOUT_MS ); +while ((OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) + &&time_before (jiffies, timeout)) +msleep (1 ); + +if (OMAP_HSMMC_READ (host->base,SYSCTL ) &SRD ) +dev_err (mmc_dev (host->mmc),"Timeout waiting on SRD\n");mmc_detect_change (host->mmc, (HZ *50 ) /1000 );}--
1.6.0.1.42.gf8c9c
Re: [PATCH] OMAP: MMC: replace infinite loops with timeouts (was Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend)
Hi,
Here is the new version of the patch, which now uses cpu_relax in an inline function. The new function can be used from an irq handler as well.
Regards,
Jean
From 9d1993dcf4d217837437a1cd9f6e9c1b81533549 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Fri, 6 Feb 2009 16:42:51 +0100
Subject: [PATCH] OMAP: MMC: Change while(); loops with finite version
Replace the infinite 'while() ;' loops
with a finite loop version.
--- drivers/mmc/host/omap_hsmmc.c | 54 ++++++++++++++++++++++------------------ 1 files changed, 30 insertions(+), 24 deletions(-)
drivers/mmc/host/omap_hsmmc.c +0 -0
@@ -375,6 +375,32 @@ static void mmc_omap_report_irq(struct mmc_omap_host
*host, u32 status)
}
#endif /* CONFIG_MMC_DEBUG */
+/*
+ * MMC controller internal state machines reset
+ *
+ * Used to reset command or data internal state machines, using respectively
+ * SRC or SRD bit of SYSCTL register
+ * Can be called from interrupt context
+ */
+static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host,
+ unsigned long bit)
+{
+ unsigned long i = 0;
+ unsigned long limit = (loops_per_jiffy *
+ msecs_to_jiffies(MMC_TIMEOUT_MS));
+
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
+
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
+ (i++ < limit))
+ cpu_relax();
+
+ if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on controller reset in %s\n",
+ __func__);
+}
/*
* MMC controller IRQ handler
@@ -403,13 +429,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
(status & CMD_CRC)) {
if (host->cmd) {
if (status & CMD_TIMEOUT) {- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base,
- SYSCTL) |
SRC);
- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRC)
- ;
-
+ mmc_omap_reset_controller_fsm(host,
SRC);
host->cmd->error = -ETIMEDOUT;
} else {
host->cmd->error = -EILSEQ;
@@ -418,12 +438,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
if (host->data) {
mmc_dma_cleanup(host);- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base,
- SYSCTL) | SRD);
- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRD)
- ;
+ mmc_omap_reset_controller_fsm(host, SRD);
}
}
if ((status & DATA_TIMEOUT) ||
@@ -433,12 +448,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
mmc_dma_cleanup(host);
else
host->data->error = -EILSEQ;- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base,
- SYSCTL) | SRD);
- while (OMAP_HSMMC_READ(host->base,
- SYSCTL) & SRD)
- ;
+ mmc_omap_reset_controller_fsm(host, SRD);
end_trans = 1;
}
}
@@ -529,11 +539,7 @@ static void mmc_omap_detect(struct work_struct *work)
if (host->carddetect) {
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
} else {- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) | SRD);
- while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD)
- ;
-
+ mmc_omap_reset_controller_fsm(host, SRD);
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
} }
--
1.6.0.1.42.gf8c9c
Quoted 36 lines · On Monday 09 February 2009 16:58:14 Adrian Hunter wrote:
Quoted 7 lines · Jean Pihet
Hi,
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines · Andrew Morton
Quoted 3 lines
An infinite loop which assumes the hardware is perfect is always a worry. But I see the driver already does that, so we're no worse off..
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Even if Andrew doesn't, I'd sure like it. (the finite bit at least) :)
Ok here is a patch that replaces the infinite loops with a timeout version. This patch applies on top of the previous one I sent ('[PATCH]
OMAP: MMC: recover from transfer failures - Resend'). Is that OK?What about making use of a function like this:
static void
reset_host_controller(struct mmc_omap_host *host, unsigned bit){ unsigned long i, limit = loops_per_jiffy; OMAP_HSMMC_WRITE(host->base, SYSCTL, OMAP_HSMMC_READ(host->base, SYSCTL) | bit); for (i = 0; i < limit; i++) { if (!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit)) return; cpu_relax(); } dev_err(mmc_dev(host->mmc), "%s: timeout waiting on software reset\n", mmc_hostname(host->mmc)); }And then just put:
Quoted 7 lines
reset_host_controller(host, SRD);and
reset_host_controller(host, SRC);in the right places.
From 9d1993dcf4d217837437a1cd9f6e9c1b81533549 Mon Sep 17 00:00:00 2001
From: Jean Pihet <[email protected]>
Date: Fri, 6 Feb 2009 16:42:51 +0100
Subject: [PATCH] OMAP: MMC: Change while(); loops with finite version
Replace the infinite 'while() ;' loops
with a finite loop version.
--- drivers/mmc/host/omap_hsmmc.c | 54 ++++++++++++++++++++++------------------ 1 files changed, 30 insertions(+), 24 deletions(-)
drivers/mmc/host/omap_hsmmc.c +30 -24
84 lines not on this page · raw message
Signature · 1 line
1.6.0.1.42.gf8c9c
Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend
In reply to Pierre OssmanQuoted 2 lines · Pierre Ossman
Related, who is the maintainer of this driver? Tony? I'd like to have someone who checks patches before I queue them up.
I can be. Tony asked me a month ago to set up git tree for OMAP HSMMC and put the workaround for the HSMMC multi-block DMA read corruption there, but hate to admit things have been hanging on todo list.
There are some other fixes waiting. Omap_mmc_set_ios() doesn't handle power off case correctly and resume from suspend can hang if the SDBP bit fails to set.
Cheers
Jarkko
Tony Lindgren
maintainerRe: [PATCH] OMAP: MMC: recover from transfer failures - Resend
Quoted 8 lines · Jarkko Lavinen
Quoted 2 lines · Pierre Ossman
Related, who is the maintainer of this driver? Tony? I'd like to have someone who checks patches before I queue them up.
I can be. Tony asked me a month ago to set up git tree for OMAP HSMMC and put the workaround for the HSMMC multi-block DMA read corruption there, but hate to admit things have been hanging on todo list.
Yeah it would be great if Jarkkko can queue up all the omap MMC patches from now on.
Quoted 3 lines
There are some other fixes waiting.
Omap_mmc_set_ios()doesn't handle power off case correctly and resume from suspend can hang if the SDBP bit fails to set.
And then all your PM patches for the next merge window..
Tony
Paul Walmsley
maintainerRe: [PATCH] OMAP: MMC: recover from transfer failures - Resend
In reply to Jean PihetQuoted 2 lines · Jean Pihet
Do you want a finite loop with udelay in it? I located 4 places were this could be used. If so I can generate a new patch for that.
Just as an aside, from the standpoint of minimizing CPU usage, there seems little point in using udelay() here, since it is implemented as a CPU busy-wait.
- Paul
Re: [PATCH] OMAP: MMC: recover from transfer failures - Resend
In reply to Paul WalmsleyQuoted 11 lines · Paul Walmsley
Quoted 7 lines
Quoted 4 lines
+ while (OMAP_HSMMC_READ(host->base,
+ SYSCTL) & SRD)
+ ;Is a
__raw_readl()sufficient to prevent the cpu from burning up here, or should we addcpu_relax()?The
__raw_readl()should be sufficient. The MMC controller is located on the L4 CORE interconnect, so the round trip latency for the read from MMC is at least 90 ns, while the CPU cycle time is only about 1 to 2 ns.
It's still good policy to have a cpu_relax() in such loops. Not that it'll do much on most ARMs, but empty statements are in general worth avoiding.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
maintainergit pull request for omap mmc init changes (Re: [PATCH 0/5] Omap MMC init updates and new controller for 2.6.29 merge window)
In reply to Tony LindgrenQuoted 6 lines · Tony Lindgren
Hi Pierre & Russell,
This series contains a better platform init for omap MMC as discussed earlier on the linux-omap mailing list. The last patch in the series adds support for a newer omap MMC controller available on 2430 and 34xx omaps.
Quoted 8 lines
The first four patches should get merged via Russell. The last one adding the new controller depends on comments from Pierre, so I can separate that out if desired.
The third patch in the series depends on the "Omap3 updates for 2.6.29 merge window" series for the changes to Pandora board support.
Comments welcome as always!
Russell, here's a pull request for the first four patches in this series for the mmc init changes. This depends on the omap3-upstream pull request posted earlier today.
I'm not including the actual driver in this series, that should go via Pierre. Or at least we should have an ack from Pierre first.
Regards,
Tony
The following changes since commit 2619bc327417f549f1c89d5ef9b4a4aa768f41a2:
Arun KS (1):
ARM: OMAP3: Pin multiplexing updates for 24xx and 34xx
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git hsmmc-init
Kevin Hilman (1):
omap mmc: force MMC module reset on boot
Tony Lindgren (3):
omap mmc: Remove broken MMC init code
omap mmc: Add better MMC low-level init
omap mmc: Add low-level initialization for hsmmc controller
arch/arm/mach-omap1/board-h2-mmc.c | 89 +++---- arch/arm/mach-omap1/board-h2.c | 25 +- arch/arm/mach-omap1/board-h3-mmc.c | 100 ++----- arch/arm/mach-omap1/board-h3.c | 10 - arch/arm/mach-omap1/board-innovator.c | 50 +++- arch/arm/mach-omap1/board-nokia770.c | 74 ++++- arch/arm/mach-omap1/board-palmte.c | 1 - arch/arm/mach-omap1/board-palmz71.c | 11 - arch/arm/mach-omap1/board-sx1-mmc.c | 80 +----- arch/arm/mach-omap1/board-sx1.c | 10 - arch/arm/mach-omap1/board-voiceblue.c | 10 +- arch/arm/mach-omap1/clock.h | 3 +- arch/arm/mach-omap1/devices.c | 90 ++++++ arch/arm/mach-omap2/Makefile | 15 +- arch/arm/mach-omap2/board-2430sdp.c | 48 ++++ arch/arm/mach-omap2/board-apollon.c | 11 - arch/arm/mach-omap2/board-generic.c | 11 - arch/arm/mach-omap2/board-h4.c | 11 - arch/arm/mach-omap2/board-ldp.c | 40 +++- arch/arm/mach-omap2/board-omap3beagle.c | 90 ++++++ arch/arm/mach-omap2/board-omap3pandora.c | 32 +++ arch/arm/mach-omap2/board-overo.c | 43 +++ arch/arm/mach-omap2/clock24xx.h | 9 +- arch/arm/mach-omap2/clock34xx.h | 10 +- arch/arm/mach-omap2/devices.c | 169 ++++++++++++ arch/arm/mach-omap2/mmc-twl4030.c | 408 ++++++++++++++++++++++++++++ arch/arm/mach-omap2/mmc-twl4030.h | 29 ++ arch/arm/plat-omap/devices.c | 225 +++------------- arch/arm/plat-omap/include/mach/board-h2.h | 6 +- arch/arm/plat-omap/include/mach/board.h | 22 -- arch/arm/plat-omap/include/mach/control.h | 17 ++ arch/arm/plat-omap/include/mach/mmc.h | 74 +++++- drivers/mmc/host/omap.c | 7 +- 33 files changed, 1282 insertions(+), 548 deletions(-) create mode 100644 arch/arm/mach-omap2/mmc-twl4030.c create mode 100644 arch/arm/mach-omap2/mmc-twl4030.h