Merge tag 'topic/designware-baytrail-2017-03-02' of git://anongit.freedesktop.org...
authorWolfram Sang <wsa@the-dreams.de>
Wed, 22 Mar 2017 08:32:44 +0000 (09:32 +0100)
committerWolfram Sang <wsa@the-dreams.de>
Wed, 22 Mar 2017 08:32:44 +0000 (09:32 +0100)
Pull immutable branch as a common base for further development:

"Baytrail PMIC vs. PMU race fixes from Hans de Goede

This time the right version (v4), with the compile fix."

1  2 
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_uncore.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c

@@@ -1139,7 -1139,7 +1139,7 @@@ static void i915_driver_register(struc
        if (IS_GEN5(dev_priv))
                intel_gpu_ips_init(dev_priv);
  
 -      i915_audio_component_init(dev_priv);
 +      intel_audio_init(dev_priv);
  
        /*
         * Some ports require correctly set-up hpd registers for detection to
   */
  static void i915_driver_unregister(struct drm_i915_private *dev_priv)
  {
 -      i915_audio_component_cleanup(dev_priv);
 +      intel_audio_deinit(dev_priv);
  
        intel_gpu_ips_teardown();
        acpi_video_unregister();
@@@ -1456,7 -1456,7 +1456,7 @@@ static int i915_drm_suspend(struct drm_
        opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
        intel_opregion_notify_adapter(dev_priv, opregion_target_state);
  
-       intel_uncore_forcewake_reset(dev_priv, false);
+       intel_uncore_suspend(dev_priv);
        intel_opregion_unregister(dev_priv);
  
        intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
@@@ -1701,7 -1701,7 +1701,7 @@@ static int i915_drm_resume_early(struc
                DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
                          ret);
  
-       intel_uncore_early_sanitize(dev_priv, true);
+       intel_uncore_resume_early(dev_priv);
  
        if (IS_GEN9_LP(dev_priv)) {
                if (!dev_priv->suspended_to_idle)
@@@ -2343,7 -2343,7 +2343,7 @@@ static int intel_runtime_suspend(struc
                return ret;
        }
  
-       intel_uncore_forcewake_reset(dev_priv, false);
+       intel_uncore_suspend(dev_priv);
  
        enable_rpm_wakeref_asserts(dev_priv);
        WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count));
@@@ -293,7 -293,6 +293,7 @@@ enum plane_id 
        PLANE_PRIMARY,
        PLANE_SPRITE0,
        PLANE_SPRITE1,
 +      PLANE_SPRITE2,
        PLANE_CURSOR,
        I915_MAX_PLANES,
  };
@@@ -723,6 -722,7 +723,7 @@@ struct intel_uncore 
        const struct intel_forcewake_range *fw_domains_table;
        unsigned int fw_domains_table_entries;
  
+       struct notifier_block pmic_bus_access_nb;
        struct intel_uncore_funcs funcs;
  
        unsigned fifo_count;
@@@ -2460,12 -2460,6 +2461,12 @@@ struct drm_i915_private 
        /* Used to save the pipe-to-encoder mapping for audio */
        struct intel_encoder *av_enc_map[I915_MAX_PIPES];
  
 +      /* necessary resource sharing with HDMI LPE audio driver. */
 +      struct {
 +              struct platform_device *platdev;
 +              int     irq;
 +      } lpe_audio;
 +
        /*
         * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
         * will be rejected. Instead look for a better place.
@@@ -2991,14 -2985,12 +2992,12 @@@ int intel_irq_install(struct drm_i915_p
  void intel_irq_uninstall(struct drm_i915_private *dev_priv);
  
  extern void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
- extern void intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
-                                       bool restore_forcewake);
  extern void intel_uncore_init(struct drm_i915_private *dev_priv);
  extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
  extern bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
  extern void intel_uncore_fini(struct drm_i915_private *dev_priv);
- extern void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
                                       bool restore);
+ extern void intel_uncore_suspend(struct drm_i915_private *dev_priv);
extern void intel_uncore_resume_early(struct drm_i915_private *dev_priv);
  const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
  void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
                                enum forcewake_domains domains);
@@@ -3353,7 -3345,7 +3352,7 @@@ int __must_check i915_gem_wait_for_idle
                                        unsigned int flags);
  int __must_check i915_gem_suspend(struct drm_i915_private *dev_priv);
  void i915_gem_resume(struct drm_i915_private *dev_priv);
 -int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 +int i915_gem_fault(struct vm_fault *vmf);
  int i915_gem_object_wait(struct drm_i915_gem_object *obj,
                         unsigned int flags,
                         long timeout,
@@@ -3604,14 -3596,6 +3603,14 @@@ extern int i915_restore_state(struct dr
  void i915_setup_sysfs(struct drm_i915_private *dev_priv);
  void i915_teardown_sysfs(struct drm_i915_private *dev_priv);
  
 +/* intel_lpe_audio.c */
 +int  intel_lpe_audio_init(struct drm_i915_private *dev_priv);
 +void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv);
 +void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv);
 +void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
 +                          void *eld, int port, int pipe, int tmds_clk_speed,
 +                          bool dp_output, int link_rate);
 +
  /* intel_i2c.c */
  extern int intel_setup_gmbus(struct drm_i915_private *dev_priv);
  extern void intel_teardown_gmbus(struct drm_i915_private *dev_priv);
@@@ -25,6 -25,7 +25,7 @@@
  #include "intel_drv.h"
  #include "i915_vgpu.h"
  
+ #include <asm/iosf_mbi.h>
  #include <linux/pm_runtime.h>
  
  #define FORCEWAKE_ACK_TIMEOUT_MS 50
@@@ -119,8 -120,6 +120,8 @@@ fw_domains_get(struct drm_i915_private 
  
        for_each_fw_domain_masked(d, fw_domains, dev_priv)
                fw_domain_wait_ack(d);
 +
 +      dev_priv->uncore.fw_domains_active |= fw_domains;
  }
  
  static void
@@@ -132,8 -131,6 +133,8 @@@ fw_domains_put(struct drm_i915_private 
                fw_domain_put(d);
                fw_domain_posting_read(d);
        }
 +
 +      dev_priv->uncore.fw_domains_active &= ~fw_domains;
  }
  
  static void
@@@ -244,16 -241,18 +245,16 @@@ intel_uncore_fw_release_timer(struct hr
        if (WARN_ON(domain->wake_count == 0))
                domain->wake_count++;
  
 -      if (--domain->wake_count == 0) {
 +      if (--domain->wake_count == 0)
                dev_priv->uncore.funcs.force_wake_put(dev_priv, domain->mask);
 -              dev_priv->uncore.fw_domains_active &= ~domain->mask;
 -      }
  
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  
        return HRTIMER_NORESTART;
  }
  
- void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
-                                 bool restore)
static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
+                                        bool restore)
  {
        unsigned long irqflags;
        struct intel_uncore_forcewake_domain *domain;
@@@ -429,10 -428,18 +430,18 @@@ static void __intel_uncore_early_saniti
        intel_uncore_forcewake_reset(dev_priv, restore_forcewake);
  }
  
- void intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
-                                bool restore_forcewake)
+ void intel_uncore_suspend(struct drm_i915_private *dev_priv)
  {
-       __intel_uncore_early_sanitize(dev_priv, restore_forcewake);
+       iosf_mbi_unregister_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
+       intel_uncore_forcewake_reset(dev_priv, false);
+ }
+ void intel_uncore_resume_early(struct drm_i915_private *dev_priv)
+ {
+       __intel_uncore_early_sanitize(dev_priv, true);
+       iosf_mbi_register_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
        i915_check_and_clear_faults(dev_priv);
  }
  
@@@ -456,8 -463,10 +465,8 @@@ static void __intel_uncore_forcewake_ge
                        fw_domains &= ~domain->mask;
        }
  
 -      if (fw_domains) {
 +      if (fw_domains)
                dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
 -              dev_priv->uncore.fw_domains_active |= fw_domains;
 -      }
  }
  
  /**
@@@ -968,6 -977,7 +977,6 @@@ static noinline void ___force_wake_auto
                fw_domain_arm_timer(domain);
  
        dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
 -      dev_priv->uncore.fw_domains_active |= fw_domains;
  }
  
  static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
@@@ -1385,6 -1395,32 +1394,32 @@@ static void intel_uncore_fw_domains_ini
        dev_priv->uncore.fw_domains_table_entries = ARRAY_SIZE((d)); \
  }
  
+ static int i915_pmic_bus_access_notifier(struct notifier_block *nb,
+                                        unsigned long action, void *data)
+ {
+       struct drm_i915_private *dev_priv = container_of(nb,
+                       struct drm_i915_private, uncore.pmic_bus_access_nb);
+       switch (action) {
+       case MBI_PMIC_BUS_ACCESS_BEGIN:
+               /*
+                * forcewake all now to make sure that we don't need to do a
+                * forcewake later which on systems where this notifier gets
+                * called requires the punit to access to the shared pmic i2c
+                * bus, which will be busy after this notification, leading to:
+                * "render: timed out waiting for forcewake ack request."
+                * errors.
+                */
+               intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+               break;
+       case MBI_PMIC_BUS_ACCESS_END:
+               intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+               break;
+       }
+       return NOTIFY_OK;
+ }
  void intel_uncore_init(struct drm_i915_private *dev_priv)
  {
        i915_check_vgpu(dev_priv);
        __intel_uncore_early_sanitize(dev_priv, false);
  
        dev_priv->uncore.unclaimed_mmio_check = 1;
+       dev_priv->uncore.pmic_bus_access_nb.notifier_call =
+               i915_pmic_bus_access_notifier;
  
        switch (INTEL_INFO(dev_priv)->gen) {
        default:
                ASSIGN_READ_MMIO_VFUNCS(vgpu);
        }
  
+       iosf_mbi_register_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
        i915_check_and_clear_faults(dev_priv);
  }
  #undef ASSIGN_WRITE_MMIO_VFUNCS
  
  void intel_uncore_fini(struct drm_i915_private *dev_priv)
  {
+       iosf_mbi_unregister_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
        /* Paranoia: make sure we have disabled everything before we exit. */
        intel_uncore_sanitize(dev_priv);
        intel_uncore_forcewake_reset(dev_priv, false);
@@@ -177,13 -177,13 +177,13 @@@ static u32 dw_readl(struct dw_i2c_dev *
  {
        u32 value;
  
-       if (dev->accessor_flags & ACCESS_16BIT)
+       if (dev->flags & ACCESS_16BIT)
                value = readw_relaxed(dev->base + offset) |
                        (readw_relaxed(dev->base + offset + 2) << 16);
        else
                value = readl_relaxed(dev->base + offset);
  
-       if (dev->accessor_flags & ACCESS_SWAP)
+       if (dev->flags & ACCESS_SWAP)
                return swab32(value);
        else
                return value;
  
  static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
  {
-       if (dev->accessor_flags & ACCESS_SWAP)
+       if (dev->flags & ACCESS_SWAP)
                b = swab32(b);
  
-       if (dev->accessor_flags & ACCESS_16BIT) {
+       if (dev->flags & ACCESS_16BIT) {
                writew_relaxed((u16)b, dev->base + offset);
                writew_relaxed((u16)(b >> 16), dev->base + offset + 2);
        } else {
@@@ -339,10 -339,10 +339,10 @@@ int i2c_dw_init(struct dw_i2c_dev *dev
        reg = dw_readl(dev, DW_IC_COMP_TYPE);
        if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
                /* Configure register endianess access */
-               dev->accessor_flags |= ACCESS_SWAP;
+               dev->flags |= ACCESS_SWAP;
        } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
                /* Configure register access mode 16bit */
-               dev->accessor_flags |= ACCESS_16BIT;
+               dev->flags |= ACCESS_16BIT;
        } else if (reg != DW_IC_COMP_TYPE_VALUE) {
                dev_err(dev->dev, "Unknown Synopsys component type: "
                        "0x%08x\n", reg);
@@@ -475,28 -475,30 +475,28 @@@ static int i2c_dw_wait_bus_not_busy(str
  static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
  {
        struct i2c_msg *msgs = dev->msgs;
 -      u32 ic_tar = 0;
 +      u32 ic_con, ic_tar = 0;
  
        /* Disable the adapter */
        __i2c_dw_enable_and_wait(dev, false);
  
        /* if the slave address is ten bit address, enable 10BITADDR */
 -      if (dev->dynamic_tar_update_enabled) {
 +      ic_con = dw_readl(dev, DW_IC_CON);
 +      if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) {
 +              ic_con |= DW_IC_CON_10BITADDR_MASTER;
                /*
                 * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing
 -               * mode has to be enabled via bit 12 of IC_TAR register,
 -               * otherwise bit 4 of IC_CON is used.
 +               * mode has to be enabled via bit 12 of IC_TAR register.
 +               * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be
 +               * detected from registers.
                 */
 -              if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
 -                      ic_tar = DW_IC_TAR_10BITADDR_MASTER;
 +              ic_tar = DW_IC_TAR_10BITADDR_MASTER;
        } else {
 -              u32 ic_con = dw_readl(dev, DW_IC_CON);
 -
 -              if (msgs[dev->msg_write_idx].flags & I2C_M_TEN)
 -                      ic_con |= DW_IC_CON_10BITADDR_MASTER;
 -              else
 -                      ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
 -              dw_writel(dev, ic_con, DW_IC_CON);
 +              ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
        }
  
 +      dw_writel(dev, ic_con, DW_IC_CON);
 +
        /*
         * Set the slave (target) address and enable 10-bit addressing mode
         * if applicable.
@@@ -820,7 -822,7 +820,7 @@@ static u32 i2c_dw_func(struct i2c_adapt
        return dev->functionality;
  }
  
 -static struct i2c_algorithm i2c_dw_algo = {
 +static const struct i2c_algorithm i2c_dw_algo = {
        .master_xfer    = i2c_dw_xfer,
        .functionality  = i2c_dw_func,
  };
@@@ -924,7 -926,7 +924,7 @@@ static irqreturn_t i2c_dw_isr(int this_
  tx_aborted:
        if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
                complete(&dev->cmd_complete);
-       else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
+       else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
                /* workaround to trigger pending interrupt */
                stat = dw_readl(dev, DW_IC_INTR_MASK);
                i2c_dw_disable_int(dev);
@@@ -961,6 -963,7 +961,6 @@@ int i2c_dw_probe(struct dw_i2c_dev *dev
  {
        struct i2c_adapter *adap = &dev->adapter;
        int r;
 -      u32 reg;
  
        init_completion(&dev->cmd_complete);
  
        if (r)
                return r;
  
 -      r = i2c_dw_acquire_lock(dev);
 -      if (r)
 -              return r;
 -
 -      /*
 -       * Test if dynamic TAR update is enabled in this controller by writing
 -       * to IC_10BITADDR_MASTER field in IC_CON: when it is enabled this
 -       * field is read-only so it should not succeed
 -       */
 -      reg = dw_readl(dev, DW_IC_CON);
 -      dw_writel(dev, reg ^ DW_IC_CON_10BITADDR_MASTER, DW_IC_CON);
 -
 -      if ((dw_readl(dev, DW_IC_CON) & DW_IC_CON_10BITADDR_MASTER) ==
 -          (reg & DW_IC_CON_10BITADDR_MASTER)) {
 -              dev->dynamic_tar_update_enabled = true;
 -              dev_dbg(dev->dev, "Dynamic TAR update enabled");
 -      }
 -
 -      i2c_dw_release_lock(dev);
 -
        snprintf(adap->name, sizeof(adap->name),
                 "Synopsys DesignWare I2C adapter");
        adap->retries = 3;
@@@ -23,6 -23,7 +23,7 @@@
   */
  
  #include <linux/i2c.h>
+ #include <linux/pm_qos.h>
  
  #define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C |                   \
                                        I2C_FUNC_SMBUS_BYTE |           \
@@@ -75,6 -76,7 +76,7 @@@
   * @fp_lcnt: fast plus LCNT value
   * @hs_hcnt: high speed HCNT value
   * @hs_lcnt: high speed LCNT value
+  * @pm_qos: pm_qos_request used while holding a hardware lock on the bus
   * @acquire_lock: function to acquire a hardware lock on the bus
   * @release_lock: function to release a hardware lock on the bus
   * @pm_runtime_disabled: true if pm runtime is disabled
@@@ -88,7 -90,6 +90,7 @@@ struct dw_i2c_dev 
        void __iomem            *base;
        struct completion       cmd_complete;
        struct clk              *clk;
 +      struct reset_control    *rst;
        u32                     (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
        struct dw_pci_controller *controller;
        int                     cmd_err;
        unsigned int            status;
        u32                     abort_source;
        int                     irq;
-       u32                     accessor_flags;
+       u32                     flags;
        struct i2c_adapter      adapter;
        u32                     functionality;
        u32                     master_cfg;
        u16                     fp_lcnt;
        u16                     hs_hcnt;
        u16                     hs_lcnt;
+       struct pm_qos_request   pm_qos;
        int                     (*acquire_lock)(struct dw_i2c_dev *dev);
        void                    (*release_lock)(struct dw_i2c_dev *dev);
        bool                    pm_runtime_disabled;
 -      bool                    dynamic_tar_update_enabled;
  };
  
  #define ACCESS_SWAP           0x00000001
  #define ACCESS_16BIT          0x00000002
  #define ACCESS_INTR_MASK      0x00000004
  
+ #define MODEL_CHERRYTRAIL     0x00000100
  extern int i2c_dw_init(struct dw_i2c_dev *dev);
  extern void i2c_dw_disable(struct dw_i2c_dev *dev);
  extern void i2c_dw_disable_int(struct dw_i2c_dev *dev);
@@@ -139,7 -144,9 +144,9 @@@ extern u32 i2c_dw_read_comp_param(struc
  extern int i2c_dw_probe(struct dw_i2c_dev *dev);
  
  #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL)
- extern int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev);
+ extern int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev);
+ extern void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev);
  #else
- static inline int i2c_dw_eval_lock_support(struct dw_i2c_dev *dev) { return 0; }
+ static inline int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev) { return 0; }
+ static inline void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) {}
  #endif
@@@ -38,7 -38,6 +38,7 @@@
  #include <linux/pm_runtime.h>
  #include <linux/property.h>
  #include <linux/io.h>
 +#include <linux/reset.h>
  #include <linux/slab.h>
  #include <linux/acpi.h>
  #include <linux/platform_data/i2c-designware.h>
@@@ -113,7 -112,7 +113,7 @@@ static int dw_i2c_acpi_configure(struc
  
        id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
        if (id && id->driver_data)
-               dev->accessor_flags |= (u32)id->driver_data;
+               dev->flags |= (u32)id->driver_data;
  
        return 0;
  }
@@@ -124,7 -123,7 +124,7 @@@ static const struct acpi_device_id dw_i
        { "INT3432", 0 },
        { "INT3433", 0 },
        { "80860F41", 0 },
-       { "808622C1", 0 },
+       { "808622C1", MODEL_CHERRYTRAIL },
        { "AMD0010", ACCESS_INTR_MASK },
        { "AMDI0010", ACCESS_INTR_MASK },
        { "AMDI0510", 0 },
@@@ -200,14 -199,6 +200,14 @@@ static int dw_i2c_plat_probe(struct pla
        dev->irq = irq;
        platform_set_drvdata(pdev, dev);
  
 +      dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
 +      if (IS_ERR(dev->rst)) {
 +              if (PTR_ERR(dev->rst) == -EPROBE_DEFER)
 +                      return -EPROBE_DEFER;
 +      } else {
 +              reset_control_deassert(dev->rst);
 +      }
 +
        if (pdata) {
                dev->clk_freq = pdata->i2c_scl_freq;
        } else {
            && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
                dev_err(&pdev->dev,
                        "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
 -              return -EINVAL;
 +              r = -EINVAL;
 +              goto exit_reset;
        }
  
-       r = i2c_dw_eval_lock_support(dev);
+       r = i2c_dw_probe_lock_support(dev);
        if (r)
 -              return r;
 +              goto exit_reset;
  
        dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
  
        }
  
        r = i2c_dw_probe(dev);
 -      if (r && !dev->pm_runtime_disabled)
 -              pm_runtime_disable(&pdev->dev);
 +      if (r)
 +              goto exit_probe;
  
        return r;
 +
 +exit_probe:
 +      if (!dev->pm_runtime_disabled)
 +              pm_runtime_disable(&pdev->dev);
 +exit_reset:
 +      if (!IS_ERR_OR_NULL(dev->rst))
 +              reset_control_assert(dev->rst);
 +      return r;
  }
  
  static int dw_i2c_plat_remove(struct platform_device *pdev)
        pm_runtime_put_sync(&pdev->dev);
        if (!dev->pm_runtime_disabled)
                pm_runtime_disable(&pdev->dev);
 +      if (!IS_ERR_OR_NULL(dev->rst))
 +              reset_control_assert(dev->rst);
  
+       i2c_dw_remove_lock_support(dev);
        return 0;
  }