Commit d9dfbbac authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

driver core: fix up the pcmcia code to work with the new class changes.

This isn't the optimal fix, but things still work properly for me with
my hardware and this patch.

Dominik Brodowski has stated he will be fixing up this code a lot more
after the class changes are in the main tree.
parent d7068318
......@@ -313,9 +313,9 @@ static void parse_events(void *info, u_int events);
/**
* pcmcia_register_socket - add a new pcmcia socket device
*/
int pcmcia_register_socket(struct device *dev)
int pcmcia_register_socket(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = to_class_data(dev);
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
socket_info_t *s_info;
unsigned int i, j;
......@@ -375,9 +375,9 @@ int pcmcia_register_socket(struct device *dev)
/**
* pcmcia_unregister_socket - remove a pcmcia socket device
*/
void pcmcia_unregister_socket(struct device *dev)
void pcmcia_unregister_socket(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = to_class_data(dev);
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
unsigned int i;
int j, socket = -1;
client_t *client;
......@@ -751,9 +751,8 @@ void pcmcia_resume_socket (socket_info_t *s)
}
int pcmcia_socket_dev_suspend(struct device * dev, u32 state, u32 level)
int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level)
{
struct pcmcia_socket_class_data *cls_d = to_class_data(dev);
socket_info_t *s;
int i;
......@@ -771,9 +770,8 @@ int pcmcia_socket_dev_suspend(struct device * dev, u32 state, u32 level)
}
EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
int pcmcia_socket_dev_resume(struct device * dev, u32 level)
int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level)
{
struct pcmcia_socket_class_data *cls_d = to_class_data(dev);
socket_info_t *s;
int i;
......@@ -2423,20 +2421,25 @@ EXPORT_SYMBOL(pcmcia_unregister_socket);
EXPORT_SYMBOL(pcmcia_suspend_socket);
EXPORT_SYMBOL(pcmcia_resume_socket);
struct device_class pcmcia_socket_class = {
struct class pcmcia_socket_class = {
.name = "pcmcia_socket",
.add_device = &pcmcia_register_socket,
.remove_device = &pcmcia_unregister_socket,
};
EXPORT_SYMBOL(pcmcia_socket_class);
static struct class_interface pcmcia_socket = {
.class = &pcmcia_socket_class,
.add = &pcmcia_register_socket,
.remove = &pcmcia_unregister_socket,
};
static int __init init_pcmcia_cs(void)
{
printk(KERN_INFO "%s\n", release);
printk(KERN_INFO " %s\n", options);
DEBUG(0, "%s\n", version);
devclass_register(&pcmcia_socket_class);
class_register(&pcmcia_socket_class);
class_interface_register(&pcmcia_socket);
#ifdef CONFIG_PROC_FS
proc_pccard = proc_mkdir("pccard", proc_bus);
#endif
......@@ -2453,7 +2456,8 @@ static void __exit exit_pcmcia_cs(void)
}
#endif
release_resource_db();
devclass_unregister(&pcmcia_socket_class);
class_interface_unregister(&pcmcia_socket);
class_unregister(&pcmcia_socket_class);
}
subsys_initcall(init_pcmcia_cs);
......
......@@ -957,9 +957,9 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, unsigned int sock
}
static int __devinit pcmcia_bus_add_socket_dev(struct device *dev)
static int pcmcia_bus_add_socket_dev(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = dev->class_data;
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
unsigned int i;
unsigned int ret = 0;
......@@ -968,45 +968,42 @@ static int __devinit pcmcia_bus_add_socket_dev(struct device *dev)
down_write(&bus_socket_list_rwsem);
for (i = 0; i < cls_d->nsock; i++)
ret += pcmcia_bus_add_socket(dev, i);
ret += pcmcia_bus_add_socket(class_dev->dev, i);
up_write(&bus_socket_list_rwsem);
return ret;
}
static int __devexit pcmcia_bus_remove_socket_dev(struct device *dev)
static void pcmcia_bus_remove_socket_dev(struct class_device *class_dev)
{
struct pcmcia_socket_class_data *cls_d = dev->class_data;
struct pcmcia_socket_class_data *cls_d = class_get_devdata(class_dev);
struct list_head *list_loop;
struct list_head *tmp_storage;
if (!cls_d)
return -ENODEV;
return;
flush_scheduled_work();
down_write(&bus_socket_list_rwsem);
list_for_each_safe(list_loop, tmp_storage, &bus_socket_list) {
struct pcmcia_bus_socket *bus_sock = container_of(list_loop, struct pcmcia_bus_socket, socket_list);
if (bus_sock->socket_dev == dev) {
if (bus_sock->socket_dev == class_dev->dev) {
pcmcia_deregister_client(bus_sock->handle);
list_del(&bus_sock->socket_list);
kfree(bus_sock);
}
}
up_write(&bus_socket_list_rwsem);
return 0;
return;
}
/* the pcmcia_bus_interface is used to handle pcmcia socket devices */
static struct device_interface pcmcia_bus_interface = {
.name = "pcmcia-bus",
.devclass = &pcmcia_socket_class,
.add_device = &pcmcia_bus_add_socket_dev,
.remove_device = __devexit_p(&pcmcia_bus_remove_socket_dev),
.kset = { .subsys = &pcmcia_socket_class.subsys, },
.devnum = 0,
static struct class_interface pcmcia_bus_interface = {
.class = &pcmcia_socket_class,
.add = &pcmcia_bus_add_socket_dev,
.remove = &pcmcia_bus_remove_socket_dev,
};
......@@ -1021,7 +1018,7 @@ static int __init init_pcmcia_bus(void)
int i;
bus_register(&pcmcia_bus_type);
interface_register(&pcmcia_bus_interface);
class_interface_register(&pcmcia_bus_interface);
/* Set up character device for user mode clients */
i = register_chrdev(0, "pcmcia", &ds_fops);
......@@ -1044,7 +1041,7 @@ fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
static void __exit exit_pcmcia_bus(void)
{
interface_unregister(&pcmcia_bus_interface);
class_interface_unregister(&pcmcia_bus_interface);
#ifdef CONFIG_PROC_FS
if (proc_pccard)
......
......@@ -44,12 +44,14 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
static int i82092aa_socket_suspend (struct pci_dev *dev, u32 state)
{
return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
return pcmcia_socket_dev_suspend(cls_d, state, 0);
}
static int i82092aa_socket_resume (struct pci_dev *dev)
{
return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
return pcmcia_socket_dev_resume(cls_d, RESUME_RESTORE_STATE);
}
static struct pci_driver i82092aa_pci_drv = {
......@@ -59,9 +61,6 @@ static struct pci_driver i82092aa_pci_drv = {
.remove = __devexit_p(i82092aa_pci_remove),
.suspend = i82092aa_socket_suspend,
.resume = i82092aa_socket_resume,
.driver = {
.devclass = &pcmcia_socket_class,
},
};
......@@ -176,7 +175,12 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
memset(cls_d, 0, sizeof(*cls_d));
cls_d->nsock = socket_count;
cls_d->ops = &i82092aa_operations;
dev->dev.class_data = cls_d;
pci_set_drvdata(dev, &cls_d);
cls_d->class_dev.class = &pcmcia_socket_class;
cls_d->class_dev.dev = &dev->dev;
strncpy(cls_d->class_dev.class_id, dev->dev.name, BUS_ID_SIZE);
class_set_devdata(&cls_d->class_dev, cls_d);
class_device_register(&cls_d->class_dev);
leave("i82092aa_pci_probe");
return 0;
......@@ -192,11 +196,16 @@ static int __init i82092aa_pci_probe(struct pci_dev *dev, const struct pci_devic
static void __devexit i82092aa_pci_remove(struct pci_dev *dev)
{
struct pcmcia_socket_class_data *cls_d = pci_get_drvdata(dev);
enter("i82092aa_pci_remove");
free_irq(dev->irq, i82092aa_interrupt);
if (dev->dev.class_data)
kfree(dev->dev.class_data);
if (cls_d) {
class_device_unregister(&cls_d->class_dev);
kfree(cls_d);
}
leave("i82092aa_pci_remove");
}
......
......@@ -1509,9 +1509,8 @@ static struct pcmcia_socket_class_data i82365_data = {
static struct device_driver i82365_driver = {
.name = "i82365",
.bus = &platform_bus_type,
.devclass = &pcmcia_socket_class,
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
/* .suspend = pcmcia_socket_dev_suspend, FIXME? */
/* .resume = pcmcia_socket_dev_resume, FIXME? */
};
static struct platform_device i82365_device = {
......@@ -1522,6 +1521,10 @@ static struct platform_device i82365_device = {
},
};
static struct class_device i82365_class_data = {
.class = &pcmcia_socket_class,
};
static int __init init_i82365(void)
{
servinfo_t serv;
......@@ -1555,9 +1558,12 @@ static int __init init_i82365(void)
#endif
i82365_data.nsock = sockets;
i82365_device.dev.class_data = &i82365_data;
i82365_class_data.dev = &i82365_device.dev;
i82365_class_data.class_data = &i82365_data;
strncpy(i82365_class_data.class_id, "i82365", BUS_ID_SIZE);
platform_device_register(&i82365_device);
class_device_register(&i82365_class_data);
/* Finally, schedule a polling interrupt */
if (poll_interval != 0) {
......@@ -1578,6 +1584,7 @@ static void __exit exit_i82365(void)
#ifdef CONFIG_PROC_FS
for (i = 0; i < sockets; i++) pcic_proc_remove(i);
#endif
class_device_unregister(&i82365_class_data);
platform_device_unregister(&i82365_device);
if (poll_interval != 0)
del_timer_sync(&poll_timer);
......
......@@ -153,7 +153,10 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock
socket->cls_d.nsock = 1; /* yenta is 1, no other low-level driver uses
this yet */
socket->cls_d.ops = &pci_socket_operations;
dev->dev.class_data = &socket->cls_d;
socket->cls_d.class_dev.class = &pcmcia_socket_class;
socket->cls_d.class_dev.dev = &dev->dev;
strncpy(socket->cls_d.class_dev.class_id, dev->dev.bus_id, BUS_ID_SIZE);
class_set_devdata(&socket->cls_d.class_dev, &socket->cls_d);
/* prepare pci_socket_t */
socket->dev = dev;
......@@ -161,10 +164,11 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock
pci_set_drvdata(dev, socket);
spin_lock_init(&socket->event_lock);
err = socket->op->open(socket);
if(err)
{
if (err) {
socket->dev = NULL;
pci_set_drvdata(dev, NULL);
} else {
class_device_register(&socket->cls_d.class_dev);
}
return err;
}
......@@ -194,17 +198,20 @@ static void __devexit cardbus_remove (struct pci_dev *dev)
/* note: we are already unregistered from the cs core */
if (socket->op && socket->op->close)
socket->op->close(socket);
class_device_unregister(&socket->cls_d.class_dev);
pci_set_drvdata(dev, NULL);
}
static int cardbus_suspend (struct pci_dev *dev, u32 state)
{
return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_suspend(&socket->cls_d, state, 0);
}
static int cardbus_resume (struct pci_dev *dev)
{
return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
pci_socket_t *socket = pci_get_drvdata(dev);
return pcmcia_socket_dev_resume(&socket->cls_d, RESUME_RESTORE_STATE);
}
......@@ -227,9 +234,6 @@ static struct pci_driver pci_cardbus_driver = {
.remove = __devexit_p(cardbus_remove),
.suspend = cardbus_suspend,
.resume = cardbus_resume,
.driver = {
.devclass = &pcmcia_socket_class,
},
};
static int __init pci_socket_init(void)
......
......@@ -176,7 +176,6 @@ static struct sa1111_driver pcmcia_driver = {
.drv = {
.name = "sa1111-pcmcia",
.bus = &sa1111_bus_type,
.devclass = &pcmcia_socket_class,
.probe = pcmcia_probe,
.remove = __devexit_p(pcmcia_remove),
.suspend = pcmcia_socket_dev_suspend,
......
......@@ -379,9 +379,8 @@ static struct pcmcia_socket_class_data tcic_data = {
static struct device_driver tcic_driver = {
.name = "tcic-pcmcia",
.bus = &platform_bus_type,
.devclass = &pcmcia_socket_class,
.suspend = pcmcia_socket_dev_suspend,
.resume = pcmcia_socket_dev_resume,
/* .suspend = pcmcia_socket_dev_suspend, FIXME? */
/* .resume = pcmcia_socket_dev_resume, FIXME? */
};
static struct platform_device tcic_device = {
......@@ -392,6 +391,10 @@ static struct platform_device tcic_device = {
},
};
static struct class_device tcic_class_data = {
.class = &pcmcia_socket_class,
};
static int __init init_tcic(void)
{
int i, sock;
......@@ -522,9 +525,12 @@ static int __init init_tcic(void)
tcic_interrupt(0, NULL, NULL);
tcic_data.nsock = sockets;
tcic_device.dev.class_data = &tcic_data;
tcic_class_data.dev = &tcic_device.dev;
tcic_class_data.class_data = &tcic_data;
strncpy(tcic_class_data.class_id, "tcic-pcmcia", BUS_ID_SIZE);
platform_device_register(&tcic_device);
class_device_register(&tcic_class_data);
return 0;
......@@ -540,6 +546,7 @@ static void __exit exit_tcic(void)
free_irq(cs_irq, tcic_interrupt);
}
release_region(tcic_base, 16);
class_device_unregister(&tcic_class_data);
platform_device_unregister(&tcic_device);
driver_unregister(&tcic_driver);
} /* exit_tcic */
......
......@@ -148,12 +148,13 @@ struct pcmcia_socket_class_data {
* returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */
struct pccard_operations *ops; /* see above */
void *s_info; /* socket_info_t */
struct class_device class_dev; /* generic class structure */
};
extern struct device_class pcmcia_socket_class;
extern struct class pcmcia_socket_class;
/* socket drivers are expected to use these callbacks in their .drv struct */
int pcmcia_socket_dev_suspend(struct device * dev, u32 state, u32 level);
int pcmcia_socket_dev_resume(struct device * dev, u32 level);
extern int pcmcia_socket_dev_suspend(struct pcmcia_socket_class_data *cls_d, u32 state, u32 level);
extern int pcmcia_socket_dev_resume(struct pcmcia_socket_class_data *cls_d, u32 level);
#endif /* _LINUX_SS_H */
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