diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index be4570b..d1ea6da 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -73,4 +73,15 @@ config TI_SCI_PM_DOMAINS
 	  called ti_sci_pm_domains. Note this is needed early in boot before
 	  rootfs may be available.
 
+config TI_PRUSS
+	tristate "TI PRU-ICSS Subsystem Platform drivers"
+	depends on SOC_AM33XX
+	default n
+	help
+	  TI PRU-ICSS Subsystem platform specific support.
+
+	  Say Y or M here to support the Programmable Realtime Unit (PRU)
+	  processors on various TI SoCs. It's safe to say N here if you're
+	  not interested in the PRU or if you are unsure.
+
 endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index a22edc0..ac6b695 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA)	+= knav_dma.o
 obj-$(CONFIG_AMX3_PM)			+= pm33xx.o
 obj-$(CONFIG_WKUP_M3_IPC)		+= wkup_m3_ipc.o
 obj-$(CONFIG_TI_SCI_PM_DOMAINS)		+= ti_sci_pm_domains.o
+obj-$(CONFIG_TI_PRUSS)			+= pruss_soc_bus.o
diff --git a/drivers/soc/ti/pruss_soc_bus.c b/drivers/soc/ti/pruss_soc_bus.c
new file mode 100644
index 0000000..16b4802
--- /dev/null
+++ b/drivers/soc/ti/pruss_soc_bus.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PRU-ICSS SoC bus driver for various TI SoCs
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ *	Suman Anna <s-anna@ti.com>
+ *	Keerthy <j-keerthy@ti.com>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/platform_data/ti-pruss.h>
+
+/**
+ * struct pruss_soc_bus - PRUSS SoC bus structure
+ * @syscfg: kernel mapped address for SYSCFG register
+ * @has_reset: cached variable for storing global module reset flag
+ */
+struct pruss_soc_bus {
+	void __iomem *syscfg;
+	bool has_reset;
+};
+
+/**
+ * struct pruss_soc_bus_match_data - PRUSS SoC bus driver match data
+ * @has_reset: flag to indicate the presence of global module reset
+ */
+struct pruss_soc_bus_match_data {
+	bool has_reset;
+};
+
+static int pruss_soc_bus_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct pruss_platform_data *pdata = dev_get_platdata(dev);
+	struct pruss_soc_bus *psoc_bus;
+	const struct pruss_soc_bus_match_data *data;
+	int ret;
+
+	psoc_bus = devm_kzalloc(dev, sizeof(*psoc_bus), GFP_KERNEL);
+	if (!psoc_bus)
+		return -ENOMEM;
+
+	psoc_bus->syscfg = of_iomap(node, 0);
+	if (!psoc_bus->syscfg)
+		return -ENOMEM;
+
+	data = of_device_get_match_data(dev);
+	if (!data) {
+		dev_err(dev, "missing match data\n");
+		return -ENODEV;
+	}
+
+	if (data->has_reset && (!pdata || !pdata->deassert_reset ||
+				!pdata->assert_reset || !pdata->reset_name)) {
+		dev_err(dev, "platform data (reset configuration information) missing\n");
+		return -ENODEV;
+	}
+	psoc_bus->has_reset = data->has_reset;
+	platform_set_drvdata(pdev, psoc_bus);
+
+	if (psoc_bus->has_reset) {
+		ret = pdata->deassert_reset(pdev, pdata->reset_name);
+		if (ret) {
+			dev_err(dev, "deassert_reset failed: %d\n", ret);
+			goto fail_reset;
+		}
+	}
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev);
+		goto fail_clock;
+	}
+
+	ret = of_platform_populate(node, NULL, NULL, dev);
+	if (ret)
+		goto fail_of;
+
+	return 0;
+
+fail_of:
+	pm_runtime_put_sync(dev);
+fail_clock:
+	pm_runtime_disable(dev);
+	if (psoc_bus->has_reset)
+		pdata->assert_reset(pdev, pdata->reset_name);
+fail_reset:
+	iounmap(psoc_bus->syscfg);
+	return ret;
+}
+
+static int pruss_soc_bus_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pruss_platform_data *pdata = dev_get_platdata(dev);
+	struct pruss_soc_bus *psoc_bus = platform_get_drvdata(pdev);
+
+	of_platform_depopulate(dev);
+
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	if (psoc_bus->has_reset)
+		pdata->assert_reset(pdev, pdata->reset_name);
+	iounmap(psoc_bus->syscfg);
+
+	return 0;
+}
+
+/* instance-specific driver private data */
+static const struct pruss_soc_bus_match_data am335x_data = {
+	.has_reset = true,
+};
+
+static const struct of_device_id pruss_soc_bus_of_match[] = {
+	{ .compatible = "ti,am3356-pruss-soc-bus", .data = &am335x_data, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, pruss_soc_bus_of_match);
+
+static struct platform_driver pruss_soc_bus_driver = {
+	.driver	= {
+		.name = "pruss-soc-bus",
+		.of_match_table = pruss_soc_bus_of_match,
+	},
+	.probe	= pruss_soc_bus_probe,
+	.remove	= pruss_soc_bus_remove,
+};
+module_platform_driver(pruss_soc_bus_driver);
+
+MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
+MODULE_AUTHOR("Keerthy <j-keerthy@ti.com>");
+MODULE_DESCRIPTION("PRU-ICSS SoC Bus Driver for TI SoCs");
+MODULE_LICENSE("GPL v2");
