diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 1da5f29abbcb..706d9cb1a49e 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
| @@ -87,6 +87,12 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = { | |||
| 87 | .enable_dma = sdhci_acpi_enable_dma, | 87 | .enable_dma = sdhci_acpi_enable_dma, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | ||
| 91 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, | ||
| 92 | .caps2 = MMC_CAP2_HC_ERASE_SZ, | ||
| 93 | .flags = SDHCI_ACPI_RUNTIME_PM, | ||
| 94 | }; | ||
| 95 | |||
| 90 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | 96 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { |
| 91 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, | 97 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, |
| 92 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, | 98 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, |
| @@ -94,23 +100,67 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
| 94 | .pm_caps = MMC_PM_KEEP_POWER, | 100 | .pm_caps = MMC_PM_KEEP_POWER, |
| 95 | }; | 101 | }; |
| 96 | 102 | ||
| 103 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | ||
| 104 | }; | ||
| 105 | |||
| 106 | struct sdhci_acpi_uid_slot { | ||
| 107 | const char *hid; | ||
| 108 | const char *uid; | ||
| 109 | const struct sdhci_acpi_slot *slot; | ||
| 110 | }; | ||
| 111 | |||
| 112 | static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | ||
| 113 | { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc }, | ||
| 114 | { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, | ||
| 115 | { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, | ||
| 116 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, | ||
| 117 | { "PNP0D40" }, | ||
| 118 | { }, | ||
| 119 | }; | ||
| 120 | |||
| 97 | static const struct acpi_device_id sdhci_acpi_ids[] = { | 121 | static const struct acpi_device_id sdhci_acpi_ids[] = { |
| 98 | { "INT33C6", (kernel_ulong_t)&sdhci_acpi_slot_int_sdio }, | 122 | { "80860F14" }, |
| 99 | { "PNP0D40" }, | 123 | { "INT33BB" }, |
| 124 | { "INT33C6" }, | ||
| 125 | { "PNP0D40" }, | ||
| 100 | { }, | 126 | { }, |
| 101 | }; | 127 | }; |
| 102 | MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); | 128 | MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); |
| 103 | 129 | ||
| 104 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid) | 130 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot_by_ids(const char *hid, |
| 131 | const char *uid) | ||
| 105 | { | 132 | { |
| 106 | const struct acpi_device_id *id; | 133 | const struct sdhci_acpi_uid_slot *u; |
| 107 | 134 | ||
| 108 | for (id = sdhci_acpi_ids; id->id[0]; id++) | 135 | for (u = sdhci_acpi_uids; u->hid; u++) { |
| 109 | if (!strcmp(id->id, hid)) | 136 | if (strcmp(u->hid, hid)) |
| 110 | return (const struct sdhci_acpi_slot *)id->driver_data; | 137 | continue; |
| 138 | if (!u->uid) | ||
| 139 | return u->slot; | ||
| 140 | if (uid && !strcmp(u->uid, uid)) | ||
| 141 | return u->slot; | ||
| 142 | } | ||
| 111 | return NULL; | 143 | return NULL; |
| 112 | } | 144 | } |
| 113 | 145 | ||
| 146 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle, | ||
| 147 | const char *hid) | ||
| 148 | { | ||
| 149 | const struct sdhci_acpi_slot *slot; | ||
| 150 | struct acpi_device_info *info; | ||
| 151 | const char *uid = NULL; | ||
| 152 | acpi_status status; | ||
| 153 | |||
| 154 | status = acpi_get_object_info(handle, &info); | ||
| 155 | if (!ACPI_FAILURE(status) && (info->valid & ACPI_VALID_UID)) | ||
| 156 | uid = info->unique_id.string; | ||
| 157 | |||
| 158 | slot = sdhci_acpi_get_slot_by_ids(hid, uid); | ||
| 159 | |||
| 160 | kfree(info); | ||
| 161 | return slot; | ||
| 162 | } | ||
| 163 | |||
| 114 | static int sdhci_acpi_probe(struct platform_device *pdev) | 164 | static int sdhci_acpi_probe(struct platform_device *pdev) |
| 115 | { | 165 | { |
| 116 | struct device *dev = &pdev->dev; | 166 | struct device *dev = &pdev->dev; |
| @@ -148,7 +198,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
| 148 | 198 | ||
| 149 | c = sdhci_priv(host); | 199 | c = sdhci_priv(host); |
| 150 | c->host = host; | 200 | c->host = host; |
| 151 | c->slot = sdhci_acpi_get_slot(hid); | 201 | c->slot = sdhci_acpi_get_slot(handle, hid); |
| 152 | c->pdev = pdev; | 202 | c->pdev = pdev; |
| 153 | c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); | 203 | c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); |
| 154 | 204 | ||
