blob: 341e5b27d2c50fb4cbf3ca72896d4089a0b0d252 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/fs.h>
18#include <linux/slab.h>
19#include <linux/miscdevice.h>
20#include <linux/delay.h>
21#include <linux/qfp_fuse.h>
22#include <linux/io.h>
23#include <linux/uaccess.h>
24#include <linux/regulator/consumer.h>
25#include <linux/platform_device.h>
26#include <linux/mutex.h>
27
28/*
29 * Time QFPROM requires to reliably burn a fuse.
30 */
31#define QFPROM_BLOW_TIMEOUT_US 10
32#define QFPROM_BLOW_TIMER_OFFSET 0x2038
33/*
34 * Denotes number of cycles required to blow the fuse.
35 */
36#define QFPROM_BLOW_TIMER_VALUE (QFPROM_BLOW_TIMEOUT_US * 83)
37
38#define QFPROM_BLOW_STATUS_OFFSET 0x204C
39#define QFPROM_BLOW_STATUS_BUSY 0x01
40#define QFPROM_BLOW_STATUS_ERROR 0x02
41
42#define QFP_FUSE_READY 0x01
43#define QFP_FUSE_OFF 0x00
44
45struct qfp_priv_t {
46 uint32_t base;
47 uint32_t end;
48 struct mutex lock;
49 struct regulator *fuse_vdd;
50 u8 state;
51};
52
53/* We need only one instance of this for the driver */
54static struct qfp_priv_t *qfp_priv;
55
56
57static int qfp_fuse_open(struct inode *inode, struct file *filp)
58{
59 if (qfp_priv == NULL)
60 return -ENODEV;
61
62 filp->private_data = qfp_priv;
63
64 return 0;
65}
66
67static int qfp_fuse_release(struct inode *inode, struct file *filp)
68{
69
70 filp->private_data = NULL;
71
72 return 0;
73}
74
75static inline int qfp_fuse_wait_for_fuse_blow(u32 *status)
76{
77 u32 timeout = QFPROM_BLOW_TIMEOUT_US;
78 /* wait for 400us before checking for the first time */
79 udelay(400);
80 do {
81 *status = readl_relaxed(
82 qfp_priv->base + QFPROM_BLOW_STATUS_OFFSET);
83
84 if (!(*status & QFPROM_BLOW_STATUS_BUSY))
85 return 0;
86
87 timeout--;
88 udelay(1);
89 } while (timeout);
90 pr_err("Timeout waiting for FUSE blow, status = %x\n", *status);
91 return -ETIMEDOUT;
92}
93
94static inline int qfp_fuse_enable_regulator(void)
95{
96 int err;
97 err = regulator_enable(qfp_priv->fuse_vdd);
98 if (err != 0)
99 pr_err("Error (%d) enabling regulator\n", err);
100 return err;
101}
102
103static inline int qfp_fuse_disable_regulator(void)
104{
105 int err;
106 err = regulator_disable(qfp_priv->fuse_vdd);
107 if (err != 0)
108 pr_err("Error (%d) disabling regulator\n", err);
109 return err;
110}
111
112static int qfp_fuse_write_word(u32 *addr, u32 data)
113{
114 u32 blow_status = 0;
115 u32 read_data;
116 int err;
117
118 /* Set QFPROM blow timer register */
119 writel_relaxed(QFPROM_BLOW_TIMER_VALUE,
120 qfp_priv->base + QFPROM_BLOW_TIMER_OFFSET);
121 mb();
122
123 /* Enable LVS0 regulator */
124 err = qfp_fuse_enable_regulator();
125 if (err != 0)
126 return err;
127
128 /*
129 * Wait for about 1ms. However msleep(1) can sleep for
130 * up to 20ms as per Documentation/timers/timers-howto.txt.
131 * Time is not a constraint here.
132 */
133
134 msleep(20);
135
136 /* Write data */
137 __raw_writel(data, addr);
138 mb();
139
140 /* blow_status = QFPROM_BLOW_STATUS_BUSY; */
141 err = qfp_fuse_wait_for_fuse_blow(&blow_status);
142 if (err) {
143 qfp_fuse_disable_regulator();
144 return err;
145 }
146
147 /* Check error status */
148 if (blow_status & QFPROM_BLOW_STATUS_ERROR) {
149 pr_err("Fuse blow status error: %d\n", blow_status);
150 qfp_fuse_disable_regulator();
151 return -EFAULT;
152 }
153
154 /* Disable regulator */
155 qfp_fuse_disable_regulator();
156 /*
157 * Wait for about 1ms. However msleep(1) can sleep for
158 * up to 20ms as per Documentation/timers/timers-howto.txt.
159 * Time is not a constraint here.
160 */
161 msleep(20);
162
163 /* Verify written data */
164 read_data = readl_relaxed(addr);
165 if (read_data != data) {
166 pr_err("Error: read/write data mismatch\n");
167 pr_err("Address = %p written data = %x read data = %x\n",
168 addr, data, read_data);
169 return -EFAULT;
170 }
171
172 return 0;
173}
174
175static long
176qfp_fuse_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
177{
178 int err = 0;
179 struct qfp_fuse_req req;
180 u32 *buf = NULL;
181 int i;
182
183 /* Verify user arguments. */
184 if (_IOC_TYPE(cmd) != QFP_FUSE_IOC_MAGIC)
185 return -ENOTTY;
186
187 switch (cmd) {
188 case QFP_FUSE_IOC_READ:
189 if (arg == 0) {
190 pr_err("user space arg not supplied\n");
191 err = -EFAULT;
192 break;
193 }
194
195 if (copy_from_user(&req, (void __user *)arg, sizeof(req))) {
196 pr_err("Error copying req from user space\n");
197 err = -EFAULT;
198 break;
199 }
200
201 /* Check for limits */
202 if (!req.size) {
203 pr_err("Request size zero.\n");
204 err = -EFAULT;
205 break;
206 }
207
208 if (qfp_priv->base + req.offset + (req.size - 1) * 4 >
209 qfp_priv->end) {
210 pr_err("Req size exceeds QFPROM addr space\n");
211 err = -EFAULT;
212 break;
213 }
214
215 /* Allocate memory for buffer */
216 buf = kzalloc(req.size * 4, GFP_KERNEL);
217 if (buf == NULL) {
218 pr_alert("No memory for data\n");
219 err = -ENOMEM;
220 break;
221 }
222
223 if (mutex_lock_interruptible(&qfp_priv->lock)) {
224 err = -ERESTARTSYS;
225 break;
226 }
227
228 /* Read data */
229 for (i = 0; i < req.size; i++)
230 buf[i] = readl_relaxed(
231 ((u32 *) (qfp_priv->base + req.offset)) + i);
232
233 if (copy_to_user((void __user *)req.data, buf, 4*(req.size))) {
234 pr_err("Error copying to user space\n");
235 err = -EFAULT;
236 }
237
238 mutex_unlock(&qfp_priv->lock);
239 break;
240
241 case QFP_FUSE_IOC_WRITE:
242 if (arg == 0) {
243 pr_err("user space arg not supplied\n");
244 err = -EFAULT;
245 break;
246 }
247
248 if (copy_from_user(&req, (void __user *)arg, sizeof(req))) {
249 pr_err("Error copying req from user space\n");
250 err = -EFAULT;
251 break;
252 }
253 /* Check for limits */
254 if (!req.size) {
255 pr_err("Request size zero.\n");
256 err = -EFAULT;
257 break;
258 }
259 if (qfp_priv->base + req.offset + (req.size - 1) * 4 >
260 qfp_priv->end) {
261 pr_err("Req size exceeds QFPROM space\n");
262 err = -EFAULT;
263 break;
264 }
265
266 /* Allocate memory for buffer */
267 buf = kzalloc(4 * (req.size), GFP_KERNEL);
268 if (buf == NULL) {
269 pr_alert("No memory for data\n");
270 err = -ENOMEM;
271 break;
272 }
273
274 /* Copy user data to local buffer */
275 if (copy_from_user(buf, (void __user *)req.data,
276 4 * (req.size))) {
277 pr_err("Error copying data from user space\n");
278 err = -EFAULT;
279 break;
280 }
281
282 if (mutex_lock_interruptible(&qfp_priv->lock)) {
283 err = -ERESTARTSYS;
284 break;
285 }
286
287 /* Write data word at a time */
288 for (i = 0; i < req.size && !err; i++) {
289 err = qfp_fuse_write_word(((u32 *) (
290 qfp_priv->base + req.offset) + i), buf[i]);
291 }
292
293 mutex_unlock(&qfp_priv->lock);
294 break;
295 default:
296 pr_err("Invalid ioctl command.\n");
297 return -ENOTTY;
298 }
299 kfree(buf);
300 return err;
301}
302
303static const struct file_operations qfp_fuse_fops = {
304 .owner = THIS_MODULE,
305 .unlocked_ioctl = qfp_fuse_ioctl,
306 .open = qfp_fuse_open,
307 .release = qfp_fuse_release
308};
309
310static struct miscdevice qfp_fuse_dev = {
311 .minor = MISC_DYNAMIC_MINOR,
312 .name = "qfpfuse",
313 .fops = &qfp_fuse_fops
314};
315
316
317static int qfp_fuse_probe(struct platform_device *pdev)
318{
319 int ret = 0;
320 struct resource *res;
321 const char *regulator_name = pdev->dev.platform_data;
322
323
324 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
325 if (!res)
326 return -ENODEV;
327
328 if (!regulator_name)
329 return -EINVAL;
330
331 /* Initialize */
332 qfp_priv = kzalloc(sizeof(struct qfp_priv_t), GFP_KERNEL);
333
334 if (qfp_priv == NULL) {
335 pr_alert("Not enough memory to initialize device\n");
336 return -ENOMEM;
337 }
338
339 /* The driver is passed ioremapped address */
340 qfp_priv->base = res->start;
341 qfp_priv->end = res->end;
342
343 /* Get regulator for QFPROM writes */
344 qfp_priv->fuse_vdd = regulator_get(NULL, regulator_name);
345 if (IS_ERR(qfp_priv->fuse_vdd)) {
346 ret = PTR_ERR(qfp_priv->fuse_vdd);
347 pr_err("Err (%d) getting %s\n", ret, regulator_name);
348 qfp_priv->fuse_vdd = NULL;
349 goto err;
350 }
351
352 mutex_init(&qfp_priv->lock);
353
354 ret = misc_register(&qfp_fuse_dev);
355 if (ret < 0)
356 goto err;
357
358 pr_info("Fuse driver base:%x end:%x\n", qfp_priv->base, qfp_priv->end);
359 return 0;
360
361err:
362 if (qfp_priv->fuse_vdd)
363 regulator_put(qfp_priv->fuse_vdd);
364
365 kfree(qfp_priv);
366 qfp_priv = NULL;
367
368 return ret;
369
370}
371
372static int __devexit qfp_fuse_remove(struct platform_device *plat)
373{
374 if (qfp_priv && qfp_priv->fuse_vdd)
375 regulator_put(qfp_priv->fuse_vdd);
376
377 kfree(qfp_priv);
378 qfp_priv = NULL;
379
380 misc_deregister(&qfp_fuse_dev);
381 pr_info("Removing Fuse driver\n");
382 return 0;
383}
384
385static struct platform_driver qfp_fuse_driver = {
386 .probe = qfp_fuse_probe,
387 .remove = qfp_fuse_remove,
388 .driver = {
389 .name = "qfp_fuse_driver",
390 .owner = THIS_MODULE,
391 },
392};
393
394static int __init qfp_fuse_init(void)
395{
396 return platform_driver_register(&qfp_fuse_driver);
397}
398
399static void __exit qfp_fuse_exit(void)
400{
401 platform_driver_unregister(&qfp_fuse_driver);
402}
403
404MODULE_LICENSE("GPL v2");
405MODULE_AUTHOR("Rohit Vaswani <rvaswani@codeaurora.org>");
406MODULE_DESCRIPTION("Driver to read/write to QFPROM fuses.");
407MODULE_VERSION("1.01");
408
409module_init(qfp_fuse_init);
410module_exit(qfp_fuse_exit);