PWM: ehrpwm: Support for low power sleep
authorPhilip, Avinash <avinashphilip@ti.com>
Fri, 9 Mar 2012 05:40:11 +0000 (11:10 +0530)
committerPhilip, Avinash <avinashphilip@ti.com>
Tue, 13 Mar 2012 13:20:11 +0000 (18:50 +0530)
This pattch
1. Adds context save/restore functionality to support low power sleep
transitions.
2. Adds pm_runtime [get_sync/put_sync] in context save function to
handle unenabled clock situation.
3. Removes check for clock use count.

Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
drivers/pwm/ehrpwm.c
include/linux/pwm/ehrpwm.h

index 8140ce7f1bbfbc83666090c66d4cafc8aa1e8f85..d37db5229dbe10a5f238315c1a64f5ab1ef0d60a 100644 (file)
@@ -1509,12 +1509,53 @@ err_mem_failure:
 }
 
 #ifdef CONFIG_PM
+
+void ehrpwm_context_save(struct ehrpwm_pwm *ehrpwm,
+               struct ehrpwm_context *ehrpwm_ctx)
+{
+       pm_runtime_get_sync(ehrpwm->dev);
+       ehrpwm_ctx->tbctl = ehrpwm_read(ehrpwm, TBCTL);
+       ehrpwm_ctx->tbprd = ehrpwm_read(ehrpwm, TBPRD);
+       if (ehrpwm->version == PWM_VERSION_1)
+               ehrpwm_ctx->hrcfg = ehrpwm_read(ehrpwm, AM335X_HRCNFG);
+       else
+               ehrpwm_ctx->hrcfg = ehrpwm_read(ehrpwm, HRCNFG);
+       ehrpwm_ctx->aqctla = ehrpwm_read(ehrpwm, AQCTLA);
+       ehrpwm_ctx->aqctlb = ehrpwm_read(ehrpwm, AQCTLB);
+       ehrpwm_ctx->cmpa = ehrpwm_read(ehrpwm, CMPA);
+       ehrpwm_ctx->cmpb = ehrpwm_read(ehrpwm, CMPB);
+       ehrpwm_ctx->tzctl = ehrpwm_read(ehrpwm, TZCTL);
+       ehrpwm_ctx->tzflg = ehrpwm_read(ehrpwm, TZFLG);
+       ehrpwm_ctx->tzclr = ehrpwm_read(ehrpwm, TZCLR);
+       ehrpwm_ctx->tzfrc = ehrpwm_read(ehrpwm, TZFRC);
+       pm_runtime_put_sync(ehrpwm->dev);
+}
+
+void ehrpwm_context_restore(struct ehrpwm_pwm *ehrpwm,
+               struct ehrpwm_context *ehrpwm_ctx)
+{
+       ehrpwm_write(ehrpwm, TBCTL, ehrpwm_ctx->tbctl);
+       ehrpwm_write(ehrpwm, TBPRD, ehrpwm_ctx->tbprd);
+       if (ehrpwm->version == PWM_VERSION_1)
+               ehrpwm_write(ehrpwm, AM335X_HRCNFG, ehrpwm_ctx->hrcfg);
+       else
+               ehrpwm_write(ehrpwm, HRCNFG, ehrpwm_ctx->hrcfg);
+       ehrpwm_write(ehrpwm, AQCTLA, ehrpwm_ctx->aqctla);
+       ehrpwm_write(ehrpwm, AQCTLB, ehrpwm_ctx->aqctlb);
+       ehrpwm_write(ehrpwm, CMPA, ehrpwm_ctx->cmpa);
+       ehrpwm_write(ehrpwm, CMPB, ehrpwm_ctx->cmpb);
+       ehrpwm_write(ehrpwm, TZCTL, ehrpwm_ctx->tzctl);
+       ehrpwm_write(ehrpwm, TZFLG, ehrpwm_ctx->tzflg);
+       ehrpwm_write(ehrpwm, TZCLR, ehrpwm_ctx->tzclr);
+       ehrpwm_write(ehrpwm, TZFRC, ehrpwm_ctx->tzfrc);
+}
+
 static int ehrpwm_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct ehrpwm_pwm *ehrpwm = platform_get_drvdata(pdev);
 
-       if (ehrpwm->clk->usecount > 0)
-               pm_runtime_put_sync(ehrpwm->dev);
+       ehrpwm_context_save(ehrpwm, &ehrpwm->ctx);
+       pm_runtime_put_sync(ehrpwm->dev);
 
        return 0;
 }
@@ -1524,6 +1565,7 @@ static int ehrpwm_resume(struct platform_device *pdev)
        struct ehrpwm_pwm *ehrpwm = platform_get_drvdata(pdev);
 
        pm_runtime_get_sync(ehrpwm->dev);
+       ehrpwm_context_restore(ehrpwm, &ehrpwm->ctx);
 
        return 0;
 }
index 56f88068bf4395ad1190f1e77869fb6a75285cd7..53a448143dcc8a7583b0a1cf287db5f926be9502 100644 (file)
@@ -19,6 +19,20 @@ struct tz_int {
        p_fcallback pcallback;
 };
 
+struct ehrpwm_context {
+       u32 tbctl;
+       u32 tbprd;
+       u32 hrcfg;
+       u32 aqctla;
+       u32 aqctlb;
+       u32 cmpa;
+       u32 cmpb;
+       u32 tzctl;
+       u32 tzflg;
+       u32 tzclr;
+       u32 tzfrc;
+};
+
 struct ehrpwm_pwm {
        struct pwm_device pwm[NCHAN];
        struct pwm_device_ops ops;
@@ -32,6 +46,7 @@ struct ehrpwm_pwm {
        u8 version;
        void __iomem *config_mem_base;
        struct device *dev;
+       struct ehrpwm_context ctx;
 };
 
 enum tz_event {