2014-12-04 12:40:20

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.

Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
standards based on ARMv8 multiple core architecture.Now we have only one
SoC(SC9836) based on this Platform in developing.

This patchset adds Sharkl64 support in arm64 device tree and the serial driver
of SC9836-UART.

This patchset also has patches which address "sprd" prefix and DT compatible
strings for nodes which appear un-documented.

This version code was tesed both on Fast Mode and sc9836-fpga board.
We use the latest boot-wrapper-aarch64 as the bootloader.

Changes from v3:
* Addressed review comments:
- Added the description of clock property for sc9836-uart
- Revised the size of GICC to be 8KiB
- Added another compatible string for psci-0.1
- Removed the clock-frequency property of timer in DT
- Removed ARCH_SHARKL64, just left ARCH_SPRD only
- sprd_serial.c: Removed .owner of platform_driver.driver
- sprd_serial.c: Removed all usages of unlikely
- sprd_serial.c: Used the .port member of sprd_port instead of the cast
- sprd_serial.c: Used dynamic allocation for major/minor device id
- sprd_serial.c: Added a timeout and a cpu_relax for clearing rx/tx fifo
- sprd_serial.c: clear CMSPAR in termios->c_cflag
- sprd_serial.c: Set the resulting baud back into the termios
- sprd_serial.c: Implemented a shared interrupt handler

Changes from v2:
* Addressed review comments:
- Added a specific compitible string 'sc9836-uart' for the serial
- Added a full serial driver
- Added the property 'clock-frequency' for timer node in dtsi.
- Replaceed the old macro prefix 'UART_' with 'SPRD_' in the
Spreadtrum serial driver code.
* Revised the name of SoC and board from 'sharkl3' to 'sc9836'
* Used dual-license for DTS files
* Added a menuconfig 'ARCH_SPRD' in arch/arm64/Kconfig

Changes from v1:
* Addressed review comments:
- Added "sprd" prefix to vendor-prefixes.txt
- Created serial/sprd-serial.txt and remove the properties for serial-sprd
from of-serial.txt to it.
- Renamed of-serial.txt to 8250.txt according to Arnd's review comments
- Splited and revised .dts for Sharkl64 Platform
- Changed to PSCI method for cpu power management
- Revised Kconfig Makefile to match the alphabetical ordering
- Renamed serial-sprd-earlycon.c to serial-sprd.c

Chunyan Zhang (3):
Documentation: DT: Renamed of-serial.txt to 8250.txt
Documentation: DT: Add bindings for Spreadtrum SoC Platform
tty/serial: Add Spreadtrum sc9836-uart driver support

Zhizhou Zhang (2):
arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile
arm64: Add support for Spreadtrum's Sharkl64 Platform in Kconfig and
defconfig

Documentation/devicetree/bindings/arm/sprd.txt | 11 +
.../bindings/serial/{of-serial.txt => 8250.txt} | 0
.../devicetree/bindings/serial/sprd-uart.txt | 9 +
.../devicetree/bindings/vendor-prefixes.txt | 1 +
arch/arm64/Kconfig | 6 +
arch/arm64/boot/dts/Makefile | 1 +
arch/arm64/boot/dts/sprd-sc9836-openphone.dts | 85 +++
arch/arm64/boot/dts/sprd-sc9836.dtsi | 102 +++
arch/arm64/boot/dts/sprd-sharkl64.dtsi | 105 +++
arch/arm64/configs/defconfig | 1 +
drivers/tty/serial/Kconfig | 18 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/sprd_serial.c | 761 ++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
14 files changed, 1104 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
rename Documentation/devicetree/bindings/serial/{of-serial.txt => 8250.txt} (100%)
create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt
create mode 100644 arch/arm64/boot/dts/sprd-sc9836-openphone.dts
create mode 100644 arch/arm64/boot/dts/sprd-sc9836.dtsi
create mode 100644 arch/arm64/boot/dts/sprd-sharkl64.dtsi
create mode 100644 drivers/tty/serial/sprd_serial.c

--
1.7.9.5


2014-12-04 11:54:36

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 2/5] 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.

Signed-off-by: Chunyan Zhang <[email protected]>
Signed-off-by: Orson Zhai <[email protected]>
---
Documentation/devicetree/bindings/arm/sprd.txt | 11 +++++++++++
.../devicetree/bindings/serial/sprd-uart.txt | 9 +++++++++
.../devicetree/bindings/vendor-prefixes.txt | 1 +
3 files changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/sprd.txt
create mode 100644 Documentation/devicetree/bindings/serial/sprd-uart.txt

diff --git a/Documentation/devicetree/bindings/arm/sprd.txt b/Documentation/devicetree/bindings/arm/sprd.txt
new file mode 100644
index 0000000..31a629d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sprd.txt
@@ -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";
diff --git a/Documentation/devicetree/bindings/serial/sprd-uart.txt b/Documentation/devicetree/bindings/serial/sprd-uart.txt
new file mode 100644
index 0000000..9000e2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/sprd-uart.txt
@@ -0,0 +1,9 @@
+* 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
+
+Optional properties:
+- clocks: phandles to input clocks.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 723999d..ce99ecdfb 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -142,6 +142,7 @@ snps Synopsys, Inc.
solidrun SolidRun
sony Sony Corporation
spansion Spansion Inc.
+sprd Spreadtrum Communications Inc.
st STMicroelectronics
ste ST-Ericsson
stericsson ST-Ericsson
--
1.7.9.5

2014-12-04 11:57:52

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 1/5] Documentation: DT: Renamed of-serial.txt to 8250.txt

The file of-serial.txt was only for 8250 compatible UART implementations,
so renamed it to 8250.txt to avoid confusing other persons.
This is suggested by Arnd, see:
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/291455.html

Signed-off-by: Chunyan Zhang <[email protected]>
Acked-by: Mark Rutland <[email protected]>
---
.../bindings/serial/{of-serial.txt => 8250.txt} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename Documentation/devicetree/bindings/serial/{of-serial.txt => 8250.txt} (100%)

diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/8250.txt
similarity index 100%
rename from Documentation/devicetree/bindings/serial/of-serial.txt
rename to Documentation/devicetree/bindings/serial/8250.txt
--
1.7.9.5

2014-12-04 12:02:07

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 4/5] arm64: Add support for Spreadtrum's Sharkl64 Platform in Kconfig and defconfig

From: Zhizhou Zhang <[email protected]>

Adds support for Spreadtrum's SoC Platform in the arm64 Kconfig and
defconfig files.

Signed-off-by: Zhizhou Zhang <[email protected]>
Signed-off-by: Chunyan Zhang <[email protected]>
Signed-off-by: Orson Zhai <[email protected]>
---
arch/arm64/Kconfig | 6 ++++++
arch/arm64/configs/defconfig | 1 +
2 files changed, 7 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ac9afde..abca2c4 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -146,6 +146,12 @@ config ARCH_THUNDER
help
This enables support for Cavium's Thunder Family of SoCs.

+config ARCH_SPRD
+ bool "Spreadtrum SoC platform"
+ depends on ARM64
+ help
+ Support for Spreadtrum ARM based SoCs
+
config ARCH_VEXPRESS
bool "ARMv8 software model (Versatile Express)"
select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 9cd37de..db39340 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -33,6 +33,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_ARCH_THUNDER=y
+CONFIG_ARCH_SPRD=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
CONFIG_SMP=y
--
1.7.9.5

2014-12-04 12:05:30

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 3/5] arm64: dts: Add support for Spreadtrum SC9836 SoC in dts and Makefile

From: Zhizhou Zhang <[email protected]>

Adds the device tree support for Spreadtrum SC9836 SoC which is based on
Sharkl64 platform.

Sharkl64 platform contains the common nodes of Spreadtrum's arm64-based SoCs.

Signed-off-by: Zhizhou Zhang <[email protected]>
Signed-off-by: Chunyan Zhang <[email protected]>
Signed-off-by: Orson Zhai <[email protected]>
---
arch/arm64/boot/dts/Makefile | 1 +
arch/arm64/boot/dts/sprd-sc9836-openphone.dts | 85 ++++++++++++++++++++
arch/arm64/boot/dts/sprd-sc9836.dtsi | 102 ++++++++++++++++++++++++
arch/arm64/boot/dts/sprd-sharkl64.dtsi | 105 +++++++++++++++++++++++++
4 files changed, 293 insertions(+)
create mode 100644 arch/arm64/boot/dts/sprd-sc9836-openphone.dts
create mode 100644 arch/arm64/boot/dts/sprd-sc9836.dtsi
create mode 100644 arch/arm64/boot/dts/sprd-sharkl64.dtsi

diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index f8001a6..d0aff8a 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,4 +1,5 @@
dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
+dtb-$(CONFIG_ARCH_SHARKL64) += sprd-sc9836-openphone.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb

diff --git a/arch/arm64/boot/dts/sprd-sc9836-openphone.dts b/arch/arm64/boot/dts/sprd-sc9836-openphone.dts
new file mode 100644
index 0000000..484d714
--- /dev/null
+++ b/arch/arm64/boot/dts/sprd-sc9836-openphone.dts
@@ -0,0 +1,85 @@
+/*
+ * Spreadtrum SC9836 openphone board DTS file
+ *
+ * Copyright (C) 2014, Spreadtrum Communications Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "sprd-sc9836.dtsi"
+
+/ {
+ model = "Spreadtrum,SC9836 Openphone Board";
+
+ compatible = "sprd,sc9836-openphone", "sprd,sc9836";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0 0x80000000 0 0x20000000>;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/sprd-sc9836.dtsi b/arch/arm64/boot/dts/sprd-sc9836.dtsi
new file mode 100644
index 0000000..1abf897
--- /dev/null
+++ b/arch/arm64/boot/dts/sprd-sc9836.dtsi
@@ -0,0 +1,102 @@
+/*
+ * Spreadtrum SC9836 SoC DTS file
+ *
+ * Copyright (C) 2014, Spreadtrum Communications Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "sprd-sharkl64.dtsi"
+
+/ {
+ compatible = "sprd,sc9836";
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ };
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ };
+ };
+
+ gic: interrupt-controller@12001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0 0x12001000 0 0x1000>,
+ <0 0x12002000 0 0x2000>,
+ <0 0x12004000 0 0x2000>,
+ <0 0x12006000 0 0x2000>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2", "arm,psci";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0xff01>,
+ <1 14 0xff01>,
+ <1 11 0xff01>,
+ <1 10 0xff01>;
+ };
+};
diff --git a/arch/arm64/boot/dts/sprd-sharkl64.dtsi b/arch/arm64/boot/dts/sprd-sharkl64.dtsi
new file mode 100644
index 0000000..d9ecfe9
--- /dev/null
+++ b/arch/arm64/boot/dts/sprd-sharkl64.dtsi
@@ -0,0 +1,105 @@
+/*
+ * Spreadtrum Sharkl64 platform DTS file
+ *
+ * Copyright (C) 2014, Spreadtrum Communications Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ soc {
+ compatible = "simple-bus";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ap_apb: apb@70000000 {
+ compatible = "simple-bus";
+ reg = <0x0 0x70000000 0x0 0x10000000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ uart0: serial@70000000 {
+ compatible = "sprd,sc9836-uart";
+ reg = <0 0x70000000 0 0x100>;
+ interrupts = <0 2 0xf04>;
+ clocks = <&clk26mhz>;
+ status = "disabled";
+ };
+
+ uart1: serial@70100000 {
+ compatible = "sprd,sc9836-uart";
+ reg = <0 0x70100000 0 0x100>;
+ interrupts = <0 3 0xf04>;
+ clocks = <&clk26mhz>;
+ status = "disabled";
+ };
+
+ uart2: serial@70200000 {
+ compatible = "sprd,sc9836-uart";
+ reg = <0 0x70200000 0 0x100>;
+ interrupts = <0 2 0xf04>;
+ clocks = <&clk26mhz>;
+ status = "disabled";
+ };
+
+ uart3: serial@70300000 {
+ compatible = "sprd,sc9836-uart";
+ reg = <0 0x70300000 0 0x100>;
+ interrupts = <0 3 0xf04>;
+ clocks = <&clk26mhz>;
+ status = "disabled";
+ };
+ };
+ };
+
+ clocks {
+ clk26mhz: clk26mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ };
+ };
+};
--
1.7.9.5

2014-12-04 12:06:40

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v4 5/5] tty/serial: Add Spreadtrum sc9836-uart driver support

Add a full sc9836-uart driver for SC9836 SoC which is based on the
spreadtrum sharkl64 platform.
This driver also support earlycon.
This patch also replaced the spaces between the macros and their
values with the tabs in serial_core.h

Signed-off-by: Chunyan Zhang <[email protected]>
Signed-off-by: Orson Zhai <[email protected]>
Originally-by: Lanqing Liu <[email protected]>
---
drivers/tty/serial/Kconfig | 18 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/sprd_serial.c | 761 ++++++++++++++++++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
4 files changed, 783 insertions(+)
create mode 100644 drivers/tty/serial/sprd_serial.c

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 649b784..7b9b0f4 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1573,6 +1573,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 SPRD serial"
+ depends on ARCH_SPRD
+ select SERIAL_CORE
+ help
+ This enables the driver for the Spreadtrum's serial.
+
+config SERIAL_SPRD_CONSOLE
+ bool "SPRD 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
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 9a548ac..4801aca 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -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
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
new file mode 100644
index 0000000..1ad800e
--- /dev/null
+++ b/drivers/tty/serial/sprd_serial.c
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/console.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+/* device name */
+#define UART_NR_MAX 8
+#define SPRD_TTY_NAME "ttySPX"
+#define SPRD_FIFO_SIZE 128
+#define SPRD_DEF_RATE 26000000
+#define SPRD_TIMEOUT 2048
+
+/* the offset of serial registers and BITs for them */
+/* data registers */
+#define SPRD_TXD 0x0000
+#define SPRD_RXD 0x0004
+
+/* line status register and its BITs */
+#define SPRD_LSR 0x0008
+#define SPRD_LSR_OE BIT(4)
+#define SPRD_LSR_FE BIT(3)
+#define SPRD_LSR_PE BIT(2)
+#define SPRD_LSR_BI BIT(7)
+#define SPRD_LSR_TX_OVER BIT(15)
+
+/* data number in TX and RX fifo */
+#define SPRD_STS1 0x000C
+
+/* interrupt enable register and its BITs */
+#define SPRD_IEN 0x0010
+#define SPRD_IEN_RX_FULL BIT(0)
+#define SPRD_IEN_TX_EMPTY BIT(1)
+#define SPRD_IEN_BREAK_DETECT BIT(7)
+#define SPRD_IEN_TIMEOUT BIT(13)
+
+/* interrupt clear register */
+#define SPRD_ICLR 0x0014
+
+/* line control register */
+#define SPRD_LCR 0x0018
+#define SPRD_LCR_STOP_1BIT 0x10
+#define SPRD_LCR_STOP_2BIT 0x30
+#define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3))
+#define SPRD_LCR_DATA_LEN5 0x0
+#define SPRD_LCR_DATA_LEN6 0x4
+#define SPRD_LCR_DATA_LEN7 0x8
+#define SPRD_LCR_DATA_LEN8 0xc
+#define SPRD_LCR_PARITY (BIT(0) | BIT(1))
+#define SPRD_LCR_PARITY_EN 0x2
+#define SPRD_LCR_EVEN_PAR 0x0
+#define SPRD_LCR_ODD_PAR 0x1
+
+/* control register 1 */
+#define SPRD_CTL1 0x001C
+#define RX_HW_FLOW_CTL_THLD BIT(6)
+#define RX_HW_FLOW_CTL_EN BIT(7)
+#define TX_HW_FLOW_CTL_EN BIT(8)
+
+/* fifo threshold register */
+#define SPRD_CTL2 0x0020
+#define THLD_TX_EMPTY 0x40
+#define THLD_RX_FULL 0x40
+
+/* config baud rate register */
+#define SPRD_CLKD0 0x0024
+#define SPRD_CLKD1 0x0028
+
+/* interrupt mask status register */
+#define SPRD_IMSR 0x002C
+#define SPRD_IMSR_RX_FIFO_FULL BIT(0)
+#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
+#define SPRD_IMSR_BREAK_DETECT BIT(7)
+#define SPRD_IMSR_TIMEOUT BIT(13)
+
+struct reg_backup {
+ uint32_t ien;
+ uint32_t ctrl0;
+ uint32_t ctrl1;
+ uint32_t ctrl2;
+ uint32_t clkd0;
+ uint32_t clkd1;
+ uint32_t dspwait;
+};
+struct sprd_uart_port {
+ struct uart_port port;
+ struct reg_backup reg_bak;
+ char name[16];
+};
+static struct sprd_uart_port *sprd_port[UART_NR_MAX] = { NULL };
+
+static inline unsigned int serial_in(struct uart_port *port, int offset)
+{
+ return readl_relaxed(port->membase + offset);
+}
+
+static inline void serial_out(struct uart_port *port, int offset, int value)
+{
+ writel_relaxed(value, port->membase + offset);
+}
+
+static unsigned int sprd_tx_empty(struct uart_port *port)
+{
+ if (serial_in(port, SPRD_STS1) & 0xff00)
+ return 0;
+ else
+ return TIOCSER_TEMT;
+}
+
+static unsigned int sprd_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_DSR | TIOCM_CTS;
+}
+
+static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ /* nothing to do */
+}
+
+static void sprd_stop_tx(struct uart_port *port)
+{
+ unsigned int ien, iclr;
+
+ iclr = serial_in(port, SPRD_ICLR);
+ ien = serial_in(port, SPRD_IEN);
+
+ iclr |= SPRD_IEN_TX_EMPTY;
+ ien &= ~SPRD_IEN_TX_EMPTY;
+
+ serial_out(port, SPRD_ICLR, iclr);
+ serial_out(port, SPRD_IEN, ien);
+}
+
+static void sprd_start_tx(struct uart_port *port)
+{
+ unsigned int ien;
+
+ ien = serial_in(port, SPRD_IEN);
+ if (!(ien & SPRD_IEN_TX_EMPTY)) {
+ ien |= SPRD_IEN_TX_EMPTY;
+ serial_out(port, SPRD_IEN, ien);
+ }
+}
+
+static void sprd_stop_rx(struct uart_port *port)
+{
+ unsigned int ien, iclr;
+
+ iclr = serial_in(port, SPRD_ICLR);
+ ien = serial_in(port, SPRD_IEN);
+
+ ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT);
+ iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT;
+
+ serial_out(port, SPRD_IEN, ien);
+ serial_out(port, SPRD_ICLR, iclr);
+}
+
+/* The Sprd serial does not support this function. */
+static void sprd_break_ctl(struct uart_port *port, int break_state)
+{
+ /* nothing to do */
+}
+
+static inline int handle_lsr_errors(struct uart_port *port,
+ unsigned int *flag, unsigned int *lsr)
+{
+ int ret = 0;
+
+ /* stastics */
+ if (*lsr & SPRD_LSR_BI) {
+ *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE);
+ port->icount.brk++;
+ ret = uart_handle_break(port);
+ if (ret)
+ return ret;
+ } else if (*lsr & SPRD_LSR_PE)
+ port->icount.parity++;
+ else if (*lsr & SPRD_LSR_FE)
+ port->icount.frame++;
+ if (*lsr & SPRD_LSR_OE)
+ port->icount.overrun++;
+
+ /* mask off conditions which should be ignored */
+ *lsr &= port->read_status_mask;
+ if (*lsr & SPRD_LSR_BI)
+ *flag = TTY_BREAK;
+ else if (*lsr & SPRD_LSR_PE)
+ *flag = TTY_PARITY;
+ else if (*lsr & SPRD_LSR_FE)
+ *flag = TTY_FRAME;
+
+ return ret;
+}
+
+static inline void sprd_rx(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ struct tty_port *tty = &port->state->port;
+ unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT;
+
+ while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) {
+ lsr = serial_in(port, SPRD_LSR);
+ ch = serial_in(port, SPRD_RXD);
+ flag = TTY_NORMAL;
+ port->icount.rx++;
+
+ if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE
+ | SPRD_LSR_FE | SPRD_LSR_OE))
+ if (handle_lsr_errors(port, &lsr, &flag))
+ continue;
+ if (uart_handle_sysrq_char(port, ch))
+ continue;
+
+ uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag);
+ }
+
+ tty_flip_buffer_push(tty);
+}
+
+static inline void sprd_tx(int irq, void *dev_id)
+{
+ struct uart_port *port = dev_id;
+ struct circ_buf *xmit = &port->state->xmit;
+ int count;
+
+ if (port->x_char) {
+ serial_out(port, SPRD_TXD, port->x_char);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ sprd_stop_tx(port);
+ return;
+ }
+ count = THLD_TX_EMPTY;
+ do {
+ serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+ if (uart_circ_empty(xmit))
+ break;
+ } while (--count > 0);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ sprd_stop_tx(port);
+}
+
+/*
+ *this handles the interrupt from one port
+ */
+static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
+{
+ struct uart_port *port = (struct uart_port *)dev_id;
+ u32 ims;
+
+ ims = serial_in(port, SPRD_IMSR);
+
+ if (!ims)
+ return IRQ_NONE;
+
+ serial_out(port, SPRD_ICLR, ~0);
+
+ if (ims & (SPRD_IMSR_RX_FIFO_FULL |
+ SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) {
+ sprd_rx(irq, port);
+ }
+ if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
+ sprd_tx(irq, port);
+
+ return IRQ_HANDLED;
+}
+
+static int sprd_startup(struct uart_port *port)
+{
+ int ret = 0;
+ unsigned int ien, ctrl1;
+ unsigned int timeout;
+ struct sprd_uart_port *sp;
+
+ serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL));
+
+ /* clear rx fifo */
+ timeout = SPRD_TIMEOUT;
+ while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff)
+ serial_in(port, SPRD_RXD);
+
+ /* clear tx fifo */
+ timeout = SPRD_TIMEOUT;
+ while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00)
+ cpu_relax();
+
+ /* clear interrupt */
+ serial_out(port, SPRD_IEN, 0x0);
+ serial_out(port, SPRD_ICLR, ~0);
+
+ /* allocate irq */
+ sp = container_of(port, struct sprd_uart_port, port);
+ snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line);
+ ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq,
+ IRQF_SHARED, sp->name, port);
+ if (ret) {
+ dev_err(port->dev, "fail to request serial irq %d\n",
+ port->irq);
+ return ret;
+ }
+ ctrl1 = serial_in(port, SPRD_CTL1);
+ ctrl1 |= 0x3e00 | THLD_RX_FULL;
+ serial_out(port, SPRD_CTL1, ctrl1);
+
+ /* enable interrupt */
+ spin_lock(&port->lock);
+ ien = serial_in(port, SPRD_IEN);
+ ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT;
+ serial_out(port, SPRD_IEN, ien);
+ spin_unlock(&port->lock);
+
+ return 0;
+}
+
+static void sprd_shutdown(struct uart_port *port)
+{
+ serial_out(port, SPRD_IEN, 0x0);
+ serial_out(port, SPRD_ICLR, ~0);
+ devm_free_irq(port->dev, port->irq, port);
+}
+
+static void sprd_set_termios(struct uart_port *port,
+ struct ktermios *termios,
+ struct ktermios *old)
+{
+ unsigned int baud, quot;
+ unsigned int lcr, fc;
+
+ /* ask the core to calculate the divisor for us */
+ baud = uart_get_baud_rate(port, termios, old, 1200, 3000000);
+
+ quot = (unsigned int)((port->uartclk + baud / 2) / baud);
+
+ /* set data length */
+ lcr = serial_in(port, SPRD_LCR);
+ lcr &= ~SPRD_LCR_DATA_LEN;
+ 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;
+ }
+
+ /* change the port state. */
+ /* update the per-port timeout */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ port->read_status_mask = SPRD_LSR_OE;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ port->read_status_mask |= SPRD_LSR_BI;
+
+ /* characters to ignore */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= SPRD_LSR_BI;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= SPRD_LSR_OE;
+ }
+
+ /* flow control */
+ fc = serial_in(port, SPRD_CTL1);
+ fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN);
+ if (termios->c_cflag & CRTSCTS) {
+ fc |= RX_HW_FLOW_CTL_THLD;
+ fc |= RX_HW_FLOW_CTL_EN;
+ fc |= TX_HW_FLOW_CTL_EN;
+ }
+
+ /* clock divider bit0~bit15 */
+ serial_out(port, SPRD_CLKD0, quot & 0xffff);
+
+ /* clock divider bit16~bit20 */
+ serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16);
+ serial_out(port, SPRD_LCR, lcr);
+ fc |= 0x3e00 | THLD_RX_FULL;
+ serial_out(port, SPRD_CTL1, fc);
+
+ /* Don't rewrite B0 */
+ if (tty_termios_baud_rate(termios))
+ tty_termios_encode_baud_rate(termios, baud, baud);
+}
+
+static const char *sprd_type(struct uart_port *port)
+{
+ return "SPX";
+}
+
+static void sprd_release_port(struct uart_port *port)
+{
+ /* nothing to do */
+}
+
+static int sprd_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+static void sprd_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE)
+ port->type = PORT_SPRD;
+}
+
+static int sprd_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ if (ser->type != PORT_SPRD)
+ return -EINVAL;
+ if (port->irq != ser->irq)
+ return -EINVAL;
+ return 0;
+}
+
+static struct uart_ops serial_sprd_ops = {
+ .tx_empty = sprd_tx_empty,
+ .get_mctrl = sprd_get_mctrl,
+ .set_mctrl = sprd_set_mctrl,
+ .stop_tx = sprd_stop_tx,
+ .start_tx = sprd_start_tx,
+ .stop_rx = sprd_stop_rx,
+ .break_ctl = sprd_break_ctl,
+ .startup = sprd_startup,
+ .shutdown = sprd_shutdown,
+ .set_termios = sprd_set_termios,
+ .type = sprd_type,
+ .release_port = sprd_release_port,
+ .request_port = sprd_request_port,
+ .config_port = sprd_config_port,
+ .verify_port = sprd_verify_port,
+};
+
+#ifdef CONFIG_SERIAL_SPRD_CONSOLE
+static inline void wait_for_xmitr(struct uart_port *port)
+{
+ unsigned int status, tmout = 10000;
+
+ /* wait up to 10ms for the character(s) to be sent */
+ do {
+ status = serial_in(port, SPRD_STS1);
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ } while (status & 0xff00);
+}
+
+static void sprd_console_putchar(struct uart_port *port, int ch)
+{
+ wait_for_xmitr(port);
+ serial_out(port, SPRD_TXD, ch);
+}
+
+static void sprd_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct uart_port *port = &sprd_port[co->index]->port;
+ int ien;
+ int locked = 1;
+
+ if (oops_in_progress)
+ locked = spin_trylock(&port->lock);
+ else
+ spin_lock(&port->lock);
+ /* save the IEN then disable the interrupts */
+ ien = serial_in(port, SPRD_IEN);
+ serial_out(port, SPRD_IEN, 0x0);
+
+ uart_console_write(port, s, count, sprd_console_putchar);
+
+ /* wait for transmitter to become empty and restore the IEN */
+ wait_for_xmitr(port);
+ serial_out(port, SPRD_IEN, ien);
+ if (locked)
+ spin_unlock(&port->lock);
+}
+
+static int __init sprd_console_setup(struct console *co, char *options)
+{
+ struct uart_port *port;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index >= UART_NR_MAX || co->index < 0)
+ co->index = 0;
+
+ port = &sprd_port[co->index]->port;
+ if (port == NULL) {
+ pr_info("serial port %d not yet initialized\n", co->index);
+ return -ENODEV;
+ }
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver sprd_uart_driver;
+static struct console sprd_console = {
+ .name = SPRD_TTY_NAME,
+ .write = sprd_console_write,
+ .device = uart_console_device,
+ .setup = sprd_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &sprd_uart_driver,
+};
+
+#define SPRD_CONSOLE (&sprd_console)
+
+/* Support for earlycon */
+static void sprd_putc(struct uart_port *port, int c)
+{
+ while (!(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER))
+ ;
+ writeb(c, port->membase + SPRD_TXD);
+}
+
+static void sprd_early_write(struct console *con, const char *s,
+ unsigned n)
+{
+ struct earlycon_device *dev = con->data;
+
+ uart_console_write(&dev->port, s, n, sprd_putc);
+}
+
+static int __init sprd_early_console_setup(
+ struct earlycon_device *device,
+ const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->con->write = sprd_early_write;
+ return 0;
+}
+
+EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup);
+OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart",
+ sprd_early_console_setup);
+
+#else /* !CONFIG_SERIAL_SPRD_CONSOLE */
+#define SPRD_CONSOLE NULL
+#endif
+
+static struct uart_driver sprd_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = "sprd_serial",
+ .dev_name = SPRD_TTY_NAME,
+ .major = 0,
+ .minor = 0,
+ .nr = UART_NR_MAX,
+ .cons = SPRD_CONSOLE,
+};
+
+static int sprd_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ struct uart_port *up;
+ struct clk *clk;
+ int irq;
+
+
+ if (np)
+ pdev->id = of_alias_get_id(np, "serial");
+
+ if (pdev->id < 0 || pdev->id >= UART_NR_MAX) {
+ dev_err(&pdev->dev, "does not support id %d\n", pdev->id);
+ return -ENXIO;
+ }
+
+ sprd_port[pdev->id] = devm_kzalloc(&pdev->dev,
+ sizeof(*sprd_port[pdev->id]), GFP_KERNEL);
+ if (!sprd_port[pdev->id])
+ return -ENOMEM;
+
+ up = &sprd_port[pdev->id]->port;
+ up->dev = &pdev->dev;
+ up->line = pdev->id;
+ 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 = ASYNC_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;
+
+ platform_set_drvdata(pdev, up);
+
+ return uart_add_one_port(&sprd_uart_driver, up);
+}
+
+static int sprd_remove(struct platform_device *dev)
+{
+ struct uart_port *up = platform_get_drvdata(dev);
+
+ return uart_remove_one_port(&sprd_uart_driver, up);
+}
+
+static int sprd_suspend(struct platform_device *dev, pm_message_t state)
+{
+ int id = dev->id;
+ struct uart_port *port = &sprd_port[id]->port;
+ struct reg_backup *reg_bak = &sprd_port[id]->reg_bak;
+
+ reg_bak->ien = serial_in(port, SPRD_IEN);
+ reg_bak->ctrl0 = serial_in(port, SPRD_LCR);
+ reg_bak->ctrl1 = serial_in(port, SPRD_CTL1);
+ reg_bak->ctrl2 = serial_in(port, SPRD_CTL2);
+ reg_bak->clkd0 = serial_in(port, SPRD_CLKD0);
+ reg_bak->clkd1 = serial_in(port, SPRD_CLKD1);
+
+ return 0;
+}
+
+static int sprd_resume(struct platform_device *dev)
+{
+ int id = dev->id;
+ struct uart_port *port = &sprd_port[id]->port;
+ struct reg_backup *reg_bak = &sprd_port[id]->reg_bak;
+
+ serial_out(port, SPRD_LCR, reg_bak->ctrl0);
+ serial_out(port, SPRD_CTL1, reg_bak->ctrl1);
+ serial_out(port, SPRD_CTL2, reg_bak->ctrl2);
+ serial_out(port, SPRD_CLKD0, reg_bak->clkd0);
+ serial_out(port, SPRD_CLKD1, reg_bak->clkd1);
+ serial_out(port, SPRD_IEN, reg_bak->ien);
+
+ return 0;
+}
+
+static const struct of_device_id serial_ids[] = {
+ {.compatible = "sprd,sc9836-uart",},
+ {}
+};
+
+static struct platform_driver sprd_platform_driver = {
+ .probe = sprd_probe,
+ .remove = sprd_remove,
+ .suspend = sprd_suspend,
+ .resume = sprd_resume,
+ .driver = {
+ .name = "sprd_serial",
+ .of_match_table = of_match_ptr(serial_ids),
+ },
+};
+
+static int __init sprd_serial_init(void)
+{
+ int ret = 0;
+
+ ret = uart_register_driver(&sprd_uart_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&sprd_platform_driver);
+ if (ret)
+ uart_unregister_driver(&sprd_uart_driver);
+
+ return ret;
+}
+
+static void __exit sprd_serial_exit(void)
+{
+ platform_driver_unregister(&sprd_platform_driver);
+ uart_unregister_driver(&sprd_uart_driver);
+}
+
+module_init(sprd_serial_init);
+module_exit(sprd_serial_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Spreadtrum SoC serial driver series");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 16ad852..c0791d6 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -247,4 +247,7 @@
/* MESON */
#define PORT_MESON 109

+/* SPRD SERIAL */
+#define PORT_SPRD 110
+
#endif /* _UAPILINUX_SERIAL_CORE_H */
--
1.7.9.5

2014-12-05 07:24:05

by Olof Johansson

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

On Thu, Dec 04, 2014 at 07:34:15PM +0800, Chunyan Zhang wrote:
> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>
> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
> standards based on ARMv8 multiple core architecture.Now we have only one
> SoC(SC9836) based on this Platform in developing.
>
> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
> of SC9836-UART.
>
> This patchset also has patches which address "sprd" prefix and DT compatible
> strings for nodes which appear un-documented.
>
> This version code was tesed both on Fast Mode and sc9836-fpga board.
> We use the latest boot-wrapper-aarch64 as the bootloader.

Hi,

We only got 3 of the 5 patches of this version (1, 2 and 4). Can you
resend the dts patch to us (I'm guessing the serial one will go through Greg).


Thanks,

-Olof

2014-12-05 12:27:28

by Chunyan Zhang

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

On Fri, Dec 5, 2014 at 6:40 PM, Mark Rutland <[email protected]> wrote:
> Hi,
>
> On Thu, Dec 04, 2014 at 11:34:15AM +0000, Chunyan Zhang wrote:
>> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>>
>> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
>> standards based on ARMv8 multiple core architecture.Now we have only one
>> SoC(SC9836) based on this Platform in developing.
>>
>> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
>> of SC9836-UART.
>>
>> This patchset also has patches which address "sprd" prefix and DT compatible
>> strings for nodes which appear un-documented.
>>
>> This version code was tesed both on Fast Mode and sc9836-fpga board.
>> We use the latest boot-wrapper-aarch64 as the bootloader.
>>
>> Changes from v3:
>> * Addressed review comments:
>> - Added the description of clock property for sc9836-uart
>> - Revised the size of GICC to be 8KiB
>> - Added another compatible string for psci-0.1
>
> I had open questions on v3 regarding your PSCI imlpementation. You
> mentioned that you are using the aarch64 bootwrapper, but your DT
> describes PSCI 0.2, and the (upstream) bootwrapper does not implement
> PSCI 0.2. Adding the old PSCI compatible string is _not_ sufficient if
> you do not have a full PSCI 0.2 implementation.
>
> Given that PSCI 0.2 requires more functionality to be implemented, I'd
> like to know that your implementation is spec-compliant (implementing
> the mandatory functions, nters the kernel in the correct state, etc),
> and that it has been tested.
>
> Would you be able to look at my comments from the last posting please?
>
> Thanks,
> Mark.
> --

Hi, Mark

Ok, I'll check it again with our related engineers.

Actually, I had read all of your comments carefully before sending
each version of patches, and I replied you a few days early, I guess
you may miss it :)

If we just implemented psci-0.1 until now, can we submit this path
without "compatible = "arm,psci-0.2"", but only with " compatible =
"arm,psci" ".



Thanks,
Chunyan

2014-12-05 14:13:35

by Orson Zhai

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

Hi, Mark,

On Fri, Dec 5, 2014 at 8:27 PM, Lyra Zhang <[email protected]> wrote:
> On Fri, Dec 5, 2014 at 6:40 PM, Mark Rutland <[email protected]> wrote:
>> Hi,
>>
>> On Thu, Dec 04, 2014 at 11:34:15AM +0000, Chunyan Zhang wrote:
>>> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>>>
>>> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
>>> standards based on ARMv8 multiple core architecture.Now we have only one
>>> SoC(SC9836) based on this Platform in developing.
>>>
>>> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
>>> of SC9836-UART.
>>>
>>> This patchset also has patches which address "sprd" prefix and DT compatible
>>> strings for nodes which appear un-documented.
>>>
>>> This version code was tesed both on Fast Mode and sc9836-fpga board.
>>> We use the latest boot-wrapper-aarch64 as the bootloader.
>>>
>>> Changes from v3:
>>> * Addressed review comments:
>>> - Added the description of clock property for sc9836-uart
>>> - Revised the size of GICC to be 8KiB
>>> - Added another compatible string for psci-0.1
>>
>> I had open questions on v3 regarding your PSCI imlpementation. You
>> mentioned that you are using the aarch64 bootwrapper, but your DT
>> describes PSCI 0.2, and the (upstream) bootwrapper does not implement
>> PSCI 0.2. Adding the old PSCI compatible string is _not_ sufficient if
>> you do not have a full PSCI 0.2 implementation.
>>
>> Given that PSCI 0.2 requires more functionality to be implemented, I'd
>> like to know that your implementation is spec-compliant (implementing
>> the mandatory functions, nters the kernel in the correct state, etc),
>> and that it has been tested.
>>
>> Would you be able to look at my comments from the last posting please?

I'd like to show you more technical details of our psci implementation.

Here the dt code is fresh from our engineering repository.
As far as I know our engineers are testing on psci currently.

04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 98) psci {
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 99)
compatible = "arm,psci";
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 100)
method = "smc";
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 101)
cpu_on = <0xc4000003>;
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 102)
cpu_off = <0x84000002>;
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 103)
cpu_suspend = <0xc4000001>;
04b8b5a5 (zhiqiang.zhang 2014-12-04 15:27:17 +0800 104) };

Does it reveal the information as you concern?
It's no doubt that we'll implement psci-v0.2 eventually.
Considering that the code might be upstreamed in few weeks later, we
submit a psci-v0.2 dts in advanced.

Thanks,
Orson

>>
>> Thanks,
>> Mark.
>> --
>
> Hi, Mark
>
> Ok, I'll check it again with our related engineers.
>
> Actually, I had read all of your comments carefully before sending
> each version of patches, and I replied you a few days early, I guess
> you may miss it :)
>
> If we just implemented psci-0.1 until now, can we submit this path
> without "compatible = "arm,psci-0.2"", but only with " compatible =
> "arm,psci" ".
>
>
>
> Thanks,
> Chunyan

2014-12-05 10:41:09

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

Hi,

On Thu, Dec 04, 2014 at 11:34:15AM +0000, Chunyan Zhang wrote:
> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>
> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
> standards based on ARMv8 multiple core architecture.Now we have only one
> SoC(SC9836) based on this Platform in developing.
>
> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
> of SC9836-UART.
>
> This patchset also has patches which address "sprd" prefix and DT compatible
> strings for nodes which appear un-documented.
>
> This version code was tesed both on Fast Mode and sc9836-fpga board.
> We use the latest boot-wrapper-aarch64 as the bootloader.
>
> Changes from v3:
> * Addressed review comments:
> - Added the description of clock property for sc9836-uart
> - Revised the size of GICC to be 8KiB
> - Added another compatible string for psci-0.1

I had open questions on v3 regarding your PSCI imlpementation. You
mentioned that you are using the aarch64 bootwrapper, but your DT
describes PSCI 0.2, and the (upstream) bootwrapper does not implement
PSCI 0.2. Adding the old PSCI compatible string is _not_ sufficient if
you do not have a full PSCI 0.2 implementation.

Given that PSCI 0.2 requires more functionality to be implemented, I'd
like to know that your implementation is spec-compliant (implementing
the mandatory functions, nters the kernel in the correct state, etc),
and that it has been tested.

Would you be able to look at my comments from the last posting please?

Thanks,
Mark.

2014-12-15 13:39:16

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

On Fri, Dec 05, 2014 at 12:27:23PM +0000, Lyra Zhang wrote:
> On Fri, Dec 5, 2014 at 6:40 PM, Mark Rutland <[email protected]> wrote:
> > Hi,
> >
> > On Thu, Dec 04, 2014 at 11:34:15AM +0000, Chunyan Zhang wrote:
> >> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
> >>
> >> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
> >> standards based on ARMv8 multiple core architecture.Now we have only one
> >> SoC(SC9836) based on this Platform in developing.
> >>
> >> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
> >> of SC9836-UART.
> >>
> >> This patchset also has patches which address "sprd" prefix and DT compatible
> >> strings for nodes which appear un-documented.
> >>
> >> This version code was tesed both on Fast Mode and sc9836-fpga board.
> >> We use the latest boot-wrapper-aarch64 as the bootloader.
> >>
> >> Changes from v3:
> >> * Addressed review comments:
> >> - Added the description of clock property for sc9836-uart
> >> - Revised the size of GICC to be 8KiB
> >> - Added another compatible string for psci-0.1
> >
> > I had open questions on v3 regarding your PSCI imlpementation. You
> > mentioned that you are using the aarch64 bootwrapper, but your DT
> > describes PSCI 0.2, and the (upstream) bootwrapper does not implement
> > PSCI 0.2. Adding the old PSCI compatible string is _not_ sufficient if
> > you do not have a full PSCI 0.2 implementation.
> >
> > Given that PSCI 0.2 requires more functionality to be implemented, I'd
> > like to know that your implementation is spec-compliant (implementing
> > the mandatory functions, nters the kernel in the correct state, etc),
> > and that it has been tested.
> >
> > Would you be able to look at my comments from the last posting please?
> >
> > Thanks,
> > Mark.
> > --
>
> Hi, Mark
>
> Ok, I'll check it again with our related engineers.
>
> Actually, I had read all of your comments carefully before sending
> each version of patches, and I replied you a few days early, I guess
> you may miss it :)
>
> If we just implemented psci-0.1 until now, can we submit this path
> without "compatible = "arm,psci-0.2"", but only with " compatible =
> "arm,psci" ".

Elsewhere I've recommended such things are placed in the DTB by the
bootloader (at least for those cases where the bootlaoder is tied to the
firmware), as it can fill in the appropriate enable-method (and add any
other nodes as required).

Having compatible = "arm,psci", and a couple of other properties for now
is certainly preferable to describing a not-yet-implemented PSCI 0.2.

Thanks,
Mark.

2014-12-17 06:16:53

by Chunyan Zhang

[permalink] [raw]
Subject: Re: [PATCH v4 0/5] Add Spreadtrum Sharkl64 Platform support

Hi, Mark

On Mon, Dec 15, 2014 at 9:38 PM, Mark Rutland <[email protected]> wrote:
> On Fri, Dec 05, 2014 at 12:27:23PM +0000, Lyra Zhang wrote:
>> On Fri, Dec 5, 2014 at 6:40 PM, Mark Rutland <[email protected]> wrote:
>> > Hi,
>> >
>> > On Thu, Dec 04, 2014 at 11:34:15AM +0000, Chunyan Zhang wrote:
>> >> Spreadtrum is a rapid growing chip vendor providing smart phone total solutions.
>> >>
>> >> Sharkl64 Platform is nominated as a SoC infrastructure that supports 4G/3G/2G
>> >> standards based on ARMv8 multiple core architecture.Now we have only one
>> >> SoC(SC9836) based on this Platform in developing.
>> >>
>> >> This patchset adds Sharkl64 support in arm64 device tree and the serial driver
>> >> of SC9836-UART.
>> >>
>> >> This patchset also has patches which address "sprd" prefix and DT compatible
>> >> strings for nodes which appear un-documented.
>> >>
>> >> This version code was tesed both on Fast Mode and sc9836-fpga board.
>> >> We use the latest boot-wrapper-aarch64 as the bootloader.
>> >>
>> >> Changes from v3:
>> >> * Addressed review comments:
>> >> - Added the description of clock property for sc9836-uart
>> >> - Revised the size of GICC to be 8KiB
>> >> - Added another compatible string for psci-0.1
>> >
>> > I had open questions on v3 regarding your PSCI imlpementation. You
>> > mentioned that you are using the aarch64 bootwrapper, but your DT
>> > describes PSCI 0.2, and the (upstream) bootwrapper does not implement
>> > PSCI 0.2. Adding the old PSCI compatible string is _not_ sufficient if
>> > you do not have a full PSCI 0.2 implementation.
>> >
>> > Given that PSCI 0.2 requires more functionality to be implemented, I'd
>> > like to know that your implementation is spec-compliant (implementing
>> > the mandatory functions, nters the kernel in the correct state, etc),
>> > and that it has been tested.
>> >
>> > Would you be able to look at my comments from the last posting please?
>> >
>> > Thanks,
>> > Mark.
>> > --
>>
>> Hi, Mark
>>
>> Ok, I'll check it again with our related engineers.
>>
>> Actually, I had read all of your comments carefully before sending
>> each version of patches, and I replied you a few days early, I guess
>> you may miss it :)
>>
>> If we just implemented psci-0.1 until now, can we submit this path
>> without "compatible = "arm,psci-0.2"", but only with " compatible =
>> "arm,psci" ".
>
> Elsewhere I've recommended such things are placed in the DTB by the
> bootloader (at least for those cases where the bootlaoder is tied to the
> firmware), as it can fill in the appropriate enable-method (and add any
> other nodes as required).
>
> Having compatible = "arm,psci", and a couple of other properties for now
> is certainly preferable to describing a not-yet-implemented PSCI 0.2.
>
> Thanks,
> Mark.
> --

Thank you for the replay.
I'll still ping my colleagues to implement PSCI 0.2, and test it.
But it perhaps would not be finished soon, because our internal
developing code right now is based on a little old version Linux
kernel which doesn't support PSCI-0.2

Thanks again,
Chunyan