Merge tag 'acpi-4.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[platform/kernel/linux-starfive.git] / drivers / i2c / busses / i2c-designware-platdrv.c
index a14fb5f..9eaac3b 100644 (file)
@@ -85,10 +85,6 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
        struct i2c_timings *t = &dev->timings;
        u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
-       acpi_handle handle = ACPI_HANDLE(&pdev->dev);
-       const struct acpi_device_id *id;
-       struct acpi_device *adev;
-       const char *uid;
 
        dev->adapter.nr = -1;
        dev->tx_fifo_depth = 32;
@@ -119,22 +115,6 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
                break;
        }
 
-       id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
-       if (id && id->driver_data)
-               dev->flags |= (u32)id->driver_data;
-
-       if (acpi_bus_get_device(handle, &adev))
-               return -ENODEV;
-
-       /*
-        * Cherrytrail I2C7 gets used for the PMIC which gets accessed
-        * through ACPI opregions during late suspend / early resume
-        * disable pm for it.
-        */
-       uid = adev->pnp.unique_id;
-       if ((dev->flags & MODEL_CHERRYTRAIL) && !strcmp(uid, "7"))
-               dev->pm_disabled = true;
-
        return 0;
 }
 
@@ -143,8 +123,8 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "INT33C3", 0 },
        { "INT3432", 0 },
        { "INT3433", 0 },
-       { "80860F41", 0 },
-       { "808622C1", MODEL_CHERRYTRAIL },
+       { "80860F41", ACCESS_NO_IRQ_SUSPEND },
+       { "808622C1", ACCESS_NO_IRQ_SUSPEND | MODEL_CHERRYTRAIL },
        { "AMD0010", ACCESS_INTR_MASK },
        { "AMDI0010", ACCESS_INTR_MASK },
        { "AMDI0510", 0 },
@@ -161,6 +141,51 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
 }
 #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 platform_device *pdev)
+{
+       struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       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 platform_device *pdev)
+{
+       return -ENODEV;
+}
+#endif
+
 static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
 {
        struct i2c_timings *t = &dev->timings;
@@ -221,7 +246,7 @@ static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
 {
        pm_runtime_disable(dev->dev);
 
-       if (dev->pm_disabled)
+       if (dev->shared_with_punit)
                pm_runtime_put_noidle(dev->dev);
 }
 
@@ -291,6 +316,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        else
                t->bus_freq_hz = 400000;
 
+       dev->flags |= (uintptr_t)device_get_match_data(&pdev->dev);
+
+       if (pdev->dev.of_node)
+               dw_i2c_of_configure(pdev);
+
        if (has_acpi_companion(&pdev->dev))
                dw_i2c_acpi_configure(pdev);
 
@@ -348,7 +378,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_set_active(&pdev->dev);
 
-       if (dev->pm_disabled)
+       if (dev->shared_with_punit)
                pm_runtime_get_noresume(&pdev->dev);
 
        pm_runtime_enable(&pdev->dev);
@@ -391,14 +421,6 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id dw_i2c_of_match[] = {
-       { .compatible = "snps,designware-i2c", },
-       {},
-};
-MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
-#endif
-
 #ifdef CONFIG_PM_SLEEP
 static int dw_i2c_plat_prepare(struct device *dev)
 {
@@ -432,7 +454,7 @@ static int dw_i2c_plat_suspend(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       if (i_dev->pm_disabled)
+       if (i_dev->shared_with_punit)
                return 0;
 
        i_dev->disable(i_dev);
@@ -445,7 +467,7 @@ static int dw_i2c_plat_resume(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       if (!i_dev->pm_disabled)
+       if (!i_dev->shared_with_punit)
                i2c_dw_prepare_clk(i_dev, true);
 
        i_dev->init(i_dev);