1、sdio子设备识别添加:
mmc_attach_sdio
sdio_add_func
int sdio_add_func(struct sdio_func *func)
{
int ret;
dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
sdio_set_of_node(func);
ret = device_add(&func->dev);
......
}
static void sdio_set_of_node(struct sdio_func *func)
{
struct mmc_host *host = func->card->host;
func->dev.of_node = mmc_of_find_child_device(host, func->num);
}
struct device_node *mmc_of_find_child_device(struct mmc_host *host,
unsigned func_num)
{
struct device_node *node;
for_each_child_of_node(host->parent->of_node, node) {
if (mmc_of_get_func_num(node) == func_num)
return node;
}
}
func_num值是:
static int mmc_of_get_func_num(struct device_node *node)
{
u32 reg;
of_property_read_u32(node, "reg", ®);
return reg;
}
/*
* SDIO function devices
*/
struct sdio_func {
struct mmc_card *card; /* the card this device belongs to */
struct device dev; /* the device */
......
}
2、设备驱动匹配:
static struct bus_type sdio_bus_type = {
.name = "sdio",
.dev_groups = sdio_dev_groups,
.match = sdio_bus_match,
.uevent = sdio_bus_uevent,
.probe = sdio_bus_probe,
.remove = sdio_bus_remove,
.pm = &sdio_bus_pm_ops,
};
static int sdio_bus_probe(struct device *dev)
{
struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev);
const struct sdio_device_id *id;
id = sdio_match_device(func, drv);
......
drv->probe(func, id);
......
return 0;
}
static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
struct sdio_driver *sdrv)
{
const struct sdio_device_id *ids;
ids = sdrv->id_table;
if (ids) {
while (ids->class || ids->vendor || ids->device) {
if (sdio_match_one(func, ids))
return ids;
ids++;
}
}
return NULL;
}
#define SDIO_ANY_ID (~0)
static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
const struct sdio_device_id *id)
{
if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
return NULL;
if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
return NULL;
if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
return NULL;
return id;
}
3、sdio子设备驱动注册:
struct sdio_device_id bcmsdh_sdmmc_ids[]={
{SDIO_DEVICE(...,...)},
};
struct sdio_driver bcmsdh_sdmmc_driver={
.probe=xxx_probe,
.id=bcmsdh_sdmmc_ids,
};
sdio_register_driver(&bcmsdh_sdmmc_driver);