diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-rw-r--r-- | drivers/pcmcia/yenta_socket.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 4145eb83b9b6..47e57602d5ea 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -287,7 +287,10 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
287 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | 287 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); |
288 | u16 bridge; | 288 | u16 bridge; |
289 | 289 | ||
290 | yenta_set_power(socket, state); | 290 | /* if powering down: do it immediately */ |
291 | if (state->Vcc == 0) | ||
292 | yenta_set_power(socket, state); | ||
293 | |||
291 | socket->io_irq = state->io_irq; | 294 | socket->io_irq = state->io_irq; |
292 | bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); | 295 | bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); |
293 | if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { | 296 | if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { |
@@ -339,6 +342,10 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
339 | /* Socket event mask: get card insert/remove events.. */ | 342 | /* Socket event mask: get card insert/remove events.. */ |
340 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 343 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
341 | cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); | 344 | cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK); |
345 | |||
346 | /* if powering up: do it as the last step when the socket is configured */ | ||
347 | if (state->Vcc != 0) | ||
348 | yenta_set_power(socket, state); | ||
342 | return 0; | 349 | return 0; |
343 | } | 350 | } |
344 | 351 | ||
@@ -998,6 +1005,77 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
998 | config_writew(socket, CB_BRIDGE_CONTROL, bridge); | 1005 | config_writew(socket, CB_BRIDGE_CONTROL, bridge); |
999 | } | 1006 | } |
1000 | 1007 | ||
1008 | /** | ||
1009 | * yenta_fixup_parent_bridge - Fix subordinate bus# of the parent bridge | ||
1010 | * @cardbus_bridge: The PCI bus which the CardBus bridge bridges to | ||
1011 | * | ||
1012 | * Checks if devices on the bus which the CardBus bridge bridges to would be | ||
1013 | * invisible during PCI scans because of a misconfigured subordinate number | ||
1014 | * of the parent brige - some BIOSes seem to be too lazy to set it right. | ||
1015 | * Does the fixup carefully by checking how far it can go without conflicts. | ||
1016 | * See http://bugzilla.kernel.org/show_bug.cgi?id=2944 for more information. | ||
1017 | */ | ||
1018 | static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge) | ||
1019 | { | ||
1020 | struct list_head *tmp; | ||
1021 | unsigned char upper_limit; | ||
1022 | /* | ||
1023 | * We only check and fix the parent bridge: All systems which need | ||
1024 | * this fixup that have been reviewed are laptops and the only bridge | ||
1025 | * which needed fixing was the parent bridge of the CardBus bridge: | ||
1026 | */ | ||
1027 | struct pci_bus *bridge_to_fix = cardbus_bridge->parent; | ||
1028 | |||
1029 | /* Check bus numbers are already set up correctly: */ | ||
1030 | if (bridge_to_fix->subordinate >= cardbus_bridge->subordinate) | ||
1031 | return; /* The subordinate number is ok, nothing to do */ | ||
1032 | |||
1033 | if (!bridge_to_fix->parent) | ||
1034 | return; /* Root bridges are ok */ | ||
1035 | |||
1036 | /* stay within the limits of the bus range of the parent: */ | ||
1037 | upper_limit = bridge_to_fix->parent->subordinate; | ||
1038 | |||
1039 | /* check the bus ranges of all silbling bridges to prevent overlap */ | ||
1040 | list_for_each(tmp, &bridge_to_fix->parent->children) { | ||
1041 | struct pci_bus * silbling = pci_bus_b(tmp); | ||
1042 | /* | ||
1043 | * If the silbling has a higher secondary bus number | ||
1044 | * and it's secondary is equal or smaller than our | ||
1045 | * current upper limit, set the new upper limit to | ||
1046 | * the bus number below the silbling's range: | ||
1047 | */ | ||
1048 | if (silbling->secondary > bridge_to_fix->subordinate | ||
1049 | && silbling->secondary <= upper_limit) | ||
1050 | upper_limit = silbling->secondary - 1; | ||
1051 | } | ||
1052 | |||
1053 | /* Show that the wanted subordinate number is not possible: */ | ||
1054 | if (cardbus_bridge->subordinate > upper_limit) | ||
1055 | printk(KERN_WARNING "Yenta: Upper limit for fixing this " | ||
1056 | "bridge's parent bridge: #%02x\n", upper_limit); | ||
1057 | |||
1058 | /* If we have room to increase the bridge's subordinate number, */ | ||
1059 | if (bridge_to_fix->subordinate < upper_limit) { | ||
1060 | |||
1061 | /* use the highest number of the hidden bus, within limits */ | ||
1062 | unsigned char subordinate_to_assign = | ||
1063 | min(cardbus_bridge->subordinate, upper_limit); | ||
1064 | |||
1065 | printk(KERN_INFO "Yenta: Raising subordinate bus# of parent " | ||
1066 | "bus (#%02x) from #%02x to #%02x\n", | ||
1067 | bridge_to_fix->number, | ||
1068 | bridge_to_fix->subordinate, subordinate_to_assign); | ||
1069 | |||
1070 | /* Save the new subordinate in the bus struct of the bridge */ | ||
1071 | bridge_to_fix->subordinate = subordinate_to_assign; | ||
1072 | |||
1073 | /* and update the PCI config space with the new subordinate */ | ||
1074 | pci_write_config_byte(bridge_to_fix->self, | ||
1075 | PCI_SUBORDINATE_BUS, bridge_to_fix->subordinate); | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1001 | /* | 1079 | /* |
1002 | * Initialize a cardbus controller. Make sure we have a usable | 1080 | * Initialize a cardbus controller. Make sure we have a usable |
1003 | * interrupt, and that we can map the cardbus area. Fill in the | 1081 | * interrupt, and that we can map the cardbus area. Fill in the |
@@ -1113,6 +1191,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
1113 | yenta_get_socket_capabilities(socket, isa_interrupts); | 1191 | yenta_get_socket_capabilities(socket, isa_interrupts); |
1114 | printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); | 1192 | printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); |
1115 | 1193 | ||
1194 | yenta_fixup_parent_bridge(dev->subordinate); | ||
1195 | |||
1116 | /* Register it with the pcmcia layer.. */ | 1196 | /* Register it with the pcmcia layer.. */ |
1117 | ret = pcmcia_register_socket(&socket->socket); | 1197 | ret = pcmcia_register_socket(&socket->socket); |
1118 | if (ret == 0) { | 1198 | if (ret == 0) { |
@@ -1232,6 +1312,7 @@ static struct pci_device_id yenta_table [] = { | |||
1232 | 1312 | ||
1233 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX), | 1313 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX), |
1234 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX), | 1314 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX), |
1315 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX12, TI12XX), | ||
1235 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX), | 1316 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX), |
1236 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX), | 1317 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX), |
1237 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX), | 1318 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX), |