1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/mmc/core/sdio_irq.c 4 * 5 * Author: Nicolas Pitre 6 * Created: June 18, 2007 7 * Copyright: MontaVista Software Inc. 8 * 9 * Copyright 2008 Pierre Ossman 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/sched.h> 14 #include <uapi/linux/sched/types.h> 15 #include <linux/kthread.h> 16 #include <linux/export.h> 17 #include <linux/wait.h> 18 #include <linux/delay.h> 19 20 #include <linux/mmc/core.h> 21 #include <linux/mmc/host.h> 22 #include <linux/mmc/card.h> 23 #include <linux/mmc/sdio.h> 24 #include <linux/mmc/sdio_func.h> 25 26 #include "sdio_ops.h" 27 #include "core.h" 28 #include "card.h" 29 30 static int sdio_get_pending_irqs(struct mmc_host *host, u8 *pending) 31 { 32 struct mmc_card *card = host->card; 33 int ret; 34 35 WARN_ON(!host->claimed); 36 37 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, pending); 38 if (ret) { 39 pr_debug("%s: error %d reading SDIO_CCCR_INTx\n", 40 mmc_card_id(card), ret); 41 return ret; 42 } 43 44 if (*pending && mmc_card_broken_irq_polling(card) && 45 !(host->caps & MMC_CAP_SDIO_IRQ)) { 46 unsigned char dummy; 47 48 /* A fake interrupt could be created when we poll SDIO_CCCR_INTx 49 * register with a Marvell SD8797 card. A dummy CMD52 read to 50 * function 0 register 0xff can avoid this. 51 */ 52 mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy); 53 } 54 55 return 0; 56 } 57 58 static int process_sdio_pending_irqs(struct mmc_host *host) 59 { 60 struct mmc_card *card = host->card; 61 int i, ret, count; 62 bool sdio_irq_pending = host->sdio_irq_pending; 63 unsigned char pending; 64 struct sdio_func *func; 65 66 /* Don't process SDIO IRQs if the card is suspended. */ 67 if (mmc_card_suspended(card)) 68 return 0; 69 70 /* Clear the flag to indicate that we have processed the IRQ. */ 71 host->sdio_irq_pending = false; 72 73 /* 74 * Optimization, if there is only 1 function interrupt registered 75 * and we know an IRQ was signaled then call irq handler directly. 76 * Otherwise do the full probe. 77 */ 78 func = card->sdio_single_irq; 79 if (func && sdio_irq_pending) { 80 func->irq_handler(func); 81 return 1; 82 } 83 84 ret = sdio_get_pending_irqs(host, &pending); 85 if (ret) 86 return ret; 87 88 count = 0; 89 for (i = 1; i <= 7; i++) { 90 if (pending & (1 << i)) { 91 func = card->sdio_func[i - 1]; 92 if (!func) { 93 pr_warn("%s: pending IRQ for non-existent function\n", 94 mmc_card_id(card)); 95 ret = -EINVAL; 96 } else if (func->irq_handler) { 97 func->irq_handler(func); 98 count++; 99 } else { 100 pr_warn("%s: pending IRQ with no handler\n", 101 sdio_func_id(func)); 102 ret = -EINVAL; 103 } 104 } 105 } 106 107 if (count) 108 return count; 109 110 return ret; 111 } 112 113 static void sdio_run_irqs(struct mmc_host *host) 114 { 115 mmc_claim_host(host); 116 if (host->sdio_irqs) { 117 process_sdio_pending_irqs(host); 118 if (!host->sdio_irq_pending) 119 host->ops->ack_sdio_irq(host); 120 } 121 mmc_release_host(host); 122 } 123 124 void sdio_irq_work(struct work_struct *work) 125 { 126 struct mmc_host *host = 127 container_of(work, struct mmc_host, sdio_irq_work.work); 128 129 sdio_run_irqs(host); 130 } 131 132 void sdio_signal_irq(struct mmc_host *host) 133 { 134 host->sdio_irq_pending = true; 135 queue_delayed_work(system_wq, &host->sdio_irq_work, 0); 136 } 137 EXPORT_SYMBOL_GPL(sdio_signal_irq); 138 139 static int sdio_irq_thread(void *_host) 140 { 141 struct mmc_host *host = _host; 142 struct sched_param param = { .sched_priority = 1 }; 143 unsigned long period, idle_period; 144 int ret; 145 146 sched_setscheduler(current, SCHED_FIFO, ¶m); 147 148 /* 149 * We want to allow for SDIO cards to work even on non SDIO 150 * aware hosts. One thing that non SDIO host cannot do is 151 * asynchronous notification of pending SDIO card interrupts 152 * hence we poll for them in that case. 153 */ 154 idle_period = msecs_to_jiffies(10); 155 period = (host->caps & MMC_CAP_SDIO_IRQ) ? 156 MAX_SCHEDULE_TIMEOUT : idle_period; 157 158 pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n", 159 mmc_hostname(host), period); 160 161 do { 162 /* 163 * We claim the host here on drivers behalf for a couple 164 * reasons: 165 * 166 * 1) it is already needed to retrieve the CCCR_INTx; 167 * 2) we want the driver(s) to clear the IRQ condition ASAP; 168 * 3) we need to control the abort condition locally. 169 * 170 * Just like traditional hard IRQ handlers, we expect SDIO 171 * IRQ handlers to be quick and to the point, so that the 172 * holding of the host lock does not cover too much work 173 * that doesn't require that lock to be held. 174 */ 175 ret = __mmc_claim_host(host, NULL, 176 &host->sdio_irq_thread_abort); 177 if (ret) 178 break; 179 ret = process_sdio_pending_irqs(host); 180 mmc_release_host(host); 181 182 /* 183 * Give other threads a chance to run in the presence of 184 * errors. 185 */ 186 if (ret < 0) { 187 set_current_state(TASK_INTERRUPTIBLE); 188 if (!kthread_should_stop()) 189 schedule_timeout(HZ); 190 set_current_state(TASK_RUNNING); 191 } 192 193 /* 194 * Adaptive polling frequency based on the assumption 195 * that an interrupt will be closely followed by more. 196 * This has a substantial benefit for network devices. 197 */ 198 if (!(host->caps & MMC_CAP_SDIO_IRQ)) { 199 if (ret > 0) 200 period /= 2; 201 else { 202 period++; 203 if (period > idle_period) 204 period = idle_period; 205 } 206 } 207 208 set_current_state(TASK_INTERRUPTIBLE); 209 if (host->caps & MMC_CAP_SDIO_IRQ) 210 host->ops->enable_sdio_irq(host, 1); 211 if (!kthread_should_stop()) 212 schedule_timeout(period); 213 set_current_state(TASK_RUNNING); 214 } while (!kthread_should_stop()); 215 216 if (host->caps & MMC_CAP_SDIO_IRQ) 217 host->ops->enable_sdio_irq(host, 0); 218 219 pr_debug("%s: IRQ thread exiting with code %d\n", 220 mmc_hostname(host), ret); 221 222 return ret; 223 } 224 225 static int sdio_card_irq_get(struct mmc_card *card) 226 { 227 struct mmc_host *host = card->host; 228 229 WARN_ON(!host->claimed); 230 231 if (!host->sdio_irqs++) { 232 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { 233 atomic_set(&host->sdio_irq_thread_abort, 0); 234 host->sdio_irq_thread = 235 kthread_run(sdio_irq_thread, host, 236 "ksdioirqd/%s", mmc_hostname(host)); 237 if (IS_ERR(host->sdio_irq_thread)) { 238 int err = PTR_ERR(host->sdio_irq_thread); 239 host->sdio_irqs--; 240 return err; 241 } 242 } else if (host->caps & MMC_CAP_SDIO_IRQ) { 243 host->ops->enable_sdio_irq(host, 1); 244 } 245 } 246 247 return 0; 248 } 249 250 static int sdio_card_irq_put(struct mmc_card *card) 251 { 252 struct mmc_host *host = card->host; 253 254 WARN_ON(!host->claimed); 255 256 if (host->sdio_irqs < 1) 257 return -EINVAL; 258 259 if (!--host->sdio_irqs) { 260 if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) { 261 atomic_set(&host->sdio_irq_thread_abort, 1); 262 kthread_stop(host->sdio_irq_thread); 263 } else if (host->caps & MMC_CAP_SDIO_IRQ) { 264 host->ops->enable_sdio_irq(host, 0); 265 } 266 } 267 268 return 0; 269 } 270 271 /* If there is only 1 function registered set sdio_single_irq */ 272 static void sdio_single_irq_set(struct mmc_card *card) 273 { 274 struct sdio_func *func; 275 int i; 276 277 card->sdio_single_irq = NULL; 278 if ((card->host->caps & MMC_CAP_SDIO_IRQ) && 279 card->host->sdio_irqs == 1) { 280 for (i = 0; i < card->sdio_funcs; i++) { 281 func = card->sdio_func[i]; 282 if (func && func->irq_handler) { 283 card->sdio_single_irq = func; 284 break; 285 } 286 } 287 } 288 } 289 290 /** 291 * sdio_claim_irq - claim the IRQ for a SDIO function 292 * @func: SDIO function 293 * @handler: IRQ handler callback 294 * 295 * Claim and activate the IRQ for the given SDIO function. The provided 296 * handler will be called when that IRQ is asserted. The host is always 297 * claimed already when the handler is called so the handler should not 298 * call sdio_claim_host() or sdio_release_host(). 299 */ 300 int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler) 301 { 302 int ret; 303 unsigned char reg; 304 305 if (!func) 306 return -EINVAL; 307 308 pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func)); 309 310 if (func->irq_handler) { 311 pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func)); 312 return -EBUSY; 313 } 314 315 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); 316 if (ret) 317 return ret; 318 319 reg |= 1 << func->num; 320 321 reg |= 1; /* Master interrupt enable */ 322 323 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); 324 if (ret) 325 return ret; 326 327 func->irq_handler = handler; 328 ret = sdio_card_irq_get(func->card); 329 if (ret) 330 func->irq_handler = NULL; 331 sdio_single_irq_set(func->card); 332 333 return ret; 334 } 335 EXPORT_SYMBOL_GPL(sdio_claim_irq); 336 337 /** 338 * sdio_release_irq - release the IRQ for a SDIO function 339 * @func: SDIO function 340 * 341 * Disable and release the IRQ for the given SDIO function. 342 */ 343 int sdio_release_irq(struct sdio_func *func) 344 { 345 int ret; 346 unsigned char reg; 347 348 if (!func) 349 return -EINVAL; 350 351 pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func)); 352 353 if (func->irq_handler) { 354 func->irq_handler = NULL; 355 sdio_card_irq_put(func->card); 356 sdio_single_irq_set(func->card); 357 } 358 359 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®); 360 if (ret) 361 return ret; 362 363 reg &= ~(1 << func->num); 364 365 /* Disable master interrupt with the last function interrupt */ 366 if (!(reg & 0xFE)) 367 reg = 0; 368 369 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL); 370 if (ret) 371 return ret; 372 373 return 0; 374 } 375 EXPORT_SYMBOL_GPL(sdio_release_irq); 376 377