--- zzzz-none-000/linux-4.9.279/drivers/mmc/host/sdhci-acpi.c 2021-08-08 06:38:54.000000000 +0000 +++ puma7-atom-6591-750/linux-4.9.279/drivers/mmc/host/sdhci-acpi.c 2023-02-08 11:43:42.000000000 +0000 @@ -49,6 +49,10 @@ #include "sdhci.h" +#ifdef CONFIG_HW_MUTEXES +#include +#endif + enum { SDHCI_ACPI_SD_CD = BIT(0), SDHCI_ACPI_RUNTIME_PM = BIT(1), @@ -103,6 +107,30 @@ usleep_range(300, 1000); } +void puma7_write_l(struct sdhci_host *host, u32 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writel(val, host->ioaddr + reg); +} + +void puma7_write_w(struct sdhci_host *host, u16 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writew(val, host->ioaddr + reg); +} + +void puma7_write_b(struct sdhci_host *host, u8 val, int reg) +{ + if (!(host->flags & SDHCI_DISABLE_REGISTER_WRITE)) + writeb(val, host->ioaddr + reg); +} + +unsigned int sdhci_acpi_puma7_get_min_clock(struct sdhci_host *host) +{ + /* PUMA7 host controllers only support down to 200kHz */ + return 200000; +} + static const struct sdhci_ops sdhci_acpi_ops_dflt = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, @@ -118,10 +146,28 @@ .hw_reset = sdhci_acpi_int_hw_reset, }; +static const struct sdhci_ops sdhci_acpi_ops_int_puma7_emmc = { + .set_clock = sdhci_set_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .hw_reset = sdhci_acpi_int_hw_reset, + .get_min_clock = sdhci_acpi_puma7_get_min_clock, +#ifdef CONFIG_HW_MUTEXES + .write_l = puma7_write_l, + .write_w = puma7_write_w, + .write_b = puma7_write_b, +#endif +}; + static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { .ops = &sdhci_acpi_ops_int, }; +static const struct sdhci_acpi_chip sdhci_acpi_chip_int_puma7_emmc = { + .ops = &sdhci_acpi_ops_int_puma7_emmc, +}; + #ifdef CONFIG_X86 static bool sdhci_acpi_byt(void) @@ -285,6 +331,32 @@ .probe_slot = sdhci_acpi_emmc_probe_slot, }; +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_puma7_emmc1 = { + .chip = &sdhci_acpi_chip_int_puma7_emmc, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | + MMC_CAP_CMD_DURING_TFR | MMC_CAP_WAIT_WHILE_BUSY, + .caps2 = MMC_CAP2_HC_ERASE_SZ | MMC_CAP2_NO_SHUTDOWN_BUS, + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_STOP_WITH_TC | + SDHCI_QUIRK2_HW_MUTEX, + .probe_slot = sdhci_acpi_emmc_probe_slot, +}; + +static const struct sdhci_acpi_slot sdhci_acpi_slot_int_puma7_emmc2 = { + .chip = &sdhci_acpi_chip_int_puma7_emmc, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | + MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | + MMC_CAP_CMD_DURING_TFR | MMC_CAP_WAIT_WHILE_BUSY, + .caps2 = MMC_CAP2_HC_ERASE_SZ, + .flags = SDHCI_ACPI_RUNTIME_PM, + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_STOP_WITH_TC, + .probe_slot = sdhci_acpi_emmc_probe_slot, +}; + static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, @@ -297,11 +369,9 @@ }; static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { - .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | - SDHCI_ACPI_RUNTIME_PM, + .flags = SDHCI_ACPI_RUNTIME_PM, .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, - .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | - SDHCI_QUIRK2_STOP_WITH_TC, + .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC, .caps = MMC_CAP_WAIT_WHILE_BUSY, .probe_slot = sdhci_acpi_sd_probe_slot, }; @@ -330,6 +400,9 @@ { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc }, { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, { "80860F16" , NULL, &sdhci_acpi_slot_int_sd }, + { "80862B94" , "1" , &sdhci_acpi_slot_int_puma7_emmc1 }, + { "80862B95" , "1" , &sdhci_acpi_slot_int_puma7_emmc2 }, + { "80862B96" , "1" , &sdhci_acpi_slot_int_sd }, { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, @@ -348,6 +421,7 @@ { "80865AD0" }, { "80860F14" }, { "80860F16" }, + { "80862B94" }, { "INT33BB" }, { "INT33C6" }, { "INT3436" }, @@ -384,8 +458,8 @@ struct sdhci_host *host; struct resource *iomem; resource_size_t len; - const char *hid; - const char *uid; + const char *hid = NULL; + const char *uid = NULL; int err; if (acpi_bus_get_device(handle, &device)) @@ -406,6 +480,11 @@ hid = acpi_device_hid(device); uid = device->pnp.unique_id; + if (!hid || !uid) { + printk(KERN_ERR "Invalid device HID[%s] UID[%s]\n", hid, uid); + return -ENODEV; + } + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem) return -ENOMEM; @@ -475,7 +554,19 @@ } } +#ifdef CONFIG_HW_MUTEXES + if (SDHCI_HOST_SUPPORTS_HW_MUTEX(host)) { + MMC_LOCK_HW_MUTEX(host->mmc); + host->flags |= SDHCI_DISABLE_REGISTER_WRITE; + err = sdhci_add_host(host); + host->flags &= ~SDHCI_DISABLE_REGISTER_WRITE; + MMC_UNLOCK_HW_MUTEX(host->mmc); + } else { + err = sdhci_add_host(host); + } +#else err = sdhci_add_host(host); +#endif if (err) goto err_free; @@ -485,6 +576,10 @@ pm_runtime_set_autosuspend_delay(dev, 50); pm_runtime_use_autosuspend(dev); pm_runtime_enable(dev); + /**Puma power manager will enable runtime pm for + * SD card controller*/ + if (! strncmp(hid, "80862B96", 8)) + pm_runtime_forbid(dev); } device_enable_async_suspend(dev);