diff mbox

[PATCHv3,2/4] drm/tilcdc: Stop using struct drm_driver load() callback

Message ID e7e27520e1c01e29ae7d559855fe0cc651a65d76.1478102115.git.jsarha@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jyri Sarha Nov. 2, 2016, 3:57 p.m. UTC
Stop using struct drm_driver load() and unload() callbacks. The
callbacks should not be used anymore. Instead of using load the
drm_device is allocated with drm_dev_alloc() and registered with
drm_dev_register() only after the driver is completely initialized.
The deinitialization is done directly either in component unbind
callback or in platform driver demove callback.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 124 ++++++++++++++++++++----------------
 1 file changed, 70 insertions(+), 54 deletions(-)

Comments

Laurent Pinchart Nov. 3, 2016, 6:15 p.m. UTC | #1
Hi Jyri,

Thank you for the patch.

On Wednesday 02 Nov 2016 17:57:50 Jyri Sarha wrote:
> Stop using struct drm_driver load() and unload() callbacks. The
> callbacks should not be used anymore. Instead of using load the
> drm_device is allocated with drm_dev_alloc() and registered with
> drm_dev_register() only after the driver is completely initialized.
> The deinitialization is done directly either in component unbind
> callback or in platform driver demove callback.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c | 124 ++++++++++++++++++--------------
>  1 file changed, 70 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 5cf534c..11f3262 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -194,18 +194,22 @@ static int cpufreq_transition(struct notifier_block
> *nb, * DRM operations:
>   */
> 
> -static int tilcdc_unload(struct drm_device *dev)
> +static void tilcdc_fini(struct drm_device *dev)
>  {
>  	struct tilcdc_drm_private *priv = dev->dev_private;
> 
> -	tilcdc_remove_external_encoders(dev);
> +	drm_modeset_lock_crtc(priv->crtc, NULL);
> +	tilcdc_crtc_disable(priv->crtc);
> +	drm_modeset_unlock_crtc(priv->crtc);
> +
> +	drm_dev_unregister(dev);
> 
> -	drm_fbdev_cma_fini(priv->fbdev);
>  	drm_kms_helper_poll_fini(dev);
> +	drm_fbdev_cma_fini(priv->fbdev);

Is there a need to reorder these ?

> +	drm_irq_uninstall(dev);
>  	drm_mode_config_cleanup(dev);
> -	drm_vblank_cleanup(dev);
> 
> -	drm_irq_uninstall(dev);
> +	tilcdc_remove_external_encoders(dev);
> 
>  #ifdef CONFIG_CPU_FREQ
>  	cpufreq_unregister_notifier(&priv->freq_transition,
> @@ -225,28 +229,34 @@ static int tilcdc_unload(struct drm_device *dev)
> 
>  	pm_runtime_disable(dev->dev);
> 
> -	return 0;
> +	drm_dev_unref(dev);
>  }
> 
> -static int tilcdc_load(struct drm_device *dev, unsigned long flags)
> +static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
>  {
> -	struct platform_device *pdev = dev->platformdev;
> -	struct device_node *node = pdev->dev.of_node;
> +	struct drm_device *ddev;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct device_node *node = dev->of_node;
>  	struct tilcdc_drm_private *priv;
>  	struct resource *res;
>  	u32 bpp = 0;
>  	int ret;
> 
> -	priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>  	if (!priv) {
> -		dev_err(dev->dev, "failed to allocate private data\n");
> +		dev_err(dev, "failed to allocate private data\n");
>  		return -ENOMEM;
>  	}
> 
> -	dev->dev_private = priv;
> +	ddev = drm_dev_alloc(ddrv, dev);

As a follow-up patch you might want to move tilcdc_driver above this function 
and use it directly to remove the ddrv argument.

Apart from that,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	if (IS_ERR(ddev))
> +		return PTR_ERR(ddev);
> +
> +	ddev->platformdev = pdev;
> +	ddev->dev_private = priv;

[snip]
Jyri Sarha Nov. 3, 2016, 8:11 p.m. UTC | #2
On 11/03/16 20:15, Laurent Pinchart wrote:
> Hi Jyri,
> 
> Thank you for the patch.
> 
> On Wednesday 02 Nov 2016 17:57:50 Jyri Sarha wrote:
>> Stop using struct drm_driver load() and unload() callbacks. The
>> callbacks should not be used anymore. Instead of using load the
>> drm_device is allocated with drm_dev_alloc() and registered with
>> drm_dev_register() only after the driver is completely initialized.
>> The deinitialization is done directly either in component unbind
>> callback or in platform driver demove callback.
>>
>> Signed-off-by: Jyri Sarha <jsarha@ti.com>
>> ---
>>  drivers/gpu/drm/tilcdc/tilcdc_drv.c | 124 ++++++++++++++++++--------------
>>  1 file changed, 70 insertions(+), 54 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 5cf534c..11f3262 100644
>> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> @@ -194,18 +194,22 @@ static int cpufreq_transition(struct notifier_block
>> *nb, * DRM operations:
>>   */
>>
>> -static int tilcdc_unload(struct drm_device *dev)
>> +static void tilcdc_fini(struct drm_device *dev)
>>  {
>>  	struct tilcdc_drm_private *priv = dev->dev_private;
>>
>> -	tilcdc_remove_external_encoders(dev);
>> +	drm_modeset_lock_crtc(priv->crtc, NULL);
>> +	tilcdc_crtc_disable(priv->crtc);
>> +	drm_modeset_unlock_crtc(priv->crtc);
>> +
>> +	drm_dev_unregister(dev);
>>
>> -	drm_fbdev_cma_fini(priv->fbdev);
>>  	drm_kms_helper_poll_fini(dev);
>> +	drm_fbdev_cma_fini(priv->fbdev);
> 
> Is there a need to reorder these ?

I am not sure actually. When the things did not work properly in the
beginning I just ordered unloading to happen strictly in the reverse
order compared to loading. I did not go back to check what changes were
actually needed when I got things working.

> 
>> +	drm_irq_uninstall(dev);
>>  	drm_mode_config_cleanup(dev);
>> -	drm_vblank_cleanup(dev);
>>
>> -	drm_irq_uninstall(dev);
>> +	tilcdc_remove_external_encoders(dev);
>>
>>  #ifdef CONFIG_CPU_FREQ
>>  	cpufreq_unregister_notifier(&priv->freq_transition,
>> @@ -225,28 +229,34 @@ static int tilcdc_unload(struct drm_device *dev)
>>
>>  	pm_runtime_disable(dev->dev);
>>
>> -	return 0;
>> +	drm_dev_unref(dev);
>>  }
>>
>> -static int tilcdc_load(struct drm_device *dev, unsigned long flags)
>> +static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
>>  {
>> -	struct platform_device *pdev = dev->platformdev;
>> -	struct device_node *node = pdev->dev.of_node;
>> +	struct drm_device *ddev;
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct device_node *node = dev->of_node;
>>  	struct tilcdc_drm_private *priv;
>>  	struct resource *res;
>>  	u32 bpp = 0;
>>  	int ret;
>>
>> -	priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
>> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>  	if (!priv) {
>> -		dev_err(dev->dev, "failed to allocate private data\n");
>> +		dev_err(dev, "failed to allocate private data\n");
>>  		return -ENOMEM;
>>  	}
>>
>> -	dev->dev_private = priv;
>> +	ddev = drm_dev_alloc(ddrv, dev);
> 
> As a follow-up patch you might want to move tilcdc_driver above this function 
> and use it directly to remove the ddrv argument.
> 

Ok, thanks.

> Apart from that,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> +	if (IS_ERR(ddev))
>> +		return PTR_ERR(ddev);
>> +
>> +	ddev->platformdev = pdev;
>> +	ddev->dev_private = priv;
> 
> [snip]
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 5cf534c..11f3262 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -194,18 +194,22 @@  static int cpufreq_transition(struct notifier_block *nb,
  * DRM operations:
  */
 
-static int tilcdc_unload(struct drm_device *dev)
+static void tilcdc_fini(struct drm_device *dev)
 {
 	struct tilcdc_drm_private *priv = dev->dev_private;
 
-	tilcdc_remove_external_encoders(dev);
+	drm_modeset_lock_crtc(priv->crtc, NULL);
+	tilcdc_crtc_disable(priv->crtc);
+	drm_modeset_unlock_crtc(priv->crtc);
+
+	drm_dev_unregister(dev);
 
-	drm_fbdev_cma_fini(priv->fbdev);
 	drm_kms_helper_poll_fini(dev);
+	drm_fbdev_cma_fini(priv->fbdev);
+	drm_irq_uninstall(dev);
 	drm_mode_config_cleanup(dev);
-	drm_vblank_cleanup(dev);
 
-	drm_irq_uninstall(dev);
+	tilcdc_remove_external_encoders(dev);
 
 #ifdef CONFIG_CPU_FREQ
 	cpufreq_unregister_notifier(&priv->freq_transition,
@@ -225,28 +229,34 @@  static int tilcdc_unload(struct drm_device *dev)
 
 	pm_runtime_disable(dev->dev);
 
-	return 0;
+	drm_dev_unref(dev);
 }
 
-static int tilcdc_load(struct drm_device *dev, unsigned long flags)
+static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
 {
-	struct platform_device *pdev = dev->platformdev;
-	struct device_node *node = pdev->dev.of_node;
+	struct drm_device *ddev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct device_node *node = dev->of_node;
 	struct tilcdc_drm_private *priv;
 	struct resource *res;
 	u32 bpp = 0;
 	int ret;
 
-	priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
-		dev_err(dev->dev, "failed to allocate private data\n");
+		dev_err(dev, "failed to allocate private data\n");
 		return -ENOMEM;
 	}
 
-	dev->dev_private = priv;
+	ddev = drm_dev_alloc(ddrv, dev);
+	if (IS_ERR(ddev))
+		return PTR_ERR(ddev);
+
+	ddev->platformdev = pdev;
+	ddev->dev_private = priv;
 
 	priv->is_componentized =
-		tilcdc_get_external_components(dev->dev, NULL) > 0;
+		tilcdc_get_external_components(dev, NULL) > 0;
 
 	priv->wq = alloc_ordered_workqueue("tilcdc", 0);
 	if (!priv->wq) {
@@ -256,21 +266,21 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(dev->dev, "failed to get memory resource\n");
+		dev_err(dev, "failed to get memory resource\n");
 		ret = -EINVAL;
 		goto fail_free_wq;
 	}
 
 	priv->mmio = ioremap_nocache(res->start, resource_size(res));
 	if (!priv->mmio) {
-		dev_err(dev->dev, "failed to ioremap\n");
+		dev_err(dev, "failed to ioremap\n");
 		ret = -ENOMEM;
 		goto fail_free_wq;
 	}
 
-	priv->clk = clk_get(dev->dev, "fck");
+	priv->clk = clk_get(dev, "fck");
 	if (IS_ERR(priv->clk)) {
-		dev_err(dev->dev, "failed to get functional clock\n");
+		dev_err(dev, "failed to get functional clock\n");
 		ret = -ENODEV;
 		goto fail_iounmap;
 	}
@@ -280,7 +290,7 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 	ret = cpufreq_register_notifier(&priv->freq_transition,
 			CPUFREQ_TRANSITION_NOTIFIER);
 	if (ret) {
-		dev_err(dev->dev, "failed to register cpufreq notifier\n");
+		dev_err(dev, "failed to register cpufreq notifier\n");
 		goto fail_put_clk;
 	}
 #endif
@@ -301,11 +311,11 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 
 	DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock);
 
-	pm_runtime_enable(dev->dev);
+	pm_runtime_enable(dev);
 
 	/* Determine LCD IP Version */
-	pm_runtime_get_sync(dev->dev);
-	switch (tilcdc_read(dev, LCDC_PID_REG)) {
+	pm_runtime_get_sync(dev);
+	switch (tilcdc_read(ddev, LCDC_PID_REG)) {
 	case 0x4c100102:
 		priv->rev = 1;
 		break;
@@ -314,14 +324,14 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 		priv->rev = 2;
 		break;
 	default:
-		dev_warn(dev->dev, "Unknown PID Reg value 0x%08x, "
-				"defaulting to LCD revision 1\n",
-				tilcdc_read(dev, LCDC_PID_REG));
+		dev_warn(dev, "Unknown PID Reg value 0x%08x, "
+			"defaulting to LCD revision 1\n",
+			tilcdc_read(ddev, LCDC_PID_REG));
 		priv->rev = 1;
 		break;
 	}
 
-	pm_runtime_put_sync(dev->dev);
+	pm_runtime_put_sync(dev);
 
 	if (priv->rev == 1) {
 		DBG("Revision 1 LCDC supports only RGB565 format");
@@ -354,74 +364,82 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 		}
 	}
 
-	ret = modeset_init(dev);
+	ret = modeset_init(ddev);
 	if (ret < 0) {
-		dev_err(dev->dev, "failed to initialize mode setting\n");
+		dev_err(dev, "failed to initialize mode setting\n");
 		goto fail_cpufreq_unregister;
 	}
 
-	platform_set_drvdata(pdev, dev);
+	platform_set_drvdata(pdev, ddev);
 
 	if (priv->is_componentized) {
-		ret = component_bind_all(dev->dev, dev);
+		ret = component_bind_all(dev, ddev);
 		if (ret < 0)
 			goto fail_mode_config_cleanup;
 
-		ret = tilcdc_add_external_encoders(dev);
+		ret = tilcdc_add_external_encoders(ddev);
 		if (ret < 0)
 			goto fail_component_cleanup;
 	}
 
 	if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) {
-		dev_err(dev->dev, "no encoders/connectors found\n");
+		dev_err(dev, "no encoders/connectors found\n");
 		ret = -ENXIO;
 		goto fail_external_cleanup;
 	}
 
-	ret = drm_vblank_init(dev, 1);
+	ret = drm_vblank_init(ddev, 1);
 	if (ret < 0) {
-		dev_err(dev->dev, "failed to initialize vblank\n");
+		dev_err(dev, "failed to initialize vblank\n");
 		goto fail_external_cleanup;
 	}
 
-	ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
+	ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
 	if (ret < 0) {
-		dev_err(dev->dev, "failed to install IRQ handler\n");
+		dev_err(dev, "failed to install IRQ handler\n");
 		goto fail_vblank_cleanup;
 	}
 
-	drm_mode_config_reset(dev);
+	drm_mode_config_reset(ddev);
 
-	priv->fbdev = drm_fbdev_cma_init(dev, bpp,
-			dev->mode_config.num_crtc,
-			dev->mode_config.num_connector);
+	priv->fbdev = drm_fbdev_cma_init(ddev, bpp,
+			ddev->mode_config.num_crtc,
+			ddev->mode_config.num_connector);
 	if (IS_ERR(priv->fbdev)) {
 		ret = PTR_ERR(priv->fbdev);
 		goto fail_irq_uninstall;
 	}
 
-	drm_kms_helper_poll_init(dev);
+	drm_kms_helper_poll_init(ddev);
+
+	ret = drm_dev_register(ddev, 0);
+	if (ret)
+		goto fail_platform_init;
 
 	return 0;
 
+fail_platform_init:
+	drm_kms_helper_poll_fini(ddev);
+	drm_fbdev_cma_fini(priv->fbdev);
+
 fail_irq_uninstall:
-	drm_irq_uninstall(dev);
+	drm_irq_uninstall(ddev);
 
 fail_vblank_cleanup:
-	drm_vblank_cleanup(dev);
+	drm_vblank_cleanup(ddev);
 
 fail_component_cleanup:
 	if (priv->is_componentized)
-		component_unbind_all(dev->dev, dev);
+		component_unbind_all(dev, dev);
 
 fail_mode_config_cleanup:
-	drm_mode_config_cleanup(dev);
+	drm_mode_config_cleanup(ddev);
 
 fail_external_cleanup:
-	tilcdc_remove_external_encoders(dev);
+	tilcdc_remove_external_encoders(ddev);
 
 fail_cpufreq_unregister:
-	pm_runtime_disable(dev->dev);
+	pm_runtime_disable(dev);
 #ifdef CONFIG_CPU_FREQ
 	cpufreq_unregister_notifier(&priv->freq_transition,
 			CPUFREQ_TRANSITION_NOTIFIER);
@@ -438,7 +456,8 @@  static int tilcdc_load(struct drm_device *dev, unsigned long flags)
 	destroy_workqueue(priv->wq);
 
 fail_unset_priv:
-	dev->dev_private = NULL;
+	ddev->dev_private = NULL;
+	drm_dev_unref(ddev);
 
 	return ret;
 }
@@ -585,8 +604,6 @@  static void tilcdc_debugfs_cleanup(struct drm_minor *minor)
 static struct drm_driver tilcdc_driver = {
 	.driver_features    = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET |
 			       DRIVER_PRIME | DRIVER_ATOMIC),
-	.load               = tilcdc_load,
-	.unload             = tilcdc_unload,
 	.lastclose          = tilcdc_lastclose,
 	.irq_handler        = tilcdc_irq,
 	.get_vblank_counter = drm_vblank_no_hw_counter,
@@ -660,10 +677,9 @@  static int tilcdc_pm_resume(struct device *dev)
 /*
  * Platform driver:
  */
-
 static int tilcdc_bind(struct device *dev)
 {
-	return drm_platform_init(&tilcdc_driver, to_platform_device(dev));
+	return tilcdc_init(&tilcdc_driver, dev);
 }
 
 static void tilcdc_unbind(struct device *dev)
@@ -674,7 +690,7 @@  static void tilcdc_unbind(struct device *dev)
 	if (!ddev->dev_private)
 		return;
 
-	drm_put_dev(dev_get_drvdata(dev));
+	tilcdc_fini(dev_get_drvdata(dev));
 }
 
 static const struct component_master_ops tilcdc_comp_ops = {
@@ -697,7 +713,7 @@  static int tilcdc_pdev_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 	else if (ret == 0)
-		return drm_platform_init(&tilcdc_driver, pdev);
+		return tilcdc_init(&tilcdc_driver, &pdev->dev);
 	else
 		return component_master_add_with_match(&pdev->dev,
 						       &tilcdc_comp_ops,
@@ -712,7 +728,7 @@  static int tilcdc_pdev_remove(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 	else if (ret == 0)
-		drm_put_dev(platform_get_drvdata(pdev));
+		tilcdc_fini(platform_get_drvdata(pdev));
 	else
 		component_master_del(&pdev->dev, &tilcdc_comp_ops);