0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/pci.h>
0013 #include <linux/pnp.h>
0014 #include <linux/string.h>
0015 #include <linux/kernel.h>
0016 #include <linux/property.h>
0017 #include <linux/serial_core.h>
0018 #include <linux/bitops.h>
0019
0020 #include <asm/byteorder.h>
0021
0022 #include "8250.h"
0023
0024 #define UNKNOWN_DEV 0x3000
0025 #define CIR_PORT 0x0800
0026
0027 static const struct pnp_device_id pnp_dev_table[] = {
0028
0029
0030 { "AAC000F", 0 },
0031
0032
0033 { "ADC0001", 0 },
0034
0035 { "ADC0002", 0 },
0036
0037 { "AEI0250", 0 },
0038
0039 { "AEI1240", 0 },
0040
0041 { "AKY1021", 0 },
0042
0043
0044
0045
0046
0047 { "ALI5123", 0 },
0048
0049 { "AZT4001", 0 },
0050
0051 { "BDP3336", 0 },
0052
0053
0054 { "BRI0A49", 0 },
0055
0056 { "BRI1400", 0 },
0057
0058 { "BRI3400", 0 },
0059
0060
0061 { "CPI4050", 0 },
0062
0063
0064 { "CTL3001", 0 },
0065
0066 { "CTL3011", 0 },
0067
0068 { "DAV0336", 0 },
0069
0070
0071 { "DMB1032", 0 },
0072
0073 { "DMB2001", 0 },
0074
0075
0076 { "ETT0002", 0 },
0077
0078
0079 { "FUJ0202", 0 },
0080
0081 { "FUJ0205", 0 },
0082
0083 { "FUJ0206", 0 },
0084
0085 { "FUJ0209", 0 },
0086
0087
0088 { "GVC000F", 0 },
0089
0090 { "GVC0303", 0 },
0091
0092
0093 { "HAY0001", 0 },
0094
0095 { "HAY000C", 0 },
0096
0097 { "HAY000D", 0 },
0098
0099 { "HAY5670", 0 },
0100
0101 { "HAY5674", 0 },
0102
0103 { "HAY5675", 0 },
0104
0105 { "HAYF000", 0 },
0106
0107 { "HAYF001", 0 },
0108
0109
0110 { "IBM0033", 0 },
0111
0112
0113 { "PNP4972", 0 },
0114
0115
0116 { "IXDC801", 0 },
0117
0118 { "IXDC901", 0 },
0119
0120 { "IXDD801", 0 },
0121
0122 { "IXDD901", 0 },
0123
0124 { "IXDF401", 0 },
0125
0126 { "IXDF801", 0 },
0127
0128 { "IXDF901", 0 },
0129
0130
0131 { "KOR4522", 0 },
0132
0133 { "KORF661", 0 },
0134
0135
0136 { "LAS4040", 0 },
0137
0138 { "LAS4540", 0 },
0139
0140 { "LAS5440", 0 },
0141
0142
0143 { "MNP0281", 0 },
0144
0145 { "MNP0336", 0 },
0146
0147 { "MNP0339", 0 },
0148
0149 { "MNP0342", 0 },
0150
0151 { "MNP0500", 0 },
0152
0153 { "MNP0501", 0 },
0154
0155 { "MNP0502", 0 },
0156
0157
0158 { "MOT1105", 0 },
0159
0160 { "MOT1111", 0 },
0161
0162 { "MOT1114", 0 },
0163
0164 { "MOT1115", 0 },
0165
0166 { "MOT1190", 0 },
0167
0168 { "MOT1501", 0 },
0169
0170 { "MOT1502", 0 },
0171
0172 { "MOT1505", 0 },
0173
0174 { "MOT1509", 0 },
0175
0176 { "MOT150A", 0 },
0177
0178 { "MOT150F", 0 },
0179
0180 { "MOT1510", 0 },
0181
0182 { "MOT1550", 0 },
0183
0184 { "MOT1560", 0 },
0185
0186 { "MOT1580", 0 },
0187
0188 { "MOT15B0", 0 },
0189
0190 { "MOT15F0", 0 },
0191
0192
0193 { "MVX00A1", 0 },
0194
0195 { "MVX00F2", 0 },
0196
0197 { "nEC8241", 0 },
0198
0199 { "PMC2430", 0 },
0200
0201
0202 { "PNP0500", 0 },
0203
0204 { "PNP0501", 0 },
0205
0206 { "PNPC000", 0 },
0207
0208 { "PNPC001", 0 },
0209
0210 { "PNPC031", 0 },
0211
0212 { "PNPC032", 0 },
0213
0214 { "PNPC100", 0 },
0215
0216 { "PNPC101", 0 },
0217
0218 { "PNPC102", 0 },
0219
0220 { "PNPC103", 0 },
0221
0222 { "PNPC104", 0 },
0223
0224 { "PNPC105", 0 },
0225
0226 { "PNPC106", 0 },
0227
0228 { "PNPC107", 0 },
0229
0230 { "PNPC108", 0 },
0231
0232 { "PNPC109", 0 },
0233
0234 { "PNPC10A", 0 },
0235
0236 { "PNPC10B", 0 },
0237
0238 { "PNPC10C", 0 },
0239
0240 { "PNPC10D", 0 },
0241
0242 { "PNPC10E", 0 },
0243
0244 { "PNPC10F", 0 },
0245
0246 { "PNP2000", 0 },
0247
0248
0249
0250
0251 { "ROK0030", 0 },
0252
0253
0254 { "ROK0100", 0 },
0255
0256 { "ROK4120", 0 },
0257
0258
0259 { "ROK4920", 0 },
0260
0261
0262
0263
0264
0265
0266 { "RSS00A0", 0 },
0267
0268 { "RSS0262", 0 },
0269
0270 { "RSS0250", 0 },
0271
0272 { "SUP1310", 0 },
0273
0274 { "SUP1381", 0 },
0275
0276 { "SUP1421", 0 },
0277
0278 { "SUP1590", 0 },
0279
0280 { "SUP1620", 0 },
0281
0282 { "SUP1760", 0 },
0283
0284 { "SUP2171", 0 },
0285
0286
0287 { "TEX0011", 0 },
0288
0289
0290 { "UAC000F", 0 },
0291
0292
0293 { "USR0000", 0 },
0294
0295 { "USR0002", 0 },
0296
0297 { "USR0004", 0 },
0298
0299 { "USR0006", 0 },
0300
0301 { "USR0007", 0 },
0302
0303 { "USR0009", 0 },
0304
0305 { "USR2002", 0 },
0306
0307 { "USR2070", 0 },
0308
0309 { "USR2080", 0 },
0310
0311 { "USR3031", 0 },
0312
0313 { "USR3050", 0 },
0314
0315 { "USR3070", 0 },
0316
0317 { "USR3080", 0 },
0318
0319 { "USR3090", 0 },
0320
0321 { "USR9100", 0 },
0322
0323 { "USR9160", 0 },
0324
0325 { "USR9170", 0 },
0326
0327 { "USR9180", 0 },
0328
0329 { "USR9190", 0 },
0330
0331 { "WACFXXX", 0 },
0332
0333 { "FPI2002", 0 },
0334
0335 { "FUJ02B2", 0 },
0336 { "FUJ02B3", 0 },
0337
0338 { "FUJ02B4", 0 },
0339
0340 { "FUJ02B6", 0 },
0341 { "FUJ02B7", 0 },
0342 { "FUJ02B8", 0 },
0343 { "FUJ02B9", 0 },
0344 { "FUJ02BC", 0 },
0345
0346 { "FUJ02E5", 0 },
0347
0348 { "FUJ02E6", 0 },
0349
0350 { "FUJ02E7", 0 },
0351
0352 { "FUJ02E9", 0 },
0353
0354
0355
0356
0357 { "LTS0001", 0 },
0358
0359 { "WCI0003", 0 },
0360
0361 { "PNPCXXX", UNKNOWN_DEV },
0362
0363 { "PNPDXXX", UNKNOWN_DEV },
0364
0365
0366
0367
0368 { "WEC1022", CIR_PORT },
0369
0370
0371
0372
0373 { "SMCF010", CIR_PORT },
0374 { "", 0 }
0375 };
0376
0377 MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
0378
0379 static const char *modem_names[] = {
0380 "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
0381 "56K", "56k", "K56", "33.6", "28.8", "14.4",
0382 "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
0383 "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
0384 };
0385
0386 static bool check_name(const char *name)
0387 {
0388 const char **tmp;
0389
0390 for (tmp = modem_names; *tmp; tmp++)
0391 if (strstr(name, *tmp))
0392 return true;
0393
0394 return false;
0395 }
0396
0397 static bool check_resources(struct pnp_dev *dev)
0398 {
0399 static const resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
0400 unsigned int i;
0401
0402 for (i = 0; i < ARRAY_SIZE(base); i++) {
0403 if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
0404 return true;
0405 }
0406
0407 return false;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 static int serial_pnp_guess_board(struct pnp_dev *dev)
0422 {
0423 if (!(check_name(pnp_dev_name(dev)) ||
0424 (dev->card && check_name(dev->card->name))))
0425 return -ENODEV;
0426
0427 if (check_resources(dev))
0428 return 0;
0429
0430 return -ENODEV;
0431 }
0432
0433 static int
0434 serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
0435 {
0436 struct uart_8250_port uart, *port;
0437 int ret, line, flags = dev_id->driver_data;
0438
0439 if (flags & UNKNOWN_DEV) {
0440 ret = serial_pnp_guess_board(dev);
0441 if (ret < 0)
0442 return ret;
0443 }
0444
0445 memset(&uart, 0, sizeof(uart));
0446 if (pnp_irq_valid(dev, 0))
0447 uart.port.irq = pnp_irq(dev, 0);
0448 if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
0449 uart.port.iobase = pnp_port_start(dev, 2);
0450 uart.port.iotype = UPIO_PORT;
0451 } else if (pnp_port_valid(dev, 0)) {
0452 uart.port.iobase = pnp_port_start(dev, 0);
0453 uart.port.iotype = UPIO_PORT;
0454 } else if (pnp_mem_valid(dev, 0)) {
0455 uart.port.mapbase = pnp_mem_start(dev, 0);
0456 uart.port.iotype = UPIO_MEM;
0457 uart.port.flags = UPF_IOREMAP;
0458 } else
0459 return -ENODEV;
0460
0461 dev_dbg(&dev->dev,
0462 "Setup PNP port: port %#lx, mem %#llx, irq %u, type %u\n",
0463 uart.port.iobase, (unsigned long long)uart.port.mapbase,
0464 uart.port.irq, uart.port.iotype);
0465
0466 if (flags & CIR_PORT) {
0467 uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
0468 uart.port.type = PORT_8250_CIR;
0469 }
0470
0471 uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
0472 if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
0473 uart.port.flags |= UPF_SHARE_IRQ;
0474 uart.port.uartclk = 1843200;
0475 device_property_read_u32(&dev->dev, "clock-frequency", &uart.port.uartclk);
0476 uart.port.dev = &dev->dev;
0477
0478 line = serial8250_register_8250_port(&uart);
0479 if (line < 0 || (flags & CIR_PORT))
0480 return -ENODEV;
0481
0482 port = serial8250_get_port(line);
0483 if (uart_console(&port->port))
0484 dev->capabilities |= PNP_CONSOLE;
0485
0486 pnp_set_drvdata(dev, (void *)((long)line + 1));
0487 return 0;
0488 }
0489
0490 static void serial_pnp_remove(struct pnp_dev *dev)
0491 {
0492 long line = (long)pnp_get_drvdata(dev);
0493
0494 dev->capabilities &= ~PNP_CONSOLE;
0495 if (line)
0496 serial8250_unregister_port(line - 1);
0497 }
0498
0499 static int __maybe_unused serial_pnp_suspend(struct device *dev)
0500 {
0501 long line = (long)dev_get_drvdata(dev);
0502
0503 if (!line)
0504 return -ENODEV;
0505 serial8250_suspend_port(line - 1);
0506 return 0;
0507 }
0508
0509 static int __maybe_unused serial_pnp_resume(struct device *dev)
0510 {
0511 long line = (long)dev_get_drvdata(dev);
0512
0513 if (!line)
0514 return -ENODEV;
0515 serial8250_resume_port(line - 1);
0516 return 0;
0517 }
0518
0519 static SIMPLE_DEV_PM_OPS(serial_pnp_pm_ops, serial_pnp_suspend, serial_pnp_resume);
0520
0521 static struct pnp_driver serial_pnp_driver = {
0522 .name = "serial",
0523 .probe = serial_pnp_probe,
0524 .remove = serial_pnp_remove,
0525 .driver = {
0526 .pm = &serial_pnp_pm_ops,
0527 },
0528 .id_table = pnp_dev_table,
0529 };
0530
0531 int serial8250_pnp_init(void)
0532 {
0533 return pnp_register_driver(&serial_pnp_driver);
0534 }
0535
0536 void serial8250_pnp_exit(void)
0537 {
0538 pnp_unregister_driver(&serial_pnp_driver);
0539 }
0540