#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/config.h>
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#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>
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,
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;
int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct skt_dev_info *sinfo;
+ struct au1000_pcmcia_socket *skt;
int ret, i;
sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
* Initialise the per-socket structure.
*/
for (i = 0; i < nr; i++) {
- struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+ skt = PCMCIA_SOCKET(i);
memset(skt, 0, sizeof(*skt));
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;
dev_set_drvdata(dev, sinfo);
return 0;
- do {
- struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+out_err:
+ flush_scheduled_work();
+ ops->hw_shutdown(skt);
+ while (i-- > 0) {
+ skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
-out_err:
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);
- i--;
- } while (i > 0);
+ }
kfree(sinfo);
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);
}
kfree(sinfo);
- up(&pcmcia_sockets_lock);
+ mutex_unlock(&pcmcia_sockets_lock);
return 0;
}
* 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, state);
+}
+
+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,
};
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;
}
*/
static void __exit au1x00_pcmcia_exit(void)
{
- driver_unregister(&au1x00_pcmcia_driver);
+ platform_driver_unregister(&au1x00_pcmcia_driver);
}
module_init(au1x00_pcmcia_init);