2008-12-11 04:37:17 +03:00
/*
2010-02-15 21:03:34 +03:00
* linux / arch / arm / mach - omap2 / hsmmc . c
2008-12-11 04:37:17 +03:00
*
* Copyright ( C ) 2007 - 2008 Texas Instruments
* Copyright ( C ) 2008 Nokia Corporation
* Author : Texas Instruments
*
* 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 .
*/
2010-02-15 21:03:34 +03:00
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/string.h>
2008-12-11 04:37:17 +03:00
# include <linux/delay.h>
2011-07-04 15:10:00 +04:00
# include <linux/gpio.h>
2012-08-31 02:37:24 +04:00
# include <linux/platform_data/gpio-omap.h>
2012-10-06 00:25:59 +04:00
# include "soc.h"
2012-10-03 04:25:48 +04:00
# include "omap_device.h"
2012-10-04 03:36:40 +04:00
# include "omap-pm.h"
2008-12-11 04:37:17 +03:00
2011-02-28 18:18:03 +03:00
# include "mux.h"
2012-10-15 23:09:43 +04:00
# include "mmc.h"
2010-02-15 21:03:34 +03:00
# include "hsmmc.h"
2010-10-08 21:40:20 +04:00
# include "control.h"
2008-12-11 04:37:17 +03:00
2010-02-15 21:03:34 +03:00
# if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
2008-12-11 04:37:17 +03:00
static u16 control_pbias_offset ;
static u16 control_devconf1_offset ;
# define HSMMC_NAME_LEN 9
2009-09-23 03:44:40 +04:00
# if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
2010-02-15 21:03:34 +03:00
static int hsmmc_get_context_loss ( struct device * dev )
2009-09-23 03:44:40 +04:00
{
2010-02-15 21:03:34 +03:00
return omap_pm_get_dev_context_loss_count ( dev ) ;
2009-09-23 03:44:40 +04:00
}
# else
2010-02-15 21:03:34 +03:00
# define hsmmc_get_context_loss NULL
2009-09-23 03:44:40 +04:00
# endif
2010-05-15 22:21:25 +04:00
static void omap_hsmmc1_before_set_reg ( struct device * dev , int slot ,
2010-02-15 21:03:34 +03:00
int power_on , int vdd )
2008-12-11 04:37:17 +03:00
{
2009-11-22 21:11:08 +03:00
u32 reg , prog_io ;
2008-12-11 04:37:17 +03:00
struct omap_mmc_platform_data * mmc = dev - > platform_data ;
2010-02-15 21:03:34 +03:00
if ( mmc - > slots [ 0 ] . remux )
mmc - > slots [ 0 ] . remux ( dev , slot , power_on ) ;
2009-03-24 04:23:47 +03:00
/*
* Assume we power both OMAP VMMC1 ( for CMD , CLK , DAT0 . .3 ) and the
2009-05-29 01:04:03 +04:00
* card with Vcc regulator ( from twl4030 or whatever ) . OMAP has both
2009-03-24 04:23:47 +03:00
* 1.8 V and 3.0 V modes , controlled by the PBIAS register .
*
* In 8 - bit modes , OMAP VMMC1A ( for DAT4 . .7 ) needs a supply , which
* is most naturally TWL VSIM ; those pins also use PBIAS .
2009-05-29 01:04:03 +04:00
*
* FIXME handle VMMC1A as needed . . .
2009-03-24 04:23:47 +03:00
*/
2008-12-11 04:37:17 +03:00
if ( power_on ) {
if ( cpu_is_omap2430 ( ) ) {
reg = omap_ctrl_readl ( OMAP243X_CONTROL_DEVCONF1 ) ;
if ( ( 1 < < vdd ) > = MMC_VDD_30_31 )
reg | = OMAP243X_MMC1_ACTIVE_OVERWRITE ;
else
reg & = ~ OMAP243X_MMC1_ACTIVE_OVERWRITE ;
omap_ctrl_writel ( reg , OMAP243X_CONTROL_DEVCONF1 ) ;
}
if ( mmc - > slots [ 0 ] . internal_clock ) {
reg = omap_ctrl_readl ( OMAP2_CONTROL_DEVCONF0 ) ;
reg | = OMAP2_MMCSDIO1ADPCLKISEL ;
omap_ctrl_writel ( reg , OMAP2_CONTROL_DEVCONF0 ) ;
}
reg = omap_ctrl_readl ( control_pbias_offset ) ;
2009-11-22 21:11:08 +03:00
if ( cpu_is_omap3630 ( ) ) {
/* Set MMC I/O to 52Mhz */
prog_io = omap_ctrl_readl ( OMAP343X_CONTROL_PROG_IO1 ) ;
prog_io | = OMAP3630_PRG_SDMMC1_SPEEDCTRL ;
omap_ctrl_writel ( prog_io , OMAP343X_CONTROL_PROG_IO1 ) ;
} else {
reg | = OMAP2_PBIASSPEEDCTRL0 ;
}
2008-12-11 04:37:17 +03:00
reg & = ~ OMAP2_PBIASLITEPWRDNZ0 ;
omap_ctrl_writel ( reg , control_pbias_offset ) ;
2010-02-15 21:03:34 +03:00
} else {
reg = omap_ctrl_readl ( control_pbias_offset ) ;
reg & = ~ OMAP2_PBIASLITEPWRDNZ0 ;
omap_ctrl_writel ( reg , control_pbias_offset ) ;
}
}
2010-05-15 22:21:25 +04:00
static void omap_hsmmc1_after_set_reg ( struct device * dev , int slot ,
2010-02-15 21:03:34 +03:00
int power_on , int vdd )
{
u32 reg ;
2008-12-11 04:37:17 +03:00
2010-02-15 21:03:34 +03:00
/* 100ms delay required for PBIAS configuration */
msleep ( 100 ) ;
2008-12-11 04:37:17 +03:00
2010-02-15 21:03:34 +03:00
if ( power_on ) {
2008-12-11 04:37:17 +03:00
reg = omap_ctrl_readl ( control_pbias_offset ) ;
reg | = ( OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0 ) ;
if ( ( 1 < < vdd ) < = MMC_VDD_165_195 )
reg & = ~ OMAP2_PBIASLITEVMODE0 ;
else
reg | = OMAP2_PBIASLITEVMODE0 ;
omap_ctrl_writel ( reg , control_pbias_offset ) ;
} else {
reg = omap_ctrl_readl ( control_pbias_offset ) ;
reg | = ( OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
OMAP2_PBIASLITEVMODE0 ) ;
omap_ctrl_writel ( reg , control_pbias_offset ) ;
}
}
2011-11-29 13:37:48 +04:00
static void hsmmc2_select_input_clk_src ( struct omap_mmc_platform_data * mmc )
{
u32 reg ;
2012-01-12 18:26:45 +04:00
reg = omap_ctrl_readl ( control_devconf1_offset ) ;
if ( mmc - > slots [ 0 ] . internal_clock )
2011-11-29 13:37:48 +04:00
reg | = OMAP2_MMCSDIO2ADPCLKISEL ;
2012-01-12 18:26:45 +04:00
else
reg & = ~ OMAP2_MMCSDIO2ADPCLKISEL ;
omap_ctrl_writel ( reg , control_devconf1_offset ) ;
2011-11-29 13:37:48 +04:00
}
2011-12-18 04:35:47 +04:00
static void hsmmc2_before_set_reg ( struct device * dev , int slot ,
2010-02-15 21:03:34 +03:00
int power_on , int vdd )
2008-12-11 04:37:17 +03:00
{
struct omap_mmc_platform_data * mmc = dev - > platform_data ;
2009-05-29 01:04:03 +04:00
2010-02-15 21:03:34 +03:00
if ( mmc - > slots [ 0 ] . remux )
mmc - > slots [ 0 ] . remux ( dev , slot , power_on ) ;
2011-11-29 13:37:48 +04:00
if ( power_on )
hsmmc2_select_input_clk_src ( mmc ) ;
}
2008-12-11 04:37:17 +03:00
2011-11-29 13:37:48 +04:00
static int am35x_hsmmc2_set_power ( struct device * dev , int slot ,
int power_on , int vdd )
{
struct omap_mmc_platform_data * mmc = dev - > platform_data ;
if ( power_on )
hsmmc2_select_input_clk_src ( mmc ) ;
return 0 ;
2009-09-23 03:44:50 +04:00
}
2010-05-13 16:39:31 +04:00
static int nop_mmc_set_power ( struct device * dev , int slot , int power_on ,
int vdd )
{
return 0 ;
}
2011-02-28 18:18:03 +03:00
static inline void omap_hsmmc_mux ( struct omap_mmc_platform_data * mmc_controller ,
int controller_nr )
{
2011-11-18 01:39:40 +04:00
if ( gpio_is_valid ( mmc_controller - > slots [ 0 ] . switch_pin ) & &
( mmc_controller - > slots [ 0 ] . switch_pin < OMAP_MAX_GPIO_LINES ) )
2011-02-28 18:18:03 +03:00
omap_mux_init_gpio ( mmc_controller - > slots [ 0 ] . switch_pin ,
OMAP_PIN_INPUT_PULLUP ) ;
2011-11-18 01:39:40 +04:00
if ( gpio_is_valid ( mmc_controller - > slots [ 0 ] . gpio_wp ) & &
( mmc_controller - > slots [ 0 ] . gpio_wp < OMAP_MAX_GPIO_LINES ) )
2011-02-28 18:18:03 +03:00
omap_mux_init_gpio ( mmc_controller - > slots [ 0 ] . gpio_wp ,
OMAP_PIN_INPUT_PULLUP ) ;
if ( cpu_is_omap34xx ( ) ) {
if ( controller_nr = = 0 ) {
omap_mux_init_signal ( " sdmmc1_clk " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_cmd " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat0 " ,
OMAP_PIN_INPUT_PULLUP ) ;
if ( mmc_controller - > slots [ 0 ] . caps &
( MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA ) ) {
omap_mux_init_signal ( " sdmmc1_dat1 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat2 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat3 " ,
OMAP_PIN_INPUT_PULLUP ) ;
}
if ( mmc_controller - > slots [ 0 ] . caps &
MMC_CAP_8_BIT_DATA ) {
omap_mux_init_signal ( " sdmmc1_dat4 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat5 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat6 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc1_dat7 " ,
OMAP_PIN_INPUT_PULLUP ) ;
}
}
if ( controller_nr = = 1 ) {
/* MMC2 */
omap_mux_init_signal ( " sdmmc2_clk " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_cmd " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat0 " ,
OMAP_PIN_INPUT_PULLUP ) ;
/*
* For 8 wire configurations , Lines DAT4 , 5 , 6 and 7
* need to be muxed in the board - * . c files
*/
if ( mmc_controller - > slots [ 0 ] . caps &
( MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA ) ) {
omap_mux_init_signal ( " sdmmc2_dat1 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat2 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat3 " ,
OMAP_PIN_INPUT_PULLUP ) ;
}
if ( mmc_controller - > slots [ 0 ] . caps &
MMC_CAP_8_BIT_DATA ) {
omap_mux_init_signal ( " sdmmc2_dat4.sdmmc2_dat4 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat5.sdmmc2_dat5 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat6.sdmmc2_dat6 " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " sdmmc2_dat7.sdmmc2_dat7 " ,
OMAP_PIN_INPUT_PULLUP ) ;
}
}
/*
* For MMC3 the pins need to be muxed in the board - * . c files
*/
}
}
2012-02-20 21:43:30 +04:00
static int __init omap_hsmmc_pdata_init ( struct omap2_hsmmc_info * c ,
struct omap_mmc_platform_data * mmc )
2011-02-28 18:18:04 +03:00
{
char * hc_name ;
hc_name = kzalloc ( sizeof ( char ) * ( HSMMC_NAME_LEN + 1 ) , GFP_KERNEL ) ;
if ( ! hc_name ) {
pr_err ( " Cannot allocate memory for controller slot name \n " ) ;
kfree ( hc_name ) ;
return - ENOMEM ;
}
if ( c - > name )
strncpy ( hc_name , c - > name , HSMMC_NAME_LEN ) ;
else
snprintf ( hc_name , ( HSMMC_NAME_LEN + 1 ) , " mmc%islot%i " ,
c - > mmc , 1 ) ;
mmc - > slots [ 0 ] . name = hc_name ;
mmc - > nr_slots = 1 ;
mmc - > slots [ 0 ] . caps = c - > caps ;
2011-11-22 18:02:18 +04:00
mmc - > slots [ 0 ] . pm_caps = c - > pm_caps ;
2011-02-28 18:18:04 +03:00
mmc - > slots [ 0 ] . internal_clock = ! c - > ext_clock ;
2012-02-19 16:20:33 +04:00
mmc - > max_freq = c - > max_freq ;
2013-05-30 23:53:06 +04:00
mmc - > reg_offset = 0 ;
2011-02-28 18:18:04 +03:00
mmc - > get_context_loss_count = hsmmc_get_context_loss ;
mmc - > slots [ 0 ] . switch_pin = c - > gpio_cd ;
mmc - > slots [ 0 ] . gpio_wp = c - > gpio_wp ;
mmc - > slots [ 0 ] . remux = c - > remux ;
mmc - > slots [ 0 ] . init_card = c - > init_card ;
if ( c - > cover_only )
mmc - > slots [ 0 ] . cover = 1 ;
if ( c - > nonremovable )
mmc - > slots [ 0 ] . nonremovable = 1 ;
if ( c - > power_saving )
mmc - > slots [ 0 ] . power_saving = 1 ;
if ( c - > no_off )
mmc - > slots [ 0 ] . no_off = 1 ;
2011-05-30 18:25:34 +04:00
if ( c - > no_off_init )
mmc - > slots [ 0 ] . no_regulator_off_init = c - > no_off_init ;
2011-02-28 18:18:04 +03:00
if ( c - > vcc_aux_disable_is_sleep )
mmc - > slots [ 0 ] . vcc_aux_disable_is_sleep = 1 ;
/*
* NOTE : MMC slots should have a Vcc regulator set up .
* This may be from a TWL4030 - family chip , another
* controllable regulator , or a fixed supply .
*
* temporary HACK : ocr_mask instead of fixed supply
*/
2012-05-01 03:37:10 +04:00
if ( soc_is_am35xx ( ) )
2011-12-10 00:27:36 +04:00
mmc - > slots [ 0 ] . ocr_mask = MMC_VDD_165_195 |
MMC_VDD_26_27 |
MMC_VDD_27_28 |
MMC_VDD_29_30 |
MMC_VDD_30_31 |
MMC_VDD_31_32 ;
else
mmc - > slots [ 0 ] . ocr_mask = c - > ocr_mask ;
2011-02-28 18:18:04 +03:00
2012-05-01 03:37:10 +04:00
if ( ! soc_is_am35xx ( ) )
2011-02-28 18:18:04 +03:00
mmc - > slots [ 0 ] . features | = HSMMC_HAS_PBIAS ;
switch ( c - > mmc ) {
case 1 :
if ( mmc - > slots [ 0 ] . features & HSMMC_HAS_PBIAS ) {
/* on-chip level shifting via PBIAS0/PBIAS1 */
2013-05-30 23:53:06 +04:00
mmc - > slots [ 0 ] . before_set_reg =
omap_hsmmc1_before_set_reg ;
mmc - > slots [ 0 ] . after_set_reg =
omap_hsmmc1_after_set_reg ;
2011-02-28 18:18:04 +03:00
}
2012-05-01 03:37:10 +04:00
if ( soc_is_am35xx ( ) )
2011-11-29 13:37:48 +04:00
mmc - > slots [ 0 ] . set_power = nop_mmc_set_power ;
2011-02-28 18:18:04 +03:00
/* OMAP3630 HSMMC1 supports only 4-bit */
if ( cpu_is_omap3630 ( ) & &
( c - > caps & MMC_CAP_8_BIT_DATA ) ) {
c - > caps & = ~ MMC_CAP_8_BIT_DATA ;
c - > caps | = MMC_CAP_4_BIT_DATA ;
mmc - > slots [ 0 ] . caps = c - > caps ;
}
break ;
case 2 :
2012-05-01 03:37:10 +04:00
if ( soc_is_am35xx ( ) )
2011-11-29 13:37:48 +04:00
mmc - > slots [ 0 ] . set_power = am35x_hsmmc2_set_power ;
2011-02-28 18:18:04 +03:00
if ( c - > ext_clock )
c - > transceiver = 1 ;
if ( c - > transceiver & & ( c - > caps & MMC_CAP_8_BIT_DATA ) ) {
c - > caps & = ~ MMC_CAP_8_BIT_DATA ;
c - > caps | = MMC_CAP_4_BIT_DATA ;
}
if ( mmc - > slots [ 0 ] . features & HSMMC_HAS_PBIAS ) {
/* off-chip level shifting, or none */
2011-12-18 04:35:47 +04:00
mmc - > slots [ 0 ] . before_set_reg = hsmmc2_before_set_reg ;
2011-02-28 18:18:04 +03:00
mmc - > slots [ 0 ] . after_set_reg = NULL ;
}
break ;
2011-12-18 04:35:47 +04:00
case 3 :
2011-02-28 18:18:04 +03:00
case 4 :
case 5 :
mmc - > slots [ 0 ] . before_set_reg = NULL ;
mmc - > slots [ 0 ] . after_set_reg = NULL ;
break ;
default :
pr_err ( " MMC%d configuration not supported! \n " , c - > mmc ) ;
kfree ( hc_name ) ;
return - ENODEV ;
}
return 0 ;
}
2012-02-20 21:43:28 +04:00
static int omap_hsmmc_done ;
2012-02-20 21:43:29 +04:00
void omap_hsmmc_late_init ( struct omap2_hsmmc_info * c )
{
struct platform_device * pdev ;
struct omap_mmc_platform_data * mmc_pdata ;
int res ;
if ( omap_hsmmc_done ! = 1 )
return ;
omap_hsmmc_done + + ;
for ( ; c - > mmc ; c + + ) {
if ( ! c - > deferred )
continue ;
pdev = c - > pdev ;
if ( ! pdev )
continue ;
mmc_pdata = pdev - > dev . platform_data ;
if ( ! mmc_pdata )
continue ;
mmc_pdata - > slots [ 0 ] . switch_pin = c - > gpio_cd ;
mmc_pdata - > slots [ 0 ] . gpio_wp = c - > gpio_wp ;
res = omap_device_register ( pdev ) ;
if ( res )
pr_err ( " Could not late init MMC %s \n " ,
c - > name ) ;
}
}
2011-02-28 18:18:04 +03:00
# define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
2012-03-08 06:54:24 +04:00
static void __init omap_hsmmc_init_one ( struct omap2_hsmmc_info * hsmmcinfo ,
2012-02-20 21:43:29 +04:00
int ctrl_nr )
2011-02-28 18:18:04 +03:00
{
struct omap_hwmod * oh ;
2012-02-20 21:43:29 +04:00
struct omap_hwmod * ohs [ 1 ] ;
struct omap_device * od ;
2011-07-22 00:48:45 +04:00
struct platform_device * pdev ;
2011-02-28 18:18:04 +03:00
char oh_name [ MAX_OMAP_MMC_HWMOD_NAME_LEN ] ;
struct omap_mmc_platform_data * mmc_data ;
struct omap_mmc_dev_attr * mmc_dev_attr ;
char * name ;
2012-02-20 21:43:29 +04:00
int res ;
2011-02-28 18:18:04 +03:00
mmc_data = kzalloc ( sizeof ( struct omap_mmc_platform_data ) , GFP_KERNEL ) ;
if ( ! mmc_data ) {
pr_err ( " Cannot allocate memory for mmc device! \n " ) ;
2012-02-20 21:43:29 +04:00
return ;
2011-02-28 18:18:04 +03:00
}
2012-02-20 21:43:29 +04:00
res = omap_hsmmc_pdata_init ( hsmmcinfo , mmc_data ) ;
if ( res < 0 )
goto free_mmc ;
2011-02-28 18:18:04 +03:00
omap_hsmmc_mux ( mmc_data , ( ctrl_nr - 1 ) ) ;
2011-02-28 18:18:05 +03:00
name = " omap_hsmmc " ;
2012-02-20 21:43:29 +04:00
res = snprintf ( oh_name , MAX_OMAP_MMC_HWMOD_NAME_LEN ,
2011-02-28 18:18:04 +03:00
" mmc%d " , ctrl_nr ) ;
2012-02-20 21:43:29 +04:00
WARN ( res > = MAX_OMAP_MMC_HWMOD_NAME_LEN ,
2011-02-28 18:18:04 +03:00
" String buffer overflow in MMC%d device setup \n " , ctrl_nr ) ;
2012-02-20 21:43:29 +04:00
2011-02-28 18:18:04 +03:00
oh = omap_hwmod_lookup ( oh_name ) ;
if ( ! oh ) {
pr_err ( " Could not look up %s \n " , oh_name ) ;
2012-02-20 21:43:29 +04:00
goto free_name ;
2011-02-28 18:18:04 +03:00
}
2012-02-20 21:43:29 +04:00
ohs [ 0 ] = oh ;
2011-02-28 18:18:04 +03:00
if ( oh - > dev_attr ! = NULL ) {
mmc_dev_attr = oh - > dev_attr ;
mmc_data - > controller_flags = mmc_dev_attr - > flags ;
2012-03-16 16:49:54 +04:00
/*
* erratum 2.1 .1 .128 doesn ' t apply if board has
* a transceiver is attached
*/
if ( hsmmcinfo - > transceiver )
mmc_data - > controller_flags & =
~ OMAP_HSMMC_BROKEN_MULTIBLOCK_READ ;
2011-02-28 18:18:04 +03:00
}
2012-02-20 21:43:29 +04:00
pdev = platform_device_alloc ( name , ctrl_nr - 1 ) ;
if ( ! pdev ) {
pr_err ( " Could not allocate pdev for %s \n " , name ) ;
goto free_name ;
2011-02-28 18:18:04 +03:00
}
2012-02-20 21:43:29 +04:00
dev_set_name ( & pdev - > dev , " %s.%d " , pdev - > name , pdev - > id ) ;
2013-01-26 11:48:53 +04:00
od = omap_device_alloc ( pdev , ohs , 1 ) ;
2012-09-21 10:30:50 +04:00
if ( IS_ERR ( od ) ) {
2012-02-20 21:43:29 +04:00
pr_err ( " Could not allocate od for %s \n " , name ) ;
goto put_pdev ;
}
res = platform_device_add_data ( pdev , mmc_data ,
sizeof ( struct omap_mmc_platform_data ) ) ;
if ( res ) {
pr_err ( " Could not add pdata for %s \n " , name ) ;
goto put_pdev ;
}
hsmmcinfo - > pdev = pdev ;
if ( hsmmcinfo - > deferred )
goto free_mmc ;
res = omap_device_register ( pdev ) ;
if ( res ) {
pr_err ( " Could not register od for %s \n " , name ) ;
goto free_od ;
}
goto free_mmc ;
free_od :
omap_device_delete ( od ) ;
put_pdev :
platform_device_put ( pdev ) ;
free_name :
kfree ( mmc_data - > slots [ 0 ] . name ) ;
2011-02-28 18:18:04 +03:00
2012-02-20 21:43:29 +04:00
free_mmc :
2011-02-28 18:18:04 +03:00
kfree ( mmc_data ) ;
}
2008-12-11 04:37:17 +03:00
2012-02-20 21:43:30 +04:00
void __init omap_hsmmc_init ( struct omap2_hsmmc_info * controllers )
2008-12-11 04:37:17 +03:00
{
2012-02-20 21:43:28 +04:00
if ( omap_hsmmc_done )
return ;
omap_hsmmc_done = 1 ;
2013-05-30 23:53:06 +04:00
if ( cpu_is_omap2430 ( ) ) {
control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE ;
control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1 ;
2008-12-11 04:37:17 +03:00
} else {
2013-05-30 23:53:06 +04:00
control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE ;
control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1 ;
2008-12-11 04:37:17 +03:00
}
2011-02-28 18:18:04 +03:00
for ( ; controllers - > mmc ; controllers + + )
2012-02-20 21:43:29 +04:00
omap_hsmmc_init_one ( controllers , controllers - > mmc ) ;
2009-03-24 04:23:47 +03:00
2008-12-11 04:37:17 +03:00
}
# endif