diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2011-12-27 08:48:43 -0500 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-01-11 23:58:47 -0500 |
commit | 52c506f0bc72530fb786838e7ffd4f158a2e5c3a (patch) | |
tree | 2c46fdd2ce9ac582846733ed60f12caea2856196 | |
parent | c79396c191bc19703df6eb6bbd0f673ed0df6c9d (diff) |
mmc: sdhci-pci: add platform data
Add a means of getting platform data for the SDHCI PCI
devices. The data is stored against the slot not the
device in order to support multi-slot devices.
The data allows platform-specific setup (such as getting
GPIO numbers from firmware or setting up wl12xx for SDIO)
to be done in platform support files instead of the
sdhci-pci driver.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | drivers/Makefile | 2 | ||||
-rw-r--r-- | drivers/mmc/Makefile | 3 | ||||
-rw-r--r-- | drivers/mmc/host/Makefile | 1 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci-data.c | 5 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 32 | ||||
-rw-r--r-- | include/linux/mmc/sdhci-pci-data.h | 18 |
6 files changed, 54 insertions, 7 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 1b3142127bf..c07be024b96 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -97,7 +97,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
97 | obj-y += lguest/ | 97 | obj-y += lguest/ |
98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
100 | obj-$(CONFIG_MMC) += mmc/ | 100 | obj-y += mmc/ |
101 | obj-$(CONFIG_MEMSTICK) += memstick/ | 101 | obj-$(CONFIG_MEMSTICK) += memstick/ |
102 | obj-y += leds/ | 102 | obj-y += leds/ |
103 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 103 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 12eef393e21..400756ec7c4 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
@@ -6,5 +6,4 @@ subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG | |||
6 | 6 | ||
7 | obj-$(CONFIG_MMC) += core/ | 7 | obj-$(CONFIG_MMC) += core/ |
8 | obj-$(CONFIG_MMC) += card/ | 8 | obj-$(CONFIG_MMC) += card/ |
9 | obj-$(CONFIG_MMC) += host/ | 9 | obj-$(subst m,y,$(CONFIG_MMC)) += host/ |
10 | |||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index b4b83f302e3..745f8fce251 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o | |||
9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o | 9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o |
10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
12 | obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o | ||
12 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o | 13 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o |
13 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o | 14 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o |
14 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 15 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
diff --git a/drivers/mmc/host/sdhci-pci-data.c b/drivers/mmc/host/sdhci-pci-data.c new file mode 100644 index 00000000000..a611217769f --- /dev/null +++ b/drivers/mmc/host/sdhci-pci-data.c | |||
@@ -0,0 +1,5 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/mmc/sdhci-pci-data.h> | ||
3 | |||
4 | struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, int slotno); | ||
5 | EXPORT_SYMBOL_GPL(sdhci_pci_get_data); | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d2e77fb21b2..4e8f324e2c8 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/sfi.h> | 26 | #include <linux/sfi.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/mmc/sdhci-pci-data.h> | ||
28 | 29 | ||
29 | #include "sdhci.h" | 30 | #include "sdhci.h" |
30 | 31 | ||
@@ -61,6 +62,7 @@ struct sdhci_pci_fixes { | |||
61 | struct sdhci_pci_slot { | 62 | struct sdhci_pci_slot { |
62 | struct sdhci_pci_chip *chip; | 63 | struct sdhci_pci_chip *chip; |
63 | struct sdhci_host *host; | 64 | struct sdhci_host *host; |
65 | struct sdhci_pci_data *data; | ||
64 | 66 | ||
65 | int pci_bar; | 67 | int pci_bar; |
66 | int rst_n_gpio; | 68 | int rst_n_gpio; |
@@ -1188,11 +1190,12 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = { | |||
1188 | \*****************************************************************************/ | 1190 | \*****************************************************************************/ |
1189 | 1191 | ||
1190 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | 1192 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( |
1191 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar) | 1193 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar, |
1194 | int slotno) | ||
1192 | { | 1195 | { |
1193 | struct sdhci_pci_slot *slot; | 1196 | struct sdhci_pci_slot *slot; |
1194 | struct sdhci_host *host; | 1197 | struct sdhci_host *host; |
1195 | int ret; | 1198 | int ret, bar = first_bar + slotno; |
1196 | 1199 | ||
1197 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { | 1200 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { |
1198 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); | 1201 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); |
@@ -1227,6 +1230,20 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
1227 | slot->pci_bar = bar; | 1230 | slot->pci_bar = bar; |
1228 | slot->rst_n_gpio = -EINVAL; | 1231 | slot->rst_n_gpio = -EINVAL; |
1229 | 1232 | ||
1233 | /* Retrieve platform data if there is any */ | ||
1234 | if (*sdhci_pci_get_data) | ||
1235 | slot->data = sdhci_pci_get_data(pdev, slotno); | ||
1236 | |||
1237 | if (slot->data) { | ||
1238 | if (slot->data->setup) { | ||
1239 | ret = slot->data->setup(slot->data); | ||
1240 | if (ret) { | ||
1241 | dev_err(&pdev->dev, "platform setup failed\n"); | ||
1242 | goto free; | ||
1243 | } | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1230 | host->hw_name = "PCI"; | 1247 | host->hw_name = "PCI"; |
1231 | host->ops = &sdhci_pci_ops; | 1248 | host->ops = &sdhci_pci_ops; |
1232 | host->quirks = chip->quirks; | 1249 | host->quirks = chip->quirks; |
@@ -1236,7 +1253,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
1236 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); | 1253 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); |
1237 | if (ret) { | 1254 | if (ret) { |
1238 | dev_err(&pdev->dev, "cannot request region\n"); | 1255 | dev_err(&pdev->dev, "cannot request region\n"); |
1239 | goto free; | 1256 | goto cleanup; |
1240 | } | 1257 | } |
1241 | 1258 | ||
1242 | host->ioaddr = pci_ioremap_bar(pdev, bar); | 1259 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
@@ -1270,6 +1287,10 @@ unmap: | |||
1270 | release: | 1287 | release: |
1271 | pci_release_region(pdev, bar); | 1288 | pci_release_region(pdev, bar); |
1272 | 1289 | ||
1290 | cleanup: | ||
1291 | if (slot->data && slot->data->cleanup) | ||
1292 | slot->data->cleanup(slot->data); | ||
1293 | |||
1273 | free: | 1294 | free: |
1274 | sdhci_free_host(host); | 1295 | sdhci_free_host(host); |
1275 | 1296 | ||
@@ -1291,6 +1312,9 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) | |||
1291 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) | 1312 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) |
1292 | slot->chip->fixes->remove_slot(slot, dead); | 1313 | slot->chip->fixes->remove_slot(slot, dead); |
1293 | 1314 | ||
1315 | if (slot->data && slot->data->cleanup) | ||
1316 | slot->data->cleanup(slot->data); | ||
1317 | |||
1294 | pci_release_region(slot->chip->pdev, slot->pci_bar); | 1318 | pci_release_region(slot->chip->pdev, slot->pci_bar); |
1295 | 1319 | ||
1296 | sdhci_free_host(slot->host); | 1320 | sdhci_free_host(slot->host); |
@@ -1377,7 +1401,7 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, | |||
1377 | slots = chip->num_slots; /* Quirk may have changed this */ | 1401 | slots = chip->num_slots; /* Quirk may have changed this */ |
1378 | 1402 | ||
1379 | for (i = 0; i < slots; i++) { | 1403 | for (i = 0; i < slots; i++) { |
1380 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); | 1404 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); |
1381 | if (IS_ERR(slot)) { | 1405 | if (IS_ERR(slot)) { |
1382 | for (i--; i >= 0; i--) | 1406 | for (i--; i >= 0; i--) |
1383 | sdhci_pci_remove_slot(chip->slots[i]); | 1407 | sdhci_pci_remove_slot(chip->slots[i]); |
diff --git a/include/linux/mmc/sdhci-pci-data.h b/include/linux/mmc/sdhci-pci-data.h new file mode 100644 index 00000000000..8959604a13d --- /dev/null +++ b/include/linux/mmc/sdhci-pci-data.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef LINUX_MMC_SDHCI_PCI_DATA_H | ||
2 | #define LINUX_MMC_SDHCI_PCI_DATA_H | ||
3 | |||
4 | struct pci_dev; | ||
5 | |||
6 | struct sdhci_pci_data { | ||
7 | struct pci_dev *pdev; | ||
8 | int slotno; | ||
9 | int rst_n_gpio; /* Set to -EINVAL if unused */ | ||
10 | int cd_gpio; /* Set to -EINVAL if unused */ | ||
11 | int (*setup)(struct sdhci_pci_data *data); | ||
12 | void (*cleanup)(struct sdhci_pci_data *data); | ||
13 | }; | ||
14 | |||
15 | extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, | ||
16 | int slotno); | ||
17 | |||
18 | #endif | ||