Commit fd0dacff authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] pcmcia: add socket_offset for multiple pci_sockets, correct suspend&resume

 - suspend & remove for pci_socket was broken -- thanks to Paul
   Mackerras for noting this
 - to correctly initialize multiple pci_socket devices, a sock_offset is
   needed.
 - s_info doesn't need to be an array.
parent ade30b83
......@@ -337,13 +337,14 @@ int pcmcia_register_socket(struct device *dev)
return -ENOMEM;
memset(s_info, 0, cls_d->nsock * sizeof(socket_info_t));
cls_d->s_info = s_info;
/* socket initialization */
for (i = 0; i < cls_d->nsock; i++) {
socket_info_t *s = &s_info[i];
cls_d->s_info[i] = s;
s->ss_entry = cls_d->ops;
s->sock = i;
s->sock = i + cls_d->sock_offset;
/* base address = 0, map = 0 */
s->cis_mem.flags = 0;
......@@ -359,7 +360,7 @@ int pcmcia_register_socket(struct device *dev)
if (j == sockets) sockets++;
init_socket(s);
s->ss_entry->inquire_socket(i, &s->cap);
s->ss_entry->inquire_socket(s->sock, &s->cap);
#ifdef CONFIG_PROC_FS
if (proc_pccard) {
char name[3];
......
......@@ -171,6 +171,16 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock
int err;
memset(socket, 0, sizeof(*socket));
/* prepare class_data */
socket->cls_d.sock_offset = nr;
socket->cls_d.nsock = 1; /* yenta is 1, no other low-level driver uses
this yet */
socket->cls_d.ops = &pci_socket_operations;
socket->cls_d.use_bus_pm = 1;
dev->dev.class_data = &socket->cls_d;
/* prepare pci_socket_t */
socket->dev = dev;
socket->op = ops;
pci_set_drvdata(dev, socket);
......@@ -186,18 +196,6 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock
int cardbus_register(struct pci_dev *p_dev)
{
pci_socket_t *socket = pci_get_drvdata(p_dev);
struct pcmcia_socket_class_data *cls_d;
if (!socket)
return -EINVAL;
cls_d = &socket->cls_d;
cls_d->nsock = 1; /* yenta is 1, no other low-level driver uses
this yet */
cls_d->ops = &pci_socket_operations;
cls_d->use_bus_pm = 1;
p_dev->dev.class_data = cls_d;
return 0;
}
......@@ -227,14 +225,16 @@ static void __devexit cardbus_remove (struct pci_dev *dev)
static int cardbus_suspend (struct pci_dev *dev, u32 state)
{
pci_socket_t *socket = pci_get_drvdata(dev);
pcmcia_suspend_socket (socket->pcmcia_socket);
if (socket && socket->cls_d.s_info)
pcmcia_suspend_socket (socket->cls_d.s_info);
return 0;
}
static int cardbus_resume (struct pci_dev *dev)
{
pci_socket_t *socket = pci_get_drvdata(dev);
pcmcia_resume_socket (socket->pcmcia_socket);
if (socket && socket->cls_d.s_info)
pcmcia_resume_socket (socket->cls_d.s_info);
return 0;
}
......
......@@ -20,7 +20,6 @@ typedef struct pci_socket {
socket_cap_t cap;
spinlock_t event_lock;
unsigned int events;
struct socket_info_t *pcmcia_socket;
struct work_struct tq_task;
struct timer_list poll_timer;
......
......@@ -145,12 +145,12 @@ struct pccard_operations {
* Calls to set up low-level "Socket Services" drivers
*/
#define MAX_SOCKETS_PER_DEV 8
struct pcmcia_socket_class_data {
unsigned int nsock; /* number of sockets */
unsigned int sock_offset; /* socket # (which is
* returned to driver) = sock_offset + (0, 1, .. , (nsock-1) */
struct pccard_operations *ops; /* see above */
void *s_info[MAX_SOCKETS_PER_DEV]; /* socket_info_t */
void *s_info; /* socket_info_t */
unsigned int use_bus_pm;
};
......
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