Signed-off-by: Lennert Buytenhek <[EMAIL PROTECTED]>

Index: linux-2.6.20/drivers/pcmcia/Kconfig
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/Kconfig
+++ linux-2.6.20/drivers/pcmcia/Kconfig
@@ -197,6 +197,12 @@ config PCMCIA_AU1X00
        tristate "Au1x00 pcmcia support"
        depends on SOC_AU1X00 && PCMCIA
 
+config PCMCIA_EP93XX
+       tristate "EP93xx support"
+       depends on ARM && ARCH_EP93XX && PCMCIA
+       help
+         Say Y here to include support for the EP93xx PCMCIA controller
+
 config PCMCIA_SA1100
        tristate "SA1100 support"
        depends on ARM && ARCH_SA1100 && PCMCIA
Index: linux-2.6.20/drivers/pcmcia/Makefile
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/Makefile
+++ linux-2.6.20/drivers/pcmcia/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_I82092)                          += i82092.o
 obj-$(CONFIG_TCIC)                             += tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)                      += m8xx_pcmcia.o
 obj-$(CONFIG_HD64465_PCMCIA)                   += hd64465_ss.o
+obj-$(CONFIG_PCMCIA_EP93XX)                    += ep93xx_core.o ep93xx_cs.o
 obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_core.o sa1100_cs.o
 obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_core.o sa1111_cs.o
 obj-$(CONFIG_PCMCIA_PXA2XX)                     += pxa2xx_core.o pxa2xx_cs.o
@@ -38,6 +39,7 @@ obj-$(CONFIG_PCMCIA_VRC4173)                  += vrc417
 obj-$(CONFIG_OMAP_CF)                          += omap_cf.o
 obj-$(CONFIG_AT91_CF)                          += at91_cf.o
 
+ep93xx_core-y                                  += soc_common.o ep93xx_base.o
 sa11xx_core-y                                  += soc_common.o sa11xx_base.o
 pxa2xx_core-y                                  += soc_common.o pxa2xx_base.o
 
Index: linux-2.6.20/drivers/pcmcia/ep93xx_base.c
===================================================================
--- /dev/null
+++ linux-2.6.20/drivers/pcmcia/ep93xx_base.c
@@ -0,0 +1,194 @@
+/*======================================================================
+
+  Device driver for the PCMCIA control functionality of EP93xx
+  microprocessors.  Derived from pxa2xx_base.c
+
+    The contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL")
+
+    (c) Ian Molton ([EMAIL PROTECTED]) 2003
+    (c) Stefan Eletzhofer ([EMAIL PROTECTED]) 2003,4
+    (c) Robert Whaley ([EMAIL PROTECTED]) 2005
+
+    derived from sa11xx_base.c
+
+     Portions created by John G. Dorsey are
+     Copyright (C) 1999 John G. Dorsey.
+
+  ======================================================================*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+#include "soc_common.h"
+
+#define PC1ATTRIB              (EP93XX_PCMCIA_CONTROLLER_BASE + 0x20)
+#define PC1COMMON              (EP93XX_PCMCIA_CONTROLLER_BASE + 0x24)
+#define PC1IO                  (EP93XX_PCMCIA_CONTROLLER_BASE + 0x28)
+#define PC16BITSWIDE           0x80000000
+
+#define MIN(a,b)               ((a) > (b) ? (b) : (a))
+
+#define MCXX_SETUP_MAX         0xff
+#define MCXX_ASST_MAX          0xff
+#define MCXX_HOLD_MAX          0x0f
+
+#define MCXX_SETUP_SHIFT       0
+#define MCXX_ASST_SHIFT                16
+#define MCXX_HOLD_SHIFT                8
+
+
+static inline u_int ep93xx_mcxx_hold(u_int pcmcia_cycle_ns,
+                                    u_int hclk_10khz)
+{
+       u_int code = pcmcia_cycle_ns * hclk_10khz;
+       return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static inline u_int ep93xx_mcxx_asst(u_int pcmcia_cycle_ns,
+                                    u_int hclk_10khz)
+{
+       u_int code = pcmcia_cycle_ns * hclk_10khz;
+       return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static inline u_int ep93xx_mcxx_setup(u_int pcmcia_cycle_ns,
+                                     u_int hclk_10khz)
+{
+       u_int code = pcmcia_cycle_ns * hclk_10khz;
+       return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
+}
+
+static int ep93xx_pcmcia_set_mcmem( int sock, int speed, int clock )
+{
+        writel(PC16BITSWIDE
+            | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << 
MCXX_SETUP_SHIFT)
+            | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << 
MCXX_ASST_SHIFT)
+            | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << 
MCXX_HOLD_SHIFT),
+            PC1COMMON);
+
+       return 0;
+}
+
+static int ep93xx_pcmcia_set_mcio( int sock, int speed, int clock )
+{
+        writel(PC16BITSWIDE
+            | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << 
MCXX_SETUP_SHIFT)
+            | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << 
MCXX_ASST_SHIFT)
+            | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << 
MCXX_HOLD_SHIFT),
+            PC1IO);
+
+       return 0;
+}
+
+static int ep93xx_pcmcia_set_mcatt( int sock, int speed, int clock )
+{
+        writel(PC16BITSWIDE
+            | (MIN(ep93xx_mcxx_setup(speed, clock), MCXX_SETUP_MAX) << 
MCXX_SETUP_SHIFT)
+            | (MIN(ep93xx_mcxx_asst(speed, clock), MCXX_ASST_MAX) << 
MCXX_ASST_SHIFT)
+            | (MIN(ep93xx_mcxx_hold(speed, clock), MCXX_HOLD_MAX) << 
MCXX_HOLD_SHIFT),
+            PC1ATTRIB);
+
+       return 0;
+}
+
+static int ep93xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int 
clk)
+{
+       struct soc_pcmcia_timing timing;
+       int sock = skt->nr;
+
+       soc_common_pcmcia_get_timing(skt, &timing);
+
+       ep93xx_pcmcia_set_mcmem(sock, timing.mem, clk);
+       ep93xx_pcmcia_set_mcatt(sock, timing.attr, clk);
+       ep93xx_pcmcia_set_mcio(sock, timing.io, clk);
+
+       return 0;
+}
+
+static int ep93xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
+{
+       unsigned int hclk;
+
+       /* for now just hard code hclk to 100Mhz (in 10khz units)*/
+       hclk = 10000;
+
+       return ep93xx_pcmcia_set_mcxx(skt, hclk);
+}
+
+
+static int ep93xx_drv_pcmcia_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct pcmcia_low_level *ops;
+       int first, nr;
+
+       if (pdev->dev.platform_data == NULL)
+               return -ENODEV;
+
+       ops = (struct pcmcia_low_level *)pdev->dev.platform_data;
+       first = ops->first;
+       nr = ops->nr;
+
+       /* Provide our EP93xx specific timing routines. */
+       ops->set_timing  = ep93xx_pcmcia_set_timing;
+
+       ret = soc_common_drv_pcmcia_probe(&pdev->dev, ops, first, nr);
+
+       return ret;
+}
+
+static int ep93xx_drv_pcmcia_remove(struct platform_device *pdev)
+{
+       return soc_common_drv_pcmcia_remove(&pdev->dev);
+}
+
+static int ep93xx_drv_pcmcia_suspend(struct platform_device *pdev, 
pm_message_t state)
+{
+       return pcmcia_socket_dev_suspend(&pdev->dev, state);
+}
+
+static int ep93xx_drv_pcmcia_resume(struct platform_device *pdev)
+{
+       return pcmcia_socket_dev_resume(&pdev->dev);
+}
+
+static struct platform_driver ep93xx_pcmcia_driver = {
+       .probe          = ep93xx_drv_pcmcia_probe,
+       .remove         = ep93xx_drv_pcmcia_remove,
+       .suspend        = ep93xx_drv_pcmcia_suspend,
+       .resume         = ep93xx_drv_pcmcia_resume,
+       .driver         = {
+               .name   = "ep93xx-pcmcia",
+       },
+};
+
+static int __init ep93xx_pcmcia_init(void)
+{
+       return platform_driver_register(&ep93xx_pcmcia_driver);
+}
+
+static void __exit ep93xx_pcmcia_exit(void)
+{
+       platform_driver_unregister(&ep93xx_pcmcia_driver);
+}
+
+fs_initcall(ep93xx_pcmcia_init);
+module_exit(ep93xx_pcmcia_exit);
+
+MODULE_AUTHOR("Robert Whaley <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: EP93xx core socket driver");
+MODULE_LICENSE("GPL");
Index: linux-2.6.20/drivers/pcmcia/soc_common.c
===================================================================
--- linux-2.6.20.orig/drivers/pcmcia/soc_common.c
+++ linux-2.6.20/drivers/pcmcia/soc_common.c
@@ -49,6 +49,9 @@
 #include "soc_common.h"
 
 /* FIXME: platform dependent resource declaration has to move out of this file 
*/
+#ifdef CONFIG_ARCH_EP93XX
+#include <asm/arch/pcmcia.h>
+#endif
 #ifdef CONFIG_ARCH_PXA
 #include <asm/arch/pxa-regs.h>
 #endif
Index: linux-2.6.20/include/asm-arm/arch-ep93xx/pcmcia.h
===================================================================
--- /dev/null
+++ linux-2.6.20/include/asm-arm/arch-ep93xx/pcmcia.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-arm/arch-ep93xx/pcmcia.h
+ */
+
+#ifndef __ASM_ARCH_PCMCIA_H
+#define __ASM_ARCH_PCMCIA_H
+
+#define _PCMCIA(slt)           (0x40000000 + ((slt) ? 0x10000000 : 0))
+#define _PCMCIAIO(slt)         _PCMCIA(slt)
+#define _PCMCIAAttr(slt)       (_PCMCIA(slt) + 0x08000000)
+#define _PCMCIAMem(slt)                (_PCMCIA(slt) + 0x0c000000)
+
+#define PCMCIASp               0x10000000
+#define PCMCIAIOSp             0x04000000
+#define PCMCIAAttrSp           0x04000000
+#define PCMCIAMemSp            0x04000000
+
+
+#endif

_______________________________________________
Linux PCMCIA reimplementation list
http://lists.infradead.org/mailman/listinfo/linux-pcmcia

Reply via email to