--- zzzz-none-000/linux-4.9.279/drivers/mmc/host/sdhci.h 2021-08-08 06:38:54.000000000 +0000 +++ puma7-atom-6591-750/linux-4.9.279/drivers/mmc/host/sdhci.h 2023-02-08 11:43:42.000000000 +0000 @@ -19,6 +19,9 @@ #include #include +#ifdef CONFIG_HW_MUTEXES +#include +#endif /* * Controller registers @@ -69,11 +72,13 @@ #define SDHCI_SPACE_AVAILABLE 0x00000400 #define SDHCI_DATA_AVAILABLE 0x00000800 #define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_CARD_IS_STABLE 0x00020000 #define SDHCI_WRITE_PROTECT 0x00080000 #define SDHCI_DATA_LVL_MASK 0x00F00000 #define SDHCI_DATA_LVL_SHIFT 20 #define SDHCI_DATA_0_LVL_MASK 0x00100000 #define SDHCI_CMD_LVL 0x01000000 +#define SDHCI_STATE_BUSY_MASK (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT) #define SDHCI_HOST_CONTROL 0x28 #define SDHCI_CTRL_LED 0x01 @@ -426,6 +431,9 @@ #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) /* Broken Clock divider zero in controller */ #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) +/* Two or more processors access the controller, HW mutex is needed to avoid + control conflicts. */ +#define SDHCI_QUIRK2_HW_MUTEX (1<<16) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ @@ -459,6 +467,7 @@ #define SDHCI_SIGNALING_330 (1<<14) /* Host is capable of 3.3V signaling */ #define SDHCI_SIGNALING_180 (1<<15) /* Host is capable of 1.8V signaling */ #define SDHCI_SIGNALING_120 (1<<16) /* Host is capable of 1.2V signaling */ +#define SDHCI_PANIC_SYNC (1<<17) /* AVM: Sync writes on panic */ unsigned int version; /* SDHCI spec. version */ @@ -522,10 +531,17 @@ unsigned int tuning_count; /* Timer count for re-tuning */ unsigned int tuning_mode; /* Re-tuning mode supported by host */ +#ifdef CONFIG_HW_MUTEXES + unsigned int irq_enable_count; /* Count to enable recursive locking */ +#endif + #define SDHCI_TUNING_MODE_1 0 #define SDHCI_TUNING_MODE_2 1 #define SDHCI_TUNING_MODE_3 2 +#ifdef CONFIG_AVM_MMC_SDHCI_ERRORSTATS + atomic_t errcnt[16]; +#endif unsigned long private[0] ____cacheline_aligned; }; @@ -680,6 +696,8 @@ return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED); } +void sdhci_clock_gating(struct sdhci_host *host, bool enable); + u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, unsigned int *actual_clock); void sdhci_set_clock(struct sdhci_host *host, unsigned int clock); @@ -699,4 +717,46 @@ extern int sdhci_runtime_resume_host(struct sdhci_host *host); #endif +#ifdef CONFIG_HW_MUTEXES +#define SDHCI_DISABLE_REGISTER_WRITE (1<<16) + +#define SDHCI_HOST_SUPPORTS_HW_MUTEX(sdhci) \ + ((sdhci)->quirks2 & SDHCI_QUIRK2_HW_MUTEX) +#define MMC_HOST_SUPPORTS_HW_MUTEX(mmc) SDHCI_HOST_SUPPORTS_HW_MUTEX( ((struct sdhci_host*)mmc->private)) + +#define EMMC_HW_MUTEX_IS_LOCKED() hw_mutex_is_locked(HW_MUTEX_EMMC) + +#define MMC_LOCK_HW_MUTEX(mmc) \ +do { \ + struct sdhci_host *sdhci = (struct sdhci_host*)mmc->private; \ + if (SDHCI_HOST_SUPPORTS_HW_MUTEX(sdhci)) \ + { \ + hw_mutex_lock(HW_MUTEX_EMMC); \ + sdhci_clock_gating(sdhci, 1); \ + if (sdhci->irq_enable_count == 0) \ + { \ + enable_irq(sdhci->irq); \ + } \ + sdhci->irq_enable_count++; \ + } \ +} while(0) + +#define MMC_UNLOCK_HW_MUTEX(mmc) \ +do{ \ + struct sdhci_host *sdhci = (struct sdhci_host*)mmc->private; \ + if (SDHCI_HOST_SUPPORTS_HW_MUTEX(sdhci)) \ + { \ + WARN_ON(sdhci->irq_enable_count == 0); \ + if (sdhci->irq_enable_count == 1) \ + { \ + disable_irq(sdhci->irq); \ + } \ + sdhci->irq_enable_count -= (sdhci->irq_enable_count == 0) ? 0 : 1; \ + sdhci_clock_gating(sdhci, 0); \ + hw_mutex_unlock(HW_MUTEX_EMMC); \ + } \ +} while(0) + +#endif /* CONFIG_HW_MUTEXES */ + #endif /* __SDHCI_HW_H */