[MTD] Use mutex instead of semaphore in dataflash driver
[linux-2.6.git] / drivers / mtd / devices / docprobe.c
index 197d670..78872c3 100644 (file)
@@ -4,22 +4,22 @@
 /* (C) 1999 Machine Vision Holdings, Inc.                      */
 /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>         */
 
-/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $      */
+/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $   */
 
 
 
 /* DOC_PASSIVE_PROBE:
-   In order to ensure that the BIOS checksum is correct at boot time, and 
-   hence that the onboard BIOS extension gets executed, the DiskOnChip 
-   goes into reset mode when it is read sequentially: all registers 
-   return 0xff until the chip is woken up again by writing to the 
-   DOCControl register. 
-
-   Unfortunately, this means that the probe for the DiskOnChip is unsafe, 
-   because one of the first things it does is write to where it thinks 
-   the DOCControl register should be - which may well be shared memory 
-   for another device. I've had machines which lock up when this is 
-   attempted. Hence the possibility to do a passive probe, which will fail 
+   In order to ensure that the BIOS checksum is correct at boot time, and
+   hence that the onboard BIOS extension gets executed, the DiskOnChip
+   goes into reset mode when it is read sequentially: all registers
+   return 0xff until the chip is woken up again by writing to the
+   DOCControl register.
+
+   Unfortunately, this means that the probe for the DiskOnChip is unsafe,
+   because one of the first things it does is write to where it thinks
+   the DOCControl register should be - which may well be shared memory
+   for another device. I've had machines which lock up when this is
+   attempted. Hence the possibility to do a passive probe, which will fail
    to detect a chip in reset mode, but is at least guaranteed not to lock
    the machine.
 
 
    The old Millennium-only driver has been retained just in case there
    are problems with the new code. If the combined driver doesn't work
-   for you, you can try the old one by undefining DOC_SINGLE_DRIVER 
+   for you, you can try the old one by undefining DOC_SINGLE_DRIVER
    below and also enabling it in your configuration. If this fixes the
-   problems, please send a report to the MTD mailing list at 
+   problems, please send a report to the MTD mailing list at
    <linux-mtd@lists.infradead.org>.
 */
 #define DOC_SINGLE_DRIVER
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/errno.h>
@@ -68,16 +67,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
 static unsigned long __initdata doc_locations[] = {
 #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
 #ifdef CONFIG_MTD_DOCPROBE_HIGH
-       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 
+       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
        0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
-       0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 
-       0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 
+       0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
+       0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
        0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
 #else /*  CONFIG_MTD_DOCPROBE_HIGH */
-       0xc8000, 0xca000, 0xcc000, 0xce000, 
+       0xc8000, 0xca000, 0xcc000, 0xce000,
        0xd0000, 0xd2000, 0xd4000, 0xd6000,
-       0xd8000, 0xda000, 0xdc000, 0xde000, 
-       0xe0000, 0xe2000, 0xe4000, 0xe6000, 
+       0xd8000, 0xda000, 0xdc000, 0xde000,
+       0xe0000, 0xe2000, 0xe4000, 0xe6000,
        0xe8000, 0xea000, 0xec000, 0xee000,
 #endif /*  CONFIG_MTD_DOCPROBE_HIGH */
 #elif defined(__PPC__)
@@ -111,35 +110,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
                return 0;
 #endif /* CONFIG_MTD_DOCPROBE_55AA */
 
-#ifndef DOC_PASSIVE_PROBE      
+#ifndef DOC_PASSIVE_PROBE
        /* It's not possible to cleanly detect the DiskOnChip - the
         * bootup procedure will put the device into reset mode, and
         * it's not possible to talk to it without actually writing
         * to the DOCControl register. So we store the current contents
         * of the DOCControl register's location, in case we later decide
         * that it's not a DiskOnChip, and want to put it back how we
-        * found it. 
+        * found it.
         */
        tmp2 = ReadDOC(window, DOCControl);
-       
+
        /* Reset the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
                 window, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
                 window, DOCControl);
-       
+
        /* Enable the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
                 window, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 
+       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
                 window, DOCControl);
-#endif /* !DOC_PASSIVE_PROBE */        
+#endif /* !DOC_PASSIVE_PROBE */
 
        /* We need to read the ChipID register four times. For some
           newer DiskOnChip 2000 units, the first three reads will
           return the DiskOnChip Millennium ident. Don't ask. */
        ChipID = ReadDOC(window, ChipID);
-  
+
        switch (ChipID) {
        case DOC_ChipID_Doc2k:
                /* Check the TOGGLE bit in the ECC register */
@@ -149,7 +148,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
                if (tmp != tmpb && tmp == tmpc)
                                return ChipID;
                break;
-               
+
        case DOC_ChipID_DocMil:
                /* Check for the new 2000 with Millennium ASIC */
                ReadDOC(window, ChipID);
@@ -164,7 +163,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
                if (tmp != tmpb && tmp == tmpc)
                                return ChipID;
                break;
-               
+
        case DOC_ChipID_DocMilPlus16:
        case DOC_ChipID_DocMilPlus32:
        case 0:
@@ -179,7 +178,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
                        DOC_MODE_BDECT;
                WriteDOC(tmp, window, Mplus_DOCControl);
                WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-       
+
                mdelay(1);
                /* Enable the DiskOnChip ASIC */
                tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
@@ -187,7 +186,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
                WriteDOC(tmp, window, Mplus_DOCControl);
                WriteDOC(~tmp, window, Mplus_CtrlConfirm);
                mdelay(1);
-#endif /* !DOC_PASSIVE_PROBE */        
+#endif /* !DOC_PASSIVE_PROBE */
 
                ChipID = ReadDOC(window, ChipID);
 
@@ -227,10 +226,14 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
        WriteDOC(tmp2, window, DOCControl);
 #endif
        return 0;
-}   
+}
 
 static int docfound;
 
+extern void DoC2k_init(struct mtd_info *);
+extern void DoCMil_init(struct mtd_info *);
+extern void DoCMilPlus_init(struct mtd_info *);
+
 static void __init DoC_Probe(unsigned long physadr)
 {
        void __iomem *docptr;
@@ -239,15 +242,13 @@ static void __init DoC_Probe(unsigned long physadr)
        int ChipID;
        char namebuf[15];
        char *name = namebuf;
-       char *im_funcname = NULL;
-       char *im_modname = NULL;
        void (*initroutine)(struct mtd_info *) = NULL;
 
        docptr = ioremap(physadr, DOC_IOREMAP_LEN);
-       
+
        if (!docptr)
                return;
-       
+
        if ((ChipID = doccheck(docptr, physadr))) {
                if (ChipID == DOC_ChipID_Doc2kTSOP) {
                        /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
@@ -263,9 +264,9 @@ static void __init DoC_Probe(unsigned long physadr)
                        iounmap(docptr);
                        return;
                }
-               
+
                this = (struct DiskOnChip *)(&mtd[1]);
-               
+
                memset((char *)mtd,0, sizeof(struct mtd_info));
                memset((char *)this, 0, sizeof(struct DiskOnChip));
 
@@ -278,41 +279,33 @@ static void __init DoC_Probe(unsigned long physadr)
                switch(ChipID) {
                case DOC_ChipID_Doc2kTSOP:
                        name="2000 TSOP";
-                       im_funcname = "DoC2k_init";
-                       im_modname = "doc2000";
+                       initroutine = symbol_request(DoC2k_init);
                        break;
-                       
+
                case DOC_ChipID_Doc2k:
                        name="2000";
-                       im_funcname = "DoC2k_init";
-                       im_modname = "doc2000";
+                       initroutine = symbol_request(DoC2k_init);
                        break;
-                       
+
                case DOC_ChipID_DocMil:
                        name="Millennium";
 #ifdef DOC_SINGLE_DRIVER
-                       im_funcname = "DoC2k_init";
-                       im_modname = "doc2000";
+                       initroutine = symbol_request(DoC2k_init);
 #else
-                       im_funcname = "DoCMil_init";
-                       im_modname = "doc2001";
+                       initroutine = symbol_request(DoCMil_init);
 #endif /* DOC_SINGLE_DRIVER */
                        break;
 
                case DOC_ChipID_DocMilPlus16:
                case DOC_ChipID_DocMilPlus32:
                        name="MillenniumPlus";
-                       im_funcname = "DoCMilPlus_init";
-                       im_modname = "doc2001plus";
+                       initroutine = symbol_request(DoCMilPlus_init);
                        break;
                }
 
-               if (im_funcname)
-                       initroutine = inter_module_get_request(im_funcname, im_modname);
-
                if (initroutine) {
                        (*initroutine)(mtd);
-                       inter_module_put(im_funcname);
+                       symbol_put_addr(initroutine);
                        return;
                }
                printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
@@ -331,7 +324,7 @@ static void __init DoC_Probe(unsigned long physadr)
 static int __init init_doc(void)
 {
        int i;
-       
+
        if (doc_config_location) {
                printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
                DoC_Probe(doc_config_location);