diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index ed6927c4c540..2f047cf07fee 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -566,6 +566,18 @@ config I2C_DESIGNWARE_SLAVE
 	  This is not a standalone module, this module compiles together with
 	  i2c-designware-core.
 
+config I2C_DESIGNWARE_MSCC
+	tristate "Microsemi Ocelot I2C"
+	depends on MSCC_OCELOT
+	select I2C_DESIGNWARE_PLATFORM
+	default y
+	help
+	  This driver supports the Microsemi Ocelot SoC version of the Synopsys
+	  Designware I2C IP-core.
+
+	  The driver can also be built as a module. If so, the module will be
+	  called i2c-designware-mscc.
+
 config I2C_DESIGNWARE_PCI
 	tristate "Synopsys DesignWare PCI"
 	depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index c6813d7b2780..480a9fe4fb64 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -55,6 +55,7 @@ i2c-designware-core-$(CONFIG_I2C_DESIGNWARE_SLAVE) 	+= i2c-designware-slave.o
 obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM)			+= i2c-designware-platform.o
 i2c-designware-platform-y 				:= i2c-designware-platdrv.o
 i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c-designware-baytrail.o
+obj-$(CONFIG_I2C_DESIGNWARE_MSCC)			+= i2c-designware-mscc.o
 obj-$(CONFIG_I2C_DESIGNWARE_PCI)			+= i2c-designware-pci.o
 i2c-designware-pci-y					:= i2c-designware-pcidrv.o
 obj-$(CONFIG_I2C_DIGICOLOR)	+= i2c-digicolor.o
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 10606266b30c..64544777a1fa 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -177,7 +177,6 @@
  * @dev: driver model device node
  * @map: IO registers map
  * @base: IO registers pointer
- * @ext: Extended IO registers pointer
  * @cmd_complete: tx completion indicator
  * @clk: input reference clock
  * @pclk: clock required to access the registers
@@ -229,7 +228,6 @@ struct dw_i2c_dev {
 	struct device		*dev;
 	struct regmap		*map;
 	void __iomem		*base;
-	void __iomem		*ext;
 	struct completion	cmd_complete;
 	struct clk		*clk;
 	struct clk		*pclk;
@@ -284,7 +282,6 @@ struct dw_i2c_dev {
 #define ACCESS_NO_IRQ_SUSPEND	0x00000008
 
 #define MODEL_CHERRYTRAIL	0x00000100
-#define MODEL_MSCC_OCELOT	0x00000200
 #define MODEL_MASK		0x00000f00
 
 int i2c_dw_init_regmap(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-mscc.c b/drivers/i2c/busses/i2c-designware-mscc.c
new file mode 100644
index 000000000000..0649e3d1fefc
--- /dev/null
+++ b/drivers/i2c/busses/i2c-designware-mscc.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Microsemi Ocelot I2C Controller.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "i2c-designware-core.h"
+#include "i2c-designware-platdrv.h"
+
+#define MSCC_ICPU_CFG_TWI_DELAY		0x0
+#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE	BIT(0)
+#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER	0x4
+
+struct mscc_i2c_dev {
+	struct dw_i2c_dev	dev;
+	void __iomem		*ext;
+};
+#define to_mscc_device(_dev)	container_of((_dev), struct mscc_i2c_dev, dev)
+
+static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
+{
+	struct mscc_i2c_dev *mscc = to_mscc_device(dev);
+
+	writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
+	       mscc->ext + MSCC_ICPU_CFG_TWI_DELAY);
+
+	return 0;
+}
+
+static int mscc_i2c_plat_probe(struct platform_device *pdev)
+{
+	struct mscc_i2c_dev *mscc;
+	struct resource *mem;
+
+	mscc = devm_kzalloc(&pdev->dev, sizeof(*mscc), GFP_KERNEL);
+	if (!mscc)
+		return -ENOMEM;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mscc->ext = devm_ioremap_resource(&pdev->dev, mem);
+	if (!IS_ERR(mscc->ext))
+		mscc->dev.set_sda_hold_time = mscc_twi_set_sda_hold_time;
+
+	mscc->dev.dev = &pdev->dev;
+	platform_set_drvdata(pdev, mscc);
+
+	return i2c_dw_plat_setup(&mscc->dev);
+}
+
+static int mscc_i2c_plat_remove(struct platform_device *pdev)
+{
+	struct mscc_i2c_dev *mscc = platform_get_drvdata(pdev);
+
+	return i2c_dw_plat_clear(&mscc->dev);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mscc_i2c_of_match[] = {
+	{ .compatible = "mscc,ocelot-i2c" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mscc_i2c_of_match);
+#endif
+
+static struct platform_driver mscc_i2c_driver = {
+	.probe = mscc_i2c_plat_probe,
+	.remove = mscc_i2c_plat_remove,
+	.driver		= {
+		.name	= "i2c_ocelot",
+		.of_match_table = of_match_ptr(mscc_i2c_of_match),
+		.pm	= &i2c_dw_plat_dev_pm_ops,
+	},
+};
+module_platform_driver(mscc_i2c_driver);
+
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
+MODULE_DESCRIPTION("Microsemi Ocelot I2C Controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 274953155569..1f56865bb6ca 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -143,48 +143,11 @@ static inline int dw_i2c_acpi_configure(struct dw_i2c_dev *dev)
 #endif
 
 #ifdef CONFIG_OF
-#define MSCC_ICPU_CFG_TWI_DELAY		0x0
-#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE	BIT(0)
-#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER	0x4
-
-static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
-{
-	writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
-	       dev->ext + MSCC_ICPU_CFG_TWI_DELAY);
-
-	return 0;
-}
-
-static int dw_i2c_of_configure(struct dw_i2c_dev *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev->dev);
-	struct resource *mem;
-
-	switch (dev->flags & MODEL_MASK) {
-	case MODEL_MSCC_OCELOT:
-		mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		dev->ext = devm_ioremap_resource(&pdev->dev, mem);
-		if (!IS_ERR(dev->ext))
-			dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
 static const struct of_device_id dw_i2c_of_match[] = {
 	{ .compatible = "snps,designware-i2c", },
-	{ .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
 	{},
 };
 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
-#else
-static inline int dw_i2c_of_configure(struct dw_i2c_dev *dev)
-{
-	return -ENODEV;
-}
 #endif
 
 static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
@@ -288,9 +251,6 @@ int i2c_dw_plat_setup(struct dw_i2c_dev *dev)
 	else
 		t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
 
-	if (pdev->dev.of_node)
-		dw_i2c_of_configure(dev);
-
 	if (has_acpi_companion(&pdev->dev))
 		dw_i2c_acpi_configure(dev);
 
