MMC subsystem series (in continuous update):
[MMC subsystem] concepts and frameworks
[MMC Subsystem] MMC core (chapter I)--Overview
[MMC Subsystem] MMC core (chapter II)--Description of data structure and macro definitions
[MMC Subsystem] MMC core (chapter III)--bus module description
[MMC Subsystem] MMC core (fourth chapter)--host module description
[MMC Subsystem] MMC core (fifth chapter)--card related modules (MMC type card)
[MMC Subsystem] MMC core (sixth chapter)--MMC Core Master Module
It is recommended that you refer to the [MMC subsystem] concepts and frameworks and [MMC Subsystem] MMC core (chapter I)-Overview for an understanding of the whole.
========================================================================================================= 0, Description
The corresponding code DRIVERS/MMC/CORE/BUS.C.
Abstract out the virtual MMC bus to implement MMC bus operations. First, API overview 1. MMC Bus related Mmc_register_bus & Mmc_unregister_bus
Used to register and uninstall MMC bus (Virtual MMC bus) into the device driver model.
Prototype: int mmc_register_bus (void)
prototype: void Mmc_unregister_bus (void)
2, MMC driver related
Mmc_register_driver & Mmc_unregister_driver
Used to register and unload the struct mmc_driver *drv to Mmc_bus. Mmc_driver is the MMC core abstract card device driver.
Prototype: int mmc_register_driver (struct mmc_driver *drv)
prototype: void Mmc_unregister_driver (struct mmc_driver *drv)
3. MMC Card related
Mmc_alloc_card & Mmc_release_card
Used to assign or release a struct mmc_card struct, creating an association between the MMC host and the MMC bus.
Prototype: struct Mmc_card *mmc_alloc_card (struct mmc_host *host, struct device_type *type)
parameter description: host--"The card to be assigned belongs to MMC_ host,type--"Device type.
prototype: static void Mmc_release_card (struct device *dev)
Mmc_add_card & Mmc_remove_card
Used to register or unload the struct mmc_card to Mmc_bus.
Prototype: int mmc_add_card (struct Mmc_card *card)
prototype: void Mmc_remove_card (struct mmc_card *card)
second, data structure
1, Mmc_bus_type
The Mmc_bus_type represents the MMC virtual bus. The contents are as follows:
The static struct Bus_type Mmc_bus_type = {. Name = "mmc", and//The MMC directory is generated under/sys/bus. dev_a Ttrs = mmc_dev_attrs,//bus under Device inherited properties, you can see the/sys/bus/mmc/devices/mmc0:0001/type property is here. Match = Mmc_bus_match,//For matching of device and driver on MMC bus. uevent = mmc_bus_uevent,. Probe = Mmc_bus_probe, When match succeeds, the probe action is performed. remove = Mmc_bus_remove,. Shutdown = Mmc_bus_shutdown,. PM =
&mmc_bus_pm_ops,//A collection of power management operations for the device that is hung on the MMC bus}; /***************************match method ***************************/static int mmc_bus_match (struct device *dev, struct Device_driver *drv) {return 1;
Returns 1 unconditionally, stating that device (Mmc_card) and Driver (Mmc_driver) on the mounted MMC bus are unconditionally matched. }/****************************probe method ***************************/static int mmc_bus_probe (struct device *dev) {str
UCT Mmc_driver *drv = To_mmc_driver (dev->driver);
struct Mmc_card *card = Mmc_dev_to_card (dev); return Drv->probe (card); Call the probe operation in Mmc_driver directly, for BLOCK.C is mmc_blk_probe}
In addition, by using the Mmc_bus match method above, we can know that the Mmc_card and mmc_driver on the Mount MMC bus are unconditionally matched. Third, Interface code description 1, mmc_register_bus implementation
Used to register an MMC bus (virtual MMC bus) into the device driver model.
int Mmc_register_bus (void)
{
return bus_register (&mmc_bus_type); Register a virtual bus with Mmc_bus_type for Bus_type, about Mmc_bus_type already explained above
}
Later we will mmc_bus_type this bus called Mmc_bus.
Related nodes:/sys/bus/mmc. 2, Mmc_register_driver realization
Used to register the struct mmc_driver *drv to Mmc_bus. Mmc_driver is the MMC core abstract card device driver.
int mmc_register_driver (struct mmc_driver *drv)
{
Drv->drv.bus = &mmc_bus_type; By setting mmc_driver--"device_driver--" Bus_type to set Mmc_driver bus to Mmc_bus
return Driver_register (&drv-> DRV); This will hang the mmc_driver on the Mmc_bus.
}
Related nodes:/sys/bus/mmc/drivers. 3, Mmc_alloc_card realization
The
is used to assign a struct mmc_card struct to create an association between the MMC host and the MMC bus.
struct Mmc_card *mmc_alloc_card (struct mmc_host *host, struct device_type *type) {struct Mmc_card *card; Card = kzalloc (sizeof (struct mmc_card), gfp_kernel);
Assign a Mmc_card if (!card) return err_ptr (-ENOMEM); Card->host = host;
Associated Mmc_card and Mmc_host device_initialize (&card->dev);
Card->dev.parent = Mmc_classdev (host); The card device's parent device is mmc_host Classdev,//registered to the device driver model, and the corresponding card node is generated in the/SYS/CLASS/MMC_HOST/MMC0 directory, such as mmc0:0
001 Card->dev.bus = &mmc_bus_type;
The bus that sets the card is Mmc_bus_type so that Mmc_card is registered to the device driver model and then hangs under Mmc_bus.
will generate the corresponding card node in the/sys/bus/mmc/devices/directory, such as mmc0:0001 card->dev.release = Mmc_release_card; Card->dev.type = type; Set Device type Spin_lock_init (&card->bkops_info.bkops_stats.lock); Initialize Spin_lock spin_lock_init (&card->wr_pack_stats.lock);
Initialize Spin_lock return card; }
4, Mmc_add_card realization
Used to register the struct mmc_card to Mmc_bus.
/* Register a new MMC card with the driver model.
*/int Mmc_add_card (struct mmc_card *card) {int ret;
/* The following is used to print card registration information */const char *type;
const char *uhs_bus_speed_mode = ""; Set the speed mode of the string, in order to print out the card information//... if (MMC_HOST_IS_SPI (card->host)) {pr_info ("%s:new%s%s%s CA Rd on Spi\n ", Mmc_hostname (Card->host), mmc_card_highspeed (card)? "High Speed": "", Mmc_card_ddr_mode (card)? "
DDR ":" ", type);
} else {pr_info ("%s:new%s%s%s%s%s%s Card at address%04x\n", Mmc_hostname (Card->host), MMC_CARD_UHS (card)? "Ultra High Speed": (Mmc_card_highspeed (card)? " High speed ":"), (mmc_card_hs400 (card)? " HS400 ":"), (mmc_card_hs200 (card)? " HS200 ":"), Mmc_card_ddr_mode (card)? "
DDR ":", Uhs_bus_speed_mode, type, CARD->RCA); }//here will print out a string of card information//EG:mmc0:new HS200 MMC Card at address 0001/* Set the card's DEBUG node */#ifdef CONFIG_DEBUG_FS Mmc_add_card_debugfs (card); Create a card corresponding to the debug node, the corresponding path for example:/sys/kernel/debug/mmc0/mmc0:0001 #endif mmc_init_context_info (card->host);
Initialize the synchronized text information */* The following enable card device's PM Runtime function */ret = pm_runtime_set_active (&card->dev); if (ret) Pr_err ("%s:%s:failed setting Runtime Active:ret:%d\n", Mmc_hostname (card->host), __
FUNC__, ret); else if (!mmc_card_sdio (card) && mmc_use_core_runtime_pm (card->host)) pm_runtime_enable (&card->d
EV);
/* Added to the device driver Model */ret = Device_add (&card->dev); The/sys/bus/mmc/devices/mmc0:0001 node and the/sys/class/mmc_host/mmc0/mmc0:0001 node are created */enable asynchronous device suspend, initialize RUNTIME_PM_
Timeout attribute */device_enable_async_suspend (&CARD->DEV); if (mmc_use_core_runtime_pm (card->host) &&!mmc_card_sdio (card)) {card->rpm_attrib.show = Show_rpm_
Delay Card->rpm_attrib.store = Store_rpm_delay;
Sysfs_attr_init (&CARD->RPM_ATTRIB.ATTR);
Card->rpm_attrib.attr.name = "Runtime_pm_timeout"; Card->rpm_attrib.attr.mode = S_irugo |
S_IWUSR;
ret = Device_create_file (&card->dev, &card->rpm_attrib); if (ret) Pr_err ("%s:%s:creating runtime pm SYSFS entry:failed:%d\n", Mmc_hostname (card-
>host), __func__, ret);
/* Default timeout is seconds */card->idle_timeout = Runtime_suspend_delay_ms;
}/* Set the state identity of the MMC card */mmc_card_set_present (card); Set the card's mmc_state_present status//#define MMC_STATE_PRESENT (1<<0)//PRESENT in SYSFS *//
Indicates that the card has been combined into SYSFS return 0; }
Related nodes:
/sys/bus/mmc/devices/mmc0:0001
/sys/class/mmc_host/mmc0/mmc0:0001
/sys/kernel/debug/mmc0/ mmc0:0001