aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/amba/bus.c39
-rw-r--r--include/linux/amba/bus.h8
2 files changed, 47 insertions, 0 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 2737b9752205..e7df019d29d4 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -147,6 +147,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
147 clk_put(pclk); 147 clk_put(pclk);
148} 148}
149 149
150static int amba_get_enable_vcore(struct amba_device *pcdev)
151{
152 struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
153 int ret;
154
155 pcdev->vcore = vcore;
156
157 if (IS_ERR(vcore)) {
158 /* It is OK not to supply a vcore regulator */
159 if (PTR_ERR(vcore) == -ENODEV)
160 return 0;
161 return PTR_ERR(vcore);
162 }
163
164 ret = regulator_enable(vcore);
165 if (ret) {
166 regulator_put(vcore);
167 pcdev->vcore = ERR_PTR(-ENODEV);
168 }
169
170 return ret;
171}
172
173static void amba_put_disable_vcore(struct amba_device *pcdev)
174{
175 struct regulator *vcore = pcdev->vcore;
176
177 if (!IS_ERR(vcore)) {
178 regulator_disable(vcore);
179 regulator_put(vcore);
180 }
181}
182
150/* 183/*
151 * These are the device model conversion veneers; they convert the 184 * These are the device model conversion veneers; they convert the
152 * device model structures to our more specific structures. 185 * device model structures to our more specific structures.
@@ -159,6 +192,10 @@ static int amba_probe(struct device *dev)
159 int ret; 192 int ret;
160 193
161 do { 194 do {
195 ret = amba_get_enable_vcore(pcdev);
196 if (ret)
197 break;
198
162 ret = amba_get_enable_pclk(pcdev); 199 ret = amba_get_enable_pclk(pcdev);
163 if (ret) 200 if (ret)
164 break; 201 break;
@@ -168,6 +205,7 @@ static int amba_probe(struct device *dev)
168 break; 205 break;
169 206
170 amba_put_disable_pclk(pcdev); 207 amba_put_disable_pclk(pcdev);
208 amba_put_disable_vcore(pcdev);
171 } while (0); 209 } while (0);
172 210
173 return ret; 211 return ret;
@@ -180,6 +218,7 @@ static int amba_remove(struct device *dev)
180 int ret = drv->remove(pcdev); 218 int ret = drv->remove(pcdev);
181 219
182 amba_put_disable_pclk(pcdev); 220 amba_put_disable_pclk(pcdev);
221 amba_put_disable_vcore(pcdev);
183 222
184 return ret; 223 return ret;
185} 224}
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index c6454cca0447..9e7f259346e1 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/resource.h> 20#include <linux/resource.h>
21#include <linux/regulator/consumer.h>
21 22
22#define AMBA_NR_IRQS 2 23#define AMBA_NR_IRQS 2
23#define AMBA_CID 0xb105f00d 24#define AMBA_CID 0xb105f00d
@@ -28,6 +29,7 @@ struct amba_device {
28 struct device dev; 29 struct device dev;
29 struct resource res; 30 struct resource res;
30 struct clk *pclk; 31 struct clk *pclk;
32 struct regulator *vcore;
31 u64 dma_mask; 33 u64 dma_mask;
32 unsigned int periphid; 34 unsigned int periphid;
33 unsigned int irq[AMBA_NR_IRQS]; 35 unsigned int irq[AMBA_NR_IRQS];
@@ -71,6 +73,12 @@ void amba_release_regions(struct amba_device *);
71#define amba_pclk_disable(d) \ 73#define amba_pclk_disable(d) \
72 do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) 74 do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
73 75
76#define amba_vcore_enable(d) \
77 (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore))
78
79#define amba_vcore_disable(d) \
80 do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0)
81
74/* Some drivers don't use the struct amba_device */ 82/* Some drivers don't use the struct amba_device */
75#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) 83#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
76#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) 84#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)