2.6.28上的sd/mmc/sdio驱动

本文详细阐述了解决SDIO驱动在配置冲突及热插拔时遇到的问题,包括GPIO配置、中断处理、bus_width指定等关键步骤。通过调整配置,实现了稳定识别SDIO卡并解决了热插拔不可用的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

def_data用setup来设置,

首先对def_data有个赋值,然后通过对其的引用来进行setup,最后达到填充了全部的结构体。

 

 

 

 

 

 

  mod_timer(&host->timer, jiffies + 10 * HZ);  //try this
line 868 in sdhci.c

结果发现不是这个原因

 

后来又发现,昨天晚上用华恒的kernel上一版板子上面试验的时候,偶尔出现的-110是不是错觉,确实是

 


没有设置中断怎么也跳

idea GPG6 GPN10
LIYUTAI GPG6
hhtech GPG6 for sd
       GPN11/XEINT11  sdio

int里面NORINTSTS0 0x7C200030

在老板子A板,确实有一次没有起来,烧的是必定起来的kernel,后来每次都这样了

新班子上面
static void wifi_enable_power(void)
{
 //    gpio_direction_output(S3C_GPK15, 1);
        gpio_direction_output(S3C_GPP13, 1);
//     gpio_direction_output(S3C_GPQ3, 0);
}
一定要拉成1,不然起不来,因为不然就没有VDD_WIFI了

两个detect的脚的关系

27-57
27-60
最下方

GPG6是无关的也就是MMC DETECT 1

移到初始化里面就可以了,不然会调用三次,第一次复位的中间开开始正常probe又被第二次复位打断。

在这样修改后,2.6.24的kernel在板子上每次都能找到sdio卡了。(此时是把mmc0和mmc2屏蔽了之后测的)。

 

    果然,插上sd卡就是110了,说明检测卡插入的系统默认的mmccd0没有在没有插sd卡的时候没有起作用。

 

    最后解决问题,是再最不可能的地方出的问题,竟然没有指定bus_width,因为bus_width是通过card_type来指定的,而card_type是再mmc_rescan里面获得的,而gpio的初始化涉及到需要初始化多少根数据线,这样在最初的时候mmc1的gpio就没有完全的初始化好。但是mmc0为什么又可以呢。现在只是硬性的把bus_width写成4.

 

mach-smdk6410.c
dev-hsmmc.c
 .cfg_ext_cd = setup_sdhci0_irq_cd,
 .detect_ext_cd = detect_sdhci0_irq_cd,
 .ext_cd  = S3C_EINT(13),
这里添加后就可以认出mmc0了
dev-hsmmc1.c
#elif 1
 .host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |
    MMC_CAP_SD_HIGHSPEED | MMC_CAP_ON_BOARD),
#endif
必须添加,不然mmc控制器的中卡状态对应位只能靠mmc0的中断来置位

 

还有个问题,不能热插拔。

 

static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
{
 unsigned long rate = clk_get_rate(clk->parent);

 printk(KERN_DEBUG "%s: parent is %ld/n", __func__, rate);

 if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
  rate /= 2;

 return rate;
}

 

如果修改kernel改成256M mem

 

很奇怪,mmc2写上了MMC_CAP_ON_BOARD。可能是原来就是用来做为SDIO用的。

 

 

setup-sdhci.c中

void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
 unsigned int gpio;
 unsigned int end;

 end = S3C64XX_GPG(2 + width);

 /* Set all the necessary GPG pins to special-function 0 */
 for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
  s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
  s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
 }
#if 0 //for armsys6410
 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
 s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
#endif
}

把屏蔽的恢复应该就可以了。

 

再看看别的版本的kernel是怎么写的。

 

原因竟然是同一个GPIO只能配一种探测对象--mmc0 or mmc1。

 

 和文先讨论了sdio驱动,发现在power_up的时候默认先设置成1线,然后再idle的时候切换到4线,但是28内核就没有切换。为什么人家传给我的就可以不用设定成4呢。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值