camsys_drv: v0.0x17.0
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_drv.c
1 #include <media/camsys_head.h>
2
3 #include "camsys_cif.h"
4 #include "camsys_marvin.h"
5 #include "camsys_mipicsi_phy.h"
6 #include "camsys_gpio.h"
7 #include "camsys_soc_priv.h"
8
9 unsigned int camsys_debug=1;
10 module_param(camsys_debug, int, S_IRUGO|S_IWUSR);
11
12 static int drv_version = CAMSYS_DRIVER_VERSION;
13 module_param(drv_version, int, S_IRUGO);
14 static int head_version = CAMSYS_HEAD_VERSION;
15 module_param(head_version, int, S_IRUGO);
16
17
18 typedef struct camsys_devs_s {
19     spinlock_t lock;
20     struct list_head devs;
21 } camsys_devs_t;
22
23 static camsys_devs_t camsys_devs;
24
25 static int camsys_i2c_write(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
26 {
27     int err = 0,i,j;
28     unsigned char buf[8],*bufp;
29     unsigned short msg_times,totallen,onelen;
30     struct i2c_msg msg[1];
31     struct i2c_adapter *adapter;
32     
33     adapter = i2c_get_adapter(i2cinfo->bus_num);
34     if (adapter == NULL) {
35         camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
36         err = -EINVAL;
37         goto end;
38     }
39     
40     if (i2cinfo->i2cbuf_directly) {
41         if (camsys_dev->devmems.i2cmem == NULL) {
42             camsys_err("%s has not i2c mem, it isn't support i2c buf write!",dev_name(camsys_dev->miscdev.this_device));
43             err = -EINVAL;
44             goto end;
45         }
46         totallen = (i2cinfo->i2cbuf_bytes&0xffff);
47         onelen = (i2cinfo->i2cbuf_bytes&0xffff0000)>>16;
48         msg_times = totallen/onelen;
49         if (totallen > camsys_dev->devmems.i2cmem->size) {
50             camsys_err("Want to write 0x%x bytes, i2c memory(size: 0x%x) is overlap",totallen,camsys_dev->devmems.i2cmem->size);
51             err = -EINVAL;
52             goto end;
53         }
54         bufp = (unsigned char*)camsys_dev->devmems.i2cmem->vir_base;        
55     } else {
56         for (i=0; i<i2cinfo->reg_size; i++) {
57             buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
58         }
59         for (j=0; j<i2cinfo->val_size; j++) {
60             buf[i+j] = (i2cinfo->val>>((i2cinfo->val_size-1-j)*8))&0xff;  /* ddl@rock-chips.com: v0.a.0 */
61         }
62         bufp = buf;
63         onelen = i2cinfo->val_size + i2cinfo->reg_size;
64         msg_times = 1;
65     }
66     
67         err = -EAGAIN;    
68     msg->addr = (i2cinfo->slave_addr>>1);
69     msg->flags = 0;
70     msg->scl_rate = i2cinfo->speed;
71    // msg->read_type = 0; 
72     msg->len = onelen;
73     for (i=0; i<msg_times; i++) {        
74         msg->buf = bufp+i*onelen;        
75                 err = i2c_transfer(adapter, msg, 1);            
76                 if (err < 0) {
77             camsys_err("i2c write dev(addr:0x%x) failed!",i2cinfo->slave_addr);
78                         udelay(10);
79                 }
80     }
81
82 end:
83     return err;
84 }
85
86 static int camsys_i2c_read(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
87 {
88     int err = 0,i,retry=2,tmp, num_msg;
89     unsigned char buf[8];
90     struct i2c_msg msg[2];
91     struct i2c_adapter *adapter;
92     
93     adapter = i2c_get_adapter(i2cinfo->bus_num);
94     if (adapter == NULL) {
95         camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
96         err = -EINVAL;
97         goto end;
98     } 
99
100         num_msg = 0;
101         if (i2cinfo->reg_size) {                /* ddl@rock-chips.com: v0.a.0 */
102             for (i=0; i<i2cinfo->reg_size; i++) {
103                 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
104             }
105                 
106             msg[0].addr = (i2cinfo->slave_addr>>1);
107                 msg[0].flags = 0;
108                 msg[0].scl_rate = i2cinfo->speed;
109                 //msg[0].read_type = 0;
110             msg[0].buf = buf;
111             msg[0].len = i2cinfo->reg_size;
112                 num_msg++;
113         }
114     
115     msg[1].addr = (i2cinfo->slave_addr>>1);
116         msg[1].flags = I2C_M_RD;
117         msg[1].scl_rate = i2cinfo->speed;
118 //      msg[1].read_type = 0;
119     msg[1].buf = buf;
120     msg[1].len = (unsigned short)i2cinfo->val_size;
121         err = -EAGAIN;    
122         num_msg++;
123
124         while ((retry-- > 0) && (err < 0)) {                                             /* ddl@rock-chips.com :  Transfer again if transent is failed   */
125                 if (num_msg==1) {                       
126                         err = i2c_transfer(adapter, &msg[1], num_msg);
127                 } else {
128                         err = i2c_transfer(adapter, msg, num_msg);
129                 }
130         
131                 if (err >= 0) {
132             err = 0;
133                 } else {
134                         camsys_err("i2c read dev(addr:0x%x) failed,try again-%d!",i2cinfo->slave_addr,retry);
135                         udelay(10);
136                 }
137         }
138
139
140     if (err==0) { 
141         i2cinfo->val = 0x00;
142         for(i=0; i<i2cinfo->val_size; i++) {
143             tmp = buf[i];
144             i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
145         }
146     }
147     
148 end:
149     return err;
150 }
151
152
153 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *camsys_dev)
154 {
155     int err = 0,i;
156     camsys_extdev_t *extdev;
157     camsys_regulator_info_t *regulator_info;
158     camsys_regulator_t *regulator;
159     camsys_gpio_info_t *gpio_info;
160     camsys_gpio_t *gpio;
161     
162     if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
163         err = -EINVAL;
164         camsys_err("dev_id: 0x%x is not support for camsys!",devio->dev_id);
165         goto end;
166     }  
167
168     extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
169     if (extdev != NULL) {
170         if (strcmp(extdev->dev_name, devio->dev_name) == 0) {
171             err = 0;
172         } else {
173             err = -EINVAL;    /* ddl@rock-chips.com: v0.0x13.0 */
174             camsys_warn("Extdev(dev_id: 0x%x dev_name: %s) has been registered in %s!",
175                 extdev->dev_id, extdev->dev_name,dev_name(camsys_dev->miscdev.this_device));
176         }
177         goto end;
178     }
179
180     extdev = kzalloc(sizeof(camsys_extdev_t),GFP_KERNEL);
181     if (extdev == NULL) {
182         camsys_err("alloc camsys_extdev_t failed!");
183         err = -ENOMEM;
184         goto end;
185     }
186     
187     extdev->dev_cfg = devio->dev_cfg;
188     extdev->fl.fl.active = devio->fl.fl.active;
189     regulator_info = &devio->avdd;
190     regulator = &extdev->avdd;
191     for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
192         if (strcmp(regulator_info->name,"NC")) {
193             regulator->ldo = regulator_get(NULL,regulator_info->name);
194             if (IS_ERR_OR_NULL(regulator->ldo)) {
195                 camsys_err("Get %s regulator for dev_id 0x%x failed!",regulator_info->name,devio->dev_id);
196                 err = -EINVAL;
197                 goto fail;
198             }
199             
200             regulator->min_uv = regulator_info->min_uv;
201             regulator->max_uv = regulator_info->max_uv;
202             camsys_trace(1,"Get %s regulator(min: %duv  max: %duv) for dev_id 0x%x success",
203                         regulator_info->name,regulator->min_uv,regulator->max_uv,
204                         devio->dev_id);
205         } else {
206             regulator->ldo = NULL;
207             regulator->min_uv = 0;
208             regulator->max_uv = 0;
209         }
210
211         regulator++;
212         regulator_info++;
213     }
214
215     gpio_info = &devio->pwrdn;
216     gpio = &extdev->pwrdn;
217     for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
218         if (strcmp(gpio_info->name,"NC")) {
219             gpio->io = camsys_gpio_get(gpio_info->name);
220             if (gpio->io < 0) {
221                 camsys_err("Get %s gpio for dev_id 0x%x failed!",gpio_info->name,devio->dev_id);
222                 err = -EINVAL;
223                 goto fail;
224             }
225             if (gpio_request(gpio->io,"camsys_gpio")<0) {
226                 camsys_err("Request %s(%d) failed",gpio_info->name,gpio->io);
227             }
228             gpio->active = gpio_info->active;
229             camsys_trace(1,"Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
230                         gpio_info->name,gpio->io,gpio->active,devio->dev_id);
231         } else {
232             gpio->io = 0xffffffff;
233             gpio->active = 0xffffffff;
234         }
235
236         gpio++;
237         gpio_info++;
238     }
239
240     extdev->pdev = camsys_dev->pdev;
241     extdev->phy = devio->phy;
242     extdev->clk = devio->clk;
243     extdev->dev_id = devio->dev_id;
244     //spin_lock(&camsys_dev->lock);
245     mutex_lock(&camsys_dev->extdevs.mut);
246     list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
247     //spin_unlock(&camsys_dev->lock);
248     mutex_unlock(&camsys_dev->extdevs.mut);
249
250     camsys_dev->iomux(extdev, (void*)camsys_dev);
251
252     memcpy(extdev->dev_name,devio->dev_name, sizeof(extdev->dev_name));
253     camsys_trace(1,"Extdev(dev_id: 0x%x  dev_name: %s) register success",
254         extdev->dev_id,
255         extdev->dev_name);
256
257     return 0;
258 fail:
259     if (extdev) { 
260         kfree(extdev);
261         extdev = NULL;
262     }
263 end:
264     
265     return err;
266 }
267
268 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
269 {
270     int err = 0,i;
271     camsys_extdev_t *extdev;
272     camsys_regulator_t *regulator;
273     camsys_gpio_t *gpio;
274
275     if (all == false) {
276         if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
277             err = -EINVAL;
278             camsys_err("dev_id: 0x%x is not support for %s!",dev_id, dev_name(camsys_dev->miscdev.this_device));
279             goto end;
280         }
281
282         extdev = camsys_find_extdev(dev_id, camsys_dev);
283         if (extdev == NULL) {
284             err = -EINVAL;
285             camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
286                 dev_id, dev_name(camsys_dev->miscdev.this_device));
287             goto end;
288         }
289
290         regulator = &extdev->avdd;
291         for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
292             if (!IS_ERR_OR_NULL(regulator->ldo)) {
293                 while(regulator_is_enabled(regulator->ldo)>0)   
294                             regulator_disable(regulator->ldo);
295                         regulator_put(regulator->ldo);
296             }
297             regulator++;
298         }
299
300         gpio = &extdev->pwrdn;
301         for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
302             if (gpio->io!=0xffffffff) {                    
303                 gpio_free(gpio->io);
304             }
305             gpio++;
306         }
307
308         //spin_lock(&camsys_dev->lock);
309         mutex_lock(&camsys_dev->extdevs.mut);
310         list_del_init(&extdev->list);
311         list_del_init(&extdev->active);
312         //spin_unlock(&camsys_dev->lock);
313         mutex_unlock(&camsys_dev->extdevs.mut);
314         
315         camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
316         kfree(extdev);
317         extdev = NULL;
318         
319     } else {
320         //spin_lock(&camsys_dev->lock);
321         mutex_lock(&camsys_dev->extdevs.mut);
322         while (!list_empty(&camsys_dev->extdevs.list)) {
323
324             extdev = list_first_entry(&camsys_dev->extdevs.list, camsys_extdev_t, list);
325             if (extdev) {
326                 regulator = &extdev->avdd;
327                 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
328                     if (!IS_ERR(regulator->ldo)) {
329                         while(regulator_is_enabled(regulator->ldo)>0)   
330                                     regulator_disable(regulator->ldo);
331                                 regulator_put(regulator->ldo);
332                     }
333                     regulator++; 
334                 }
335
336                 gpio = &extdev->pwrdn;
337                 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
338                     if (gpio->io!=0xffffffff) {                    
339                         gpio_free(gpio->io);
340                     }
341                     gpio++;
342                 }
343                 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
344                 list_del_init(&extdev->list);
345                 list_del_init(&extdev->active);
346                 kfree(extdev);
347                 extdev=NULL;
348             }
349         }
350         //spin_unlock(&camsys_dev->lock);        
351         mutex_unlock(&camsys_dev->extdevs.mut);
352         camsys_trace(1, "All extdev is deregister success!");
353     }
354     
355
356 end:    
357     return err;
358
359 }
360
361 static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
362 {
363     int i;
364     int err = 0;    
365     camsys_extdev_t *extdev,*extdev2;
366
367     //spin_lock(&camsys_dev->lock);
368     mutex_lock(&camsys_dev->extdevs.mut);
369         if(devctl->ops == 0xaa){
370                 dump_stack();
371                 return 0;
372         }
373     //Internal 
374     if (camsys_dev->dev_id & devctl->dev_mask) {
375         switch (devctl->ops)
376         {
377             case CamSys_ClkIn:
378             {
379                 camsys_dev->clkin_cb(camsys_dev,devctl->on);
380                 break;
381             }
382
383             case CamSys_Rst:
384             {
385                 camsys_dev->reset_cb(camsys_dev, devctl->on);
386                 break;
387             } 
388             case CamSys_Flash_Trigger:
389             {
390                 camsys_dev->flash_trigger_cb(camsys_dev, devctl->on);
391                 break;
392             }
393             case CamSys_IOMMU:
394             {
395                 if(camsys_dev->iommu_cb(camsys_dev, devctl) < 0){
396                     err = -1;
397                     }
398                 break;
399             }
400             default:
401                 break;
402
403         }
404     }
405
406     //External
407     for (i=0; i<8; i++) {
408         if (devctl->dev_mask & (1<<(i+24))) {
409             extdev = camsys_find_extdev((1<<(i+24)), camsys_dev);
410             if (extdev) {
411                 camsys_sysctl_extdev(extdev, devctl, camsys_dev);
412
413                 if (devctl->ops == CamSys_ClkIn) {
414                     if (devctl->on) {
415                         list_add_tail(&extdev->active,&camsys_dev->extdevs.active);
416                     } else {
417                         if (!list_empty(&camsys_dev->extdevs.active)) {    /* ddla@rock-chips.com: v0.0.7 */
418                             list_for_each_entry(extdev2, &camsys_dev->extdevs.active, active) {
419                                 if (extdev2 == extdev) {
420                                     list_del_init(&extdev->active);
421                                     break;
422                                 }
423                             }
424                         }
425                     }
426                 }
427                 
428             } else {
429                 camsys_err("Can not find dev_id 0x%x device in %s!", (1<<(i+24)), dev_name(camsys_dev->miscdev.this_device));
430             }
431         }
432     }
433
434     //spin_unlock(&camsys_dev->lock);
435     mutex_unlock(&camsys_dev->extdevs.mut);
436     return err;
437 }
438 static int camsys_phy_ops (camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, void *ptr)
439 {
440     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
441     camsys_mipiphy_t *mipiphy;
442     int err = 0;
443     
444     if (extdev->phy.type == CamSys_Phy_Mipi) {
445         mipiphy = (camsys_mipiphy_t*)devctl->rev;
446         if (devctl->on == 0) {
447             mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
448             mipiphy->bit_rate = 0;
449             mipiphy->data_en_bit = 0x00;
450         } else {
451             if ((mipiphy->bit_rate == 0) || (mipiphy->data_en_bit == 0)) {
452                 *mipiphy = extdev->phy.info.mipi;
453             }
454             if (mipiphy->phy_index != extdev->phy.info.mipi.phy_index) {
455                 camsys_warn("mipiphy->phy_index(%d) != extdev->phy.info.mipi.phy_index(%d)!",
456                     mipiphy->phy_index,extdev->phy.info.mipi.phy_index);
457                 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
458                 
459             }
460         }
461         err = camsys_dev->mipiphy[mipiphy->phy_index].ops(ptr,mipiphy);
462         if (err < 0) {
463             camsys_err("extdev(0x%x) mipi phy ops config failed!",extdev->dev_id);
464         }
465     }
466
467     return err;
468 }
469 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev)
470 {
471     int err = 0,i;
472     camsys_irqpool_t *irqpool; 
473     unsigned long int flags;
474
475     if ((irqcnnt->mis != MRV_ISP_MIS) &&
476         (irqcnnt->mis != MRV_MIPI_MIS) &&
477         (irqcnnt->mis != MRV_MI_MIS) &&
478         (irqcnnt->mis != MRV_JPG_MIS) &&
479         (irqcnnt->mis != MRV_JPG_ERR_MIS)) {
480
481         camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate, irq connect failed!",
482             irqcnnt->pid, irqcnnt->mis);
483
484         err = -EINVAL;
485         goto end;
486     }   
487
488     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
489     if (!list_empty(&camsys_dev->irq.irq_pool)) {
490         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
491             if (irqpool->pid == irqcnnt->pid) {
492                 camsys_warn("this thread(pid: %d) had been connect irq!",current->pid);
493                 spin_unlock(&camsys_dev->irq.lock);
494                 goto end;
495             }
496         }
497     }
498     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
499     
500     irqpool = kzalloc(sizeof(camsys_irqpool_t),GFP_KERNEL);
501     if (irqpool) {
502         spin_lock_init(&irqpool->lock);
503         irqpool->pid = irqcnnt->pid;
504         irqpool->timeout = irqcnnt->timeout;
505         irqpool->mis = irqcnnt->mis;
506         irqpool->icr = irqcnnt->icr;
507         INIT_LIST_HEAD(&irqpool->active);
508         INIT_LIST_HEAD(&irqpool->deactive);
509         init_waitqueue_head(&irqpool->done);
510         for (i=0; i<CAMSYS_IRQPOOL_NUM; i++) {
511             list_add_tail(&irqpool->pool[i].list, &irqpool->deactive);
512         }
513     }
514     
515     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
516     //camsys_dev->irq.timeout = irqcnnt->timeout;
517     list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
518     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
519     camsys_trace(1, "Thread(pid: %d) connect %s irq success! mis: 0x%x icr: 0x%x ", irqpool->pid, dev_name(camsys_dev->miscdev.this_device),
520         irqpool->mis,irqpool->icr);
521
522 end:
523     return err;
524 }
525 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
526 {
527     int err;
528     unsigned long int flags;
529     
530     spin_lock_irqsave(&irqpool->lock,flags);
531     err = list_empty(&irqpool->active);
532     spin_unlock_irqrestore(&irqpool->lock,flags);
533
534     return !err;
535     
536 }
537 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
538 {
539     int err = 0;
540     bool find_pool = false;
541     camsys_irqstas_t *irqstas;
542     camsys_irqpool_t *irqpool;
543     unsigned long int flags;
544     
545     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
546     if (!list_empty(&camsys_dev->irq.irq_pool)) {
547         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
548             if (irqpool->pid == current->pid) {
549                 find_pool = true;
550                 break;
551             }
552         }
553     }
554     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
555
556     if (find_pool == false) {
557         camsys_err("this thread(pid: %d) hasn't been connect irq, so wait irq failed!",current->pid);
558         err = -EINVAL;
559         goto end;
560     }
561     
562     
563     spin_lock_irqsave(&irqpool->lock,flags);
564     if (!list_empty(&irqpool->active)) {
565         irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
566         *irqsta = irqstas->sta;
567         list_del_init(&irqstas->list);
568         list_add_tail(&irqstas->list,&irqpool->deactive);
569         spin_unlock_irqrestore(&irqpool->lock,flags);
570     } else {
571         spin_unlock_irqrestore(&irqpool->lock,flags);
572         
573         wait_event_interruptible_timeout(irqpool->done,
574             active_list_isnot_empty(irqpool),
575             usecs_to_jiffies(irqpool->timeout));
576
577         if (irqpool->pid == current->pid) {
578             if (active_list_isnot_empty(irqpool)) {
579                 spin_lock_irqsave(&irqpool->lock,flags);
580                 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
581                 *irqsta = irqstas->sta;
582                 list_del_init(&irqstas->list);
583                 list_add_tail(&irqstas->list,&irqpool->deactive);
584                 spin_unlock_irqrestore(&irqpool->lock,flags);
585             } else {
586                 err = -EAGAIN;
587             }
588         } else {
589             camsys_warn("Thread(pid: %d) has been disconnect!",current->pid);
590             err = -EAGAIN;
591         }
592     }
593
594     if (err == 0) {
595         camsys_trace(3,"Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
596                      current->pid, irqsta->mis, irqsta->ris);
597     }
598
599 end:
600     return err;
601 }
602
603 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev, bool all)
604 {
605     int err = 0;
606     bool find_pool = false;
607     camsys_irqpool_t *irqpool;    
608     unsigned long int flags;
609     
610     if (all == false) {
611         spin_lock_irqsave(&camsys_dev->irq.lock,flags);
612                 if (!list_empty(&camsys_dev->irq.irq_pool)) {
613             list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
614                 if (irqpool->pid == irqcnnt->pid) {
615                     find_pool = true;
616                     irqpool->pid = 0;
617                     break;
618                 }
619             }
620         }
621         spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
622
623         if (find_pool == false) {
624             camsys_err("this thread(pid: %d) have not been connect irq!, disconnect failed",current->pid);         
625         } else {
626             wake_up_all(&irqpool->done);
627         }
628
629         camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!", irqcnnt->pid, dev_name(camsys_dev->miscdev.this_device));
630    } else {
631         spin_lock_irqsave(&camsys_dev->irq.lock,flags);
632         while (!list_empty(&camsys_dev->irq.irq_pool)) {
633             irqpool = list_first_entry(&camsys_dev->irq.irq_pool, camsys_irqpool_t, list);
634             list_del_init(&irqpool->list);
635             irqpool->pid = 0;
636             wake_up_all(&irqpool->done);
637             kfree(irqpool);
638             irqpool = NULL;
639         }
640         spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
641
642         camsys_trace(1, "All thread disconnect %s irq success!", dev_name(camsys_dev->miscdev.this_device));
643    }
644
645
646     return err;
647 }
648
649 static int camsys_querymem (camsys_dev_t *camsys_dev,  camsys_querymem_t *qmem)
650 {
651     int err = 0;
652     
653     if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
654         if (camsys_dev->devmems.registermem == NULL) {
655             camsys_err("%s register memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
656             err = -EINVAL;
657             goto end;
658         }
659
660         qmem->mem_size = camsys_dev->devmems.registermem->size;
661         qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
662     } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
663         if (camsys_dev->devmems.i2cmem== NULL) {
664             camsys_err("%s i2c memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
665             err = -EINVAL;
666             goto end;
667         }
668
669         qmem->mem_size = camsys_dev->devmems.i2cmem->size;
670         qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
671     } else {
672         camsys_err("%d memory type have not in %s memory list",qmem->mem_type,dev_name(camsys_dev->miscdev.this_device));
673         err = -EINVAL;
674         goto end;
675     }
676     
677
678     return 0;
679 end: 
680     return err;
681 }
682 static int camsys_open(struct inode *inode, struct file *file)
683 {
684     int err = 0;
685     int minor = iminor(inode);
686     camsys_dev_t *camsys_dev;
687     unsigned int i,phycnt;
688
689     spin_lock(&camsys_devs.lock);
690     list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
691         if (camsys_dev->miscdev.minor == minor) {
692             file->private_data = (void*)(camsys_dev);
693             break;
694         }
695     }
696     spin_unlock(&camsys_devs.lock);
697
698     //zyc add
699     INIT_LIST_HEAD(&camsys_dev->extdevs.active);
700     
701     if (camsys_dev->mipiphy != NULL) {
702         phycnt = camsys_dev->mipiphy[0].phycnt;
703          
704         for (i=0; i<phycnt; i++) {
705             if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
706                 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,1);
707             }
708         }
709     }
710
711     
712     if (file->private_data == NULL) {
713         camsys_err("Cann't find camsys_dev!");
714         err = -ENODEV;
715         goto end;
716     } else {     
717         camsys_trace(1,"%s(%p) is opened!",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
718     }
719
720 end:
721     return err;
722 }
723
724 static int camsys_release(struct inode *inode, struct file *file)
725 {
726     camsys_dev_t *camsys_dev = (camsys_dev_t*)file->private_data;
727     unsigned int i,phycnt;
728     
729     camsys_irq_disconnect(NULL,camsys_dev, true);
730
731     if (camsys_dev->mipiphy != NULL) {
732         phycnt = camsys_dev->mipiphy[0].phycnt;
733          
734         for (i=0; i<phycnt; i++) {
735             if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
736                 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,0);
737             }
738         }
739     }
740
741     camsys_trace(1,"%s(%p) is closed",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
742
743     return 0;
744 }
745
746 /*
747 * The ioctl() implementation
748 */
749
750 static long camsys_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
751 {
752         long err = 0;
753     camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data; 
754     
755         if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) { 
756         camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
757         err = -ENOTTY;
758         goto end;
759         }
760         if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
761         camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
762         err = -ENOTTY;
763         goto end;
764         }
765
766     if (_IOC_DIR(cmd) & _IOC_READ)
767         err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));     
768     else if (_IOC_DIR(cmd) & _IOC_WRITE)
769         err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
770
771     if (err) {
772         camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
773         err = -EFAULT;
774         goto end;
775     }
776
777         switch (cmd) {
778
779             case CAMSYS_VERCHK:
780             {
781                 camsys_version_t camsys_ver;
782                 
783             camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
784             camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
785             if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
786                 return -EFAULT;
787             break;
788             }
789             case CAMSYS_QUREYIOMMU:
790             {
791             int iommu_enabled = 0;
792             #ifdef CONFIG_ROCKCHIP_IOMMU
793                                 struct device_node * vpu_node =NULL;
794                                 int vpu_iommu_enabled = 0;
795                 vpu_node = of_find_compatible_node(NULL,NULL, "vpu_service");
796                                 if(vpu_node){
797                                         of_property_read_u32(vpu_node, "iommu_enabled", &vpu_iommu_enabled);
798                                         of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled);
799                                         if(iommu_enabled != vpu_iommu_enabled){
800                                                 camsys_err("iommu status not consistent,check the dts file ! isp:%d,vpu:%d",iommu_enabled,vpu_iommu_enabled);
801                                                 return -EFAULT;
802                                         }
803                                 }
804                         #endif
805             if (copy_to_user((void __user *)arg,(void*)&iommu_enabled, sizeof(iommu_enabled)))
806                 return -EFAULT;
807             break;
808             }
809             case CAMSYS_I2CRD:
810             {
811                 camsys_i2c_info_t i2cinfo;
812                 
813             if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t))) 
814                 return -EFAULT;
815
816             err = camsys_i2c_read(&i2cinfo,camsys_dev);
817             if (err==0) {
818                 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
819                     return -EFAULT;
820             }
821             break;
822             }
823
824             case CAMSYS_I2CWR:
825             {
826             camsys_i2c_info_t i2cinfo;
827                 
828             if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t))) 
829                 return -EFAULT;
830
831             err = camsys_i2c_write(&i2cinfo,camsys_dev);
832             break;
833             }
834
835         case CAMSYS_SYSCTRL:
836         {
837             camsys_sysctrl_t devctl;
838
839             if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t))) 
840                 return -EFAULT;
841
842             err = camsys_sysctl(&devctl, camsys_dev);
843             if ((err==0) && (devctl.ops == CamSys_IOMMU)){
844                 if (copy_to_user((void __user *)arg,(void*)&devctl, sizeof(camsys_sysctrl_t))) 
845                     return -EFAULT;
846             }
847             break;
848         }
849
850         case CAMSYS_REGRD:
851         {
852
853             break;
854         }
855
856         case CAMSYS_REGWR:
857         {
858
859             break;
860         }
861
862         case CAMSYS_REGISTER_DEVIO:
863         {
864             camsys_devio_name_t devio;
865
866             if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t))) 
867                 return -EFAULT;
868
869             err = camsys_extdev_register(&devio,camsys_dev);
870             break;
871         }
872
873         case CAMSYS_DEREGISTER_DEVIO:
874         {
875             unsigned int dev_id;
876
877             if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
878                 return -EFAULT;
879
880             err = camsys_extdev_deregister(dev_id, camsys_dev, false);
881             break;
882         }
883
884         case CAMSYS_IRQCONNECT:
885         {
886             camsys_irqcnnt_t irqcnnt;
887
888             if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t))) 
889                 return -EFAULT;
890             
891             err = camsys_irq_connect(&irqcnnt, camsys_dev);
892             
893             break;
894         }
895
896         case CAMSYS_IRQWAIT:
897         {
898             camsys_irqsta_t irqsta;
899
900             err = camsys_irq_wait(&irqsta, camsys_dev);
901             if (err==0) {
902                 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t))) 
903                     return -EFAULT;
904             }
905             break;
906         }
907
908         case CAMSYS_IRQDISCONNECT:
909         {
910             camsys_irqcnnt_t irqcnnt;
911
912             if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t))) 
913                 return -EFAULT;
914             err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
915                         break;
916         }
917
918         
919         case CAMSYS_QUREYMEM:
920         {
921             camsys_querymem_t qmem;
922
923             if (copy_from_user((void*)&qmem,(void __user *)arg, sizeof(camsys_querymem_t))) 
924                 return -EFAULT;
925             
926             err = camsys_querymem(camsys_dev,&qmem);
927             if (err == 0) {
928                 if (copy_to_user((void __user *)arg,(void*)&qmem, sizeof(camsys_querymem_t))) 
929                     return -EFAULT;
930             }
931             break;
932         }
933        
934         default :
935             break;
936         }
937
938 end:    
939         return err;
940
941 }
942 /*
943  * VMA operations.
944  */
945 static void camsys_vm_open(struct vm_area_struct *vma)
946 {
947     camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
948
949     meminfo->vmas++;
950     return;
951 }
952
953 static void camsys_vm_close(struct vm_area_struct *vma)
954 {
955     camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
956
957     meminfo->vmas--;
958     return;
959 }
960
961 static const struct vm_operations_struct camsys_vm_ops = {
962         .open           = camsys_vm_open,
963         .close          = camsys_vm_close,
964 };
965
966 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
967 {
968     camsys_dev_t *camsys_dev = (camsys_dev_t*)flip->private_data;
969         unsigned long addr, start, size;    
970         camsys_mmap_type_t mem_type;
971         camsys_meminfo_t *meminfo;              
972         int ret = 0;
973
974     mem_type = vma->vm_pgoff;     
975     
976     if (mem_type == CamSys_Mmap_RegisterMem) {
977         if (camsys_dev->devmems.registermem != NULL) {
978             meminfo = camsys_dev->devmems.registermem;
979         } else {
980             camsys_err("this camsys device has not register mem!");
981             ret = -EINVAL;
982             goto done;
983         }
984     } else if (mem_type == CamSys_Mmap_I2cMem) {
985         if (camsys_dev->devmems.i2cmem != NULL) {
986             meminfo = camsys_dev->devmems.i2cmem;
987         } else {
988             camsys_err("this camsys device has not i2c mem!");
989             ret = -EINVAL;
990             goto done;
991         }
992     } else {
993         camsys_err("mmap buffer type %d is invalidate!",mem_type);
994         ret = -EINVAL;
995         goto done;
996     }
997     
998     size = vma->vm_end - vma->vm_start;
999     if (size > meminfo->size) {
1000         ret = -ENOMEM;
1001         camsys_err("mmap size(0x%lx) > memory size(0x%x), so failed!",size,meminfo->size);
1002         goto done;
1003     }
1004     
1005         start = vma->vm_start;
1006         addr = __phys_to_pfn(meminfo->phy_base);    
1007         
1008     if (remap_pfn_range(vma, start, addr,size,pgprot_noncached(vma->vm_page_prot))) { 
1009         
1010         ret = -EAGAIN;
1011         goto done;
1012     }
1013     
1014     vma->vm_ops = &camsys_vm_ops;
1015     vma->vm_flags |= VM_IO;
1016     vma->vm_flags |=VM_ACCOUNT;//same as VM_RESERVED;
1017     vma->vm_private_data = (void*)meminfo;
1018     camsys_vm_open(vma);
1019
1020 done:
1021         return ret;
1022 }
1023
1024 struct file_operations camsys_fops = {
1025         .owner =            THIS_MODULE,
1026     .open =             camsys_open,
1027     .release =          camsys_release,
1028         .unlocked_ioctl =   camsys_ioctl,
1029         .mmap =             camsys_mmap,
1030 };
1031
1032 static int camsys_platform_probe(struct platform_device *pdev){
1033     int err = 0;
1034         camsys_dev_t *camsys_dev;
1035     struct resource register_res ;
1036     struct device *dev = &pdev->dev;
1037     unsigned long i2cmem;
1038         camsys_meminfo_t *meminfo;
1039     unsigned int irq_id;
1040     
1041     err = of_address_to_resource(dev->of_node, 0, &register_res);
1042     if (err < 0){
1043         camsys_err("Get register resource from %s platform device failed!",pdev->name);
1044         err = -ENODEV;
1045         goto fail_end;
1046     }
1047
1048     //map irqs
1049     irq_id = irq_of_parse_and_map(dev->of_node, 0);
1050     if (irq_id < 0) {
1051         camsys_err("Get irq resource from %s platform device failed!",pdev->name);
1052         err = -ENODEV;
1053         goto fail_end;
1054     }
1055
1056     camsys_dev = (camsys_dev_t*)devm_kzalloc(&pdev->dev,sizeof(camsys_dev_t), GFP_KERNEL);
1057     if (camsys_dev == NULL) {
1058         camsys_err("Allocate camsys_dev for %s platform device failed",pdev->name);
1059         err = -ENOMEM;
1060         goto fail_end;
1061     }
1062
1063     //spin_lock_init(&camsys_dev->lock);
1064     mutex_init(&camsys_dev->extdevs.mut);
1065     INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1066     INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1067     INIT_LIST_HEAD(&camsys_dev->list);
1068     
1069
1070     //IRQ init
1071     camsys_dev->irq.irq_id = irq_id;  
1072     spin_lock_init(&camsys_dev->irq.lock);
1073     INIT_LIST_HEAD(&camsys_dev->irq.irq_pool); 
1074     //init_waitqueue_head(&camsys_dev->irq.irq_done);
1075     
1076     INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1077
1078     // get soc operation
1079     camsys_dev->soc = (void*)camsys_soc_get();
1080     if (camsys_dev->soc == NULL) {
1081         err = -ENODEV;
1082         goto fail_end;
1083     }
1084
1085     //Register mem init
1086     meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1087     if (meminfo == NULL) {
1088         err = -ENOMEM;
1089         goto request_mem_fail;
1090     }
1091
1092     meminfo->vir_base = (unsigned int)devm_ioremap_resource(dev, &register_res);
1093     if (!meminfo->vir_base){
1094         camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), CAMSYS_REGISTER_MEM_NAME);
1095         err = -ENXIO;
1096         goto request_mem_fail;
1097     }
1098
1099     strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME,sizeof(meminfo->name));
1100     meminfo->phy_base = register_res.start;
1101     meminfo->size = register_res.end - register_res.start + 1;  
1102     list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1103
1104
1105     //I2c mem init
1106     i2cmem = __get_free_page(GFP_KERNEL);
1107     if (i2cmem == 0) {
1108         camsys_err("Allocate i2cmem failed!");
1109         err = -ENOMEM;
1110         goto request_mem_fail;
1111     }
1112     SetPageReserved(virt_to_page(i2cmem));
1113     
1114     meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1115     if (meminfo == NULL) {
1116         err = -ENOMEM;
1117         goto request_mem_fail;
1118     }
1119     strlcpy(meminfo->name,CAMSYS_I2C_MEM_NAME,sizeof(meminfo->name));
1120     meminfo->vir_base = i2cmem;
1121     meminfo->phy_base = virt_to_phys((void*)i2cmem);
1122     meminfo->size = PAGE_SIZE;
1123     list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1124
1125     {
1126         unsigned int *tmpp;
1127
1128         tmpp = (unsigned int*)meminfo->vir_base;
1129         *tmpp = 0xfa561243;
1130     }
1131
1132     //Special init
1133
1134     {        
1135         if (camsys_mipiphy_probe_cb(pdev, camsys_dev) <0) {
1136             camsys_err("Mipi phy probe failed!");
1137         }
1138     }
1139
1140 #if 0
1141     if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_MARVIN_NAME) == 0) {
1142         #if (defined(CONFIG_CAMSYS_MRV))
1143         camsys_mrv_probe_cb(pdev, camsys_dev);        
1144         #else
1145         camsys_err("Marvin controller camsys driver haven't been complie!!!");
1146         #endif
1147     } else {
1148         #if (defined(CONFIG_CAMSYS_CIF))
1149         camsys_cif_probe_cb(pdev,camsys_dev);
1150         #else
1151         camsys_err("CIF controller camsys driver haven't been complie!!!");
1152         #endif
1153     }
1154 #else
1155         #if (defined(CONFIG_CAMSYS_MRV))
1156         camsys_mrv_probe_cb(pdev, camsys_dev);        
1157         #elif (defined(CONFIG_CAMSYS_CIF))
1158         camsys_cif_probe_cb(pdev,camsys_dev);
1159         #else
1160         camsys_err("camsys driver haven't been complie!!!");
1161         #endif
1162 #endif
1163     camsys_trace(1, "%s memory:",dev_name(&pdev->dev));
1164     list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1165         if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME) == 0) {
1166             camsys_dev->devmems.i2cmem = meminfo;
1167             camsys_trace(1,"    I2c memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1168                         meminfo->phy_base,meminfo->vir_base,meminfo->size);
1169         }
1170         if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME) == 0) {
1171             camsys_dev->devmems.registermem = meminfo;
1172             camsys_trace(1,"    Register memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1173                         meminfo->phy_base,meminfo->vir_base,meminfo->size);
1174         }
1175     }
1176
1177
1178     camsys_dev->phy_cb = camsys_phy_ops;
1179     camsys_dev->pdev    =   pdev;
1180
1181     platform_set_drvdata(pdev,(void*)camsys_dev);
1182     //Camsys_devs list add    
1183     spin_lock(&camsys_devs.lock);    
1184     list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1185     spin_unlock(&camsys_devs.lock);
1186
1187     
1188     camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1189     return 0;
1190 request_mem_fail:
1191     if (camsys_dev != NULL) {
1192     
1193         while(!list_empty(&camsys_dev->devmems.memslist)) {
1194             meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1195             if (meminfo) {
1196                 list_del_init(&meminfo->list);
1197                 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1198                     iounmap((void __iomem *)meminfo->vir_base);
1199                     release_mem_region(meminfo->phy_base,meminfo->size);
1200                 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1201                     kfree((void*)meminfo->vir_base);
1202                 }
1203                 kfree(meminfo);
1204                 meminfo = NULL;
1205             }
1206         } 
1207     
1208         kfree(camsys_dev);
1209         camsys_dev = NULL;
1210     }
1211 fail_end:
1212     return -1;
1213
1214     
1215 }
1216 static int  camsys_platform_remove(struct platform_device *pdev)
1217 {
1218     camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1219     camsys_meminfo_t *meminfo;
1220     
1221     if (camsys_dev) {
1222
1223         //Mem deinit
1224         while(!list_empty(&camsys_dev->devmems.memslist)) {
1225             meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1226             if (meminfo) {
1227                 list_del_init(&meminfo->list);
1228                 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1229                     iounmap((void __iomem *)meminfo->vir_base);
1230                     release_mem_region(meminfo->phy_base,meminfo->size);
1231                 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1232                     kfree((void*)meminfo->vir_base);
1233                 }
1234                 kfree(meminfo);
1235                 meminfo = NULL;
1236             }
1237         }        
1238
1239         //Irq deinit
1240         if (camsys_dev->irq.irq_id) {
1241             free_irq(camsys_dev->irq.irq_id, camsys_dev);
1242             camsys_irq_disconnect(NULL,camsys_dev,true);
1243         }
1244
1245         //Extdev deinit
1246         if (!list_empty(&camsys_dev->extdevs.list)) {
1247             camsys_extdev_deregister(0,camsys_dev,true);
1248         }
1249         if (camsys_dev->mipiphy != NULL) {
1250             camsys_dev->mipiphy->remove(pdev);
1251         }
1252         if (camsys_dev->cifphy.remove)
1253             camsys_dev->cifphy.remove(pdev);
1254         camsys_dev->platform_remove(pdev);
1255
1256         misc_deregister(&camsys_dev->miscdev);
1257         
1258         spin_lock(&camsys_devs.lock);
1259         list_del_init(&camsys_dev->list);
1260         spin_unlock(&camsys_devs.lock);
1261
1262         kfree(camsys_dev);
1263         camsys_dev=NULL;
1264     } else {
1265         camsys_err("This platform device havn't obtain camsys_dev!");
1266     }
1267
1268     return 0;
1269 }
1270
1271
1272 static const struct of_device_id cif_of_match[] = {
1273     { .compatible = "rockchip,isp" },
1274 };
1275 MODULE_DEVICE_TABLE(of, cif_of_match);
1276
1277 static struct platform_driver camsys_platform_driver =
1278 {
1279     .driver     = {
1280         .name   = CAMSYS_PLATFORM_DRV_NAME,
1281         .of_match_table = of_match_ptr(cif_of_match),
1282     },
1283     .probe              = camsys_platform_probe,
1284     .remove             = (camsys_platform_remove),
1285 };
1286
1287 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1288 static int __init camsys_platform_init(void)  
1289 {
1290     printk("CamSys driver version: v%d.%d.%d,  CamSys head file version: v%d.%d.%d\n",
1291         (CAMSYS_DRIVER_VERSION&0xff0000)>>16, (CAMSYS_DRIVER_VERSION&0xff00)>>8,
1292         CAMSYS_DRIVER_VERSION&0xff,
1293         (CAMSYS_HEAD_VERSION&0xff0000)>>16, (CAMSYS_HEAD_VERSION&0xff00)>>8,
1294         CAMSYS_HEAD_VERSION&0xff);
1295
1296     spin_lock_init(&camsys_devs.lock);
1297     INIT_LIST_HEAD(&camsys_devs.devs);
1298     camsys_soc_init();
1299     platform_driver_register(&camsys_platform_driver);
1300    // platform_driver_probe(&camsys_platform_driver, camsys_platform_probe_new);
1301     
1302     return 0;
1303 }  
1304   
1305 static void __exit camsys_platform_exit(void)  
1306 {
1307     platform_driver_unregister(&camsys_platform_driver);
1308     camsys_soc_deinit();
1309
1310
1311 module_init(camsys_platform_init);              
1312 module_exit(camsys_platform_exit);      
1313
1314 MODULE_DESCRIPTION("RockChip Camera System");
1315 MODULE_AUTHOR("<ddl@rock-chips>");
1316 MODULE_LICENSE("GPL");
1317