* [PATCH 1/6] mmc: sdhci-pltfm: Add structure for host-specific data
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
@ 2010-10-15 10:20 ` Wolfram Sang
2010-10-15 10:21 ` [PATCH 2/6] mmc: sdhci-pltfm: move .h-file into apropriate subdir Wolfram Sang
` (5 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:20 UTC (permalink / raw)
To: linux-arm-kernel
We need to carry some information per host, e.g. the clock. Add a
structure for it and initialize it in the generic part. Also improve
the check for a parent.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Richard R?jfors <richard.rojfors.ext@mocean-labs.com>
---
drivers/mmc/host/sdhci-pltfm.c | 10 +++++++---
drivers/mmc/host/sdhci-pltfm.h | 7 +++++++
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 4f126de..730fdf5 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -55,6 +55,7 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
struct sdhci_pltfm_data *pdata = pdev->dev.platform_data;
const struct platform_device_id *platid = platform_get_device_id(pdev);
struct sdhci_host *host;
+ struct sdhci_pltfm_host *pltfm_host;
struct resource *iomem;
int ret;
@@ -71,16 +72,19 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Invalid iomem size. You may "
"experience problems.\n");
- if (pdev->dev.parent)
- host = sdhci_alloc_host(pdev->dev.parent, 0);
+ /* Some PCI-based MFD need the parent here */
+ if (pdev->dev.parent != &platform_bus)
+ host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
else
- host = sdhci_alloc_host(&pdev->dev, 0);
+ host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
if (IS_ERR(host)) {
ret = PTR_ERR(host);
goto err;
}
+ pltfm_host = sdhci_priv(host);
+
host->hw_name = "platform";
if (pdata && pdata->ops)
host->ops = pdata->ops;
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 900f329..93a0319 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -11,8 +11,15 @@
#ifndef _DRIVERS_MMC_SDHCI_PLTFM_H
#define _DRIVERS_MMC_SDHCI_PLTFM_H
+#include <linux/clk.h>
+#include <linux/types.h>
#include <linux/sdhci-pltfm.h>
+struct sdhci_pltfm_host {
+ struct clk *clk;
+ u32 scratchpad; /* to handle quirks across io-accessor calls */
+};
+
extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
#endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/6] mmc: sdhci-pltfm: move .h-file into apropriate subdir
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
2010-10-15 10:20 ` [PATCH 1/6] mmc: sdhci-pltfm: Add structure for host-specific data Wolfram Sang
@ 2010-10-15 10:21 ` Wolfram Sang
2010-10-15 10:21 ` [PATCH 3/6] mmc: sdhci: introduce private get_ro Wolfram Sang
` (4 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:21 UTC (permalink / raw)
To: linux-arm-kernel
Make use of the mmc-directory.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Tested-by : Eric B?nard <eric@eukrea.com>
---
drivers/mmc/host/sdhci-cns3xxx.c | 2 +-
drivers/mmc/host/sdhci-pltfm.c | 2 +-
drivers/mmc/host/sdhci-pltfm.h | 2 +-
include/linux/mmc/sdhci-pltfm.h | 35 +++++++++++++++++++++++++++++++++++
include/linux/sdhci-pltfm.h | 35 -----------------------------------
5 files changed, 38 insertions(+), 38 deletions(-)
create mode 100644 include/linux/mmc/sdhci-pltfm.h
delete mode 100644 include/linux/sdhci-pltfm.h
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index b7050b3..9ebd1d7 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -15,7 +15,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mmc/host.h>
-#include <linux/sdhci-pltfm.h>
+#include <linux/mmc/sdhci-pltfm.h>
#include <mach/cns3xxx.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 730fdf5..685202b 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -30,7 +30,7 @@
#include <linux/mmc/host.h>
#include <linux/io.h>
-#include <linux/sdhci-pltfm.h>
+#include <linux/mmc/sdhci-pltfm.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 93a0319..562b929 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -13,7 +13,7 @@
#include <linux/clk.h>
#include <linux/types.h>
-#include <linux/sdhci-pltfm.h>
+#include <linux/mmc/sdhci-pltfm.h>
struct sdhci_pltfm_host {
struct clk *clk;
diff --git a/include/linux/mmc/sdhci-pltfm.h b/include/linux/mmc/sdhci-pltfm.h
new file mode 100644
index 0000000..0239bd7
--- /dev/null
+++ b/include/linux/mmc/sdhci-pltfm.h
@@ -0,0 +1,35 @@
+/*
+ * Platform data declarations for the sdhci-pltfm driver.
+ *
+ * Copyright (c) 2010 MontaVista Software, LLC.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _SDHCI_PLTFM_H
+#define _SDHCI_PLTFM_H
+
+struct sdhci_ops;
+struct sdhci_host;
+
+/**
+ * struct sdhci_pltfm_data - SDHCI platform-specific information & hooks
+ * @ops: optional pointer to the platform-provided SDHCI ops
+ * @quirks: optional SDHCI quirks
+ * @init: optional hook that is called during device probe, before the
+ * driver tries to access any SDHCI registers
+ * @exit: optional hook that is called during device removal
+ */
+struct sdhci_pltfm_data {
+ struct sdhci_ops *ops;
+ unsigned int quirks;
+ int (*init)(struct sdhci_host *host);
+ void (*exit)(struct sdhci_host *host);
+};
+
+#endif /* _SDHCI_PLTFM_H */
diff --git a/include/linux/sdhci-pltfm.h b/include/linux/sdhci-pltfm.h
deleted file mode 100644
index 0239bd7..0000000
--- a/include/linux/sdhci-pltfm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Platform data declarations for the sdhci-pltfm driver.
- *
- * Copyright (c) 2010 MontaVista Software, LLC.
- *
- * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef _SDHCI_PLTFM_H
-#define _SDHCI_PLTFM_H
-
-struct sdhci_ops;
-struct sdhci_host;
-
-/**
- * struct sdhci_pltfm_data - SDHCI platform-specific information & hooks
- * @ops: optional pointer to the platform-provided SDHCI ops
- * @quirks: optional SDHCI quirks
- * @init: optional hook that is called during device probe, before the
- * driver tries to access any SDHCI registers
- * @exit: optional hook that is called during device removal
- */
-struct sdhci_pltfm_data {
- struct sdhci_ops *ops;
- unsigned int quirks;
- int (*init)(struct sdhci_host *host);
- void (*exit)(struct sdhci_host *host);
-};
-
-#endif /* _SDHCI_PLTFM_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/6] mmc: sdhci: introduce private get_ro
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
2010-10-15 10:20 ` [PATCH 1/6] mmc: sdhci-pltfm: Add structure for host-specific data Wolfram Sang
2010-10-15 10:21 ` [PATCH 2/6] mmc: sdhci-pltfm: move .h-file into apropriate subdir Wolfram Sang
@ 2010-10-15 10:21 ` Wolfram Sang
2010-10-15 10:21 ` [PATCH 4/6] mmc: sdhci_pltfm: pass more data on custom init-call Wolfram Sang
` (3 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:21 UTC (permalink / raw)
To: linux-arm-kernel
Some controllers handle their write-protection differently. Introduce a
callback to be able to handle it, ensuring the same locking takes place
for it. Rename the status variable to make it more obvious why the read
from the registers needs to be inverted.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by : Eric B?nard <eric@eukrea.com>
---
Changes since last version:
rename the variable to make usage of '!' more obvious
drivers/mmc/host/sdhci.c | 15 +++++++++------
drivers/mmc/host/sdhci.h | 1 +
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9cb60ba..782c0ee 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1223,22 +1223,25 @@ static int sdhci_get_ro(struct mmc_host *mmc)
{
struct sdhci_host *host;
unsigned long flags;
- int present;
+ int is_readonly;
host = mmc_priv(mmc);
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_DEVICE_DEAD)
- present = 0;
+ is_readonly = 0;
+ else if (host->ops->get_ro)
+ is_readonly = host->ops->get_ro(host);
else
- present = sdhci_readl(host, SDHCI_PRESENT_STATE);
+ is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
+ & SDHCI_WRITE_PROTECT);
spin_unlock_irqrestore(&host->lock, flags);
- if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
- return !!(present & SDHCI_WRITE_PROTECT);
- return !(present & SDHCI_WRITE_PROTECT);
+ /* This quirk needs to be replaced by a callback-function later */
+ return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
+ !is_readonly : is_readonly;
}
static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index bfcd611..b7b8a3b 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -214,6 +214,7 @@ struct sdhci_ops {
unsigned int (*get_timeout_clock)(struct sdhci_host *host);
void (*platform_send_init_74_clocks)(struct sdhci_host *host,
u8 power_mode);
+ unsigned int (*get_ro)(struct sdhci_host *host);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/6] mmc: sdhci_pltfm: pass more data on custom init-call
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
` (2 preceding siblings ...)
2010-10-15 10:21 ` [PATCH 3/6] mmc: sdhci: introduce private get_ro Wolfram Sang
@ 2010-10-15 10:21 ` Wolfram Sang
2010-10-15 10:21 ` [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff Wolfram Sang
` (2 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:21 UTC (permalink / raw)
To: linux-arm-kernel
The custom init call may need more data to perform its job, so we pass
it a pointer to pdata, too. Also, always use the platform_id specific
data even if platform_data is present. Doing that, platform_data can
additionally be parsed by init() for board-specific information (via
sdhci->mmc->parent).
(Note: the old behaviour was that you could override the platform_id
specific data with your own. However, one can still do this by using the
"sdhci" id instead of "sdhci-<something>".)
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by : Eric B?nard <eric@eukrea.com>
---
drivers/mmc/host/sdhci-pltfm.c | 8 +++++---
include/linux/mmc/sdhci-pltfm.h | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 685202b..00e8a8a 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -52,15 +52,17 @@ static struct sdhci_ops sdhci_pltfm_ops = {
static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
{
- struct sdhci_pltfm_data *pdata = pdev->dev.platform_data;
const struct platform_device_id *platid = platform_get_device_id(pdev);
+ struct sdhci_pltfm_data *pdata;
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
struct resource *iomem;
int ret;
- if (!pdata && platid && platid->driver_data)
+ if (platid && platid->driver_data)
pdata = (void *)platid->driver_data;
+ else
+ pdata = pdev->dev.platform_data;
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem) {
@@ -109,7 +111,7 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev)
}
if (pdata && pdata->init) {
- ret = pdata->init(host);
+ ret = pdata->init(host, pdata);
if (ret)
goto err_plat_init;
}
diff --git a/include/linux/mmc/sdhci-pltfm.h b/include/linux/mmc/sdhci-pltfm.h
index 0239bd7..548d59d 100644
--- a/include/linux/mmc/sdhci-pltfm.h
+++ b/include/linux/mmc/sdhci-pltfm.h
@@ -28,7 +28,7 @@ struct sdhci_host;
struct sdhci_pltfm_data {
struct sdhci_ops *ops;
unsigned int quirks;
- int (*init)(struct sdhci_host *host);
+ int (*init)(struct sdhci_host *host, struct sdhci_pltfm_data *pdata);
void (*exit)(struct sdhci_host *host);
};
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
` (3 preceding siblings ...)
2010-10-15 10:21 ` [PATCH 4/6] mmc: sdhci_pltfm: pass more data on custom init-call Wolfram Sang
@ 2010-10-15 10:21 ` Wolfram Sang
2010-10-18 16:13 ` Chris Ball
2010-10-15 10:21 ` [PATCH 6/6] mmc: sdhci-pltfm: add pltfm-driver for imx35/51 Wolfram Sang
2010-10-15 20:18 ` [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Chris Ball
6 siblings, 1 reply; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:21 UTC (permalink / raw)
To: linux-arm-kernel
Put everything which can be shared between the OF and platform version
of this driver into a local .h-file.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by : Eric B?nard <eric@eukrea.com>
---
No change since last version. 80-char/line changes confirmed.
drivers/mmc/host/sdhci-esdhc.h | 83 +++++++++++++++++++++++++++++++++++++
drivers/mmc/host/sdhci-of-esdhc.c | 70 ++++---------------------------
2 files changed, 91 insertions(+), 62 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-esdhc.h
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
new file mode 100644
index 0000000..afaf1bc
--- /dev/null
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -0,0 +1,83 @@
+/*
+ * Freescale eSDHC controller driver generics for OF and pltfm.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ * Copyright (c) 2010 Pengutronix e.K.
+ * Author: Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#ifndef _DRIVERS_MMC_SDHCI_ESDHC_H
+#define _DRIVERS_MMC_SDHCI_ESDHC_H
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
+ SDHCI_QUIRK_BROKEN_CARD_DETECTION | \
+ SDHCI_QUIRK_NO_BUSY_IRQ | \
+ SDHCI_QUIRK_NONSTANDARD_CLOCK | \
+ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
+ SDHCI_QUIRK_PIO_NEEDS_DELAY | \
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \
+ SDHCI_QUIRK_NO_CARD_NO_RESET)
+
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+/* pltfm-specific */
+#define ESDHC_HOST_CONTROL_LE 0x20
+
+/* OF-specific */
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_DMA_SNOOP 0x00000040
+
+#define ESDHC_HOST_CONTROL_RES 0x05
+
+static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int pre_div = 2;
+ int div = 1;
+ u32 temp;
+
+ temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+ temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
+ | ESDHC_CLOCK_MASK);
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+
+ if (clock == 0)
+ goto out;
+
+ while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
+ pre_div *= 2;
+
+ while (host->max_clk / pre_div / div > clock && div < 16)
+ div++;
+
+ dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
+ clock, host->max_clk / pre_div / div);
+
+ pre_div >>= 1;
+ div--;
+
+ temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+ temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
+ | (div << ESDHC_DIVIDER_SHIFT)
+ | (pre_div << ESDHC_PREDIV_SHIFT));
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+ mdelay(100);
+out:
+ host->clock = clock;
+}
+
+#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index c8623de..277fcb9 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -18,23 +18,7 @@
#include <linux/mmc/host.h>
#include "sdhci-of.h"
#include "sdhci.h"
-
-/*
- * Ops and quirks for the Freescale eSDHC controller.
- */
-
-#define ESDHC_DMA_SYSCTL 0x40c
-#define ESDHC_DMA_SNOOP 0x00000040
-
-#define ESDHC_SYSTEM_CONTROL 0x2c
-#define ESDHC_CLOCK_MASK 0x0000fff0
-#define ESDHC_PREDIV_SHIFT 8
-#define ESDHC_DIVIDER_SHIFT 4
-#define ESDHC_CLOCK_PEREN 0x00000004
-#define ESDHC_CLOCK_HCKEN 0x00000002
-#define ESDHC_CLOCK_IPGEN 0x00000001
-
-#define ESDHC_HOST_CONTROL_RES 0x05
+#include "sdhci-esdhc.c"
static u16 esdhc_readw(struct sdhci_host *host, int reg)
{
@@ -68,51 +52,20 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
sdhci_be32bs_writeb(host, val, reg);
}
-static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
-{
- int pre_div = 2;
- int div = 1;
-
- clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
- ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
-
- if (clock == 0)
- goto out;
-
- while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
- pre_div *= 2;
-
- while (host->max_clk / pre_div / div > clock && div < 16)
- div++;
-
- dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
- clock, host->max_clk / pre_div / div);
-
- pre_div >>= 1;
- div--;
-
- setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
- ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
- div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
- mdelay(100);
-out:
- host->clock = clock;
-}
-
-static int esdhc_enable_dma(struct sdhci_host *host)
+static int esdhc_of_enable_dma(struct sdhci_host *host)
{
setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
return 0;
}
-static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
{
struct sdhci_of_host *of_host = sdhci_priv(host);
return of_host->clock;
}
-static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
+static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
{
struct sdhci_of_host *of_host = sdhci_priv(host);
@@ -120,14 +73,7 @@ static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
}
struct sdhci_of_data sdhci_esdhc = {
- .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
- SDHCI_QUIRK_BROKEN_CARD_DETECTION |
- SDHCI_QUIRK_NO_BUSY_IRQ |
- SDHCI_QUIRK_NONSTANDARD_CLOCK |
- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
- SDHCI_QUIRK_PIO_NEEDS_DELAY |
- SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
- SDHCI_QUIRK_NO_CARD_NO_RESET,
+ .quirks = ESDHC_DEFAULT_QUIRKS,
.ops = {
.read_l = sdhci_be32bs_readl,
.read_w = esdhc_readw,
@@ -136,8 +82,8 @@ struct sdhci_of_data sdhci_esdhc = {
.write_w = esdhc_writew,
.write_b = esdhc_writeb,
.set_clock = esdhc_set_clock,
- .enable_dma = esdhc_enable_dma,
- .get_max_clock = esdhc_get_max_clock,
- .get_min_clock = esdhc_get_min_clock,
+ .enable_dma = esdhc_of_enable_dma,
+ .get_max_clock = esdhc_of_get_max_clock,
+ .get_min_clock = esdhc_of_get_min_clock,
},
};
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff
2010-10-15 10:21 ` [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff Wolfram Sang
@ 2010-10-18 16:13 ` Chris Ball
2010-10-19 2:29 ` Wolfram Sang
0 siblings, 1 reply; 16+ messages in thread
From: Chris Ball @ 2010-10-18 16:13 UTC (permalink / raw)
To: linux-arm-kernel
Hi Wolfram,
On Fri, Oct 15, 2010 at 12:21:03PM +0200, Wolfram Sang wrote:
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index c8623de..277fcb9 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -18,23 +18,7 @@
> #include <linux/mmc/host.h>
> #include "sdhci-of.h"
> #include "sdhci.h"
> -
> -/*
> - * Ops and quirks for the Freescale eSDHC controller.
> - */
> -
> -#define ESDHC_DMA_SYSCTL 0x40c
> -#define ESDHC_DMA_SNOOP 0x00000040
> -
> -#define ESDHC_SYSTEM_CONTROL 0x2c
> -#define ESDHC_CLOCK_MASK 0x0000fff0
> -#define ESDHC_PREDIV_SHIFT 8
> -#define ESDHC_DIVIDER_SHIFT 4
> -#define ESDHC_CLOCK_PEREN 0x00000004
> -#define ESDHC_CLOCK_HCKEN 0x00000002
> -#define ESDHC_CLOCK_IPGEN 0x00000001
> -
> -#define ESDHC_HOST_CONTROL_RES 0x05
> +#include "sdhci-esdhc.c"
Stephen reports a -next build failure after this patch. Presumably this
should be sdhci-esdhc.h? It's confusing that no-one else hit this.
Thanks,
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff
2010-10-18 16:13 ` Chris Ball
@ 2010-10-19 2:29 ` Wolfram Sang
2010-10-19 2:36 ` Chris Ball
0 siblings, 1 reply; 16+ messages in thread
From: Wolfram Sang @ 2010-10-19 2:29 UTC (permalink / raw)
To: linux-arm-kernel
Hi Chris,
> > -#define ESDHC_HOST_CONTROL_RES 0x05
> > +#include "sdhci-esdhc.c"
>
> Stephen reports a -next build failure after this patch. Presumably this
> should be sdhci-esdhc.h? It's confusing that no-one else hit this.
Uh, ouch, one brown paper bag, please! Yeah, confusing, that is.
Regarding your patch:
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101019/ea6e72c6/attachment.sig>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff
2010-10-19 2:29 ` Wolfram Sang
@ 2010-10-19 2:36 ` Chris Ball
0 siblings, 0 replies; 16+ messages in thread
From: Chris Ball @ 2010-10-19 2:36 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Oct 19, 2010 at 04:29:50AM +0200, Wolfram Sang wrote:
> > Stephen reports a -next build failure after this patch. Presumably this
> > should be sdhci-esdhc.h? It's confusing that no-one else hit this.
>
> Uh, ouch, one brown paper bag, please! Yeah, confusing, that is.
Ah, not that confusing -- sdhci-of-esdhc.c essentially depends on PPC,
and MMC_SDHCI_ESDHC_IMX depends on ARM, and I imagine we've only had
testing on the latter.
> Regarding your patch:
>
> Acked-by: Wolfram Sang <w.sang@pengutronix.de>
Thanks. When it comes time to send to Linus, I'll just roll this into
your original [5/6].
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 6/6] mmc: sdhci-pltfm: add pltfm-driver for imx35/51
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
` (4 preceding siblings ...)
2010-10-15 10:21 ` [PATCH 5/6] mmc: sdhci-of-esdhc: factor out common stuff Wolfram Sang
@ 2010-10-15 10:21 ` Wolfram Sang
2010-10-15 20:18 ` [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Chris Ball
6 siblings, 0 replies; 16+ messages in thread
From: Wolfram Sang @ 2010-10-15 10:21 UTC (permalink / raw)
To: linux-arm-kernel
This driver adds basic support for the esdhc-core found on e.g.
imx35/51. It adds up to the pltfm-core.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Tested-by : Eric B?nard <eric@eukrea.com>
---
Change since last version:
* Add Kconfig dependency for imx-archs
drivers/mmc/host/Kconfig | 10 +++
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-esdhc-imx.c | 143 ++++++++++++++++++++++++++++++++++++
drivers/mmc/host/sdhci-pltfm.c | 3 +
drivers/mmc/host/sdhci-pltfm.h | 1 +
5 files changed, 158 insertions(+), 0 deletions(-)
create mode 100644 drivers/mmc/host/sdhci-esdhc-imx.c
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0b7024a..c9c2520 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -130,6 +130,16 @@ config MMC_SDHCI_CNS3XXX
If unsure, say N.
+config MMC_SDHCI_ESDHC_IMX
+ bool "SDHCI platform support for the Freescale eSDHC i.MX controller"
+ depends on MMC_SDHCI_PLTFM && (ARCH_MX25 || ARCH_MX35 || ARCH_MX5)
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the Freescale eSDHC controller support on the platform
+ bus, found on platforms like mx35/51.
+
+ If unsure, say N.
+
config MMC_SDHCI_S3C
tristate "SDHCI support on Samsung S3C SoC"
depends on MMC_SDHCI && PLAT_SAMSUNG
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index eae5d62..6c4ac67 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_MMC_USHC) += ushc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-platform.o
sdhci-platform-y := sdhci-pltfm.o
sdhci-platform-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
+sdhci-platform-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
sdhci-of-y := sdhci-of-core.o
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
new file mode 100644
index 0000000..2e9cca1
--- /dev/null
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -0,0 +1,143 @@
+/*
+ * Freescale eSDHC i.MX controller driver for the platform bus.
+ *
+ * derived from the OF-version.
+ *
+ * Copyright (c) 2010 Pengutronix e.K.
+ * Author: Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdhci-pltfm.h>
+#include "sdhci.h"
+#include "sdhci-pltfm.h"
+#include "sdhci-esdhc.h"
+
+static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
+{
+ void __iomem *base = host->ioaddr + (reg & ~0x3);
+ u32 shift = (reg & 0x3) * 8;
+
+ writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
+}
+
+static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
+{
+ if (unlikely(reg == SDHCI_HOST_VERSION))
+ reg ^= 2;
+
+ return readw(host->ioaddr + reg);
+}
+
+static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ pltfm_host->scratchpad = val;
+ return;
+ case SDHCI_COMMAND:
+ writel(val << 16 | pltfm_host->scratchpad,
+ host->ioaddr + SDHCI_TRANSFER_MODE);
+ return;
+ case SDHCI_BLOCK_SIZE:
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ break;
+ }
+ esdhc_clrset_le(host, 0xffff, val, reg);
+}
+
+static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
+{
+ u32 new_val;
+
+ switch (reg) {
+ case SDHCI_POWER_CONTROL:
+ /*
+ * FSL put some DMA bits here
+ * If your board has a regulator, code should be here
+ */
+ return;
+ case SDHCI_HOST_CONTROL:
+ /* FSL messed up here, so we can just keep those two */
+ new_val = val & (SDHCI_CTRL_LED | SDHCI_CTRL_4BITBUS);
+ /* ensure the endianess */
+ new_val |= ESDHC_HOST_CONTROL_LE;
+ /* DMA mode bits are shifted */
+ new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
+
+ esdhc_clrset_le(host, 0xffff, new_val, reg);
+ return;
+ }
+ esdhc_clrset_le(host, 0xff, val, reg);
+}
+
+static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return clk_get_rate(pltfm_host->clk);
+}
+
+static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return clk_get_rate(pltfm_host->clk) / 256 / 16;
+}
+
+static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct clk *clk;
+
+ clk = clk_get(mmc_dev(host->mmc), NULL);
+ if (IS_ERR(clk)) {
+ dev_err(mmc_dev(host->mmc), "clk err\n");
+ return PTR_ERR(clk);
+ }
+ clk_enable(clk);
+ pltfm_host->clk = clk;
+
+ return 0;
+}
+
+static void esdhc_pltfm_exit(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+}
+
+static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_w = esdhc_readw_le,
+ .write_w = esdhc_writew_le,
+ .write_b = esdhc_writeb_le,
+ .set_clock = esdhc_set_clock,
+ .get_max_clock = esdhc_pltfm_get_max_clock,
+ .get_min_clock = esdhc_pltfm_get_min_clock,
+};
+
+struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK
+ | SDHCI_QUIRK_BROKEN_ADMA,
+ /* ADMA has issues. Might be fixable */
+ /* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */
+ .ops = &sdhci_esdhc_ops,
+ .init = esdhc_pltfm_init,
+ .exit = esdhc_pltfm_exit,
+};
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 00e8a8a..0502f89 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -167,6 +167,9 @@ static const struct platform_device_id sdhci_pltfm_ids[] = {
#ifdef CONFIG_MMC_SDHCI_CNS3XXX
{ "sdhci-cns3xxx", (kernel_ulong_t)&sdhci_cns3xxx_pdata },
#endif
+#ifdef CONFIG_MMC_SDHCI_ESDHC_IMX
+ { "sdhci-esdhc-imx", (kernel_ulong_t)&sdhci_esdhc_imx_pdata },
+#endif
{ },
};
MODULE_DEVICE_TABLE(platform, sdhci_pltfm_ids);
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index 562b929..c1bfe48 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -21,5 +21,6 @@ struct sdhci_pltfm_host {
};
extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
+extern struct sdhci_pltfm_data sdhci_esdhc_imx_pdata;
#endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V5 0/6] SD/MMC driver for MX25/35/51
2010-10-15 10:20 [PATCH V5 0/6] SD/MMC driver for MX25/35/51 Wolfram Sang
` (5 preceding siblings ...)
2010-10-15 10:21 ` [PATCH 6/6] mmc: sdhci-pltfm: add pltfm-driver for imx35/51 Wolfram Sang
@ 2010-10-15 20:18 ` Chris Ball
6 siblings, 0 replies; 16+ messages in thread
From: Chris Ball @ 2010-10-15 20:18 UTC (permalink / raw)
To: linux-arm-kernel
Hi Wolfram,
On Fri, Oct 15, 2010 at 12:20:58PM +0200, Wolfram Sang wrote:
> Another try. The driver seems to be known by now and used already :) Minor
> fixes only:
>
> 3/6: Rename a variable (found while working on write-protect-pin support)
> 5/6: Tested the checkpatch fixes
> 6/6: Added Kconfig dependencies
>
> The series is based on mmc-next as of today and also available at
>
> git://git.pengutronix.de/git/wsa/linux-2.6.git pcm043-mmc
>
> Thanks,
>
> Wolfram
>
> Wolfram Sang (6):
> mmc: sdhci-pltfm: Add structure for host-specific data
> mmc: sdhci-pltfm: move .h-file into apropriate subdir
> mmc: sdhci: introduce private get_ro
> mmc: sdhci_pltfm: pass more data on custom init-call
> mmc: sdhci-of-esdhc: factor out common stuff
> mmc: sdhci-pltfm: add pltfm-driver for imx35/51
Thanks! All pushed to mmc-next.
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
^ permalink raw reply [flat|nested] 16+ messages in thread