#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
        }
 }
 
-static void anx7625_chip_control(struct anx7625_data *ctx, int state)
-{
-       struct device *dev = &ctx->client->dev;
-
-       DRM_DEV_DEBUG_DRIVER(dev, "before set, power_state(%d).\n",
-                            atomic_read(&ctx->power_status));
-
-       if (!ctx->pdata.low_power_mode)
-               return;
-
-       if (state) {
-               atomic_inc(&ctx->power_status);
-               if (atomic_read(&ctx->power_status) == 1)
-                       anx7625_power_on_init(ctx);
-       } else {
-               if (atomic_read(&ctx->power_status)) {
-                       atomic_dec(&ctx->power_status);
-
-                       if (atomic_read(&ctx->power_status) == 0)
-                               anx7625_power_standby(ctx);
-               }
-       }
-
-       DRM_DEV_DEBUG_DRIVER(dev, "after set, power_state(%d).\n",
-                            atomic_read(&ctx->power_status));
-}
-
 static void anx7625_init_gpio(struct anx7625_data *platform)
 {
        struct device *dev = &platform->client->dev;
        ctx->hpd_status = 0;
        ctx->hpd_high_cnt = 0;
        ctx->display_timing_valid = 0;
-
-       if (ctx->pdata.low_power_mode == 0)
-               anx7625_disable_pd_protocol(ctx);
 }
 
 static void anx7625_start_dp_work(struct anx7625_data *ctx)
        int ret, val;
        struct device *dev = &ctx->client->dev;
 
-       if (atomic_read(&ctx->power_status) != 1) {
-               DRM_DEV_DEBUG_DRIVER(dev, "No need to poling HPD status.\n");
-               return;
-       }
-
        ret = readx_poll_timeout(anx7625_read_hpd_status_p0,
                                 ctx, val,
                                 ((val & HPD_STATUS) || (val < 0)),
                                 5000,
                                 5000 * 100);
        if (ret) {
-               DRM_DEV_ERROR(dev, "HPD polling timeout!\n");
-       } else {
-               DRM_DEV_DEBUG_DRIVER(dev, "HPD raise up.\n");
-               anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
-                                 INTR_ALERT_1, 0xFF);
-               anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
-                                 INTERFACE_CHANGE_INT, 0);
+               DRM_DEV_ERROR(dev, "no hpd.\n");
+               return;
        }
 
-       anx7625_start_dp_work(ctx);
-}
-
-static void anx7625_disconnect_check(struct anx7625_data *ctx)
-{
-       if (atomic_read(&ctx->power_status) == 0)
-               anx7625_stop_dp_work(ctx);
-}
-
-static void anx7625_low_power_mode_check(struct anx7625_data *ctx,
-                                        int state)
-{
-       struct device *dev = &ctx->client->dev;
+       DRM_DEV_DEBUG_DRIVER(dev, "system status: 0x%x. HPD raise up.\n", val);
+       anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
+                         INTR_ALERT_1, 0xFF);
+       anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
+                         INTERFACE_CHANGE_INT, 0);
 
-       DRM_DEV_DEBUG_DRIVER(dev, "low power mode check, state(%d).\n", state);
+       anx7625_start_dp_work(ctx);
 
-       if (ctx->pdata.low_power_mode) {
-               anx7625_chip_control(ctx, state);
-               if (state)
-                       anx7625_hpd_polling(ctx);
-               else
-                       anx7625_disconnect_check(ctx);
-       }
+       if (!ctx->pdata.panel_bridge && ctx->bridge_attached)
+               drm_helper_hpd_irq_event(ctx->bridge.dev);
 }
 
 static void anx7625_remove_edid(struct anx7625_data *ctx)
        int intr_vector, status;
        struct device *dev = &ctx->client->dev;
 
-       DRM_DEV_DEBUG_DRIVER(dev, "power_status=%d\n",
-                            (u32)atomic_read(&ctx->power_status));
-
        status = anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
                                   INTR_ALERT_1, 0xFF);
        if (status < 0) {
                                                struct anx7625_data, work);
 
        mutex_lock(&ctx->lock);
+
+       if (pm_runtime_suspended(&ctx->client->dev))
+               goto unlock;
+
        event = anx7625_hpd_change_detect(ctx);
-       mutex_unlock(&ctx->lock);
        if (event < 0)
-               return;
+               goto unlock;
 
        if (ctx->bridge_attached)
                drm_helper_hpd_irq_event(ctx->bridge.dev);
+
+unlock:
+       mutex_unlock(&ctx->lock);
 }
 
 static irqreturn_t anx7625_intr_hpd_isr(int irq, void *data)
 {
        struct anx7625_data *ctx = (struct anx7625_data *)data;
 
-       if (atomic_read(&ctx->power_status) != 1)
-               return IRQ_NONE;
-
        queue_work(ctx->workqueue, &ctx->work);
 
        return IRQ_HANDLED;
                return (struct edid *)edid;
        }
 
-       anx7625_low_power_mode_check(ctx, 1);
+       pm_runtime_get_sync(dev);
        edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data);
-       anx7625_low_power_mode_check(ctx, 0);
+       pm_runtime_put(dev);
 
        if (edid_num < 1) {
                DRM_DEV_ERROR(dev, "Fail to read EDID: %d\n", edid_num);
 
        DRM_DEV_DEBUG_DRIVER(dev, "drm enable\n");
 
-       anx7625_low_power_mode_check(ctx, 1);
-
-       if (WARN_ON(!atomic_read(&ctx->power_status)))
-               return;
+       pm_runtime_get_sync(dev);
 
        anx7625_dp_start(ctx);
 }
        struct anx7625_data *ctx = bridge_to_anx7625(bridge);
        struct device *dev = &ctx->client->dev;
 
-       if (WARN_ON(!atomic_read(&ctx->power_status)))
-               return;
-
        DRM_DEV_DEBUG_DRIVER(dev, "drm disable\n");
 
        anx7625_dp_stop(ctx);
 
-       anx7625_low_power_mode_check(ctx, 0);
+       pm_runtime_put(dev);
 }
 
 static enum drm_connector_status
        i2c_unregister_device(ctx->i2c.tcpc_client);
 }
 
+static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev)
+{
+       struct anx7625_data *ctx = dev_get_drvdata(dev);
+
+       mutex_lock(&ctx->lock);
+
+       anx7625_stop_dp_work(ctx);
+       anx7625_power_standby(ctx);
+
+       mutex_unlock(&ctx->lock);
+
+       return 0;
+}
+
+static int __maybe_unused anx7625_runtime_pm_resume(struct device *dev)
+{
+       struct anx7625_data *ctx = dev_get_drvdata(dev);
+
+       mutex_lock(&ctx->lock);
+
+       anx7625_power_on_init(ctx);
+       anx7625_hpd_polling(ctx);
+
+       mutex_unlock(&ctx->lock);
+
+       return 0;
+}
+
+static const struct dev_pm_ops anx7625_pm_ops = {
+       SET_RUNTIME_PM_OPS(anx7625_runtime_pm_suspend,
+                          anx7625_runtime_pm_resume, NULL)
+};
+
 static int anx7625_i2c_probe(struct i2c_client *client,
                             const struct i2c_device_id *id)
 {
        }
        anx7625_init_gpio(platform);
 
-       atomic_set(&platform->power_status, 0);
-
        mutex_init(&platform->lock);
 
        platform->pdata.intp_irq = client->irq;
                goto free_wq;
        }
 
-       if (platform->pdata.low_power_mode == 0) {
+       pm_runtime_enable(dev);
+
+       if (!platform->pdata.low_power_mode) {
                anx7625_disable_pd_protocol(platform);
-               atomic_set(&platform->power_status, 1);
+               pm_runtime_get_sync(dev);
        }
 
        /* Add work function */
        if (platform->pdata.intp_irq)
                destroy_workqueue(platform->workqueue);
 
+       if (!platform->pdata.low_power_mode)
+               pm_runtime_put_sync_suspend(&client->dev);
+
        anx7625_unregister_i2c_dummy_clients(platform);
 
        kfree(platform);
        .driver = {
                .name = "anx7625",
                .of_match_table = anx_match_table,
+               .pm = &anx7625_pm_ops,
        },
        .probe = anx7625_i2c_probe,
        .remove = anx7625_i2c_remove,