This source file includes following definitions.
- sdio_get_pending_irqs
- process_sdio_pending_irqs
- sdio_run_irqs
- sdio_irq_work
- sdio_signal_irq
- sdio_irq_thread
- sdio_card_irq_get
- sdio_card_irq_put
- sdio_single_irq_set
- sdio_claim_irq
- sdio_release_irq
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  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                 
  49 
  50 
  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         
  67         if (mmc_card_suspended(card))
  68                 return 0;
  69 
  70         
  71         host->sdio_irq_pending = false;
  72 
  73         
  74 
  75 
  76 
  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 
 150 
 151 
 152 
 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 
 164 
 165 
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 
 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 
 184 
 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 
 195 
 196 
 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 
 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 
 292 
 293 
 294 
 295 
 296 
 297 
 298 
 299 int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
 300 {
 301         int ret;
 302         unsigned char reg;
 303 
 304         if (!func)
 305                 return -EINVAL;
 306 
 307         pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));
 308 
 309         if (func->irq_handler) {
 310                 pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
 311                 return -EBUSY;
 312         }
 313 
 314         ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®);
 315         if (ret)
 316                 return ret;
 317 
 318         reg |= 1 << func->num;
 319 
 320         reg |= 1; 
 321 
 322         ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
 323         if (ret)
 324                 return ret;
 325 
 326         func->irq_handler = handler;
 327         ret = sdio_card_irq_get(func->card);
 328         if (ret)
 329                 func->irq_handler = NULL;
 330         sdio_single_irq_set(func->card);
 331 
 332         return ret;
 333 }
 334 EXPORT_SYMBOL_GPL(sdio_claim_irq);
 335 
 336 
 337 
 338 
 339 
 340 
 341 
 342 int sdio_release_irq(struct sdio_func *func)
 343 {
 344         int ret;
 345         unsigned char reg;
 346 
 347         if (!func)
 348                 return -EINVAL;
 349 
 350         pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func));
 351 
 352         if (func->irq_handler) {
 353                 func->irq_handler = NULL;
 354                 sdio_card_irq_put(func->card);
 355                 sdio_single_irq_set(func->card);
 356         }
 357 
 358         ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, ®);
 359         if (ret)
 360                 return ret;
 361 
 362         reg &= ~(1 << func->num);
 363 
 364         
 365         if (!(reg & 0xFE))
 366                 reg = 0;
 367 
 368         ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
 369         if (ret)
 370                 return ret;
 371 
 372         return 0;
 373 }
 374 EXPORT_SYMBOL_GPL(sdio_release_irq);
 375