Skip to contentSkip to conversation

Add Spreadtrum SoC bindings and serial driver support

PATCH Superseded Chunyan Zhang 3 participants 5 messages Jan 23, 2015 1 message not in the archive

Subsystems (4)

v7 of 10 Superseded Latest is v10 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): sprd-serial-v7

#1 lore raw

v7 cover Add Spreadtrum SoC bindings and serial driver support

This patch-set split the last version, and addressed the review comments from last version on serial driver code.

Changes from v6:
- Setted SPRD_TIMEOUT with 256 rather than 2048
- Used u32 instead of uint32_t
- Removed inline of handle_lsr_errors which is a single call site function
- Removed unused parameter of sprd_tx & sprd_rx
- Used spin_lock_irqsave in sprd_startup() instead of spin_lock
- Added a check for port->sysrq in sprd_console_write()
- Used a global counter as a condition of calling uart_{un}register_driver
- Added pdev->id assignment in probe()
- Setted port->flags with UPF_BOOT_AUTOCONF instead of ASYNC_BOOT_AUTOCONF

Changes from v5:
- Used Spreadtrum instead of SPRD in menus
- Changed TTY name to 'ttyS'
- Moved uart_register_driver() to probe()
- Added spinlock as needed
- Removed register states saving and restoring in suspend() and resume()

Chunyan Zhang (2):
Documentation: DT: Add bindings for Spreadtrum SoC Platform tty/serial: Add Spreadtrum sc9836-uart driver support

 Documentation/devicetree/bindings/arm/sprd.txt     |   11 +
 .../devicetree/bindings/serial/sprd-uart.txt       |    7 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 drivers/tty/serial/Kconfig                         |   18 +
 drivers/tty/serial/Makefile                        |    1 +
 drivers/tty/serial/sprd_serial.c                   |  799 ++++++++++++++++++++
 include/uapi/linux/serial_core.h                   |    3 +
 7 files changed, 840 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
 create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
 create mode 100644 drivers/tty/serial/sprd_serial.c
Signature · 6 lines
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw

PATCH v7 1/2 Documentation: DT: Add bindings for Spreadtrum SoC Platform

Adds Spreadtrum's prefix "sprd" to vendor-prefixes file. Adds the devicetree binding documentations for Spreadtrum's sc9836-uart and SC9836 SoC based on the Sharkl64 Platform which is a 64-bit SoC Platform of Spreadtrum.

---
 Documentation/devicetree/bindings/arm/sprd.txt     |   11 +++++++++++
 .../devicetree/bindings/serial/sprd-uart.txt       |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 3 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
 create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
Documentation/devicetree/bindings/arm/sprd.txt new file +11 -0
new file mode 100644
index 0000000..31a629d
@@ -0,0 +1,11 @@
+Spreadtrum SoC Platforms Device Tree Bindings
+----------------------------------------------------
+
+Sharkl64 is a Spreadtrum's SoC Platform which is based
+on ARM 64-bit processor.
+
+SC9836 openphone board with SC9836 SoC based on the
+Sharkl64 Platform shall have the following properties.
+
+Required root node properties:
+        - compatible = "sprd,sc9836-openphone", "sprd,sc9836";
Documentation/devicetree/bindings/serial/sprd-uart.txt new file +7 -0
new file mode 100644
index 0000000..2aff0f2
@@ -0,0 +1,7 @@
+* Spreadtrum serial UART
+
+Required properties:
+- compatible: must be "sprd,sc9836-uart"
+- reg: offset and length of the register set for the device
+- interrupts: exactly one interrupt specifier
+- clocks: phandles to input clocks.
Documentation/devicetree/bindings/vendor-prefixes.txt +1 -0
index b1df0ad..0a8384f 100644
@@ -153,6 +153,7 @@ snps	Synopsys, Inc.
 solidrun	SolidRun
 sony	Sony Corporation
 spansion	Spansion Inc.
+sprd	Spreadtrum Communications Inc.
 st	STMicroelectronics
 ste	ST-Ericsson
 stericsson	ST-Ericsson
Signature · 6 lines
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

PATCH v7 2/2 tty/serial: Add Spreadtrum sc9836-uart driver support

In reply to Chunyan Zhang

Add a full sc9836-uart driver for SC9836 SoC which is based on the spreadtrum sharkl64 platform.
This driver also support earlycon.

---
 drivers/tty/serial/Kconfig       |   18 +
 drivers/tty/serial/Makefile      |    1 +
 drivers/tty/serial/sprd_serial.c |  799 ++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/serial_core.h |    3 +
 4 files changed, 821 insertions(+)
 create mode 100644 drivers/tty/serial/sprd_serial.c
drivers/tty/serial/Kconfig +18 -0
index c79b43c..13211f7 100644
@@ -1577,6 +1577,24 @@ config SERIAL_MEN_Z135
 	  This driver can also be build as a module. If so, the module will be called
 	  men_z135_uart.ko
 
+config SERIAL_SPRD
+	tristate "Support for Spreadtrum serial"
+	depends on ARCH_SPRD
+	select SERIAL_CORE
+	help
+	  This enables the driver for the Spreadtrum's serial.
+
+config SERIAL_SPRD_CONSOLE
+	bool "Spreadtrum UART console support"
+	depends on SERIAL_SPRD=y
+	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
+	help
+	  Support for early debug console using Spreadtrum's serial. This enables
+	  the console before standard serial driver is probed. This is enabled
+	  with "earlycon" on the kernel command line. The console is
+	  enabled when early_param is processed.
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
drivers/tty/serial/Makefile +1 -0
index 9a548ac..4801aca 100644
@@ -93,6 +93,7 @@ obj-$(CONFIG_SERIAL_ARC)	+= arc_uart.o
 obj-$(CONFIG_SERIAL_RP2)	+= rp2.o
 obj-$(CONFIG_SERIAL_FSL_LPUART)	+= fsl_lpuart.o
 obj-$(CONFIG_SERIAL_MEN_Z135)	+= men_z135_uart.o
+obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)	+= serial_mctrl_gpio.o
drivers/tty/serial/sprd_serial.c new file +799 -0

799 lines not on this page · raw message

include/uapi/linux/serial_core.h +3 -0
index c172180..7e6eb39 100644
@@ -248,4 +248,7 @@
 /* MESON */
 #define PORT_MESON	109
 
+/* SPRD SERIAL  */
+#define PORT_SPRD	110
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
Signature · 6 lines
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw

Re: [PATCH v7 2/2] tty/serial: Add Spreadtrum sc9836-uart driver support

Hi Chunyan,

Just the minor fix to zeroing the stack local in sprd_set_termios() and using dev_get_drvdata() in sprd_suspend()/sprd_resume().

Regards,
Peter Hurley

Quoted 3 lines · Chunyan Zhang

Add a full sc9836-uart driver for SC9836 SoC which is based on the spreadtrum sharkl64 platform.
This driver also support earlycon.

[...]

drivers/tty/serial/sprd_serial.c line 369

Quoted 6 lines
drivers/tty/serial/sprd_serial.c new file +6 -0
+static void sprd_set_termios(struct uart_port *port,
+				    struct ktermios *termios,
+				    struct ktermios *old)
+{
+	unsigned int baud, quot;
+	unsigned int lcr, fc;
	unsigned int lcr = 0, fc;
Quoted 41 lines
drivers/tty/serial/sprd_serial.c new file +41 -0
+	unsigned long flags;
+
+	/* ask the core to calculate the divisor for us */
+	baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT);
+
+	quot = (unsigned int)((port->uartclk + baud / 2) / baud);
+
+	/* set data length */
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		lcr |= SPRD_LCR_DATA_LEN5;
+		break;
+	case CS6:
+		lcr |= SPRD_LCR_DATA_LEN6;
+		break;
+	case CS7:
+		lcr |= SPRD_LCR_DATA_LEN7;
+		break;
+	case CS8:
+	default:
+		lcr |= SPRD_LCR_DATA_LEN8;
+		break;
+	}
+
+	/* calculate stop bits */
+	lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT);
+	if (termios->c_cflag & CSTOPB)
+		lcr |= SPRD_LCR_STOP_2BIT;
+	else
+		lcr |= SPRD_LCR_STOP_1BIT;
+
+	/* calculate parity */
+	lcr &= ~SPRD_LCR_PARITY;
+	termios->c_cflag &= ~CMSPAR;	/* no support mark/space */
+	if (termios->c_cflag & PARENB) {
+		lcr |= SPRD_LCR_PARITY_EN;
+		if (termios->c_cflag & PARODD)
+			lcr |= SPRD_LCR_ODD_PAR;
+		else
+			lcr |= SPRD_LCR_EVEN_PAR;
+	}

[...]

Quoted 14 lines
drivers/tty/serial/sprd_serial.c new file +14 -0
+static int sprd_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct uart_port *up;
+	struct clk *clk;
+	int irq;
+	int index;
+	int ret;
+
+	for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
+		if (sprd_port[index] == NULL)
+			break;
+
+	if (index == ARRAY_SIZE(sprd_port))

drivers/tty/serial/sprd_serial.c line 706

Quoted 10 lines
drivers/tty/serial/sprd_serial.c new file +10 -0
+		return -EBUSY;
+
+	index = sprd_probe_dt_alias(index, &pdev->dev);
+
+	sprd_port[index] = devm_kzalloc(&pdev->dev,
+		sizeof(*sprd_port[index]), GFP_KERNEL);
+	if (!sprd_port[index])
+		return -ENOMEM;
+
+	pdev->id = index;

see my recent reply regarding this and sprd_suspend/sprd_resume.

Quoted 48 lines
drivers/tty/serial/sprd_serial.c new file +48 -0
+
+	up = &sprd_port[index]->port;
+	up->dev = &pdev->dev;
+	up->line = index;
+	up->type = PORT_SPRD;
+	up->iotype = SERIAL_IO_PORT;
+	up->uartclk = SPRD_DEF_RATE;
+	up->fifosize = SPRD_FIFO_SIZE;
+	up->ops = &serial_sprd_ops;
+	up->flags = UPF_BOOT_AUTOCONF;
+
+	clk = devm_clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(clk))
+		up->uartclk = clk_get_rate(clk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "not provide mem resource\n");
+		return -ENODEV;
+	}
+	up->mapbase = res->start;
+	up->membase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(up->membase))
+		return PTR_ERR(up->membase);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "not provide irq resource\n");
+		return -ENODEV;
+	}
+	up->irq = irq;
+
+	if (!sprd_ports_num) {
+		ret = uart_register_driver(&sprd_uart_driver);
+		if (ret < 0) {
+			pr_err("Failed to register SPRD-UART driver\n");
+			return ret;
+		}
+	}
+	sprd_ports_num++;
+
+	ret = uart_add_one_port(&sprd_uart_driver, up);
+	if (ret) {
+		sprd_port[index] = NULL;
+		sprd_remove(pdev);
+	}
+
+	platform_set_drvdata(pdev, up);

drivers/tty/serial/sprd_serial.c line 764

Quoted 10 lines
drivers/tty/serial/sprd_serial.c new file +10 -0
+
+	return ret;
+}
+
+static int sprd_suspend(struct device *dev)
+{
+	int id = to_platform_device(dev)->id;
+	struct uart_port *port = &sprd_port[id]->port;
+
+	uart_suspend_port(&sprd_uart_driver, port);

same comment: see my recent reply using dev_get_drvdata().

Quoted 4 lines
drivers/tty/serial/sprd_serial.c new file +4 -0
+
+	return 0;
+}
+

drivers/tty/serial/sprd_serial.c line 778

Quoted 10 lines
drivers/tty/serial/sprd_serial.c new file +10 -0
+static int sprd_resume(struct device *dev)
+{
+	int id = to_platform_device(dev)->id;
+	struct uart_port *port = &sprd_port[id]->port;
+
+	uart_resume_port(&sprd_uart_driver, port);
+
+	return 0;
+}
+

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

reviewer
#5 lore raw

Re: [PATCH v7 2/2] tty/serial: Add Spreadtrum sc9836-uart driver support

Quoted 5 lines · Peter Hurley

Hi Chunyan,

Just the minor fix to zeroing the stack local in sprd_set_termios() and using dev_get_drvdata() in sprd_suspend()/sprd_resume().

ok, I see.

Quoted 142 lines

Regards,
Peter Hurley

Quoted 3 lines · Chunyan Zhang

Add a full sc9836-uart driver for SC9836 SoC which is based on the spreadtrum sharkl64 platform.
This driver also support earlycon.

[...]

drivers/tty/serial/sprd_serial.c line 369

Quoted 6 lines
drivers/tty/serial/sprd_serial.c new file +6 -0
+static void sprd_set_termios(struct uart_port *port,
+                                 struct ktermios *termios,
+                                 struct ktermios *old)
+{
+     unsigned int baud, quot;
+     unsigned int lcr, fc;
        unsigned int lcr = 0, fc;
Quoted 41 lines
drivers/tty/serial/sprd_serial.c new file +41 -0
+     unsigned long flags;
+
+     /* ask the core to calculate the divisor for us */
+     baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT);
+
+     quot = (unsigned int)((port->uartclk + baud / 2) / baud);
+
+     /* set data length */
+     switch (termios->c_cflag & CSIZE) {
+     case CS5:
+             lcr |= SPRD_LCR_DATA_LEN5;
+             break;
+     case CS6:
+             lcr |= SPRD_LCR_DATA_LEN6;
+             break;
+     case CS7:
+             lcr |= SPRD_LCR_DATA_LEN7;
+             break;
+     case CS8:
+     default:
+             lcr |= SPRD_LCR_DATA_LEN8;
+             break;
+     }
+
+     /* calculate stop bits */
+     lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT);
+     if (termios->c_cflag & CSTOPB)
+             lcr |= SPRD_LCR_STOP_2BIT;
+     else
+             lcr |= SPRD_LCR_STOP_1BIT;
+
+     /* calculate parity */
+     lcr &= ~SPRD_LCR_PARITY;
+     termios->c_cflag &= ~CMSPAR;    /* no support mark/space */
+     if (termios->c_cflag & PARENB) {
+             lcr |= SPRD_LCR_PARITY_EN;
+             if (termios->c_cflag & PARODD)
+                     lcr |= SPRD_LCR_ODD_PAR;
+             else
+                     lcr |= SPRD_LCR_EVEN_PAR;
+     }

[...]

Quoted 14 lines
drivers/tty/serial/sprd_serial.c new file +14 -0
+static int sprd_probe(struct platform_device *pdev)
+{
+     struct resource *res;
+     struct uart_port *up;
+     struct clk *clk;
+     int irq;
+     int index;
+     int ret;
+
+     for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
+             if (sprd_port[index] == NULL)
+                     break;
+
+     if (index == ARRAY_SIZE(sprd_port))

drivers/tty/serial/sprd_serial.c line 706

Quoted 10 lines
drivers/tty/serial/sprd_serial.c new file +10 -0
+             return -EBUSY;
+
+     index = sprd_probe_dt_alias(index, &pdev->dev);
+
+     sprd_port[index] = devm_kzalloc(&pdev->dev,
+             sizeof(*sprd_port[index]), GFP_KERNEL);
+     if (!sprd_port[index])
+             return -ENOMEM;
+
+     pdev->id = index;

see my recent reply regarding this and sprd_suspend/sprd_resume.

Quoted 52 lines
drivers/tty/serial/sprd_serial.c new file +52 -0
+
+     up = &sprd_port[index]->port;
+     up->dev = &pdev->dev;
+     up->line = index;
+     up->type = PORT_SPRD;
+     up->iotype = SERIAL_IO_PORT;
+     up->uartclk = SPRD_DEF_RATE;
+     up->fifosize = SPRD_FIFO_SIZE;
+     up->ops = &serial_sprd_ops;
+     up->flags = UPF_BOOT_AUTOCONF;
+
+     clk = devm_clk_get(&pdev->dev, NULL);
+     if (!IS_ERR(clk))
+             up->uartclk = clk_get_rate(clk);
+
+     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+     if (!res) {
+             dev_err(&pdev->dev, "not provide mem resource\n");
+             return -ENODEV;
+     }
+     up->mapbase = res->start;
+     up->membase = devm_ioremap_resource(&pdev->dev, res);
+     if (IS_ERR(up->membase))
+             return PTR_ERR(up->membase);
+
+     irq = platform_get_irq(pdev, 0);
+     if (irq < 0) {
+             dev_err(&pdev->dev, "not provide irq resource\n");
+             return -ENODEV;
+     }
+     up->irq = irq;
+
+     if (!sprd_ports_num) {
+             ret = uart_register_driver(&sprd_uart_driver);
+             if (ret < 0) {
+                     pr_err("Failed to register SPRD-UART driver\n");
+                     return ret;
+             }
+     }
+     sprd_ports_num++;
+
+     ret = uart_add_one_port(&sprd_uart_driver, up);
+     if (ret) {
+             sprd_port[index] = NULL;
+             sprd_remove(pdev);
+     }
+
+     platform_set_drvdata(pdev, up);
+
+     return ret;
+}
+
Quoted 9 lines

drivers/tty/serial/sprd_serial.c line 764

Quoted 6 lines
drivers/tty/serial/sprd_serial.c new file +6 -0
+static int sprd_suspend(struct device *dev)
+{
+     int id = to_platform_device(dev)->id;
+     struct uart_port *port = &sprd_port[id]->port;
+
+     uart_suspend_port(&sprd_uart_driver, port);

same comment: see my recent reply using dev_get_drvdata().

ok, i see. thanks!

Chunyan

Quoted 6 lines
Quoted 6 lines
drivers/tty/serial/sprd_serial.c new file +6 -0
+
+     return 0;
+}
+
+static int sprd_resume(struct device *dev)
+{
Quoted 10 lines

drivers/tty/serial/sprd_serial.c line 778

Quoted 8 lines
drivers/tty/serial/sprd_serial.c new file +8 -0
+     int id = to_platform_device(dev)->id;
+     struct uart_port *port = &sprd_port[id]->port;
+
+     uart_resume_port(&sprd_uart_driver, port);
+
+     return 0;
+}
+

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html