Skip to content

Commit

Permalink
arm: msm: add vreg reference count
Browse files Browse the repository at this point in the history
Support independent enable and disable by clients for common
vreg. First enable switches on and last disable switches off.

This change has no check for voltage level so clients
must agree on level for common vreg.

Signed-off-by: Matthew Wilson <mtwilson@quicinc.com>
  • Loading branch information
Matt Wilson authored and Daniel Walker committed May 12, 2010
1 parent 4eab625 commit 0e44106
Showing 1 changed file with 79 additions and 36 deletions.
115 changes: 79 additions & 36 deletions arch/arm/mach-msm/vreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/string.h>
#include <mach/vreg.h>

#include "proc_comm.h"
Expand All @@ -27,43 +28,44 @@ struct vreg {
const char *name;
unsigned id;
int status;
unsigned refcnt;
};

#define VREG(_name, _id, _status) \
{ .name = _name, .id = _id, .status = _status }
#define VREG(_name, _id, _status, _refcnt) \
{ .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }

static struct vreg vregs[] = {
VREG("msma", 0, 0),
VREG("msmp", 1, 0),
VREG("msme1", 2, 0),
VREG("msmc1", 3, 0),
VREG("msmc2", 4, 0),
VREG("gp3", 5, 0),
VREG("msme2", 6, 0),
VREG("gp4", 7, 0),
VREG("gp1", 8, 0),
VREG("tcxo", 9, 0),
VREG("pa", 10, 0),
VREG("rftx", 11, 0),
VREG("rfrx1", 12, 0),
VREG("rfrx2", 13, 0),
VREG("synt", 14, 0),
VREG("wlan", 15, 0),
VREG("usb", 16, 0),
VREG("boost", 17, 0),
VREG("mmc", 18, 0),
VREG("ruim", 19, 0),
VREG("msmc0", 20, 0),
VREG("gp2", 21, 0),
VREG("gp5", 22, 0),
VREG("gp6", 23, 0),
VREG("rf", 24, 0),
VREG("rf_vco", 26, 0),
VREG("mpll", 27, 0),
VREG("s2", 28, 0),
VREG("s3", 29, 0),
VREG("rfubm", 30, 0),
VREG("ncp", 31, 0),
VREG("msma", 0, 0, 0),
VREG("msmp", 1, 0, 0),
VREG("msme1", 2, 0, 0),
VREG("msmc1", 3, 0, 0),
VREG("msmc2", 4, 0, 0),
VREG("gp3", 5, 0, 0),
VREG("msme2", 6, 0, 0),
VREG("gp4", 7, 0, 0),
VREG("gp1", 8, 0, 0),
VREG("tcxo", 9, 0, 0),
VREG("pa", 10, 0, 0),
VREG("rftx", 11, 0, 0),
VREG("rfrx1", 12, 0, 0),
VREG("rfrx2", 13, 0, 0),
VREG("synt", 14, 0, 0),
VREG("wlan", 15, 0, 0),
VREG("usb", 16, 0, 0),
VREG("boost", 17, 0, 0),
VREG("mmc", 18, 0, 0),
VREG("ruim", 19, 0, 0),
VREG("msmc0", 20, 0, 0),
VREG("gp2", 21, 0, 0),
VREG("gp5", 22, 0, 0),
VREG("gp6", 23, 0, 0),
VREG("rf", 24, 0, 0),
VREG("rf_vco", 26, 0, 0),
VREG("mpll", 27, 0, 0),
VREG("s2", 28, 0, 0),
VREG("s3", 29, 0, 0),
VREG("rfubm", 30, 0, 0),
VREG("ncp", 31, 0, 0),
};

struct vreg *vreg_get(struct device *dev, const char *id)
Expand All @@ -85,7 +87,12 @@ int vreg_enable(struct vreg *vreg)
unsigned id = vreg->id;
unsigned enable = 1;

vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
if (vreg->refcnt == 0)
vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);

if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
vreg->refcnt++;

return vreg->status;
}

Expand All @@ -94,7 +101,15 @@ int vreg_disable(struct vreg *vreg)
unsigned id = vreg->id;
unsigned enable = 0;

vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
if (!vreg->refcnt)
return 0;

if (vreg->refcnt == 1)
vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);

if (!vreg->status)
vreg->refcnt--;

return vreg->status;
}

Expand Down Expand Up @@ -137,21 +152,49 @@ static int vreg_debug_get(void *data, u64 *val)
return 0;
}

static int vreg_debug_count_set(void *data, u64 val)
{
struct vreg *vreg = data;
if (val > UINT_MAX)
val = UINT_MAX;
vreg->refcnt = val;
return 0;
}

static int vreg_debug_count_get(void *data, u64 *val)
{
struct vreg *vreg = data;

*val = vreg->refcnt;

return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
vreg_debug_count_set, "%llu\n");

static int __init vreg_debug_init(void)
{
struct dentry *dent;
int n;
char name[32];
const char *refcnt_name = "_refcnt";

dent = debugfs_create_dir("vreg", 0);
if (IS_ERR(dent))
return 0;

for (n = 0; n < ARRAY_SIZE(vregs); n++)
for (n = 0; n < ARRAY_SIZE(vregs); n++) {
(void) debugfs_create_file(vregs[n].name, 0644,
dent, vregs + n, &vreg_fops);

strlcpy(name, vregs[n].name, sizeof(name));
strlcat(name, refcnt_name, sizeof(name));
(void) debugfs_create_file(name, 0644,
dent, vregs + n, &vreg_count_fops);
}

return 0;
}

Expand Down

0 comments on commit 0e44106

Please sign in to comment.