mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
sdio: slove sdio & emmc dealocks on m8b
PD#141217: slove sdio & emmc dealocks on m8b. 1) Add a semaphore to avoid emmc deadlocks occur and sdio when they shared the same controller. 2) remove sd ro of dts. 3) add m400 dts support. Change-Id: I5fe0a76517a341313513e5abdbc16366724cbbe9 Signed-off-by: Nan Li <nan.li@amlogic.com>
This commit is contained in:
@@ -499,26 +499,17 @@
|
||||
};
|
||||
|
||||
sdhc_emmc_clk_cmd_pins:sdhc_emmc_clk_cmd_pins {
|
||||
mux1 {
|
||||
mux {
|
||||
groups = "sdxc_clk_c",
|
||||
"sdxc_cmd_c";
|
||||
function = "sdxc_c";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux2 {
|
||||
groups = "GPIOX_0",
|
||||
"GPIOX_1",
|
||||
"GPIOX_2",
|
||||
"GPIOX_3",
|
||||
"GPIOX_8",
|
||||
"GPIOX_9";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
sdhc_emmc_all_pins:sdhc_emmc_all_pins {
|
||||
mux1 {
|
||||
mux {
|
||||
groups = "sdxc_d0_c",
|
||||
"sdxc_d13_c",
|
||||
"sdxc_d47_c",
|
||||
@@ -528,15 +519,6 @@
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux2 {
|
||||
groups = "GPIOX_0",
|
||||
"GPIOX_1",
|
||||
"GPIOX_2",
|
||||
"GPIOX_3",
|
||||
"GPIOX_8",
|
||||
"GPIOX_9";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
sdhc_sd_clk_cmd_pins:sdhc_sd_clk_cmd_pins {
|
||||
@@ -562,31 +544,17 @@
|
||||
};
|
||||
|
||||
sdhc_sdio_clk_cmd_pins:sdhc_sdio_clk_cmd_pins {
|
||||
mux1 {
|
||||
mux {
|
||||
groups = "sdxc_clk_a",
|
||||
"sdxc_cmd_a";
|
||||
function = "sdxc_a";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux2 {
|
||||
groups = "BOOT_0",
|
||||
"BOOT_1",
|
||||
"BOOT_2",
|
||||
"BOOT_3",
|
||||
"BOOT_4",
|
||||
"BOOT_5",
|
||||
"BOOT_6",
|
||||
"BOOT_7",
|
||||
"BOOT_8",
|
||||
"BOOT_10";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
sdhc_sdio_all_pins:sdhc_sdio_all_pins {
|
||||
mux1 {
|
||||
mux {
|
||||
groups = "sdxc_d0_1_a",
|
||||
"sdxc_d13_1_a",
|
||||
"sdxc_clk_a",
|
||||
@@ -595,19 +563,6 @@
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux2 {
|
||||
groups = "BOOT_0",
|
||||
"BOOT_1",
|
||||
"BOOT_2",
|
||||
"BOOT_3",
|
||||
"BOOT_4",
|
||||
"BOOT_5",
|
||||
"BOOT_6",
|
||||
"BOOT_7",
|
||||
"BOOT_8",
|
||||
"BOOT_10";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
uart_a_pins: uart_a_pins {
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;
|
||||
/*gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;*/
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
@@ -559,4 +559,95 @@
|
||||
&i2c_ao {
|
||||
status = "ok";
|
||||
};
|
||||
&pinctrl_cbus {
|
||||
sdhc_emmc_clk_cmd_pins:sdhc_emmc_clk_cmd_pins {
|
||||
mux {
|
||||
groups = "sdxc_clk_c",
|
||||
"sdxc_cmd_c";
|
||||
function = "sdxc_c";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux1 {
|
||||
groups = "GPIOX_0",
|
||||
"GPIOX_1",
|
||||
"GPIOX_2",
|
||||
"GPIOX_3",
|
||||
"GPIOX_8",
|
||||
"GPIOX_9";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
sdhc_emmc_all_pins:sdhc_emmc_all_pins {
|
||||
mux {
|
||||
groups = "sdxc_d0_c",
|
||||
"sdxc_d13_c",
|
||||
"sdxc_d47_c",
|
||||
"sdxc_clk_c",
|
||||
"sdxc_cmd_c";
|
||||
function = "sdxc_c";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux1 {
|
||||
groups = "GPIOX_0",
|
||||
"GPIOX_1",
|
||||
"GPIOX_2",
|
||||
"GPIOX_3",
|
||||
"GPIOX_8",
|
||||
"GPIOX_9";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
|
||||
sdhc_sdio_clk_cmd_pins:sdhc_sdio_clk_cmd_pins {
|
||||
mux {
|
||||
groups = "sdxc_clk_a",
|
||||
"sdxc_cmd_a";
|
||||
function = "sdxc_a";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux1 {
|
||||
groups = "BOOT_0",
|
||||
"BOOT_1",
|
||||
"BOOT_2",
|
||||
"BOOT_3",
|
||||
"BOOT_4",
|
||||
"BOOT_5",
|
||||
"BOOT_6",
|
||||
"BOOT_7",
|
||||
"BOOT_8",
|
||||
"BOOT_10";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
sdhc_sdio_all_pins:sdhc_sdio_all_pins {
|
||||
mux {
|
||||
groups = "sdxc_d0_1_a",
|
||||
"sdxc_d13_1_a",
|
||||
"sdxc_clk_a",
|
||||
"sdxc_cmd_a";
|
||||
function = "sdxc_a";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
mux1 {
|
||||
groups = "BOOT_0",
|
||||
"BOOT_1",
|
||||
"BOOT_2",
|
||||
"BOOT_3",
|
||||
"BOOT_4",
|
||||
"BOOT_5",
|
||||
"BOOT_6",
|
||||
"BOOT_7",
|
||||
"BOOT_8",
|
||||
"BOOT_10";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;
|
||||
/*gpio_ro = <&gpio GPIODV_25 GPIO_ACTIVE_HIGH>;*/
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
@@ -110,7 +110,7 @@
|
||||
sdhc {
|
||||
compatible = "amlogic, aml_sdhc";
|
||||
dev_name = "aml_sdhc.0";
|
||||
status = "disable";
|
||||
status = "okay";
|
||||
interrupts = <0 78 1>;
|
||||
reg = <0xc1108e00 0x3c>;
|
||||
pinctrl-names = "sdhc_sd_clk_cmd_pins",
|
||||
@@ -129,42 +129,6 @@
|
||||
<&clkc CLKID_FCLK_DIV3>;
|
||||
clock-names = "core", "div3";
|
||||
|
||||
emmc {
|
||||
status = "okay";
|
||||
port = <5>;
|
||||
/* 0:sdio_a,
|
||||
* 1:sdio_b,
|
||||
* 2:sdio_c,
|
||||
* 3:sdhc_a,
|
||||
* 4:sdhc_b,
|
||||
* 5:sdhc_c
|
||||
*/
|
||||
pinname = "emmc";
|
||||
ocr_avail = <0x00200080>;
|
||||
/* 3.3:0x200000, 1.8+3.3:0x00200080 */
|
||||
caps = "MMC_CAP_8_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_ERASE",
|
||||
"MMC_CAP_HW_RESET";
|
||||
caps2 = "MMC_CAP2_HS200_1_8V_SDR";
|
||||
f_min = <300000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /* 128KB */
|
||||
gpio_dat3 = <&gpio BOOT_3 GPIO_ACTIVE_HIGH>;
|
||||
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <1>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD),
|
||||
* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card,
|
||||
* 5:NON sdio device(means sd/mmc card),
|
||||
* other:reserved
|
||||
*/
|
||||
};
|
||||
|
||||
sdio {
|
||||
status = "okay";
|
||||
port = <3>;
|
||||
@@ -581,4 +545,3 @@
|
||||
&i2c_ao {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ unsigned int timeout_cnt;
|
||||
static unsigned int sdhc_error_flag;
|
||||
static unsigned int sdhc_debug_flag;
|
||||
static int sdhc_err_bak;
|
||||
static struct semaphore sdhc_sema;
|
||||
wait_queue_head_t mmc_req_wait_q;
|
||||
static int wait_req_flag;
|
||||
|
||||
static void aml_sdhc_send_stop(struct amlsd_host *host);
|
||||
static void aml_sdhc_emmc_clock_switch_on(struct amlsd_platform *pdata);
|
||||
@@ -875,6 +876,8 @@ void aml_sdhc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
}
|
||||
aml_sdhc_clk_switch_off(host);
|
||||
mmc_request_done(host->mmc, mrq);
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
}
|
||||
|
||||
char *msg_err[] = {
|
||||
@@ -1031,6 +1034,8 @@ static void aml_sdhc_timeout(struct work_struct *work)
|
||||
if (host->xfer_step == XFER_FINISHED) {
|
||||
spin_unlock_irqrestore(&host->mrq_lock, flags);
|
||||
sdhc_err("timeout after xfer finished\n");
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1049,7 +1054,8 @@ static void aml_sdhc_timeout(struct work_struct *work)
|
||||
mmc_hostname(host->mmc),
|
||||
host->mrq->cmd->opcode, host->xfer_step,
|
||||
time_start_cnt, timeout_cnt);
|
||||
up(&sdhc_sema);
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
return;
|
||||
}
|
||||
timeout_handle:
|
||||
@@ -1125,6 +1131,7 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
unsigned long flags;
|
||||
unsigned int timeout;
|
||||
u32 tuning_opcode;
|
||||
long status;
|
||||
|
||||
WARN_ON(!mmc);
|
||||
WARN_ON(!mrq);
|
||||
@@ -1132,8 +1139,21 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
pdata = mmc_priv(mmc);
|
||||
host = (void *)pdata->host;
|
||||
|
||||
if (aml_check_unsupport_cmd(mmc, mrq))
|
||||
status = wait_event_interruptible_timeout(mmc_req_wait_q,
|
||||
wait_req_flag == 0, WAIT_UNTIL_REQ_DONE);
|
||||
if (status == 0) {
|
||||
mmc_request_done(mmc, mrq);
|
||||
sdhc_err("SDHC CMD conflict!\n");
|
||||
return;
|
||||
} else if (status < 0)
|
||||
return;
|
||||
wait_req_flag = 1;
|
||||
|
||||
if (aml_check_unsupport_cmd(mmc, mrq)) {
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
return;
|
||||
}
|
||||
aml_sdhc_emmc_clock_switch_on(pdata);
|
||||
/* only for SDCARD */
|
||||
if (!pdata->is_in || (!host->init_flag && aml_card_type_sd(pdata))) {
|
||||
@@ -1142,14 +1162,27 @@ void aml_sdhc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
mrq->cmd->retries = 0;
|
||||
spin_unlock_irqrestore(&host->mrq_lock, flags);
|
||||
mmc_request_done(mmc, mrq);
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdata->need_retuning && mmc->card) {
|
||||
wake_up_interruptible(&mmc_req_wait_q);
|
||||
wait_req_flag = 0;
|
||||
/* eMMC uses cmd21 but sd and sdio use cmd19 */
|
||||
tuning_opcode = (mmc->card->type == MMC_TYPE_MMC) ?
|
||||
MMC_SEND_TUNING_BLOCK_HS200 : MMC_SEND_TUNING_BLOCK;
|
||||
aml_sdhc_execute_tuning(mmc, tuning_opcode);
|
||||
status = wait_event_interruptible_timeout(mmc_req_wait_q,
|
||||
wait_req_flag == 0, WAIT_UNTIL_REQ_DONE);
|
||||
if (status == 0) {
|
||||
mmc_request_done(mmc, mrq);
|
||||
sdhc_err(" SDHC CMD conflict in tuning\n");
|
||||
return;
|
||||
} else if (status < 0)
|
||||
return;
|
||||
wait_req_flag = 1;
|
||||
}
|
||||
|
||||
aml_sdhc_disable_imask(host, SDHC_ICTL_ALL);
|
||||
@@ -2230,6 +2263,7 @@ static int aml_sdhc_probe(struct platform_device *pdev)
|
||||
host->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, host);
|
||||
aml_sdhc_reg_init(host);
|
||||
init_waitqueue_head(&mmc_req_wait_q);
|
||||
|
||||
/* for (i = 0; i < MMC_MAX_DEVICE; i++) {*/
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
@@ -160,6 +160,8 @@ extern const u8 tuning_blk_pattern_8bit[128];
|
||||
|
||||
#define SD_CAPS(a, b) { .caps = a, .name = b }
|
||||
|
||||
#define WAIT_UNTIL_REQ_DONE msecs_to_jiffies(10000)
|
||||
|
||||
struct sd_caps {
|
||||
unsigned int caps;
|
||||
const char *name;
|
||||
|
||||
Reference in New Issue
Block a user