GIT 35b86edf75270176310cb9507745d8c02b9e6592 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git/ commit 35b86edf75270176310cb9507745d8c02b9e6592 Author: Dominik Brodowski Date: Wed Apr 26 19:57:32 2006 +0200 [PATCH] pcmcia: another ID for serial_cs.c Add an ID for "GlobeTrotter" cards which need a CIS override Signed-off-by: Dominik Brodowski commit 448de55be568fe8a353076e8da1af21573ca9eb2 Author: Bernhard Kaindl Date: Thu Apr 13 19:12:10 2006 +0200 [PATCH] yenta: fix hidden PCI bus numbers Fixup the subordinate number parent bridge of yenta Cardbus Bridges before the PCI bus scan starts to make the cardbus cards which are otherwise hidden for PCI scans work. Signed-off-by: Bernhard Kaindl Signed-off-by: Dominik Brodowski commit 50cb16079294033d1994118c8adbebceb4218ce6 Author: Daniel Ritz Date: Mon Mar 6 17:37:04 2006 +0100 [PATCH] yenta: do power-up only after socket is configured power-up the card only after the socket is configured. power-down in the old place. the point is not to power-up the card before the interrupt routing is set up correctly. Signed-off-by: Daniel Ritz Signed-off-by: Dominik Brodowski --- diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 4145eb8..9e61f41 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -287,7 +287,10 @@ static int yenta_set_socket(struct pcmci struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); u16 bridge; - yenta_set_power(socket, state); + /* if powering down: do it immediately */ + if (state->Vcc == 0) + yenta_set_power(socket, state); + socket->io_irq = state->io_irq; bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { @@ -339,6 +342,10 @@ static int yenta_set_socket(struct pcmci /* Socket event mask: get card insert/remove events.. */ cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); + + /* if powering up: do it as the last step when the socket is configured */ + if (state->Vcc != 0) + yenta_set_power(socket, state); return 0; } @@ -998,6 +1005,77 @@ static void yenta_config_init(struct yen config_writew(socket, CB_BRIDGE_CONTROL, bridge); } +/** + * pci_fixup_parent_subordinate - Fix the subordinate number parent bridge + * @cardbus_bridge: Bus the CardBus bridge bridge to + * + * Checks if devices on the bus the CardBus bridge bridges to would be + * invisible during PCI scans because of a misconfigured subordinate number + * of the parent brige - some BIOSes seem to be too lazy to set it right. + * Does to fixup carefully by checking how far it can go without overlap. + */ +static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) +{ + struct list_head *tmp; + /* Our starting point is the max PCI bus number */ + unsigned char upper_limit = 0xff; + /* + * We only check and fix the parent bridge, all setup which need + * this fixup and have been reviewed are laptops and the only bridge + * which needed fixing was the parent bridge of the cardbus bridge: + */ + struct pci_bus *bridge_to_fix = cardbus_bridge->parent; + + /* Check bus numbers are already set up correctly: */ + if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate) + return; /* Thanks, nothing to do */ + + if (!bridge_to_fix->parent) + return; /* The root bridges are ok */ + + /* stay within the limits of the bus range of the parent: */ + upper_limit = bridge_to_fix->parent->subordinate; + + /* check the bus ranges of all silbling bridges to prevent overlap */ + list_for_each(tmp, &bridge_to_fix->parent->children) { + struct pci_bus * silbling = pci_bus_b(tmp); + /* + * If the silbling has a higher secondary bus number + * and it's secondary is equal or smaller than our + * current upper limit, set the new upper limit to + * the bus number below the silbling's range: + */ + if (silbling->secondary > bridge_to_fix->subordinate + && silbling->secondary <= upper_limit) + upper_limit = silbling->secondary - 1; + } + + /* Show that the wanted subordinate number is not possible: */ + if (cardbus_bridge->subordinate > upper_limit) + printk(KERN_WARNING "Yenta: Upper limit for fixing this " + "bridge's parent bridge: #%02x\n", upper_limit); + + /* If we have room to increase the bridge's subordinate number, */ + if (bridge_to_fix->subordinate < upper_limit) { + + /* use the highest number of the hidden bus, within limits */ + unsigned char subordinate_to_assign = + min(cardbus_bridge->subordinate, upper_limit); + + printk(KERN_INFO "Yenta: Raising subordinate bus# of parent " + "bus (#%02x) from #%02x to #%02x\n", + bridge_to_fix->number, + bridge_to_fix->subordinate, subordinate_to_assign); + + /* Save the new subordinate in the bus struct of the bridge */ + bridge_to_fix->subordinate = subordinate_to_assign; + + /* and update the PCI config space with the new subordinate */ + pci_write_config_byte(bridge_to_fix->self, + PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate); + } +} + /* * Initialize a cardbus controller. Make sure we have a usable * interrupt, and that we can map the cardbus area. Fill in the @@ -1113,6 +1191,8 @@ static int __devinit yenta_probe (struct yenta_get_socket_capabilities(socket, isa_interrupts); printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); + yenta_fixup_parent_bridge(dev->subordinate); + /* Register it with the pcmcia layer.. */ ret = pcmcia_register_socket(&socket->socket); if (ret == 0) { diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 2c70773..cbf260b 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -786,6 +786,7 @@ static struct pcmcia_device_id serial_id PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), + PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), /* too generic */ /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */