diff options
-rw-r--r-- | drivers/amba/bus.c | 39 | ||||
-rw-r--r-- | include/linux/amba/bus.h | 8 |
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 | ||
150 | static 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 | |||
173 | static 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) |