msm_serial_hs : Add support to select device id with BLSP Based UART
UART device is enumerated as /dev/ttyHS<id>. Currently cell-index
is used as id to enumerated the device. It is not required to
provide any device specific configuration with device tree usage.
Hence use below approaches to select device ID with BLSP based UART:
1. Use auto increment approach for selecting id by default. HSUART
driver would increment id based on HSUART device binding with driver.
2. Add support to provide user defined id for particular HSUART device.
Alias property can be used as user defined id for used HSUART device.
Hence add support for the same. Also check if alias based ID is already
under-used, then fail the probe of driver for the same.
Here it is responsibility of user to use either of above approach.
If hybrid approach is being used,then user shouldn't use those
aliases ID which are already used by previously enumerated HSUART
devices.
Add required documentaion for alias usage for BLSP based UART.
CRs-Fixed: 410636
Change-Id: Ibd5f25c73cd5a08f6bf851a9846fecc780404b2b
Signed-off-by: Saket Saurabh <ssaurabh@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
index 91c2461..e00584f 100644
--- a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
@@ -3,10 +3,6 @@
Required properties:
- compatible :
- "qcom,msm-hsuart-v14" to be used for UARTDM Core v1.4
-- cell-index : cell-index to be used as device id to enumerate
- TTY based HSUART device as /dev/ttyHS<cell-index>.
- Device probe fails if cell-index is not available.
- The cell-index value should be from 0 to 255.
- reg : offset and length of the register set for both the device,
uart core and bam core
- reg-names :
@@ -34,14 +30,15 @@
Example:
- uart7@f995d000 {
+ uart7: uart@f995d000 {
compatible = "qcom,msm-hsuart-v14";
- cell-index = <0>;
reg = <0xf995d000 0x1000>,
<0xf9944000 0x5000>;
reg-names = "core_mem", "bam_mem";
interrupts = <0 113 0>, <0 239 0>;
interrupt-names = "core_irq", "bam_irq";
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
};
Optional properties:
@@ -59,11 +56,21 @@
- qcom, rx_to_inject : The character to be inserted on wakeup.
+Aliases :
+An alias may be optionally used to bind the UART device to a TTY device
+(ttyHS<alias_num>) with a given alias number. Aliases are of the form
+uart<n> where <n> is an integer representing the alias number to use.
+On systems with multiple UART devices present, an alias may optionally be
+defined for such devices. The alias value should be from 0 to 255.
+
Example:
+ aliases {
+ uart4 = &uart7; // This device will be enumerated as ttyHS4
+ };
+
uart7: uart@f995d000 {
compatible = "qcom,msm-hsuart-v14"
- cell-index = <0>;
reg = <0x19c40000 0x1000">,
<0xf9944000 0x5000>;
reg-names = "core_mem", "bam_mem";
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 6684fc4..efd9a32 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -40,6 +40,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/ioport.h>
+#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/clk.h>
@@ -2593,9 +2594,13 @@
return rc;
}
+#define BLSP_UART_NR 12
+static int deviceid[BLSP_UART_NR] = {0};
+static atomic_t msm_serial_hs_next_id = ATOMIC_INIT(0);
+
static int __devinit msm_hs_probe(struct platform_device *pdev)
{
- int ret = 0;
+ int ret = 0, alias_num = -1;
struct uart_port *uport;
struct msm_hs_port *msm_uport;
struct resource *core_resource;
@@ -2603,7 +2608,6 @@
struct resource *resource;
int core_irqres, bam_irqres;
struct msm_serial_hs_platform_data *pdata = pdev->dev.platform_data;
- struct device_node *node = pdev->dev.of_node;
if (pdev->dev.of_node) {
dev_dbg(&pdev->dev, "device tree enabled\n");
@@ -2611,8 +2615,32 @@
if (IS_ERR(pdata))
return PTR_ERR(pdata);
- of_property_read_u32(node, "cell-index",
- &pdev->id);
+ if (pdev->id == -1) {
+ pdev->id = atomic_inc_return(&msm_serial_hs_next_id)-1;
+ deviceid[pdev->id] = 1;
+ }
+
+ /* Use alias from device tree if present
+ * Alias is used as an optional property
+ */
+ alias_num = of_alias_get_id(pdev->dev.of_node, "uart");
+ if (alias_num >= 0) {
+ /* If alias_num is between 0 and 11, check that it not
+ * equal to previous incremented pdev-ids. If it is
+ * equal to previous pdev.ids , fail deviceprobe.
+ */
+ if (alias_num < BLSP_UART_NR) {
+ if (deviceid[alias_num] == 0) {
+ pdev->id = alias_num;
+ } else {
+ pr_err("alias_num=%d already used\n",
+ alias_num);
+ return -EINVAL;
+ }
+ } else {
+ pdev->id = alias_num;
+ }
+ }
pdev->dev.platform_data = pdata;
}