X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpcmcia%2Fyenta_socket.c;h=9fae06ac2761c13a5f9b80bc5ccfc5f9a16dd61a;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=4c8a7a5724d615a5755e1dcfd4b6dec49f2617e2;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 4c8a7a572..9fae06ac2 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -28,6 +28,9 @@ #include "yenta_socket.h" #include "i82365.h" +static int disable_clkrun; +module_param(disable_clkrun, bool, 0444); +MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); #if 0 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) @@ -42,6 +45,10 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket); +static unsigned int override_bios; +module_param(override_bios, uint, 0000); +MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation"); + /* * Generate easy-to-use ways of reading a cardbus sockets * regular memory space ("cb_xxx"), configuration space @@ -343,14 +350,17 @@ static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) { struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); + struct pci_bus_region region; int map; unsigned char addr, enable; unsigned int start, stop, card_start; unsigned short word; + pcibios_resource_to_bus(socket->dev, ®ion, mem->res); + map = mem->map; - start = mem->sys_start; - stop = mem->sys_stop; + start = region.start; + stop = region.end; card_start = mem->card_start; if (map > 4 || start > stop || ((start ^ stop) >> 24) || @@ -447,7 +457,7 @@ static void yenta_clear_maps(struct yenta_socket *socket) int i; struct resource res = { .start = 0, .end = 0x0fff }; pccard_io_map io = { 0, 0, 0, 0, 1 }; - pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, }; + pccard_mem_map mem = { .res = &res, }; yenta_set_socket(&socket->socket, &dead_socket); for (i = 0; i < 2; i++) { @@ -548,7 +558,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ start = config_readl(socket, offset) & mask; end = config_readl(socket, offset+4) | ~mask; - if (start && end > start) { + if (start && end > start && !override_bios) { res->start = start; res->end = end; if (request_resource(root, res) == 0) @@ -650,6 +660,7 @@ static void yenta_close(struct pci_dev *dev) yenta_free_resources(sock); pci_release_regions(dev); + pci_disable_device(dev); pci_set_drvdata(dev, NULL); } @@ -685,7 +696,7 @@ enum { * Different cardbus controllers have slightly different * initialization sequences etc details. List them here.. */ -struct cardbus_type cardbus_type[] = { +static struct cardbus_type cardbus_type[] = { [CARDBUS_TYPE_TI] = { .override = ti_override, .save_state = ti_save_state, @@ -824,8 +835,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); /* disable interrupts */ cb_writel(socket, CB_SOCKET_MASK, 0); @@ -911,6 +921,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i /* prepare pcmcia_socket */ socket->socket.ops = ¥ta_socket_operations; + socket->socket.resource_ops = &pccard_nonstatic_ops; socket->socket.dev.dev = &dev->dev; socket->socket.driver_data = socket; socket->socket.owner = THIS_MODULE; @@ -1020,10 +1031,16 @@ static int yenta_dev_suspend (struct pci_dev *dev, u32 state) socket->type->save_state(socket); /* FIXME: pci_save_state needs to have a better interface */ - pci_save_state(dev, socket->saved_state); - pci_read_config_dword(dev, 16*4, &socket->saved_state[16]); - pci_read_config_dword(dev, 17*4, &socket->saved_state[17]); - pci_set_power_state(dev, 3); + pci_save_state(dev); + pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); + pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); + + /* + * Some laptops (IBM T22) do not like us putting the Cardbus + * bridge into D3. At a guess, some other laptop will + * probably require this, so leave it commented out for now. + */ + /* pci_set_power_state(dev, 3); */ } return ret; @@ -1037,9 +1054,9 @@ static int yenta_dev_resume (struct pci_dev *dev) if (socket) { pci_set_power_state(dev, 0); /* FIXME: pci_restore_state needs to have a better interface */ - pci_restore_state(dev, socket->saved_state); - pci_write_config_dword(dev, 16*4, socket->saved_state[16]); - pci_write_config_dword(dev, 17*4, socket->saved_state[17]); + pci_restore_state(dev); + pci_write_config_dword(dev, 16*4, socket->saved_state[0]); + pci_write_config_dword(dev, 17*4, socket->saved_state[1]); if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); @@ -1088,6 +1105,7 @@ static struct pci_device_id yenta_table [] = { CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4520, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),