@@ -1731,7 +1731,7 @@ static const struct component_ops exynos_dsi_component_ops = {
.unbind = exynos_dsi_unbind,
};
-static int exynos_dsi_probe(struct platform_device *pdev)
+static struct exynos_dsi *__exynos_dsi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
@@ -1740,7 +1740,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
/* To be checked as invalid one */
dsi->te_gpio = -ENOENT;
@@ -1763,14 +1763,14 @@ static int exynos_dsi_probe(struct platform_device *pdev)
if (ret) {
if (ret != -EPROBE_DEFER)
dev_info(dev, "failed to get regulators: %d\n", ret);
- return ret;
+ return ERR_PTR(ret);
}
dsi->clks = devm_kcalloc(dev,
dsi->driver_data->num_clks, sizeof(*dsi->clks),
GFP_KERNEL);
if (!dsi->clks)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
for (i = 0; i < dsi->driver_data->num_clks; i++) {
dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
@@ -1784,7 +1784,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dev_info(dev, "failed to get the clock: %s\n",
clk_names[i]);
- return PTR_ERR(dsi->clks[i]);
+ return ERR_PTR(PTR_ERR(dsi->clks[i]));
}
}
@@ -1792,18 +1792,18 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dsi->reg_base = devm_ioremap_resource(dev, res);
if (IS_ERR(dsi->reg_base)) {
dev_err(dev, "failed to remap io region\n");
- return PTR_ERR(dsi->reg_base);
+ return dsi->reg_base;
}
dsi->phy = devm_phy_get(dev, "dsim");
if (IS_ERR(dsi->phy)) {
dev_info(dev, "failed to get dsim phy\n");
- return PTR_ERR(dsi->phy);
+ return ERR_PTR(PTR_ERR(dsi->phy));
}
dsi->irq = platform_get_irq(pdev, 0);
if (dsi->irq < 0)
- return dsi->irq;
+ return ERR_PTR(dsi->irq);
irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
ret = devm_request_threaded_irq(dev, dsi->irq, NULL,
@@ -1811,13 +1811,29 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dev_name(dev), dsi);
if (ret) {
dev_err(dev, "failed to request dsi irq\n");
- return ret;
+ return ERR_PTR(ret);
}
ret = exynos_dsi_parse_dt(dsi);
if (ret)
- return ret;
+ return ERR_PTR(ret);
+
+ return dsi;
+}
+
+static void __exynos_dsi_remove(struct exynos_dsi *dsi)
+{
+}
+static int exynos_dsi_probe(struct platform_device *pdev)
+{
+ struct exynos_dsi *dsi;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ dsi = __exynos_dsi_probe(pdev);
+ if (IS_ERR(dsi))
+ return PTR_ERR(dsi);
platform_set_drvdata(pdev, dsi);
pm_runtime_enable(dev);
@@ -1836,8 +1852,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
static int exynos_dsi_remove(struct platform_device *pdev)
{
+ struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
pm_runtime_disable(&pdev->dev);
+ __exynos_dsi_remove(dsi);
+
component_del(&pdev->dev, &exynos_dsi_component_ops);
return 0;
As the driver shall be usable with drivers that use the component framework and drivers that don't, split the common probing code into a separate function that can be called from different locations. Signed-off-by: Michael Tretter <m.tretter@pengutronix.de> --- v2: - move pm_runtime_enable from helper to calling function --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-)