root/drivers/crypto/ccree/cc_pm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cc_pm_suspend
  2. cc_pm_resume
  3. cc_pm_get
  4. cc_pm_put_suspend
  5. cc_pm_is_dev_suspended
  6. cc_pm_init
  7. cc_pm_go
  8. cc_pm_fini

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (C) 2012-2019 ARM Limited (or its affiliates). */
   3 
   4 #include <linux/kernel.h>
   5 #include <linux/interrupt.h>
   6 #include <linux/pm_runtime.h>
   7 #include "cc_driver.h"
   8 #include "cc_buffer_mgr.h"
   9 #include "cc_request_mgr.h"
  10 #include "cc_sram_mgr.h"
  11 #include "cc_hash.h"
  12 #include "cc_pm.h"
  13 #include "cc_fips.h"
  14 
  15 #define POWER_DOWN_ENABLE 0x01
  16 #define POWER_DOWN_DISABLE 0x00
  17 
  18 const struct dev_pm_ops ccree_pm = {
  19         SET_RUNTIME_PM_OPS(cc_pm_suspend, cc_pm_resume, NULL)
  20 };
  21 
  22 int cc_pm_suspend(struct device *dev)
  23 {
  24         struct cc_drvdata *drvdata = dev_get_drvdata(dev);
  25 
  26         dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
  27         fini_cc_regs(drvdata);
  28         cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
  29         cc_clk_off(drvdata);
  30         return 0;
  31 }
  32 
  33 int cc_pm_resume(struct device *dev)
  34 {
  35         int rc;
  36         struct cc_drvdata *drvdata = dev_get_drvdata(dev);
  37 
  38         dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n");
  39         /* Enables the device source clk */
  40         rc = cc_clk_on(drvdata);
  41         if (rc) {
  42                 dev_err(dev, "failed getting clock back on. We're toast.\n");
  43                 return rc;
  44         }
  45         /* wait for Crytpcell reset completion */
  46         if (!cc_wait_for_reset_completion(drvdata)) {
  47                 dev_err(dev, "Cryptocell reset not completed");
  48                 return -EBUSY;
  49         }
  50 
  51         cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE);
  52         rc = init_cc_regs(drvdata, false);
  53         if (rc) {
  54                 dev_err(dev, "init_cc_regs (%x)\n", rc);
  55                 return rc;
  56         }
  57         /* check if tee fips error occurred during power down */
  58         cc_tee_handle_fips_error(drvdata);
  59 
  60         cc_init_hash_sram(drvdata);
  61 
  62         return 0;
  63 }
  64 
  65 int cc_pm_get(struct device *dev)
  66 {
  67         int rc = 0;
  68         struct cc_drvdata *drvdata = dev_get_drvdata(dev);
  69 
  70         if (drvdata->pm_on)
  71                 rc = pm_runtime_get_sync(dev);
  72 
  73         return (rc == 1 ? 0 : rc);
  74 }
  75 
  76 int cc_pm_put_suspend(struct device *dev)
  77 {
  78         int rc = 0;
  79         struct cc_drvdata *drvdata = dev_get_drvdata(dev);
  80 
  81         if (drvdata->pm_on) {
  82                 pm_runtime_mark_last_busy(dev);
  83                 rc = pm_runtime_put_autosuspend(dev);
  84         }
  85 
  86         return rc;
  87 }
  88 
  89 bool cc_pm_is_dev_suspended(struct device *dev)
  90 {
  91         /* check device state using runtime api */
  92         return pm_runtime_suspended(dev);
  93 }
  94 
  95 int cc_pm_init(struct cc_drvdata *drvdata)
  96 {
  97         struct device *dev = drvdata_to_dev(drvdata);
  98 
  99         /* must be before the enabling to avoid resdundent suspending */
 100         pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
 101         pm_runtime_use_autosuspend(dev);
 102         /* set us as active - note we won't do PM ops until cc_pm_go()! */
 103         return pm_runtime_set_active(dev);
 104 }
 105 
 106 /* enable the PM module*/
 107 void cc_pm_go(struct cc_drvdata *drvdata)
 108 {
 109         pm_runtime_enable(drvdata_to_dev(drvdata));
 110         drvdata->pm_on = true;
 111 }
 112 
 113 void cc_pm_fini(struct cc_drvdata *drvdata)
 114 {
 115         pm_runtime_disable(drvdata_to_dev(drvdata));
 116         drvdata->pm_on = false;
 117 }

/* [<][>][^][v][top][bottom][index][help] */