mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
update sdmmc sdio
This commit is contained in:
@@ -235,9 +235,11 @@ static u32 get_card_status(struct mmc_card *card, struct request *req)
|
||||
cmd.arg = card->rca << 16;
|
||||
cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
|
||||
err = mmc_wait_for_cmd(card->host, &cmd, 0);
|
||||
#if 0 //[xjh] not printk,save time
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: error %d sending status comand",
|
||||
req->rq_disk->disk_name, err);
|
||||
#endif
|
||||
return cmd.resp[0];
|
||||
}
|
||||
|
||||
@@ -376,7 +378,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
* until later as we need to wait for the card to leave
|
||||
* programming mode even when things go wrong.
|
||||
*/
|
||||
#if 1/*[xjh] do not retry with cmd17*/
|
||||
if (brq.cmd.error || brq.data.error || brq.stop.error) {
|
||||
|
||||
if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {
|
||||
/* Redo read one sector at a time */
|
||||
printk(KERN_WARNING "%s: retrying using single "
|
||||
@@ -384,11 +388,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
disable_multi = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
status = get_card_status(card, req);
|
||||
} else if (disable_multi == 1) {
|
||||
disable_multi = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 //[xjh] not printk,save time
|
||||
if (brq.cmd.error) {
|
||||
printk(KERN_ERR "%s: error %d sending read/write "
|
||||
"command, response %#x, card status %#x\n",
|
||||
@@ -413,6 +420,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
req->rq_disk->disk_name, brq.stop.error,
|
||||
brq.stop.resp[0], status);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
|
||||
do {
|
||||
@@ -445,6 +453,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
}
|
||||
|
||||
if (brq.cmd.error || brq.stop.error || brq.data.error) {
|
||||
#if 1/*[xjh] do not retry with cmd17*/
|
||||
if (rq_data_dir(req) == READ) {
|
||||
/*
|
||||
* After an error, we redo I/O one sector at a
|
||||
@@ -456,6 +465,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
spin_unlock_irq(&md->lock);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
goto cmd_err;
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ int mmc_add_card(struct mmc_card *card)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int sdmmc0_disable_Irq_ForRemoval;
|
||||
/*
|
||||
* Unregister a new MMC card with the driver model, and
|
||||
* (eventually) free it.
|
||||
@@ -277,6 +278,7 @@ void mmc_remove_card(struct mmc_card *card)
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
mmc_remove_card_debugfs(card);
|
||||
#endif
|
||||
unsigned long flags;
|
||||
|
||||
if (mmc_card_present(card)) {
|
||||
if (mmc_host_is_spi(card->host)) {
|
||||
@@ -286,6 +288,13 @@ void mmc_remove_card(struct mmc_card *card)
|
||||
printk(KERN_INFO "%s: card %04x removed\n",
|
||||
mmc_hostname(card->host), card->rca);
|
||||
}
|
||||
|
||||
if( !strncmp( mmc_hostname(card->host) ,"mmc0" , strlen("mmc0")) )
|
||||
{
|
||||
local_irq_save(flags);
|
||||
sdmmc0_disable_Irq_ForRemoval = 1; //close the IRQ for insertion or removal
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
device_del(&card->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1059,7 +1059,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
|
||||
|
||||
EXPORT_SYMBOL(mmc_detect_change);
|
||||
|
||||
|
||||
#if 0
|
||||
void mmc_rescan(struct work_struct *work)
|
||||
{
|
||||
struct mmc_host *host =
|
||||
@@ -1154,6 +1154,102 @@ out:
|
||||
if (host->caps & MMC_CAP_NEEDS_POLL)
|
||||
mmc_schedule_delayed_work(&host->detect, HZ);
|
||||
}
|
||||
#else
|
||||
void mmc_rescan(struct work_struct *work)
|
||||
{
|
||||
struct mmc_host *host =
|
||||
container_of(work, struct mmc_host, detect.work);
|
||||
u32 ocr;
|
||||
int err;
|
||||
int extend_wakelock = 0;
|
||||
|
||||
mmc_bus_get(host);
|
||||
if(host->bus_ops == NULL)
|
||||
{
|
||||
/* detect a newly inserted card */
|
||||
|
||||
/*
|
||||
* Only we can add a new handler, so it's safe to
|
||||
* release the lock here.
|
||||
*/
|
||||
mmc_bus_put(host);
|
||||
|
||||
if (host->ops->get_cd && host->ops->get_cd(host) == 0)
|
||||
goto out;
|
||||
|
||||
mmc_claim_host(host);
|
||||
|
||||
mmc_power_up(host);
|
||||
mmc_go_idle(host);
|
||||
|
||||
mmc_send_if_cond(host, host->ocr_avail);
|
||||
|
||||
/*
|
||||
* First we search for SDIO...
|
||||
*/
|
||||
err = mmc_send_io_op_cond(host, 0, &ocr);
|
||||
if (!err) {
|
||||
if (mmc_attach_sdio(host, ocr))
|
||||
mmc_power_off(host);
|
||||
extend_wakelock = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* ...then normal SD...
|
||||
*/
|
||||
err = mmc_send_app_op_cond(host, 0, &ocr);
|
||||
if (!err) {
|
||||
if (mmc_attach_sd(host, ocr))
|
||||
mmc_power_off(host);
|
||||
extend_wakelock = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* ...and finally MMC.
|
||||
*/
|
||||
err = mmc_send_op_cond(host, 0, &ocr);
|
||||
if (!err) {
|
||||
if (mmc_attach_mmc(host, ocr))
|
||||
mmc_power_off(host);
|
||||
extend_wakelock = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mmc_release_host(host);
|
||||
mmc_power_off(host);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if there is a card registered, check whether it is still present */
|
||||
if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
|
||||
host->bus_ops->detect(host);
|
||||
|
||||
/* If the card was removed the bus will be marked
|
||||
* as dead - extend the wakelock so userspace
|
||||
* can respond */
|
||||
if (host->bus_dead)
|
||||
extend_wakelock = 1;
|
||||
|
||||
mmc_bus_put(host);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
out:
|
||||
if (extend_wakelock)
|
||||
wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
|
||||
else
|
||||
wake_unlock(&mmc_delayed_work_wake_lock);
|
||||
|
||||
if (host->caps & MMC_CAP_NEEDS_POLL)
|
||||
mmc_schedule_delayed_work(&host->detect, HZ);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void mmc_start_host(struct mmc_host *host)
|
||||
{
|
||||
|
||||
@@ -660,6 +660,9 @@ static void mmc_attach_bus_ops(struct mmc_host *host)
|
||||
int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
|
||||
{
|
||||
int err;
|
||||
|
||||
unsigned long flags;
|
||||
extern int sdmmc0_disable_Irq_ForRemoval;
|
||||
|
||||
BUG_ON(!host);
|
||||
WARN_ON(!host->claimed);
|
||||
@@ -708,6 +711,10 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
|
||||
err = mmc_add_card(host->card);
|
||||
if (err)
|
||||
goto remove_card;
|
||||
|
||||
local_irq_save(flags);
|
||||
sdmmc0_disable_Irq_ForRemoval = 0; //close the IRQ for insertion or removal
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,9 +106,27 @@
|
||||
#define SDMMC_CMD_RESP_EXP RK2818_BIT(6)
|
||||
#define SDMMC_CMD_INDX(n) ((n) & 0x1F)
|
||||
/* Status register defines */
|
||||
#define SDMMC_STAUTS_RESP_INDEX RK2818_BIT(11)
|
||||
#define SDMMC_STAUTS_MC_BUSY RK2818_BIT(10)
|
||||
#define SDMMC_STAUTS_DATA_BUSY RK2818_BIT(9)
|
||||
#define SDMMC_STAUTS_CARD_PRESENT RK2818_BIT(8)
|
||||
#define SDMMC_STAUTS_FIFO_FULL RK2818_BIT(3)
|
||||
#define SDMMC_STAUTS_FIFO_EMPTY RK2818_BIT(2)
|
||||
#define SDMMC_STAUTS_FIFO_TX_WATERMARK RK2818_BIT(1)
|
||||
#define SDMMC_STAUTS_FIFO_RX_WATERMARK RK2818_BIT(0)
|
||||
|
||||
|
||||
|
||||
|
||||
#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF)
|
||||
#define SDMMC_FIFO_SZ 32
|
||||
|
||||
#define SDMMC_WRITE_PROTECT RK2818_BIT(0)
|
||||
#define SDMMC_CARD_DETECT_N RK2818_BIT(0)
|
||||
|
||||
/* Specifies how often in millisecs to poll for card removal-insertion changes
|
||||
* when the timer switch is open */
|
||||
#define RK28_SDMMC0_SWITCH_POLL_DELAY 3500
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user