diff options
author | Jyri Sarha <jsarha@ti.com> | 2016-10-17 10:53:33 -0400 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2016-11-29 14:03:19 -0500 |
commit | 923310ba73d742450bb41bb017cb1b6704bd32b5 (patch) | |
tree | a43537c6a25e39c0ccc550be038b8a83f10a3f75 /drivers/gpu/drm/tilcdc | |
parent | 15d704e53c7d870f58558839eadfca7bcb8de5f5 (diff) |
drm/tilcdc: Stop using struct drm_driver load() callback
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>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_drv.c | 124 |
1 files changed, 70 insertions, 54 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 8f897fe2332e..c54e92a207fe 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, | |||
194 | * DRM operations: | 194 | * DRM operations: |
195 | */ | 195 | */ |
196 | 196 | ||
197 | static int tilcdc_unload(struct drm_device *dev) | 197 | static void tilcdc_fini(struct drm_device *dev) |
198 | { | 198 | { |
199 | struct tilcdc_drm_private *priv = dev->dev_private; | 199 | struct tilcdc_drm_private *priv = dev->dev_private; |
200 | 200 | ||
201 | tilcdc_remove_external_encoders(dev); | 201 | drm_modeset_lock_crtc(priv->crtc, NULL); |
202 | tilcdc_crtc_disable(priv->crtc); | ||
203 | drm_modeset_unlock_crtc(priv->crtc); | ||
204 | |||
205 | drm_dev_unregister(dev); | ||
202 | 206 | ||
203 | drm_fbdev_cma_fini(priv->fbdev); | ||
204 | drm_kms_helper_poll_fini(dev); | 207 | drm_kms_helper_poll_fini(dev); |
208 | drm_fbdev_cma_fini(priv->fbdev); | ||
209 | drm_irq_uninstall(dev); | ||
205 | drm_mode_config_cleanup(dev); | 210 | drm_mode_config_cleanup(dev); |
206 | drm_vblank_cleanup(dev); | ||
207 | 211 | ||
208 | drm_irq_uninstall(dev); | 212 | tilcdc_remove_external_encoders(dev); |
209 | 213 | ||
210 | #ifdef CONFIG_CPU_FREQ | 214 | #ifdef CONFIG_CPU_FREQ |
211 | cpufreq_unregister_notifier(&priv->freq_transition, | 215 | cpufreq_unregister_notifier(&priv->freq_transition, |
@@ -225,28 +229,34 @@ static int tilcdc_unload(struct drm_device *dev) | |||
225 | 229 | ||
226 | pm_runtime_disable(dev->dev); | 230 | pm_runtime_disable(dev->dev); |
227 | 231 | ||
228 | return 0; | 232 | drm_dev_unref(dev); |
229 | } | 233 | } |
230 | 234 | ||
231 | static int tilcdc_load(struct drm_device *dev, unsigned long flags) | 235 | static int tilcdc_init(struct drm_driver *ddrv, struct device *dev) |
232 | { | 236 | { |
233 | struct platform_device *pdev = dev->platformdev; | 237 | struct drm_device *ddev; |
234 | struct device_node *node = pdev->dev.of_node; | 238 | struct platform_device *pdev = to_platform_device(dev); |
239 | struct device_node *node = dev->of_node; | ||
235 | struct tilcdc_drm_private *priv; | 240 | struct tilcdc_drm_private *priv; |
236 | struct resource *res; | 241 | struct resource *res; |
237 | u32 bpp = 0; | 242 | u32 bpp = 0; |
238 | int ret; | 243 | int ret; |
239 | 244 | ||
240 | priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); | 245 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
241 | if (!priv) { | 246 | if (!priv) { |
242 | dev_err(dev->dev, "failed to allocate private data\n"); | 247 | dev_err(dev, "failed to allocate private data\n"); |
243 | return -ENOMEM; | 248 | return -ENOMEM; |
244 | } | 249 | } |
245 | 250 | ||
246 | dev->dev_private = priv; | 251 | ddev = drm_dev_alloc(ddrv, dev); |
252 | if (IS_ERR(ddev)) | ||
253 | return PTR_ERR(ddev); | ||
254 | |||
255 | ddev->platformdev = pdev; | ||
256 | ddev->dev_private = priv; | ||
247 | 257 | ||
248 | priv->is_componentized = | 258 | priv->is_componentized = |
249 | tilcdc_get_external_components(dev->dev, NULL) > 0; | 259 | tilcdc_get_external_components(dev, NULL) > 0; |
250 | 260 | ||
251 | priv->wq = alloc_ordered_workqueue("tilcdc", 0); | 261 | priv->wq = alloc_ordered_workqueue("tilcdc", 0); |
252 | if (!priv->wq) { | 262 | if (!priv->wq) { |
@@ -256,21 +266,21 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
256 | 266 | ||
257 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 267 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
258 | if (!res) { | 268 | if (!res) { |
259 | dev_err(dev->dev, "failed to get memory resource\n"); | 269 | dev_err(dev, "failed to get memory resource\n"); |
260 | ret = -EINVAL; | 270 | ret = -EINVAL; |
261 | goto fail_free_wq; | 271 | goto fail_free_wq; |
262 | } | 272 | } |
263 | 273 | ||
264 | priv->mmio = ioremap_nocache(res->start, resource_size(res)); | 274 | priv->mmio = ioremap_nocache(res->start, resource_size(res)); |
265 | if (!priv->mmio) { | 275 | if (!priv->mmio) { |
266 | dev_err(dev->dev, "failed to ioremap\n"); | 276 | dev_err(dev, "failed to ioremap\n"); |
267 | ret = -ENOMEM; | 277 | ret = -ENOMEM; |
268 | goto fail_free_wq; | 278 | goto fail_free_wq; |
269 | } | 279 | } |
270 | 280 | ||
271 | priv->clk = clk_get(dev->dev, "fck"); | 281 | priv->clk = clk_get(dev, "fck"); |
272 | if (IS_ERR(priv->clk)) { | 282 | if (IS_ERR(priv->clk)) { |
273 | dev_err(dev->dev, "failed to get functional clock\n"); | 283 | dev_err(dev, "failed to get functional clock\n"); |
274 | ret = -ENODEV; | 284 | ret = -ENODEV; |
275 | goto fail_iounmap; | 285 | goto fail_iounmap; |
276 | } | 286 | } |
@@ -280,7 +290,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
280 | ret = cpufreq_register_notifier(&priv->freq_transition, | 290 | ret = cpufreq_register_notifier(&priv->freq_transition, |
281 | CPUFREQ_TRANSITION_NOTIFIER); | 291 | CPUFREQ_TRANSITION_NOTIFIER); |
282 | if (ret) { | 292 | if (ret) { |
283 | dev_err(dev->dev, "failed to register cpufreq notifier\n"); | 293 | dev_err(dev, "failed to register cpufreq notifier\n"); |
284 | goto fail_put_clk; | 294 | goto fail_put_clk; |
285 | } | 295 | } |
286 | #endif | 296 | #endif |
@@ -301,11 +311,11 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
301 | 311 | ||
302 | DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); | 312 | DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); |
303 | 313 | ||
304 | pm_runtime_enable(dev->dev); | 314 | pm_runtime_enable(dev); |
305 | 315 | ||
306 | /* Determine LCD IP Version */ | 316 | /* Determine LCD IP Version */ |
307 | pm_runtime_get_sync(dev->dev); | 317 | pm_runtime_get_sync(dev); |
308 | switch (tilcdc_read(dev, LCDC_PID_REG)) { | 318 | switch (tilcdc_read(ddev, LCDC_PID_REG)) { |
309 | case 0x4c100102: | 319 | case 0x4c100102: |
310 | priv->rev = 1; | 320 | priv->rev = 1; |
311 | break; | 321 | break; |
@@ -314,14 +324,14 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
314 | priv->rev = 2; | 324 | priv->rev = 2; |
315 | break; | 325 | break; |
316 | default: | 326 | default: |
317 | dev_warn(dev->dev, "Unknown PID Reg value 0x%08x, " | 327 | dev_warn(dev, "Unknown PID Reg value 0x%08x, " |
318 | "defaulting to LCD revision 1\n", | 328 | "defaulting to LCD revision 1\n", |
319 | tilcdc_read(dev, LCDC_PID_REG)); | 329 | tilcdc_read(ddev, LCDC_PID_REG)); |
320 | priv->rev = 1; | 330 | priv->rev = 1; |
321 | break; | 331 | break; |
322 | } | 332 | } |
323 | 333 | ||
324 | pm_runtime_put_sync(dev->dev); | 334 | pm_runtime_put_sync(dev); |
325 | 335 | ||
326 | if (priv->rev == 1) { | 336 | if (priv->rev == 1) { |
327 | DBG("Revision 1 LCDC supports only RGB565 format"); | 337 | DBG("Revision 1 LCDC supports only RGB565 format"); |
@@ -354,74 +364,82 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) | |||
354 | } | 364 | } |
355 | } | 365 | } |
356 | 366 | ||
357 | ret = modeset_init(dev); | 367 | ret = modeset_init(ddev); |
358 | if (ret < 0) { | 368 | if (ret < 0) { |
359 | dev_err(dev->dev, "failed to initialize mode setting\n"); | 369 | dev_err(dev, "failed to initialize mode setting\n"); |
360 | goto fail_cpufreq_unregister; | 370 | goto fail_cpufreq_unregister; |
361 | } | 371 | } |
362 | 372 | ||
363 | platform_set_drvdata(pdev, dev); | 373 | platform_set_drvdata(pdev, ddev); |
364 | 374 | ||
365 | if (priv->is_componentized) { | 375 | if (priv->is_componentized) { |
366 | ret = component_bind_all(dev->dev, dev); | 376 | ret = component_bind_all(dev, ddev); |
367 | if (ret < 0) | 377 | if (ret < 0) |
368 | goto fail_mode_config_cleanup; | 378 | goto fail_mode_config_cleanup; |
369 | 379 | ||
370 | ret = tilcdc_add_external_encoders(dev); | 380 | ret = tilcdc_add_external_encoders(ddev); |
371 | if (ret < 0) | 381 | if (ret < 0) |
372 | goto fail_component_cleanup; | 382 | goto fail_component_cleanup; |
373 | } | 383 | } |
374 | 384 | ||
375 | if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) { | 385 | if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) { |
376 | dev_err(dev->dev, "no encoders/connectors found\n"); | 386 | dev_err(dev, "no encoders/connectors found\n"); |
377 | ret = -ENXIO; | 387 | ret = -ENXIO; |
378 | goto fail_external_cleanup; | 388 | goto fail_external_cleanup; |
379 | } | 389 | } |
380 | 390 | ||
381 | ret = drm_vblank_init(dev, 1); | 391 | ret = drm_vblank_init(ddev, 1); |
382 | if (ret < 0) { | 392 | if (ret < 0) { |
383 | dev_err(dev->dev, "failed to initialize vblank\n"); | 393 | dev_err(dev, "failed to initialize vblank\n"); |
384 | goto fail_external_cleanup; | 394 | goto fail_external_cleanup; |
385 | } | 395 | } |
386 | 396 | ||
387 | ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0)); | 397 | ret = drm_irq_install(ddev, platform_get_irq(pdev, 0)); |
388 | if (ret < 0) { | 398 | if (ret < 0) { |
389 | dev_err(dev->dev, "failed to install IRQ handler\n"); | 399 | dev_err(dev, "failed to install IRQ handler\n"); |
390 | goto fail_vblank_cleanup; | 400 | goto fail_vblank_cleanup; |
391 | } | 401 | } |
392 | 402 | ||
393 | drm_mode_config_reset(dev); | 403 | drm_mode_config_reset(ddev); |
394 | 404 | ||
395 | priv->fbdev = drm_fbdev_cma_init(dev, bpp, | 405 | priv->fbdev = drm_fbdev_cma_init(ddev, bpp, |
396 | dev->mode_config.num_crtc, | 406 | ddev->mode_config.num_crtc, |
397 | dev->mode_config.num_connector); | 407 | ddev->mode_config.num_connector); |
398 | if (IS_ERR(priv->fbdev)) { | 408 | if (IS_ERR(priv->fbdev)) { |
399 | ret = PTR_ERR(priv->fbdev); | 409 | ret = PTR_ERR(priv->fbdev); |
400 | goto fail_irq_uninstall; | 410 | goto fail_irq_uninstall; |
401 | } | 411 | } |
402 | 412 | ||
403 | drm_kms_helper_poll_init(dev); | 413 | drm_kms_helper_poll_init(ddev); |
414 | |||
415 | ret = drm_dev_register(ddev, 0); | ||
416 | if (ret) | ||
417 | goto fail_platform_init; | ||
404 | 418 | ||
405 | return 0; | 419 | return 0; |
406 | 420 | ||
421 | fail_platform_init: | ||
422 | drm_kms_helper_poll_fini(ddev); | ||
423 | drm_fbdev_cma_fini(priv->fbdev); | ||
424 | |||
407 | fail_irq_uninstall: | 425 | fail_irq_uninstall: |
408 | drm_irq_uninstall(dev); | 426 | drm_irq_uninstall(ddev); |
409 | 427 | ||
410 | fail_vblank_cleanup: | 428 | fail_vblank_cleanup: |
411 | drm_vblank_cleanup(dev); | 429 | drm_vblank_cleanup(ddev); |
412 | 430 | ||
413 | fail_component_cleanup: | 431 | fail_component_cleanup: |
414 | if (priv->is_componentized) | 432 | if (priv->is_componentized) |
415 | component_unbind_all(dev->dev, dev); | 433 | component_unbind_all(dev, dev); |
416 | 434 | ||
417 | fail_mode_config_cleanup: | 435 | fail_mode_config_cleanup: |
418 | drm_mode_config_cleanup(dev); | 436 | drm_mode_config_cleanup(ddev); |
419 | 437 | ||
420 | fail_external_cleanup: | 438 | fail_external_cleanup: |
421 | tilcdc_remove_external_encoders(dev); | 439 | tilcdc_remove_external_encoders(ddev); |
422 | 440 | ||
423 | fail_cpufreq_unregister: | 441 | fail_cpufreq_unregister: |
424 | pm_runtime_disable(dev->dev); | 442 | pm_runtime_disable(dev); |
425 | #ifdef CONFIG_CPU_FREQ | 443 | #ifdef CONFIG_CPU_FREQ |
426 | cpufreq_unregister_notifier(&priv->freq_transition, | 444 | cpufreq_unregister_notifier(&priv->freq_transition, |
427 | CPUFREQ_TRANSITION_NOTIFIER); | 445 | CPUFREQ_TRANSITION_NOTIFIER); |
@@ -438,7 +456,8 @@ fail_free_wq: | |||
438 | destroy_workqueue(priv->wq); | 456 | destroy_workqueue(priv->wq); |
439 | 457 | ||
440 | fail_unset_priv: | 458 | fail_unset_priv: |
441 | dev->dev_private = NULL; | 459 | ddev->dev_private = NULL; |
460 | drm_dev_unref(ddev); | ||
442 | 461 | ||
443 | return ret; | 462 | return ret; |
444 | } | 463 | } |
@@ -583,8 +602,6 @@ static const struct file_operations fops = { | |||
583 | static struct drm_driver tilcdc_driver = { | 602 | static struct drm_driver tilcdc_driver = { |
584 | .driver_features = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | | 603 | .driver_features = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | |
585 | DRIVER_PRIME | DRIVER_ATOMIC), | 604 | DRIVER_PRIME | DRIVER_ATOMIC), |
586 | .load = tilcdc_load, | ||
587 | .unload = tilcdc_unload, | ||
588 | .lastclose = tilcdc_lastclose, | 605 | .lastclose = tilcdc_lastclose, |
589 | .irq_handler = tilcdc_irq, | 606 | .irq_handler = tilcdc_irq, |
590 | .get_vblank_counter = drm_vblank_no_hw_counter, | 607 | .get_vblank_counter = drm_vblank_no_hw_counter, |
@@ -658,10 +675,9 @@ static const struct dev_pm_ops tilcdc_pm_ops = { | |||
658 | /* | 675 | /* |
659 | * Platform driver: | 676 | * Platform driver: |
660 | */ | 677 | */ |
661 | |||
662 | static int tilcdc_bind(struct device *dev) | 678 | static int tilcdc_bind(struct device *dev) |
663 | { | 679 | { |
664 | return drm_platform_init(&tilcdc_driver, to_platform_device(dev)); | 680 | return tilcdc_init(&tilcdc_driver, dev); |
665 | } | 681 | } |
666 | 682 | ||
667 | static void tilcdc_unbind(struct device *dev) | 683 | static void tilcdc_unbind(struct device *dev) |
@@ -672,7 +688,7 @@ static void tilcdc_unbind(struct device *dev) | |||
672 | if (!ddev->dev_private) | 688 | if (!ddev->dev_private) |
673 | return; | 689 | return; |
674 | 690 | ||
675 | drm_put_dev(dev_get_drvdata(dev)); | 691 | tilcdc_fini(dev_get_drvdata(dev)); |
676 | } | 692 | } |
677 | 693 | ||
678 | static const struct component_master_ops tilcdc_comp_ops = { | 694 | static const struct component_master_ops tilcdc_comp_ops = { |
@@ -695,7 +711,7 @@ static int tilcdc_pdev_probe(struct platform_device *pdev) | |||
695 | if (ret < 0) | 711 | if (ret < 0) |
696 | return ret; | 712 | return ret; |
697 | else if (ret == 0) | 713 | else if (ret == 0) |
698 | return drm_platform_init(&tilcdc_driver, pdev); | 714 | return tilcdc_init(&tilcdc_driver, &pdev->dev); |
699 | else | 715 | else |
700 | return component_master_add_with_match(&pdev->dev, | 716 | return component_master_add_with_match(&pdev->dev, |
701 | &tilcdc_comp_ops, | 717 | &tilcdc_comp_ops, |
@@ -710,7 +726,7 @@ static int tilcdc_pdev_remove(struct platform_device *pdev) | |||
710 | if (ret < 0) | 726 | if (ret < 0) |
711 | return ret; | 727 | return ret; |
712 | else if (ret == 0) | 728 | else if (ret == 0) |
713 | drm_put_dev(platform_get_drvdata(pdev)); | 729 | tilcdc_fini(platform_get_drvdata(pdev)); |
714 | else | 730 | else |
715 | component_master_del(&pdev->dev, &tilcdc_comp_ops); | 731 | component_master_del(&pdev->dev, &tilcdc_comp_ops); |
716 | 732 | ||