aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig7
-rw-r--r--drivers/serial/amba-pl010.c9
-rw-r--r--drivers/serial/ioc3_serial.c5
-rw-r--r--drivers/serial/mfd.c18
-rw-r--r--drivers/serial/mpc52xx_uart.c1
-rw-r--r--drivers/serial/mrst_max3110.c1
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/serial_cs.c261
8 files changed, 134 insertions, 170 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 12900f7083b0..3198c5335f0b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS
458 int 458 int
459 depends on ARM && PLAT_SAMSUNG 459 depends on ARM && PLAT_SAMSUNG
460 default 2 if ARCH_S3C2400 460 default 2 if ARCH_S3C2400
461 default 6 if ARCH_S5P6450
461 default 4 if SERIAL_SAMSUNG_UARTS_4 462 default 4 if SERIAL_SAMSUNG_UARTS_4
462 default 3 463 default 3
463 help 464 help
@@ -526,12 +527,12 @@ config SERIAL_S3C24A0
526 Serial port support for the Samsung S3C24A0 SoC 527 Serial port support for the Samsung S3C24A0 SoC
527 528
528config SERIAL_S3C6400 529config SERIAL_S3C6400
529 tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support" 530 tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
530 depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100) 531 depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
531 select SERIAL_SAMSUNG_UARTS_4 532 select SERIAL_SAMSUNG_UARTS_4
532 default y 533 default y
533 help 534 help
534 Serial port support for the Samsung S3C6400, S3C6410, S5P6440 535 Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
535 and S5PC100 SoCs 536 and S5PC100 SoCs
536 537
537config SERIAL_S5PV210 538config SERIAL_S5PV210
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 50441ffe8e38..2904aa044126 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -472,14 +472,9 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
472 spin_unlock_irqrestore(&uap->port.lock, flags); 472 spin_unlock_irqrestore(&uap->port.lock, flags);
473} 473}
474 474
475static void pl010_set_ldisc(struct uart_port *port) 475static void pl010_set_ldisc(struct uart_port *port, int new)
476{ 476{
477 int line = port->line; 477 if (new == N_PPS) {
478
479 if (line >= port->state->port.tty->driver->num)
480 return;
481
482 if (port->state->port.tty->ldisc->ops->num == N_PPS) {
483 port->flags |= UPF_HARDPPS_CD; 478 port->flags |= UPF_HARDPPS_CD;
484 pl010_enable_ms(port); 479 pl010_enable_ms(port);
485 } else 480 } else
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 93de907b1208..ee43efc7bdcc 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -2017,6 +2017,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
2017 struct ioc3_port *port; 2017 struct ioc3_port *port;
2018 struct ioc3_port *ports[PORTS_PER_CARD]; 2018 struct ioc3_port *ports[PORTS_PER_CARD];
2019 int phys_port; 2019 int phys_port;
2020 int cnt;
2020 2021
2021 DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd)); 2022 DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd));
2022 2023
@@ -2044,6 +2045,7 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
2044 if (!port) { 2045 if (!port) {
2045 printk(KERN_WARNING 2046 printk(KERN_WARNING
2046 "IOC3 serial memory not available for port\n"); 2047 "IOC3 serial memory not available for port\n");
2048 ret = -ENOMEM;
2047 goto out4; 2049 goto out4;
2048 } 2050 }
2049 spin_lock_init(&port->ip_lock); 2051 spin_lock_init(&port->ip_lock);
@@ -2146,6 +2148,9 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
2146 2148
2147 /* error exits that give back resources */ 2149 /* error exits that give back resources */
2148out4: 2150out4:
2151 for (cnt = 0; cnt < phys_port; cnt++)
2152 kfree(ports[cnt]);
2153
2149 kfree(card_ptr); 2154 kfree(card_ptr);
2150 return ret; 2155 return ret;
2151} 2156}
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c
index bc9af503907f..5dff45c76d32 100644
--- a/drivers/serial/mfd.c
+++ b/drivers/serial/mfd.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/sysrq.h> 29#include <linux/sysrq.h>
30#include <linux/slab.h>
30#include <linux/serial_reg.h> 31#include <linux/serial_reg.h>
31#include <linux/circ_buf.h> 32#include <linux/circ_buf.h>
32#include <linux/delay.h> 33#include <linux/delay.h>
@@ -1423,7 +1424,6 @@ static void hsu_global_init(void)
1423 } 1424 }
1424 1425
1425 phsu = hsu; 1426 phsu = hsu;
1426
1427 hsu_debugfs_init(hsu); 1427 hsu_debugfs_init(hsu);
1428 return; 1428 return;
1429 1429
@@ -1435,18 +1435,20 @@ err_free_region:
1435 1435
1436static void serial_hsu_remove(struct pci_dev *pdev) 1436static void serial_hsu_remove(struct pci_dev *pdev)
1437{ 1437{
1438 struct hsu_port *hsu; 1438 void *priv = pci_get_drvdata(pdev);
1439 int i; 1439 struct uart_hsu_port *up;
1440 1440
1441 hsu = pci_get_drvdata(pdev); 1441 if (!priv)
1442 if (!hsu)
1443 return; 1442 return;
1444 1443
1445 for (i = 0; i < 3; i++) 1444 /* For port 0/1/2, priv is the address of uart_hsu_port */
1446 uart_remove_one_port(&serial_hsu_reg, &hsu->port[i].port); 1445 if (pdev->device != 0x081E) {
1446 up = priv;
1447 uart_remove_one_port(&serial_hsu_reg, &up->port);
1448 }
1447 1449
1448 pci_set_drvdata(pdev, NULL); 1450 pci_set_drvdata(pdev, NULL);
1449 free_irq(hsu->irq, hsu); 1451 free_irq(pdev->irq, priv);
1450 pci_disable_device(pdev); 1452 pci_disable_device(pdev);
1451} 1453}
1452 1454
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 8dedb266f143..c4399e23565a 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -500,6 +500,7 @@ static int __init mpc512x_psc_fifoc_init(void)
500 psc_fifoc = of_iomap(np, 0); 500 psc_fifoc = of_iomap(np, 0);
501 if (!psc_fifoc) { 501 if (!psc_fifoc) {
502 pr_err("%s: Can't map FIFOC\n", __func__); 502 pr_err("%s: Can't map FIFOC\n", __func__);
503 of_node_put(np);
503 return -ENODEV; 504 return -ENODEV;
504 } 505 }
505 506
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c
index f6ad1ecbff79..51c15f58e01e 100644
--- a/drivers/serial/mrst_max3110.c
+++ b/drivers/serial/mrst_max3110.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/irq.h>
32#include <linux/init.h> 33#include <linux/init.h>
33#include <linux/console.h> 34#include <linux/console.h>
34#include <linux/sysrq.h> 35#include <linux/sysrq.h>
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index b1156ba8ad14..7ac2bf5167cd 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -1101,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1101 dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); 1101 dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
1102 1102
1103 port->mapbase = res->start; 1103 port->mapbase = res->start;
1104 port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000); 1104 port->membase = S3C_VA_UART + (res->start & 0xfffff);
1105 ret = platform_get_irq(platdev, 0); 1105 ret = platform_get_irq(platdev, 0);
1106 if (ret < 0) 1106 if (ret < 0)
1107 port->irq = 0; 1107 port->irq = 0;
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 141c69554bd4..93760b2ea172 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -45,7 +45,6 @@
45#include <asm/io.h> 45#include <asm/io.h>
46#include <asm/system.h> 46#include <asm/system.h>
47 47
48#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
50#include <pcmcia/ciscode.h> 49#include <pcmcia/ciscode.h>
51#include <pcmcia/ds.h> 50#include <pcmcia/ds.h>
@@ -183,10 +182,8 @@ static void quirk_config_socket(struct pcmcia_device *link)
183{ 182{
184 struct serial_info *info = link->priv; 183 struct serial_info *info = link->priv;
185 184
186 if (info->multi) { 185 if (info->multi)
187 link->conf.Present |= PRESENT_EXT_STATUS; 186 link->config_flags |= CONF_ENABLE_ESR;
188 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
189 }
190} 187}
191 188
192static const struct serial_quirk quirks[] = { 189static const struct serial_quirk quirks[] = {
@@ -265,13 +262,6 @@ static const struct serial_quirk quirks[] = {
265static int serial_config(struct pcmcia_device * link); 262static int serial_config(struct pcmcia_device * link);
266 263
267 264
268/*======================================================================
269
270 After a card is removed, serial_remove() will unregister
271 the serial device(s), and release the PCMCIA configuration.
272
273======================================================================*/
274
275static void serial_remove(struct pcmcia_device *link) 265static void serial_remove(struct pcmcia_device *link)
276{ 266{
277 struct serial_info *info = link->priv; 267 struct serial_info *info = link->priv;
@@ -314,14 +304,6 @@ static int serial_resume(struct pcmcia_device *link)
314 return 0; 304 return 0;
315} 305}
316 306
317/*======================================================================
318
319 serial_attach() creates an "instance" of the driver, allocating
320 local data structures for one device. The device is registered
321 with Card Services.
322
323======================================================================*/
324
325static int serial_probe(struct pcmcia_device *link) 307static int serial_probe(struct pcmcia_device *link)
326{ 308{
327 struct serial_info *info; 309 struct serial_info *info;
@@ -335,27 +317,13 @@ static int serial_probe(struct pcmcia_device *link)
335 info->p_dev = link; 317 info->p_dev = link;
336 link->priv = info; 318 link->priv = info;
337 319
338 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 320 link->config_flags |= CONF_ENABLE_IRQ;
339 link->resource[0]->end = 8; 321 if (do_sound)
340 link->conf.Attributes = CONF_ENABLE_IRQ; 322 link->config_flags |= CONF_ENABLE_SPKR;
341 if (do_sound) {
342 link->conf.Attributes |= CONF_ENABLE_SPKR;
343 link->conf.Status = CCSR_AUDIO_ENA;
344 }
345 link->conf.IntType = INT_MEMORY_AND_IO;
346 323
347 return serial_config(link); 324 return serial_config(link);
348} 325}
349 326
350/*======================================================================
351
352 This deletes a driver "instance". The device is de-registered
353 with Card Services. If it has been released, all local data
354 structures are freed. Otherwise, the structures will be freed
355 when the device is released.
356
357======================================================================*/
358
359static void serial_detach(struct pcmcia_device *link) 327static void serial_detach(struct pcmcia_device *link)
360{ 328{
361 struct serial_info *info = link->priv; 329 struct serial_info *info = link->priv;
@@ -363,11 +331,6 @@ static void serial_detach(struct pcmcia_device *link)
363 dev_dbg(&link->dev, "serial_detach\n"); 331 dev_dbg(&link->dev, "serial_detach\n");
364 332
365 /* 333 /*
366 * Ensure any outstanding scheduled tasks are completed.
367 */
368 flush_scheduled_work();
369
370 /*
371 * Ensure that the ports have been released. 334 * Ensure that the ports have been released.
372 */ 335 */
373 serial_remove(link); 336 serial_remove(link);
@@ -411,47 +374,66 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
411 374
412/*====================================================================*/ 375/*====================================================================*/
413 376
414static int simple_config_check(struct pcmcia_device *p_dev, 377static int pfc_config(struct pcmcia_device *p_dev)
415 cistpl_cftable_entry_t *cf, 378{
416 cistpl_cftable_entry_t *dflt, 379 unsigned int port = 0;
417 unsigned int vcc, 380 struct serial_info *info = p_dev->priv;
418 void *priv_data) 381
382 if ((p_dev->resource[1]->end != 0) &&
383 (resource_size(p_dev->resource[1]) == 8)) {
384 port = p_dev->resource[1]->start;
385 info->slave = 1;
386 } else if ((info->manfid == MANFID_OSITECH) &&
387 (resource_size(p_dev->resource[0]) == 0x40)) {
388 port = p_dev->resource[0]->start + 0x28;
389 info->slave = 1;
390 }
391 if (info->slave)
392 return setup_serial(p_dev, info, port, p_dev->irq);
393
394 dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
395 return -ENODEV;
396}
397
398static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
419{ 399{
420 static const int size_table[2] = { 8, 16 }; 400 static const int size_table[2] = { 8, 16 };
421 int *try = priv_data; 401 int *try = priv_data;
422 402
423 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) 403 if (p_dev->resource[0]->start == 0)
424 p_dev->conf.Vpp = 404 return -ENODEV;
425 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
426 405
427 p_dev->io_lines = ((*try & 0x1) == 0) ? 406 if ((*try & 0x1) == 0)
428 16 : cf->io.flags & CISTPL_IO_LINES_MASK; 407 p_dev->io_lines = 16;
429 408
430 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) 409 if (p_dev->resource[0]->end != size_table[(*try >> 1)])
431 && (cf->io.win[0].base != 0)) { 410 return -ENODEV;
432 p_dev->resource[0]->start = cf->io.win[0].base; 411
433 if (!pcmcia_request_io(p_dev)) 412 p_dev->resource[0]->end = 8;
434 return 0; 413 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
435 } 414 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
436 return -EINVAL; 415
416 return pcmcia_request_io(p_dev);
437} 417}
438 418
439static int simple_config_check_notpicky(struct pcmcia_device *p_dev, 419static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
440 cistpl_cftable_entry_t *cf,
441 cistpl_cftable_entry_t *dflt,
442 unsigned int vcc,
443 void *priv_data) 420 void *priv_data)
444{ 421{
445 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 422 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
446 int j; 423 int j;
447 424
448 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { 425 if (p_dev->io_lines > 3)
449 for (j = 0; j < 5; j++) { 426 return -ENODEV;
450 p_dev->resource[0]->start = base[j]; 427
451 p_dev->io_lines = base[j] ? 16 : 3; 428 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
452 if (!pcmcia_request_io(p_dev)) 429 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
453 return 0; 430 p_dev->resource[0]->end = 8;
454 } 431
432 for (j = 0; j < 5; j++) {
433 p_dev->resource[0]->start = base[j];
434 p_dev->io_lines = base[j] ? 16 : 3;
435 if (!pcmcia_request_io(p_dev))
436 return 0;
455 } 437 }
456 return -ENODEV; 438 return -ENODEV;
457} 439}
@@ -461,26 +443,9 @@ static int simple_config(struct pcmcia_device *link)
461 struct serial_info *info = link->priv; 443 struct serial_info *info = link->priv;
462 int i = -ENODEV, try; 444 int i = -ENODEV, try;
463 445
464 /* If the card is already configured, look up the port and irq */
465 if (link->function_config) {
466 unsigned int port = 0;
467 if ((link->resource[1]->end != 0) &&
468 (resource_size(link->resource[1]) == 8)) {
469 port = link->resource[1]->end;
470 info->slave = 1;
471 } else if ((info->manfid == MANFID_OSITECH) &&
472 (resource_size(link->resource[0]) == 0x40)) {
473 port = link->resource[0]->start + 0x28;
474 info->slave = 1;
475 }
476 if (info->slave) {
477 return setup_serial(link, info, port,
478 link->irq);
479 }
480 }
481
482 /* First pass: look for a config entry that looks normal. 446 /* First pass: look for a config entry that looks normal.
483 * Two tries: without IO aliases, then with aliases */ 447 * Two tries: without IO aliases, then with aliases */
448 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO;
484 for (try = 0; try < 4; try++) 449 for (try = 0; try < 4; try++)
485 if (!pcmcia_loop_config(link, simple_config_check, &try)) 450 if (!pcmcia_loop_config(link, simple_config_check, &try))
486 goto found_port; 451 goto found_port;
@@ -491,13 +456,12 @@ static int simple_config(struct pcmcia_device *link)
491 if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) 456 if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
492 goto found_port; 457 goto found_port;
493 458
494 printk(KERN_NOTICE 459 dev_warn(&link->dev, "no usable port range found, giving up\n");
495 "serial_cs: no usable port range found, giving up\n");
496 return -1; 460 return -1;
497 461
498found_port: 462found_port:
499 if (info->multi && (info->manfid == MANFID_3COM)) 463 if (info->multi && (info->manfid == MANFID_3COM))
500 link->conf.ConfigIndex &= ~(0x08); 464 link->config_index &= ~(0x08);
501 465
502 /* 466 /*
503 * Apply any configuration quirks. 467 * Apply any configuration quirks.
@@ -505,51 +469,50 @@ found_port:
505 if (info->quirk && info->quirk->config) 469 if (info->quirk && info->quirk->config)
506 info->quirk->config(link); 470 info->quirk->config(link);
507 471
508 i = pcmcia_request_configuration(link, &link->conf); 472 i = pcmcia_enable_device(link);
509 if (i != 0) 473 if (i != 0)
510 return -1; 474 return -1;
511 return setup_serial(link, info, link->resource[0]->start, link->irq); 475 return setup_serial(link, info, link->resource[0]->start, link->irq);
512} 476}
513 477
514static int multi_config_check(struct pcmcia_device *p_dev, 478static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
515 cistpl_cftable_entry_t *cf,
516 cistpl_cftable_entry_t *dflt,
517 unsigned int vcc,
518 void *priv_data)
519{ 479{
520 int *base2 = priv_data; 480 int *multi = priv_data;
481
482 if (p_dev->resource[1]->end)
483 return -EINVAL;
521 484
522 /* The quad port cards have bad CIS's, so just look for a 485 /* The quad port cards have bad CIS's, so just look for a
523 window larger than 8 ports and assume it will be right */ 486 window larger than 8 ports and assume it will be right */
524 if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { 487 if (p_dev->resource[0]->end <= 8)
525 p_dev->resource[0]->start = cf->io.win[0].base; 488 return -EINVAL;
526 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 489
527 if (!pcmcia_request_io(p_dev)) { 490 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
528 *base2 = p_dev->resource[0]->start + 8; 491 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
529 return 0; 492 p_dev->resource[0]->end = *multi * 8;
530 } 493
531 } 494 if (pcmcia_request_io(p_dev))
532 return -ENODEV; 495 return -ENODEV;
496 return 0;
533} 497}
534 498
535static int multi_config_check_notpicky(struct pcmcia_device *p_dev, 499static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
536 cistpl_cftable_entry_t *cf,
537 cistpl_cftable_entry_t *dflt,
538 unsigned int vcc,
539 void *priv_data) 500 void *priv_data)
540{ 501{
541 int *base2 = priv_data; 502 int *base2 = priv_data;
542 503
543 if (cf->io.nwin == 2) { 504 if (!p_dev->resource[0]->end || !p_dev->resource[1]->end)
544 p_dev->resource[0]->start = cf->io.win[0].base; 505 return -ENODEV;
545 p_dev->resource[1]->start = cf->io.win[1].base; 506
546 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 507 p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
547 if (!pcmcia_request_io(p_dev)) { 508 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
548 *base2 = p_dev->resource[1]->start; 509 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
549 return 0; 510
550 } 511 if (pcmcia_request_io(p_dev))
551 } 512 return -ENODEV;
552 return -ENODEV; 513
514 *base2 = p_dev->resource[0]->start + 8;
515 return 0;
553} 516}
554 517
555static int multi_config(struct pcmcia_device *link) 518static int multi_config(struct pcmcia_device *link)
@@ -557,23 +520,23 @@ static int multi_config(struct pcmcia_device *link)
557 struct serial_info *info = link->priv; 520 struct serial_info *info = link->priv;
558 int i, base2 = 0; 521 int i, base2 = 0;
559 522
523 link->config_flags |= CONF_AUTO_SET_IO;
560 /* First, look for a generic full-sized window */ 524 /* First, look for a generic full-sized window */
561 link->resource[0]->end = info->multi * 8; 525 if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
562 if (pcmcia_loop_config(link, multi_config_check, &base2)) { 526 base2 = link->resource[0]->start + 8;
527 else {
563 /* If that didn't work, look for two windows */ 528 /* If that didn't work, look for two windows */
564 link->resource[0]->end = link->resource[1]->end = 8;
565 info->multi = 2; 529 info->multi = 2;
566 if (pcmcia_loop_config(link, multi_config_check_notpicky, 530 if (pcmcia_loop_config(link, multi_config_check_notpicky,
567 &base2)) { 531 &base2)) {
568 printk(KERN_NOTICE "serial_cs: no usable port range" 532 dev_warn(&link->dev, "no usable port range "
569 "found, giving up\n"); 533 "found, giving up\n");
570 return -ENODEV; 534 return -ENODEV;
571 } 535 }
572 } 536 }
573 537
574 if (!link->irq) 538 if (!link->irq)
575 dev_warn(&link->dev, 539 dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
576 "serial_cs: no usable IRQ found, continuing...\n");
577 540
578 /* 541 /*
579 * Apply any configuration quirks. 542 * Apply any configuration quirks.
@@ -581,7 +544,7 @@ static int multi_config(struct pcmcia_device *link)
581 if (info->quirk && info->quirk->config) 544 if (info->quirk && info->quirk->config)
582 info->quirk->config(link); 545 info->quirk->config(link);
583 546
584 i = pcmcia_request_configuration(link, &link->conf); 547 i = pcmcia_enable_device(link);
585 if (i != 0) 548 if (i != 0)
586 return -ENODEV; 549 return -ENODEV;
587 550
@@ -593,11 +556,11 @@ static int multi_config(struct pcmcia_device *link)
593 info->prodid == PRODID_POSSIO_GCC)) { 556 info->prodid == PRODID_POSSIO_GCC)) {
594 int err; 557 int err;
595 558
596 if (link->conf.ConfigIndex == 1 || 559 if (link->config_index == 1 ||
597 link->conf.ConfigIndex == 3) { 560 link->config_index == 3) {
598 err = setup_serial(link, info, base2, 561 err = setup_serial(link, info, base2,
599 link->irq); 562 link->irq);
600 base2 = link->resource[0]->start;; 563 base2 = link->resource[0]->start;
601 } else { 564 } else {
602 err = setup_serial(link, info, link->resource[0]->start, 565 err = setup_serial(link, info, link->resource[0]->start,
603 link->irq); 566 link->irq);
@@ -621,33 +584,24 @@ static int multi_config(struct pcmcia_device *link)
621 return 0; 584 return 0;
622} 585}
623 586
624static int serial_check_for_multi(struct pcmcia_device *p_dev, 587static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data)
625 cistpl_cftable_entry_t *cf,
626 cistpl_cftable_entry_t *dflt,
627 unsigned int vcc,
628 void *priv_data)
629{ 588{
630 struct serial_info *info = p_dev->priv; 589 struct serial_info *info = p_dev->priv;
631 590
632 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) 591 if (!p_dev->resource[0]->end)
633 info->multi = cf->io.win[0].len >> 3; 592 return -EINVAL;
593
594 if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
595 info->multi = p_dev->resource[0]->end >> 3;
634 596
635 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && 597 if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
636 (cf->io.win[1].len == 8)) 598 && (p_dev->resource[1]->end == 8))
637 info->multi = 2; 599 info->multi = 2;
638 600
639 return 0; /* break */ 601 return 0; /* break */
640} 602}
641 603
642 604
643/*======================================================================
644
645 serial_config() is scheduled to run after a CARD_INSERTION event
646 is received, to configure the PCMCIA socket, and to make the
647 serial device available to the system.
648
649======================================================================*/
650
651static int serial_config(struct pcmcia_device * link) 605static int serial_config(struct pcmcia_device * link)
652{ 606{
653 struct serial_info *info = link->priv; 607 struct serial_info *info = link->priv;
@@ -675,6 +629,7 @@ static int serial_config(struct pcmcia_device * link)
675 multifunction cards that ask for appropriate IO port ranges */ 629 multifunction cards that ask for appropriate IO port ranges */
676 if ((info->multi == 0) && 630 if ((info->multi == 0) &&
677 (link->has_func_id) && 631 (link->has_func_id) &&
632 (link->socket->pcmcia_pfc == 0) &&
678 ((link->func_id == CISTPL_FUNCID_MULTI) || 633 ((link->func_id == CISTPL_FUNCID_MULTI) ||
679 (link->func_id == CISTPL_FUNCID_SERIAL))) 634 (link->func_id == CISTPL_FUNCID_SERIAL)))
680 pcmcia_loop_config(link, serial_check_for_multi, info); 635 pcmcia_loop_config(link, serial_check_for_multi, info);
@@ -685,7 +640,13 @@ static int serial_config(struct pcmcia_device * link)
685 if (info->quirk && info->quirk->multi != -1) 640 if (info->quirk && info->quirk->multi != -1)
686 info->multi = info->quirk->multi; 641 info->multi = info->quirk->multi;
687 642
688 if (info->multi > 1) 643 dev_info(&link->dev,
644 "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
645 link->manf_id, link->card_id,
646 link->socket->pcmcia_pfc, info->multi, info->quirk);
647 if (link->socket->pcmcia_pfc)
648 i = pfc_config(link);
649 else if (info->multi > 1)
689 i = multi_config(link); 650 i = multi_config(link);
690 else 651 else
691 i = simple_config(link); 652 i = simple_config(link);
@@ -704,7 +665,7 @@ static int serial_config(struct pcmcia_device * link)
704 return 0; 665 return 0;
705 666
706failed: 667failed:
707 dev_warn(&link->dev, "serial_cs: failed to initialize\n"); 668 dev_warn(&link->dev, "failed to initialize\n");
708 serial_remove(link); 669 serial_remove(link);
709 return -ENODEV; 670 return -ENODEV;
710} 671}
@@ -884,9 +845,7 @@ MODULE_FIRMWARE("cis/RS-COM-2P.cis");
884 845
885static struct pcmcia_driver serial_cs_driver = { 846static struct pcmcia_driver serial_cs_driver = {
886 .owner = THIS_MODULE, 847 .owner = THIS_MODULE,
887 .drv = { 848 .name = "serial_cs",
888 .name = "serial_cs",
889 },
890 .probe = serial_probe, 849 .probe = serial_probe,
891 .remove = serial_detach, 850 .remove = serial_detach,
892 .id_table = serial_ids, 851 .id_table = serial_ids,