diff --git a/CHANGES b/CHANGES
index deb574abf2c89f26402d710702708a72968d41c2..e2ddc1da34b486ab85381dbb63d597cce5886c5e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -23,6 +23,7 @@ Upcoming release: BREAKING
       user level.
 * Support added for Aarch64 hypervisor mode (EL2) for Nvidia TX1 and TX2. This is not verified.
 * Support for generating ARM machine header files (memory regions and interrupts) based on a device tree.
+* Support added for ARM kernel serial driver to be linked in at build time based on the device tree compatibility string.
 
 ## Upgrade Notes
 ---
diff --git a/src/plat/hikey/machine/io.c b/src/drivers/serial/arm,pl011.c
similarity index 84%
rename from src/plat/hikey/machine/io.c
rename to src/drivers/serial/arm,pl011.c
index 6dae9a84e0c01d0ab68a11029b38ce15f9be12ee..17ab80219ca2593d139d097d702ae463b24b048e 100644
--- a/src/plat/hikey/machine/io.c
+++ b/src/drivers/serial/arm,pl011.c
@@ -17,6 +17,7 @@
 #define UARTDR                    0x000
 #define UARTFR                    0x018
 #define PL011_UARTFR_TXFF         (1 << 5)
+#define PL011_UARTFR_RXFE         (1 << 4)
 
 #define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
 
@@ -34,6 +35,8 @@ putDebugChar(unsigned char c)
 unsigned char
 getDebugChar(void)
 {
-    return 0;
+    while ((*UART_REG(UARTFR) & PL011_UARTFR_RXFE) != 0);
+
+    return *UART_REG(UARTDR);
 }
-#endif
+#endif //CONFIG_DEBUG_BUILD
\ No newline at end of file
diff --git a/src/plat/bcm2837/machine/io.c b/src/drivers/serial/brcm,bcm2835-aux-uart.c
similarity index 98%
rename from src/plat/bcm2837/machine/io.c
rename to src/drivers/serial/brcm,bcm2835-aux-uart.c
index 7ea6fb6ed9bf62e3a5b9b2d598b1709565c0779b..bbf9470b0f3020231a7fe6baf88ad6273bb8c011 100644
--- a/src/plat/bcm2837/machine/io.c
+++ b/src/drivers/serial/brcm,bcm2835-aux-uart.c
@@ -59,4 +59,4 @@ unsigned char getDebugChar(void)
     while ( !(*UART_REG(MU_LSR) & MU_LSR_DATAREADY) );
     return *UART_REG(MU_IO);
 }
-#endif /* CONFIG_DEBUG_BUILD */
+#endif //CONFIG_DEBUG_BUILD
\ No newline at end of file
diff --git a/src/drivers/serial/config.cmake b/src/drivers/serial/config.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d2f41e6795ae2fccd1725bdbb13b025c643bf2aa
--- /dev/null
+++ b/src/drivers/serial/config.cmake
@@ -0,0 +1,19 @@
+
+cmake_minimum_required(VERSION 3.7.2)
+
+macro(RegisterDriver compatibility_strings match_strings)
+    foreach(match_string IN ITEMS ${match_strings})
+        list(FIND ${compatibility_strings} ${match_string} res)
+        if(NOT (res EQUAL -1))
+            add_sources(${ARGN})
+            break()
+        endif()
+    endforeach()
+endmacro()
+
+RegisterDriver(compatibility_strings "nvidia,tegra20-uart;ti,omap3-uart;snps,dw-apb-uart" PREFIX src/drivers/serial CFILES "tegra_omap3_dwapb.c")
+
+set(serial_list brcm,bcm2835-aux-uart fsl,imx31-uart arm,pl011 samsung,exynos4210-uart fsl,imx6q-uart qcom,msm-uartdm xlnx,xuartps)    
+foreach(c IN ITEMS ${serial_list})
+    RegisterDriver(compatibility_strings "${c}" PREFIX src/drivers/serial CFILES "${c}.c")
+endforeach()
\ No newline at end of file
diff --git a/src/plat/imx31/machine/io.c b/src/drivers/serial/fsl,imx31-uart.c
similarity index 100%
rename from src/plat/imx31/machine/io.c
rename to src/drivers/serial/fsl,imx31-uart.c
diff --git a/src/plat/imx6/machine/io.c b/src/drivers/serial/fsl,imx6q-uart.c
similarity index 100%
rename from src/plat/imx6/machine/io.c
rename to src/drivers/serial/fsl,imx6q-uart.c
diff --git a/src/plat/apq8064/machine/io.c b/src/drivers/serial/qcom,msm-uartdm.c
similarity index 100%
rename from src/plat/apq8064/machine/io.c
rename to src/drivers/serial/qcom,msm-uartdm.c
diff --git a/src/plat/exynos_common/io.c b/src/drivers/serial/samsung,exynos4210-uart.c
similarity index 100%
rename from src/plat/exynos_common/io.c
rename to src/drivers/serial/samsung,exynos4210-uart.c
diff --git a/src/plat/tk1/machine/io.c b/src/drivers/serial/tegra_omap3_dwapb.c
similarity index 100%
rename from src/plat/tk1/machine/io.c
rename to src/drivers/serial/tegra_omap3_dwapb.c
diff --git a/src/plat/zynq7000/machine/io.c b/src/drivers/serial/xlnx,xuartps.c
similarity index 100%
rename from src/plat/zynq7000/machine/io.c
rename to src/drivers/serial/xlnx,xuartps.c
diff --git a/src/plat/allwinnerA20/config.cmake b/src/plat/allwinnerA20/config.cmake
index 082d7a5915443cc343a37a6494a5cf4ba42f4433..6dd67698d2412dc62dc948eacf42bf7e952ae0bc 100644
--- a/src/plat/allwinnerA20/config.cmake
+++ b/src/plat/allwinnerA20/config.cmake
@@ -25,8 +25,7 @@ endif()
 
 add_sources(
     DEP "KernelPlatAllwinnerA20"
-    CFILES src/plat/allwinnerA20/machine/io.c
-           src/plat/allwinnerA20/machine/hardware.c
+    CFILES src/plat/allwinnerA20/machine/hardware.c
            src/plat/allwinnerA20/machine/l2cache.c
            src/arch/arm/machine/gic_pl390.c
 )
diff --git a/src/plat/allwinnerA20/machine/io.c b/src/plat/allwinnerA20/machine/io.c
deleted file mode 100755
index c4f24224f8fbe4cd9b23c9e7fdb58845463e7085..0000000000000000000000000000000000000000
--- a/src/plat/allwinnerA20/machine/io.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2015, DornerWorks, Ltd.
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(GD_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define UTHR 0x00 /* UART Transmit Holding Register */
-#define ULSR 0x14 /* UART Line Status Register */
-#define ULSR_THRE 0x20 /* Transmit Holding Register Empty */
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
-
-    *UART_REG(UTHR) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    return 0;
-}
-#endif
diff --git a/src/plat/am335x/config.cmake b/src/plat/am335x/config.cmake
index aa564bc93e56c65311a286ae61b5e89550980032..b55ecee06a74175afdf1661cb6d1b0772323cfa5 100644
--- a/src/plat/am335x/config.cmake
+++ b/src/plat/am335x/config.cmake
@@ -24,6 +24,5 @@ add_sources(
     DEP "KernelPlatformAM335X"
     CFILES
         src/plat/am335x/machine/hardware.c
-        src/plat/am335x/machine/io.c
         src/plat/am335x/machine/l2cache.c
 )
diff --git a/src/plat/am335x/machine/io.c b/src/plat/am335x/machine/io.c
deleted file mode 100644
index 1b93e0b9234042e72a80e05421d67fc6e60c25b8..0000000000000000000000000000000000000000
--- a/src/plat/am335x/machine/io.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2014, General Dynamics C4 Systems
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(GD_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define UTHR 0x00 /* UART Transmit Holding Register */
-#define ULSR 0x14 /* UART Line Status Register */
-#define ULSR_THRE BIT(5) /* Transmit Holding Register Empty */
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_PRINTING) || defined(CONFIG_DEBUG_BUILD)
-void
-putDebugChar(unsigned char c)
-{
-    while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
-    *UART_REG(UTHR) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    return 0;
-}
-#endif
diff --git a/src/plat/apq8064/config.cmake b/src/plat/apq8064/config.cmake
index b811a90a6099236a04066c65332cf8f4ba7b6974..74e31b25bda46fb1581355b9ed8eb01722a9d248 100644
--- a/src/plat/apq8064/config.cmake
+++ b/src/plat/apq8064/config.cmake
@@ -24,7 +24,6 @@ endif()
 add_sources(
     DEP "KernelPlatformAPQ8064"
     CFILES
-        src/plat/apq8064/machine/io.c
         src/plat/apq8064/machine/timer.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/bcm2837/config.cmake b/src/plat/bcm2837/config.cmake
index 8a1ebdb89ea974505f6d638071a6c521dadbdfa4..c64844112e130e7c5945f30832e569613881a6b6 100644
--- a/src/plat/bcm2837/config.cmake
+++ b/src/plat/bcm2837/config.cmake
@@ -27,7 +27,6 @@ endif()
 add_sources(
     DEP "KernelPlatformRpi3"
     CFILES
-        src/plat/bcm2837/machine/io.c
         src/plat/bcm2837/machine/intc.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/exynos4/config.cmake b/src/plat/exynos4/config.cmake
index ac08178815c5c86dc889946148178a4f8242460c..63fcfbc8a7647e4ddbefaf8116cd0bdbfa407f89 100644
--- a/src/plat/exynos4/config.cmake
+++ b/src/plat/exynos4/config.cmake
@@ -23,7 +23,6 @@ endif()
 add_sources(
     DEP "KernelPlatformExynos4"
     CFILES
-        src/plat/exynos_common/io.c
         src/plat/exynos4/machine/hardware.c
         src/arch/arm/machine/l2c_310.c
         src/arch/arm/machine/gic_pl390.c
diff --git a/src/plat/exynos5/config.cmake b/src/plat/exynos5/config.cmake
index 720b644c3a7611813b11989e2ec303e5f5e3d737..685123a8108183d27a0883f3406668f029385e97 100644
--- a/src/plat/exynos5/config.cmake
+++ b/src/plat/exynos5/config.cmake
@@ -36,7 +36,6 @@ add_sources(
     CFILES
         src/arch/arm/machine/generic_timer.c
         src/plat/exynos5/machine/hardware.c
-        src/plat/exynos_common/io.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
 )
diff --git a/src/plat/hikey/config.cmake b/src/plat/hikey/config.cmake
index bbcf79fe0e609954ba86c8f6b97324d38f73a036..66ef6e0b2c2c0f1055f548d46ef2e6e3c649aced 100644
--- a/src/plat/hikey/config.cmake
+++ b/src/plat/hikey/config.cmake
@@ -73,7 +73,6 @@ endif()
 add_sources(
     DEP "KernelPlatformHikey"
     CFILES
-        src/plat/hikey/machine/io.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/imx31/config.cmake b/src/plat/imx31/config.cmake
index bfcd84674018be0ca7f721ed4da9d9dfe35cd3cf..79870aa9ee867b2e158153cd757036d8c75f769d 100644
--- a/src/plat/imx31/config.cmake
+++ b/src/plat/imx31/config.cmake
@@ -24,7 +24,6 @@ endif()
 add_sources(
     DEP "KernelPlatformKZM"
     CFILES
-        src/plat/imx31/machine/io.c
         src/plat/imx31/machine/hardware.c
 )
 
diff --git a/src/plat/imx6/config.cmake b/src/plat/imx6/config.cmake
index 7c20f02dabcd1ca0ef5339ab3450d4f9eb0b74cc..dc87ced34ce37852d44cae0fc12f0462a64d07a8 100644
--- a/src/plat/imx6/config.cmake
+++ b/src/plat/imx6/config.cmake
@@ -33,7 +33,6 @@ endif()
 add_sources(
     DEP "KernelPlatImx6"
     CFILES
-        src/plat/imx6/machine/io.c
         src/arch/arm/machine/l2c_310.c
         src/arch/arm/machine/priv_timer.c
         src/arch/arm/machine/gic_pl390.c
diff --git a/src/plat/imx7/config.cmake b/src/plat/imx7/config.cmake
index 73ddd16c213e1e4a967f2f620659461e04d7796b..c486b60631a8a33f07b163e7f3eb5d448a751793 100644
--- a/src/plat/imx7/config.cmake
+++ b/src/plat/imx7/config.cmake
@@ -26,7 +26,7 @@ endif()
 
 add_sources(
     DEP "KernelPlatImx7"
-    CFILES src/plat/imx7/machine/io.c
+    CFILES 
            src/arch/arm/machine/generic_timer.c
            src/arch/arm/machine/gic_pl390.c
            src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/imx7/machine/io.c b/src/plat/imx7/machine/io.c
deleted file mode 100644
index 967aabb5761c1f604f9b098a932751d545c3bf33..0000000000000000000000000000000000000000
--- a/src/plat/imx7/machine/io.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2014, General Dynamics C4 Systems
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(GD_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define URXD  0x00 /* UART Receiver Register */
-#define UTXD  0x40 /* UART Transmitter Register */
-#define UCR1  0x80 /* UART Control Register 1 */
-#define UCR2  0x84 /* UART Control Register 2 */
-#define UCR3  0x88 /* UART Control Register 3 */
-#define UCR4  0x8c /* UART Control Register 4 */
-#define UFCR  0x90 /* UART FIFO Control Register */
-#define USR1  0x94 /* UART Status Register 1 */
-#define USR2  0x98 /* UART Status Register 2 */
-#define UESC  0x9c /* UART Escape Character Register */
-#define UTIM  0xa0 /* UART Escape Timer Register */
-#define UBIR  0xa4 /* UART BRM Incremental Register */
-#define UBMR  0xa8 /* UART BRM Modulator Register */
-#define UBRC  0xac /* UART Baud Rate Counter Register */
-#define ONEMS 0xb0 /* UART One Millisecond Register */
-#define UTS   0xb4 /* UART Test Register */
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-
-#define UART_SR2_TXFIFO_EMPTY 14
-#define UART_SR2_RXFIFO_RDR    0
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while (!(*UART_REG(USR2) & BIT(UART_SR2_TXFIFO_EMPTY)));
-    *UART_REG(UTXD) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    while (!(*UART_REG(USR2) & BIT(UART_SR2_RXFIFO_RDR)));
-    return *UART_REG(URXD);
-}
-#endif /* CONFIG_DEBUG_BUILD */
diff --git a/src/plat/omap3/config.cmake b/src/plat/omap3/config.cmake
index d0439f2231de44cffea8febcc05191d44118a28b..ba19afad3908b92578b239d3cced7d02b373672f 100644
--- a/src/plat/omap3/config.cmake
+++ b/src/plat/omap3/config.cmake
@@ -25,6 +25,5 @@ add_sources(
     DEP "KernelPlatformOMAP3"
     CFILES
         src/plat/omap3/machine/hardware.c
-        src/plat/omap3/machine/io.c
         src/plat/omap3/machine/l2cache.c
 )
diff --git a/src/plat/omap3/machine/io.c b/src/plat/omap3/machine/io.c
deleted file mode 100644
index 11760221bc55f10e6e8e83e2f14f2047f8b6df72..0000000000000000000000000000000000000000
--- a/src/plat/omap3/machine/io.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2014, General Dynamics C4 Systems
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(GD_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define UTHR 0x00 /* UART Transmit Holding Register */
-#define ULSR 0x14 /* UART Line Status Register */
-#define ULSR_THRE 0x20 /* Transmit Holding Register Empty */
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
-
-    *UART_REG(UTHR) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    return 0;
-}
-#endif
diff --git a/src/plat/tk1/config.cmake b/src/plat/tk1/config.cmake
index 0b4616aef68e80acc2f31ae2f741bcc2a9ee208d..b24d67abbf17858ec68df3ac5185765df58bfb20 100644
--- a/src/plat/tk1/config.cmake
+++ b/src/plat/tk1/config.cmake
@@ -25,7 +25,6 @@ endif()
 add_sources(
     DEP "KernelPlatformTK1"
     CFILES
-        src/plat/tk1/machine/io.c
         src/plat/tk1/machine/smmu.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/gic_pl390.c
diff --git a/src/plat/tx1/config.cmake b/src/plat/tx1/config.cmake
index 578cdf2d611e17a72a75687e1196bc327102bae2..574525647a58a6fada6decd1c979d58b8719f57e 100644
--- a/src/plat/tx1/config.cmake
+++ b/src/plat/tx1/config.cmake
@@ -26,7 +26,6 @@ endif()
 add_sources(
     DEP "KernelPlatformTx1"
     CFILES
-        src/plat/tx1/machine/io.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/tx1/machine/io.c b/src/plat/tx1/machine/io.c
deleted file mode 100644
index 9190bf1612a49a450243eac900d83444b6c00ad0..0000000000000000000000000000000000000000
--- a/src/plat/tx1/machine/io.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define UTHR        0x0
-#define ULSR        0x14
-#define ULSR_THRE   (1 << 5)
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
-
-    *UART_REG(UTHR) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    return 0;
-}
-#endif
-
diff --git a/src/plat/tx2/config.cmake b/src/plat/tx2/config.cmake
index db68fabb2dfd94868167ea464d3f38f80be83d76..8b6307dee1fb58ac69e3b3b0269ee9a42aab4971 100644
--- a/src/plat/tx2/config.cmake
+++ b/src/plat/tx2/config.cmake
@@ -29,7 +29,6 @@ endif()
 add_sources(
     DEP "KernelPlatformTx2"
     CFILES
-        src/plat/tx2/machine/io.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/tx2/machine/io.c b/src/plat/tx2/machine/io.c
deleted file mode 100644
index 6d03e77e1e63c8fa7ac9defc47bd292fcec7094e..0000000000000000000000000000000000000000
--- a/src/plat/tx2/machine/io.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define UTHR        0x0
-#define ULSR        0x14
-#define ULSR_THRE   BIT(5)
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while ((*UART_REG(ULSR) & ULSR_THRE) == 0);
-
-    *UART_REG(UTHR) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    return 0;
-}
-#endif
-
diff --git a/src/plat/zynq7000/config.cmake b/src/plat/zynq7000/config.cmake
index b77f92a2d818971d1483cc15d7e0d17a9f358dd2..d3e34f53a3d6ca74038e4de4a775e6bb343def4a 100644
--- a/src/plat/zynq7000/config.cmake
+++ b/src/plat/zynq7000/config.cmake
@@ -23,7 +23,6 @@ endif()
 add_sources(
     DEP "KernelPlatformZynq7000"
     CFILES
-        src/plat/zynq7000/machine/io.c
         src/arch/arm/machine/l2c_310.c
         src/arch/arm/machine/priv_timer.c
         src/arch/arm/machine/gic_pl390.c
diff --git a/src/plat/zynqmp/config.cmake b/src/plat/zynqmp/config.cmake
index d86b77071814572f7c6366202276f706f3886054..f6c916b53234aed81edc010d7f4e7f02271a05ce 100644
--- a/src/plat/zynqmp/config.cmake
+++ b/src/plat/zynqmp/config.cmake
@@ -37,7 +37,6 @@ add_sources(
     DEP "KernelPlatformZynqmp"
     CFILES
         src/plat/zynqmp/machine/hardware.c
-        src/plat/zynqmp/machine/io.c
         src/arch/arm/machine/generic_timer.c
         src/arch/arm/machine/gic_pl390.c
         src/arch/arm/machine/l2c_nop.c
diff --git a/src/plat/zynqmp/machine/io.c b/src/plat/zynqmp/machine/io.c
deleted file mode 100644
index ee8c396983753f65d662d196573e8b949985e2e8..0000000000000000000000000000000000000000
--- a/src/plat/zynqmp/machine/io.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2017, DornerWorks
- * Copyright 2014, General Dynamics C4 Systems
- *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(GD_DORNERWORKS_GPL)
- */
-/*
- * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
- * a DARPA SBIR, Contract Number D16PC00107.
- *
- * Approved for Public Release, Distribution Unlimited.
- */
-
-#include <config.h>
-#include <stdint.h>
-#include <util.h>
-#include <machine/io.h>
-#include <plat/machine/devices_gen.h>
-
-#define XUARTPS_SR             0x2C
-#define XUARTPS_FIFO           0x30
-
-#define XUARTPS_SR_TXEMPTY     BIT(3)
-
-#define UART_REG(x) ((volatile uint32_t *)(UART_PPTR + (x)))
-
-#if defined(CONFIG_DEBUG_BUILD) || defined(CONFIG_PRINTING)
-void
-putDebugChar(unsigned char c)
-{
-    while (!(*UART_REG(XUARTPS_SR) & XUARTPS_SR_TXEMPTY));
-    *UART_REG(XUARTPS_FIFO) = c;
-}
-#endif
-
-#ifdef CONFIG_DEBUG_BUILD
-unsigned char
-getDebugChar(void)
-{
-    while (!(*UART_REG(XUARTPS_SR) & BIT(XUARTPS_SR_TXEMPTY)));
-    return *UART_REG(XUARTPS_FIFO);
-}
-#endif /* CONFIG_DEBUG_BUILD */
diff --git a/tools/hardware.yml b/tools/hardware.yml
index 5788a10236f17fee6beccfd7bc1a1b2cae2f65a6..2a5786d6f720a567d78dae68dedd481457f60fa6 100644
--- a/tools/hardware.yml
+++ b/tools/hardware.yml
@@ -224,7 +224,6 @@ devices:
     - qcom,msm-uartdm
     - samsung,exynos4210-uart
     - snps,dw-apb-uart
-    - ti,am3352-uart
     - ti,omap3-uart
     - xlnx,xuartps
     chosen: stdout-path
diff --git a/tools/hardware_gen.py b/tools/hardware_gen.py
index 328df00db46bc2ea87e9e3a9bd236347406966d5..943be7aa6dc9255bbbc8dd4ebb1ea300e518cb46 100755
--- a/tools/hardware_gen.py
+++ b/tools/hardware_gen.py
@@ -445,6 +445,8 @@ class Config:
         self.blob = blob
         self.chosen = None
         self.aliases = None
+        self.matched_devices = set()
+
         # wrangle the json a little so it's easier
         # to figure out which rules apply to a given device
         for dev in blob['devices']:
@@ -526,6 +528,7 @@ class Config:
                         if reg.user_macro or ('user' in reg_rule and reg_rule['user'] == True):
                             user.add(reg)
                         regs.append(reg)
+                        self.matched_devices.add(compatible)
 
                 kernel.update(set(regs))
 
@@ -586,6 +589,9 @@ class Config:
                 break
         return ret
 
+    def get_matched_devices(self):
+        return sorted(self.matched_devices)
+
 def is_compatible(node, compatibles):
     """ returns True if node matches a compatible in the given list """
     try:
@@ -819,6 +825,11 @@ static const p_region_t BOOT_RODATA dev_p_regs[] = {
 #endif /* __PLAT_DEVICES_GEN_H */
 """
 
+def add_build_rules(devices):
+    devices[-1] = devices[-1] + ";"
+    #print result to cmake variable
+    print(';'.join(devices))
+
 def output_regions(args, devices, memory, kernel, irqs, fp):
     """ generate the device list for the C header file """
     memory = sorted(memory, key=lambda a: a.start)
@@ -920,6 +931,9 @@ def main(args):
     user = fixup_device_regions(user, 1 << args.page_bits, merge=True)
     kernel = fixup_device_regions(kernel, 1 << args.page_bits)
     output_regions(args, user, memory, kernel, kernel_irqs, args.output)
+  
+    #generate cmake
+    add_build_rules(cfg.get_matched_devices())
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser()
@@ -929,6 +943,5 @@ if __name__ == '__main__':
     parser.add_argument('--phys-align', help='alignment in bits of the base address of the kernel', default=24, type=int)
     parser.add_argument('--config', help='kernel device configuration', required=True, type=argparse.FileType())
     parser.add_argument('--schema', help='config file schema for validation', required=True, type=argparse.FileType())
-
     args = parser.parse_args()
-    main(args)
+    main(args)
\ No newline at end of file