[MMC Subsystem] MMC core (fourth chapter)--host module description

Source: Internet
Author: User
Tags unique id

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/host.c,drivers/mmc/core/host.h.
Implementation of the application of MMC host for the underlying host controller driver and the registered API, etc., and the implementation of host-related properties. First, API overview 1. MMC host assignment, registration related Mmc_alloc_host & Mmc_free_host
The underlying host controller driver invocation is used to assign or release a struct mmc_host struct, associate it to Mmc_host_class, and do some initialization.

    Prototype: struct mmc_host *mmc_alloc_host (int extra, struct device *dev)
    parameter description: extra--"Mmc_host" The length of private data, and MMC_ The host struct is assigned together, dev--, the device structure of the
                     underlying host controller, used as the parent device prototype for mmc_host

    : void Mmc_free_host (struct MMC_ Host *host)
Mmc_add_host & Mmc_remove_host
The underlying host controller drives the call, registers or uninstalls the mmc_host to the device driver, adds it to the Sys class, and sets the corresponding debug directory. Then start Mmc_host.
    Prototype: int mmc_add_host (struct mmc_host *host)
    prototype: void Mmc_remove_host (struct mmc_host *host)
2. MMC Host class related Mmc_register_host_class & Mmc_unregister_host_class
Register or uninstall the Mmc_host class.
    Prototype: int mmc_register_host_class (void)
    prototype: void Mmc_unregister_host_class (void)
3, MMC host property resolution related Mmc_of_parse
The underlying host controller drives the call, parsing the partial properties of the Mmc_host DTSi node.
    Prototype: void Mmc_of_parse (struct mmc_host *host)
4. MMC Host clock correlation Mmc_host_clk_hold & Mmc_host_clk_release
MMC Core Master module call for getting the host clock and freeing the host clock second, data structure 1, Mmc_host_class

The Mmc_host_class represents the Mmc_host class. The contents are as follows:

static struct Class Mmc_host_class = {
    . Name       = "Mmc_host",        //Added to SYS file system, generates/sys/class/mmc_host this directory
    . Dev_release    = mmc_host_classdev_release,    //The corresponding operation to be done after a device is removed from the Mmc_host class
    . PM     = &mmc_host_pm_ops,        //PM Power management operation for host under this class
};

static const struct Dev_pm_ops mmc_host_pm_ops = {
    Set_system_sleep_pm_ops (mmc_host_suspend, Mmc_host_resume)
    set_runtime_pm_ops (Mmc_host_runtime_suspend, Mmc_host_runtime_resume,
               pm_generic_runtime_idle)
};
Concrete function implementation encountered a supplementary
2, Clk_scaling_attr_grp

Some attribute groups associated with clock scaling (clk_scaling)

static struct attribute *clk_scaling_attrs[] = {
    &dev_attr_enable.attr,
    &dev_attr_up_threshold.attr ,
    &dev_attr_down_threshold.attr,
    &dev_attr_polling_interval.attr,
    NULL,
};

static struct Attribute_group clk_scaling_attr_grp = {
    . Name = "Clk_scaling",
    . Attrs = Clk_scaling_attrs,
} ;

corresponding to the/sys/class/mmc_host/mmc0/clk_scaling directory of Properties 3, Dev_attr_grp

Device-related attribute group, only the perf attribute is defined

static struct attribute *dev_attrs[] = {
#ifdef config_mmc_perf_profiling
    &dev_attr_perf.attr,
# endif
    NULL,
};
static struct Attribute_group dev_attr_grp = {
    . attrs = Dev_attrs,
};

Corresponding/sys/class/mmc_host/mmc0/perf attribute Three, interface code description 1, mmc_register_host_class implementation

Register Mmc_host class.

int Mmc_register_host_class (void)
{
    return class_register (&mmc_host_class);   Create a class with Mmc_host_class as the class, about Mmc_host_class has been explained in the above data structure
}

Related nodes:/sys/class/mmc_host 2, mmc_alloc_host implementation

The underlying host controller driver invocation is used to assign a struct mmc_host struct, associate it to Mmc_host_class, and do a partial initialization operation.

Primary work: Allocate memory space Initialize its class device (corresponding/SYS/CLASS/MMC0 node) initialization of Clock Gate, lock, Work queue, Wakelock, detect work Initializes the detect member (that is, the detection work) to Mmc_rescan

The code is as follows:

/** * Mmc_alloc_host-initialise the per-host structure. * @extra: sizeof private Data structure * @dev: Pointer to host device model structure * * Initialise the per-host s
 Tructure. 
*/struct Mmc_host *mmc_alloc_host (int extra, struct device *dev) {//Parameter description: extra--"Mmc_host" the length of the private data will be assigned with the MMC_HOST structure,
    dev--"The device structure of the underlying host controller, used as the parent device int err of the device of Mmc_host;

struct Mmc_host *host;
    /* Allocates memory space, where more than extra bytes are allocated as private data */host = Kzalloc (sizeof (struct mmc_host) + extra, gfp_kernel);

    if (!host) return NULL; /* Scanning will is enabled when we ' re ready */* because just assigned a mmc_host,host is not prepared, so disable rescan here, that is, set Mmc_host->rescan_   Disable host->rescan_disable = 1;
    In Mmc_start_host will go to enable/* Assign a unique ID number to the Mmc_host, set to Host->index */idr_preload (Gfp_kernel);
    Spin_lock (&mmc_host_lock);
    Err = Idr_alloc (&MMC_HOST_IDR, host, 0, 0, gfp_nowait);
    if (Err >= 0) Host->index = err; Spin_uNlock (&mmc_host_lock);
    Idr_preload_end ();

if (Err < 0) Goto free;   /* Set mmc_host name */dev_set_name (&host->class_dev, "mmc%d", Host->index); The name of the Mmc_host is made up of the ID number of the mmc_host, such as MMC0, MMC1/* Associated Mmc_host Class_dev and initialized */* Class_dev represents the device structure of Mmc_host,                              is its embodiment in the device-driven model */host->parent = dev;             
        The Mmc_host parent is set to the device host->class_dev.parent = Dev that is converted from the host controller node; The parent of the Mmc_host device (Class_dev) is set to the device//registered to SYSFS that corresponds to the host controller node, and the/sys/bus/platform/device is generated accordingly.  S/7824900.SDHCI/MMC_HOST/MMC0//Where 7824900.SDHCI means the device host->class_dev.class that the qcom's host controller node is converted from
         &mmc_host_class; After the class of Mmc_device (Class_dev) is set to Mmc_host_class//registered to SYSFS,/SYS/CLASS/MMC_HOST/MMC0 Device_initialize is generated accordingly (&A   Mp;host->class_dev); Initialize MMC_HOST-&GT;CLASS_DEV/* Clock Gate, lock, Work queue, Wakelock, detect initialization of work */Mmc_host_clk_init(host);
    Mutex_init (&host->slot.lock);

    HOST-&GT;SLOT.CD_IRQ =-einval;
    Spin_lock_init (&host->lock);
    Init_waitqueue_head (&AMP;HOST-&GT;WQ); Host->wlock_name = kasprintf (Gfp_kernel, "%s_detect", Mmc_hostname (host)); The name of the set Detect_wake_lock is Mmc0_detect, which is used when the card is detected wake_lock_init (&host->detect_wake_lock, Wake_lock_   SUSPEND, Host->wlock_name); Initialization Detect_wake_lock//Can be/sys/kernel/debug/wakeup_sources, Mmc0_detect and Mmc1_detect two wakelock INIT are generated accordingly
        _delayed_work (&host->detect, Mmc_rescan); 。。。。 This is very important ....
The initialization detect work is Mmc_rescan, the subsequent dispatch host->detect to detect if there is a card insert, it will be called to Mmc_rescan.
#ifdef config_pm host->pm_notify.notifier_call = mmc_pm_notify;   #endif/* Initialization of some size */host->max_segs = 1; Initializes the maximum support segment (modified by the host itself according to the hardware) and can be modified by/sys/block/mmcblk0/queue/max_segments host->max_seg_size = Page_cache_size   ;   Initialize segment size, (modified by host itself according to hardware) host->max_req_size = Page_cache_size; The first time the MMC requests the mostLarge number of knots host->max_blk_size = 512; Maximum number of bytes for a block host->max_blk_count = page_cache_size/512;

The maximum number of blocks requested by an MMC return host;
    Free:kfree (host);
return NULL; }

The emphasis here is on a mmc_host->detect=mmc_rescan, which is called to Mmc_rescan when Mmc_host's detect work is executed.
Related nodes, take mmc_host0 as an example:
/sys/bus/platform/devices/7824900.sdhci/mmc_host/mmc0
/SYS/CLASS/MMC_HOST/MMC0 3, mmc_add_host realization

The underlying host controller drives the call, registers the Mmc_host to the device driver, adds it to the Sys class, and sets the corresponding debug directory. Then start Mmc_host. Main work:
The Enable PM Runtime feature adds Mmc_host Class_dev to the device driver model, generating the corresponding node initialization in SYSFS mmc_host related debug directory settings Mmc_host Class_dev property calls Mmc_ Start_host boot host (into the part of the MMC Core Master module)

/** * mmc_add_host-initialise Host hardware * @host: MMC host * Register the host with the driver model.
 The host must is * prepared to start servicing requests before this function * completes. */int Mmc_add_host (struct mmc_host *host) {int err;/* Enable MMC host's Class_dev PM runtime function */err = Pm_runtime_set
    _active (&host->class_dev); if (err) Pr_err ("%s:%s:failed setting Runtime Active:err:%d\n", Mmc_hostname (host), __func__, E
    RR);

else if (MMC_USE_CORE_RUNTIME_PM (host)) pm_runtime_enable (&host->class_dev);
        /* Add Mmc_host->class_dev to the device driver model via Device_add, generate the corresponding node under SYS */err = Device_add (&host->class_dev);
        The Class_dev associated with mmc_host in Mmc_alloc_host can generate the following two nodes///sys/bus/platform/devices/7824900.sdhci/mmc_host/mmc0 /SYS/CLASS/MMC_HOST/MMC0/* Enable Class_dev asynchronous suspend function for MMC host */Device_enable_async_suspend (&host->c
    Lass_dev); Led_trigger_register_simple(Dev_name (&host->class_dev), &host->led);
/* Set the DEBUG node for Mmc_host */#ifdef CONFIG_DEBUG_FS Mmc_add_host_debugfs (host);
        The/SYS/KERNEL/DEBUG/MMC0///Mmc_host_clk_sysfs_init (host) of the Class_dev of the MMC host is set for the #endif//corresponding SYS node for the following settings:/*
    Corresponds to/sys/class/mmc_host/mmc0/clkgate_delay attribute host->clk_scaling.up_threshold = 35;
    Host->clk_scaling.down_threshold = 5;
    Host->clk_scaling.polling_delay_ms = 100;
        Err = Sysfs_create_group (&host->class_dev.kobj, &AMP;CLK_SCALING_ATTR_GRP); Corresponding to the four attributes in the/sys/class/mmc_host/mmc0/clk_scaling directory, CLK_SCALING_ATTR_GRP has been previously explained by err = Sysfs_create_group (&host-
        >class_dev.kobj, &AMP;DEV_ATTR_GRP); corresponding to the/sys/class/mmc_host/mmc0/perf property, DEV_ATTR_GRP has been previously explained/* Call Mmc_start_host, also called to the MMC core main module of the Start Host section, in the MMC
    The core main module when the description */Mmc_start_host (host); if (! (

    Host->pm_flags & Mmc_pm_ignore_pm_notify)) Register_pm_notifier (&host->pm_notify);
return 0; }

Notice that the mmc_start_host was finally called to start host. About Mmc_start_host is described in the section of the MMC core main module.
in other words, the initialization of the host needs to be done before calling Mmc_add_host.
Related nodes:
/sys/bus/platform/devices/7824900.sdhci/mmc_host/mmc0
/sys/class/mmc_host/mmc0
/SYS/KERNEL/DEBUG/MMC0 4, mmc_of_parse realization

Resolves partial properties of the Mmc_host DTSi node.
Mmc_of_parse provides a common method of parsing the properties of the host Controller DTSi node, depending on whether the DTSi property conforms to the specification.
But host controller driver and must use this, but also can use their own set of analytic methods.
A brief description is as follows:

void Mmc_of_parse (struct mmc_host *host) {struct Device_node *np;
    U32 Bus_width;
    BOOL explicit_inv_wp, gpio_inv_wp = false;
    Enum OF_GPIO_FLAGS flags;

    int Len, ret, Gpio;

if (!host->parent | |!host->parent->of_node) return;
        /* Get to DTS node for mmc_host corresponding host controller */NP = host->parent->of_node; Host->parent points to the mmc_host corresponding to the host controller's device, gets its of_node to the corresponding DTSi node/* The following is the resolution attribute, and set to MMC_ The properties of the host identify caps and CAPS2 in/*/* "Bus-width" is translated to Mmc_cap_*_bit_data flags */if (OF_PROPERTY_READ_U32 (NP, "Bus-width", &bus_width) < 0) {dev_dbg (host->parent, "\" Bus-width\ "property is missing, as
        Suming 1 bit.\n ");
    Bus_width = 1;   } switch (bus_width) {case 8:host->caps |= mmc_cap_8_bit_data;
        "Bus-width"--"mmc_cap_8_bit_data/* Hosts capable of 8-bit transfers can also do 4 bits * * Case 4:  Host->caps |= Mmc_cap_4_bit_data; "Bus-width "-" Mmc_cap_4_bit_data break;
    Case 1:break;
    Default:dev_err (host->parent, "Invalid \" bus-width\ "Value%ud!\n", bus_width); }/* F_max is obtained from the optional ' max-frequency ' property */OF_PROPERTY_READ_U32 (NP, "Max-frequency", &A
       Mp;host->f_max); //................ The code behind is similar, skipping directly.}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.