Merge master.kernel.org:/home/rmk/linux-2.6-arm
[safe/jmp/linux-2.6] / drivers / pcmcia / au1000_generic.c
index 5387de6..0208870 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/notifier.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
@@ -71,7 +72,7 @@ extern struct au1000_pcmcia_socket au1000_pcmcia_socket[];
 u32 *pcmcia_base_vaddrs[2];
 extern const unsigned long mips_io_port_base;
 
-DECLARE_MUTEX(pcmcia_sockets_lock);
+static DEFINE_MUTEX(pcmcia_sockets_lock);
 
 static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
        au1x_board_init,
@@ -291,7 +292,7 @@ au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
                skt->spd_io[map->map] = speed;
        }
 
-       map->start=(ioaddr_t)(u32)skt->virt_io;
+       map->start=(unsigned int)(u32)skt->virt_io;
        map->stop=map->start+MAP_SIZE;
        return 0;
 
@@ -372,7 +373,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
                skt->socket.resource_ops = &pccard_static_ops;
                skt->socket.ops = &au1x00_pcmcia_operations;
                skt->socket.owner = ops->owner;
-               skt->socket.dev.dev = dev;
+               skt->socket.dev.parent = dev;
 
                init_timer(&skt->poll_timer);
                skt->poll_timer.function = au1x00_pcmcia_poll_event;
@@ -449,6 +450,16 @@ out_err:
                del_timer_sync(&skt->poll_timer);
                pcmcia_unregister_socket(&skt->socket);
                flush_scheduled_work();
+               if (i == 0) {
+                       iounmap(skt->virt_io + (u32)mips_io_port_base);
+                       skt->virt_io = NULL;
+               }
+#ifndef CONFIG_MIPS_XXS1500
+               else {
+                       iounmap(skt->virt_io + (u32)mips_io_port_base);
+                       skt->virt_io = NULL;
+               }
+#endif
                ops->hw_shutdown(skt);
 
        }
@@ -457,13 +468,13 @@ out:
        return ret;
 }
 
-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
 {
-       struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+       struct skt_dev_info *sinfo = platform_get_drvdata(dev);
        int i;
 
-       down(&pcmcia_sockets_lock);
-       dev_set_drvdata(dev, NULL);
+       mutex_lock(&pcmcia_sockets_lock);
+       platform_set_drvdata(dev, NULL);
 
        for (i = 0; i < sinfo->nskt; i++) {
                struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -478,7 +489,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
        }
 
        kfree(sinfo);
-       up(&pcmcia_sockets_lock);
+       mutex_unlock(&pcmcia_sockets_lock);
        return 0;
 }
 
@@ -487,28 +498,40 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
  * PCMCIA "Driver" API
  */
 
-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
 {
        int i, ret = -ENODEV;
 
-       down(&pcmcia_sockets_lock);
+       mutex_lock(&pcmcia_sockets_lock);
        for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
-               ret = au1x00_pcmcia_hw_init[i](dev);
+               ret = au1x00_pcmcia_hw_init[i](&dev->dev);
                if (ret == 0)
                        break;
        }
-       up(&pcmcia_sockets_lock);
+       mutex_unlock(&pcmcia_sockets_lock);
        return ret;
 }
 
+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+                                    pm_message_t state)
+{
+       return pcmcia_socket_dev_suspend(&dev->dev);
+}
+
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+       return pcmcia_socket_dev_resume(&dev->dev);
+}
 
-static struct device_driver au1x00_pcmcia_driver = {
+static struct platform_driver au1x00_pcmcia_driver = {
+       .driver = {
+               .name           = "au1x00-pcmcia",
+               .owner          = THIS_MODULE,
+       },
        .probe          = au1x00_drv_pcmcia_probe,
        .remove         = au1x00_drv_pcmcia_remove,
-       .name           = "au1x00-pcmcia",
-       .bus            = &platform_bus_type,
-       .suspend        = pcmcia_socket_dev_suspend,
-       .resume         = pcmcia_socket_dev_resume,
+       .suspend        = au1x00_drv_pcmcia_suspend,
+       .resume         = au1x00_drv_pcmcia_resume,
 };
 
 
@@ -522,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = {
 static int __init au1x00_pcmcia_init(void)
 {
        int error = 0;
-       if ((error = driver_register(&au1x00_pcmcia_driver)))
-               return error;
+       error = platform_driver_register(&au1x00_pcmcia_driver);
        return error;
 }
 
@@ -533,7 +555,7 @@ static int __init au1x00_pcmcia_init(void)
  */
 static void __exit au1x00_pcmcia_exit(void)
 {
-       driver_unregister(&au1x00_pcmcia_driver);
+       platform_driver_unregister(&au1x00_pcmcia_driver);
 }
 
 module_init(au1x00_pcmcia_init);