Skip to content

Commit

Permalink
Merge tag 'mmc-updates-for-3.13-rc1' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/cjb/mmc

Pull MMC updates from Chris Ball:
 "MMC highlights for 3.13:

  Core:
   - Improve runtime PM support, remove mmc_{suspend,resume}_host().
   - Add MMC_CAP_RUNTIME_RESUME, for delaying MMC resume until we're
     outside of the resume sequence (in runtime_resume) to decrease
     system resume time.

  Drivers:
   - dw_mmc: Support HS200 mode.
   - sdhci-eshdc-imx: Support SD3.0 SDR clock tuning, DDR on IMX6.
   - sdhci-pci: Add support for Intel Clovertrail and Merrifield"

* tag 'mmc-updates-for-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (108 commits)
  mmc: wbsd: Silence compiler warning
  mmc: core: Silence compiler warning in __mmc_switch
  mmc: sh_mmcif: Convert to clk_prepare|unprepare
  mmc: sh_mmcif: Convert to PM macros when defining dev_pm_ops
  mmc: dw_mmc: exynos: Revert the sdr_timing assignment
  mmc: sdhci: Avoid needless loop while handling SDIO interrupts in sdhci_irq
  mmc: core: Add MMC_CAP_RUNTIME_RESUME to resume at runtime_resume
  mmc: core: Improve runtime PM support during suspend/resume for sd/mmc
  mmc: core: Remove redundant mmc_power_up|off at runtime callbacks
  mmc: Don't force card to active state when entering suspend/shutdown
  MIPS: db1235: Don't use MMC_CLKGATE
  mmc: core: Remove deprecated mmc_suspend|resume_host APIs
  mmc: mmci: Move away from using deprecated APIs
  mmc: via-sdmmc: Move away from using deprecated APIs
  mmc: tmio: Move away from using deprecated APIs
  mmc: sh_mmcif: Move away from using deprecated APIs
  mmc: sdricoh_cs: Move away from using deprecated APIs
  mmc: rtsx: Remove redundant suspend and resume callbacks
  mmc: wbsd: Move away from using deprecated APIs
  mmc: pxamci: Remove redundant suspend and resume callbacks
  ...
  • Loading branch information
torvalds committed Nov 18, 2013
2 parents 2d3c627 + e395c43 commit c2ac2ae
Show file tree
Hide file tree
Showing 54 changed files with 1,818 additions and 1,240 deletions.
5 changes: 5 additions & 0 deletions Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Required properties:
Optional properties:
- fsl,cd-controller : Indicate to use controller internal card detection
- fsl,wp-controller : Indicate to use controller internal write protection
- fsl,delay-line : Specify the number of delay cells for override mode.
This is used to set the clock delay for DLL(Delay Line) on override mode
to select a proper data sampling window in case the clock quality is not good
due to signal path is too long on the board. Please refer to eSDHC/uSDHC
chapter, DLL (Delay Line) section in RM for details.

Examples:

Expand Down
9 changes: 9 additions & 0 deletions Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ Optional properties:
is specified and the ciu clock is specified then we'll try to set the ciu
clock to this at probe time.

* clock-freq-min-max: Minimum and Maximum clock frequency for card output
clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.

* num-slots: specifies the number of slots supported by the controller.
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
Expand All @@ -66,6 +69,10 @@ Optional properties:

* supports-highspeed: Enables support for high speed cards (up to 50MHz)

* caps2-mmc-hs200-1_8v: Supports mmc HS200 SDR 1.8V mode

* caps2-mmc-hs200-1_2v: Supports mmc HS200 SDR 1.2V mode

* broken-cd: as documented in mmc core bindings.

* vmmc-supply: The phandle to the regulator to use for vmmc. If this is
Expand Down Expand Up @@ -93,8 +100,10 @@ board specific portions as listed below.

dwmmc0@12200000 {
clock-frequency = <400000000>;
clock-freq-min-max = <400000 200000000>;
num-slots = <1>;
supports-highspeed;
caps2-mmc-hs200-1_8v;
broken-cd;
fifo-depth = <0x80>;
card-detect-delay = <200>;
Expand Down
1 change: 0 additions & 1 deletion arch/mips/configs/db1235_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=y
CONFIG_MMC=y
CONFIG_MMC_CLKGATE=y
CONFIG_MMC_AU1X=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
Expand Down
1 change: 1 addition & 0 deletions arch/sh/boards/mach-ecovec24/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/mmc/sh_mmcif.h>
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/mfd/tmio.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
Expand Down
2 changes: 0 additions & 2 deletions drivers/mmc/card/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -2448,7 +2448,6 @@ static int _mmc_blk_suspend(struct mmc_card *card)
struct mmc_blk_data *md = mmc_get_drvdata(card);

if (md) {
pm_runtime_get_sync(&card->dev);
mmc_queue_suspend(&md->queue);
list_for_each_entry(part_md, &md->part, part) {
mmc_queue_suspend(&part_md->queue);
Expand Down Expand Up @@ -2483,7 +2482,6 @@ static int mmc_blk_resume(struct mmc_card *card)
list_for_each_entry(part_md, &md->part, part) {
mmc_queue_resume(&part_md->queue);
}
pm_runtime_put(&card->dev);
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/mmc/core/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ int mmc_add_card(struct mmc_card *card)
break;
}

if (mmc_sd_card_uhs(card) &&
if (mmc_card_uhs(card) &&
(card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];

Expand Down
154 changes: 58 additions & 96 deletions drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/log2.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeup.h>
#include <linux/suspend.h>
#include <linux/fault-inject.h>
#include <linux/random.h>
Expand Down Expand Up @@ -301,7 +302,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
}

err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal, true);
if (err) {
pr_warn("%s: Error %d starting bkops\n",
mmc_hostname(card->host), err);
Expand Down Expand Up @@ -917,31 +918,6 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)

EXPORT_SYMBOL(__mmc_claim_host);

/**
* mmc_try_claim_host - try exclusively to claim a host
* @host: mmc host to claim
*
* Returns %1 if the host is claimed, %0 otherwise.
*/
int mmc_try_claim_host(struct mmc_host *host)
{
int claimed_host = 0;
unsigned long flags;

spin_lock_irqsave(&host->lock, flags);
if (!host->claimed || host->claimer == current) {
host->claimed = 1;
host->claimer = current;
host->claim_cnt += 1;
claimed_host = 1;
}
spin_unlock_irqrestore(&host->lock, flags);
if (host->ops->enable && claimed_host && host->claim_cnt == 1)
host->ops->enable(host);
return claimed_host;
}
EXPORT_SYMBOL(mmc_try_claim_host);

/**
* mmc_release_host - release a host
* @host: mmc host to release
Expand Down Expand Up @@ -1382,22 +1358,31 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
{
int bit;

ocr &= host->ocr_avail;
/*
* Sanity check the voltages that the card claims to
* support.
*/
if (ocr & 0x7F) {
dev_warn(mmc_dev(host),
"card claims to support voltages below defined range\n");
ocr &= ~0x7F;
}

bit = ffs(ocr);
if (bit) {
bit -= 1;
ocr &= host->ocr_avail;
if (!ocr) {
dev_warn(mmc_dev(host), "no support for card's volts\n");
return 0;
}

if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) {
bit = ffs(ocr) - 1;
ocr &= 3 << bit;

mmc_host_clk_hold(host);
host->ios.vdd = bit;
mmc_set_ios(host);
mmc_host_clk_release(host);
mmc_power_cycle(host, ocr);
} else {
pr_warning("%s: host doesn't support card's voltages\n",
mmc_hostname(host));
ocr = 0;
bit = fls(ocr) - 1;
ocr &= 3 << bit;
if (bit != host->ios.vdd)
dev_warn(mmc_dev(host), "exceeding card's volts\n");
}

return ocr;
Expand All @@ -1422,7 +1407,7 @@ int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)

}

int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
{
struct mmc_command cmd = {0};
int err = 0;
Expand Down Expand Up @@ -1504,7 +1489,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
if (err) {
pr_debug("%s: Signal voltage switch failed, "
"power cycling card\n", mmc_hostname(host));
mmc_power_cycle(host);
mmc_power_cycle(host, ocr);
}

mmc_host_clk_release(host);
Expand Down Expand Up @@ -1545,22 +1530,14 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
* If a host does all the power sequencing itself, ignore the
* initial MMC_POWER_UP stage.
*/
void mmc_power_up(struct mmc_host *host)
void mmc_power_up(struct mmc_host *host, u32 ocr)
{
int bit;

if (host->ios.power_mode == MMC_POWER_ON)
return;

mmc_host_clk_hold(host);

/* If ocr is set, we use it */
if (host->ocr)
bit = ffs(host->ocr) - 1;
else
bit = fls(host->ocr_avail) - 1;

host->ios.vdd = bit;
host->ios.vdd = fls(ocr) - 1;
if (mmc_host_is_spi(host))
host->ios.chip_select = MMC_CS_HIGH;
else
Expand Down Expand Up @@ -1604,13 +1581,6 @@ void mmc_power_off(struct mmc_host *host)
host->ios.clock = 0;
host->ios.vdd = 0;


/*
* Reset ocr mask to be the highest possible voltage supported for
* this mmc host. This value will be used at next power up.
*/
host->ocr = 1 << (fls(host->ocr_avail) - 1);

if (!mmc_host_is_spi(host)) {
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.chip_select = MMC_CS_DONTCARE;
Expand All @@ -1630,12 +1600,12 @@ void mmc_power_off(struct mmc_host *host)
mmc_host_clk_release(host);
}

void mmc_power_cycle(struct mmc_host *host)
void mmc_power_cycle(struct mmc_host *host, u32 ocr)
{
mmc_power_off(host);
/* Wait at least 1 ms according to SD spec */
mmc_delay(1);
mmc_power_up(host);
mmc_power_up(host, ocr);
}

/*
Expand Down Expand Up @@ -1723,6 +1693,28 @@ void mmc_detach_bus(struct mmc_host *host)
mmc_bus_put(host);
}

static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
bool cd_irq)
{
#ifdef CONFIG_MMC_DEBUG
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
WARN_ON(host->removed);
spin_unlock_irqrestore(&host->lock, flags);
#endif

/*
* If the device is configured as wakeup, we prevent a new sleep for
* 5 s to give provision for user space to consume the event.
*/
if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&
device_can_wakeup(mmc_dev(host)))
pm_wakeup_event(mmc_dev(host), 5000);

host->detect_change = 1;
mmc_schedule_delayed_work(&host->detect, delay);
}

/**
* mmc_detect_change - process change of state on a MMC socket
* @host: host which changed state.
Expand All @@ -1735,16 +1727,8 @@ void mmc_detach_bus(struct mmc_host *host)
*/
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
#ifdef CONFIG_MMC_DEBUG
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
WARN_ON(host->removed);
spin_unlock_irqrestore(&host->lock, flags);
#endif
host->detect_change = 1;
mmc_schedule_delayed_work(&host->detect, delay);
_mmc_detect_change(host, delay, true);
}

EXPORT_SYMBOL(mmc_detect_change);

void mmc_init_erase(struct mmc_card *card)
Expand Down Expand Up @@ -2334,7 +2318,7 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
pr_info("%s: %s: trying to init card at %u Hz\n",
mmc_hostname(host), __func__, host->f_init);
#endif
mmc_power_up(host);
mmc_power_up(host, host->ocr_avail);

/*
* Some eMMCs (with VCCQ always on) may not be reset after power up, so
Expand Down Expand Up @@ -2423,7 +2407,7 @@ int mmc_detect_card_removed(struct mmc_host *host)
* rescan handle the card removal.
*/
cancel_delayed_work(&host->detect);
mmc_detect_change(host, 0);
_mmc_detect_change(host, 0, false);
}
}

Expand Down Expand Up @@ -2504,8 +2488,8 @@ void mmc_start_host(struct mmc_host *host)
if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
mmc_power_off(host);
else
mmc_power_up(host);
mmc_detect_change(host, 0);
mmc_power_up(host, host->ocr_avail);
_mmc_detect_change(host, 0, false);
}

void mmc_stop_host(struct mmc_host *host)
Expand Down Expand Up @@ -2583,7 +2567,7 @@ int mmc_power_restore_host(struct mmc_host *host)
return -EINVAL;
}

mmc_power_up(host);
mmc_power_up(host, host->card->ocr);
ret = host->bus_ops->power_restore(host);

mmc_bus_put(host);
Expand Down Expand Up @@ -2657,28 +2641,6 @@ EXPORT_SYMBOL(mmc_cache_ctrl);

#ifdef CONFIG_PM

/**
* mmc_suspend_host - suspend a host
* @host: mmc host
*/
int mmc_suspend_host(struct mmc_host *host)
{
/* This function is deprecated */
return 0;
}
EXPORT_SYMBOL(mmc_suspend_host);

/**
* mmc_resume_host - resume a previously suspended host
* @host: mmc host
*/
int mmc_resume_host(struct mmc_host *host)
{
/* This function is deprecated */
return 0;
}
EXPORT_SYMBOL(mmc_resume_host);

/* Do the card removal on suspend if card is assumed removeable
* Do that in pm notifier while userspace isn't yet frozen, so we will be able
to sync the card.
Expand Down Expand Up @@ -2724,7 +2686,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
spin_lock_irqsave(&host->lock, flags);
host->rescan_disable = 0;
spin_unlock_irqrestore(&host->lock, flags);
mmc_detect_change(host, 0);
_mmc_detect_change(host, 0, false);

}

Expand Down
6 changes: 3 additions & 3 deletions drivers/mmc/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr);
int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
void mmc_power_up(struct mmc_host *host);
void mmc_power_up(struct mmc_host *host, u32 ocr);
void mmc_power_off(struct mmc_host *host);
void mmc_power_cycle(struct mmc_host *host);
void mmc_power_cycle(struct mmc_host *host, u32 ocr);

static inline void mmc_delay(unsigned int ms)
{
Expand Down
Loading

0 comments on commit c2ac2ae

Please sign in to comment.