diff options
Diffstat (limited to 'drivers')
-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 |
11 files changed, 255 insertions, 58 deletions
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), */ |