Commit 921bdc72 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v6.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Fix pwrseq for WILC1000/WILC3000 SDIO card

  MMC host:
   - vub300: Fix invalid response handling"

* tag 'mmc-v6.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: pwrseq: sd8787: Fix WILC CHIP_EN and RESETN toggling order
  mmc: vub300: fix invalid response handling
parents 7bdecc26 0b5d5c43
...@@ -28,7 +28,6 @@ struct mmc_pwrseq_sd8787 { ...@@ -28,7 +28,6 @@ struct mmc_pwrseq_sd8787 {
struct mmc_pwrseq pwrseq; struct mmc_pwrseq pwrseq;
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
struct gpio_desc *pwrdn_gpio; struct gpio_desc *pwrdn_gpio;
u32 reset_pwrdwn_delay_ms;
}; };
#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq) #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
...@@ -39,7 +38,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host) ...@@ -39,7 +38,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
msleep(pwrseq->reset_pwrdwn_delay_ms); msleep(300);
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1); gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
} }
...@@ -51,17 +50,37 @@ static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host) ...@@ -51,17 +50,37 @@ static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
} }
static void mmc_pwrseq_wilc1000_pre_power_on(struct mmc_host *host)
{
struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
/* The pwrdn_gpio is really CHIP_EN, reset_gpio is RESETN */
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
msleep(5);
gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
}
static void mmc_pwrseq_wilc1000_power_off(struct mmc_host *host)
{
struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
}
static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = { static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
.pre_power_on = mmc_pwrseq_sd8787_pre_power_on, .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
.power_off = mmc_pwrseq_sd8787_power_off, .power_off = mmc_pwrseq_sd8787_power_off,
}; };
static const u32 sd8787_delay_ms = 300; static const struct mmc_pwrseq_ops mmc_pwrseq_wilc1000_ops = {
static const u32 wilc1000_delay_ms = 5; .pre_power_on = mmc_pwrseq_wilc1000_pre_power_on,
.power_off = mmc_pwrseq_wilc1000_power_off,
};
static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = { static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
{ .compatible = "mmc-pwrseq-sd8787", .data = &sd8787_delay_ms }, { .compatible = "mmc-pwrseq-sd8787", .data = &mmc_pwrseq_sd8787_ops },
{ .compatible = "mmc-pwrseq-wilc1000", .data = &wilc1000_delay_ms }, { .compatible = "mmc-pwrseq-wilc1000", .data = &mmc_pwrseq_wilc1000_ops },
{/* sentinel */}, {/* sentinel */},
}; };
MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match); MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
...@@ -77,7 +96,6 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) ...@@ -77,7 +96,6 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node); match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node);
pwrseq->reset_pwrdwn_delay_ms = *(u32 *)match->data;
pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW);
if (IS_ERR(pwrseq->pwrdn_gpio)) if (IS_ERR(pwrseq->pwrdn_gpio))
...@@ -88,7 +106,7 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) ...@@ -88,7 +106,7 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
return PTR_ERR(pwrseq->reset_gpio); return PTR_ERR(pwrseq->reset_gpio);
pwrseq->pwrseq.dev = dev; pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops; pwrseq->pwrseq.ops = match->data;
pwrseq->pwrseq.owner = THIS_MODULE; pwrseq->pwrseq.owner = THIS_MODULE;
platform_set_drvdata(pdev, pwrseq); platform_set_drvdata(pdev, pwrseq);
......
...@@ -1713,6 +1713,9 @@ static void construct_request_response(struct vub300_mmc_host *vub300, ...@@ -1713,6 +1713,9 @@ static void construct_request_response(struct vub300_mmc_host *vub300,
int bytes = 3 & less_cmd; int bytes = 3 & less_cmd;
int words = less_cmd >> 2; int words = less_cmd >> 2;
u8 *r = vub300->resp.response.command_response; u8 *r = vub300->resp.response.command_response;
if (!resp_len)
return;
if (bytes == 3) { if (bytes == 3) {
cmd->resp[words] = (r[1 + (words << 2)] << 24) cmd->resp[words] = (r[1 + (words << 2)] << 24)
| (r[2 + (words << 2)] << 16) | (r[2 + (words << 2)] << 16)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment