root/drivers/regulator/dbx500-prcmu.c

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

DEFINITIONS

This source file includes following definitions.
  1. power_state_active_enable
  2. power_state_active_disable
  3. power_state_active_get
  4. ux500_regulator_power_state_cnt_show
  5. ux500_regulator_status_show
  6. dbx500_regulator_testcase
  7. ux500_regulator_debug_init
  8. ux500_regulator_debug_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) ST-Ericsson SA 2010
   4  *
   5  * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
   6  *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
   7  *
   8  * UX500 common part of Power domain regulators
   9  */
  10 
  11 #include <linux/kernel.h>
  12 #include <linux/err.h>
  13 #include <linux/regulator/driver.h>
  14 #include <linux/debugfs.h>
  15 #include <linux/seq_file.h>
  16 #include <linux/slab.h>
  17 #include <linux/module.h>
  18 
  19 #include "dbx500-prcmu.h"
  20 
  21 /*
  22  * power state reference count
  23  */
  24 static int power_state_active_cnt; /* will initialize to zero */
  25 static DEFINE_SPINLOCK(power_state_active_lock);
  26 
  27 void power_state_active_enable(void)
  28 {
  29         unsigned long flags;
  30 
  31         spin_lock_irqsave(&power_state_active_lock, flags);
  32         power_state_active_cnt++;
  33         spin_unlock_irqrestore(&power_state_active_lock, flags);
  34 }
  35 
  36 int power_state_active_disable(void)
  37 {
  38         int ret = 0;
  39         unsigned long flags;
  40 
  41         spin_lock_irqsave(&power_state_active_lock, flags);
  42         if (power_state_active_cnt <= 0) {
  43                 pr_err("power state: unbalanced enable/disable calls\n");
  44                 ret = -EINVAL;
  45                 goto out;
  46         }
  47 
  48         power_state_active_cnt--;
  49 out:
  50         spin_unlock_irqrestore(&power_state_active_lock, flags);
  51         return ret;
  52 }
  53 
  54 #ifdef CONFIG_REGULATOR_DEBUG
  55 
  56 static int power_state_active_get(void)
  57 {
  58         unsigned long flags;
  59         int cnt;
  60 
  61         spin_lock_irqsave(&power_state_active_lock, flags);
  62         cnt = power_state_active_cnt;
  63         spin_unlock_irqrestore(&power_state_active_lock, flags);
  64 
  65         return cnt;
  66 }
  67 
  68 static struct ux500_regulator_debug {
  69         struct dentry *dir;
  70         struct dentry *status_file;
  71         struct dentry *power_state_cnt_file;
  72         struct dbx500_regulator_info *regulator_array;
  73         int num_regulators;
  74         u8 *state_before_suspend;
  75         u8 *state_after_suspend;
  76 } rdebug;
  77 
  78 static int ux500_regulator_power_state_cnt_show(struct seq_file *s, void *p)
  79 {
  80         /* print power state count */
  81         seq_printf(s, "ux500-regulator power state count: %i\n",
  82                    power_state_active_get());
  83 
  84         return 0;
  85 }
  86 DEFINE_SHOW_ATTRIBUTE(ux500_regulator_power_state_cnt);
  87 
  88 static int ux500_regulator_status_show(struct seq_file *s, void *p)
  89 {
  90         int i;
  91 
  92         /* print dump header */
  93         seq_puts(s, "ux500-regulator status:\n");
  94         seq_printf(s, "%31s : %8s : %8s\n", "current", "before", "after");
  95 
  96         for (i = 0; i < rdebug.num_regulators; i++) {
  97                 struct dbx500_regulator_info *info;
  98                 /* Access per-regulator data */
  99                 info = &rdebug.regulator_array[i];
 100 
 101                 /* print status */
 102                 seq_printf(s, "%20s : %8s : %8s : %8s\n",
 103                            info->desc.name,
 104                            info->is_enabled ? "enabled" : "disabled",
 105                            rdebug.state_before_suspend[i] ? "enabled" : "disabled",
 106                            rdebug.state_after_suspend[i] ? "enabled" : "disabled");
 107         }
 108 
 109         return 0;
 110 }
 111 DEFINE_SHOW_ATTRIBUTE(ux500_regulator_status);
 112 
 113 int __attribute__((weak)) dbx500_regulator_testcase(
 114         struct dbx500_regulator_info *regulator_info,
 115         int num_regulators)
 116 {
 117         return 0;
 118 }
 119 
 120 int
 121 ux500_regulator_debug_init(struct platform_device *pdev,
 122         struct dbx500_regulator_info *regulator_info,
 123         int num_regulators)
 124 {
 125         /* create directory */
 126         rdebug.dir = debugfs_create_dir("ux500-regulator", NULL);
 127         if (!rdebug.dir)
 128                 goto exit_no_debugfs;
 129 
 130         /* create "status" file */
 131         rdebug.status_file = debugfs_create_file("status",
 132                 S_IRUGO, rdebug.dir, &pdev->dev,
 133                 &ux500_regulator_status_fops);
 134         if (!rdebug.status_file)
 135                 goto exit_destroy_dir;
 136 
 137         /* create "power-state-count" file */
 138         rdebug.power_state_cnt_file = debugfs_create_file("power-state-count",
 139                 S_IRUGO, rdebug.dir, &pdev->dev,
 140                 &ux500_regulator_power_state_cnt_fops);
 141         if (!rdebug.power_state_cnt_file)
 142                 goto exit_destroy_status;
 143 
 144         rdebug.regulator_array = regulator_info;
 145         rdebug.num_regulators = num_regulators;
 146 
 147         rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL);
 148         if (!rdebug.state_before_suspend)
 149                 goto exit_destroy_power_state;
 150 
 151         rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL);
 152         if (!rdebug.state_after_suspend)
 153                 goto exit_free;
 154 
 155         dbx500_regulator_testcase(regulator_info, num_regulators);
 156         return 0;
 157 
 158 exit_free:
 159         kfree(rdebug.state_before_suspend);
 160 exit_destroy_power_state:
 161         debugfs_remove(rdebug.power_state_cnt_file);
 162 exit_destroy_status:
 163         debugfs_remove(rdebug.status_file);
 164 exit_destroy_dir:
 165         debugfs_remove(rdebug.dir);
 166 exit_no_debugfs:
 167         dev_err(&pdev->dev, "failed to create debugfs entries.\n");
 168         return -ENOMEM;
 169 }
 170 
 171 int ux500_regulator_debug_exit(void)
 172 {
 173         debugfs_remove_recursive(rdebug.dir);
 174         kfree(rdebug.state_after_suspend);
 175         kfree(rdebug.state_before_suspend);
 176 
 177         return 0;
 178 }
 179 #endif

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