davinci sd卡驱动学习笔记(一)

Davinci MMC SD Driver详解

1、首先我们来看看Makefile

1 #

  2 # Makefile for the kernel mmc device drivers.

  3 #

  4

  5 #

  6 # Core

  7 #

  8 obj-$(CONFIG_MMC)       += mmc_core.o

  9

 10 #

 11 # Media drivers

 12 #

 13 obj-$(CONFIG_MMC_BLOCK)     += mmc_block.o

 14

 15 #

 16 # Host drivers

 17 #

 18 obj-$(CONFIG_MMC_ARMMMCI)   += mmci.o

 19 obj-$(CONFIG_MMC_PXA)       += pxamci.o

 20 obj-$(CONFIG_MMC_IMX)       += imxmmc.o

 21 obj-$(CONFIG_MMC_SDHCI)     += sdhci.o

 22 obj-$(CONFIG_MMC_WBSD)      += wbsd.o

 23 obj-$(CONFIG_MMC_AU1X)      += au1xmmc.o

 24 obj-$(CONFIG_MMC_OMAP)      += omap.o

 25 obj-$(CONFIG_MMC_AT91RM9200)    += at91_mci.o

 26 obj-$(CONFIG_MMC_DAVINCI)   += davinci-mmc.o

 27

 28 mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o

 29

 30 ifeq ($(CONFIG_MMC_DEBUG),y)

 31 EXTRA_CFLAGS += -DDEBUG

 32 endif

Makefile我们会知道davinci sd卡驱动需要davinci-mmc.c mmc.c mmc_queue.c mmc_sysfs.c mmc_block.c

其中davinci-mmc.c是我们需要移植或者编写的sd卡驱动程序,其他基本不需要更改;

以模块方式编得sd卡驱动:davinci-mmc.ko  mmc_block.ko  mmc_core.ko

 

2、下面我们先来看看mmc_core.ko,该模块如其名就是sd卡的核心,我们先找个该模块的入口,在mmc_sysfs.c中:mmc_init函数

 

347 static int __init mmc_init(void)

348 {

349     int ret;

350     workqueue = create_singlethread_workqueue("kmmcd");

351     if(!workqueue)

352         return -ENOMEM;

353     ret = bus_register(&mmc_bus_type);

354     if (ret == 0) {

355         ret = class_register(&mmc_host_class);

356         if (ret)

357             bus_unregister(&mmc_bus_type);

358     }

359     return ret;

360 }

361

362 static void __exit mmc_exit(void)

363 {

364     class_unregister(&mmc_host_class);

365     bus_unregister(&mmc_bus_type);

366     destroy_workqueue(workqueue);

367 }

368

369 module_init(mmc_init);

370 module_exit(mmc_exit);

首先看mmc_init(),这是系统启动后将要调用的;

mmc_init函数中,主要完成3项工作 :
    a:workqueue = create_singlethread_workqueue("kmmcd");//
创见一个单线程的工作队列
    b:bus_register(&mmc_bus_type);//
注册总线
    c:class_register(&mmc_host_class);//
注册mmc_host_class

首先是创建工作队列,名为kmmcd:如下:

  857 tts/1    Ss     0:00 -sh

  858 ?        S      0:00 ./wis-streamer -s

  859 ?        S      0:00 ./wis-streamer -s

  860 ?        S      0:00 ./wis-streamer -s

  861 ?        S      0:00 ./wis-streamer -s

  876 ?        S<     0:00 [kmmcd]

  877 tts/1    R+     0:00 ps x

第二步是注册总线,我们来看下/SYS/BUS/MMC

#

# ls /sys/bus/mmc/

devices  drivers

#

目录下面有devicesdrivers两个目录,其实对应的是bus_type中的两条链表

Bus_type结构如下:

  struct bus_type {

       const char             * name;

 

       struct subsystem    subsys;

       struct kset             drivers;

       struct kset             devices;

       struct klist             klist_devices;

       struct klist             klist_drivers;

 

       struct blocking_notifier_head bus_notifier;

 

       struct bus_attribute * bus_attrs;

       struct device_attribute    * dev_attrs;

       struct driver_attribute    * drv_attrs;

 

       int           (*match)(struct device * dev, struct device_driver * drv);

       int           (*uevent)(struct device *dev, char **envp,

                              int num_envp, char *buffer, int buffer_size);

       int           (*probe)(struct device * dev);

       int           (*remove)(struct device * dev);

       void        (*shutdown)(struct device * dev);

       int           (*suspend)(struct device * dev, pm_message_t state);

       int           (*resume)(struct device * dev);

};

其中name字段为“MMC”,就对应于bus目录下的mmc目录;直插入coredriversdevices目录下面是什么也没有的,然后是注册mmc_host_class类,在/SYS/CLASS/下面会生产host_mmc目录:如下

# ls /sys/class/

/sys/class/cmem/              /sys/class/net/

/sys/class/davinci_display/   /sys/class/ppp/

/sys/class/davinci_system/    /sys/class/rtc-dev/

/sys/class/dm365mmap/         /sys/class/rtc/

/sys/class/edma/              /sys/class/scsi_device/

/sys/class/i 2c -adapter/       /sys/class/scsi_disk/

/sys/class/i 2c -dev/           /sys/class/scsi_generic/

/sys/class/input/             /sys/class/scsi_host/

/sys/class/irqk/              /sys/class/sound/

/sys/class/iscsi_connection/  /sys/class/spi_master/

/sys/class/iscsi_host/        /sys/class/spidev/

/sys/class/iscsi_session/     /sys/class/tty/

/sys/class/iscsi_transport/   /sys/class/usb_device/

/sys/class/mem/               /sys/class/usb_host/

/sys/class/misc/              /sys/class/vc/

/sys/class/mmc_host/          /sys/class/video4linux/

/sys/class/mtd/               /sys/class/vtconsole/

# ls /sys/class/mmc_host/

#

接下来我们看下mmc_bus_type的定义,我们sd卡总线就是这条总线了:

static struct bus_type mmc_bus_type = {

       .name             = "mmc",

       .dev_attrs       = mmc_dev_attrs,

       .match           = mmc_bus_match,

       .uevent           = mmc_bus_uevent,

       .probe            = mmc_bus_probe,

       .remove          = mmc_bus_remove,

       .suspend  = mmc_bus_suspend,

       .resume          = mmc_bus_resume,

};

我们主要关注mmc_bus_matchmmc_bus_probe,此两函数将要在device_registerdriver_register向总线注册设备的时候被调用。

 

下面解释关键的函数:

/*

 * This currently matches any MMC driver to any MMC card - drivers

 * themselves make the decision whether to drive this card in their

 * probe method.  However, we force "bad" cards to fail.

 */

static int mmc_bus_match(struct device *dev, struct device_driver *drv)

{

       struct mmc_card *card = dev_to_mmc_card(dev);

       return !mmc_card_bad(card);

}

#define mmc_card_bad(c)            ((c)->state & MMC_STATE_BAD)

这个函数主要是判断卡的状态;如果卡位bad,则返回真;

 

static int mmc_bus_probe(struct device *dev)

{

       struct mmc_driver *drv = to_mmc_driver(dev->driver);

       struct mmc_card *card = dev_to_mmc_card(dev);

 

       return drv->probe(card);//调用mmc_block里面的probe函数;

}

 

static struct class mmc_host_class = {

       .name             = "mmc_host",//正如我们所看到的那样

       .release    = mmc_host_classdev_release,

};

 

你可能感兴趣的:(driver,职场,休闲,mmc,Davinci)