static int fimc_lite_remove(struct platform_device *pdev) { struct fimc_lite *fimc = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; pm_runtime_disable(dev); pm_runtime_set_suspended(dev); fimc_lite_unregister_capture_subdev(fimc); vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); fimc_lite_clk_put(fimc); dev_info(dev, "Driver unloaded\n"); return 0; }
static int fimc_lite_probe(struct platform_device *pdev) { struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev); struct fimc_lite *fimc; struct resource *res; int ret; fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL); if (!fimc) return -ENOMEM; fimc->index = pdev->id; fimc->variant = drv_data->variant[fimc->index]; fimc->pdev = pdev; init_waitqueue_head(&fimc->irq_queue); spin_lock_init(&fimc->slock); mutex_init(&fimc->lock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); fimc->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(fimc->regs)) return PTR_ERR(fimc->regs); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "Failed to get IRQ resource\n"); return -ENXIO; } ret = fimc_lite_clk_get(fimc); if (ret) return ret; ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler, 0, dev_name(&pdev->dev), fimc); if (ret) { dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret); goto err_clk; } /* The video node will be created within the subdev's registered() op */ ret = fimc_lite_create_capture_subdev(fimc); if (ret) goto err_clk; platform_set_drvdata(pdev, fimc); pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) goto err_sd; fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); if (IS_ERR(fimc->alloc_ctx)) { ret = PTR_ERR(fimc->alloc_ctx); goto err_pm; } pm_runtime_put(&pdev->dev); dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n", fimc->index); return 0; err_pm: pm_runtime_put(&pdev->dev); err_sd: fimc_lite_unregister_capture_subdev(fimc); err_clk: fimc_lite_clk_put(fimc); return ret; }
static int fimc_lite_probe(struct platform_device *pdev) { struct flite_drvdata *drv_data = NULL; struct device *dev = &pdev->dev; const struct of_device_id *of_id; struct fimc_lite *fimc; struct resource *res; int ret; if (!dev->of_node) return -ENODEV; fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL); if (!fimc) return -ENOMEM; of_id = of_match_node(flite_of_match, dev->of_node); if (of_id) drv_data = (struct flite_drvdata *)of_id->data; fimc->index = of_alias_get_id(dev->of_node, "fimc-lite"); if (!drv_data || fimc->index >= drv_data->num_instances || fimc->index < 0) { dev_err(dev, "Wrong %s node alias\n", dev->of_node->full_name); return -EINVAL; } fimc->dd = drv_data; fimc->pdev = pdev; init_waitqueue_head(&fimc->irq_queue); spin_lock_init(&fimc->slock); mutex_init(&fimc->lock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); fimc->regs = devm_ioremap_resource(dev, res); if (IS_ERR(fimc->regs)) return PTR_ERR(fimc->regs); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(dev, "Failed to get IRQ resource\n"); return -ENXIO; } ret = fimc_lite_clk_get(fimc); if (ret) return ret; ret = devm_request_irq(dev, res->start, flite_irq_handler, 0, dev_name(dev), fimc); if (ret) { dev_err(dev, "Failed to install irq (%d)\n", ret); goto err_clk_put; } /* The video node will be created within the subdev's registered() op */ ret = fimc_lite_create_capture_subdev(fimc); if (ret) goto err_clk_put; platform_set_drvdata(pdev, fimc); pm_runtime_enable(dev); if (!pm_runtime_enabled(dev)) { ret = clk_enable(fimc->clock); if (ret < 0) goto err_sd; } fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); if (IS_ERR(fimc->alloc_ctx)) { ret = PTR_ERR(fimc->alloc_ctx); goto err_clk_dis; } fimc_lite_set_default_config(fimc); dev_dbg(dev, "FIMC-LITE.%d registered successfully\n", fimc->index); return 0; err_clk_dis: if (!pm_runtime_enabled(dev)) clk_disable(fimc->clock); err_sd: fimc_lite_unregister_capture_subdev(fimc); err_clk_put: fimc_lite_clk_put(fimc); return ret; }