* [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO
@ 2011-12-27 13:48 Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 1/7] mmc: sdhci: fix vmmc handling Adrian Hunter
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Hi
Here are some changes (V4) to allow wl12xx/SDIO to be set up for sdhci-pci.
There a a couple of fixes plus a method to get platform data. The
changes to the platform files are not included in this patchset.
V4: Fix initialization and free of cd_irq in
"mmc: sdhci-pci: get gpio numbers from platform data"
V3: add "mmc: sdhci-pci: enable runtime PM for Medfield SDIO"
roll-in "sdhci: Always pass clock request value zero to set_clock host op"
V2: change sdhci_pci_get_data() from a weak function to a function
pointer
Adrian Hunter (6):
mmc: sdhci: fix vmmc handling
mmc: sdhci: prevent card detection activity for non-removable cards
mmc: sdhci-pci: add platform data
mmc: sdhci-pci: get gpio numbers from platform data
mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION
mmc: sdhci-pci: enable runtime PM for Medfield SDIO
Todd Poynor (1):
sdhci: Always pass clock request value zero to set_clock host op
drivers/Makefile | 2 +-
drivers/mmc/Makefile | 3 +-
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-pci-data.c | 5 +
drivers/mmc/host/sdhci-pci.c | 143 ++++++++++++++++++------------------
drivers/mmc/host/sdhci.c | 51 ++++++-------
include/linux/mmc/sdhci-pci-data.h | 18 +++++
include/linux/mmc/sdhci.h | 2 -
8 files changed, 123 insertions(+), 102 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-pci-data.c
create mode 100644 include/linux/mmc/sdhci-pci-data.h
Regards
Adrian
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH V4 1/7] mmc: sdhci: fix vmmc handling
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 2/7] mmc: sdhci: prevent card detection activity for non-removable cards Adrian Hunter
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Presently the vmmc regulator is enabled when the host
controller is added and disabled when it is removed.
However, the vmmc regulator should be under the control
of the upper layers via ->set_ios(). Make it so.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 43 +++++++++++++++++++++----------------------
1 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ab6018f..6a35d03 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1170,7 +1170,7 @@ out:
host->clock = clock;
}
-static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
+static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
{
u8 pwr = 0;
@@ -1193,13 +1193,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
}
if (host->pwr == pwr)
- return;
+ return -1;
host->pwr = pwr;
if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
- return;
+ return 0;
}
/*
@@ -1226,6 +1226,8 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
*/
if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
mdelay(10);
+
+ return power;
}
/*****************************************************************************\
@@ -1307,12 +1309,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
{
unsigned long flags;
+ int vdd_bit = -1;
u8 ctrl;
spin_lock_irqsave(&host->lock, flags);
- if (host->flags & SDHCI_DEVICE_DEAD)
- goto out;
+ if (host->flags & SDHCI_DEVICE_DEAD) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
+ return;
+ }
/*
* Reset the chip on each power off.
@@ -1326,9 +1333,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
sdhci_set_clock(host, ios->clock);
if (ios->power_mode == MMC_POWER_OFF)
- sdhci_set_power(host, -1);
+ vdd_bit = sdhci_set_power(host, -1);
else
- sdhci_set_power(host, ios->vdd);
+ vdd_bit = sdhci_set_power(host, ios->vdd);
+
+ if (host->vmmc && vdd_bit != -1) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
+ spin_lock_irqsave(&host->lock, flags);
+ }
if (host->ops->platform_send_init_74_clocks)
host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1453,7 +1466,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
-out:
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
}
@@ -2357,9 +2369,6 @@ int sdhci_suspend_host(struct sdhci_host *host)
free_irq(host->irq, host);
- if (host->vmmc)
- ret = regulator_disable(host->vmmc);
-
return ret;
}
@@ -2369,12 +2378,6 @@ int sdhci_resume_host(struct sdhci_host *host)
{
int ret;
- if (host->vmmc) {
- int ret = regulator_enable(host->vmmc);
- if (ret)
- return ret;
- }
-
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma)
host->ops->enable_dma(host);
@@ -2936,8 +2939,6 @@ int sdhci_add_host(struct sdhci_host *host)
if (IS_ERR(host->vmmc)) {
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
host->vmmc = NULL;
- } else {
- regulator_enable(host->vmmc);
}
sdhci_init(host, 0);
@@ -3026,10 +3027,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
- if (host->vmmc) {
- regulator_disable(host->vmmc);
+ if (host->vmmc)
regulator_put(host->vmmc);
- }
kfree(host->adma_desc);
kfree(host->align_buffer);
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 2/7] mmc: sdhci: prevent card detection activity for non-removable cards
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 1/7] mmc: sdhci: fix vmmc handling Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 3/7] mmc: sdhci-pci: add platform data Adrian Hunter
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Do not enable card detection interrupts for non-removable cards.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6a35d03..e6c6cd6 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -146,10 +146,9 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
{
u32 present, irqs;
- if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
- return;
-
- if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION)
+ if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
+ (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION) ||
+ !mmc_card_is_removable(host->mmc))
return;
present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 3/7] mmc: sdhci-pci: add platform data
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 1/7] mmc: sdhci: fix vmmc handling Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 2/7] mmc: sdhci: prevent card detection activity for non-removable cards Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 4/7] mmc: sdhci-pci: get gpio numbers from " Adrian Hunter
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
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>
---
drivers/Makefile | 2 +-
drivers/mmc/Makefile | 3 +--
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-pci-data.c | 5 +++++
drivers/mmc/host/sdhci-pci.c | 32 ++++++++++++++++++++++++++++----
include/linux/mmc/sdhci-pci-data.h | 18 ++++++++++++++++++
6 files changed, 54 insertions(+), 7 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-pci-data.c
create mode 100644 include/linux/mmc/sdhci-pci-data.h
diff --git a/drivers/Makefile b/drivers/Makefile
index 1b31421..c07be02 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -97,7 +97,7 @@ obj-$(CONFIG_EISA) += eisa/
obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
-obj-$(CONFIG_MMC) += mmc/
+obj-y += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-y += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 12eef39..400756e 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -6,5 +6,4 @@ subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG
obj-$(CONFIG_MMC) += core/
obj-$(CONFIG_MMC) += card/
-obj-$(CONFIG_MMC) += host/
-
+obj-$(subst m,y,$(CONFIG_MMC)) += host/
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b4b83f3..745f8fc 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
+obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o
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 0000000..a611217
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pci-data.c
@@ -0,0 +1,5 @@
+#include <linux/module.h>
+#include <linux/mmc/sdhci-pci-data.h>
+
+struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, int slotno);
+EXPORT_SYMBOL_GPL(sdhci_pci_get_data);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index d2e77fb..4e8f324 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/sfi.h>
#include <linux/pm_runtime.h>
+#include <linux/mmc/sdhci-pci-data.h>
#include "sdhci.h"
@@ -61,6 +62,7 @@ struct sdhci_pci_fixes {
struct sdhci_pci_slot {
struct sdhci_pci_chip *chip;
struct sdhci_host *host;
+ struct sdhci_pci_data *data;
int pci_bar;
int rst_n_gpio;
@@ -1188,11 +1190,12 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = {
\*****************************************************************************/
static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
- struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar)
+ struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
+ int slotno)
{
struct sdhci_pci_slot *slot;
struct sdhci_host *host;
- int ret;
+ int ret, bar = first_bar + slotno;
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
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(
slot->pci_bar = bar;
slot->rst_n_gpio = -EINVAL;
+ /* Retrieve platform data if there is any */
+ if (*sdhci_pci_get_data)
+ slot->data = sdhci_pci_get_data(pdev, slotno);
+
+ if (slot->data) {
+ if (slot->data->setup) {
+ ret = slot->data->setup(slot->data);
+ if (ret) {
+ dev_err(&pdev->dev, "platform setup failed\n");
+ goto free;
+ }
+ }
+ }
+
host->hw_name = "PCI";
host->ops = &sdhci_pci_ops;
host->quirks = chip->quirks;
@@ -1236,7 +1253,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
if (ret) {
dev_err(&pdev->dev, "cannot request region\n");
- goto free;
+ goto cleanup;
}
host->ioaddr = pci_ioremap_bar(pdev, bar);
@@ -1270,6 +1287,10 @@ unmap:
release:
pci_release_region(pdev, bar);
+cleanup:
+ if (slot->data && slot->data->cleanup)
+ slot->data->cleanup(slot->data);
+
free:
sdhci_free_host(host);
@@ -1291,6 +1312,9 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
if (slot->chip->fixes && slot->chip->fixes->remove_slot)
slot->chip->fixes->remove_slot(slot, dead);
+ if (slot->data && slot->data->cleanup)
+ slot->data->cleanup(slot->data);
+
pci_release_region(slot->chip->pdev, slot->pci_bar);
sdhci_free_host(slot->host);
@@ -1377,7 +1401,7 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
slots = chip->num_slots; /* Quirk may have changed this */
for (i = 0; i < slots; i++) {
- slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i);
+ slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
if (IS_ERR(slot)) {
for (i--; i >= 0; i--)
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 0000000..8959604
--- /dev/null
+++ b/include/linux/mmc/sdhci-pci-data.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_MMC_SDHCI_PCI_DATA_H
+#define LINUX_MMC_SDHCI_PCI_DATA_H
+
+struct pci_dev;
+
+struct sdhci_pci_data {
+ struct pci_dev *pdev;
+ int slotno;
+ int rst_n_gpio; /* Set to -EINVAL if unused */
+ int cd_gpio; /* Set to -EINVAL if unused */
+ int (*setup)(struct sdhci_pci_data *data);
+ void (*cleanup)(struct sdhci_pci_data *data);
+};
+
+extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev,
+ int slotno);
+
+#endif
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 4/7] mmc: sdhci-pci: get gpio numbers from platform data
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (2 preceding siblings ...)
2011-12-27 13:48 ` [PATCH V4 3/7] mmc: sdhci-pci: add platform data Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 5/7] mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION Adrian Hunter
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Retrieve the GPIO numbers for hardware reset and
card detect from platform data.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci-pci.c | 109 ++++++++++++++++--------------------------
1 files changed, 41 insertions(+), 68 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 4e8f324..646680a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -23,7 +23,6 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/gpio.h>
-#include <linux/sfi.h>
#include <linux/pm_runtime.h>
#include <linux/mmc/sdhci-pci-data.h>
@@ -173,32 +172,9 @@ static int mrst_hc_probe(struct sdhci_pci_chip *chip)
return 0;
}
-/* Medfield eMMC hardware reset GPIOs */
-static int mfd_emmc0_rst_gpio = -EINVAL;
-static int mfd_emmc1_rst_gpio = -EINVAL;
-
-static int mfd_emmc_gpio_parse(struct sfi_table_header *table)
-{
- struct sfi_table_simple *sb = (struct sfi_table_simple *)table;
- struct sfi_gpio_table_entry *entry;
- int i, num;
-
- num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
- entry = (struct sfi_gpio_table_entry *)sb->pentry;
-
- for (i = 0; i < num; i++, entry++) {
- if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN))
- mfd_emmc0_rst_gpio = entry->pin_no;
- else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN))
- mfd_emmc1_rst_gpio = entry->pin_no;
- }
-
- return 0;
-}
-
#ifdef CONFIG_PM_RUNTIME
-static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
+static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
{
struct sdhci_pci_slot *slot = dev_id;
struct sdhci_host *host = slot->host;
@@ -207,15 +183,16 @@ static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
return IRQ_HANDLED;
}
-#define MFLD_SD_CD_PIN 69
-
-static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
+static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
{
- int err, irq, gpio = MFLD_SD_CD_PIN;
+ int err, irq, gpio = slot->cd_gpio;
slot->cd_gpio = -EINVAL;
slot->cd_irq = -EINVAL;
+ if (!gpio_is_valid(gpio))
+ return;
+
err = gpio_request(gpio, "sd_cd");
if (err < 0)
goto out;
@@ -228,7 +205,7 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
if (irq < 0)
goto out_free;
- err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING |
+ err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING, "sd_cd", slot);
if (err)
goto out_free;
@@ -237,65 +214,41 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
slot->cd_irq = irq;
slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION;
- return 0;
+ return;
out_free:
gpio_free(gpio);
out:
dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
- return 0;
}
-static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead)
+static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
{
if (slot->cd_irq >= 0)
free_irq(slot->cd_irq, slot);
- gpio_free(slot->cd_gpio);
+ if (gpio_is_valid(slot->cd_gpio))
+ gpio_free(slot->cd_gpio);
}
#else
-#define mfd_sd_probe_slot NULL
-#define mfd_sd_remove_slot NULL
+static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
+{
+}
+
+static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
+{
+}
#endif
static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
{
- const char *name = NULL;
- int gpio = -EINVAL;
-
- sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mfd_emmc_gpio_parse);
-
- switch (slot->chip->pdev->device) {
- case PCI_DEVICE_ID_INTEL_MFD_EMMC0:
- gpio = mfd_emmc0_rst_gpio;
- name = "eMMC0_reset";
- break;
- case PCI_DEVICE_ID_INTEL_MFD_EMMC1:
- gpio = mfd_emmc1_rst_gpio;
- name = "eMMC1_reset";
- break;
- }
-
- if (!gpio_request(gpio, name)) {
- gpio_direction_output(gpio, 1);
- slot->rst_n_gpio = gpio;
- slot->host->mmc->caps |= MMC_CAP_HW_RESET;
- }
-
slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
-
slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC;
-
return 0;
}
-static void mfd_emmc_remove_slot(struct sdhci_pci_slot *slot, int dead)
-{
- gpio_free(slot->rst_n_gpio);
-}
-
static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
.probe_slot = mrst_hc_probe_slot,
@@ -309,8 +262,6 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
- .probe_slot = mfd_sd_probe_slot,
- .remove_slot = mfd_sd_remove_slot,
};
static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
@@ -322,7 +273,6 @@ static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
.probe_slot = mfd_emmc_probe_slot,
- .remove_slot = mfd_emmc_remove_slot,
};
/* O2Micro extra registers */
@@ -1229,6 +1179,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
slot->host = host;
slot->pci_bar = bar;
slot->rst_n_gpio = -EINVAL;
+ slot->cd_gpio = -EINVAL;
/* Retrieve platform data if there is any */
if (*sdhci_pci_get_data)
@@ -1242,6 +1193,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
goto free;
}
}
+ slot->rst_n_gpio = slot->data->rst_n_gpio;
+ slot->cd_gpio = slot->data->cd_gpio;
}
host->hw_name = "PCI";
@@ -1269,15 +1222,30 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
goto unmap;
}
+ if (gpio_is_valid(slot->rst_n_gpio)) {
+ if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
+ gpio_direction_output(slot->rst_n_gpio, 1);
+ slot->host->mmc->caps |= MMC_CAP_HW_RESET;
+ } else {
+ dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
+ slot->rst_n_gpio = -EINVAL;
+ }
+ }
+
host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
ret = sdhci_add_host(host);
if (ret)
goto remove;
+ sdhci_pci_add_own_cd(slot);
+
return slot;
remove:
+ if (gpio_is_valid(slot->rst_n_gpio))
+ gpio_free(slot->rst_n_gpio);
+
if (chip->fixes && chip->fixes->remove_slot)
chip->fixes->remove_slot(slot, 0);
@@ -1302,6 +1270,8 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
int dead;
u32 scratch;
+ sdhci_pci_remove_own_cd(slot);
+
dead = 0;
scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
if (scratch == (u32)-1)
@@ -1309,6 +1279,9 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
sdhci_remove_host(slot->host, dead);
+ if (gpio_is_valid(slot->rst_n_gpio))
+ gpio_free(slot->rst_n_gpio);
+
if (slot->chip->fixes && slot->chip->fixes->remove_slot)
slot->chip->fixes->remove_slot(slot, dead);
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 5/7] mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (3 preceding siblings ...)
2011-12-27 13:48 ` [PATCH V4 4/7] mmc: sdhci-pci: get gpio numbers from " Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 6/7] sdhci: Always pass clock request value zero to set_clock host op Adrian Hunter
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Even if a driver provides separate card detection,
an interrupt is still needed to abort mmc requests
that are in progress. SDHCI_QUIRK2_OWN_CARD_DETECTION
prevents that, so remove it.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci-pci.c | 1 -
drivers/mmc/host/sdhci.c | 1 -
include/linux/mmc/sdhci.h | 2 --
3 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 646680a..83a152e 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -212,7 +212,6 @@ static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
slot->cd_gpio = gpio;
slot->cd_irq = irq;
- slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION;
return;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e6c6cd6..6f1fd02 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -147,7 +147,6 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
u32 present, irqs;
if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
- (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION) ||
!mmc_card_is_removable(host->mmc))
return;
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index e4b6935..dad7a46 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -90,8 +90,6 @@ struct sdhci_host {
unsigned int quirks2; /* More deviations from spec. */
-#define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<0)
-
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 6/7] sdhci: Always pass clock request value zero to set_clock host op
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (4 preceding siblings ...)
2011-12-27 13:48 ` [PATCH V4 5/7] mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 7/7] mmc: sdhci-pci: enable runtime PM for Medfield SDIO Adrian Hunter
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
To allow the set_clock host op to disable the SDCLK source when not
needed, always call the host op when the requested clock speed is
zero. Do this even if host->clock already equals zero, because
the SDHCI driver may set that value (without calling the host op)
to force an update at the next (non-zero-speed) call.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6f1fd02..e062997 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1068,7 +1068,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
u16 clk = 0;
unsigned long timeout;
- if (clock == host->clock)
+ if (clock && clock == host->clock)
return;
host->mmc->actual_clock = 0;
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH V4 7/7] mmc: sdhci-pci: enable runtime PM for Medfield SDIO
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (5 preceding siblings ...)
2011-12-27 13:48 ` [PATCH V4 6/7] sdhci: Always pass clock request value zero to set_clock host op Adrian Hunter
@ 2011-12-27 13:48 ` Adrian Hunter
2011-12-27 14:00 ` [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
2012-01-03 0:08 ` Chris Ball
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 13:48 UTC (permalink / raw)
To: Chris Ball; +Cc: linux-mmc, Adrian Hunter
Runtime PM for SDIO is no longer enabled by default
(see 5c7f0e083d2d98ba14ddd10e88f001a0ead4cae4) so
it must now be enabled per platform, in this case
Medfield uses it.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci-pci.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 83a152e..7165e6a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -248,6 +248,12 @@ static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
return 0;
}
+static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+ slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD;
+ return 0;
+}
+
static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
.probe_slot = mrst_hc_probe_slot,
@@ -266,6 +272,7 @@ static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
+ .probe_slot = mfd_sdio_probe_slot,
};
static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
--
1.7.6.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (6 preceding siblings ...)
2011-12-27 13:48 ` [PATCH V4 7/7] mmc: sdhci-pci: enable runtime PM for Medfield SDIO Adrian Hunter
@ 2011-12-27 14:00 ` Adrian Hunter
2012-01-03 0:08 ` Chris Ball
8 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2011-12-27 14:00 UTC (permalink / raw)
To: Chris Ball; +Cc: Adrian Hunter, linux-mmc
On 27/12/11 15:48, Adrian Hunter wrote:
> Hi
>
> Here are some changes (V4) to allow wl12xx/SDIO to be set up for sdhci-pci.
> There a a couple of fixes plus a method to get platform data. The
> changes to the platform files are not included in this patchset.
>
>
> V4: Fix initialization and free of cd_irq in
Actually "cd_gpio"
> "mmc: sdhci-pci: get gpio numbers from platform data"
>
> V3: add "mmc: sdhci-pci: enable runtime PM for Medfield SDIO"
> roll-in "sdhci: Always pass clock request value zero to set_clock host op"
>
> V2: change sdhci_pci_get_data() from a weak function to a function
> pointer
>
>
> Adrian Hunter (6):
> mmc: sdhci: fix vmmc handling
> mmc: sdhci: prevent card detection activity for non-removable cards
> mmc: sdhci-pci: add platform data
> mmc: sdhci-pci: get gpio numbers from platform data
> mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION
> mmc: sdhci-pci: enable runtime PM for Medfield SDIO
>
> Todd Poynor (1):
> sdhci: Always pass clock request value zero to set_clock host op
>
> drivers/Makefile | 2 +-
> drivers/mmc/Makefile | 3 +-
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-pci-data.c | 5 +
> drivers/mmc/host/sdhci-pci.c | 143 ++++++++++++++++++------------------
> drivers/mmc/host/sdhci.c | 51 ++++++-------
> include/linux/mmc/sdhci-pci-data.h | 18 +++++
> include/linux/mmc/sdhci.h | 2 -
> 8 files changed, 123 insertions(+), 102 deletions(-)
> create mode 100644 drivers/mmc/host/sdhci-pci-data.c
> create mode 100644 include/linux/mmc/sdhci-pci-data.h
>
>
> Regards
> Adrian
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
` (7 preceding siblings ...)
2011-12-27 14:00 ` [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
@ 2012-01-03 0:08 ` Chris Ball
8 siblings, 0 replies; 10+ messages in thread
From: Chris Ball @ 2012-01-03 0:08 UTC (permalink / raw)
To: Adrian Hunter; +Cc: linux-mmc
Hi Adrian,
On Tue, Dec 27 2011, Adrian Hunter wrote:
> Hi
>
> Here are some changes (V4) to allow wl12xx/SDIO to be set up for sdhci-pci.
> There a a couple of fixes plus a method to get platform data. The
> changes to the platform files are not included in this patchset.
Thanks, I've pushed all seven patches to mmc-next for 3.3.
- Chris.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-01-03 0:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-27 13:48 [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 1/7] mmc: sdhci: fix vmmc handling Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 2/7] mmc: sdhci: prevent card detection activity for non-removable cards Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 3/7] mmc: sdhci-pci: add platform data Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 4/7] mmc: sdhci-pci: get gpio numbers from " Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 5/7] mmc: sdhci-pci: remove SDHCI_QUIRK2_OWN_CARD_DETECTION Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 6/7] sdhci: Always pass clock request value zero to set_clock host op Adrian Hunter
2011-12-27 13:48 ` [PATCH V4 7/7] mmc: sdhci-pci: enable runtime PM for Medfield SDIO Adrian Hunter
2011-12-27 14:00 ` [PATCH V4 0/7] mmc: sdhci/sdhci-pci: prepare for wl12xx/SDIO Adrian Hunter
2012-01-03 0:08 ` Chris Ball
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).