Commit a2d48756 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "Here are a couple of mmc fixes intended for v4.13-rc1.

  I have also included a couple of cleanup patches in this pull request
  for OMAP2+, related to the omap_hsmmc driver. The reason is because of
  the changes are also depending on OMAP SoC specific code, so this
  simplifies how to deal with this.

  Summary:

  MMC host:
   - sunxi: Correct time phase settings
   - omap_hsmmc: Clean up some dead code
   - dw_mmc: Fix message printed for deprecated num-slots DT binding
   - dw_mmc: Fix DT documentation"

* tag 'mmc-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  Documentation: dw-mshc: deprecate num-slots
  mmc: dw_mmc: fix the wrong condition check of getting num-slots from DT
  mmc: host: omap_hsmmc: remove unused platform callbacks
  ARM: OMAP2+: hsmmc.c: Remove dead code
  mmc: sunxi: Keep default timing phase settings for new timing mode
parents 0b5477d9 3f5b4b79
...@@ -78,7 +78,6 @@ Example: ...@@ -78,7 +78,6 @@ Example:
}; };
dwmmc0@12200000 { dwmmc0@12200000 {
num-slots = <1>;
cap-mmc-highspeed; cap-mmc-highspeed;
cap-sd-highspeed; cap-sd-highspeed;
broken-cd; broken-cd;
......
...@@ -24,6 +24,5 @@ Example: ...@@ -24,6 +24,5 @@ Example:
fifo-depth = <0x20>; fifo-depth = <0x20>;
bus-width = <4>; bus-width = <4>;
num-slots = <1>;
disable-wp; disable-wp;
}; };
...@@ -36,7 +36,6 @@ Example: ...@@ -36,7 +36,6 @@ Example:
/* Board portion */ /* Board portion */
dwmmc0@fcd03000 { dwmmc0@fcd03000 {
num-slots = <1>;
vmmc-supply = <&ldo12>; vmmc-supply = <&ldo12>;
fifo-depth = <0x100>; fifo-depth = <0x100>;
pinctrl-names = "default"; pinctrl-names = "default";
...@@ -52,7 +51,6 @@ Example: ...@@ -52,7 +51,6 @@ Example:
dwmmc_1: dwmmc1@f723e000 { dwmmc_1: dwmmc1@f723e000 {
compatible = "hisilicon,hi6220-dw-mshc"; compatible = "hisilicon,hi6220-dw-mshc";
num-slots = <0x1>;
bus-width = <0x4>; bus-width = <0x4>;
disable-wp; disable-wp;
cap-sd-highspeed; cap-sd-highspeed;
......
...@@ -12,12 +12,12 @@ Required Properties: ...@@ -12,12 +12,12 @@ Required Properties:
* #address-cells: should be 1. * #address-cells: should be 1.
* #size-cells: should be 0. * #size-cells: should be 0.
# Slots: The slot specific information are contained within child-nodes with # Slots (DEPRECATED): The slot specific information are contained within
each child-node representing a supported slot. There should be atleast one child-nodes with each child-node representing a supported slot. There should
child node representing a card slot. The name of the child node representing be atleast one child node representing a card slot. The name of the child node
the slot is recommended to be slot@n where n is the unique number of the slot representing the slot is recommended to be slot@n where n is the unique number
connected to the controller. The following are optional properties which of the slot connected to the controller. The following are optional properties
can be included in the slot child node. which can be included in the slot child node.
* reg: specifies the physical slot number. The valid values of this * reg: specifies the physical slot number. The valid values of this
property is 0 to (num-slots -1), where num-slots is the value property is 0 to (num-slots -1), where num-slots is the value
...@@ -63,7 +63,7 @@ Optional properties: ...@@ -63,7 +63,7 @@ Optional properties:
clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default. clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.
(Use the "max-frequency" instead of "clock-freq-min-max".) (Use the "max-frequency" instead of "clock-freq-min-max".)
* num-slots: specifies the number of slots supported by the controller. * num-slots (DEPRECATED): specifies the number of slots supported by the controller.
The number of physical slots actually used could be equal or less than the The number of physical slots actually used could be equal or less than the
value specified by num-slots. If this property is not specified, the value value specified by num-slots. If this property is not specified, the value
of num-slot property is assumed to be 1. of num-slot property is assumed to be 1.
...@@ -124,7 +124,6 @@ board specific portions as listed below. ...@@ -124,7 +124,6 @@ board specific portions as listed below.
dwmmc0@12200000 { dwmmc0@12200000 {
clock-frequency = <400000000>; clock-frequency = <400000000>;
clock-freq-min-max = <400000 200000000>; clock-freq-min-max = <400000 200000000>;
num-slots = <1>;
broken-cd; broken-cd;
fifo-depth = <0x80>; fifo-depth = <0x80>;
card-detect-delay = <200>; card-detect-delay = <200>;
...@@ -139,7 +138,6 @@ board specific portions as listed below. ...@@ -139,7 +138,6 @@ board specific portions as listed below.
dwmmc0@12200000 { dwmmc0@12200000 {
clock-frequency = <400000000>; clock-frequency = <400000000>;
clock-freq-min-max = <400000 200000000>; clock-freq-min-max = <400000 200000000>;
num-slots = <1>;
broken-cd; broken-cd;
fifo-depth = <0x80>; fifo-depth = <0x80>;
card-detect-delay = <200>; card-detect-delay = <200>;
......
...@@ -25,7 +25,6 @@ Example: ...@@ -25,7 +25,6 @@ Example:
clock-frequency = <50000000>; clock-frequency = <50000000>;
clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>;
clock-names = "biu", "ciu"; clock-names = "biu", "ciu";
num-slots = <1>;
max-frequency = <50000000>; max-frequency = <50000000>;
cap-sdio-irq; cap-sdio-irq;
cap-sd-highspeed; cap-sd-highspeed;
......
...@@ -32,120 +32,6 @@ static u16 control_devconf1_offset; ...@@ -32,120 +32,6 @@ static u16 control_devconf1_offset;
#define HSMMC_NAME_LEN 9 #define HSMMC_NAME_LEN 9
static void omap_hsmmc1_before_set_reg(struct device *dev,
int power_on, int vdd)
{
u32 reg, prog_io;
struct omap_hsmmc_platform_data *mmc = dev->platform_data;
if (mmc->remux)
mmc->remux(dev, power_on);
/*
* Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
* card with Vcc regulator (from twl4030 or whatever). OMAP has both
* 1.8V and 3.0V modes, controlled by the PBIAS register.
*
* In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
* is most naturally TWL VSIM; those pins also use PBIAS.
*
* FIXME handle VMMC1A as needed ...
*/
if (power_on) {
if (cpu_is_omap2430()) {
reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
if ((1 << vdd) >= MMC_VDD_30_31)
reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
else
reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
}
if (mmc->internal_clock) {
reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
reg |= OMAP2_MMCSDIO1ADPCLKISEL;
omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
}
reg = omap_ctrl_readl(control_pbias_offset);
if (cpu_is_omap3630()) {
/* Set MMC I/O to 52MHz */
prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
} else {
reg |= OMAP2_PBIASSPEEDCTRL0;
}
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
omap_ctrl_writel(reg, control_pbias_offset);
} else {
reg = omap_ctrl_readl(control_pbias_offset);
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
omap_ctrl_writel(reg, control_pbias_offset);
}
}
static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int vdd)
{
u32 reg;
/* 100ms delay required for PBIAS configuration */
msleep(100);
if (power_on) {
reg = omap_ctrl_readl(control_pbias_offset);
reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
if ((1 << vdd) <= MMC_VDD_165_195)
reg &= ~OMAP2_PBIASLITEVMODE0;
else
reg |= OMAP2_PBIASLITEVMODE0;
omap_ctrl_writel(reg, control_pbias_offset);
} else {
reg = omap_ctrl_readl(control_pbias_offset);
reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
OMAP2_PBIASLITEVMODE0);
omap_ctrl_writel(reg, control_pbias_offset);
}
}
static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
{
u32 reg;
reg = omap_ctrl_readl(control_devconf1_offset);
if (mmc->internal_clock)
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
else
reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
omap_ctrl_writel(reg, control_devconf1_offset);
}
static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd)
{
struct omap_hsmmc_platform_data *mmc = dev->platform_data;
if (mmc->remux)
mmc->remux(dev, power_on);
if (power_on)
hsmmc2_select_input_clk_src(mmc);
}
static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd)
{
struct omap_hsmmc_platform_data *mmc = dev->platform_data;
if (power_on)
hsmmc2_select_input_clk_src(mmc);
return 0;
}
static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
{
return 0;
}
static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
struct omap_hsmmc_platform_data *mmc) struct omap_hsmmc_platform_data *mmc)
{ {
...@@ -157,101 +43,11 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, ...@@ -157,101 +43,11 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
return -ENOMEM; return -ENOMEM;
} }
if (c->name) snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", c->mmc, 1);
strncpy(hc_name, c->name, HSMMC_NAME_LEN);
else
snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
c->mmc, 1);
mmc->name = hc_name; mmc->name = hc_name;
mmc->caps = c->caps; mmc->caps = c->caps;
mmc->internal_clock = !c->ext_clock;
mmc->reg_offset = 0; mmc->reg_offset = 0;
if (c->cover_only) {
/* detect if mobile phone cover removed */
mmc->gpio_cd = -EINVAL;
mmc->gpio_cod = c->gpio_cd;
} else {
/* card detect pin on the mmc socket itself */
mmc->gpio_cd = c->gpio_cd;
mmc->gpio_cod = -EINVAL;
}
mmc->gpio_wp = c->gpio_wp;
mmc->remux = c->remux;
mmc->init_card = c->init_card;
if (c->nonremovable)
mmc->nonremovable = 1;
/*
* NOTE: MMC slots should have a Vcc regulator set up.
* This may be from a TWL4030-family chip, another
* controllable regulator, or a fixed supply.
*
* temporary HACK: ocr_mask instead of fixed supply
*/
if (soc_is_am35xx())
mmc->ocr_mask = MMC_VDD_165_195 |
MMC_VDD_26_27 |
MMC_VDD_27_28 |
MMC_VDD_29_30 |
MMC_VDD_30_31 |
MMC_VDD_31_32;
else
mmc->ocr_mask = c->ocr_mask;
if (!soc_is_am35xx())
mmc->features |= HSMMC_HAS_PBIAS;
switch (c->mmc) {
case 1:
if (mmc->features & HSMMC_HAS_PBIAS) {
/* on-chip level shifting via PBIAS0/PBIAS1 */
mmc->before_set_reg =
omap_hsmmc1_before_set_reg;
mmc->after_set_reg =
omap_hsmmc1_after_set_reg;
}
if (soc_is_am35xx())
mmc->set_power = nop_mmc_set_power;
/* OMAP3630 HSMMC1 supports only 4-bit */
if (cpu_is_omap3630() &&
(c->caps & MMC_CAP_8_BIT_DATA)) {
c->caps &= ~MMC_CAP_8_BIT_DATA;
c->caps |= MMC_CAP_4_BIT_DATA;
mmc->caps = c->caps;
}
break;
case 2:
if (soc_is_am35xx())
mmc->set_power = am35x_hsmmc2_set_power;
if (c->ext_clock)
c->transceiver = 1;
if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
c->caps &= ~MMC_CAP_8_BIT_DATA;
c->caps |= MMC_CAP_4_BIT_DATA;
}
if (mmc->features & HSMMC_HAS_PBIAS) {
/* off-chip level shifting, or none */
mmc->before_set_reg = hsmmc2_before_set_reg;
mmc->after_set_reg = NULL;
}
break;
case 3:
case 4:
case 5:
mmc->before_set_reg = NULL;
mmc->after_set_reg = NULL;
break;
default:
pr_err("MMC%d configuration not supported!\n", c->mmc);
kfree(hc_name);
return -ENODEV;
}
return 0; return 0;
} }
...@@ -260,7 +56,6 @@ static int omap_hsmmc_done; ...@@ -260,7 +56,6 @@ static int omap_hsmmc_done;
void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
{ {
struct platform_device *pdev; struct platform_device *pdev;
struct omap_hsmmc_platform_data *mmc_pdata;
int res; int res;
if (omap_hsmmc_done != 1) if (omap_hsmmc_done != 1)
...@@ -269,32 +64,12 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) ...@@ -269,32 +64,12 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
omap_hsmmc_done++; omap_hsmmc_done++;
for (; c->mmc; c++) { for (; c->mmc; c++) {
if (!c->deferred)
continue;
pdev = c->pdev; pdev = c->pdev;
if (!pdev) if (!pdev)
continue; continue;
mmc_pdata = pdev->dev.platform_data;
if (!mmc_pdata)
continue;
if (c->cover_only) {
/* detect if mobile phone cover removed */
mmc_pdata->gpio_cd = -EINVAL;
mmc_pdata->gpio_cod = c->gpio_cd;
} else {
/* card detect pin on the mmc socket itself */
mmc_pdata->gpio_cd = c->gpio_cd;
mmc_pdata->gpio_cod = -EINVAL;
}
mmc_pdata->gpio_wp = c->gpio_wp;
res = omap_device_register(pdev); res = omap_device_register(pdev);
if (res) if (res)
pr_err("Could not late init MMC %s\n", pr_err("Could not late init MMC\n");
c->name);
} }
} }
...@@ -336,13 +111,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, ...@@ -336,13 +111,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
if (oh->dev_attr != NULL) { if (oh->dev_attr != NULL) {
mmc_dev_attr = oh->dev_attr; mmc_dev_attr = oh->dev_attr;
mmc_data->controller_flags = mmc_dev_attr->flags; mmc_data->controller_flags = mmc_dev_attr->flags;
/*
* erratum 2.1.1.128 doesn't apply if board has
* a transceiver is attached
*/
if (hsmmcinfo->transceiver)
mmc_data->controller_flags &=
~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ;
} }
pdev = platform_device_alloc(name, ctrl_nr - 1); pdev = platform_device_alloc(name, ctrl_nr - 1);
...@@ -367,9 +135,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, ...@@ -367,9 +135,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
hsmmcinfo->pdev = pdev; hsmmcinfo->pdev = pdev;
if (hsmmcinfo->deferred)
goto free_mmc;
res = omap_device_register(pdev); res = omap_device_register(pdev);
if (res) { if (res) {
pr_err("Could not register od for %s\n", name); pr_err("Could not register od for %s\n", name);
......
...@@ -12,18 +12,9 @@ struct omap2_hsmmc_info { ...@@ -12,18 +12,9 @@ struct omap2_hsmmc_info {
u8 mmc; /* controller 1/2/3 */ u8 mmc; /* controller 1/2/3 */
u32 caps; /* 4/8 wires and any additional host u32 caps; /* 4/8 wires and any additional host
* capabilities OR'd (ref. linux/mmc/host.h) */ * capabilities OR'd (ref. linux/mmc/host.h) */
bool transceiver; /* MMC-2 option */
bool ext_clock; /* use external pin for input clock */
bool cover_only; /* No card detect - just cover switch */
bool nonremovable; /* Nonremovable e.g. eMMC */
bool deferred; /* mmc needs a deferred probe */
int gpio_cd; /* or -EINVAL */ int gpio_cd; /* or -EINVAL */
int gpio_wp; /* or -EINVAL */ int gpio_wp; /* or -EINVAL */
char *name; /* or NULL for default */
struct platform_device *pdev; /* mmc controller instance */ struct platform_device *pdev; /* mmc controller instance */
int ocr_mask; /* temporary HACK */
/* Remux (pad configuration) when powering on/off */
void (*remux)(struct device *dev, int power_on);
/* init some special card */ /* init some special card */
void (*init_card)(struct mmc_card *card); void (*init_card)(struct mmc_card *card);
}; };
......
...@@ -2957,7 +2957,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) ...@@ -2957,7 +2957,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
} }
/* find out number of slots supported */ /* find out number of slots supported */
if (device_property_read_u32(dev, "num-slots", &pdata->num_slots)) if (!device_property_read_u32(dev, "num-slots", &pdata->num_slots))
dev_info(dev, "'num-slots' was deprecated.\n"); dev_info(dev, "'num-slots' was deprecated.\n");
if (device_property_read_u32(dev, "fifo-depth", &pdata->fifo_depth)) if (device_property_read_u32(dev, "fifo-depth", &pdata->fifo_depth))
......
...@@ -356,9 +356,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, ...@@ -356,9 +356,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
struct mmc_host *mmc = host->mmc; struct mmc_host *mmc = host->mmc;
int ret = 0; int ret = 0;
if (mmc_pdata(host)->set_power)
return mmc_pdata(host)->set_power(host->dev, power_on, vdd);
/* /*
* If we don't see a Vcc regulator, assume it's a fixed * If we don't see a Vcc regulator, assume it's a fixed
* voltage always-on regulator. * voltage always-on regulator.
...@@ -366,9 +363,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, ...@@ -366,9 +363,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
if (IS_ERR(mmc->supply.vmmc)) if (IS_ERR(mmc->supply.vmmc))
return 0; return 0;
if (mmc_pdata(host)->before_set_reg)
mmc_pdata(host)->before_set_reg(host->dev, power_on, vdd);
ret = omap_hsmmc_set_pbias(host, false, 0); ret = omap_hsmmc_set_pbias(host, false, 0);
if (ret) if (ret)
return ret; return ret;
...@@ -400,9 +394,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, ...@@ -400,9 +394,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
return ret; return ret;
} }
if (mmc_pdata(host)->after_set_reg)
mmc_pdata(host)->after_set_reg(host->dev, power_on, vdd);
return 0; return 0;
err_set_voltage: err_set_voltage:
...@@ -469,8 +460,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) ...@@ -469,8 +460,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
int ret; int ret;
struct mmc_host *mmc = host->mmc; struct mmc_host *mmc = host->mmc;
if (mmc_pdata(host)->set_power)
return 0;
ret = mmc_regulator_get_supply(mmc); ret = mmc_regulator_get_supply(mmc);
if (ret == -EPROBE_DEFER) if (ret == -EPROBE_DEFER)
......
...@@ -793,8 +793,12 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, ...@@ -793,8 +793,12 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
} }
mmc_writel(host, REG_CLKCR, rval); mmc_writel(host, REG_CLKCR, rval);
if (host->cfg->needs_new_timings) if (host->cfg->needs_new_timings) {
mmc_writel(host, REG_SD_NTSR, SDXC_2X_TIMING_MODE); /* Don't touch the delay bits */
rval = mmc_readl(host, REG_SD_NTSR);
rval |= SDXC_2X_TIMING_MODE;
mmc_writel(host, REG_SD_NTSR, rval);
}
ret = sunxi_mmc_clk_set_phase(host, ios, rate); ret = sunxi_mmc_clk_set_phase(host, ios, rate);
if (ret) if (ret)
......
...@@ -55,9 +55,6 @@ struct omap_hsmmc_platform_data { ...@@ -55,9 +55,6 @@ struct omap_hsmmc_platform_data {
u32 caps; /* Used for the MMC driver on 2430 and later */ u32 caps; /* Used for the MMC driver on 2430 and later */
u32 pm_caps; /* PM capabilities of the mmc */ u32 pm_caps; /* PM capabilities of the mmc */
/* use the internal clock */
unsigned internal_clock:1;
/* nonremovable e.g. eMMC */ /* nonremovable e.g. eMMC */
unsigned nonremovable:1; unsigned nonremovable:1;
...@@ -73,13 +70,6 @@ struct omap_hsmmc_platform_data { ...@@ -73,13 +70,6 @@ struct omap_hsmmc_platform_data {
int gpio_cd; /* gpio (card detect) */ int gpio_cd; /* gpio (card detect) */
int gpio_cod; /* gpio (cover detect) */ int gpio_cod; /* gpio (cover detect) */
int gpio_wp; /* gpio (write protect) */ int gpio_wp; /* gpio (write protect) */
int (*set_power)(struct device *dev, int power_on, int vdd);
void (*remux)(struct device *dev, int power_on);
/* Call back before enabling / disabling regulators */
void (*before_set_reg)(struct device *dev, int power_on, int vdd);
/* Call back after enabling / disabling regulators */
void (*after_set_reg)(struct device *dev, int power_on, int vdd);
/* if we have special card, init it using this callback */ /* if we have special card, init it using this callback */
void (*init_card)(struct mmc_card *card); void (*init_card)(struct mmc_card *card);
......
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