misc:cryptodev: fix null_check coverity issue
[linux-3.10.git] / drivers / misc / tegra_cpc.c
1 /*
2  * tegra_cpc.c - Access CPC storage blocks through i2c bus
3  *
4  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  */
20 #include <linux/module.h>
21 #include <linux/regmap.h>
22 #include <linux/io.h>
23 #include <linux/uaccess.h>
24 #include <linux/slab.h>
25 #include <linux/irq.h>
26 #include <linux/interrupt.h>
27 #include <linux/completion.h>
28
29 /* misc device */
30 #include <linux/fs.h>
31 #include <linux/miscdevice.h>
32 #include <linux/i2c.h>
33 #include <asm/unaligned.h>
34 #include <linux/ioctl.h>
35 #include <linux/types.h>
36 #include <linux/tegra_cpc.h>
37
38 /* local data structures */
39 struct cpc_i2c_host {
40         struct i2c_client *i2c_client;
41         struct regmap *regmap;
42         struct i2c_msg readback;
43
44         int irq;
45         struct mutex lock;
46         struct completion complete;
47 };
48
49 static atomic_t cpc_in_use;
50 static struct cpc_i2c_host *cpc_host;
51
52 static int cpc_read_data(struct i2c_client *client, u8 cmd,
53                                         void *data, u16 length)
54 {
55         int err;
56         struct i2c_msg msg[2];
57
58         if (!client->adapter)
59                 return -ENODEV;
60
61         /*
62            First put header of CPC read command. Start with the write mode flag,
63            to communicate which command we are sending. Then read the response
64            on the bus
65         */
66         msg[0].addr = client->addr;
67         msg[0].flags = 0;
68         msg[0].len = 1;
69         msg[0].buf = &cmd;
70
71         msg[1].addr = client->addr;
72         msg[1].flags = I2C_M_RD;
73         msg[1].len = length;
74         msg[1].buf = data;
75
76
77         err = i2c_transfer(client->adapter, msg, 2);
78         if (err != 2) {
79                 pr_warn("%s: i2c transfer failed\n", __func__);
80                 return -EINVAL;
81         }
82
83         return 0;
84 }
85
86 static int cpc_write_data(struct i2c_client *client, u8 cmd,
87                                 void *data, u8 length, void *hmac)
88 {
89         int err;
90         struct i2c_msg msg[4];
91         u8 command = cmd;
92
93         if (!client->adapter)
94                 return -ENODEV;
95
96         /* first put header of CPC write command */
97         msg[0].addr = client->addr;
98         msg[0].flags = 0;
99         msg[0].len = 1;
100         msg[0].buf = &command;
101
102         msg[1].addr = client->addr;
103         msg[1].flags = 0;
104         msg[1].len = sizeof(length);
105         msg[1].buf = &length;
106
107         msg[2].addr = client->addr;
108         msg[2].flags = 0;
109         msg[2].len = length;
110         msg[2].buf = data;
111
112         msg[3].addr = client->addr;
113         msg[3].flags = 0;
114         msg[3].len = CPC_HMAC_SIZE;
115         msg[3].buf = hmac;
116
117
118         err = i2c_transfer(client->adapter, msg, 4);
119         if (err != 4) {
120                 pr_err("cpc: i2c transfer failed, for cmd %x\n", cmd);
121                 return -EINVAL;
122         }
123
124         return err;
125 }
126
127 static int cpc_write_key(struct i2c_client *client, u8 cmd,
128                                                 void *hmac, u8 length)
129 {
130         int err;
131         struct i2c_msg msg[2];
132         u8 command = cmd;
133
134         if (!client->adapter)
135                 return -ENODEV;
136
137         /* first put header of CPC write command */
138         msg[0].addr = client->addr;
139         msg[0].flags = 0;
140         msg[0].len = 1;
141         msg[0].buf = &command;
142
143         msg[1].addr = client->addr;
144         msg[1].flags = 0;
145         msg[1].len = length;
146         msg[1].buf = hmac;
147
148         err = i2c_transfer(client->adapter, msg, 2);
149         if (err != 2) {
150                 pr_err("cpc: i2c transfer failed, for cmd %x\n", cmd);
151                 return -EINVAL;
152         }
153
154         return err;
155 }
156
157 static void _cpc_do_data(struct cpc_i2c_host *cpc, struct cpc_frame_t *fr)
158 {
159         __u32 write_counter = 0;
160         u8 status = 0;
161
162         mutex_lock(&cpc->lock);
163         switch (fr->req_or_resp) {
164         case CPC_READ_M_COUNT:
165                 /* mcounter size = 4 */
166                 cpc_read_data(cpc->i2c_client, fr->req_or_resp,
167                                                 &write_counter, 4);
168                 fr->write_counter = write_counter;
169
170                 cpc_read_data(cpc->i2c_client, CPC_GET_RESULT, &status, 1);
171                 fr->result = status;
172                 break;
173
174         case CPC_READ_FRAME:
175                 cpc_read_data(cpc->i2c_client, fr->req_or_resp,
176                                 fr->data, fr->len);
177
178                 cpc_read_data(cpc->i2c_client, CPC_GET_RESULT, &status, 1);
179                 fr->result = status;
180                 break;
181
182         case CPC_WRITE_FRAME:
183                 init_completion(&cpc->complete);
184                 cpc_write_data(cpc->i2c_client, fr->req_or_resp, fr->data,
185                                 fr->len, fr->hmac);
186
187                 if (!wait_for_completion_timeout(&cpc->complete,
188                                                 msecs_to_jiffies(200))) {
189                         pr_err("%s timeout on write complete\n", __func__);
190                         fr->result = CPC_WR_FAIL;
191                         /*
192                            TODO: break
193                          */
194                 }
195
196                 cpc_read_data(cpc->i2c_client, CPC_GET_RESULT, &status, 1);
197                 fr->result = status;
198                 break;
199
200         case CPC_PROGRAM_KEY:
201                 init_completion(&cpc->complete);
202                 cpc_write_key(cpc->i2c_client, fr->req_or_resp,
203                                                 fr->hmac, CPC_HMAC_SIZE);
204
205                 if (!wait_for_completion_timeout(&cpc->complete,
206                                                 msecs_to_jiffies(200))) {
207                         pr_err("%s timeout on write complete\n", __func__);
208                         fr->result = CPC_KEY_FAIL;
209                         /*
210                            TODO: break
211                          */
212                 }
213
214                 cpc_read_data(cpc->i2c_client, CPC_GET_RESULT, &status, 1);
215                 fr->result = status;
216                 break;
217
218         default:
219                 pr_warn("unsupported CPC command\n");
220         }
221         fr->req_or_resp = fr->req_or_resp<<8;
222         mutex_unlock(&cpc->lock);
223 }
224
225 static irqreturn_t cpc_irq(int irq, void *data)
226 {
227         struct cpc_i2c_host *cpc = data;
228
229         complete(&cpc->complete);
230         return IRQ_HANDLED;
231 }
232
233 static int cpc_open(struct inode *inode, struct file *filp)
234 {
235         if (atomic_xchg(&cpc_in_use, 1))
236                 return -EBUSY;
237
238         if (!cpc_host) {
239                 pr_info("CPC is not ready\n");
240                 return -EBADF;
241         }
242
243         filp->private_data = cpc_host;
244
245         return nonseekable_open(inode, filp);
246 }
247
248 static int cpc_release(struct inode *inode, struct file *filp)
249 {
250         WARN_ON(!atomic_xchg(&cpc_in_use, 0));
251         return 0;
252 }
253
254 static long cpc_ioctl(struct file *file,
255                         unsigned int cmd, unsigned long arg)
256 {
257         struct cpc_i2c_host *cpc = file->private_data;
258         struct cpc_frame_t *cpc_fr;
259
260         if (_IOC_TYPE(cmd) != NVCPC_IOC_MAGIC)
261                 return -ENOTTY;
262
263         if (_IOC_NR(cmd) > NVCPC_IOCTL_DO_IO)
264                 return -ENOTTY;
265
266         switch (cmd) {
267         case NVCPC_IOCTL_DO_IO:
268                 cpc_fr = kmalloc(sizeof(struct cpc_frame_t), GFP_KERNEL);
269                 if (cpc_fr == NULL) {
270                         pr_err("%s: failed to allocate mem\n", __func__);
271                         return -ENOMEM;
272                 }
273
274                 if (copy_from_user(cpc_fr, (const void __user *)arg,
275                                         sizeof(struct cpc_frame_t))) {
276                         kfree(cpc_fr);
277                         return -EFAULT;
278                 }
279
280                 _cpc_do_data(cpc, cpc_fr);
281
282                 if (copy_to_user((void __user *)arg, cpc_fr,
283                                         sizeof(struct cpc_frame_t))) {
284                         kfree(cpc_fr);
285                         return -EFAULT;
286                 }
287                 kfree(cpc_fr);
288                 break;
289         default:
290                 pr_err("CPC: unsupported ioctl\n");
291                 return -EINVAL;
292         }
293
294         return 0;
295 }
296
297 static const struct file_operations cpc_dev_fops = {
298         .owner = THIS_MODULE,
299         .open = cpc_open,
300         .release = cpc_release,
301         .unlocked_ioctl = cpc_ioctl,
302 #ifdef CONFIG_COMPAT
303         .compat_ioctl = cpc_ioctl,
304 #endif
305 };
306
307 static struct miscdevice cpc_dev = {
308         .minor = MISC_DYNAMIC_MINOR,
309         .name = "tegra_cpc",
310         .fops = &cpc_dev_fops,
311 };
312
313 static int cpc_i2c_probe(struct i2c_client *client,
314                         const struct i2c_device_id *id)
315 {
316         int status;
317
318         cpc_host = kzalloc(sizeof(struct cpc_i2c_host), GFP_KERNEL);
319         if (!cpc_host) {
320                 pr_err("unable to allocate memory\n");
321                 return -ENOMEM;
322         }
323
324         cpc_host->i2c_client = client;
325         i2c_set_clientdata(client, cpc_host);
326         cpc_host->irq = client->irq;
327         mutex_init(&cpc_host->lock);
328
329         status = request_threaded_irq(cpc_host->irq, cpc_irq, NULL,
330                                 IRQF_TRIGGER_RISING, "cpc_irq", cpc_host);
331         if (status) {
332                 pr_err("%s: request irq failed %d\n", __func__, status);
333                 goto fail;
334         }
335
336         /* TODO: check for CP DRM controller status. Make sure it's ready
337          */
338
339         /* setup misc device for userspace io*/
340         if (misc_register(&cpc_dev)) {
341                 pr_err("%s: misc device register failed\n", __func__);
342                 status = -ENOMEM;
343                 goto fail;
344         }
345
346         dev_info(&client->dev, "host driver for CPC\n");
347         return 0;
348 fail:
349         dev_set_drvdata(&client->dev, NULL);
350         mutex_destroy(&cpc_host->lock);
351         kfree(cpc_host);
352         return status;
353 }
354
355 static int cpc_i2c_remove(struct i2c_client *client)
356 {
357         struct cpc_i2c_host *cpc_host = dev_get_drvdata(&client->dev);
358
359         mutex_destroy(&cpc_host->lock);
360         kfree(cpc_host);
361         cpc_host = NULL;
362         return 0;
363 }
364
365 static struct of_device_id cpc_i2c_of_match_table[] = {
366         { .compatible = "nvidia,cpc", },
367         {},
368 };
369
370 static const struct i2c_device_id cpc_i2c_id[] = {
371         { "cpc", 0 },
372         { }
373 };
374 MODULE_DEVICE_TABLE(i2c, mmc_i2c_id);
375
376 static struct i2c_driver cpc_i2c_driver = {
377         .driver = {
378                 .name = "cpc",
379                 .owner = THIS_MODULE,
380                 .of_match_table = cpc_i2c_of_match_table,
381         },
382         .probe = cpc_i2c_probe,
383         .remove = cpc_i2c_remove,
384         .id_table = cpc_i2c_id,
385 };
386
387 module_i2c_driver(cpc_i2c_driver);
388
389 MODULE_AUTHOR("Vinayak Pane");
390 MODULE_DESCRIPTION("Content protection misc driver");
391 MODULE_LICENSE("GPL v2");
392 MODULE_ALIAS("i2c:cpc_i2c");