mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
mmc: support logic_card and alive_card for sdio
Signed-off-by: Yao Xiao <xiaoyao@rock-chips.com> Change-Id: Ic51f0dfb3bb2de2e1f52ab5e24dbeaebc729ec99
This commit is contained in:
@@ -88,3 +88,8 @@ config MMC_CRYPTO
|
||||
Enabling this makes it possible for the kernel to use the crypto
|
||||
capabilities of the MMC device (if present) to perform crypto
|
||||
operations on data being transferred to/from the device.
|
||||
|
||||
config SDIO_KEEPALIVE
|
||||
bool "SDIO KEEPALIVE"
|
||||
help
|
||||
support sdio keepalive during host poweroff
|
||||
|
||||
@@ -2505,6 +2505,20 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
|
||||
mmc_hw_reset_for_init(host);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (host->support_chip_alive) {
|
||||
host->chip_alive = 1;
|
||||
if (!mmc_attach_sdio(host)) {
|
||||
return 0;
|
||||
} else {
|
||||
pr_err("%s: chip_alive attach sdio failed.\n", mmc_hostname(host));
|
||||
host->chip_alive = 0;
|
||||
}
|
||||
} else {
|
||||
host->chip_alive = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sdio_reset sends CMD52 to reset card. Since we do not know
|
||||
* if the card is being re-initialized, just send it. CMD52
|
||||
@@ -2532,9 +2546,14 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
|
||||
if (!(host->caps2 & MMC_CAP2_NO_MMC))
|
||||
if (!mmc_attach_mmc(host))
|
||||
return 0;
|
||||
#else
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if ((!(host->chip_alive)) && (host->restrict_caps & RESTRICT_CARD_TYPE_SDIO))
|
||||
sdio_reset(host);
|
||||
#else
|
||||
if (host->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
|
||||
sdio_reset(host);
|
||||
#endif
|
||||
|
||||
mmc_go_idle(host);
|
||||
|
||||
|
||||
@@ -342,6 +342,13 @@ int mmc_of_parse(struct mmc_host *host)
|
||||
if (device_property_read_bool(dev, "supports-emmc"))
|
||||
host->restrict_caps |= RESTRICT_CARD_TYPE_EMMC;
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
host->support_chip_alive =
|
||||
device_property_read_bool(dev, "supports-chip-alive");
|
||||
host->logic_remove_card =
|
||||
device_property_read_bool(dev, "logic-remove-card");
|
||||
#endif
|
||||
|
||||
host->dsr_req = !device_property_read_u32(dev, "dsr", &host->dsr);
|
||||
if (host->dsr_req && (host->dsr & ~0xffff)) {
|
||||
dev_err(host->parent,
|
||||
|
||||
@@ -587,11 +587,25 @@ try_again:
|
||||
/*
|
||||
* Inform the card of the voltage
|
||||
*/
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (!(host->chip_alive)) {
|
||||
if (!powered_resume) {
|
||||
err = mmc_send_io_op_cond(host, ocr, &rocr);
|
||||
if (err) {
|
||||
pr_err("%s: mmc_send_io_op_cond() err=%d\n", __func__, err);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rocr = 0xa0ffff00;
|
||||
}
|
||||
#else
|
||||
if (!powered_resume) {
|
||||
err = mmc_send_io_op_cond(host, ocr, &rocr);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For SPI, enable CRC as appropriate.
|
||||
@@ -661,9 +675,19 @@ try_again:
|
||||
* For native busses: set card RCA and quit open drain mode.
|
||||
*/
|
||||
if (!powered_resume && !mmc_host_is_spi(host)) {
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (!(host->chip_alive)) {
|
||||
err = mmc_send_relative_addr(host, &card->rca);
|
||||
if (err)
|
||||
goto remove;
|
||||
} else {
|
||||
card->rca = 1;
|
||||
}
|
||||
#else
|
||||
err = mmc_send_relative_addr(host, &card->rca);
|
||||
if (err)
|
||||
goto remove;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update oldcard with the new RCA received from the SDIO
|
||||
@@ -1104,9 +1128,21 @@ int mmc_attach_sdio(struct mmc_host *host)
|
||||
|
||||
WARN_ON(!host->claimed);
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (!(host->chip_alive)) {
|
||||
err = mmc_send_io_op_cond(host, 0, &ocr);
|
||||
if (err) {
|
||||
pr_err("%s mmc_send_io_op_cond err: %d\n", mmc_hostname(host), err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
ocr = 0x20ffff00;
|
||||
}
|
||||
#else
|
||||
err = mmc_send_io_op_cond(host, 0, &ocr);
|
||||
if (err)
|
||||
return err;
|
||||
#endif
|
||||
|
||||
mmc_attach_bus(host, &mmc_sdio_ops);
|
||||
if (host->ocr_avail_sdio)
|
||||
@@ -1177,6 +1213,11 @@ int mmc_attach_sdio(struct mmc_host *host)
|
||||
pm_runtime_enable(&card->sdio_func[i]->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (host->card->sdio_func[1])
|
||||
host->card->sdio_func[1]->card_alive = host->chip_alive;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First add the card to the driver model...
|
||||
*/
|
||||
@@ -1228,6 +1269,11 @@ int sdio_reset_comm(struct mmc_card *card)
|
||||
u32 rocr;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (host->chip_alive)
|
||||
host->chip_alive = 0;
|
||||
#endif
|
||||
|
||||
printk("%s():\n", __func__);
|
||||
mmc_claim_host(host);
|
||||
|
||||
|
||||
@@ -1005,6 +1005,11 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
|
||||
struct dw_mci *host = slot->host;
|
||||
int gpio_cd = mmc_gpio_get_cd(mmc);
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (mmc->logic_remove_card)
|
||||
return test_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
#endif
|
||||
|
||||
/* Use platform get_cd function, else try onboard card detect */
|
||||
if (((mmc->caps & MMC_CAP_NEEDS_POLL)
|
||||
|| !mmc_card_is_removable(mmc))) {
|
||||
@@ -2944,6 +2949,11 @@ static int dw_mci_init_slot(struct dw_mci *host)
|
||||
|
||||
dw_mci_get_cd(mmc);
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
if (mmc->logic_remove_card)
|
||||
clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
|
||||
#endif
|
||||
|
||||
ret = mmc_add_host(mmc);
|
||||
if (ret)
|
||||
goto err_host_allocated;
|
||||
|
||||
@@ -379,6 +379,12 @@ struct mmc_host {
|
||||
#define RESTRICT_CARD_TYPE_SDIO (1 << 1) /* Can support Secure-Digital I/O Card or Combo-Mem */
|
||||
#define RESTRICT_CARD_TYPE_EMMC (1 << 2) /* Can support embedded Multi-Media Card */
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
bool support_chip_alive;
|
||||
bool chip_alive;
|
||||
bool logic_remove_card;
|
||||
#endif
|
||||
|
||||
/* host specific block data */
|
||||
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
|
||||
unsigned short max_segs; /* see blk_queue_max_segments */
|
||||
|
||||
@@ -59,6 +59,10 @@ struct sdio_func {
|
||||
const char **info; /* info strings */
|
||||
|
||||
struct sdio_func_tuple *tuples;
|
||||
|
||||
#ifdef CONFIG_SDIO_KEEPALIVE
|
||||
u8 card_alive;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT)
|
||||
|
||||
Reference in New Issue
Block a user