1 #include "camsys_marvin.h"
2 #include "camsys_soc_priv.h"
3 #include "camsys_gpio.h"
5 #include <linux/rockchip/common.h>
6 #include <dt-bindings/clock/rk_system_status.h>
7 #include <linux/rockchip_ion.h>
8 #include <linux/file.h>
10 extern int rockchip_set_system_status(unsigned long status);
11 extern int rockchip_clear_system_status(unsigned long status);
13 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
16 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
18 struct pinctrl *pinctrl;
19 struct pinctrl_state *state;
21 char state_str[20] = {0};
22 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
23 struct device *dev = &(extdev->pdev->dev);
24 camsys_soc_priv_t *soc;
28 if (extdev->phy.type == CamSys_Phy_Cif) {
30 switch (extdev->phy.info.cif.fmt)
32 case CamSys_Fmt_Raw_8b:
33 case CamSys_Fmt_Yuv420_8b:
34 case CamSys_Fmt_Yuv422_8b:
36 if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit0) {
37 strcpy(state_str,"isp_dvp8bit0");
38 } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit2) {
39 strcpy(state_str,"isp_dvp8bit2");
40 } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit4) {
41 strcpy(state_str,"isp_dvp8bit4");
43 camsys_err("extdev->phy.info.cif.cifio: 0x%x is invalidate!", extdev->phy.info.cif.cifio);
50 case CamSys_Fmt_Raw_10b:
52 strcpy(state_str,"isp_dvp10bit");
56 case CamSys_Fmt_Raw_12b:
58 strcpy(state_str,"isp_dvp12bit");
64 camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!",extdev->phy.info.cif.fmt);
69 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
70 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
71 strcpy(state_str,"isp_mipi_fl_prefl");
73 strcpy(state_str,"isp_mipi_fl");
76 //mux triggerout as gpio
78 int flash_trigger_io ;
79 enum of_gpio_flags flags;
80 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
81 if(gpio_is_valid(flash_trigger_io)){
82 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
83 gpio_request(flash_trigger_io,"camsys_gpio");
84 gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1));
88 strcpy(state_str,"default");
92 camsys_trace(1,"marvin pinctrl select: %s", state_str);
94 pinctrl = devm_pinctrl_get(dev);
95 if (IS_ERR(pinctrl)) {
96 camsys_err("devm_pinctrl_get failed!");
99 state = pinctrl_lookup_state(pinctrl,
102 camsys_err("pinctrl_lookup_state failed!");
106 if (!IS_ERR(state)) {
107 retval = pinctrl_select_state(pinctrl, state);
109 camsys_err("pinctrl_select_state failed!");
114 if (camsys_dev->soc) {
115 soc = (camsys_soc_priv_t*)camsys_dev->soc;
117 (soc->soc_cfg)(Cif_IoDomain_Cfg,(void*)&extdev->dovdd.min_uv);
118 (soc->soc_cfg)(Clk_DriverStrength_Cfg,(void*)&extdev->clk.driver_strength);
120 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
123 camsys_err("camsys_dev->soc is NULL!");
131 static int camsys_mrv_flash_trigger_cb(void *ptr,int mode,unsigned int on)
133 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
134 struct device *dev = &(camsys_dev->pdev->dev);
135 int flash_trigger_io ;
136 struct pinctrl *pinctrl;
137 struct pinctrl_state *state;
138 char state_str[20] = {0};
140 enum of_gpio_flags flags;
141 camsys_extdev_t *extdev = NULL;
144 strcpy(state_str,"isp_flash_as_gpio");
145 pinctrl = devm_pinctrl_get(dev);
146 if (IS_ERR(pinctrl)) {
147 camsys_err("devm_pinctrl_get failed!");
149 state = pinctrl_lookup_state(pinctrl,
152 camsys_err("pinctrl_lookup_state failed!");
155 if (!IS_ERR(state)) {
156 retval = pinctrl_select_state(pinctrl, state);
158 camsys_err("pinctrl_select_state failed!");
164 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
165 if(gpio_is_valid(flash_trigger_io)){
166 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
167 gpio_request(flash_trigger_io,"camsys_gpio");
168 //get flash io active pol
169 if (!list_empty(&camsys_dev->extdevs.list)) {
170 list_for_each_entry(extdev, &camsys_dev->extdevs.list, list) {
171 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
172 gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1));
178 strcpy(state_str,"isp_flash_as_trigger_out");
179 pinctrl = devm_pinctrl_get(dev);
180 if (IS_ERR(pinctrl)) {
181 camsys_err("devm_pinctrl_get failed!");
183 state = pinctrl_lookup_state(pinctrl,
186 camsys_err("pinctrl_lookup_state failed!");
189 if (!IS_ERR(state)) {
190 retval = pinctrl_select_state(pinctrl, state);
192 camsys_err("pinctrl_select_state failed!");
199 static struct device *rockchip_get_sysmmu_device_by_compatible(const char *compt)
201 struct device_node *dn = NULL;
202 struct platform_device *pd = NULL;
203 struct device *ret = NULL ;
205 dn = of_find_compatible_node(NULL,NULL,compt);
208 printk("can't find device node %s \r\n",compt);
212 pd = of_find_device_by_node(dn);
215 printk("can't find platform device in device node %s \r\n",compt);
223 #ifdef CONFIG_IOMMU_API
224 static inline void platform_set_sysmmu(struct device *iommu, struct device *dev)
226 dev->archdata.iommu = iommu;
229 static inline void platform_set_sysmmu(struct device *iommu, struct device *dev)
235 static int camsys_mrv_iommu_cb(void *ptr,camsys_sysctrl_t *devctl)
237 struct device *iommu_dev = NULL,*dev = NULL;
238 struct file *file = NULL;
239 struct ion_client *client = NULL;
240 struct ion_handle *handle = NULL;
241 camsys_iommu_t *iommu = NULL;
242 int ret = 0,iommu_enabled = 0;
243 camsys_dev_t * camsys_dev = (camsys_dev_t *)ptr;
245 of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled);
246 if(iommu_enabled != 1){
247 camsys_err("isp iommu have not been enabled!\n");
251 iommu_dev = rockchip_get_sysmmu_device_by_compatible(ISP_IOMMU_COMPATIBLE_NAME);
253 camsys_err("get iommu device erro!\n");
257 dev = &(camsys_dev->pdev->dev);
258 iommu = (camsys_iommu_t *)(devctl->rev);
259 file = fget(iommu->client_fd);
261 camsys_err("get client_fd file erro!\n");
266 client = file->private_data;
269 camsys_err("get ion_client erro!\n");
276 handle = ion_import_dma_buf(client,iommu->map_fd);
278 camsys_trace(1,"map fd %d ,client fd %d\n",iommu->map_fd,iommu->client_fd);
280 camsys_err("get ion_handle erro!\n");
285 platform_set_sysmmu(iommu_dev,dev);
286 ret = rockchip_iovmm_activate(dev);
288 ret = ion_map_iommu(dev,client,handle,&(iommu->linear_addr),&(iommu->len));
291 ion_unmap_iommu(dev,client,handle);
292 platform_set_sysmmu(iommu_dev,dev);
293 rockchip_iovmm_deactivate(dev);
298 static int camsys_mrv_reset_cb(void *ptr,unsigned int on)
300 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
301 camsys_soc_priv_t *soc;
304 if (camsys_dev->soc) {
305 soc = (camsys_soc_priv_t*)camsys_dev->soc;
307 (soc->soc_cfg)(Isp_SoftRst,(void*)(unsigned long)on);
309 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
312 camsys_err("camsys_dev->soc is NULL!");
318 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
320 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
321 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
322 unsigned long isp_clk;
324 if (on && !clk->in_on) {
325 rockchip_set_system_status(SYS_STATUS_ISP);
333 clk_set_rate(clk->isp,isp_clk);
334 clk_set_rate(clk->isp_jpe, isp_clk);
336 clk_prepare_enable(clk->pd_isp);
337 clk_prepare_enable(clk->aclk_isp);
338 clk_prepare_enable(clk->hclk_isp);
339 clk_prepare_enable(clk->isp);
340 clk_prepare_enable(clk->isp_jpe);
341 clk_prepare_enable(clk->pclkin_isp);
342 if(CHIP_TYPE == 3368){
344 clk_prepare_enable(clk->cif_clk_out);
345 clk_prepare_enable(clk->pclk_dphyrx);
346 clk_prepare_enable(clk->clk_vio0_noc);
348 clk_prepare_enable(clk->clk_mipi_24m);
352 camsys_trace(1, "%s clock(f: %ld Hz) in turn on",dev_name(camsys_dev->miscdev.this_device),isp_clk);
353 camsys_mrv_reset_cb(ptr,1);
355 camsys_mrv_reset_cb(ptr,0);
357 } else if (!on && clk->in_on) {
359 clk_disable_unprepare(clk->aclk_isp);
360 clk_disable_unprepare(clk->hclk_isp);
361 clk_disable_unprepare(clk->isp);
362 clk_disable_unprepare(clk->isp_jpe);
363 clk_disable_unprepare(clk->pclkin_isp);
364 if(CHIP_TYPE == 3368){
365 clk_disable_unprepare(clk->cif_clk_out);
366 clk_disable_unprepare(clk->pclk_dphyrx);
367 clk_disable_unprepare(clk->clk_vio0_noc);
370 clk_disable_unprepare(clk->clk_mipi_24m);
372 clk_disable_unprepare(clk->pd_isp);
374 rockchip_clear_system_status(SYS_STATUS_ISP);
376 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
381 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk)
383 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
384 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
386 mutex_lock(&clk->lock);
387 if (on && (clk->out_on != on)) {
389 clk_set_rate(clk->cif_clk_out,inclk);
390 clk_prepare_enable(clk->cif_clk_out);
393 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
395 } else if (!on && clk->out_on) {
396 if(!IS_ERR_OR_NULL(clk->cif_clk_pll)) {
397 clk_set_parent(clk->cif_clk_out, clk->cif_clk_pll);
399 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
402 clk_disable_unprepare( clk->cif_clk_out);
406 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
408 mutex_unlock(&clk->lock);
412 static irqreturn_t camsys_mrv_irq(int irq, void *data)
414 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
415 camsys_irqstas_t *irqsta;
416 camsys_irqpool_t *irqpool;
417 unsigned int isp_mis,mipi_mis,mi_mis,*mis,jpg_mis,jpg_err_mis;
419 unsigned int mi_ris,mi_imis;
421 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
422 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
423 jpg_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_MIS));
424 jpg_err_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ERR_MIS));
425 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
427 mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS));
428 mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS));
429 while((mi_ris & mi_imis) != mi_mis){
430 camsys_trace(2,"mi_mis status erro,mi_mis 0x%x,mi_ris 0x%x,imis 0x%x\n",mi_mis,mi_ris,mi_imis);
431 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
432 mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS));
433 mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS));
438 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
439 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
440 __raw_writel(jpg_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ICR));
441 __raw_writel(jpg_err_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ERR_ICR));
442 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
444 spin_lock(&camsys_dev->irq.lock);
445 if (!list_empty(&camsys_dev->irq.irq_pool)) {
446 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
447 if (irqpool->pid != 0) {
473 case MRV_JPG_ERR_MIS:
481 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
487 spin_lock(&irqpool->lock);
488 if (!list_empty(&irqpool->deactive)) {
489 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
490 irqsta->sta.mis = *mis;
491 list_del_init(&irqsta->list);
492 list_add_tail(&irqsta->list,&irqpool->active);
493 wake_up(&irqpool->done);
495 spin_unlock(&irqpool->lock);
501 spin_unlock(&camsys_dev->irq.lock);
505 static int camsys_mrv_remove_cb(struct platform_device *pdev)
507 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
508 camsys_mrv_clk_t *mrv_clk=NULL;
510 if (camsys_dev->clk != NULL) {
512 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
514 camsys_mrv_clkout_cb(mrv_clk,0,0);
516 camsys_mrv_clkin_cb(mrv_clk,0);
518 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
519 devm_clk_put(&pdev->dev,mrv_clk->pd_isp);
521 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
522 devm_clk_put(&pdev->dev,mrv_clk->aclk_isp);
524 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
525 devm_clk_put(&pdev->dev,mrv_clk->hclk_isp);
527 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
528 devm_clk_put(&pdev->dev,mrv_clk->isp);
530 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
531 devm_clk_put(&pdev->dev,mrv_clk->isp_jpe);
533 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
534 devm_clk_put(&pdev->dev,mrv_clk->pclkin_isp);
536 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
537 devm_clk_put(&pdev->dev,mrv_clk->cif_clk_out);
539 if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
540 devm_clk_put(&pdev->dev,mrv_clk->clk_vio0_noc);
549 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
552 camsys_mrv_clk_t *mrv_clk=NULL;
554 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, IRQF_SHARED, CAMSYS_MARVIN_IRQNAME,camsys_dev);
556 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
561 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
562 if (mrv_clk == NULL) {
563 camsys_err("Allocate camsys_mrv_clk_t failed!");
567 if(CHIP_TYPE == 3368){
568 mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
569 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
570 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
571 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
572 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
573 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
574 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
575 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
576 mrv_clk->pclk_dphyrx = devm_clk_get(&pdev->dev, "pclk_dphyrx");
577 mrv_clk->clk_vio0_noc = devm_clk_get(&pdev->dev, "clk_vio0_noc");
579 if (IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) ||
580 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
581 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)||
582 IS_ERR_OR_NULL(mrv_clk->pd_isp) || IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
583 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
588 mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
589 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
590 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
591 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
592 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
593 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
594 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
595 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
596 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
598 if (IS_ERR_OR_NULL(mrv_clk->pd_isp) || IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) ||
599 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
600 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
601 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
606 clk_set_rate(mrv_clk->isp,210000000);
607 clk_set_rate(mrv_clk->isp_jpe, 210000000);
609 mutex_init(&mrv_clk->lock);
611 mrv_clk->in_on = false;
614 camsys_dev->clk = (void*)mrv_clk;
615 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
616 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
617 camsys_dev->reset_cb = camsys_mrv_reset_cb;
618 camsys_dev->iomux = camsys_mrv_iomux_cb;
619 camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb;
620 camsys_dev->iommu_cb = camsys_mrv_iommu_cb;
622 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
623 camsys_dev->miscdev.name = miscdev_name;
624 camsys_dev->miscdev.nodename = miscdev_name;
625 camsys_dev->miscdev.fops = &camsys_fops;
627 err = misc_register(&camsys_dev->miscdev);
629 camsys_err("misc register %s failed!",miscdev_name);
630 goto misc_register_failed;
634 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
635 camsys_dev->platform_remove = camsys_mrv_remove_cb;
639 misc_register_failed:
640 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
641 misc_deregister(&camsys_dev->miscdev);
645 if (mrv_clk != NULL) {
646 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
647 clk_put(mrv_clk->pd_isp);
649 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
650 clk_put(mrv_clk->aclk_isp);
652 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
653 clk_put(mrv_clk->hclk_isp);
655 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
656 clk_put(mrv_clk->isp);
658 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
659 clk_put(mrv_clk->isp_jpe);
661 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
662 clk_put(mrv_clk->pclkin_isp);
664 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
665 clk_put(mrv_clk->cif_clk_out);
667 if(CHIP_TYPE == 3368){
668 if (!IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) {
669 clk_put(mrv_clk->pclk_dphyrx);
671 if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
672 clk_put(mrv_clk->clk_vio0_noc);
683 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);