#define MMC_BUS_WIDTH_1 0
#define MMC_BUS_WIDTH_4 2
+#define MMC_BUS_WIDTH_8 3
unsigned char timing; /* timing specification used */
};
struct mmc_host_ops {
+ /*
+ * Hosts that support power saving can use the 'enable' and 'disable'
+ * methods to exit and enter power saving states. 'enable' is called
+ * when the host is claimed and 'disable' is called (or scheduled with
+ * a delay) when the host is released. The 'disable' is scheduled if
+ * the disable delay set by 'mmc_set_disable_delay()' is non-zero,
+ * otherwise 'disable' is called immediately. 'disable' may be
+ * scheduled repeatedly, to permit ever greater power saving at the
+ * expense of ever greater latency to re-enable. Rescheduling is
+ * determined by the return value of the 'disable' method. A positive
+ * value gives the delay in jiffies.
+ *
+ * In the case where a host function (like set_ios) may be called
+ * with or without the host claimed, enabling and disabling can be
+ * done directly and will nest correctly. Call 'mmc_host_enable()' and
+ * 'mmc_host_lazy_disable()' for this purpose, but note that these
+ * functions must be paired.
+ *
+ * Alternatively, 'mmc_host_enable()' may be paired with
+ * 'mmc_host_disable()' which calls 'disable' immediately. In this
+ * case the 'disable' method will be called with 'lazy' set to 0.
+ * This is mainly useful for error paths.
+ *
+ * Because lazy disble may be called from a work queue, the 'disable'
+ * method must claim the host when 'lazy' != 0, which will work
+ * correctly because recursion is detected and handled.
+ */
+ int (*enable)(struct mmc_host *host);
+ int (*disable)(struct mmc_host *host, int lazy);
void (*request)(struct mmc_host *host, struct mmc_request *req);
/*
* Avoid calling these three functions too often or in a "fast path",
#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */
#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
+#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */
+#define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */
+#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
+#define MMC_CAP_NOT_SDIO (1 << 9) /* Card cannot be SDIO */
+#define MMC_CAP_NOT_SD (1 << 10) /* Card cannot be SD */
+#define MMC_CAP_NOT_MMC (1 << 11) /* Card cannot be MMC */
+
+#define MMC_CAP_SDIO_ONLY (MMC_CAP_NOT_SD | MMC_CAP_NOT_MMC)
+#define MMC_CAP_SD_ONLY (MMC_CAP_NOT_SDIO | MMC_CAP_NOT_MMC)
+#define MMC_CAP_MMC_ONLY (MMC_CAP_NOT_SDIO | MMC_CAP_NOT_SD)
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
unsigned int removed:1; /* host is being removed */
#endif
+ /* Only used with MMC_CAP_DISABLE */
+ int enabled; /* host is enabled */
+ int nesting_cnt; /* "enable" nesting count */
+ int en_dis_recurs; /* detect recursion */
+ unsigned int disable_delay; /* disable delay in msecs */
+ struct delayed_work disable; /* disabling work */
+
struct mmc_card *card; /* device attached to this host */
wait_queue_head_t wq;
+ struct task_struct *claimer; /* task that has host claimed */
+ int claim_cnt; /* "claim" nesting count */
struct delayed_work detect;
extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
extern int mmc_resume_host(struct mmc_host *);
+extern void mmc_power_save_host(struct mmc_host *host);
+extern void mmc_power_restore_host(struct mmc_host *host);
+
extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
wake_up_process(host->sdio_irq_thread);
}
+int mmc_card_awake(struct mmc_host *host);
+int mmc_card_sleep(struct mmc_host *host);
+int mmc_card_can_sleep(struct mmc_host *host);
+
+int mmc_host_enable(struct mmc_host *host);
+int mmc_host_disable(struct mmc_host *host);
+int mmc_host_lazy_disable(struct mmc_host *host);
+
+static inline void mmc_set_disable_delay(struct mmc_host *host,
+ unsigned int disable_delay)
+{
+ host->disable_delay = disable_delay;
+}
+
#endif