.. | .. |
---|
9 | 9 | * in the code. |
---|
10 | 10 | */ |
---|
11 | 11 | |
---|
12 | | -#if defined(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
---|
13 | | -#define SUPPORT_SYSRQ |
---|
14 | | -#endif |
---|
15 | | - |
---|
16 | 12 | #include <linux/platform_device.h> |
---|
17 | 13 | #include <linux/serial.h> |
---|
18 | 14 | #include <linux/console.h> |
---|
.. | .. |
---|
32 | 28 | #define CDNS_UART_NAME "xuartps" |
---|
33 | 29 | #define CDNS_UART_MAJOR 0 /* use dynamic node allocation */ |
---|
34 | 30 | #define CDNS_UART_MINOR 0 /* works best with devtmpfs */ |
---|
35 | | -#define CDNS_UART_NR_PORTS 2 |
---|
| 31 | +#define CDNS_UART_NR_PORTS 16 |
---|
36 | 32 | #define CDNS_UART_FIFO_SIZE 64 /* FIFO size */ |
---|
37 | 33 | #define CDNS_UART_REGISTER_SPACE 0x1000 |
---|
38 | 34 | #define TX_TIMEOUT 500000 |
---|
39 | 35 | |
---|
40 | 36 | /* Rx Trigger level */ |
---|
41 | 37 | static int rx_trigger_level = 56; |
---|
42 | | -module_param(rx_trigger_level, uint, S_IRUGO); |
---|
| 38 | +module_param(rx_trigger_level, uint, 0444); |
---|
43 | 39 | MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes"); |
---|
44 | 40 | |
---|
45 | 41 | /* Rx Timeout */ |
---|
46 | 42 | static int rx_timeout = 10; |
---|
47 | | -module_param(rx_timeout, uint, S_IRUGO); |
---|
| 43 | +module_param(rx_timeout, uint, 0444); |
---|
48 | 44 | MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); |
---|
49 | 45 | |
---|
50 | 46 | /* Register offsets for the UART. */ |
---|
.. | .. |
---|
160 | 156 | #define CDNS_UART_MODEMCR_DTR 0x00000001 /* Data Terminal Ready */ |
---|
161 | 157 | |
---|
162 | 158 | /* |
---|
| 159 | + * Modem Status register: |
---|
| 160 | + * The read/write Modem Status register reports the interface with the modem |
---|
| 161 | + * or data set, or a peripheral device emulating a modem. |
---|
| 162 | + */ |
---|
| 163 | +#define CDNS_UART_MODEMSR_DCD BIT(7) /* Data Carrier Detect */ |
---|
| 164 | +#define CDNS_UART_MODEMSR_RI BIT(6) /* Ting Indicator */ |
---|
| 165 | +#define CDNS_UART_MODEMSR_DSR BIT(5) /* Data Set Ready */ |
---|
| 166 | +#define CDNS_UART_MODEMSR_CTS BIT(4) /* Clear To Send */ |
---|
| 167 | + |
---|
| 168 | +/* |
---|
163 | 169 | * Channel Status Register: |
---|
164 | 170 | * The channel status register (CSR) is provided to enable the control logic |
---|
165 | 171 | * to monitor the status of bits in the channel interrupt status register, |
---|
.. | .. |
---|
182 | 188 | * @port: Pointer to the UART port |
---|
183 | 189 | * @uartclk: Reference clock |
---|
184 | 190 | * @pclk: APB clock |
---|
| 191 | + * @cdns_uart_driver: Pointer to UART driver |
---|
185 | 192 | * @baud: Current baud rate |
---|
186 | 193 | * @clk_rate_change_nb: Notifier block for clock changes |
---|
187 | 194 | * @quirks: Flags for RXBS support. |
---|
.. | .. |
---|
190 | 197 | struct uart_port *port; |
---|
191 | 198 | struct clk *uartclk; |
---|
192 | 199 | struct clk *pclk; |
---|
| 200 | + struct uart_driver *cdns_uart_driver; |
---|
193 | 201 | unsigned int baud; |
---|
194 | 202 | struct notifier_block clk_rate_change_nb; |
---|
195 | 203 | u32 quirks; |
---|
| 204 | + bool cts_override; |
---|
196 | 205 | }; |
---|
197 | 206 | struct cdns_platform_data { |
---|
198 | 207 | u32 quirks; |
---|
199 | 208 | }; |
---|
200 | 209 | #define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \ |
---|
201 | | - clk_rate_change_nb); |
---|
| 210 | + clk_rate_change_nb) |
---|
202 | 211 | |
---|
203 | 212 | /** |
---|
204 | 213 | * cdns_uart_handle_rx - Handle the received bytes along with Rx errors. |
---|
.. | .. |
---|
311 | 320 | } else { |
---|
312 | 321 | numbytes = port->fifosize; |
---|
313 | 322 | while (numbytes && !uart_circ_empty(&port->state->xmit) && |
---|
314 | | - !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)) { |
---|
| 323 | + !(readl(port->membase + CDNS_UART_SR) & |
---|
| 324 | + CDNS_UART_SR_TXFULL)) { |
---|
315 | 325 | /* |
---|
316 | 326 | * Get the data from the UART circular buffer |
---|
317 | 327 | * and write it to the cdns_uart's TX_FIFO |
---|
318 | 328 | * register. |
---|
319 | 329 | */ |
---|
320 | 330 | writel( |
---|
321 | | - port->state->xmit.buf[port->state->xmit. |
---|
322 | | - tail], port->membase + CDNS_UART_FIFO); |
---|
| 331 | + port->state->xmit.buf[port->state->xmit.tail], |
---|
| 332 | + port->membase + CDNS_UART_FIFO); |
---|
323 | 333 | |
---|
324 | 334 | port->icount.tx++; |
---|
325 | 335 | |
---|
.. | .. |
---|
365 | 375 | isrstatus &= ~CDNS_UART_IXR_TXEMPTY; |
---|
366 | 376 | } |
---|
367 | 377 | |
---|
| 378 | + isrstatus &= port->read_status_mask; |
---|
| 379 | + isrstatus &= ~port->ignore_status_mask; |
---|
368 | 380 | /* |
---|
369 | 381 | * Skip RX processing if RX is disabled as RXEMPTY will never be set |
---|
370 | 382 | * as read bytes will not be removed from the FIFO. |
---|
.. | .. |
---|
534 | 546 | |
---|
535 | 547 | cdns_uart->baud = cdns_uart_set_baud_rate(cdns_uart->port, |
---|
536 | 548 | cdns_uart->baud); |
---|
537 | | - /* fall through */ |
---|
| 549 | + fallthrough; |
---|
538 | 550 | case ABORT_RATE_CHANGE: |
---|
539 | 551 | if (!locked) |
---|
540 | 552 | spin_lock_irqsave(&cdns_uart->port->lock, flags); |
---|
.. | .. |
---|
641 | 653 | unsigned int status; |
---|
642 | 654 | |
---|
643 | 655 | status = readl(port->membase + CDNS_UART_SR) & |
---|
644 | | - CDNS_UART_SR_TXEMPTY; |
---|
645 | | - return status ? TIOCSER_TEMT : 0; |
---|
| 656 | + (CDNS_UART_SR_TXEMPTY | CDNS_UART_SR_TACTIVE); |
---|
| 657 | + return (status == CDNS_UART_SR_TXEMPTY) ? TIOCSER_TEMT : 0; |
---|
646 | 658 | } |
---|
647 | 659 | |
---|
648 | 660 | /** |
---|
.. | .. |
---|
681 | 693 | static void cdns_uart_set_termios(struct uart_port *port, |
---|
682 | 694 | struct ktermios *termios, struct ktermios *old) |
---|
683 | 695 | { |
---|
684 | | - unsigned int cval = 0; |
---|
| 696 | + u32 cval = 0; |
---|
685 | 697 | unsigned int baud, minbaud, maxbaud; |
---|
686 | 698 | unsigned long flags; |
---|
687 | | - unsigned int ctrl_reg, mode_reg, val; |
---|
688 | | - int err; |
---|
| 699 | + unsigned int ctrl_reg, mode_reg; |
---|
689 | 700 | |
---|
690 | | - /* Wait for the transmit FIFO to empty before making changes */ |
---|
691 | | - if (!(readl(port->membase + CDNS_UART_CR) & |
---|
692 | | - CDNS_UART_CR_TX_DIS)) { |
---|
693 | | - err = readl_poll_timeout(port->membase + CDNS_UART_SR, |
---|
694 | | - val, (val & CDNS_UART_SR_TXEMPTY), |
---|
695 | | - 1000, TX_TIMEOUT); |
---|
696 | | - if (err) { |
---|
697 | | - dev_err(port->dev, "timed out waiting for tx empty"); |
---|
698 | | - return; |
---|
699 | | - } |
---|
700 | | - } |
---|
701 | 701 | spin_lock_irqsave(&port->lock, flags); |
---|
702 | 702 | |
---|
703 | 703 | /* Disable the TX and RX to set baud rate */ |
---|
.. | .. |
---|
801 | 801 | } |
---|
802 | 802 | cval |= mode_reg & 1; |
---|
803 | 803 | writel(cval, port->membase + CDNS_UART_MR); |
---|
| 804 | + |
---|
| 805 | + cval = readl(port->membase + CDNS_UART_MODEMCR); |
---|
| 806 | + if (termios->c_cflag & CRTSCTS) |
---|
| 807 | + cval |= CDNS_UART_MODEMCR_FCM; |
---|
| 808 | + else |
---|
| 809 | + cval &= ~CDNS_UART_MODEMCR_FCM; |
---|
| 810 | + writel(cval, port->membase + CDNS_UART_MODEMCR); |
---|
804 | 811 | |
---|
805 | 812 | spin_unlock_irqrestore(&port->lock, flags); |
---|
806 | 813 | } |
---|
.. | .. |
---|
1004 | 1011 | */ |
---|
1005 | 1012 | static unsigned int cdns_uart_get_mctrl(struct uart_port *port) |
---|
1006 | 1013 | { |
---|
1007 | | - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
---|
| 1014 | + u32 val; |
---|
| 1015 | + unsigned int mctrl = 0; |
---|
| 1016 | + struct cdns_uart *cdns_uart_data = port->private_data; |
---|
| 1017 | + |
---|
| 1018 | + if (cdns_uart_data->cts_override) |
---|
| 1019 | + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
---|
| 1020 | + |
---|
| 1021 | + val = readl(port->membase + CDNS_UART_MODEMSR); |
---|
| 1022 | + if (val & CDNS_UART_MODEMSR_CTS) |
---|
| 1023 | + mctrl |= TIOCM_CTS; |
---|
| 1024 | + if (val & CDNS_UART_MODEMSR_DSR) |
---|
| 1025 | + mctrl |= TIOCM_DSR; |
---|
| 1026 | + if (val & CDNS_UART_MODEMSR_RI) |
---|
| 1027 | + mctrl |= TIOCM_RNG; |
---|
| 1028 | + if (val & CDNS_UART_MODEMSR_DCD) |
---|
| 1029 | + mctrl |= TIOCM_CAR; |
---|
| 1030 | + |
---|
| 1031 | + return mctrl; |
---|
1008 | 1032 | } |
---|
1009 | 1033 | |
---|
1010 | 1034 | static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
---|
1011 | 1035 | { |
---|
1012 | 1036 | u32 val; |
---|
1013 | 1037 | u32 mode_reg; |
---|
| 1038 | + struct cdns_uart *cdns_uart_data = port->private_data; |
---|
| 1039 | + |
---|
| 1040 | + if (cdns_uart_data->cts_override) |
---|
| 1041 | + return; |
---|
1014 | 1042 | |
---|
1015 | 1043 | val = readl(port->membase + CDNS_UART_MODEMCR); |
---|
1016 | 1044 | mode_reg = readl(port->membase + CDNS_UART_MR); |
---|
.. | .. |
---|
1068 | 1096 | cpu_relax(); |
---|
1069 | 1097 | |
---|
1070 | 1098 | spin_unlock_irqrestore(&port->lock, flags); |
---|
1071 | | - |
---|
1072 | | - return; |
---|
1073 | 1099 | } |
---|
1074 | 1100 | #endif |
---|
1075 | 1101 | |
---|
.. | .. |
---|
1109 | 1135 | .poll_put_char = cdns_uart_poll_put_char, |
---|
1110 | 1136 | #endif |
---|
1111 | 1137 | }; |
---|
| 1138 | + |
---|
| 1139 | +static struct uart_driver cdns_uart_uart_driver; |
---|
1112 | 1140 | |
---|
1113 | 1141 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
1114 | 1142 | /** |
---|
.. | .. |
---|
1185 | 1213 | unsigned int count) |
---|
1186 | 1214 | { |
---|
1187 | 1215 | struct uart_port *port = console_port; |
---|
1188 | | - unsigned long flags; |
---|
| 1216 | + unsigned long flags = 0; |
---|
1189 | 1217 | unsigned int imr, ctrl; |
---|
1190 | 1218 | int locked = 1; |
---|
1191 | 1219 | |
---|
.. | .. |
---|
1210 | 1238 | writel(ctrl, port->membase + CDNS_UART_CR); |
---|
1211 | 1239 | |
---|
1212 | 1240 | uart_console_write(port, s, count, cdns_uart_console_putchar); |
---|
1213 | | - while ((readl(port->membase + CDNS_UART_SR) & |
---|
1214 | | - (CDNS_UART_SR_TXEMPTY | CDNS_UART_SR_TACTIVE)) != |
---|
1215 | | - CDNS_UART_SR_TXEMPTY) |
---|
| 1241 | + while (cdns_uart_tx_empty(port) != TIOCSER_TEMT) |
---|
1216 | 1242 | cpu_relax(); |
---|
1217 | 1243 | |
---|
1218 | 1244 | /* restore interrupt state */ |
---|
.. | .. |
---|
1258 | 1284 | return uart_set_options(port, co, baud, parity, bits, flow); |
---|
1259 | 1285 | } |
---|
1260 | 1286 | |
---|
1261 | | -static struct uart_driver cdns_uart_uart_driver; |
---|
1262 | | - |
---|
1263 | 1287 | static struct console cdns_uart_console = { |
---|
1264 | 1288 | .name = CDNS_UART_TTY_NAME, |
---|
1265 | 1289 | .write = cdns_uart_console_write, |
---|
.. | .. |
---|
1271 | 1295 | }; |
---|
1272 | 1296 | #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ |
---|
1273 | 1297 | |
---|
1274 | | -static struct uart_driver cdns_uart_uart_driver = { |
---|
1275 | | - .owner = THIS_MODULE, |
---|
1276 | | - .driver_name = CDNS_UART_NAME, |
---|
1277 | | - .dev_name = CDNS_UART_TTY_NAME, |
---|
1278 | | - .major = CDNS_UART_MAJOR, |
---|
1279 | | - .minor = CDNS_UART_MINOR, |
---|
1280 | | - .nr = CDNS_UART_NR_PORTS, |
---|
1281 | | -#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
1282 | | - .cons = &cdns_uart_console, |
---|
1283 | | -#endif |
---|
1284 | | -}; |
---|
1285 | | - |
---|
1286 | 1298 | #ifdef CONFIG_PM_SLEEP |
---|
1287 | 1299 | /** |
---|
1288 | 1300 | * cdns_uart_suspend - suspend event |
---|
.. | .. |
---|
1293 | 1305 | static int cdns_uart_suspend(struct device *device) |
---|
1294 | 1306 | { |
---|
1295 | 1307 | struct uart_port *port = dev_get_drvdata(device); |
---|
| 1308 | + struct cdns_uart *cdns_uart = port->private_data; |
---|
1296 | 1309 | int may_wake; |
---|
1297 | 1310 | |
---|
1298 | 1311 | may_wake = device_may_wakeup(device); |
---|
1299 | 1312 | |
---|
1300 | | - if (console_suspend_enabled && may_wake) { |
---|
| 1313 | + if (console_suspend_enabled && uart_console(port) && may_wake) { |
---|
1301 | 1314 | unsigned long flags = 0; |
---|
1302 | 1315 | |
---|
1303 | 1316 | spin_lock_irqsave(&port->lock, flags); |
---|
.. | .. |
---|
1316 | 1329 | * Call the API provided in serial_core.c file which handles |
---|
1317 | 1330 | * the suspend. |
---|
1318 | 1331 | */ |
---|
1319 | | - return uart_suspend_port(&cdns_uart_uart_driver, port); |
---|
| 1332 | + return uart_suspend_port(cdns_uart->cdns_uart_driver, port); |
---|
1320 | 1333 | } |
---|
1321 | 1334 | |
---|
1322 | 1335 | /** |
---|
.. | .. |
---|
1328 | 1341 | static int cdns_uart_resume(struct device *device) |
---|
1329 | 1342 | { |
---|
1330 | 1343 | struct uart_port *port = dev_get_drvdata(device); |
---|
| 1344 | + struct cdns_uart *cdns_uart = port->private_data; |
---|
1331 | 1345 | unsigned long flags = 0; |
---|
1332 | 1346 | u32 ctrl_reg; |
---|
1333 | 1347 | int may_wake; |
---|
1334 | 1348 | |
---|
1335 | 1349 | may_wake = device_may_wakeup(device); |
---|
1336 | 1350 | |
---|
1337 | | - if (console_suspend_enabled && !may_wake) { |
---|
1338 | | - struct cdns_uart *cdns_uart = port->private_data; |
---|
1339 | | - |
---|
| 1351 | + if (console_suspend_enabled && uart_console(port) && !may_wake) { |
---|
1340 | 1352 | clk_enable(cdns_uart->pclk); |
---|
1341 | 1353 | clk_enable(cdns_uart->uartclk); |
---|
1342 | 1354 | |
---|
.. | .. |
---|
1370 | 1382 | spin_unlock_irqrestore(&port->lock, flags); |
---|
1371 | 1383 | } |
---|
1372 | 1384 | |
---|
1373 | | - return uart_resume_port(&cdns_uart_uart_driver, port); |
---|
| 1385 | + return uart_resume_port(cdns_uart->cdns_uart_driver, port); |
---|
1374 | 1386 | } |
---|
1375 | 1387 | #endif /* ! CONFIG_PM_SLEEP */ |
---|
1376 | 1388 | static int __maybe_unused cdns_runtime_suspend(struct device *dev) |
---|
.. | .. |
---|
1412 | 1424 | }; |
---|
1413 | 1425 | MODULE_DEVICE_TABLE(of, cdns_uart_of_match); |
---|
1414 | 1426 | |
---|
| 1427 | +/* Temporary variable for storing number of instances */ |
---|
| 1428 | +static int instances; |
---|
| 1429 | + |
---|
1415 | 1430 | /** |
---|
1416 | 1431 | * cdns_uart_probe - Platform driver probe |
---|
1417 | 1432 | * @pdev: Pointer to the platform device structure |
---|
.. | .. |
---|
1434 | 1449 | if (!port) |
---|
1435 | 1450 | return -ENOMEM; |
---|
1436 | 1451 | |
---|
| 1452 | + /* Look for a serialN alias */ |
---|
| 1453 | + id = of_alias_get_id(pdev->dev.of_node, "serial"); |
---|
| 1454 | + if (id < 0) |
---|
| 1455 | + id = 0; |
---|
| 1456 | + |
---|
| 1457 | + if (id >= CDNS_UART_NR_PORTS) { |
---|
| 1458 | + dev_err(&pdev->dev, "Cannot get uart_port structure\n"); |
---|
| 1459 | + return -ENODEV; |
---|
| 1460 | + } |
---|
| 1461 | + |
---|
| 1462 | + if (!cdns_uart_uart_driver.state) { |
---|
| 1463 | + cdns_uart_uart_driver.owner = THIS_MODULE; |
---|
| 1464 | + cdns_uart_uart_driver.driver_name = CDNS_UART_NAME; |
---|
| 1465 | + cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME; |
---|
| 1466 | + cdns_uart_uart_driver.major = CDNS_UART_MAJOR; |
---|
| 1467 | + cdns_uart_uart_driver.minor = CDNS_UART_MINOR; |
---|
| 1468 | + cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS; |
---|
| 1469 | +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
| 1470 | + cdns_uart_uart_driver.cons = &cdns_uart_console; |
---|
| 1471 | +#endif |
---|
| 1472 | + |
---|
| 1473 | + rc = uart_register_driver(&cdns_uart_uart_driver); |
---|
| 1474 | + if (rc < 0) { |
---|
| 1475 | + dev_err(&pdev->dev, "Failed to register driver\n"); |
---|
| 1476 | + return rc; |
---|
| 1477 | + } |
---|
| 1478 | + } |
---|
| 1479 | + |
---|
| 1480 | + cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver; |
---|
| 1481 | + |
---|
1437 | 1482 | match = of_match_node(cdns_uart_of_match, pdev->dev.of_node); |
---|
1438 | 1483 | if (match && match->data) { |
---|
1439 | 1484 | const struct cdns_platform_data *data = match->data; |
---|
.. | .. |
---|
1442 | 1487 | } |
---|
1443 | 1488 | |
---|
1444 | 1489 | cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "pclk"); |
---|
| 1490 | + if (PTR_ERR(cdns_uart_data->pclk) == -EPROBE_DEFER) { |
---|
| 1491 | + rc = PTR_ERR(cdns_uart_data->pclk); |
---|
| 1492 | + goto err_out_unregister_driver; |
---|
| 1493 | + } |
---|
| 1494 | + |
---|
1445 | 1495 | if (IS_ERR(cdns_uart_data->pclk)) { |
---|
1446 | 1496 | cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "aper_clk"); |
---|
1447 | | - if (!IS_ERR(cdns_uart_data->pclk)) |
---|
1448 | | - dev_err(&pdev->dev, "clock name 'aper_clk' is deprecated.\n"); |
---|
1449 | | - } |
---|
1450 | | - if (IS_ERR(cdns_uart_data->pclk)) { |
---|
1451 | | - dev_err(&pdev->dev, "pclk clock not found.\n"); |
---|
1452 | | - return PTR_ERR(cdns_uart_data->pclk); |
---|
| 1497 | + if (IS_ERR(cdns_uart_data->pclk)) { |
---|
| 1498 | + rc = PTR_ERR(cdns_uart_data->pclk); |
---|
| 1499 | + goto err_out_unregister_driver; |
---|
| 1500 | + } |
---|
| 1501 | + dev_err(&pdev->dev, "clock name 'aper_clk' is deprecated.\n"); |
---|
1453 | 1502 | } |
---|
1454 | 1503 | |
---|
1455 | 1504 | cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk"); |
---|
| 1505 | + if (PTR_ERR(cdns_uart_data->uartclk) == -EPROBE_DEFER) { |
---|
| 1506 | + rc = PTR_ERR(cdns_uart_data->uartclk); |
---|
| 1507 | + goto err_out_unregister_driver; |
---|
| 1508 | + } |
---|
| 1509 | + |
---|
1456 | 1510 | if (IS_ERR(cdns_uart_data->uartclk)) { |
---|
1457 | 1511 | cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "ref_clk"); |
---|
1458 | | - if (!IS_ERR(cdns_uart_data->uartclk)) |
---|
1459 | | - dev_err(&pdev->dev, "clock name 'ref_clk' is deprecated.\n"); |
---|
1460 | | - } |
---|
1461 | | - if (IS_ERR(cdns_uart_data->uartclk)) { |
---|
1462 | | - dev_err(&pdev->dev, "uart_clk clock not found.\n"); |
---|
1463 | | - return PTR_ERR(cdns_uart_data->uartclk); |
---|
| 1512 | + if (IS_ERR(cdns_uart_data->uartclk)) { |
---|
| 1513 | + rc = PTR_ERR(cdns_uart_data->uartclk); |
---|
| 1514 | + goto err_out_unregister_driver; |
---|
| 1515 | + } |
---|
| 1516 | + dev_err(&pdev->dev, "clock name 'ref_clk' is deprecated.\n"); |
---|
1464 | 1517 | } |
---|
1465 | 1518 | |
---|
1466 | 1519 | rc = clk_prepare_enable(cdns_uart_data->pclk); |
---|
1467 | 1520 | if (rc) { |
---|
1468 | 1521 | dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); |
---|
1469 | | - return rc; |
---|
| 1522 | + goto err_out_unregister_driver; |
---|
1470 | 1523 | } |
---|
1471 | 1524 | rc = clk_prepare_enable(cdns_uart_data->uartclk); |
---|
1472 | 1525 | if (rc) { |
---|
.. | .. |
---|
1493 | 1546 | &cdns_uart_data->clk_rate_change_nb)) |
---|
1494 | 1547 | dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); |
---|
1495 | 1548 | #endif |
---|
1496 | | - /* Look for a serialN alias */ |
---|
1497 | | - id = of_alias_get_id(pdev->dev.of_node, "serial"); |
---|
1498 | | - if (id < 0) |
---|
1499 | | - id = 0; |
---|
1500 | | - |
---|
1501 | | - if (id >= CDNS_UART_NR_PORTS) { |
---|
1502 | | - dev_err(&pdev->dev, "Cannot get uart_port structure\n"); |
---|
1503 | | - rc = -ENODEV; |
---|
1504 | | - goto err_out_notif_unreg; |
---|
1505 | | - } |
---|
1506 | 1549 | |
---|
1507 | 1550 | /* At this point, we've got an empty uart_port struct, initialize it */ |
---|
1508 | 1551 | spin_lock_init(&port->lock); |
---|
1509 | | - port->membase = NULL; |
---|
1510 | | - port->irq = 0; |
---|
1511 | 1552 | port->type = PORT_UNKNOWN; |
---|
1512 | 1553 | port->iotype = UPIO_MEM32; |
---|
1513 | 1554 | port->flags = UPF_BOOT_AUTOCONF; |
---|
1514 | 1555 | port->ops = &cdns_uart_ops; |
---|
1515 | 1556 | port->fifosize = CDNS_UART_FIFO_SIZE; |
---|
| 1557 | + port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE); |
---|
1516 | 1558 | port->line = id; |
---|
1517 | | - port->dev = NULL; |
---|
1518 | 1559 | |
---|
1519 | 1560 | /* |
---|
1520 | 1561 | * Register the port. |
---|
.. | .. |
---|
1533 | 1574 | pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT); |
---|
1534 | 1575 | pm_runtime_set_active(&pdev->dev); |
---|
1535 | 1576 | pm_runtime_enable(&pdev->dev); |
---|
| 1577 | + device_init_wakeup(port->dev, true); |
---|
1536 | 1578 | |
---|
1537 | 1579 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
1538 | 1580 | /* |
---|
.. | .. |
---|
1541 | 1583 | * If register_console() don't assign value, then console_port pointer |
---|
1542 | 1584 | * is cleanup. |
---|
1543 | 1585 | */ |
---|
1544 | | - if (cdns_uart_uart_driver.cons->index == -1) |
---|
| 1586 | + if (!console_port) { |
---|
| 1587 | + cdns_uart_console.index = id; |
---|
1545 | 1588 | console_port = port; |
---|
| 1589 | + } |
---|
1546 | 1590 | #endif |
---|
1547 | 1591 | |
---|
1548 | 1592 | rc = uart_add_one_port(&cdns_uart_uart_driver, port); |
---|
.. | .. |
---|
1554 | 1598 | |
---|
1555 | 1599 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
1556 | 1600 | /* This is not port which is used for console that's why clean it up */ |
---|
1557 | | - if (cdns_uart_uart_driver.cons->index == -1) |
---|
| 1601 | + if (console_port == port && |
---|
| 1602 | + !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) { |
---|
1558 | 1603 | console_port = NULL; |
---|
| 1604 | + cdns_uart_console.index = -1; |
---|
| 1605 | + } |
---|
1559 | 1606 | #endif |
---|
| 1607 | + |
---|
| 1608 | + cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node, |
---|
| 1609 | + "cts-override"); |
---|
| 1610 | + |
---|
| 1611 | + instances++; |
---|
1560 | 1612 | |
---|
1561 | 1613 | return 0; |
---|
1562 | 1614 | |
---|
.. | .. |
---|
1564 | 1616 | pm_runtime_disable(&pdev->dev); |
---|
1565 | 1617 | pm_runtime_set_suspended(&pdev->dev); |
---|
1566 | 1618 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
---|
1567 | | -err_out_notif_unreg: |
---|
1568 | 1619 | #ifdef CONFIG_COMMON_CLK |
---|
1569 | 1620 | clk_notifier_unregister(cdns_uart_data->uartclk, |
---|
1570 | 1621 | &cdns_uart_data->clk_rate_change_nb); |
---|
.. | .. |
---|
1573 | 1624 | clk_disable_unprepare(cdns_uart_data->uartclk); |
---|
1574 | 1625 | err_out_clk_dis_pclk: |
---|
1575 | 1626 | clk_disable_unprepare(cdns_uart_data->pclk); |
---|
1576 | | - |
---|
| 1627 | +err_out_unregister_driver: |
---|
| 1628 | + if (!instances) |
---|
| 1629 | + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); |
---|
1577 | 1630 | return rc; |
---|
1578 | 1631 | } |
---|
1579 | 1632 | |
---|
.. | .. |
---|
1594 | 1647 | clk_notifier_unregister(cdns_uart_data->uartclk, |
---|
1595 | 1648 | &cdns_uart_data->clk_rate_change_nb); |
---|
1596 | 1649 | #endif |
---|
1597 | | - rc = uart_remove_one_port(&cdns_uart_uart_driver, port); |
---|
| 1650 | + rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port); |
---|
1598 | 1651 | port->mapbase = 0; |
---|
1599 | 1652 | clk_disable_unprepare(cdns_uart_data->uartclk); |
---|
1600 | 1653 | clk_disable_unprepare(cdns_uart_data->pclk); |
---|
1601 | 1654 | pm_runtime_disable(&pdev->dev); |
---|
1602 | 1655 | pm_runtime_set_suspended(&pdev->dev); |
---|
1603 | 1656 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
---|
| 1657 | + device_init_wakeup(&pdev->dev, false); |
---|
| 1658 | + |
---|
| 1659 | +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
---|
| 1660 | + if (console_port == port) |
---|
| 1661 | + console_port = NULL; |
---|
| 1662 | +#endif |
---|
| 1663 | + |
---|
| 1664 | + if (!--instances) |
---|
| 1665 | + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); |
---|
1604 | 1666 | return rc; |
---|
1605 | 1667 | } |
---|
1606 | 1668 | |
---|
.. | .. |
---|
1617 | 1679 | |
---|
1618 | 1680 | static int __init cdns_uart_init(void) |
---|
1619 | 1681 | { |
---|
1620 | | - int retval = 0; |
---|
1621 | | - |
---|
1622 | | - /* Register the cdns_uart driver with the serial core */ |
---|
1623 | | - retval = uart_register_driver(&cdns_uart_uart_driver); |
---|
1624 | | - if (retval) |
---|
1625 | | - return retval; |
---|
1626 | | - |
---|
1627 | 1682 | /* Register the platform driver */ |
---|
1628 | | - retval = platform_driver_register(&cdns_uart_platform_driver); |
---|
1629 | | - if (retval) |
---|
1630 | | - uart_unregister_driver(&cdns_uart_uart_driver); |
---|
1631 | | - |
---|
1632 | | - return retval; |
---|
| 1683 | + return platform_driver_register(&cdns_uart_platform_driver); |
---|
1633 | 1684 | } |
---|
1634 | 1685 | |
---|
1635 | 1686 | static void __exit cdns_uart_exit(void) |
---|
1636 | 1687 | { |
---|
1637 | 1688 | /* Unregister the platform driver */ |
---|
1638 | 1689 | platform_driver_unregister(&cdns_uart_platform_driver); |
---|
1639 | | - |
---|
1640 | | - /* Unregister the cdns_uart driver */ |
---|
1641 | | - uart_unregister_driver(&cdns_uart_uart_driver); |
---|
1642 | 1690 | } |
---|
1643 | 1691 | |
---|
1644 | 1692 | arch_initcall(cdns_uart_init); |
---|