X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpcmcia%2Fi82365.c;h=35a92d1e4945be16f89f514717d983263b74ce20;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=ec5ff85cde4a88da667f414370e8ed29cdc6d5ca;hpb=daddc0d38b3571bed170afa273a49a0eba090c1e;p=linux-2.6.git diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index ec5ff85cd..35a92d1e4 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -47,13 +47,12 @@ #include #include #include -#include +#include +#include #include #include -#include #include -#include #include #include #include @@ -65,10 +64,9 @@ #include "cirrus.h" #include "vg468.h" #include "ricoh.h" -#include "o2micro.h" #ifdef DEBUG -static const char *version = +static const char version[] = "i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)"; static int pc_debug; @@ -97,7 +95,7 @@ static inline int _check_irq(int irq, int flags) /* Parameters that can be set with 'insmod' */ /* Default base address for i82365sl and other ISA chips */ -static int i365_base = 0x3e0; +static unsigned long i365_base = 0x3e0; /* Should we probe at 0x3e2 for an extra ISA controller? */ static int extra_sockets = 0; /* Specify a socket number to ignore */ @@ -131,11 +129,11 @@ static int async_clock = -1; static int cable_mode = -1; static int wakeup = 0; -module_param(i365_base, int, 0444); +module_param(i365_base, ulong, 0444); module_param(ignore, int, 0444); module_param(extra_sockets, int, 0444); module_param(irq_mask, int, 0444); -module_param_array(irq_list, int, irq_list_count, 0444); +module_param_array(irq_list, int, &irq_list_count, 0444); module_param(cs_irq, int, 0444); module_param(async_clock, int, 0444); module_param(cable_mode, int, 0444); @@ -168,7 +166,7 @@ struct i82365_socket { u_short type, flags; struct pcmcia_socket socket; unsigned int number; - ioaddr_t ioaddr; + kio_addr_t ioaddr; u_short psock; u_char cs_irq, intr; union { @@ -187,7 +185,7 @@ static struct i82365_socket socket[8] = { #define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */ static int grab_irq; -static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(isa_lock); #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f) #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f) @@ -209,6 +207,7 @@ typedef enum pcic_id { #define IS_UNKNOWN 0x0400 #define IS_VG_PWR 0x0800 #define IS_DF_PWR 0x1000 +#define IS_REGISTERED 0x2000 #define IS_ALIVE 0x8000 typedef struct pcic_t { @@ -234,14 +233,14 @@ static pcic_t pcic[] = { /*====================================================================*/ -static spinlock_t bus_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(bus_lock); static u_char i365_get(u_short sock, u_short reg) { unsigned long flags; spin_lock_irqsave(&bus_lock,flags); { - ioaddr_t port = socket[sock].ioaddr; + kio_addr_t port = socket[sock].ioaddr; u_char val; reg = I365_REG(socket[sock].psock, reg); outb(reg, port); val = inb(port+1); @@ -255,7 +254,7 @@ static void i365_set(u_short sock, u_short reg, u_char data) unsigned long flags; spin_lock_irqsave(&bus_lock,flags); { - ioaddr_t port = socket[sock].ioaddr; + kio_addr_t port = socket[sock].ioaddr; u_char val = I365_REG(socket[sock].psock, reg); outb(val, port); outb(data, port+1); spin_unlock_irqrestore(&bus_lock,flags); @@ -514,8 +513,7 @@ static u_int __init test_irq(u_short sock, int irq) if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0) return 1; irq_hits = 0; irq_sock = sock; - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/100); + msleep(10); if (irq_hits) { free_irq(irq, i365_count_irq); debug(2, " spurious hit!\n"); @@ -591,7 +589,7 @@ static int to_cycles(int ns) /*====================================================================*/ -static int __init identify(u_short port, u_short sock) +static int __init identify(kio_addr_t port, u_short sock) { u_char val; int type = -1; @@ -662,7 +660,7 @@ static int __init identify(u_short port, u_short sock) static int __init is_alive(u_short sock) { u_char stat; - u_short start, stop; + kio_addr_t start, stop; stat = i365_get(sock, I365_STATUS); start = i365_get_pair(sock, I365_IO(0)+I365_W_START); @@ -670,16 +668,18 @@ static int __init is_alive(u_short sock) if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) && (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) && (i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) && - (check_region(start, stop-start+1) != 0) && - ((start & 0xfeef) != 0x02e8)) - return 1; - else - return 0; + ((start & 0xfeef) != 0x02e8)) { + if (!request_region(start, stop-start+1, "i82365")) + return 1; + release_region(start, stop-start+1); + } + + return 0; } /*====================================================================*/ -static void __init add_socket(u_short port, int psock, int type) +static void __init add_socket(kio_addr_t port, int psock, int type) { socket[sockets].ioaddr = port; socket[sockets].psock = psock; @@ -697,11 +697,9 @@ static void __init add_pcic(int ns, int type) struct i82365_socket *t = &socket[sockets-ns]; base = sockets-ns; - if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365"); - if (base == 0) printk("\n"); printk(KERN_INFO " %s", pcic[type].name); - printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x", + printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x", t->ioaddr, t->psock*0x40); printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : "")); @@ -775,7 +773,7 @@ static struct pnp_dev *i82365_pnpdev; static void __init isa_probe(void) { int i, j, sock, k, ns, id; - ioaddr_t port; + kio_addr_t port; #ifdef CONFIG_PNP struct isapnp_device_id *devid; struct pnp_dev *dev; @@ -804,9 +802,9 @@ static void __init isa_probe(void) } #endif - if (check_region(i365_base, 2) != 0) { + if (!request_region(i365_base, 2, "i82365")) { if (sockets == 0) - printk("port conflict at %#x\n", i365_base); + printk("port conflict at %#lx\n", i365_base); return; } @@ -942,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value) /*====================================================================*/ -static int i365_get_socket(u_short sock, socket_state_t *state) -{ - struct i82365_socket *t = &socket[sock]; - u_char reg, vcc, vpp; - - reg = i365_get(sock, I365_POWER); - state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; - state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; - vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; - state->Vcc = state->Vpp = 0; - if (t->flags & IS_CIRRUS) { - if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) { - if (reg & I365_VCC_5V) state->Vcc = 33; - if (vpp == I365_VPP1_5V) state->Vpp = 33; - } else { - if (reg & I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - } - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else if (t->flags & IS_VG_PWR) { - if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) { - if (reg & I365_VCC_5V) state->Vcc = 33; - if (vpp == I365_VPP1_5V) state->Vpp = 33; - } else { - if (reg & I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - } - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else if (t->flags & IS_DF_PWR) { - if (vcc == I365_VCC_3V) state->Vcc = 33; - if (vcc == I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else { - if (reg & I365_VCC_5V) { - state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } - } - - /* IO card, RESET flags, IO interrupt */ - reg = i365_get(sock, I365_INTCTL); - state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; - if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD; - state->io_irq = reg & I365_IRQ_MASK; - - /* speaker control */ - if (t->flags & IS_CIRRUS) { - if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) - state->flags |= SS_SPKR_ENA; - } - - /* Card status change mask */ - reg = i365_get(sock, I365_CSCINT); - state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; - if (state->flags & SS_IOCARD) - state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; - else { - state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; - state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; - state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; - } - - debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} /* i365_get_socket */ - -/*====================================================================*/ - static int i365_set_socket(u_short sock, socket_state_t *state) { struct i82365_socket *t = &socket[sock]; @@ -1129,7 +1055,7 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io) u_char map, ioctl; debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, " - "%#4.4x-%#4.4x)\n", sock, io->map, io->flags, + "%#lx-%#lx)\n", sock, io->map, io->flags, io->speed, io->start, io->stop); map = io->map; if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || @@ -1158,15 +1084,15 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) u_short base, i; u_char map; - debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5" - "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed, - mem->sys_start, mem->sys_stop, mem->card_start); + debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, " + "%#x)\n", sock, mem->map, mem->flags, mem->speed, + mem->res->start, mem->res->end, mem->card_start); map = mem->map; if ((map > 4) || (mem->card_start > 0x3ffffff) || - (mem->sys_start > mem->sys_stop) || (mem->speed > 1000)) + (mem->res->start > mem->res->end) || (mem->speed > 1000)) return -EINVAL; - if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)) + if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff)) return -EINVAL; /* Turn off the window before changing anything */ @@ -1174,12 +1100,12 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map)); base = I365_MEM(map); - i = (mem->sys_start >> 12) & 0x0fff; + i = (mem->res->start >> 12) & 0x0fff; if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT; if (mem->flags & MAP_0WS) i |= I365_MEM_0WS; i365_set_pair(sock, base+I365_W_START, i); - i = (mem->sys_stop >> 12) & 0x0fff; + i = (mem->res->end >> 12) & 0x0fff; switch (to_cycles(mem->speed)) { case 0: break; case 1: i |= I365_MEM_WS0; break; @@ -1188,7 +1114,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) } i365_set_pair(sock, base+I365_W_STOP, i); - i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff; + i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff; if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT; if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG; i365_set_pair(sock, base+I365_W_OFF, i); @@ -1267,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value) LOCKED(i365_get_status(sock, value)); } -static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ - unsigned int sock = container_of(s, struct i82365_socket, socket)->number; - - if (socket[sock].flags & IS_ALIVE) - return -EINVAL; - - LOCKED(i365_get_socket(sock, state)); -} - static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state) { unsigned int sock = container_of(s, struct i82365_socket, socket)->number; @@ -1308,10 +1224,10 @@ static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) static int pcic_init(struct pcmcia_socket *s) { int i; + struct resource res = { .start = 0, .end = 0x1000 }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; + pccard_mem_map mem = { .res = &res, }; - mem.sys_stop = 0x1000; for (i = 0; i < 2; i++) { io.map = i; pcic_set_io_map(s, &io); @@ -1323,16 +1239,9 @@ static int pcic_init(struct pcmcia_socket *s) return 0; } -static int pcic_suspend(struct pcmcia_socket *sock) -{ - return pcic_set_socket(sock, &dead_socket); -} - static struct pccard_operations pcic_operations = { .init = pcic_init, - .suspend = pcic_suspend, .get_status = pcic_get_status, - .get_socket = pcic_get_socket, .set_socket = pcic_set_socket, .set_io_map = pcic_set_io_map, .set_mem_map = pcic_set_mem_map, @@ -1340,40 +1249,35 @@ static struct pccard_operations pcic_operations = { /*====================================================================*/ -static int i82365_suspend(struct device *dev, u32 state, u32 level) -{ - int ret = 0; - if (level == SUSPEND_SAVE_STATE) - ret = pcmcia_socket_dev_suspend(dev, state); - return ret; -} - -static int i82365_resume(struct device *dev, u32 level) -{ - int ret = 0; - if (level == RESUME_RESTORE_STATE) - ret = pcmcia_socket_dev_resume(dev); - return ret; -} - static struct device_driver i82365_driver = { .name = "i82365", .bus = &platform_bus_type, - .suspend = i82365_suspend, - .resume = i82365_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; -static struct platform_device i82365_device = { - .name = "i82365", - .id = 0, -}; +static struct platform_device *i82365_device; static int __init init_i82365(void) { int i, ret; - if (driver_register(&i82365_driver)) - return -1; + ret = driver_register(&i82365_driver); + if (ret) + return ret; + + i82365_device = platform_device_alloc("i82365", 0); + if (i82365_device) { + ret = platform_device_add(i82365_device); + if (ret) + platform_device_put(i82365_device); + } else + ret = -ENOMEM; + + if (ret) { + driver_unregister(&i82365_driver); + return ret; + } printk(KERN_INFO "Intel ISA PCIC probe: "); sockets = 0; @@ -1382,28 +1286,27 @@ static int __init init_i82365(void) if (sockets == 0) { printk("not found.\n"); + platform_device_unregister(i82365_device); + release_region(i365_base, 2); driver_unregister(&i82365_driver); return -ENODEV; } - platform_device_register(&i82365_device); - /* Set up interrupt handler(s) */ if (grab_irq != 0) request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt); /* register sockets with the pcmcia core */ for (i = 0; i < sockets; i++) { - socket[i].socket.dev.dev = &i82365_device.dev; + socket[i].socket.dev.dev = &i82365_device->dev; socket[i].socket.ops = &pcic_operations; + socket[i].socket.resource_ops = &pccard_nonstatic_ops; socket[i].socket.owner = THIS_MODULE; socket[i].number = i; - ret = pcmcia_register_socket(&socket[i].socket); - if (ret && i--) { - for (; i>= 0; i--) - pcmcia_unregister_socket(&socket[i].socket); - break; - } + ret = pcmcia_register_socket(&socket[i].socket); + if (!ret) + socket[i].flags |= IS_REGISTERED; + #if 0 /* driver model ordering issue */ class_device_create_file(&socket[i].socket.dev, &class_device_attr_info); @@ -1430,9 +1333,10 @@ static void __exit exit_i82365(void) int i; for (i = 0; i < sockets; i++) { - pcmcia_unregister_socket(&socket[i].socket); + if (socket[i].flags & IS_REGISTERED) + pcmcia_unregister_socket(&socket[i].socket); } - platform_device_unregister(&i82365_device); + platform_device_unregister(i82365_device); if (poll_interval != 0) del_timer_sync(&poll_timer); if (grab_irq != 0) @@ -1442,7 +1346,8 @@ static void __exit exit_i82365(void) i365_set(i, I365_CSCINT, 0); release_region(socket[i].ioaddr, 2); } -#ifdef __ISAPNP__ + release_region(i365_base, 2); +#ifdef CONFIG_PNP if (i82365_pnpdev) pnp_disable_dev(i82365_pnpdev); #endif