diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 22:58:42 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 22:58:42 +0000 |
commit | eed6b7c84cc33f229f6fecd884d9a22af5bec514 (patch) | |
tree | 422a7a49328c59053f4fb11805adb753523c2f2c /drivers/pcmcia | |
parent | a3b90e3c6976551acbac09f5aacd736a1658aaa8 (diff) |
Merge with Linux 2.4.0-test5-pre6.
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/ds.c | 9 | ||||
-rw-r--r-- | drivers/pcmcia/pci_socket.c | 11 | ||||
-rw-r--r-- | drivers/pcmcia/yenta.c | 134 |
3 files changed, 89 insertions, 65 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index f536e42cb..a2a963215 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -878,7 +878,14 @@ int __init init_pcmcia_ds(void) int i, ret; DEBUG(0, "%s\n", version); - + + /* + * Ugly. But we want to wait for the socket threads to have started up. + * We really should let the drivers themselves drive some of this.. + */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/10); + pcmcia_get_card_services_info(&serv); if (serv.Revision != CS_RELEASE_CODE) { printk(KERN_NOTICE "ds: Card Services release does not match!\n"); diff --git a/drivers/pcmcia/pci_socket.c b/drivers/pcmcia/pci_socket.c index ce2fd652b..7f21f827e 100644 --- a/drivers/pcmcia/pci_socket.c +++ b/drivers/pcmcia/pci_socket.c @@ -181,6 +181,13 @@ static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_sock return socket->op->open(socket); } +void cardbus_register(pci_socket_t *socket) +{ + int nr = socket - pci_socket_array; + + socket->pcmcia_socket = pcmcia_register_socket(nr, &pci_socket_operations, 1); +} + static int __devinit cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id) { @@ -189,10 +196,6 @@ cardbus_probe (struct pci_dev *dev, const struct pci_device_id *id) for (s = 0; s < MAX_SOCKETS; s++) { if (pci_socket_array [s].dev == 0) { add_pci_socket (s, dev, ¥ta_operations); - pci_socket_array [s].pcmcia_socket = - pcmcia_register_socket (s, - &pci_socket_operations, - 1); return 0; } } diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c index 25d3ed11f..0556c7906 100644 --- a/drivers/pcmcia/yenta.c +++ b/drivers/pcmcia/yenta.c @@ -470,35 +470,15 @@ static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) } /* - * Watch a socket every second (and possibly in a - * more timely manner if the state change interrupt - * works..) + * Only probe "regular" interrupts, don't + * touch dangerous spots like the mouse irq, + * because there are mice that apparently + * get really confused if they get fondled + * too intimately. + * + * Default to 11, 10, 9, 7, 6, 5, 4, 3. */ -static int yenta_socket_thread(void * data) -{ - pci_socket_t * socket = (pci_socket_t *) data; - DECLARE_WAITQUEUE(wait, current); - - daemonize(); - strcpy(current->comm, "CardBus Watcher"); - - do { - unsigned int events = socket->events | yenta_events(socket); - - if (events) { - socket->events = 0; - if (socket->handler) - socket->handler(socket->info, events); - } - - current->state = TASK_INTERRUPTIBLE; - add_wait_queue(&socket->wait, &wait); - if (!socket->events) - schedule_timeout(HZ); - remove_wait_queue(&socket->wait, &wait); - } while (!signal_pending(current)); - return 0; -} +static u32 isa_interrupts = 0x0ef8; static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask) { @@ -540,6 +520,61 @@ static unsigned int yenta_probe_irq(pci_socket_t *socket, u32 isa_irq_mask) return mask; } +/* + * Set static data that doesn't need re-initializing.. + */ +static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask) +{ + socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; + socket->cap.map_size = 0x1000; + socket->cap.pci_irq = socket->cb_irq; + socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask); + socket->cap.cb_dev = socket->dev; + socket->cap.bus = NULL; + + printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); +} + +extern void cardbus_register(pci_socket_t *socket); + +/* + * Watch a socket every second (and possibly in a + * more timely manner if the state change interrupt + * works..) + */ +static int yenta_socket_thread(void * data) +{ + pci_socket_t * socket = (pci_socket_t *) data; + DECLARE_WAITQUEUE(wait, current); + + daemonize(); + strcpy(current->comm, "CardBus Watcher"); + + /* Figure out what the dang thing can do for the PCMCIA layer... */ + yenta_get_socket_capabilities(socket, isa_interrupts); + printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); + + /* Register it with the pcmcia layer.. */ + cardbus_register(socket); + + do { + unsigned int events = socket->events | yenta_events(socket); + + if (events) { + socket->events = 0; + if (socket->handler) + socket->handler(socket->info, events); + } + + current->state = TASK_INTERRUPTIBLE; + add_wait_queue(&socket->wait, &wait); + if (!socket->events) + schedule_timeout(HZ); + remove_wait_queue(&socket->wait, &wait); + } while (!signal_pending(current)); + return 0; +} + static void yenta_clear_maps(pci_socket_t *socket) { int i; @@ -558,8 +593,10 @@ static void yenta_clear_maps(pci_socket_t *socket) } } -/* Called at resume and initialization events */ -static int yenta_init(pci_socket_t *socket) +/* + * Initialize the standard cardbus registers + */ +static int yenta_config_init(pci_socket_t *socket) { u16 bridge; struct pci_dev *dev = socket->dev; @@ -600,7 +637,12 @@ static int yenta_init(pci_socket_t *socket) /* Redo card voltage interrogation */ cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST); +} +/* Called at resume and initialization events */ +static int yenta_init(pci_socket_t *socket) +{ + yenta_config_init(socket); yenta_clear_maps(socket); return 0; } @@ -624,21 +666,6 @@ static int yenta_suspend(pci_socket_t *socket) return 0; } -/* - * Set static data that doesn't need re-initializing.. - */ -static void yenta_get_socket_capabilities(pci_socket_t *socket, u32 isa_irq_mask) -{ - socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; - socket->cap.map_size = 0x1000; - socket->cap.pci_irq = socket->cb_irq; - socket->cap.irq_mask = yenta_probe_irq(socket, isa_irq_mask); - socket->cap.cb_dev = socket->dev; - socket->cap.bus = NULL; - - printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq); -} - static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type) { struct pci_bus *bus; @@ -742,17 +769,6 @@ static struct cardbus_override_struct { #define NR_OVERRIDES (sizeof(cardbus_override)/sizeof(struct cardbus_override_struct)) /* - * Only probe "regular" interrupts, don't - * touch dangerous spots like the mouse irq, - * because there are mice that apparently - * get really confused if they get fondled - * too intimately. - * - * Default to 11, 10, 9, 7, 6, 5, 4, 3. - */ -static u32 isa_interrupts = 0x0ef8; - -/* * Initialize a cardbus controller. Make sure we have a usable * interrupt, and that we can map the cardbus area. Fill in the * socket information structure.. @@ -780,6 +796,8 @@ static int yenta_open(pci_socket_t *socket) if (!socket->base) return -1; + yenta_config_init(socket); + /* Disable all events */ cb_writel(socket, CB_SOCKET_MASK, 0x0); @@ -802,11 +820,7 @@ static int yenta_open(pci_socket_t *socket) } } - /* Figure out what the dang thing can do for the PCMCIA layer... */ - yenta_get_socket_capabilities(socket, isa_interrupts); - kernel_thread(yenta_socket_thread, socket, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); return 0; } |