aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/host.c3
-rw-r--r--drivers/mmc/core/sdio_irq.c8
-rw-r--r--include/linux/mmc/host.h8
3 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 2c7ce8f43a9a..37b761891d67 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -100,6 +100,9 @@ int mmc_add_host(struct mmc_host *host)
100{ 100{
101 int err; 101 int err;
102 102
103 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
104 !host->ops->enable_sdio_irq);
105
103 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) 106 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
104 return -ENOMEM; 107 return -ENOMEM;
105 108
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 01922d29241d..01daee934d16 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -70,7 +70,8 @@ static int sdio_irq_thread(void *_host)
70 * asynchronous notification of pending SDIO card interrupts 70 * asynchronous notification of pending SDIO card interrupts
71 * hence we poll for them in that case. 71 * hence we poll for them in that case.
72 */ 72 */
73 period = msecs_to_jiffies(10); 73 period = (host->caps & MMC_CAP_SDIO_IRQ) ?
74 MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(10);
74 75
75 pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n", 76 pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
76 mmc_hostname(host), period); 77 mmc_hostname(host), period);
@@ -104,11 +105,16 @@ static int sdio_irq_thread(void *_host)
104 ssleep(1); 105 ssleep(1);
105 106
106 set_task_state(current, TASK_INTERRUPTIBLE); 107 set_task_state(current, TASK_INTERRUPTIBLE);
108 if (host->caps & MMC_CAP_SDIO_IRQ)
109 host->ops->enable_sdio_irq(host, 1);
107 if (!kthread_should_stop()) 110 if (!kthread_should_stop())
108 schedule_timeout(period); 111 schedule_timeout(period);
109 set_task_state(current, TASK_RUNNING); 112 set_task_state(current, TASK_RUNNING);
110 } while (!kthread_should_stop()); 113 } while (!kthread_should_stop());
111 114
115 if (host->caps & MMC_CAP_SDIO_IRQ)
116 host->ops->enable_sdio_irq(host, 0);
117
112 pr_debug("%s: IRQ thread exiting with code %d\n", 118 pr_debug("%s: IRQ thread exiting with code %d\n",
113 mmc_hostname(host), ret); 119 mmc_hostname(host), ret);
114 120
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 00dc1809494c..3fd197962f73 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -51,6 +51,7 @@ struct mmc_host_ops {
51 void (*request)(struct mmc_host *host, struct mmc_request *req); 51 void (*request)(struct mmc_host *host, struct mmc_request *req);
52 void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); 52 void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
53 int (*get_ro)(struct mmc_host *host); 53 int (*get_ro)(struct mmc_host *host);
54 void (*enable_sdio_irq)(struct mmc_host *host, int enable);
54}; 55};
55 56
56struct mmc_card; 57struct mmc_card;
@@ -89,6 +90,7 @@ struct mmc_host {
89#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ 90#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */
90#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */ 91#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
91#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */ 92#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
93#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
92 94
93 /* host specific block data */ 95 /* host specific block data */
94 unsigned int max_seg_size; /* see blk_queue_max_segment_size */ 96 unsigned int max_seg_size; /* see blk_queue_max_segment_size */
@@ -150,5 +152,11 @@ extern int mmc_resume_host(struct mmc_host *);
150extern void mmc_detect_change(struct mmc_host *, unsigned long delay); 152extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
151extern void mmc_request_done(struct mmc_host *, struct mmc_request *); 153extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
152 154
155static inline void mmc_signal_sdio_irq(struct mmc_host *host)
156{
157 host->ops->enable_sdio_irq(host, 0);
158 wake_up_process(host->sdio_irq_thread);
159}
160
153#endif 161#endif
154 162