| static struct bus_type sdio_bus_type = { .name = "sdio", .dev_attrs = sdio_dev_attrs, .match = sdio_bus_match, .uevent = sdio_bus_uevent, .probe = sdio_bus_probe, .remove = sdio_bus_remove, };int sdio_register_bus(void) { return bus_register(&sdio_bus_type); }void sdio_unregister_bus(void) { bus_unregister(&sdio_bus_type); } |
| /* * SDIO function device driver */ struct sdio_driver { char *name; const struct sdio_device_id *id_table; int (*probe)(struct sdio_func *, const struct sdio_device_id *); void (*remove)(struct sdio_func *); struct device_driver drv; }; |
| /* * SDIO function devices */ struct sdio_func { struct mmc_card *card; /* the card this device belongs to */ struct device dev; /* the device */ sdio_irq_handler_t *irq_handler; /* IRQ callback */ unsigned int num; /* function number */ unsigned char class; /* standard interface class */ unsigned short vendor; /* vendor id */ unsigned short device; /* device id */ unsigned max_blksize; /* maximum block size */ unsigned cur_blksize; /* current block size */ unsigned enable_timeout; /* max enable timeout in msec */ unsigned int state; /* function state */ #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ u8 tmpbuf[4]; /* DMA:able scratch buffer */ unsigned num_info; /* number of info strings */ const char **info; /* info strings */ struct sdio_func_tuple *tuples; }; |
| static struct sdio_driver if_sdio_driver = { .name = "libertas_sdio", .id_table = if_sdio_ids, .probe = if_sdio_probe, .remove = if_sdio_remove, };static int __init if_sdio_init_module(void) { int ret = 0; ret = sdio_register_driver(&if_sdio_driver); return ret; } static void __exit if_sdio_exit_module(void) { sdio_unregister_driver(&if_sdio_driver); } |
| struct mmc_host { struct device *parent; struct device class_dev; int index; const struct mmc_host_ops *ops; unsigned int f_min; unsigned int f_max; u32 ocr_avail; unsigned long caps; /* Host capabilities */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */ unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */ unsigned short unused; unsigned int max_req_size; /* maximum number of bytes in one req */ unsigned int max_blk_size; /* maximum size of one mmc block */ unsigned int max_blk_count; /* maximum number of blocks in one req */ /* private data */ spinlock_t lock; /* lock for claim and bus ops */ struct mmc_ios ios; /* current io bus settings */ u32 ocr; /* the current OCR setting */ /* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; unsigned int claimed:1; /* host exclusively claimed */ unsigned int bus_dead:1; /* bus has been released */ #ifdef CONFIG_MMC_DEBUG unsigned int removed:1; /* host is being removed */ #endif struct mmc_card *card; /* device attached to this host */ wait_queue_head_t wq; struct delayed_work detect; const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; atomic_t sdio_irq_thread_abort;#ifdef CONFIG_LEDS_TRIGGERS struct led_trigger *led; /* activity led */ #endif struct dentry *debugfs_root; unsigned long private[0] ____cacheline_aligned; }; |
| //drivers/mmc/core/host.cstatic struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, };int mmc_register_host_class(void) { return class_register(&mmc_host_class); }void mmc_unregister_host_class(void) { class_unregister(&mmc_host_class); } |
| struct mmc_host_ops { void (*request)(struct mmc_host *host, struct mmc_request *req); void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); int (*get_ro)(struct mmc_host *host); int (*get_cd)(struct mmc_host *host); void (*enable_sdio_irq)(struct mmc_host *host, int enable); }; |
| static struct mmc_host_ops s3c_hsmmc_ops = { .request = s3c_hsmmc_request, .set_ios = s3c_hsmmc_set_ios, }; |
| 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, };int mmc_register_bus(void) { return bus_register(&mmc_bus_type); }void mmc_unregister_bus(void) { bus_unregister(&mmc_bus_type); } |
| // include/linux/mmc/card.h/* * 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 */ 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 device driver (e.g., Flash card, I/O card...) */ struct mmc_driver { struct device_driver drv; int (*probe)(struct mmc_card *); void (*remove)(struct mmc_card *); int (*suspend)(struct mmc_card *, pm_message_t); int (*resume)(struct mmc_card *); };extern int mmc_register_driver(struct mmc_driver *); extern void mmc_unregister_driver(struct mmc_driver *) |
| //driver/mmc/core/block.cstatic struct mmc_driver mmc_driver = { .drv = { .name = "mmcblk", }, .probe = mmc_blk_probe, .remove = mmc_blk_remove, .suspend = mmc_blk_suspend, .resume = mmc_blk_resume, }; |