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), |
