static int fimc_is_runtime_resume(struct device *dev) { struct fimc_is *is = dev_get_drvdata(dev); int ret; ret = fimc_is_setup_clocks(is); if (ret) return ret; return fimc_is_enable_clocks(is); }
static int fimc_is_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct fimc_is *is; struct resource res; struct device_node *node; int ret; is = devm_kzalloc(&pdev->dev, sizeof(*is), GFP_KERNEL); if (!is) return -ENOMEM; is->pdev = pdev; is->isp.pdev = pdev; init_waitqueue_head(&is->irq_queue); spin_lock_init(&is->slock); mutex_init(&is->lock); ret = of_address_to_resource(dev->of_node, 0, &res); if (ret < 0) return ret; is->regs = devm_ioremap_resource(dev, &res); if (IS_ERR(is->regs)) return PTR_ERR(is->regs); node = of_get_child_by_name(dev->of_node, "pmu"); if (!node) return -ENODEV; is->pmu_regs = of_iomap(node, 0); if (!is->pmu_regs) return -ENOMEM; is->irq = irq_of_parse_and_map(dev->of_node, 0); if (is->irq < 0) { dev_err(dev, "no irq found\n"); return is->irq; } ret = fimc_is_get_clocks(is); if (ret < 0) return ret; platform_set_drvdata(pdev, is); ret = request_irq(is->irq, fimc_is_irq_handler, 0, dev_name(dev), is); if (ret < 0) { dev_err(dev, "irq request failed\n"); goto err_clk; } pm_runtime_enable(dev); /* * Enable only the ISP power domain, keep FIMC-IS clocks off until * the whole clock tree is configured. The ISP power domain needs * be active in order to acces any CMU_ISP clock registers. */ ret = pm_runtime_get_sync(dev); if (ret < 0) goto err_irq; ret = fimc_is_setup_clocks(is); pm_runtime_put_sync(dev); if (ret < 0) goto err_irq; is->clk_init = true; is->alloc_ctx = vb2_dma_contig_init_ctx(dev); if (IS_ERR(is->alloc_ctx)) { ret = PTR_ERR(is->alloc_ctx); goto err_irq; } /* * Register FIMC-IS V4L2 subdevs to this driver. The video nodes * will be created within the subdev's registered() callback. */ ret = fimc_is_register_subdevs(is); if (ret < 0) goto err_vb; ret = fimc_is_debugfs_create(is); if (ret < 0) goto err_sd; ret = fimc_is_request_firmware(is, FIMC_IS_FW_FILENAME); if (ret < 0) goto err_dfs; dev_dbg(dev, "FIMC-IS registered successfully\n"); return 0; err_dfs: fimc_is_debugfs_remove(is); err_vb: vb2_dma_contig_cleanup_ctx(is->alloc_ctx); err_sd: fimc_is_unregister_subdevs(is); err_irq: free_irq(is->irq, is); err_clk: fimc_is_put_clocks(is); return ret; }