X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=blobdiff_plain;f=target%2Flinux%2Fs3c24xx%2Fpatches-2.6.31%2F200-s3c-mci.patch;fp=target%2Flinux%2Fs3c24xx%2Fpatches-2.6.31%2F200-s3c-mci.patch;h=0000000000000000000000000000000000000000;hp=3c1c2492316749e9d88dfe20bc3d89290380e138;hb=882e36ca7f56ba2427d7f2791b26501f2e4669f4;hpb=851d953350108e427064a344da1407c96621fdf8 diff --git a/target/linux/s3c24xx/patches-2.6.31/200-s3c-mci.patch b/target/linux/s3c24xx/patches-2.6.31/200-s3c-mci.patch deleted file mode 100644 index 3c1c249231..0000000000 --- a/target/linux/s3c24xx/patches-2.6.31/200-s3c-mci.patch +++ /dev/null @@ -1,379 +0,0 @@ -diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index d84c880..3e79f43 100644 ---- a/drivers/mmc/core/core.c -+++ b/drivers/mmc/core/core.c -@@ -59,10 +59,11 @@ static int mmc_schedule_delayed_work(struct delayed_work *work, - /* - * Internal function. Flush all scheduled work from the MMC work queue. - */ --static void mmc_flush_scheduled_work(void) -+void mmc_flush_scheduled_work(void) - { - flush_workqueue(workqueue); - } -+EXPORT_SYMBOL_GPL(mmc_flush_scheduled_work); - - /** - * mmc_request_done - finish processing an MMC request ---- a/include/linux/mmc/core.h -+++ b/include/linux/mmc/core.h -@@ -129,6 +129,8 @@ struct mmc_request { - struct mmc_host; - struct mmc_card; - -+extern void mmc_flush_scheduled_work(void); -+ - extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); - extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); - extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 891ef18..fa1889a 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -55,6 +55,18 @@ config MMC_SDHCI_PCI - - If unsure, say N. - -+config MMC_SDHCI_S3C -+ tristate "SDHCI support on Samsung S3C SoC" -+ depends on MMC_SDHCI && PLAT_S3C24XX -+ help -+ This selects the Secure Digital Host Controller Interface (SDHCI) -+ often referrered to as the HSMMC block in some of the Samsung S3C -+ range of SoC. -+ -+ If you have a controller with this interface, say Y or M here. -+ -+ If unsure, say N. -+ - config MMC_RICOH_MMC - tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" - depends on MMC_SDHCI_PCI -diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h -index f615308..570da2d 100644 ---- a/arch/arm/plat-s3c/include/plat/sdhci.h -+++ b/arch/arm/plat-s3c/include/plat/sdhci.h -@@ -29,6 +29,7 @@ struct mmc_ios; - * is necessary the controllers and/or GPIO blocks require the - * changing of driver-strength and other controls dependant on - * the card and speed of operation. -+ * sdhci_host: Pointer kept during init, allows presence change notification - * - * Initialisation data specific to either the machine or the platform - * for the device driver to use or call-back when configuring gpio or -@@ -45,8 +46,11 @@ struct s3c_sdhci_platdata { - void __iomem *regbase, - struct mmc_ios *ios, - struct mmc_card *card); -+ struct sdhci_host * sdhci_host; - }; - -+extern void sdhci_s3c_force_presence_change(struct platform_device *pdev); -+ - /** - * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. - * @pd: Platform data to register to device. ---- /dev/null -+++ b/arch/arm/mach-s3c2410/include/mach/mci.h -@@ -0,0 +1,13 @@ -+#ifndef _ARCH_MCI_H -+#define _ARCH_MCI_H -+ -+struct s3c24xx_mci_pdata { -+ unsigned int gpio_detect; -+ unsigned int gpio_wprotect; -+ unsigned long ocr_avail; -+ unsigned int do_dma; -+ void (*set_power)(unsigned char power_mode, -+ unsigned short vdd); -+}; -+ -+#endif /* _ARCH_NCI_H */ -diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c -index ac1f7ea..f7f8f31 100644 ---- a/arch/arm/mach-s3c2440/s3c2440.c -+++ b/arch/arm/mach-s3c2440/s3c2440.c -@@ -46,6 +46,9 @@ int __init s3c2440_init(void) - s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; - s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT; - -+ /* make sure SD/MMC driver can distinguish 2440 from 2410 */ -+ s3c_device_sdi.name = "s3c2440-sdi"; -+ - /* register our system device for everything else */ - - return sysdev_register(&s3c2440_sysdev); -diff --git a/arch/arm/mach-s3c2442/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c -index 4663bdc..9602d57 100644 ---- a/arch/arm/mach-s3c2442/s3c2442.c -+++ b/arch/arm/mach-s3c2442/s3c2442.c -@@ -21,6 +21,7 @@ - - #include - #include -+#include - - static struct sys_device s3c2442_sysdev = { - .cls = &s3c2442_sysclass, -@@ -30,5 +31,8 @@ int __init s3c2442_init(void) - { - printk("S3C2442: Initialising architecture\n"); - -+ /* make sure SD/MMC driver can distinguish 2440 from 2410 */ -+ s3c_device_sdi.name = "s3c2440-sdi"; -+ - return sysdev_register(&s3c2442_sysdev); - } -diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index cf153f6..c25f464 100644 ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -13,6 +13,7 @@ endif - obj-$(CONFIG_MMC_MXC) += mxcmmc.o - obj-$(CONFIG_MMC_SDHCI) += sdhci.o - obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o -+obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o - obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o - obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o - obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o -diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h -index ca1ba3d..7f80047 100644 ---- a/drivers/mmc/host/s3cmci.h -+++ b/drivers/mmc/host/s3cmci.h -@@ -8,6 +8,10 @@ - * published by the Free Software Foundation. - */ - -+ -+#include -+#include -+ - /* FIXME: DMA Resource management ?! */ - #define S3CMCI_DMA 0 - -@@ -68,7 +72,16 @@ struct s3cmci_host { - unsigned int ccnt, dcnt; - struct tasklet_struct pio_tasklet; - -+ /* -+ * Here's where we save the registers during suspend. Note that we skip -+ * SDIDATA, which is at different positions on 2410 and 2440, so -+ * there's no "+1" in the array size. -+ */ -+ u32 saved[(S3C2410_SDIIMSK-S3C2410_SDICON)/4]; -+ - #ifdef CONFIG_CPU_FREQ - struct notifier_block freq_transition; - #endif -+ -+ struct regulator *regulator; - }; -diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c -index 8c08cd7..b3cded4 100644 ---- a/drivers/mmc/host/s3cmci.c -+++ b/drivers/mmc/host/s3cmci.c -@@ -2,6 +2,7 @@ - * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver - * - * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel -+ * Copyright (C) 2007 Harald Welte - * - * Current driver maintained by Ben Dooks and Simtec Electronics - * Copyright (C) 2008 Simtec Electronics -@@ -25,9 +26,18 @@ - - #include - #include -+#include - - #include - -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ - #include "s3cmci.h" - - #define DRIVER_NAME "s3c-mci" -@@ -48,6 +58,9 @@ static const int dbgmap_err = dbg_fail; - static const int dbgmap_info = dbg_info | dbg_conf; - static const int dbgmap_debug = dbg_err | dbg_debug; - -+static int f_max = -1; /* override maximum frequency limit */ -+static int persist; /* keep interface alive across suspend/resume */ -+ - #define dbg(host, channels, args...) \ - do { \ - if (dbgmap_err & channels) \ -@@ -281,8 +294,11 @@ static void do_pio_read(struct s3cmci_host *host) - * an even multiple of 4. */ - if (fifo >= host->pio_bytes) - fifo = host->pio_bytes; -- else -+ else { - fifo -= fifo & 3; -+ if (!fifo) -+ break; -+ } - - host->pio_bytes -= fifo; - host->pio_count += fifo; -@@ -330,7 +346,7 @@ static void do_pio_write(struct s3cmci_host *host) - - to_ptr = host->base + host->sdidata; - -- while ((fifo = fifo_free(host)) > 3) { -+ while ((fifo = fifo_free(host))) { - if (!host->pio_bytes) { - res = get_data_buffer(host, &host->pio_bytes, - &host->pio_ptr); -@@ -354,8 +370,11 @@ static void do_pio_write(struct s3cmci_host *host) - * words, so round down to an even multiple of 4. */ - if (fifo >= host->pio_bytes) - fifo = host->pio_bytes; -- else -+ else { - fifo -= fifo & 3; -+ if (!fifo) -+ break; -+ } - - host->pio_bytes -= fifo; - host->pio_count += fifo; -@@ -374,7 +393,6 @@ static void pio_tasklet(unsigned long data) - { - struct s3cmci_host *host = (struct s3cmci_host *) data; - -- - disable_irq(host->irq); - - if (host->pio_active == XFER_WRITE) -@@ -615,7 +633,6 @@ irq_out: - - spin_unlock_irqrestore(&host->complete_lock, iflags); - return IRQ_HANDLED; -- - } - - /* -@@ -1027,6 +1044,7 @@ static void s3cmci_send_request(struct mmc_host *mmc) - dbg(host, dbg_err, "data prepare error %d\n", res); - cmd->error = res; - cmd->data->error = res; -+ cmd->data->error = -EIO; - - mmc_request_done(mmc, mrq); - return; -@@ -1264,10 +1282,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) - host->is2440 = is2440; - - host->pdata = pdev->dev.platform_data; -- if (!host->pdata) { -- pdev->dev.platform_data = &s3cmci_def_pdata; -+ if (!host->pdata) - host->pdata = &s3cmci_def_pdata; -- } - - spin_lock_init(&host->complete_lock); - tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); -@@ -1380,6 +1396,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) - mmc->f_min = host->clk_rate / (host->clk_div * 256); - mmc->f_max = host->clk_rate / host->clk_div; - -+ if (f_max >= 0) { -+ unsigned f = f_max; -+ -+ if (f < mmc->f_min) -+ f = mmc->f_min; -+ if (mmc->f_max > f) { -+ dev_info(&pdev->dev, "f_max lowered from %u to %u Hz\n", -+ mmc->f_max, f); -+ mmc->f_max = f; -+ } -+ } -+ - if (host->pdata->ocr_avail) - mmc->ocr_avail = host->pdata->ocr_avail; - -@@ -1492,18 +1520,60 @@ static int __devinit s3cmci_2440_probe(struct platform_device *dev) - - #ifdef CONFIG_PM - -+static int save_regs(struct mmc_host *mmc) -+{ -+ struct s3cmci_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ unsigned from; -+ u32 *to = host->saved; -+ -+ mmc_flush_scheduled_work(); -+ -+ local_irq_save(flags); -+ for (from = S3C2410_SDICON; from != S3C2410_SDIIMSK+4; from += 4) -+ if (from != host->sdidata) -+ *to++ = readl(host->base + from); -+ BUG_ON(to-host->saved != ARRAY_SIZE(host->saved)); -+ local_irq_restore(flags); -+ -+ return 0; -+} -+ -+static int restore_regs(struct mmc_host *mmc) -+{ -+ struct s3cmci_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ unsigned to; -+ u32 *from = host->saved; -+ -+ /* -+ * Before we begin with the necromancy, make sure we don't -+ * inadvertently start something we'll regret microseconds later. -+ */ -+ from[S3C2410_SDICMDCON - S3C2410_SDICON] = 0; -+ -+ local_irq_save(flags); -+ for (to = S3C2410_SDICON; to != S3C2410_SDIIMSK+4; to += 4) -+ if (to != host->sdidata) -+ writel(*from++, host->base + to); -+ BUG_ON(from-host->saved != ARRAY_SIZE(host->saved)); -+ local_irq_restore(flags); -+ -+ return 0; -+} -+ - static int s3cmci_suspend(struct platform_device *dev, pm_message_t state) - { - struct mmc_host *mmc = platform_get_drvdata(dev); - -- return mmc_suspend_host(mmc, state); -+ return persist ? save_regs(mmc) : mmc_suspend_host(mmc, state); - } - - static int s3cmci_resume(struct platform_device *dev) - { - struct mmc_host *mmc = platform_get_drvdata(dev); - -- return mmc_resume_host(mmc); -+ return persist ? restore_regs(mmc) : mmc_resume_host(mmc); - } - - #else /* CONFIG_PM */ -@@ -1561,9 +1631,13 @@ static void __exit s3cmci_exit(void) - module_init(s3cmci_init); - module_exit(s3cmci_exit); - -+module_param(f_max, int, 0644); -+module_param(persist, int, 0644); -+ - MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); - MODULE_LICENSE("GPL v2"); - MODULE_AUTHOR("Thomas Kleffel , Ben Dooks "); - MODULE_ALIAS("platform:s3c2410-sdi"); - MODULE_ALIAS("platform:s3c2412-sdi"); - MODULE_ALIAS("platform:s3c2440-sdi"); -+ -