| .. | .. |
|---|
| 14 | 14 | #include <linux/device.h> |
|---|
| 15 | 15 | #include <linux/gpio/driver.h> |
|---|
| 16 | 16 | #include <linux/i2c.h> |
|---|
| 17 | +#include <linux/mod_devicetable.h> |
|---|
| 17 | 18 | #include <linux/module.h> |
|---|
| 18 | | -#include <linux/of.h> |
|---|
| 19 | | -#include <linux/of_device.h> |
|---|
| 19 | +#include <linux/property.h> |
|---|
| 20 | 20 | #include <linux/regmap.h> |
|---|
| 21 | 21 | #include <linux/serial_core.h> |
|---|
| 22 | 22 | #include <linux/serial.h> |
|---|
| .. | .. |
|---|
| 315 | 315 | struct kthread_work tx_work; |
|---|
| 316 | 316 | struct kthread_work reg_work; |
|---|
| 317 | 317 | struct sc16is7xx_one_config config; |
|---|
| 318 | + bool irda_mode; |
|---|
| 318 | 319 | }; |
|---|
| 319 | 320 | |
|---|
| 320 | 321 | struct sc16is7xx_port { |
|---|
| .. | .. |
|---|
| 327 | 328 | unsigned char buf[SC16IS7XX_FIFO_SIZE]; |
|---|
| 328 | 329 | struct kthread_worker kworker; |
|---|
| 329 | 330 | struct task_struct *kworker_task; |
|---|
| 330 | | - struct kthread_work irq_work; |
|---|
| 331 | 331 | struct mutex efr_lock; |
|---|
| 332 | | - struct sc16is7xx_one p[0]; |
|---|
| 332 | + struct sc16is7xx_one p[]; |
|---|
| 333 | 333 | }; |
|---|
| 334 | 334 | |
|---|
| 335 | 335 | static unsigned long sc16is7xx_lines; |
|---|
| .. | .. |
|---|
| 710 | 710 | return true; |
|---|
| 711 | 711 | } |
|---|
| 712 | 712 | |
|---|
| 713 | | -static void sc16is7xx_ist(struct kthread_work *ws) |
|---|
| 713 | +static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) |
|---|
| 714 | 714 | { |
|---|
| 715 | | - struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work); |
|---|
| 715 | + struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; |
|---|
| 716 | 716 | |
|---|
| 717 | 717 | mutex_lock(&s->efr_lock); |
|---|
| 718 | 718 | |
|---|
| .. | .. |
|---|
| 727 | 727 | } |
|---|
| 728 | 728 | |
|---|
| 729 | 729 | mutex_unlock(&s->efr_lock); |
|---|
| 730 | | -} |
|---|
| 731 | | - |
|---|
| 732 | | -static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) |
|---|
| 733 | | -{ |
|---|
| 734 | | - struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; |
|---|
| 735 | | - |
|---|
| 736 | | - kthread_queue_work(&s->kworker, &s->irq_work); |
|---|
| 737 | 730 | |
|---|
| 738 | 731 | return IRQ_HANDLED; |
|---|
| 739 | 732 | } |
|---|
| .. | .. |
|---|
| 741 | 734 | static void sc16is7xx_tx_proc(struct kthread_work *ws) |
|---|
| 742 | 735 | { |
|---|
| 743 | 736 | struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port); |
|---|
| 737 | + struct sc16is7xx_port *s = dev_get_drvdata(port->dev); |
|---|
| 744 | 738 | |
|---|
| 745 | 739 | if ((port->rs485.flags & SER_RS485_ENABLED) && |
|---|
| 746 | 740 | (port->rs485.delay_rts_before_send > 0)) |
|---|
| 747 | 741 | msleep(port->rs485.delay_rts_before_send); |
|---|
| 748 | 742 | |
|---|
| 743 | + mutex_lock(&s->efr_lock); |
|---|
| 749 | 744 | sc16is7xx_handle_tx(port); |
|---|
| 745 | + mutex_unlock(&s->efr_lock); |
|---|
| 750 | 746 | } |
|---|
| 751 | 747 | |
|---|
| 752 | 748 | static void sc16is7xx_reconf_rs485(struct uart_port *port) |
|---|
| .. | .. |
|---|
| 994 | 990 | |
|---|
| 995 | 991 | static int sc16is7xx_startup(struct uart_port *port) |
|---|
| 996 | 992 | { |
|---|
| 993 | + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); |
|---|
| 997 | 994 | struct sc16is7xx_port *s = dev_get_drvdata(port->dev); |
|---|
| 998 | 995 | unsigned int val; |
|---|
| 999 | 996 | |
|---|
| .. | .. |
|---|
| 1031 | 1028 | |
|---|
| 1032 | 1029 | /* Now, initialize the UART */ |
|---|
| 1033 | 1030 | sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8); |
|---|
| 1031 | + |
|---|
| 1032 | + /* Enable IrDA mode if requested in DT */ |
|---|
| 1033 | + /* This bit must be written with LCR[7] = 0 */ |
|---|
| 1034 | + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, |
|---|
| 1035 | + SC16IS7XX_MCR_IRDA_BIT, |
|---|
| 1036 | + one->irda_mode ? |
|---|
| 1037 | + SC16IS7XX_MCR_IRDA_BIT : 0); |
|---|
| 1034 | 1038 | |
|---|
| 1035 | 1039 | /* Enable the Rx and Tx FIFO */ |
|---|
| 1036 | 1040 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, |
|---|
| .. | .. |
|---|
| 1176 | 1180 | |
|---|
| 1177 | 1181 | static int sc16is7xx_probe(struct device *dev, |
|---|
| 1178 | 1182 | const struct sc16is7xx_devtype *devtype, |
|---|
| 1179 | | - struct regmap *regmap, int irq, unsigned long flags) |
|---|
| 1183 | + struct regmap *regmap, int irq) |
|---|
| 1180 | 1184 | { |
|---|
| 1181 | | - struct sched_param sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; |
|---|
| 1182 | | - unsigned long freq, *pfreq = dev_get_platdata(dev); |
|---|
| 1185 | + unsigned long freq = 0, *pfreq = dev_get_platdata(dev); |
|---|
| 1186 | + unsigned int val; |
|---|
| 1187 | + u32 uartclk = 0; |
|---|
| 1183 | 1188 | int i, ret; |
|---|
| 1184 | 1189 | struct sc16is7xx_port *s; |
|---|
| 1185 | 1190 | |
|---|
| 1186 | 1191 | if (IS_ERR(regmap)) |
|---|
| 1187 | 1192 | return PTR_ERR(regmap); |
|---|
| 1188 | 1193 | |
|---|
| 1194 | + /* |
|---|
| 1195 | + * This device does not have an identification register that would |
|---|
| 1196 | + * tell us if we are really connected to the correct device. |
|---|
| 1197 | + * The best we can do is to check if communication is at all possible. |
|---|
| 1198 | + */ |
|---|
| 1199 | + ret = regmap_read(regmap, |
|---|
| 1200 | + SC16IS7XX_LSR_REG << SC16IS7XX_REG_SHIFT, &val); |
|---|
| 1201 | + if (ret < 0) |
|---|
| 1202 | + return -EPROBE_DEFER; |
|---|
| 1203 | + |
|---|
| 1189 | 1204 | /* Alloc port structure */ |
|---|
| 1190 | | - s = devm_kzalloc(dev, sizeof(*s) + |
|---|
| 1191 | | - sizeof(struct sc16is7xx_one) * devtype->nr_uart, |
|---|
| 1192 | | - GFP_KERNEL); |
|---|
| 1205 | + s = devm_kzalloc(dev, struct_size(s, p, devtype->nr_uart), GFP_KERNEL); |
|---|
| 1193 | 1206 | if (!s) { |
|---|
| 1194 | 1207 | dev_err(dev, "Error allocating port structure\n"); |
|---|
| 1195 | 1208 | return -ENOMEM; |
|---|
| 1196 | 1209 | } |
|---|
| 1197 | 1210 | |
|---|
| 1211 | + /* Always ask for fixed clock rate from a property. */ |
|---|
| 1212 | + device_property_read_u32(dev, "clock-frequency", &uartclk); |
|---|
| 1213 | + |
|---|
| 1198 | 1214 | s->clk = devm_clk_get(dev, NULL); |
|---|
| 1199 | 1215 | if (IS_ERR(s->clk)) { |
|---|
| 1216 | + if (uartclk) |
|---|
| 1217 | + freq = uartclk; |
|---|
| 1200 | 1218 | if (pfreq) |
|---|
| 1201 | 1219 | freq = *pfreq; |
|---|
| 1220 | + if (freq) |
|---|
| 1221 | + dev_dbg(dev, "Clock frequency: %luHz\n", freq); |
|---|
| 1202 | 1222 | else |
|---|
| 1203 | 1223 | return PTR_ERR(s->clk); |
|---|
| 1204 | 1224 | } else { |
|---|
| .. | .. |
|---|
| 1215 | 1235 | mutex_init(&s->efr_lock); |
|---|
| 1216 | 1236 | |
|---|
| 1217 | 1237 | kthread_init_worker(&s->kworker); |
|---|
| 1218 | | - kthread_init_work(&s->irq_work, sc16is7xx_ist); |
|---|
| 1219 | 1238 | s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker, |
|---|
| 1220 | 1239 | "sc16is7xx"); |
|---|
| 1221 | 1240 | if (IS_ERR(s->kworker_task)) { |
|---|
| 1222 | 1241 | ret = PTR_ERR(s->kworker_task); |
|---|
| 1223 | 1242 | goto out_clk; |
|---|
| 1224 | 1243 | } |
|---|
| 1225 | | - sched_setscheduler(s->kworker_task, SCHED_FIFO, &sched_param); |
|---|
| 1244 | + sched_set_fifo(s->kworker_task); |
|---|
| 1226 | 1245 | |
|---|
| 1227 | 1246 | #ifdef CONFIG_GPIOLIB |
|---|
| 1228 | 1247 | if (devtype->nr_gpio) { |
|---|
| .. | .. |
|---|
| 1255 | 1274 | s->p[i].port.type = PORT_SC16IS7XX; |
|---|
| 1256 | 1275 | s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE; |
|---|
| 1257 | 1276 | s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; |
|---|
| 1277 | + s->p[i].port.iobase = i; |
|---|
| 1258 | 1278 | s->p[i].port.iotype = UPIO_PORT; |
|---|
| 1259 | 1279 | s->p[i].port.uartclk = freq; |
|---|
| 1260 | 1280 | s->p[i].port.rs485_config = sc16is7xx_config_rs485; |
|---|
| .. | .. |
|---|
| 1296 | 1316 | sc16is7xx_power(&s->p[i].port, 0); |
|---|
| 1297 | 1317 | } |
|---|
| 1298 | 1318 | |
|---|
| 1299 | | - /* Setup interrupt */ |
|---|
| 1300 | | - ret = devm_request_irq(dev, irq, sc16is7xx_irq, |
|---|
| 1301 | | - flags, dev_name(dev), s); |
|---|
| 1319 | + if (dev->of_node) { |
|---|
| 1320 | + struct property *prop; |
|---|
| 1321 | + const __be32 *p; |
|---|
| 1322 | + u32 u; |
|---|
| 1323 | + |
|---|
| 1324 | + of_property_for_each_u32(dev->of_node, "irda-mode-ports", |
|---|
| 1325 | + prop, p, u) |
|---|
| 1326 | + if (u < devtype->nr_uart) |
|---|
| 1327 | + s->p[u].irda_mode = true; |
|---|
| 1328 | + } |
|---|
| 1329 | + |
|---|
| 1330 | + /* |
|---|
| 1331 | + * Setup interrupt. We first try to acquire the IRQ line as level IRQ. |
|---|
| 1332 | + * If that succeeds, we can allow sharing the interrupt as well. |
|---|
| 1333 | + * In case the interrupt controller doesn't support that, we fall |
|---|
| 1334 | + * back to a non-shared falling-edge trigger. |
|---|
| 1335 | + */ |
|---|
| 1336 | + ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_irq, |
|---|
| 1337 | + IRQF_TRIGGER_LOW | IRQF_SHARED | |
|---|
| 1338 | + IRQF_ONESHOT, |
|---|
| 1339 | + dev_name(dev), s); |
|---|
| 1340 | + if (!ret) |
|---|
| 1341 | + return 0; |
|---|
| 1342 | + |
|---|
| 1343 | + ret = devm_request_threaded_irq(dev, irq, NULL, sc16is7xx_irq, |
|---|
| 1344 | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
|---|
| 1345 | + dev_name(dev), s); |
|---|
| 1302 | 1346 | if (!ret) |
|---|
| 1303 | 1347 | return 0; |
|---|
| 1304 | 1348 | |
|---|
| .. | .. |
|---|
| 1372 | 1416 | static int sc16is7xx_spi_probe(struct spi_device *spi) |
|---|
| 1373 | 1417 | { |
|---|
| 1374 | 1418 | const struct sc16is7xx_devtype *devtype; |
|---|
| 1375 | | - unsigned long flags = 0; |
|---|
| 1376 | 1419 | struct regmap *regmap; |
|---|
| 1377 | 1420 | int ret; |
|---|
| 1378 | 1421 | |
|---|
| .. | .. |
|---|
| 1386 | 1429 | return ret; |
|---|
| 1387 | 1430 | |
|---|
| 1388 | 1431 | if (spi->dev.of_node) { |
|---|
| 1389 | | - const struct of_device_id *of_id = |
|---|
| 1390 | | - of_match_device(sc16is7xx_dt_ids, &spi->dev); |
|---|
| 1391 | | - |
|---|
| 1392 | | - if (!of_id) |
|---|
| 1432 | + devtype = device_get_match_data(&spi->dev); |
|---|
| 1433 | + if (!devtype) |
|---|
| 1393 | 1434 | return -ENODEV; |
|---|
| 1394 | | - |
|---|
| 1395 | | - devtype = (struct sc16is7xx_devtype *)of_id->data; |
|---|
| 1396 | 1435 | } else { |
|---|
| 1397 | 1436 | const struct spi_device_id *id_entry = spi_get_device_id(spi); |
|---|
| 1398 | 1437 | |
|---|
| 1399 | 1438 | devtype = (struct sc16is7xx_devtype *)id_entry->driver_data; |
|---|
| 1400 | | - flags = IRQF_TRIGGER_FALLING; |
|---|
| 1401 | 1439 | } |
|---|
| 1402 | 1440 | |
|---|
| 1403 | 1441 | regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) | |
|---|
| 1404 | 1442 | (devtype->nr_uart - 1); |
|---|
| 1405 | 1443 | regmap = devm_regmap_init_spi(spi, ®cfg); |
|---|
| 1406 | 1444 | |
|---|
| 1407 | | - return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq, flags); |
|---|
| 1445 | + return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq); |
|---|
| 1408 | 1446 | } |
|---|
| 1409 | 1447 | |
|---|
| 1410 | 1448 | static int sc16is7xx_spi_remove(struct spi_device *spi) |
|---|
| .. | .. |
|---|
| 1428 | 1466 | static struct spi_driver sc16is7xx_spi_uart_driver = { |
|---|
| 1429 | 1467 | .driver = { |
|---|
| 1430 | 1468 | .name = SC16IS7XX_NAME, |
|---|
| 1431 | | - .of_match_table = of_match_ptr(sc16is7xx_dt_ids), |
|---|
| 1469 | + .of_match_table = sc16is7xx_dt_ids, |
|---|
| 1432 | 1470 | }, |
|---|
| 1433 | 1471 | .probe = sc16is7xx_spi_probe, |
|---|
| 1434 | 1472 | .remove = sc16is7xx_spi_remove, |
|---|
| .. | .. |
|---|
| 1443 | 1481 | const struct i2c_device_id *id) |
|---|
| 1444 | 1482 | { |
|---|
| 1445 | 1483 | const struct sc16is7xx_devtype *devtype; |
|---|
| 1446 | | - unsigned long flags = 0; |
|---|
| 1447 | 1484 | struct regmap *regmap; |
|---|
| 1448 | 1485 | |
|---|
| 1449 | 1486 | if (i2c->dev.of_node) { |
|---|
| 1450 | | - const struct of_device_id *of_id = |
|---|
| 1451 | | - of_match_device(sc16is7xx_dt_ids, &i2c->dev); |
|---|
| 1452 | | - |
|---|
| 1453 | | - if (!of_id) |
|---|
| 1487 | + devtype = device_get_match_data(&i2c->dev); |
|---|
| 1488 | + if (!devtype) |
|---|
| 1454 | 1489 | return -ENODEV; |
|---|
| 1455 | | - |
|---|
| 1456 | | - devtype = (struct sc16is7xx_devtype *)of_id->data; |
|---|
| 1457 | 1490 | } else { |
|---|
| 1458 | 1491 | devtype = (struct sc16is7xx_devtype *)id->driver_data; |
|---|
| 1459 | | - flags = IRQF_TRIGGER_FALLING; |
|---|
| 1460 | 1492 | } |
|---|
| 1461 | 1493 | |
|---|
| 1462 | 1494 | regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) | |
|---|
| 1463 | 1495 | (devtype->nr_uart - 1); |
|---|
| 1464 | 1496 | regmap = devm_regmap_init_i2c(i2c, ®cfg); |
|---|
| 1465 | 1497 | |
|---|
| 1466 | | - return sc16is7xx_probe(&i2c->dev, devtype, regmap, i2c->irq, flags); |
|---|
| 1498 | + return sc16is7xx_probe(&i2c->dev, devtype, regmap, i2c->irq); |
|---|
| 1467 | 1499 | } |
|---|
| 1468 | 1500 | |
|---|
| 1469 | 1501 | static int sc16is7xx_i2c_remove(struct i2c_client *client) |
|---|
| .. | .. |
|---|
| 1486 | 1518 | static struct i2c_driver sc16is7xx_i2c_uart_driver = { |
|---|
| 1487 | 1519 | .driver = { |
|---|
| 1488 | 1520 | .name = SC16IS7XX_NAME, |
|---|
| 1489 | | - .of_match_table = of_match_ptr(sc16is7xx_dt_ids), |
|---|
| 1521 | + .of_match_table = sc16is7xx_dt_ids, |
|---|
| 1490 | 1522 | }, |
|---|
| 1491 | 1523 | .probe = sc16is7xx_i2c_probe, |
|---|
| 1492 | 1524 | .remove = sc16is7xx_i2c_remove, |
|---|
| .. | .. |
|---|
| 1524 | 1556 | |
|---|
| 1525 | 1557 | #ifdef CONFIG_SERIAL_SC16IS7XX_SPI |
|---|
| 1526 | 1558 | err_spi: |
|---|
| 1559 | +#endif |
|---|
| 1527 | 1560 | #ifdef CONFIG_SERIAL_SC16IS7XX_I2C |
|---|
| 1528 | 1561 | i2c_del_driver(&sc16is7xx_i2c_uart_driver); |
|---|
| 1529 | | -#endif |
|---|
| 1530 | | -#endif |
|---|
| 1531 | 1562 | err_i2c: |
|---|
| 1563 | +#endif |
|---|
| 1532 | 1564 | uart_unregister_driver(&sc16is7xx_uart); |
|---|
| 1533 | 1565 | return ret; |
|---|
| 1534 | 1566 | } |
|---|