Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 186284
b: refs/heads/master
c: da68c4e
h: refs/heads/master
v: v3
  • Loading branch information
Nicolas Pitre authored and Linus Torvalds committed Mar 6, 2010
1 parent 1306b20 commit 5dcd2be
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e506f35b1dc327c448d4791bc098f07b9b2efe9
refs/heads/master: da68c4eb258cd9f3f0b8aeb7e46b8118bb6358b6
12 changes: 9 additions & 3 deletions trunk/drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,9 @@ void mmc_stop_host(struct mmc_host *host)
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();

/* clear pm flags now and let card drivers set them as needed */
host->pm_flags = 0;

mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
if (host->bus_ops->remove)
Expand Down Expand Up @@ -1273,12 +1276,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_release_host(host);
host->pm_flags = 0;
err = 0;
}
}
mmc_bus_put(host);

if (!err)
if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
mmc_power_off(host);

return err;
Expand All @@ -1296,8 +1300,10 @@ int mmc_resume_host(struct mmc_host *host)

mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
}
BUG_ON(!host->bus_ops->resume);
err = host->bus_ops->resume(host);
if (err) {
Expand Down
49 changes: 49 additions & 0 deletions trunk/drivers/mmc/core/sdio_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
*err_ret = ret;
}
EXPORT_SYMBOL_GPL(sdio_f0_writeb);

/**
* sdio_get_host_pm_caps - get host power management capabilities
* @func: SDIO function attached to host
*
* Returns a capability bitmask corresponding to power management
* features supported by the host controller that the card function
* might rely upon during a system suspend. The host doesn't need
* to be claimed, nor the function active, for this information to be
* obtained.
*/
mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
{
BUG_ON(!func);
BUG_ON(!func->card);

return func->card->host->pm_caps;
}
EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);

/**
* sdio_set_host_pm_flags - set wanted host power management capabilities
* @func: SDIO function attached to host
*
* Set a capability bitmask corresponding to wanted host controller
* power management features for the upcoming suspend state.
* This must be called, if needed, each time the suspend method of
* the function driver is called, and must contain only bits that
* were returned by sdio_get_host_pm_caps().
* The host doesn't need to be claimed, nor the function active,
* for this information to be set.
*/
int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
{
struct mmc_host *host;

BUG_ON(!func);
BUG_ON(!func->card);

host = func->card->host;

if (flags & ~host->pm_caps)
return -EINVAL;

/* function suspend methods are serialized, hence no lock needed */
host->pm_flags |= flags;
return 0;
}
EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
5 changes: 5 additions & 0 deletions trunk/include/linux/mmc/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/sched.h>

#include <linux/mmc/core.h>
#include <linux/mmc/pm.h>

struct mmc_ios {
unsigned int clock; /* clock rate */
Expand Down Expand Up @@ -152,6 +153,8 @@ struct mmc_host {
#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */

mmc_pm_flag_t pm_caps; /* supported pm features */

/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */
Expand Down Expand Up @@ -197,6 +200,8 @@ struct mmc_host {
struct task_struct *sdio_irq_thread;
atomic_t sdio_irq_thread_abort;

mmc_pm_flag_t pm_flags; /* requested pm features */

#ifdef CONFIG_LEDS_TRIGGERS
struct led_trigger *led; /* activity led */
#endif
Expand Down
30 changes: 30 additions & 0 deletions trunk/include/linux/mmc/pm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* linux/include/linux/mmc/pm.h
*
* Author: Nicolas Pitre
* Copyright: (C) 2009 Marvell Technology Group Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef LINUX_MMC_PM_H
#define LINUX_MMC_PM_H

/*
* These flags are used to describe power management features that
* some cards (typically SDIO cards) might wish to benefit from when
* the host system is being suspended. There are several layers of
* abstractions involved, from the host controller driver, to the MMC core
* code, to the SDIO core code, to finally get to the actual SDIO function
* driver. This file is therefore used for common definitions shared across
* all those layers.
*/

typedef unsigned int mmc_pm_flag_t;

#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */
#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */

#endif
5 changes: 5 additions & 0 deletions trunk/include/linux/mmc/sdio_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>

#include <linux/mmc/pm.h>

struct mmc_card;
struct sdio_func;

Expand Down Expand Up @@ -153,5 +155,8 @@ extern unsigned char sdio_f0_readb(struct sdio_func *func,
extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
unsigned int addr, int *err_ret);

extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);

#endif

0 comments on commit 5dcd2be

Please sign in to comment.