Linux Sdio bus driver (ii)

Source: Internet
Author: User

Driven:

Taking Sdio as an example, it uses Mmc_attach_sdio to match the driver and the device, and its essence is to match the Sdio_bus matching rules. In Mmc_attach_sdio, the MMC first matches a bus, that is, what bus to use for the MMC bus to process host. One thing to understand here is that in Sdio, for SD card memory MMC is a physical device, and for non-SD card memory, such as the Sdio interface device, the MMC is characterized as bus, this is more important. There are sdio_bus in addition to MMC BUS.

/*
* Starting point for SDIO card init.
*/
int Mmc_attach_sdio (struct mmc_host *host)
{
int err, I, funcs;
U32 OCR;
struct Mmc_card *card;

BUG_ON (!host);
WARN_ON (!host->claimed);

Err = Mmc_send_io_op_cond (host, 0, &OCR);
if (ERR)
return err;

Mmc_attach_bus (host, &mmc_sdio_ops);
if (Host->ocr_avail_sdio)
Host->ocr_avail = host->ocr_avail_sdio;


/*
* Sanity Check the voltages the card claims to
* Support.
*/
if (OCR & 0x7F) {
Pr_warning ("%s:card claims to support voltages"
"below the defined range. These'll be ignored.\n ",
Mmc_hostname (host));
OCR &= ~0x7f;
}


HOST->OCR = Mmc_select_voltage (host, OCR);


/*
* Can We support the voltage (s) of the card (s)?
*/
if (!HOST->OCR) {
err =-einval;
Goto err;
}

/*
* Detect and init the card.
*/
Err = Mmc_sdio_init_card (host, HOST->OCR, NULL, 0);
if (err) {
if (err = =-eagain) {
/*
* Retry initialization with S18R set to 0.
*/
HOST->OCR &= ~r4_18v_present;
Err = Mmc_sdio_init_card (host, HOST->OCR, NULL, 0);
}
if (ERR)
Goto err;
}
Card = host->card;


/*
* Enable runtime PM only if supported by Host+card+board
*/
if (Host->caps & Mmc_cap_power_off_card) {
/*
* Let runtime PM core know we card is active
*/
Err = pm_runtime_set_active (&card->dev);
if (ERR)
Goto Remove;


/*
* Enable Runtime PM for this card
*/
Pm_runtime_enable (&card->dev);
}


/*
* The number of functions on the card is encoded inside
* The OCR.
*/
Funcs = (OCR & 0x70000000) >> 28;
Card->sdio_funcs = 0;


#ifdef Config_mmc_embedded_sdio
if (Host->embedded_sdio_data.funcs)
Card->sdio_funcs = Funcs = host->embedded_sdio_data.num_funcs;
#endif


/*
* Initialize (but don ' t add) all present functions.
*/
for (i = 0; i < Funcs; i++, card->sdio_funcs++) {
#ifdef Config_mmc_embedded_sdio
if (Host->embedded_sdio_data.funcs) {
struct Sdio_func *tmp;


TMP = Sdio_alloc_func (Host->card);
if (Is_err (TMP))
Goto Remove;
Tmp->num = (i + 1);
Card->sdio_func[i] = tmp;
Tmp->class = host->embedded_sdio_data.funcs[i].f_class;
Tmp->max_blksize = host->embedded_sdio_data.funcs[i].f_maxblksize;
Tmp->vendor = card->cis.vendor;
Tmp->device = card->cis.device;
} else {
#endif
Err = Sdio_init_func (Host->card, i + 1);
if (ERR)
Goto Remove;
#ifdef Config_mmc_embedded_sdio
}
#endif
/*
* Enable Runtime PM for this func (if supported)
*/
if (Host->caps & Mmc_cap_power_off_card)
Pm_runtime_enable (&card->sdio_func[i]->dev);
}


/*
* First add the card to the driver model ...
*/
Mmc_release_host (host);
Err = Mmc_add_card (Host->card);
if (ERR)
Goto remove_added;


/*
* ... then the SDIO functions.
*/
for (i = 0;i < funcs;i++) {
Err = Sdio_add_func (Host->card->sdio_func[i]);
if (ERR)
Goto remove_added;
}


Mmc_claim_host (host);
return 0;




Remove_added:
/* Remove without lock if the device has been added. */
Mmc_sdio_remove (host);
Mmc_claim_host (host);
Remove
/* And with lock if it hasn ' t been added. */
Mmc_release_host (host);
if (Host->card)
Mmc_sdio_remove (host);
Mmc_claim_host (host);
Err:
Mmc_detach_bus (host);


Pr_err ("%s:error%d whilst initialising SDIO card\n",
Mmc_hostname (host), err);


return err;
}

More difficult to understand is the func, which is actually a physical device package, it can be considered a device.

/*
* Allocate and initialise a new SDIO function structure.
*/
struct Sdio_func *sdio_alloc_func (struct Mmc_card *card)
{
struct Sdio_func *func;


Func = kzalloc (sizeof (struct sdio_func), gfp_kernel);
if (!func)
Return Err_ptr (-ENOMEM);


Func->card = Card;


Device_initialize (&func->dev);


Func->dev.parent = &card->dev;//Card device is the parent device of the SDIO device.
Func->dev.bus = &sdio_bus_type;
Func->dev.release = Sdio_release_func;


return func;
}

The above code at a glance, which is the specific device entity encapsulation, the bus type is Sdio_bus. Sdio_init_func only Initializes a device, and there is no register. In the Sdio_add_func implementation of the device register, the same is the card entity, before the Mmc_add_card is not registered, in the Mmc_add_card function to realize the registration of the device.

To this device registration is completed, in fact, Sdio bus in the form similar to the USB bus, why? Children's shoes have been written USB drive should know, write USB driver is only to write driver loading, and do not specifically load device entities, resulting in many children's shoes confusion, why no device loading, in fact, when the USB device is inserted, will dynamically create a USB device entity, after the USB device entity creation is completed, The matching driver is called according to the different device IDs. and Sdio equipment is the same. The code above is confusing, and always makes it difficult to see the loading of specific devices. In fact, in the code above, it includes the driver of the MMC host.


Linux Sdio bus driver (ii)

Related Article

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.