something mass...............
1.
#define to_platform_device(x) container_of((x), struct platform_device, dev)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
2.sdio driver module
platform device:
struct platform_device {
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
static struct platform_device mmc1_device = {
.name = "mmc_controller",
.id = 0,
.resource = mmc1_resources,
.num_resources = ARRAY_SIZE(mmc1_resources),
.dev = {
.dma_mask = &pxa_mmc_controller_dmamask,
.release = pxa_mmc_controller_release,
.coherent_dma_mask = 0xffffffff,
},
};
platform driver:
static struct device_driver pxa_mss_host_driver = {
.name = "mmc_controller",
.bus = &platform_bus_type,
.probe = pxa_mss_host_probe,
.remove = pxa_mss_host_remove,
.shutdown = pxa_mss_host_shutdown,
.suspend = pxa_mss_host_suspend,
.resume = pxa_mss_host_resume,
};
3.define a new type bus: mmc_bus. pluged in the platform bus?
static struct bus_type mmc_bus_type = {
.name = "mmc_bus",
.match = mmc_bus_match,
.hotplug = mmc_bus_hotplug,
.suspend = mmc_bus_suspend,s
.resume = mmc_bus_resume,
};
protocol struct:
struct mss_prot_driver {
char *name; /* protocol name */
struct list_head node;
int (*prot_entry)(struct mss_card *, unsigned int, void *, void *);
int (*attach_card) (struct mss_card *);
void (*detach_card) (struct mss_card *);
int (*get_errno) (struct mss_card *);
};
A:
for the condition the card insert before the driver was insmod, the flow as below:
1.in the platform driver probe function,when we init the slots of the host,
we have request the irq for the insert action:
request_irq(irq, pxa_slot_gpio_irq, 0,
"MMC card detection", (void *)slot);
the irq was associated with a slot, so we send (void *)slot to the irq func.
2.when the card was inserted ,in the irq func ,we queued the delayed work:
queue_delayed_work(pxa_host->work_queue, &pxa_slot->card_change, 20);
and int the bottom half: mss_scan_slot(slot);
note when we detected the state of the slot, we should down the seamphone of the slot,to lock.
int the mss_scan_slot, we deterimned the real state of the slot,if the slot is empty, we call the func
mss_insert_card(slot);
3.before this step, the card which the slot point to is NULL. in the insert card func, we should give it
a new real card which have the "dev" in it struct.and we go to the more precise func:
_mss_insert_card(card);
in the _mss_insert_card(card),first, we find which protocol the card follow, SD memory or SDIO.
we loop all the protocol_struct stuff and find one if there is.the protocol driver was inserted in
the protocol driver list when the protocol driver module_init.
mss_attach_protocol(card)
{
list_for_entry(protocol_driver_list)
{
sdio_prot_attach(card)--> //create a sdio_card structure
sdio_prot_entry(card, MSS_RECOGNIZE_CARD, NULL, NULL)
//call the new sdio_protocol entry func,to send some cmd from the mmc_host,
//detrimine if the card is a sdio card from the cmd response,so we need to
//claim host here, be careful the lock
}
card->prot_driver = pdrv;
//reutrn with the new found sdio protocol driver
return 0;
}
4. card->prot_driver->prot_entry(card, MSS_INIT_CARD, NULL, NULL);
we init the card from sdio_prot entry func.
send_cmd_5 ,wait for completion--->
host_write_cmd5 to register --->
host_get_response_irq, complete --->
prot_entry return.
5. register the recoginezed card to mmc bus, by invoke :
card->dev.release = mss_card_device_release;
card->dev.parent = card->slot->host->dev;
/* set bus_id and name */
snprintf(&card->dev.bus_id[0], sizeof(card->dev.bus_id), "mmc%d%d",
card->slot->host->id, card->slot->id);
card->dev.bus = &mmc_bus_type;
device_register(card->dev); //the card structure contains of the dev structure
6. when the device_register was called, and the dev.bus==mmc_bus_type, the "match"
func of the mmc_bus was invoked.
in the mss_core.c, in the module_init,we call the bus_register to create a new type bus:
static struct bus_type mmc_bus_type = {
.name = "mmc_bus",
.match = mmc_bus_match,
.hotplug = mmc_bus_hotplug,
.suspend = mmc_bus_suspend,
.resume = mmc_bus_resume,
};
7. in the "match" func,all the drivers whose bus type is "mmc_bus" was tested, to see if the driver
colud deal with the device "card->dev"
if(card->card_type == MSS_SDIO_CARD && driver->driver_type == 2)
{
printk("SDIO CARD INSERTED!\n");
return 0;
}
if the "match" func return 0, means match ok. than the "probe" func of the driver was invoked,
and go on..
8. if no match, then sometims later, we inserted a new driver, and when driver_register(cmmb_driver),
the "match" func was invoked ag.
9. when the new driver we make for the sdio-device, we read and write the device just by
prot_entry to send cmd to the protocol driver.
[platform driver] [platform device]
[platform bus]
阅读(1758) | 评论(1) | 转发(0) |