Commit 63159f81 authored by Russell King's avatar Russell King

[PCMCIA] Update SA11xx PCMCIA support for recent changes.

Re-enable the suspend and resume methods for SA11xx PCMCIA devices,
and update the initialisation/cleanup code for Dominik's recent
changes.
parent 9014144e
......@@ -106,8 +106,8 @@ static struct device_driver sa11x0_pcmcia_driver = {
.remove = sa11xx_drv_pcmcia_remove,
.name = "sa11x0-pcmcia",
.bus = &platform_bus_type,
/* .suspend = pcmcia_socket_dev_suspend,*/
/* .resume = pcmcia_socket_dev_resume,*/
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
};
/* sa11x0_pcmcia_init()
......
......@@ -178,8 +178,8 @@ static struct sa1111_driver pcmcia_driver = {
.bus = &sa1111_bus_type,
.probe = pcmcia_probe,
.remove = __devexit_p(pcmcia_remove),
/* .suspend = pcmcia_socket_dev_suspend,*/
/* .resume = pcmcia_socket_dev_resume,*/
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
},
.devid = SA1111_DEVID_PCMCIA,
};
......
......@@ -800,9 +800,13 @@ static const char *skt_names[] = {
"PCMCIA socket 1",
};
struct skt_dev_info {
int nskt;
};
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct pcmcia_socket_class_data *cls;
struct skt_dev_info *sinfo;
unsigned int cpu_clock;
int ret, i;
......@@ -813,19 +817,14 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
if (!ops->socket_get_timing)
ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
cls = kmalloc(sizeof(struct pcmcia_socket_class_data), GFP_KERNEL);
if (!cls) {
sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
if (!sinfo) {
ret = -ENOMEM;
goto out;
}
memset(cls, 0, sizeof(struct pcmcia_socket_class_data));
cls->ops = &sa11xx_pcmcia_operations;
cls->nsock = nr;
cls->class_dev.class = &pcmcia_socket_class;
cls->class_dev.dev = dev;
strlcpy(cls->class_dev.class_id, dev->bus_id, BUS_ID_SIZE);
class_set_devdata(&cls->class_dev, cls);
memset(sinfo, 0, sizeof(struct skt_dev_info));
sinfo->nskt = nr;
cpu_clock = cpufreq_get(0);
......@@ -836,6 +835,9 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
memset(skt, 0, sizeof(*skt));
skt->socket.ss_entry = &sa11xx_pcmcia_operations;
skt->socket.dev.dev = dev;
INIT_WORK(&skt->work, sa1100_pcmcia_task_handler, skt);
init_timer(&skt->poll_timer);
......@@ -902,18 +904,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
goto out_err_6;
skt->status = sa1100_pcmcia_skt_state(skt);
ret = pcmcia_register_socket(&skt->socket);
if (ret)
goto out_err_7;
WARN_ON(skt->socket.sock != i);
add_timer(&skt->poll_timer);
}
dev_set_drvdata(dev, cls);
class_device_register(&cls->class_dev);
dev_set_drvdata(dev, sinfo);
return 0;
do {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
out_err_7:
flush_scheduled_work();
ops->hw_shutdown(skt);
......@@ -931,7 +941,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, in
i--;
} while (i > 0);
kfree(cls);
kfree(sinfo);
out:
return ret;
......@@ -940,20 +950,22 @@ EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
int sa11xx_drv_pcmcia_remove(struct device *dev)
{
struct pcmcia_socket_class_data *cls = dev_get_drvdata(dev);
struct skt_dev_info *sinfo = dev_get_drvdata(dev);
int i;
class_device_unregister(&cls->class_dev);
dev_set_drvdata(dev, NULL);
for (i = 0; i < cls->nsock; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(cls->sock_offset + i);
skt->ops->hw_shutdown(skt);
for (i = 0; i < sinfo->nskt; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work();
skt->ops->hw_shutdown(skt);
sa1100_pcmcia_config_skt(skt, &dead_socket);
iounmap(skt->virt_io);
......@@ -964,7 +976,7 @@ int sa11xx_drv_pcmcia_remove(struct device *dev)
release_resource(&skt->res_skt);
}
kfree(cls);
kfree(sinfo);
return 0;
}
......
......@@ -44,6 +44,8 @@ struct pcmcia_state {
* use when responding to a Card Services query of some kind.
*/
struct sa1100_pcmcia_socket {
struct pcmcia_socket socket;
/*
* Info from low level handler
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment