{
int err;
+ WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
+ !host->ops->enable_sdio_irq);
+
if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
return -ENOMEM;
* asynchronous notification of pending SDIO card interrupts
* hence we poll for them in that case.
*/
- period = msecs_to_jiffies(10);
+ period = (host->caps & MMC_CAP_SDIO_IRQ) ?
+ MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(10);
pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
mmc_hostname(host), period);
ssleep(1);
set_task_state(current, TASK_INTERRUPTIBLE);
+ if (host->caps & MMC_CAP_SDIO_IRQ)
+ host->ops->enable_sdio_irq(host, 1);
if (!kthread_should_stop())
schedule_timeout(period);
set_task_state(current, TASK_RUNNING);
} while (!kthread_should_stop());
+ if (host->caps & MMC_CAP_SDIO_IRQ)
+ host->ops->enable_sdio_irq(host, 0);
+
pr_debug("%s: IRQ thread exiting with code %d\n",
mmc_hostname(host), ret);
void (*request)(struct mmc_host *host, struct mmc_request *req);
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
int (*get_ro)(struct mmc_host *host);
+ void (*enable_sdio_irq)(struct mmc_host *host, int enable);
};
struct mmc_card;
#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */
#define MMC_CAP_MMC_HIGHSPEED (1 << 2) /* Can do MMC high-speed timing */
#define MMC_CAP_SD_HIGHSPEED (1 << 3) /* Can do SD high-speed timing */
+#define MMC_CAP_SDIO_IRQ (1 << 4) /* Can signal pending SDIO IRQs */
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
+static inline void mmc_signal_sdio_irq(struct mmc_host *host)
+{
+ host->ops->enable_sdio_irq(host, 0);
+ wake_up_process(host->sdio_irq_thread);
+}
+
#endif