diff options
| -rw-r--r-- | Documentation/pcmcia/crc32hash.c | 32 | ||||
| -rw-r--r-- | Documentation/pcmcia/devicetable.txt | 36 | ||||
| -rw-r--r-- | drivers/char/pcmcia/cm4000_cs.c | 7 | ||||
| -rw-r--r-- | drivers/ide/legacy/ide-cs.c | 81 | ||||
| -rw-r--r-- | drivers/net/pcmcia/com20020_cs.c | 5 | ||||
| -rw-r--r-- | drivers/net/wireless/hostap/hostap_cs.c | 2 | ||||
| -rw-r--r-- | drivers/pcmcia/at91_cf.c | 75 | ||||
| -rw-r--r-- | drivers/pcmcia/au1000_db1x00.c | 2 | ||||
| -rw-r--r-- | drivers/pcmcia/cs.c | 29 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 27 | ||||
| -rw-r--r-- | drivers/pcmcia/ti113x.h | 1 | ||||
| -rw-r--r-- | drivers/pcmcia/yenta_socket.c | 83 | ||||
| -rw-r--r-- | drivers/serial/serial_cs.c | 1 | ||||
| -rw-r--r-- | include/linux/pci_ids.h | 1 |
14 files changed, 291 insertions, 91 deletions
diff --git a/Documentation/pcmcia/crc32hash.c b/Documentation/pcmcia/crc32hash.c new file mode 100644 index 000000000000..cbc36d299af8 --- /dev/null +++ b/Documentation/pcmcia/crc32hash.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */ | ||
| 2 | /* Usage example: | ||
| 3 | $ ./crc32hash "Dual Speed" | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <string.h> | ||
| 7 | #include <stdio.h> | ||
| 8 | #include <ctype.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | |||
| 11 | unsigned int crc32(unsigned char const *p, unsigned int len) | ||
| 12 | { | ||
| 13 | int i; | ||
| 14 | unsigned int crc = 0; | ||
| 15 | while (len--) { | ||
| 16 | crc ^= *p++; | ||
| 17 | for (i = 0; i < 8; i++) | ||
| 18 | crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); | ||
| 19 | } | ||
| 20 | return crc; | ||
| 21 | } | ||
| 22 | |||
| 23 | int main(int argc, char **argv) { | ||
| 24 | unsigned int result; | ||
| 25 | if (argc != 2) { | ||
| 26 | printf("no string passed as argument\n"); | ||
| 27 | return -1; | ||
| 28 | } | ||
| 29 | result = crc32(argv[1], strlen(argv[1])); | ||
| 30 | printf("0x%x\n", result); | ||
| 31 | return 0; | ||
| 32 | } | ||
diff --git a/Documentation/pcmcia/devicetable.txt b/Documentation/pcmcia/devicetable.txt index 3351c0355143..199afd100cf2 100644 --- a/Documentation/pcmcia/devicetable.txt +++ b/Documentation/pcmcia/devicetable.txt | |||
| @@ -27,37 +27,7 @@ pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000 | |||
| 27 | The hex value after "pa" is the hash of product ID string 1, after "pb" for | 27 | The hex value after "pa" is the hash of product ID string 1, after "pb" for |
| 28 | string 2 and so on. | 28 | string 2 and so on. |
| 29 | 29 | ||
| 30 | Alternatively, you can use this small tool to determine the crc32 hash. | 30 | Alternatively, you can use crc32hash (see Documentation/pcmcia/crc32hash.c) |
| 31 | simply pass the string you want to evaluate as argument to this program, | 31 | to determine the crc32 hash. Simply pass the string you want to evaluate |
| 32 | e.g. | 32 | as argument to this program, e.g.: |
| 33 | $ ./crc32hash "Dual Speed" | 33 | $ ./crc32hash "Dual Speed" |
| 34 | |||
| 35 | ------------------------------------------------------------------------- | ||
| 36 | /* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */ | ||
| 37 | #include <string.h> | ||
| 38 | #include <stdio.h> | ||
| 39 | #include <ctype.h> | ||
| 40 | #include <stdlib.h> | ||
| 41 | |||
| 42 | unsigned int crc32(unsigned char const *p, unsigned int len) | ||
| 43 | { | ||
| 44 | int i; | ||
| 45 | unsigned int crc = 0; | ||
| 46 | while (len--) { | ||
| 47 | crc ^= *p++; | ||
| 48 | for (i = 0; i < 8; i++) | ||
| 49 | crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); | ||
| 50 | } | ||
| 51 | return crc; | ||
| 52 | } | ||
| 53 | |||
| 54 | int main(int argc, char **argv) { | ||
| 55 | unsigned int result; | ||
| 56 | if (argc != 2) { | ||
| 57 | printf("no string passed as argument\n"); | ||
| 58 | return -1; | ||
| 59 | } | ||
| 60 | result = crc32(argv[1], strlen(argv[1])); | ||
| 61 | printf("0x%x\n", result); | ||
| 62 | return 0; | ||
| 63 | } | ||
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index eab5394da666..31c8a21f9d87 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
| @@ -149,12 +149,7 @@ struct cm4000_dev { | |||
| 149 | #define ZERO_DEV(dev) \ | 149 | #define ZERO_DEV(dev) \ |
| 150 | memset(&dev->atr_csum,0, \ | 150 | memset(&dev->atr_csum,0, \ |
| 151 | sizeof(struct cm4000_dev) - \ | 151 | sizeof(struct cm4000_dev) - \ |
| 152 | /*link*/ sizeof(struct pcmcia_device *) - \ | 152 | offsetof(struct cm4000_dev, atr_csum)) |
| 153 | /*node*/ sizeof(dev_node_t) - \ | ||
| 154 | /*atr*/ MAX_ATR*sizeof(char) - \ | ||
| 155 | /*rbuf*/ 512*sizeof(char) - \ | ||
| 156 | /*sbuf*/ 512*sizeof(char) - \ | ||
| 157 | /*queue*/ 4*sizeof(wait_queue_head_t)) | ||
| 158 | 153 | ||
| 159 | static struct pcmcia_device *dev_table[CM4000_MAX_DEV]; | 154 | static struct pcmcia_device *dev_table[CM4000_MAX_DEV]; |
| 160 | static struct class *cmm_class; | 155 | static struct class *cmm_class; |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 602797a44208..b7e459e4f284 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
| @@ -146,7 +146,16 @@ static void ide_detach(struct pcmcia_device *link) | |||
| 146 | kfree(link->priv); | 146 | kfree(link->priv); |
| 147 | } /* ide_detach */ | 147 | } /* ide_detach */ |
| 148 | 148 | ||
| 149 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) | 149 | static void idecs_mmio_fixup(ide_hwif_t *hwif) |
| 150 | { | ||
| 151 | default_hwif_mmiops(hwif); | ||
| 152 | hwif->mmio = 2; | ||
| 153 | |||
| 154 | ide_undecoded_slave(hwif); | ||
| 155 | } | ||
| 156 | |||
| 157 | static int idecs_register(unsigned long io, unsigned long ctl, | ||
| 158 | unsigned long irq, struct pcmcia_device *handle, int is_mmio) | ||
| 150 | { | 159 | { |
| 151 | hw_regs_t hw; | 160 | hw_regs_t hw; |
| 152 | memset(&hw, 0, sizeof(hw)); | 161 | memset(&hw, 0, sizeof(hw)); |
| @@ -154,7 +163,19 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq | |||
| 154 | hw.irq = irq; | 163 | hw.irq = irq; |
| 155 | hw.chipset = ide_pci; | 164 | hw.chipset = ide_pci; |
| 156 | hw.dev = &handle->dev; | 165 | hw.dev = &handle->dev; |
| 157 | return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); | 166 | |
| 167 | if(is_mmio) | ||
| 168 | return ide_register_hw_with_fixup(&hw, NULL, idecs_mmio_fixup); | ||
| 169 | else | ||
| 170 | return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); | ||
| 171 | } | ||
| 172 | |||
| 173 | void outb_io(unsigned char value, unsigned long port) { | ||
| 174 | outb(value, port); | ||
| 175 | } | ||
| 176 | |||
| 177 | void outb_mem(unsigned char value, unsigned long port) { | ||
| 178 | writeb(value, (void __iomem *) port); | ||
| 158 | } | 179 | } |
| 159 | 180 | ||
| 160 | /*====================================================================== | 181 | /*====================================================================== |
| @@ -180,7 +201,8 @@ static int ide_config(struct pcmcia_device *link) | |||
| 180 | } *stk = NULL; | 201 | } *stk = NULL; |
| 181 | cistpl_cftable_entry_t *cfg; | 202 | cistpl_cftable_entry_t *cfg; |
| 182 | int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0; | 203 | int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0; |
| 183 | unsigned long io_base, ctl_base; | 204 | unsigned long io_base, ctl_base, is_mmio, try_slave; |
| 205 | void (*my_outb)(unsigned char, unsigned long); | ||
| 184 | 206 | ||
| 185 | DEBUG(0, "ide_config(0x%p)\n", link); | 207 | DEBUG(0, "ide_config(0x%p)\n", link); |
| 186 | 208 | ||
| @@ -210,7 +232,7 @@ static int ide_config(struct pcmcia_device *link) | |||
| 210 | /* Not sure if this is right... look up the current Vcc */ | 232 | /* Not sure if this is right... look up the current Vcc */ |
| 211 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); | 233 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); |
| 212 | 234 | ||
| 213 | pass = io_base = ctl_base = 0; | 235 | pass = io_base = ctl_base = is_mmio = try_slave = 0; |
| 214 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 236 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
| 215 | tuple.Attributes = 0; | 237 | tuple.Attributes = 0; |
| 216 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 238 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
| @@ -258,11 +280,45 @@ static int ide_config(struct pcmcia_device *link) | |||
| 258 | goto next_entry; | 280 | goto next_entry; |
| 259 | io_base = link->io.BasePort1; | 281 | io_base = link->io.BasePort1; |
| 260 | ctl_base = link->io.BasePort1 + 0x0e; | 282 | ctl_base = link->io.BasePort1 + 0x0e; |
| 283 | |||
| 284 | if (io->win[0].len >= 0x20) | ||
| 285 | try_slave = 1; | ||
| 286 | |||
| 261 | } else goto next_entry; | 287 | } else goto next_entry; |
| 262 | /* If we've got this far, we're done */ | 288 | /* If we've got this far, we're done */ |
| 263 | break; | 289 | break; |
| 264 | } | 290 | } |
| 265 | 291 | ||
| 292 | if ((cfg->mem.nwin > 0) || (stk->dflt.mem.nwin > 0)) { | ||
| 293 | win_req_t req; | ||
| 294 | memreq_t map; | ||
| 295 | cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &stk->dflt.mem; | ||
| 296 | |||
| 297 | if (mem->win[0].len < 16) | ||
| 298 | goto next_entry; | ||
| 299 | |||
| 300 | req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | ||
| 301 | req.Attributes |= WIN_ENABLE; | ||
| 302 | req.Base = mem->win[0].host_addr; | ||
| 303 | req.Size = 0; | ||
| 304 | |||
| 305 | req.AccessSpeed = 0; | ||
| 306 | if (pcmcia_request_window(&link, &req, &link->win) != 0) | ||
| 307 | goto next_entry; | ||
| 308 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; | ||
| 309 | if (pcmcia_map_mem_page(link->win, &map) != 0) | ||
| 310 | goto next_entry; | ||
| 311 | |||
| 312 | io_base = (unsigned long) ioremap(req.Base, req.Size); | ||
| 313 | ctl_base = io_base + 0x0e; | ||
| 314 | is_mmio = 1; | ||
| 315 | |||
| 316 | if (mem->win[0].len >= 0x20) | ||
| 317 | try_slave = 1; | ||
| 318 | |||
| 319 | break; | ||
| 320 | } | ||
| 321 | |||
| 266 | next_entry: | 322 | next_entry: |
| 267 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | 323 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) |
| 268 | memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); | 324 | memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); |
| @@ -278,21 +334,26 @@ static int ide_config(struct pcmcia_device *link) | |||
| 278 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | 334 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
| 279 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 335 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
| 280 | 336 | ||
| 337 | if(is_mmio) | ||
| 338 | my_outb = outb_mem; | ||
| 339 | else | ||
| 340 | my_outb = outb_io; | ||
| 341 | |||
| 281 | /* disable drive interrupts during IDE probe */ | 342 | /* disable drive interrupts during IDE probe */ |
| 282 | outb(0x02, ctl_base); | 343 | my_outb(0x02, ctl_base); |
| 283 | 344 | ||
| 284 | /* special setup for KXLC005 card */ | 345 | /* special setup for KXLC005 card */ |
| 285 | if (is_kme) | 346 | if (is_kme) |
| 286 | outb(0x81, ctl_base+1); | 347 | my_outb(0x81, ctl_base+1); |
| 287 | 348 | ||
| 288 | /* retry registration in case device is still spinning up */ | 349 | /* retry registration in case device is still spinning up */ |
| 289 | for (hd = -1, i = 0; i < 10; i++) { | 350 | for (hd = -1, i = 0; i < 10; i++) { |
| 290 | hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); | 351 | hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link, is_mmio); |
| 291 | if (hd >= 0) break; | 352 | if (hd >= 0) break; |
| 292 | if (link->io.NumPorts1 == 0x20) { | 353 | if (try_slave) { |
| 293 | outb(0x02, ctl_base + 0x10); | 354 | my_outb(0x02, ctl_base + 0x10); |
| 294 | hd = idecs_register(io_base + 0x10, ctl_base + 0x10, | 355 | hd = idecs_register(io_base + 0x10, ctl_base + 0x10, |
| 295 | link->irq.AssignedIRQ, link); | 356 | link->irq.AssignedIRQ, link, is_mmio); |
| 296 | if (hd >= 0) { | 357 | if (hd >= 0) { |
| 297 | io_base += 0x10; | 358 | io_base += 0x10; |
| 298 | ctl_base += 0x10; | 359 | ctl_base += 0x10; |
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 441de824ab6b..48434d7924eb 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c | |||
| @@ -387,7 +387,10 @@ static int com20020_resume(struct pcmcia_device *link) | |||
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | static struct pcmcia_device_id com20020_ids[] = { | 389 | static struct pcmcia_device_id com20020_ids[] = { |
| 390 | PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), | 390 | PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", |
| 391 | "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), | ||
| 392 | PCMCIA_DEVICE_PROD_ID12("SoHard AG", | ||
| 393 | "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7), | ||
| 391 | PCMCIA_DEVICE_NULL | 394 | PCMCIA_DEVICE_NULL |
| 392 | }; | 395 | }; |
| 393 | MODULE_DEVICE_TABLE(pcmcia, com20020_ids); | 396 | MODULE_DEVICE_TABLE(pcmcia, com20020_ids); |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index db03dc2646df..fbb41893ee81 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
| @@ -844,7 +844,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
| 844 | PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), | 844 | PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), |
| 845 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), | 845 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), |
| 846 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), | 846 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), |
| 847 | PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), | 847 | /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ |
| 848 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | 848 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), |
| 849 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | 849 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), |
| 850 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), | 850 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), |
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index a4d50940ebeb..5256342e8532 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
| @@ -214,11 +214,10 @@ static struct pccard_operations at91_cf_ops = { | |||
| 214 | 214 | ||
| 215 | /*--------------------------------------------------------------------------*/ | 215 | /*--------------------------------------------------------------------------*/ |
| 216 | 216 | ||
| 217 | static int __init at91_cf_probe(struct device *dev) | 217 | static int __init at91_cf_probe(struct platform_device *pdev) |
| 218 | { | 218 | { |
| 219 | struct at91_cf_socket *cf; | 219 | struct at91_cf_socket *cf; |
| 220 | struct at91_cf_data *board = dev->platform_data; | 220 | struct at91_cf_data *board = pdev->dev.platform_data; |
| 221 | struct platform_device *pdev = to_platform_device(dev); | ||
| 222 | struct resource *io; | 221 | struct resource *io; |
| 223 | unsigned int csa; | 222 | unsigned int csa; |
| 224 | int status; | 223 | int status; |
| @@ -236,7 +235,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
| 236 | 235 | ||
| 237 | cf->board = board; | 236 | cf->board = board; |
| 238 | cf->pdev = pdev; | 237 | cf->pdev = pdev; |
| 239 | dev_set_drvdata(dev, cf); | 238 | platform_set_drvdata(pdev, cf); |
| 240 | 239 | ||
| 241 | /* CF takes over CS4, CS5, CS6 */ | 240 | /* CF takes over CS4, CS5, CS6 */ |
| 242 | csa = at91_sys_read(AT91_EBI_CSA); | 241 | csa = at91_sys_read(AT91_EBI_CSA); |
| @@ -271,6 +270,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
| 271 | SA_SAMPLE_RANDOM, driver_name, cf); | 270 | SA_SAMPLE_RANDOM, driver_name, cf); |
| 272 | if (status < 0) | 271 | if (status < 0) |
| 273 | goto fail0; | 272 | goto fail0; |
| 273 | device_init_wakeup(&pdev->dev, 1); | ||
| 274 | 274 | ||
| 275 | /* | 275 | /* |
| 276 | * The card driver will request this irq later as needed. | 276 | * The card driver will request this irq later as needed. |
| @@ -301,7 +301,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
| 301 | board->det_pin, board->irq_pin); | 301 | board->det_pin, board->irq_pin); |
| 302 | 302 | ||
| 303 | cf->socket.owner = THIS_MODULE; | 303 | cf->socket.owner = THIS_MODULE; |
| 304 | cf->socket.dev.dev = dev; | 304 | cf->socket.dev.dev = &pdev->dev; |
| 305 | cf->socket.ops = &at91_cf_ops; | 305 | cf->socket.ops = &at91_cf_ops; |
| 306 | cf->socket.resource_ops = &pccard_static_ops; | 306 | cf->socket.resource_ops = &pccard_static_ops; |
| 307 | cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | 307 | cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP |
| @@ -323,21 +323,25 @@ fail1: | |||
| 323 | free_irq(board->irq_pin, cf); | 323 | free_irq(board->irq_pin, cf); |
| 324 | fail0a: | 324 | fail0a: |
| 325 | free_irq(board->det_pin, cf); | 325 | free_irq(board->det_pin, cf); |
| 326 | device_init_wakeup(&pdev->dev, 0); | ||
| 326 | fail0: | 327 | fail0: |
| 327 | at91_sys_write(AT91_EBI_CSA, csa); | 328 | at91_sys_write(AT91_EBI_CSA, csa); |
| 328 | kfree(cf); | 329 | kfree(cf); |
| 329 | return status; | 330 | return status; |
| 330 | } | 331 | } |
| 331 | 332 | ||
| 332 | static int __exit at91_cf_remove(struct device *dev) | 333 | static int __exit at91_cf_remove(struct platform_device *pdev) |
| 333 | { | 334 | { |
| 334 | struct at91_cf_socket *cf = dev_get_drvdata(dev); | 335 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); |
| 336 | struct at91_cf_data *board = cf->board; | ||
| 335 | struct resource *io = cf->socket.io[0].res; | 337 | struct resource *io = cf->socket.io[0].res; |
| 336 | unsigned int csa; | 338 | unsigned int csa; |
| 337 | 339 | ||
| 338 | pcmcia_unregister_socket(&cf->socket); | 340 | pcmcia_unregister_socket(&cf->socket); |
| 339 | free_irq(cf->board->irq_pin, cf); | 341 | if (board->irq_pin) |
| 340 | free_irq(cf->board->det_pin, cf); | 342 | free_irq(board->irq_pin, cf); |
| 343 | free_irq(board->det_pin, cf); | ||
| 344 | device_init_wakeup(&pdev->dev, 0); | ||
| 341 | iounmap((void __iomem *) cf->socket.io_offset); | 345 | iounmap((void __iomem *) cf->socket.io_offset); |
| 342 | release_mem_region(io->start, io->end + 1 - io->start); | 346 | release_mem_region(io->start, io->end + 1 - io->start); |
| 343 | 347 | ||
| @@ -348,26 +352,65 @@ static int __exit at91_cf_remove(struct device *dev) | |||
| 348 | return 0; | 352 | return 0; |
| 349 | } | 353 | } |
| 350 | 354 | ||
| 351 | static struct device_driver at91_cf_driver = { | 355 | #ifdef CONFIG_PM |
| 352 | .name = (char *) driver_name, | 356 | |
| 353 | .bus = &platform_bus_type, | 357 | static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) |
| 358 | { | ||
| 359 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); | ||
| 360 | struct at91_cf_data *board = cf->board; | ||
| 361 | |||
| 362 | pcmcia_socket_dev_suspend(&pdev->dev, mesg); | ||
| 363 | if (device_may_wakeup(&pdev->dev)) | ||
| 364 | enable_irq_wake(board->det_pin); | ||
| 365 | else { | ||
| 366 | disable_irq_wake(board->det_pin); | ||
| 367 | disable_irq(board->det_pin); | ||
| 368 | } | ||
| 369 | if (board->irq_pin) | ||
| 370 | disable_irq(board->irq_pin); | ||
| 371 | return 0; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int at91_cf_resume(struct platform_device *pdev) | ||
| 375 | { | ||
| 376 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); | ||
| 377 | struct at91_cf_data *board = cf->board; | ||
| 378 | |||
| 379 | if (board->irq_pin) | ||
| 380 | enable_irq(board->irq_pin); | ||
| 381 | if (!device_may_wakeup(&pdev->dev)) | ||
| 382 | enable_irq(board->det_pin); | ||
| 383 | pcmcia_socket_dev_resume(&pdev->dev); | ||
| 384 | return 0; | ||
| 385 | } | ||
| 386 | |||
| 387 | #else | ||
| 388 | #define at91_cf_suspend NULL | ||
| 389 | #define at91_cf_resume NULL | ||
| 390 | #endif | ||
| 391 | |||
| 392 | static struct platform_driver at91_cf_driver = { | ||
| 393 | .driver = { | ||
| 394 | .name = (char *) driver_name, | ||
| 395 | .owner = THIS_MODULE, | ||
| 396 | }, | ||
| 354 | .probe = at91_cf_probe, | 397 | .probe = at91_cf_probe, |
| 355 | .remove = __exit_p(at91_cf_remove), | 398 | .remove = __exit_p(at91_cf_remove), |
| 356 | .suspend = pcmcia_socket_dev_suspend, | 399 | .suspend = at91_cf_suspend, |
| 357 | .resume = pcmcia_socket_dev_resume, | 400 | .resume = at91_cf_resume, |
| 358 | }; | 401 | }; |
| 359 | 402 | ||
| 360 | /*--------------------------------------------------------------------------*/ | 403 | /*--------------------------------------------------------------------------*/ |
| 361 | 404 | ||
| 362 | static int __init at91_cf_init(void) | 405 | static int __init at91_cf_init(void) |
| 363 | { | 406 | { |
| 364 | return driver_register(&at91_cf_driver); | 407 | return platform_driver_register(&at91_cf_driver); |
| 365 | } | 408 | } |
| 366 | module_init(at91_cf_init); | 409 | module_init(at91_cf_init); |
| 367 | 410 | ||
| 368 | static void __exit at91_cf_exit(void) | 411 | static void __exit at91_cf_exit(void) |
| 369 | { | 412 | { |
| 370 | driver_unregister(&at91_cf_driver); | 413 | platform_driver_unregister(&at91_cf_driver); |
| 371 | } | 414 | } |
| 372 | module_exit(at91_cf_exit); | 415 | module_exit(at91_cf_exit); |
| 373 | 416 | ||
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c index abc13f28ba3f..fef99f4e30c3 100644 --- a/drivers/pcmcia/au1000_db1x00.c +++ b/drivers/pcmcia/au1000_db1x00.c | |||
| @@ -296,7 +296,7 @@ struct pcmcia_low_level db1x00_pcmcia_ops = { | |||
| 296 | .socket_suspend = db1x00_socket_suspend | 296 | .socket_suspend = db1x00_socket_suspend |
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| 299 | int __init au1x_board_init(struct device *dev) | 299 | int au1x_board_init(struct device *dev) |
| 300 | { | 300 | { |
| 301 | int ret = -ENODEV; | 301 | int ret = -ENODEV; |
| 302 | bcsr->pcmcia = 0; /* turn off power, if it's not already off */ | 302 | bcsr->pcmcia = 0; /* turn off power, if it's not already off */ |
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 3162998579c1..f9cd831a3f31 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/pm.h> | 28 | #include <linux/pm.h> |
| 29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
| 30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
| 31 | #include <linux/kthread.h> | ||
| 31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
| 32 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
| 33 | 34 | ||
| @@ -176,6 +177,7 @@ static int pccardd(void *__skt); | |||
| 176 | */ | 177 | */ |
| 177 | int pcmcia_register_socket(struct pcmcia_socket *socket) | 178 | int pcmcia_register_socket(struct pcmcia_socket *socket) |
| 178 | { | 179 | { |
| 180 | struct task_struct *tsk; | ||
| 179 | int ret; | 181 | int ret; |
| 180 | 182 | ||
| 181 | if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops) | 183 | if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops) |
| @@ -239,15 +241,18 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) | |||
| 239 | mutex_init(&socket->skt_mutex); | 241 | mutex_init(&socket->skt_mutex); |
| 240 | spin_lock_init(&socket->thread_lock); | 242 | spin_lock_init(&socket->thread_lock); |
| 241 | 243 | ||
| 242 | ret = kernel_thread(pccardd, socket, CLONE_KERNEL); | 244 | tsk = kthread_run(pccardd, socket, "pccardd"); |
| 243 | if (ret < 0) | 245 | if (IS_ERR(tsk)) { |
| 246 | ret = PTR_ERR(tsk); | ||
| 244 | goto err; | 247 | goto err; |
| 248 | } | ||
| 245 | 249 | ||
| 246 | wait_for_completion(&socket->thread_done); | 250 | wait_for_completion(&socket->thread_done); |
| 247 | if(!socket->thread) { | 251 | if (!socket->thread) { |
| 248 | printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket); | 252 | printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket); |
| 249 | return -EIO; | 253 | return -EIO; |
| 250 | } | 254 | } |
| 255 | |||
| 251 | pcmcia_parse_events(socket, SS_DETECT); | 256 | pcmcia_parse_events(socket, SS_DETECT); |
| 252 | 257 | ||
| 253 | return 0; | 258 | return 0; |
| @@ -272,10 +277,8 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket) | |||
| 272 | cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops); | 277 | cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops); |
| 273 | 278 | ||
| 274 | if (socket->thread) { | 279 | if (socket->thread) { |
| 275 | init_completion(&socket->thread_done); | ||
| 276 | socket->thread = NULL; | ||
| 277 | wake_up(&socket->thread_wait); | 280 | wake_up(&socket->thread_wait); |
| 278 | wait_for_completion(&socket->thread_done); | 281 | kthread_stop(socket->thread); |
| 279 | } | 282 | } |
| 280 | release_cis_mem(socket); | 283 | release_cis_mem(socket); |
| 281 | 284 | ||
| @@ -630,8 +633,6 @@ static int pccardd(void *__skt) | |||
| 630 | DECLARE_WAITQUEUE(wait, current); | 633 | DECLARE_WAITQUEUE(wait, current); |
| 631 | int ret; | 634 | int ret; |
| 632 | 635 | ||
| 633 | daemonize("pccardd"); | ||
| 634 | |||
| 635 | skt->thread = current; | 636 | skt->thread = current; |
| 636 | skt->socket = dead_socket; | 637 | skt->socket = dead_socket; |
| 637 | skt->ops->init(skt); | 638 | skt->ops->init(skt); |
| @@ -643,7 +644,8 @@ static int pccardd(void *__skt) | |||
| 643 | printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", | 644 | printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", |
| 644 | skt); | 645 | skt); |
| 645 | skt->thread = NULL; | 646 | skt->thread = NULL; |
| 646 | complete_and_exit(&skt->thread_done, 0); | 647 | complete(&skt->thread_done); |
| 648 | return 0; | ||
| 647 | } | 649 | } |
| 648 | 650 | ||
| 649 | add_wait_queue(&skt->thread_wait, &wait); | 651 | add_wait_queue(&skt->thread_wait, &wait); |
| @@ -674,7 +676,7 @@ static int pccardd(void *__skt) | |||
| 674 | continue; | 676 | continue; |
| 675 | } | 677 | } |
| 676 | 678 | ||
| 677 | if (!skt->thread) | 679 | if (kthread_should_stop()) |
| 678 | break; | 680 | break; |
| 679 | 681 | ||
| 680 | schedule(); | 682 | schedule(); |
| @@ -688,7 +690,7 @@ static int pccardd(void *__skt) | |||
| 688 | /* remove from the device core */ | 690 | /* remove from the device core */ |
| 689 | class_device_unregister(&skt->dev); | 691 | class_device_unregister(&skt->dev); |
| 690 | 692 | ||
| 691 | complete_and_exit(&skt->thread_done, 0); | 693 | return 0; |
| 692 | } | 694 | } |
| 693 | 695 | ||
| 694 | /* | 696 | /* |
| @@ -697,11 +699,12 @@ static int pccardd(void *__skt) | |||
| 697 | */ | 699 | */ |
| 698 | void pcmcia_parse_events(struct pcmcia_socket *s, u_int events) | 700 | void pcmcia_parse_events(struct pcmcia_socket *s, u_int events) |
| 699 | { | 701 | { |
| 702 | unsigned long flags; | ||
| 700 | cs_dbg(s, 4, "parse_events: events %08x\n", events); | 703 | cs_dbg(s, 4, "parse_events: events %08x\n", events); |
| 701 | if (s->thread) { | 704 | if (s->thread) { |
| 702 | spin_lock(&s->thread_lock); | 705 | spin_lock_irqsave(&s->thread_lock, flags); |
| 703 | s->thread_events |= events; | 706 | s->thread_events |= events; |
| 704 | spin_unlock(&s->thread_lock); | 707 | spin_unlock_irqrestore(&s->thread_lock, flags); |
| 705 | 708 | ||
| 706 | wake_up(&s->thread_wait); | 709 | wake_up(&s->thread_wait); |
| 707 | } | 710 | } |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 3131bb0a0095..3281e519e714 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
| @@ -788,6 +788,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
| 788 | struct pcmcia_socket *s = p_dev->socket; | 788 | struct pcmcia_socket *s = p_dev->socket; |
| 789 | config_t *c; | 789 | config_t *c; |
| 790 | int ret = CS_IN_USE, irq = 0; | 790 | int ret = CS_IN_USE, irq = 0; |
| 791 | int type; | ||
| 791 | 792 | ||
| 792 | if (!(s->state & SOCKET_PRESENT)) | 793 | if (!(s->state & SOCKET_PRESENT)) |
| 793 | return CS_NO_CARD; | 794 | return CS_NO_CARD; |
| @@ -797,6 +798,13 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
| 797 | if (c->state & CONFIG_IRQ_REQ) | 798 | if (c->state & CONFIG_IRQ_REQ) |
| 798 | return CS_IN_USE; | 799 | return CS_IN_USE; |
| 799 | 800 | ||
| 801 | /* Decide what type of interrupt we are registering */ | ||
| 802 | type = 0; | ||
| 803 | if (s->functions > 1) /* All of this ought to be handled higher up */ | ||
| 804 | type = SA_SHIRQ; | ||
| 805 | if (req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) | ||
| 806 | type = SA_SHIRQ; | ||
| 807 | |||
| 800 | #ifdef CONFIG_PCMCIA_PROBE | 808 | #ifdef CONFIG_PCMCIA_PROBE |
| 801 | if (s->irq.AssignedIRQ != 0) { | 809 | if (s->irq.AssignedIRQ != 0) { |
| 802 | /* If the interrupt is already assigned, it must be the same */ | 810 | /* If the interrupt is already assigned, it must be the same */ |
| @@ -822,9 +830,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
| 822 | * marked as used by the kernel resource management core */ | 830 | * marked as used by the kernel resource management core */ |
| 823 | ret = request_irq(irq, | 831 | ret = request_irq(irq, |
| 824 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, | 832 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, |
| 825 | ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || | 833 | type, |
| 826 | (s->functions > 1) || | ||
| 827 | (irq == s->pci_irq)) ? SA_SHIRQ : 0, | ||
| 828 | p_dev->devname, | 834 | p_dev->devname, |
| 829 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); | 835 | (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); |
| 830 | if (!ret) { | 836 | if (!ret) { |
| @@ -839,18 +845,21 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
| 839 | if (ret && !s->irq.AssignedIRQ) { | 845 | if (ret && !s->irq.AssignedIRQ) { |
| 840 | if (!s->pci_irq) | 846 | if (!s->pci_irq) |
| 841 | return ret; | 847 | return ret; |
| 848 | type = SA_SHIRQ; | ||
| 842 | irq = s->pci_irq; | 849 | irq = s->pci_irq; |
| 843 | } | 850 | } |
| 844 | 851 | ||
| 845 | if (ret && req->Attributes & IRQ_HANDLE_PRESENT) { | 852 | if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) { |
| 846 | if (request_irq(irq, req->Handler, | 853 | if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance)) |
| 847 | ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || | ||
| 848 | (s->functions > 1) || | ||
| 849 | (irq == s->pci_irq)) ? SA_SHIRQ : 0, | ||
| 850 | p_dev->devname, req->Instance)) | ||
| 851 | return CS_IN_USE; | 854 | return CS_IN_USE; |
| 852 | } | 855 | } |
| 853 | 856 | ||
| 857 | /* Make sure the fact the request type was overridden is passed back */ | ||
| 858 | if (type == SA_SHIRQ && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { | ||
| 859 | req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; | ||
| 860 | printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n"); | ||
| 861 | printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n"); | ||
| 862 | } | ||
| 854 | c->irq.Attributes = req->Attributes; | 863 | c->irq.Attributes = req->Attributes; |
| 855 | s->irq.AssignedIRQ = req->AssignedIRQ = irq; | 864 | s->irq.AssignedIRQ = req->AssignedIRQ = irq; |
| 856 | s->irq.Config++; | 865 | s->irq.Config++; |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 7a3d1b8e16b9..62e9ebf967f9 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
| @@ -647,6 +647,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
| 647 | */ | 647 | */ |
| 648 | break; | 648 | break; |
| 649 | 649 | ||
| 650 | case PCI_DEVICE_ID_TI_XX12: | ||
| 650 | case PCI_DEVICE_ID_TI_X515: | 651 | case PCI_DEVICE_ID_TI_X515: |
| 651 | case PCI_DEVICE_ID_TI_X420: | 652 | case PCI_DEVICE_ID_TI_X420: |
| 652 | case PCI_DEVICE_ID_TI_X620: | 653 | case PCI_DEVICE_ID_TI_X620: |
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), |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 2c70773543e0..cbf260bc225d 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
| @@ -786,6 +786,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
| 786 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), | 786 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), |
| 787 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), | 787 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), |
| 788 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), | 788 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), |
| 789 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), | ||
| 789 | /* too generic */ | 790 | /* too generic */ |
| 790 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ | 791 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ |
| 791 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ | 792 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9ae6b1a75366..b093479a531d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -729,6 +729,7 @@ | |||
| 729 | #define PCI_DEVICE_ID_TI_4450 0x8011 | 729 | #define PCI_DEVICE_ID_TI_4450 0x8011 |
| 730 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 | 730 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 |
| 731 | #define PCI_DEVICE_ID_TI_X515 0x8036 | 731 | #define PCI_DEVICE_ID_TI_X515 0x8036 |
| 732 | #define PCI_DEVICE_ID_TI_XX12 0x8039 | ||
| 732 | #define PCI_DEVICE_ID_TI_1130 0xac12 | 733 | #define PCI_DEVICE_ID_TI_1130 0xac12 |
| 733 | #define PCI_DEVICE_ID_TI_1031 0xac13 | 734 | #define PCI_DEVICE_ID_TI_1031 0xac13 |
| 734 | #define PCI_DEVICE_ID_TI_1131 0xac15 | 735 | #define PCI_DEVICE_ID_TI_1131 0xac15 |
