从这一节起,我们正式进入mmc子系统学习笔记内容,这边walfred就根据自己的观点,整理了一份Linux下mmc子系统的结构组织框架,相信带着这个框架来理解学习mmc子系统应该会起到不错的效果。下面是mmc子系统的结构组织:
在Linux中,系统中mmc子系统本身没有任何README文档,所以此算一个"帮助文档"。其将涉及到3条总线,2块设备,2个驱动。
三条总线
总线名 | platform | mmc | sdio |
类型 | struct bus_type | ||
变量名 | platform_bus | mmc_bus_type | sdio_bus_type |
这个我们可以在/sys/bus中查看。
两块设备
设备名 | msm_sdcc | mmc_card |
类型 | struct platform_device | struct mmc_card |
备注 | msm_sdcc(soc) | 由前者sdcc的驱动,对mmc/sd/sdio的统一抽象 |
msm_sdcc(全称应该是sdcardcontroller集成到soc,所以属platform_device,优点具有较好的移植性和安全性),mmc_card(由前者sdcc的驱动,对mmc/sd/sdio的统一抽象);
两组驱动
驱动名 | msmsdcc_driver | mmc_driver |
类型 | struct platform_driver | struct mmc_driver |
备注 |
|
|
对应与上面的2块设备,分别是msmsdcc_driver,mmc_driver;
它们之间的关系
关于platform总线,下文研究的主线一
驱动msmsdcc_driver,以及设备msm_sdcc是通过platform_bus关联。
关于mmc总线,下文研究的主线二
驱动mmc_driver,以及设备mmc_card是通过该总线关联
关于sdio总线
尚未过多研究,此处暂时并考虑。以后会陆续补充。
相关结构体
这是描述一个platform设备的
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
const struct platform_device_id *id_entry;
/* arch specific additions */
struct pdev_archdata archdata;
};
这是msm_device_sdc设备
struct platform_device msm_device_sdc1 = {
.name = "msm_sdcc",//platform_device名
.id = 1,
.num_resources = ARRAY_SIZE(resources_sdc1),//资源个数
.resource = resources_sdc1,//指向资源的指针
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
platform driver这是描述一个msmsdcc_driver设备驱动的
static struct platform_driver msmsdcc_driver = {
.probe = msmsdcc_probe,
.suspend = msmsdcc_suspend,
.resume = msmsdcc_resume,
.driver = {
.name = "msm_sdcc",
},
};
描述mmc card的结构体
/*
* MMC device
*/
struct mmc_card {
struct mmc_host *host; /* the host this device belongs to */
struct device dev; /* the device */
unsigned int rca; /* relative card address of device */
unsigned int type; /* card type */
#define MMC_TYPE_MMC 0 /* MMC card */
#define MMC_TYPE_SD 1 /* SD card */
#define MMC_TYPE_SDIO 2 /* SDIO card */
unsigned int state; /* (our) card state */
#define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
#define MMC_STATE_READONLY (1<<1) /* card is read-only */
#define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */
#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
/* for byte mode */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
u32 raw_scr[2]; /* raw card SCR */
struct mmc_cid cid; /* card identification */
struct mmc_csd csd; /* card specific */
struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */
struct sd_scr scr; /* extra SD information */
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
unsigned int sdio_funcs; /* number of SDIO functions */
struct sdio_cccr cccr; /* common card info */
struct sdio_cis cis; /* common tuple info */
struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples; /* unknown common tuples */
struct dentry *debugfs_root;
};
描述mmc card驱动的结构体
static struct mmc_driver mmc_driver = {
.drv = {
.name = "mmcblk",
},
.probe = mmc_blk_probe,
.remove = mmc_blk_remove,
.suspend = mmc_blk_suspend,
.resume = mmc_blk_resume,
};
控制的结构体
struct msmsdcc_host {
struct resource *cmd_irqres;
struct resource *pio_irqres;
struct resource *memres;
struct resource *dmares;
void __iomem *base;
int pdev_id;
unsigned int stat_irq;
struct msmsdcc_curr_req curr;
struct mmc_host *mmc;
struct clk *clk; /* main MMC bus clock */
struct clk *pclk; /* SDCC peripheral bus clock */
unsigned int clks_on; /* set if clocks are enabled */
struct timer_list busclk_timer;
unsigned int eject; /* eject state */
spinlock_t lock;
unsigned int clk_rate; /* Current clock rate */
unsigned int pclk_rate;
u32 pwr;
u32 saved_irq0mask; /* MMCIMASK0 reg value */
struct mmc_platform_data *plat;
struct timer_list timer;
unsigned int oldstat;
struct msmsdcc_dma_data dma;
struct msmsdcc_pio_data pio;
int cmdpoll;
struct msmsdcc_stats stats;
#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ
struct work_struct resume_task;
#endif
/* Command parameters */
unsigned int cmd_timeout;
unsigned int cmd_pio_irqmask;
unsigned int cmd_datactrl;
struct mmc_command *cmd_cmd;
u32 cmd_c;
};