#define CDNS_UART_TTY_NAME     "ttyPS"
 #define CDNS_UART_NAME         "xuartps"
 #define CDNS_UART_MAJOR                0       /* use dynamic node allocation */
-#define CDNS_UART_NR_PORTS     2
 #define CDNS_UART_FIFO_SIZE    64      /* FIFO size */
 #define CDNS_UART_REGISTER_SPACE       0x1000
 
 };
 MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
 
+/*
+ * Maximum number of instances without alias IDs but if there is alias
+ * which target "< MAX_UART_INSTANCES" range this ID can't be used.
+ */
+#define MAX_UART_INSTANCES     32
+
+/* Stores static aliases list */
+static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
+static int alias_bitmap_initialized;
+
+/* Stores actual bitmap of allocated IDs with alias IDs together */
+static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
+/* Protect bitmap operations to have unique IDs */
+static DEFINE_MUTEX(bitmap_lock);
+
+static int cdns_get_id(struct platform_device *pdev)
+{
+       int id, ret;
+
+       mutex_lock(&bitmap_lock);
+
+       /* Alias list is stable that's why get alias bitmap only once */
+       if (!alias_bitmap_initialized) {
+               ret = of_alias_get_alias_list(cdns_uart_of_match, "serial",
+                                             alias_bitmap, MAX_UART_INSTANCES);
+               if (ret)
+                       return ret;
+
+               alias_bitmap_initialized++;
+       }
+
+       /* Make sure that alias ID is not taken by instance without alias */
+       bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
+
+       dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
+               MAX_UART_INSTANCES, bitmap);
+
+       /* Look for a serialN alias */
+       id = of_alias_get_id(pdev->dev.of_node, "serial");
+       if (id < 0) {
+               dev_warn(&pdev->dev,
+                        "No serial alias passed. Using the first free id\n");
+
+               /*
+                * Start with id 0 and check if there is no serial0 alias
+                * which points to device which is compatible with this driver.
+                * If alias exists then try next free position.
+                */
+               id = 0;
+
+               for (;;) {
+                       dev_info(&pdev->dev, "Checking id %d\n", id);
+                       id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
+
+                       /* No free empty instance */
+                       if (id == MAX_UART_INSTANCES) {
+                               dev_err(&pdev->dev, "No free ID\n");
+                               mutex_unlock(&bitmap_lock);
+                               return -EINVAL;
+                       }
+
+                       dev_dbg(&pdev->dev, "The empty id is %d\n", id);
+                       /* Check if ID is empty */
+                       if (!test_and_set_bit(id, bitmap)) {
+                               /* Break the loop if bit is taken */
+                               dev_dbg(&pdev->dev,
+                                       "Selected ID %d allocation passed\n",
+                                       id);
+                               break;
+                       }
+                       dev_dbg(&pdev->dev,
+                               "Selected ID %d allocation failed\n", id);
+                       /* if taking bit fails then try next one */
+                       id++;
+               }
+       }
+
+       mutex_unlock(&bitmap_lock);
+
+       return id;
+}
+
 /**
  * cdns_uart_probe - Platform driver probe
  * @pdev: Pointer to the platform device structure
        if (!cdns_uart_uart_driver)
                return -ENOMEM;
 
-       /* Look for a serialN alias */
-       cdns_uart_data->id = of_alias_get_id(pdev->dev.of_node, "serial");
+       cdns_uart_data->id = cdns_get_id(pdev);
        if (cdns_uart_data->id < 0)
-               cdns_uart_data->id = 0;
-
-       if (cdns_uart_data->id >= CDNS_UART_NR_PORTS) {
-               dev_err(&pdev->dev, "Cannot get uart_port structure\n");
-               return -ENODEV;
-       }
+               return cdns_uart_data->id;
 
        /* There is a need to use unique driver name */
        driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
                                     CDNS_UART_NAME, cdns_uart_data->id);
-       if (!driver_name)
-               return -ENOMEM;
+       if (!driver_name) {
+               rc = -ENOMEM;
+               goto err_out_id;
+       }
 
        cdns_uart_uart_driver->owner = THIS_MODULE;
        cdns_uart_uart_driver->driver_name = driver_name;
        rc = uart_register_driver(cdns_uart_uart_driver);
        if (rc < 0) {
                dev_err(&pdev->dev, "Failed to register driver\n");
-               return rc;
+               goto err_out_id;
        }
 
        cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
        clk_disable_unprepare(cdns_uart_data->pclk);
 err_out_unregister_driver:
        uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-
+err_out_id:
+       mutex_lock(&bitmap_lock);
+       clear_bit(cdns_uart_data->id, bitmap);
+       mutex_unlock(&bitmap_lock);
        return rc;
 }
 
 #endif
        rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
        port->mapbase = 0;
+       mutex_lock(&bitmap_lock);
+       clear_bit(cdns_uart_data->id, bitmap);
+       mutex_unlock(&bitmap_lock);
        clk_disable_unprepare(cdns_uart_data->uartclk);
        clk_disable_unprepare(cdns_uart_data->pclk);
        pm_runtime_disable(&pdev->dev);