@@ -2428,10 +2428,10 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
2428
2428
2429
2429
static irqreturn_t sdhci_irq (int irq , void * dev_id )
2430
2430
{
2431
- irqreturn_t result ;
2431
+ irqreturn_t result = IRQ_NONE ;
2432
2432
struct sdhci_host * host = dev_id ;
2433
2433
u32 intmask , mask , unexpected = 0 ;
2434
- int cardint = 0 , max_loops = 16 ;
2434
+ int max_loops = 16 ;
2435
2435
2436
2436
spin_lock (& host -> lock );
2437
2437
@@ -2490,8 +2490,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
2490
2490
pr_err ("%s: Card is consuming too much power!\n" ,
2491
2491
mmc_hostname (host -> mmc ));
2492
2492
2493
- if (intmask & SDHCI_INT_CARD_INT )
2494
- cardint = 1 ;
2493
+ if (intmask & SDHCI_INT_CARD_INT ) {
2494
+ sdhci_enable_sdio_irq_nolock (host , false);
2495
+ host -> thread_isr |= SDHCI_INT_CARD_INT ;
2496
+ result = IRQ_WAKE_THREAD ;
2497
+ }
2495
2498
2496
2499
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
2497
2500
SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
@@ -2503,17 +2506,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
2503
2506
sdhci_writel (host , intmask , SDHCI_INT_STATUS );
2504
2507
}
2505
2508
2506
- result = IRQ_HANDLED ;
2509
+ if (result == IRQ_NONE )
2510
+ result = IRQ_HANDLED ;
2507
2511
2508
2512
intmask = sdhci_readl (host , SDHCI_INT_STATUS );
2509
-
2510
- /*
2511
- * If we know we'll call the driver to signal SDIO IRQ,
2512
- * disregard further indications of Card Interrupt in
2513
- * the status to avoid a needless loop.
2514
- */
2515
- if (cardint )
2516
- intmask &= ~SDHCI_INT_CARD_INT ;
2517
2513
} while (intmask && -- max_loops );
2518
2514
out :
2519
2515
spin_unlock (& host -> lock );
@@ -2523,15 +2519,33 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
2523
2519
mmc_hostname (host -> mmc ), unexpected );
2524
2520
sdhci_dumpregs (host );
2525
2521
}
2526
- /*
2527
- * We have to delay this as it calls back into the driver.
2528
- */
2529
- if (cardint )
2530
- mmc_signal_sdio_irq (host -> mmc );
2531
2522
2532
2523
return result ;
2533
2524
}
2534
2525
2526
+ static irqreturn_t sdhci_thread_irq (int irq , void * dev_id )
2527
+ {
2528
+ struct sdhci_host * host = dev_id ;
2529
+ unsigned long flags ;
2530
+ u32 isr ;
2531
+
2532
+ spin_lock_irqsave (& host -> lock , flags );
2533
+ isr = host -> thread_isr ;
2534
+ host -> thread_isr = 0 ;
2535
+ spin_unlock_irqrestore (& host -> lock , flags );
2536
+
2537
+ if (isr & SDHCI_INT_CARD_INT ) {
2538
+ sdio_run_irqs (host -> mmc );
2539
+
2540
+ spin_lock_irqsave (& host -> lock , flags );
2541
+ if (host -> flags & SDHCI_SDIO_IRQ_ENABLED )
2542
+ sdhci_enable_sdio_irq_nolock (host , true);
2543
+ spin_unlock_irqrestore (& host -> lock , flags );
2544
+ }
2545
+
2546
+ return isr ? IRQ_HANDLED : IRQ_NONE ;
2547
+ }
2548
+
2535
2549
/*****************************************************************************\
2536
2550
* *
2537
2551
* Suspend/resume *
@@ -2601,8 +2615,9 @@ int sdhci_resume_host(struct sdhci_host *host)
2601
2615
}
2602
2616
2603
2617
if (!device_may_wakeup (mmc_dev (host -> mmc ))) {
2604
- ret = request_irq (host -> irq , sdhci_irq , IRQF_SHARED ,
2605
- mmc_hostname (host -> mmc ), host );
2618
+ ret = request_threaded_irq (host -> irq , sdhci_irq ,
2619
+ sdhci_thread_irq , IRQF_SHARED ,
2620
+ mmc_hostname (host -> mmc ), host );
2606
2621
if (ret )
2607
2622
return ret ;
2608
2623
} else {
@@ -2681,7 +2696,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
2681
2696
sdhci_mask_irqs (host , SDHCI_INT_ALL_MASK );
2682
2697
spin_unlock_irqrestore (& host -> lock , flags );
2683
2698
2684
- synchronize_irq (host -> irq );
2699
+ synchronize_hardirq (host -> irq );
2685
2700
2686
2701
spin_lock_irqsave (& host -> lock , flags );
2687
2702
host -> runtime_suspended = true;
@@ -2937,6 +2952,7 @@ int sdhci_add_host(struct sdhci_host *host)
2937
2952
mmc -> max_busy_timeout = (1 << 27 ) / host -> timeout_clk ;
2938
2953
2939
2954
mmc -> caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23 ;
2955
+ mmc -> caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD ;
2940
2956
2941
2957
if (host -> quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 )
2942
2958
host -> flags |= SDHCI_AUTO_CMD12 ;
@@ -3226,8 +3242,8 @@ int sdhci_add_host(struct sdhci_host *host)
3226
3242
3227
3243
sdhci_init (host , 0 );
3228
3244
3229
- ret = request_irq (host -> irq , sdhci_irq , IRQF_SHARED ,
3230
- mmc_hostname (mmc ), host );
3245
+ ret = request_threaded_irq (host -> irq , sdhci_irq , sdhci_thread_irq ,
3246
+ IRQF_SHARED , mmc_hostname (mmc ), host );
3231
3247
if (ret ) {
3232
3248
pr_err ("%s: Failed to request IRQ %d: %d\n" ,
3233
3249
mmc_hostname (mmc ), host -> irq , ret );
0 commit comments