Loading Documentation/devicetree/bindings/tty/serial/sccnxp-serial.txt 0 → 100644 +53 −0 Original line number Diff line number Diff line * NXP (Philips) SCC+++(SCN+++) serial driver Required properties: - compatible: Should be "nxp,<ictype>". The supported ICs include sc2681, sc2691, sc2692, sc2891, sc2892, sc28202, sc68681 and sc68692. - reg: Address and length of the register set for the device. - interrupts: Should contain the interrupt number. If omitted, polling mode will be used instead, so "poll-interval" property should be populated in this case. Optional properties: - clocks: Phandle to input clock. If omitted, default IC frequency will be used instead. - poll-interval: Poll interval time in nanoseconds. - vcc-supply: The regulator supplying the VCC to drive the chip. - nxp,sccnxp-io-cfg: Array contains values for the emulated modem signals. The number of values depends on the UART-number in the selected chip. Each value should be composed according to the following rules: (LINE1 << SIGNAL1) | ... | (LINEX << SIGNALX), where: LINE - VALUE: OP0 - 1 OP1 - 2 OP2 - 3 OP3 - 4 OP4 - 5 OP5 - 6 OP6 - 7 OP7 - 8 IP0 - 9 IP1 - 10 IP2 - 11 IP3 - 12 IP4 - 13 IP5 - 14 IP6 - 15 SIGNAL - VALUE: DTR - 0 RTS - 4 DSR - 8 CTS - 12 DCD - 16 RNG - 20 DIR - 24 Example (Dual UART with direction control on OP0 & OP1): sc2892@10100000 { compatible = "nxp,sc2892"; reg = <0x10100000 0x10>; poll-interval = <10000>; clocks = <&sc2892_clk>; vcc-supply = <&sc2892_reg>; nxp,sccnxp-io-cfg = <0x01000000 0x02000000>; }; drivers/tty/serial/sccnxp.c +37 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/console.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/serial_core.h> #include <linux/serial.h> #include <linux/io.h> Loading Loading @@ -853,10 +855,25 @@ static const struct platform_device_id sccnxp_id_table[] = { }; MODULE_DEVICE_TABLE(platform, sccnxp_id_table); static const struct of_device_id sccnxp_dt_id_table[] = { { .compatible = "nxp,sc2681", .data = &sc2681, }, { .compatible = "nxp,sc2691", .data = &sc2691, }, { .compatible = "nxp,sc2692", .data = &sc2692, }, { .compatible = "nxp,sc2891", .data = &sc2891, }, { .compatible = "nxp,sc2892", .data = &sc2892, }, { .compatible = "nxp,sc28202", .data = &sc28202, }, { .compatible = "nxp,sc68681", .data = &sc68681, }, { .compatible = "nxp,sc68692", .data = &sc68692, }, { } }; MODULE_DEVICE_TABLE(of, sccnxp_dt_id_table); static int sccnxp_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); const struct of_device_id *of_id = of_match_device(sccnxp_dt_id_table, &pdev->dev); int i, ret, uartclk; struct sccnxp_port *s; void __iomem *membase; Loading @@ -875,8 +892,23 @@ static int sccnxp_probe(struct platform_device *pdev) spin_lock_init(&s->lock); if (of_id) { s->chip = (struct sccnxp_chip *)of_id->data; of_property_read_u32(pdev->dev.of_node, "poll-interval", &s->pdata.poll_time_us); of_property_read_u32(pdev->dev.of_node, "reg-shift", &s->pdata.reg_shift); of_property_read_u32_array(pdev->dev.of_node, "nxp,sccnxp-io-cfg", s->pdata.mctrl_cfg, s->chip->nr); } else { s->chip = (struct sccnxp_chip *)pdev->id_entry->driver_data; if (pdata) memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); } s->regulator = devm_regulator_get(&pdev->dev, "vcc"); if (!IS_ERR(s->regulator)) { ret = regulator_enable(s->regulator); Loading Loading @@ -906,16 +938,11 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; } if (pdata) memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); if (s->pdata.poll_time_us) { dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", s->pdata.poll_time_us); s->poll = 1; } if (!s->poll) { } else { s->irq = platform_get_irq(pdev, 0); if (s->irq < 0) { dev_err(&pdev->dev, "Missing irq resource data\n"); Loading Loading @@ -1018,6 +1045,7 @@ static struct platform_driver sccnxp_uart_driver = { .driver = { .name = SCCNXP_NAME, .owner = THIS_MODULE, .of_match_table = sccnxp_dt_id_table, }, .probe = sccnxp_probe, .remove = sccnxp_remove, Loading include/linux/platform_data/serial-sccnxp.h +3 −3 Original line number Diff line number Diff line Loading @@ -78,11 +78,11 @@ /* SCCNXP platform data structure */ struct sccnxp_pdata { /* Shift for A0 line */ const u8 reg_shift; u32 reg_shift; /* Modem control lines configuration */ const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; u32 mctrl_cfg[SCCNXP_MAX_UARTS]; /* Timer value for polling mode (usecs) */ const unsigned int poll_time_us; u32 poll_time_us; }; #endif Loading
Documentation/devicetree/bindings/tty/serial/sccnxp-serial.txt 0 → 100644 +53 −0 Original line number Diff line number Diff line * NXP (Philips) SCC+++(SCN+++) serial driver Required properties: - compatible: Should be "nxp,<ictype>". The supported ICs include sc2681, sc2691, sc2692, sc2891, sc2892, sc28202, sc68681 and sc68692. - reg: Address and length of the register set for the device. - interrupts: Should contain the interrupt number. If omitted, polling mode will be used instead, so "poll-interval" property should be populated in this case. Optional properties: - clocks: Phandle to input clock. If omitted, default IC frequency will be used instead. - poll-interval: Poll interval time in nanoseconds. - vcc-supply: The regulator supplying the VCC to drive the chip. - nxp,sccnxp-io-cfg: Array contains values for the emulated modem signals. The number of values depends on the UART-number in the selected chip. Each value should be composed according to the following rules: (LINE1 << SIGNAL1) | ... | (LINEX << SIGNALX), where: LINE - VALUE: OP0 - 1 OP1 - 2 OP2 - 3 OP3 - 4 OP4 - 5 OP5 - 6 OP6 - 7 OP7 - 8 IP0 - 9 IP1 - 10 IP2 - 11 IP3 - 12 IP4 - 13 IP5 - 14 IP6 - 15 SIGNAL - VALUE: DTR - 0 RTS - 4 DSR - 8 CTS - 12 DCD - 16 RNG - 20 DIR - 24 Example (Dual UART with direction control on OP0 & OP1): sc2892@10100000 { compatible = "nxp,sc2892"; reg = <0x10100000 0x10>; poll-interval = <10000>; clocks = <&sc2892_clk>; vcc-supply = <&sc2892_reg>; nxp,sccnxp-io-cfg = <0x01000000 0x02000000>; };
drivers/tty/serial/sccnxp.c +37 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/console.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/serial_core.h> #include <linux/serial.h> #include <linux/io.h> Loading Loading @@ -853,10 +855,25 @@ static const struct platform_device_id sccnxp_id_table[] = { }; MODULE_DEVICE_TABLE(platform, sccnxp_id_table); static const struct of_device_id sccnxp_dt_id_table[] = { { .compatible = "nxp,sc2681", .data = &sc2681, }, { .compatible = "nxp,sc2691", .data = &sc2691, }, { .compatible = "nxp,sc2692", .data = &sc2692, }, { .compatible = "nxp,sc2891", .data = &sc2891, }, { .compatible = "nxp,sc2892", .data = &sc2892, }, { .compatible = "nxp,sc28202", .data = &sc28202, }, { .compatible = "nxp,sc68681", .data = &sc68681, }, { .compatible = "nxp,sc68692", .data = &sc68692, }, { } }; MODULE_DEVICE_TABLE(of, sccnxp_dt_id_table); static int sccnxp_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); const struct of_device_id *of_id = of_match_device(sccnxp_dt_id_table, &pdev->dev); int i, ret, uartclk; struct sccnxp_port *s; void __iomem *membase; Loading @@ -875,8 +892,23 @@ static int sccnxp_probe(struct platform_device *pdev) spin_lock_init(&s->lock); if (of_id) { s->chip = (struct sccnxp_chip *)of_id->data; of_property_read_u32(pdev->dev.of_node, "poll-interval", &s->pdata.poll_time_us); of_property_read_u32(pdev->dev.of_node, "reg-shift", &s->pdata.reg_shift); of_property_read_u32_array(pdev->dev.of_node, "nxp,sccnxp-io-cfg", s->pdata.mctrl_cfg, s->chip->nr); } else { s->chip = (struct sccnxp_chip *)pdev->id_entry->driver_data; if (pdata) memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); } s->regulator = devm_regulator_get(&pdev->dev, "vcc"); if (!IS_ERR(s->regulator)) { ret = regulator_enable(s->regulator); Loading Loading @@ -906,16 +938,11 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; } if (pdata) memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); if (s->pdata.poll_time_us) { dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", s->pdata.poll_time_us); s->poll = 1; } if (!s->poll) { } else { s->irq = platform_get_irq(pdev, 0); if (s->irq < 0) { dev_err(&pdev->dev, "Missing irq resource data\n"); Loading Loading @@ -1018,6 +1045,7 @@ static struct platform_driver sccnxp_uart_driver = { .driver = { .name = SCCNXP_NAME, .owner = THIS_MODULE, .of_match_table = sccnxp_dt_id_table, }, .probe = sccnxp_probe, .remove = sccnxp_remove, Loading
include/linux/platform_data/serial-sccnxp.h +3 −3 Original line number Diff line number Diff line Loading @@ -78,11 +78,11 @@ /* SCCNXP platform data structure */ struct sccnxp_pdata { /* Shift for A0 line */ const u8 reg_shift; u32 reg_shift; /* Modem control lines configuration */ const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; u32 mctrl_cfg[SCCNXP_MAX_UARTS]; /* Timer value for polling mode (usecs) */ const unsigned int poll_time_us; u32 poll_time_us; }; #endif