2 * sprd trusted key storage driver
6 * This driver is for ali trusted key storage
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/delay.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/errno.h>
29 #include <linux/init.h>
30 #include <linux/ion.h>
31 #include <linux/ioport.h>
32 #include <linux/jiffies.h>
33 #include <linux/miscdevice.h>
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/platform_device.h>
37 #include <linux/string.h>
38 #include <linux/timer.h>
39 #include <linux/types.h>
40 #include <linux/uaccess.h>
41 #include <soc/sprd/sci.h>
42 #include <uapi/linux/sprd_tks.h>
45 #include <linux/of_address.h>
46 #include <linux/of_device.h>
49 #define TSP_TKS_SHM_REQ_ADDR 0x2005
50 #define TSP_TKS 0x2010
52 /*from arm trusted firmware */
53 #define TSP_STD_FID(fid) ((fid) | 0x72000000 | (0 << 31))
54 #define TSP_FAST_FID(fid) ((fid) | 0x72000000 | (1 << 31))
56 /*c6e7c860-9299-455c-b5eb-68686d2c739c*/
57 #define SEC_SHAREMEM_MAX_SIZE 4096
59 #define TKS_KEY_LEN(p) (sizeof(enum key_type)+sizeof(int)+(p)->keylen)
60 #define PACK_DATA_LEN(p) (sizeof(int)+(p)->len)
62 #define KEYLEN_OFF (offsetof(struct tks_key_cal, keylen))
63 #define DATA_OFF (offsetof(struct tks_key_cal, keydata))
64 /*#define GEN_KEYPARI_LEN(p) (TKS_KEY_LEN(&((p)->rsaprv)) + \
65 TKS_KEY_LEN((&(p)->out_rsapub)))
66 #define DEC_SIMPLE_LEN(p) (TKS_KEY_LEN(&((p)->encryptkey)) + \
67 PACK_DATA_LEN(&((p)->data)))*/
69 #define SHM_SIZE (4096ul)
70 #define ERRNO_BASE (1000)
71 #define ARM7_CFG_BUS_OFFSET (0x0124)
72 #define SLEEP_STATUS_OFFSET (0x00d4)
73 #define SLEEP_STATUS_MASK (0xf << 20)
74 #define SLEEP_STATUS_VAL (0x6 << 20)
76 static unsigned long *shm_vaddr;
77 static dma_addr_t phy_addr;
78 static ulong arm7_cfg_bus;
79 static ulong sleep_status;
80 static ulong reg_val = 0;
82 __packed struct shm_mem_view {
84 u8 cmd_data[SEC_SHAREMEM_MAX_SIZE-sizeof(u32)];
88 static inline void readbyte(unsigned long addr, void *buffer, int count)
92 *buf++ = __raw_readb((void __iomem *)addr++);
95 static inline void writebyte(unsigned long addr, const void *buffer, int count)
97 const u8 *buf = buffer;
99 __raw_writeb(*buf++, (void __iomem *)addr++);
102 static noinline int __invoke_tks_fn_smc(u64 function_id, u64 arg0, u64 arg1,
112 : "r" (arg0), "r" (arg1), "r" (arg2));
118 static int (*invoke_tks_fn)(u64, u64, u64, u64);
120 static int wake_secure_ap(void)
125 reg_val = sci_glb_read(arm7_cfg_bus, 0x1);
126 sci_glb_clr(arm7_cfg_bus, BIT(0));
128 state = sci_glb_read(sleep_status, SLEEP_STATUS_MASK);
129 if (state == SLEEP_STATUS_VAL)
134 pr_info("%s secure ap awake!", __func__);
139 static int resume_bus_status(void)
141 return sci_glb_write(arm7_cfg_bus, reg_val, 0x1);
144 static int invoke_tks_fn_awake(u64 func_id, u64 arg0, u64 arg1, u64 arg2)
147 invoke_tks_fn(func_id, arg0, arg1, arg2);
153 /* filesystem operations */
154 static int sprd_tks_open(struct inode *inode, struct file *file)
157 return nonseekable_open(inode, file);
160 static int sprd_tks_release(struct inode *inode, struct file *file)
165 static long sprd_tks_ioctl(struct file *file, unsigned int cmd,
168 struct shm_mem_view *buf;
169 unsigned char *databuf;
172 unsigned char * __user userdata;
174 unsigned char *bakloc1;
176 void __user *argp = (void *)arg;
178 buf = (struct shm_mem_view *)shm_vaddr;
181 case SEC_IOC_GEN_KEYPAIR:
182 buf->cmd = _IOC_NR(SEC_IOC_GEN_KEYPAIR);
183 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
184 SEC_IOC_GEN_KEYPAIR, 0, 0);
185 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
186 SEC_IOC_GEN_KEYPAIR, 0, 0);
188 return -(ERRNO_BASE + buf->cmd);
189 databuf = buf->cmd_data;
190 readbyte((unsigned long)(databuf + KEYLEN_OFF),
191 &keylen, sizeof(keylen)); /*get rsaprv*/
192 pr_info("%s:%d:databuf=0x%p,argp=0x%p, len1= 0x%x \n",
193 __func__, __LINE__, databuf, argp, keylen);
194 if (unlikely(keylen >= SHM_SIZE)) {
195 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
196 __func__, __LINE__, keylen);
199 if (!access_ok(VERIFY_WRITE, argp, DATA_OFF + keylen))
201 /*can not use copy_to_user ,bc .
202 the 8 alignment fault.do it in byte copy.*/
203 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
204 ret = put_user(*((char *)databuf + cnt),
210 databuf += (DATA_OFF + keylen);
211 argp += offsetof(struct request_gen_keypair, out_rsapub);
212 /*bc. this is maybe not a alignment addr, so use byteget
213 method to get keylen.*/
214 readbyte((unsigned long)(databuf + KEYLEN_OFF),
215 &keylen, sizeof(keylen));
216 pr_info("%s:%d:databuf=0x%p,argp=0x%p, len1= 0x%x \n",
217 __func__, __LINE__, databuf, argp, keylen);
218 if (unlikely(keylen >= SHM_SIZE)) {
219 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
220 __func__, __LINE__, keylen);
223 if (!access_ok(VERIFY_WRITE, argp, DATA_OFF + keylen))
225 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
226 ret = put_user(*((char *)databuf + cnt),
232 case SEC_IOC_DEC_SIMPLE:
233 buf->cmd = _IOC_NR(SEC_IOC_DEC_SIMPLE);
234 databuf = buf->cmd_data;
236 ret = get_user(keylen,
237 &(((struct request_dec_simple *)argp)->encryptkey.keylen));
240 if (unlikely(keylen >= SHM_SIZE)) {
241 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
242 __func__, __LINE__, keylen);
245 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
246 ret = get_user(databuf[cnt], (char *)argp + cnt);
250 /*updata databuf pto pack_data*/
252 /*get keylen form user space.*/
253 ret = get_user(keylen,
254 &(((struct request_dec_simple *)argp)->data.len));
257 if (unlikely(keylen >= SHM_SIZE)) {
258 pr_err("%s %d:tks keylen=0x%x out of range.\n",
259 __func__, __LINE__, keylen);
262 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
263 databuf += sizeof(keylen);
264 /*get data pto usermemmory form userspace.*/
265 ret = get_user(userdata,
266 &(((struct request_dec_simple *)argp)->data.data));
269 for (cnt = 0; cnt < keylen; cnt++) {
270 ret = get_user(databuf[cnt], userdata + cnt);
274 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
275 SEC_IOC_DEC_SIMPLE, 0, 0);
277 return -(ERRNO_BASE + buf->cmd);
278 /*rollback tothe shm packdata locate.*/
279 databuf -= sizeof(keylen);
280 userdata = (unsigned char * __user)
281 (&(((struct request_dec_simple *)argp)->data.len));
282 readbyte((unsigned long)databuf, &keylen, sizeof(keylen));
283 if (unlikely(keylen >= SHM_SIZE)) {
284 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
285 __func__, __LINE__, keylen);
288 for (cnt = 0; cnt < sizeof(keylen); cnt++) {
289 ret = put_user(databuf[cnt], userdata + cnt);
293 databuf += sizeof(keylen);
294 /*get packdata.data ,the user space memmory heap*/
295 /*userdata = ((struct request_dec_simple*)argp)->data.data*/
296 ret = get_user(userdata,
297 &(((struct request_dec_simple *)argp)->data.data));
300 for (cnt = 0; cnt < keylen; cnt++) {
301 ret = put_user(databuf[cnt], userdata + cnt);
306 case SEC_IOC_DEC_PACK_USERPASS:
307 buf->cmd = _IOC_NR(SEC_IOC_DEC_PACK_USERPASS);
308 databuf = buf->cmd_data;
309 /*write shm the endryptkey from user space.
310 get keylen from user*/
311 ret = get_user(keylen,
313 ((struct request_dec_pack_userpass *)argp)->encryptkey.keylen
317 if (unlikely(keylen >= SHM_SIZE)) {
318 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
319 __func__, __LINE__, keylen);
322 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
323 ret = get_user(databuf[cnt], (char *)argp + cnt);
327 /*write shm the userpasskey from user space.*/
329 /*updata userdata pos.*/
330 userdata = (unsigned char * __user)
331 (&(((struct request_dec_pack_userpass *)argp)->userpass));
332 /*get keylen from user*/
333 ret = get_user(keylen,
334 &(((struct request_dec_pack_userpass *)argp)->userpass.keylen));
337 if (unlikely(keylen >= SHM_SIZE)) {
338 pr_err("%s %d:tks keylen=0x%x out of range.\n",
339 __func__, __LINE__, keylen);
342 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
343 ret = get_user(databuf[cnt], (char *)userdata + cnt);
347 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
348 SEC_IOC_DEC_PACK_USERPASS, 0, 0);
350 return -(ERRNO_BASE + buf->cmd);
351 /*databuf is remained; userdata is remianed*/
352 readbyte((unsigned long)(databuf + KEYLEN_OFF),
353 &keylen, sizeof(keylen));
354 if (unlikely(keylen >= SHM_SIZE)) {
355 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
356 __func__, __LINE__, keylen);
359 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
360 ret = put_user(*((char *)databuf + cnt),
361 (char *)userdata + cnt);
367 buf->cmd = _IOC_NR(SEC_IOC_CRYPTO);
368 databuf = buf->cmd_data;
369 ret = get_user(op, (char *)argp); /*write op*/
370 writebyte((unsigned long)databuf, &op, sizeof(op));
371 /*write shm the endryptkey from user space.*/
372 /*keylen = ((struct request_crypto*)argp)->encryptkey.keylen;*/
373 ret = get_user(keylen,
374 &(((struct request_crypto *)argp)->encryptkey.keylen));
377 if (unlikely(keylen >= SHM_SIZE)) {
378 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
379 __func__, __LINE__, keylen);
382 /*updata databuf,userdata.*/
383 databuf += sizeof(op);
384 userdata = (char *)argp
385 + offsetof(struct request_crypto, encryptkey);
386 /*write encryptkey to shm.*/
387 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
388 ret = get_user(databuf[cnt], (char *)userdata + cnt);
392 /*write shm the userpasskey from user space.*/
393 databuf += cnt; /*updata the databuf pos.*/
394 /*updata userdata pos.*/
395 userdata = (char *)argp +
396 offsetof(struct request_crypto, userpass);
397 ret = get_user(keylen,
398 &(((struct request_crypto *)argp)->userpass.keylen));
401 if (unlikely(keylen >= SHM_SIZE)) {
402 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
403 __func__, __LINE__, keylen);
406 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
407 ret = get_user(databuf[cnt], (char *)userdata + cnt);
411 /*packdata write to shm*/
412 databuf += cnt; /*updata the databuf pos.*/
413 bakloc1 = databuf;/*backup the pointer locate of the packdata*/
414 userdata = (char *)argp +
415 offsetof(struct request_crypto, data);
416 ret = get_user(keylen,
417 &(((struct request_crypto *)argp)->data.len));
420 if (unlikely(keylen >= SHM_SIZE)) {
421 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
422 __func__, __LINE__, keylen);
425 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
426 databuf += sizeof(keylen);
427 ret = get_user(userdata,
428 &(((struct request_crypto *)argp)->data.data));
431 for (cnt = 0; cnt < keylen; cnt++) {
432 ret = get_user(databuf[cnt], (char *)userdata + cnt);
437 if (op == 1) { /*0=SIGN,1=VERIFY,2=ENC,3=DEC; [in]*/
438 /*write the signature to shm*/
439 databuf += cnt; /*updata the databuf pos.*/
440 /*updata userdata pos.*/
441 userdata = (char *)argp +
442 offsetof(struct request_crypto, signature);
443 ret = get_user(keylen,
444 &(((struct request_crypto *)argp)->signature.len));
447 if (unlikely(keylen >= SHM_SIZE)) {
448 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
449 __func__, __LINE__, keylen);
452 writebyte((unsigned long)databuf, &keylen,
455 databuf += sizeof(keylen);
456 ret = get_user(userdata,
457 &(((struct request_crypto *)argp)->signature.data));
460 for (cnt = 0; cnt < keylen; cnt++) {
461 ret = get_user(databuf[cnt],
462 (char *)userdata + cnt);
467 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
468 SEC_IOC_CRYPTO, 0, 0);
470 return -(ERRNO_BASE + buf->cmd);
471 /* copy pack_data form shm to user space.*/
472 databuf = bakloc1; /*the shm packdata locate.*/
473 /*updata userdata pos.*/
474 userdata = (char *)argp + offsetof(struct request_crypto, data);
475 readbyte((unsigned long)databuf, &keylen, sizeof(keylen));
476 if (unlikely(keylen >= SHM_SIZE)) {
477 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
478 __func__, __LINE__, keylen);
481 for (cnt = 0; cnt < sizeof(keylen); cnt++) {
482 ret = put_user(databuf[cnt], userdata + cnt);
486 databuf += sizeof(keylen);
487 ret = get_user(userdata,
488 &(((struct request_crypto *)argp)->data.data));
491 for (cnt = 0; cnt < keylen; cnt++) {
492 ret = put_user(databuf[cnt], userdata + cnt);
497 case SEC_IOC_GEN_DHKEY:
498 buf->cmd = _IOC_NR(SEC_IOC_GEN_DHKEY);
499 databuf = buf->cmd_data;
500 /*write user space encryptkey to shm*/
501 ret = get_user(keylen,
502 &(((struct request_gen_dhkey *)argp)->encryptkey.keylen));
505 if (unlikely(keylen >= SHM_SIZE)) {
506 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
507 __func__, __LINE__, keylen);
510 for (cnt = 0; cnt < (keylen + DATA_OFF); cnt++) {
511 ret = get_user(databuf[cnt], (char *)argp + cnt);
517 userdata = (char *)argp +
518 offsetof(struct request_gen_dhkey, param) +
519 offsetof(struct dh_param, a);/*big_int a*/
520 ret = get_user(keylen,
521 &(((struct request_gen_dhkey *)argp)->param.a.len));
524 if (unlikely(keylen >= SHM_SIZE)) {
525 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
526 __func__, __LINE__, keylen);
529 /*write bit_int a keylen*/
530 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
531 databuf += sizeof(keylen);
532 ret = get_user(userdata,
533 &(((struct request_gen_dhkey *)argp)->param.a.data));
536 for (cnt = 0; cnt < keylen; cnt++) {
537 ret = get_user(databuf[cnt], (char *)userdata + cnt);
543 userdata = (char *)argp +
544 offsetof(struct request_gen_dhkey, param) +
545 offsetof(struct dh_param, g); /*big_int g*/
546 ret = get_user(keylen,
547 &(((struct request_gen_dhkey *)argp)->param.g.len));
550 if (unlikely(keylen >= SHM_SIZE)) {
551 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
552 __func__, __LINE__, keylen);
555 /*write bit_int a keylen*/
556 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
557 databuf += sizeof(keylen);
558 ret = get_user(userdata,
559 &(((struct request_gen_dhkey *)argp)->param.g.data));
562 for (cnt = 0; cnt < keylen; cnt++) {
563 ret = get_user(databuf[cnt], (char *)userdata + cnt);
569 userdata = (char *)argp +
570 offsetof(struct request_gen_dhkey, param) +
571 offsetof(struct dh_param, p); /*big_int g*/
572 ret = get_user(keylen,
573 &(((struct request_gen_dhkey *)argp)->param.p.len));
576 if (unlikely(keylen >= SHM_SIZE)) {
577 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
578 __func__, __LINE__, keylen);
581 /*write bit_int a keylen*/
582 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
583 databuf += sizeof(keylen);
584 ret = get_user(userdata,
585 &(((struct request_gen_dhkey *)argp)->param.p.data));
588 for (cnt = 0; cnt < keylen; cnt++) {
589 ret = get_user(databuf[cnt], (char *)userdata + cnt);
594 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
595 SEC_IOC_GEN_DHKEY, 0, 0);
597 return -(ERRNO_BASE + buf->cmd);
599 userdata = (char *)argp +
600 offsetof(struct request_gen_dhkey, b);
601 readbyte((unsigned long)databuf, &keylen, sizeof(keylen));
602 if (unlikely(keylen >= SHM_SIZE)) {
603 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
604 __func__, __LINE__, keylen);
607 for (cnt = 0; cnt < sizeof(keylen); cnt++) {
608 ret = put_user(databuf[cnt], userdata + cnt);
612 databuf += sizeof(keylen);
613 ret = get_user(userdata,
614 &(((struct request_gen_dhkey *)argp)->b.data));
617 for (cnt = 0; cnt < keylen; cnt++) {
618 ret = put_user(databuf[cnt], userdata + cnt);
624 userdata = (char *)argp + offsetof(struct request_gen_dhkey, k);
625 readbyte((unsigned long)databuf, &keylen, sizeof(keylen));
626 if (unlikely(keylen >= SHM_SIZE)) {
627 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
628 __func__, __LINE__, keylen);
631 for (cnt = 0; cnt < sizeof(keylen); cnt++) {
632 ret = put_user(databuf[cnt], userdata + cnt);
636 databuf += sizeof(keylen);
637 ret = get_user(userdata,
638 &(((struct request_gen_dhkey *)argp)->k.data));
641 for (cnt = 0; cnt < keylen; cnt++) {
642 ret = put_user(databuf[cnt], userdata + cnt);
648 buf->cmd = _IOC_NR(SEC_IOC_HMAC);
649 databuf = buf->cmd_data;
650 ret = get_user(keylen,
651 &(((struct request_hmac *)argp)->message.len));
654 if (unlikely(keylen >= SHM_SIZE)) {
655 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
656 __func__, __LINE__, keylen);
659 writebyte((unsigned long)databuf, &keylen, sizeof(keylen));
660 databuf += sizeof(keylen);
661 ret = get_user(userdata,
662 &(((struct request_hmac *)argp)->message.data));
665 for (cnt = 0; cnt < keylen; cnt++) {
666 ret = get_user(databuf[cnt], userdata + cnt);
670 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS)),
673 return -(ERRNO_BASE + buf->cmd);
674 databuf = buf->cmd_data;
675 userdata = (char *)argp;
676 readbyte((unsigned long)databuf, &keylen, sizeof(keylen));
677 if (unlikely(keylen >= SHM_SIZE)) {
678 pr_err("%s:%d:tks keylen=0x%x out of range.\n",
679 __func__, __LINE__, keylen);
682 for (cnt = 0; cnt < sizeof(keylen); cnt++) {
683 ret = put_user(databuf[cnt], userdata + cnt);
687 databuf += sizeof(keylen);
688 ret = get_user(userdata,
689 &(((struct request_hmac *)argp)->message.data));
692 for (cnt = 0; cnt < keylen; cnt++) {
693 ret = put_user(databuf[cnt], userdata + cnt);
698 case SEC_IDC_TEST_USED:
699 ret = copy_from_user(buf, argp, sizeof(struct shm_mem_view));
709 static ssize_t sprd_tks_write(struct file *file, const char __user *buf,
710 size_t count, loff_t *ppos)
715 static void get_cfg_addr(void)
717 struct device_node *np;
720 np = of_find_compatible_node(NULL, NULL, "sprd,aon_apb");
722 pr_err("sprd_tks_init: get aon_apb node failed!\n");
723 of_address_to_resource(np, 0, &res);
724 arm7_cfg_bus = (unsigned long)ioremap_nocache(res.start
725 + ARM7_CFG_BUS_OFFSET, 0x4);
726 np = of_find_compatible_node(NULL, NULL, "sprd,pmu_apb");
728 pr_err("sprd_tks_init: get pmu_apb node failed!\n");
729 of_address_to_resource(np, 0, &res);
730 sleep_status = (unsigned long)ioremap_nocache(res.start
731 + SLEEP_STATUS_OFFSET, 0x4);
734 static const struct file_operations sprd_tks_fops = {
735 .owner = THIS_MODULE,
737 .unlocked_ioctl = sprd_tks_ioctl,
738 .open = sprd_tks_open,
739 .write = sprd_tks_write,
740 .release = sprd_tks_release,
743 static struct miscdevice sprd_tks_miscdev = {
744 .minor = MISC_DYNAMIC_MINOR,
746 .fops = &sprd_tks_fops,
749 static int __init sprd_tks_init(void)
754 ret = misc_register(&sprd_tks_miscdev);
756 dev_err(sprd_tks_miscdev.this_device, "sprd tks reg error\n");
757 invoke_tks_fn = __invoke_tks_fn_smc;
758 shm_vaddr = dma_alloc_coherent(sprd_tks_miscdev.this_device, SHM_SIZE,
759 &phy_addr, GFP_KERNEL);
761 dev_err(sprd_tks_miscdev.this_device, "shm_vaddr failure\n");
764 memset(shm_vaddr, 0, SHM_SIZE);
765 /* the first argument of invoke_tks_fn_awake is the case that used to
766 initialize the share memory.*/
767 invoke_tks_fn_awake((TSP_FAST_FID(TSP_TKS_SHM_REQ_ADDR)),
769 pr_info("%s:shm_vaddr:%p, phy_addr:0x%lx\n",
770 __func__, shm_vaddr, (ulong)phy_addr);
775 static void __exit sprd_tks_exit(void)
777 dev_info(sprd_tks_miscdev.this_device, "sprd tks driver eixt!\n");
778 dma_free_coherent(sprd_tks_miscdev.this_device, SHM_SIZE,
779 shm_vaddr, phy_addr);
780 misc_deregister(&sprd_tks_miscdev);
783 module_init(sprd_tks_init);
784 module_exit(sprd_tks_exit);
787 MODULE_AUTHOR("spreadtrum");
788 MODULE_DESCRIPTION("sprd tks driver");
789 MODULE_LICENSE("GPL");