0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/sched.h>
0014 #include <uapi/linux/sched/types.h>
0015 #include <linux/kthread.h>
0016 #include <linux/export.h>
0017 #include <linux/wait.h>
0018 #include <linux/delay.h>
0019
0020 #include <linux/mmc/core.h>
0021 #include <linux/mmc/host.h>
0022 #include <linux/mmc/card.h>
0023 #include <linux/mmc/sdio.h>
0024 #include <linux/mmc/sdio_func.h>
0025
0026 #include "sdio_ops.h"
0027 #include "core.h"
0028 #include "card.h"
0029
0030 static int sdio_get_pending_irqs(struct mmc_host *host, u8 *pending)
0031 {
0032 struct mmc_card *card = host->card;
0033 int ret;
0034
0035 WARN_ON(!host->claimed);
0036
0037 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, pending);
0038 if (ret) {
0039 pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
0040 mmc_card_id(card), ret);
0041 return ret;
0042 }
0043
0044 if (*pending && mmc_card_broken_irq_polling(card) &&
0045 !(host->caps & MMC_CAP_SDIO_IRQ)) {
0046 unsigned char dummy;
0047
0048
0049
0050
0051
0052 mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy);
0053 }
0054
0055 return 0;
0056 }
0057
0058 static int process_sdio_pending_irqs(struct mmc_host *host)
0059 {
0060 struct mmc_card *card = host->card;
0061 int i, ret, count;
0062 bool sdio_irq_pending = host->sdio_irq_pending;
0063 unsigned char pending;
0064 struct sdio_func *func;
0065
0066
0067 if (mmc_card_suspended(card))
0068 return 0;
0069
0070
0071 host->sdio_irq_pending = false;
0072
0073
0074
0075
0076
0077
0078 func = card->sdio_single_irq;
0079 if (func && sdio_irq_pending) {
0080 func->irq_handler(func);
0081 return 1;
0082 }
0083
0084 ret = sdio_get_pending_irqs(host, &pending);
0085 if (ret)
0086 return ret;
0087
0088 count = 0;
0089 for (i = 1; i <= 7; i++) {
0090 if (pending & (1 << i)) {
0091 func = card->sdio_func[i - 1];
0092 if (!func) {
0093 pr_warn("%s: pending IRQ for non-existent function\n",
0094 mmc_card_id(card));
0095 ret = -EINVAL;
0096 } else if (func->irq_handler) {
0097 func->irq_handler(func);
0098 count++;
0099 } else {
0100 pr_warn("%s: pending IRQ with no handler\n",
0101 sdio_func_id(func));
0102 ret = -EINVAL;
0103 }
0104 }
0105 }
0106
0107 if (count)
0108 return count;
0109
0110 return ret;
0111 }
0112
0113 static void sdio_run_irqs(struct mmc_host *host)
0114 {
0115 mmc_claim_host(host);
0116 if (host->sdio_irqs) {
0117 process_sdio_pending_irqs(host);
0118 if (!host->sdio_irq_pending)
0119 host->ops->ack_sdio_irq(host);
0120 }
0121 mmc_release_host(host);
0122 }
0123
0124 void sdio_irq_work(struct work_struct *work)
0125 {
0126 struct mmc_host *host =
0127 container_of(work, struct mmc_host, sdio_irq_work.work);
0128
0129 sdio_run_irqs(host);
0130 }
0131
0132 void sdio_signal_irq(struct mmc_host *host)
0133 {
0134 host->sdio_irq_pending = true;
0135 queue_delayed_work(system_wq, &host->sdio_irq_work, 0);
0136 }
0137 EXPORT_SYMBOL_GPL(sdio_signal_irq);
0138
0139 static int sdio_irq_thread(void *_host)
0140 {
0141 struct mmc_host *host = _host;
0142 unsigned long period, idle_period;
0143 int ret;
0144
0145 sched_set_fifo_low(current);
0146
0147
0148
0149
0150
0151
0152
0153 idle_period = msecs_to_jiffies(10);
0154 period = (host->caps & MMC_CAP_SDIO_IRQ) ?
0155 MAX_SCHEDULE_TIMEOUT : idle_period;
0156
0157 pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
0158 mmc_hostname(host), period);
0159
0160 do {
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174 ret = __mmc_claim_host(host, NULL,
0175 &host->sdio_irq_thread_abort);
0176 if (ret)
0177 break;
0178 ret = process_sdio_pending_irqs(host);
0179 mmc_release_host(host);
0180
0181
0182
0183
0184
0185 if (ret < 0) {
0186 set_current_state(TASK_INTERRUPTIBLE);
0187 if (!kthread_should_stop())
0188 schedule_timeout(HZ);
0189 set_current_state(TASK_RUNNING);
0190 }
0191
0192
0193
0194
0195
0196
0197 if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
0198 if (ret > 0)
0199 period /= 2;
0200 else {
0201 period++;
0202 if (period > idle_period)
0203 period = idle_period;
0204 }
0205 }
0206
0207 set_current_state(TASK_INTERRUPTIBLE);
0208 if (host->caps & MMC_CAP_SDIO_IRQ)
0209 host->ops->enable_sdio_irq(host, 1);
0210 if (!kthread_should_stop())
0211 schedule_timeout(period);
0212 set_current_state(TASK_RUNNING);
0213 } while (!kthread_should_stop());
0214
0215 if (host->caps & MMC_CAP_SDIO_IRQ)
0216 host->ops->enable_sdio_irq(host, 0);
0217
0218 pr_debug("%s: IRQ thread exiting with code %d\n",
0219 mmc_hostname(host), ret);
0220
0221 return ret;
0222 }
0223
0224 static int sdio_card_irq_get(struct mmc_card *card)
0225 {
0226 struct mmc_host *host = card->host;
0227
0228 WARN_ON(!host->claimed);
0229
0230 if (!host->sdio_irqs++) {
0231 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) {
0232 atomic_set(&host->sdio_irq_thread_abort, 0);
0233 host->sdio_irq_thread =
0234 kthread_run(sdio_irq_thread, host,
0235 "ksdioirqd/%s", mmc_hostname(host));
0236 if (IS_ERR(host->sdio_irq_thread)) {
0237 int err = PTR_ERR(host->sdio_irq_thread);
0238 host->sdio_irqs--;
0239 return err;
0240 }
0241 } else if (host->caps & MMC_CAP_SDIO_IRQ) {
0242 host->ops->enable_sdio_irq(host, 1);
0243 }
0244 }
0245
0246 return 0;
0247 }
0248
0249 static int sdio_card_irq_put(struct mmc_card *card)
0250 {
0251 struct mmc_host *host = card->host;
0252
0253 WARN_ON(!host->claimed);
0254
0255 if (host->sdio_irqs < 1)
0256 return -EINVAL;
0257
0258 if (!--host->sdio_irqs) {
0259 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) {
0260 atomic_set(&host->sdio_irq_thread_abort, 1);
0261 kthread_stop(host->sdio_irq_thread);
0262 } else if (host->caps & MMC_CAP_SDIO_IRQ) {
0263 host->ops->enable_sdio_irq(host, 0);
0264 }
0265 }
0266
0267 return 0;
0268 }
0269
0270
0271 static void sdio_single_irq_set(struct mmc_card *card)
0272 {
0273 struct sdio_func *func;
0274 int i;
0275
0276 card->sdio_single_irq = NULL;
0277 if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
0278 card->host->sdio_irqs == 1) {
0279 for (i = 0; i < card->sdio_funcs; i++) {
0280 func = card->sdio_func[i];
0281 if (func && func->irq_handler) {
0282 card->sdio_single_irq = func;
0283 break;
0284 }
0285 }
0286 }
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
0300 {
0301 int ret;
0302 unsigned char reg;
0303
0304 if (!func)
0305 return -EINVAL;
0306
0307 pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));
0308
0309 if (func->irq_handler) {
0310 pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
0311 return -EBUSY;
0312 }
0313
0314 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®);
0315 if (ret)
0316 return ret;
0317
0318 reg |= 1 << func->num;
0319
0320 reg |= 1;
0321
0322 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
0323 if (ret)
0324 return ret;
0325
0326 func->irq_handler = handler;
0327 ret = sdio_card_irq_get(func->card);
0328 if (ret)
0329 func->irq_handler = NULL;
0330 sdio_single_irq_set(func->card);
0331
0332 return ret;
0333 }
0334 EXPORT_SYMBOL_GPL(sdio_claim_irq);
0335
0336
0337
0338
0339
0340
0341
0342 int sdio_release_irq(struct sdio_func *func)
0343 {
0344 int ret;
0345 unsigned char reg;
0346
0347 if (!func)
0348 return -EINVAL;
0349
0350 pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func));
0351
0352 if (func->irq_handler) {
0353 func->irq_handler = NULL;
0354 sdio_card_irq_put(func->card);
0355 sdio_single_irq_set(func->card);
0356 }
0357
0358 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®);
0359 if (ret)
0360 return ret;
0361
0362 reg &= ~(1 << func->num);
0363
0364
0365 if (!(reg & 0xFE))
0366 reg = 0;
0367
0368 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
0369 if (ret)
0370 return ret;
0371
0372 return 0;
0373 }
0374 EXPORT_SYMBOL_GPL(sdio_release_irq);
0375