aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInki Dae <inki.dae@samsung.com>2014-05-29 05:28:02 -0400
committerInki Dae <inki.dae@samsung.com>2014-06-02 01:29:39 -0400
commitdf5225bc9a87f1589a17797ee8e193608e4f3a9e (patch)
tree6958bf8ac68f4f3f8cbc19d5526adc3155846c80
parent2e1ce1a1dd7c110faa8b99f0b76d1382e5de61f1 (diff)
drm/exynos: consider deferred probe case
This patch makes sure that exynos drm framework handles deferred probe case correctly. Sub drivers could be probed before resources, clock, regulator, phy or panel, are ready for them so we should make sure that exynos drm core waits until all resources are ready and sub drivers are probed correctly. Chagelog v2: - Make sure that exynos drm core tries to bind sub drivers only in case that they have a pair: crtc and encoder/connector components should be a pair. - Remove unnecessary patch: drm/exynos: mipi-dsi: consider panel driver-deferred probe - Return error type correctly. Signed-off-by: Inki Dae <inki.dae@samsung.com> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c18
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c22
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c138
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h13
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c41
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c51
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c78
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c17
8 files changed, 303 insertions, 75 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 8b67f4141e78..5e05dbc60082 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1325,12 +1325,26 @@ static const struct component_ops exynos_dp_ops = {
1325 1325
1326static int exynos_dp_probe(struct platform_device *pdev) 1326static int exynos_dp_probe(struct platform_device *pdev)
1327{ 1327{
1328 return exynos_drm_component_add(&pdev->dev, &exynos_dp_ops); 1328 int ret;
1329
1330 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1331 exynos_dp_display.type);
1332 if (ret)
1333 return ret;
1334
1335 ret = component_add(&pdev->dev, &exynos_dp_ops);
1336 if (ret)
1337 exynos_drm_component_del(&pdev->dev,
1338 EXYNOS_DEVICE_TYPE_CONNECTOR);
1339
1340 return ret;
1329} 1341}
1330 1342
1331static int exynos_dp_remove(struct platform_device *pdev) 1343static int exynos_dp_remove(struct platform_device *pdev)
1332{ 1344{
1333 exynos_drm_component_del(&pdev->dev, &exynos_dp_ops); 1345 component_del(&pdev->dev, &exynos_dp_ops);
1346 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1347
1334 return 0; 1348 return 0;
1335} 1349}
1336 1350
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index a832364358a7..f1b8587cc63d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -295,9 +295,15 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
295 struct exynos_dpi *ctx; 295 struct exynos_dpi *ctx;
296 int ret; 296 int ret;
297 297
298 ret = exynos_drm_component_add(dev,
299 EXYNOS_DEVICE_TYPE_CONNECTOR,
300 exynos_dpi_display.type);
301 if (ret)
302 return ERR_PTR(ret);
303
298 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 304 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
299 if (!ctx) 305 if (!ctx)
300 return NULL; 306 goto err_del_component;
301 307
302 ctx->dev = dev; 308 ctx->dev = dev;
303 exynos_dpi_display.ctx = ctx; 309 exynos_dpi_display.ctx = ctx;
@@ -306,16 +312,24 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
306 ret = exynos_dpi_parse_dt(ctx); 312 ret = exynos_dpi_parse_dt(ctx);
307 if (ret < 0) { 313 if (ret < 0) {
308 devm_kfree(dev, ctx); 314 devm_kfree(dev, ctx);
309 return NULL; 315 goto err_del_component;
310 } 316 }
311 317
312 if (ctx->panel_node) { 318 if (ctx->panel_node) {
313 ctx->panel = of_drm_find_panel(ctx->panel_node); 319 ctx->panel = of_drm_find_panel(ctx->panel_node);
314 if (!ctx->panel) 320 if (!ctx->panel) {
321 exynos_drm_component_del(dev,
322 EXYNOS_DEVICE_TYPE_CONNECTOR);
315 return ERR_PTR(-EPROBE_DEFER); 323 return ERR_PTR(-EPROBE_DEFER);
324 }
316 } 325 }
317 326
318 return &exynos_dpi_display; 327 return &exynos_dpi_display;
328
329err_del_component:
330 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
331
332 return NULL;
319} 333}
320 334
321int exynos_dpi_remove(struct device *dev) 335int exynos_dpi_remove(struct device *dev)
@@ -327,5 +341,7 @@ int exynos_dpi_remove(struct device *dev)
327 encoder->funcs->destroy(encoder); 341 encoder->funcs->destroy(encoder);
328 drm_connector_cleanup(&ctx->connector); 342 drm_connector_cleanup(&ctx->connector);
329 343
344 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
345
330 return 0; 346 return 0;
331} 347}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index c5a401ae4de5..5d225dd58a87 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -48,7 +48,10 @@ static LIST_HEAD(drm_component_list);
48 48
49struct component_dev { 49struct component_dev {
50 struct list_head list; 50 struct list_head list;
51 struct device *dev; 51 struct device *crtc_dev;
52 struct device *conn_dev;
53 enum exynos_drm_output_type out_type;
54 unsigned int dev_type_flag;
52}; 55};
53 56
54static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 57static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
@@ -382,22 +385,65 @@ static const struct dev_pm_ops exynos_drm_pm_ops = {
382}; 385};
383 386
384int exynos_drm_component_add(struct device *dev, 387int exynos_drm_component_add(struct device *dev,
385 const struct component_ops *ops) 388 enum exynos_drm_device_type dev_type,
389 enum exynos_drm_output_type out_type)
386{ 390{
387 struct component_dev *cdev; 391 struct component_dev *cdev;
388 int ret; 392
393 if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
394 dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
395 DRM_ERROR("invalid device type.\n");
396 return -EINVAL;
397 }
398
399 mutex_lock(&drm_component_lock);
400
401 /*
402 * Make sure to check if there is a component which has two device
403 * objects, for connector and for encoder/connector.
404 * It should make sure that crtc and encoder/connector drivers are
405 * ready before exynos drm core binds them.
406 */
407 list_for_each_entry(cdev, &drm_component_list, list) {
408 if (cdev->out_type == out_type) {
409 /*
410 * If crtc and encoder/connector device objects are
411 * added already just return.
412 */
413 if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
414 EXYNOS_DEVICE_TYPE_CONNECTOR)) {
415 mutex_unlock(&drm_component_lock);
416 return 0;
417 }
418
419 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
420 cdev->crtc_dev = dev;
421 cdev->dev_type_flag |= dev_type;
422 }
423
424 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
425 cdev->conn_dev = dev;
426 cdev->dev_type_flag |= dev_type;
427 }
428
429 mutex_unlock(&drm_component_lock);
430 return 0;
431 }
432 }
433
434 mutex_unlock(&drm_component_lock);
389 435
390 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 436 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
391 if (!cdev) 437 if (!cdev)
392 return -ENOMEM; 438 return -ENOMEM;
393 439
394 ret = component_add(dev, ops); 440 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
395 if (ret) { 441 cdev->crtc_dev = dev;
396 kfree(cdev); 442 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
397 return ret; 443 cdev->conn_dev = dev;
398 }
399 444
400 cdev->dev = dev; 445 cdev->out_type = out_type;
446 cdev->dev_type_flag = dev_type;
401 447
402 mutex_lock(&drm_component_lock); 448 mutex_lock(&drm_component_lock);
403 list_add_tail(&cdev->list, &drm_component_list); 449 list_add_tail(&cdev->list, &drm_component_list);
@@ -407,23 +453,40 @@ int exynos_drm_component_add(struct device *dev,
407} 453}
408 454
409void exynos_drm_component_del(struct device *dev, 455void exynos_drm_component_del(struct device *dev,
410 const struct component_ops *ops) 456 enum exynos_drm_device_type dev_type)
411{ 457{
412 struct component_dev *cdev, *next; 458 struct component_dev *cdev, *next;
413 459
414 mutex_lock(&drm_component_lock); 460 mutex_lock(&drm_component_lock);
415 461
416 list_for_each_entry_safe(cdev, next, &drm_component_list, list) { 462 list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
417 if (dev == cdev->dev) { 463 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
464 if (cdev->crtc_dev == dev) {
465 cdev->crtc_dev = NULL;
466 cdev->dev_type_flag &= ~dev_type;
467 }
468 }
469
470 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
471 if (cdev->conn_dev == dev) {
472 cdev->conn_dev = NULL;
473 cdev->dev_type_flag &= ~dev_type;
474 }
475 }
476
477 /*
478 * Release cdev object only in case that both of crtc and
479 * encoder/connector device objects are NULL.
480 */
481 if (!cdev->crtc_dev && !cdev->conn_dev) {
418 list_del(&cdev->list); 482 list_del(&cdev->list);
419 kfree(cdev); 483 kfree(cdev);
420 break;
421 } 484 }
485
486 break;
422 } 487 }
423 488
424 mutex_unlock(&drm_component_lock); 489 mutex_unlock(&drm_component_lock);
425
426 component_del(dev, ops);
427} 490}
428 491
429static int compare_of(struct device *dev, void *data) 492static int compare_of(struct device *dev, void *data)
@@ -433,29 +496,60 @@ static int compare_of(struct device *dev, void *data)
433 496
434static int exynos_drm_add_components(struct device *dev, struct master *m) 497static int exynos_drm_add_components(struct device *dev, struct master *m)
435{ 498{
436 unsigned int attached_cnt = 0;
437 struct component_dev *cdev; 499 struct component_dev *cdev;
500 unsigned int attach_cnt = 0;
438 501
439 mutex_lock(&drm_component_lock); 502 mutex_lock(&drm_component_lock);
440 503
441 list_for_each_entry(cdev, &drm_component_list, list) { 504 list_for_each_entry(cdev, &drm_component_list, list) {
442 int ret; 505 int ret;
443 506
507 /*
508 * Add components to master only in case that crtc and
509 * encoder/connector device objects exist.
510 */
511 if (!cdev->crtc_dev || !cdev->conn_dev)
512 continue;
513
514 attach_cnt++;
515
444 mutex_unlock(&drm_component_lock); 516 mutex_unlock(&drm_component_lock);
445 517
446 ret = component_master_add_child(m, compare_of, cdev->dev); 518 /*
447 if (!ret) 519 * fimd and dpi modules have same device object so add
448 attached_cnt++; 520 * only crtc device object in this case.
521 *
522 * TODO. if dpi module follows driver-model driver then
523 * below codes can be removed.
524 */
525 if (cdev->crtc_dev == cdev->conn_dev) {
526 ret = component_master_add_child(m, compare_of,
527 cdev->crtc_dev);
528 if (ret < 0)
529 return ret;
530
531 goto out_lock;
532 }
449 533
534 /*
535 * Do not chage below call order.
536 * crtc device first should be added to master because
537 * connector/encoder need pipe number of crtc when they
538 * are created.
539 */
540 ret = component_master_add_child(m, compare_of, cdev->crtc_dev);
541 ret |= component_master_add_child(m, compare_of,
542 cdev->conn_dev);
543 if (ret < 0)
544 return ret;
545
546out_lock:
450 mutex_lock(&drm_component_lock); 547 mutex_lock(&drm_component_lock);
451 } 548 }
452 549
453 mutex_unlock(&drm_component_lock); 550 mutex_unlock(&drm_component_lock);
454 551
455 if (!attached_cnt) 552 return attach_cnt ? 0 : -ENODEV;
456 return -ENXIO;
457
458 return 0;
459} 553}
460 554
461static int exynos_drm_bind(struct device *dev) 555static int exynos_drm_bind(struct device *dev)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e82e620c2e52..36535f398848 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -42,6 +42,13 @@ struct drm_connector;
42 42
43extern unsigned int drm_vblank_offdelay; 43extern unsigned int drm_vblank_offdelay;
44 44
45/* This enumerates device type. */
46enum exynos_drm_device_type {
47 EXYNOS_DEVICE_TYPE_NONE,
48 EXYNOS_DEVICE_TYPE_CRTC,
49 EXYNOS_DEVICE_TYPE_CONNECTOR,
50};
51
45/* this enumerates display type. */ 52/* this enumerates display type. */
46enum exynos_drm_output_type { 53enum exynos_drm_output_type {
47 EXYNOS_DISPLAY_TYPE_NONE, 54 EXYNOS_DISPLAY_TYPE_NONE,
@@ -354,12 +361,12 @@ void exynos_drm_remove_vidi(void);
354int exynos_drm_create_enc_conn(struct drm_device *dev, 361int exynos_drm_create_enc_conn(struct drm_device *dev,
355 struct exynos_drm_display *display); 362 struct exynos_drm_display *display);
356 363
357struct component_ops;
358int exynos_drm_component_add(struct device *dev, 364int exynos_drm_component_add(struct device *dev,
359 const struct component_ops *ops); 365 enum exynos_drm_device_type dev_type,
366 enum exynos_drm_output_type out_type);
360 367
361void exynos_drm_component_del(struct device *dev, 368void exynos_drm_component_del(struct device *dev,
362 const struct component_ops *ops); 369 enum exynos_drm_device_type dev_type);
363 370
364extern struct platform_driver fimd_driver; 371extern struct platform_driver fimd_driver;
365extern struct platform_driver dp_driver; 372extern struct platform_driver dp_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 84661feda60f..6302aa64f6c1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1423,10 +1423,16 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1423 struct exynos_dsi *dsi; 1423 struct exynos_dsi *dsi;
1424 int ret; 1424 int ret;
1425 1425
1426 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1427 exynos_dsi_display.type);
1428 if (ret)
1429 return ret;
1430
1426 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); 1431 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
1427 if (!dsi) { 1432 if (!dsi) {
1428 dev_err(&pdev->dev, "failed to allocate dsi object.\n"); 1433 dev_err(&pdev->dev, "failed to allocate dsi object.\n");
1429 return -ENOMEM; 1434 ret = -ENOMEM;
1435 goto err_del_component;
1430 } 1436 }
1431 1437
1432 init_completion(&dsi->completed); 1438 init_completion(&dsi->completed);
@@ -1440,7 +1446,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1440 1446
1441 ret = exynos_dsi_parse_dt(dsi); 1447 ret = exynos_dsi_parse_dt(dsi);
1442 if (ret) 1448 if (ret)
1443 return ret; 1449 goto err_del_component;
1444 1450
1445 dsi->supplies[0].supply = "vddcore"; 1451 dsi->supplies[0].supply = "vddcore";
1446 dsi->supplies[1].supply = "vddio"; 1452 dsi->supplies[1].supply = "vddio";
@@ -1454,32 +1460,37 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1454 dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk"); 1460 dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");
1455 if (IS_ERR(dsi->pll_clk)) { 1461 if (IS_ERR(dsi->pll_clk)) {
1456 dev_info(&pdev->dev, "failed to get dsi pll input clock\n"); 1462 dev_info(&pdev->dev, "failed to get dsi pll input clock\n");
1457 return -EPROBE_DEFER; 1463 ret = PTR_ERR(dsi->pll_clk);
1464 goto err_del_component;
1458 } 1465 }
1459 1466
1460 dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk"); 1467 dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
1461 if (IS_ERR(dsi->bus_clk)) { 1468 if (IS_ERR(dsi->bus_clk)) {
1462 dev_info(&pdev->dev, "failed to get dsi bus clock\n"); 1469 dev_info(&pdev->dev, "failed to get dsi bus clock\n");
1463 return -EPROBE_DEFER; 1470 ret = PTR_ERR(dsi->bus_clk);
1471 goto err_del_component;
1464 } 1472 }
1465 1473
1466 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1474 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1467 dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); 1475 dsi->reg_base = devm_ioremap_resource(&pdev->dev, res);
1468 if (IS_ERR(dsi->reg_base)) { 1476 if (IS_ERR(dsi->reg_base)) {
1469 dev_err(&pdev->dev, "failed to remap io region\n"); 1477 dev_err(&pdev->dev, "failed to remap io region\n");
1470 return PTR_ERR(dsi->reg_base); 1478 ret = PTR_ERR(dsi->reg_base);
1479 goto err_del_component;
1471 } 1480 }
1472 1481
1473 dsi->phy = devm_phy_get(&pdev->dev, "dsim"); 1482 dsi->phy = devm_phy_get(&pdev->dev, "dsim");
1474 if (IS_ERR(dsi->phy)) { 1483 if (IS_ERR(dsi->phy)) {
1475 dev_info(&pdev->dev, "failed to get dsim phy\n"); 1484 dev_info(&pdev->dev, "failed to get dsim phy\n");
1476 return -EPROBE_DEFER; 1485 ret = PTR_ERR(dsi->phy);
1486 goto err_del_component;
1477 } 1487 }
1478 1488
1479 dsi->irq = platform_get_irq(pdev, 0); 1489 dsi->irq = platform_get_irq(pdev, 0);
1480 if (dsi->irq < 0) { 1490 if (dsi->irq < 0) {
1481 dev_err(&pdev->dev, "failed to request dsi irq resource\n"); 1491 dev_err(&pdev->dev, "failed to request dsi irq resource\n");
1482 return dsi->irq; 1492 ret = dsi->irq;
1493 goto err_del_component;
1483 } 1494 }
1484 1495
1485 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); 1496 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
@@ -1488,19 +1499,29 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1488 dev_name(&pdev->dev), dsi); 1499 dev_name(&pdev->dev), dsi);
1489 if (ret) { 1500 if (ret) {
1490 dev_err(&pdev->dev, "failed to request dsi irq\n"); 1501 dev_err(&pdev->dev, "failed to request dsi irq\n");
1491 return ret; 1502 goto err_del_component;
1492 } 1503 }
1493 1504
1494 exynos_dsi_display.ctx = dsi; 1505 exynos_dsi_display.ctx = dsi;
1495 1506
1496 platform_set_drvdata(pdev, &exynos_dsi_display); 1507 platform_set_drvdata(pdev, &exynos_dsi_display);
1497 1508
1498 return exynos_drm_component_add(&pdev->dev, &exynos_dsi_component_ops); 1509 ret = component_add(&pdev->dev, &exynos_dsi_component_ops);
1510 if (ret)
1511 goto err_del_component;
1512
1513 return ret;
1514
1515err_del_component:
1516 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1517 return ret;
1499} 1518}
1500 1519
1501static int exynos_dsi_remove(struct platform_device *pdev) 1520static int exynos_dsi_remove(struct platform_device *pdev)
1502{ 1521{
1503 exynos_drm_component_del(&pdev->dev, &exynos_dsi_component_ops); 1522 component_del(&pdev->dev, &exynos_dsi_component_ops);
1523 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1524
1504 return 0; 1525 return 0;
1505} 1526}
1506 1527
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 2ec634f7930a..bb45ab2e7384 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -924,12 +924,21 @@ static int fimd_probe(struct platform_device *pdev)
924 struct resource *res; 924 struct resource *res;
925 int ret = -EINVAL; 925 int ret = -EINVAL;
926 926
927 if (!dev->of_node) 927 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
928 return -ENODEV; 928 fimd_manager.type);
929 if (ret)
930 return ret;
931
932 if (!dev->of_node) {
933 ret = -ENODEV;
934 goto err_del_component;
935 }
929 936
930 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 937 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
931 if (!ctx) 938 if (!ctx) {
932 return -ENOMEM; 939 ret = -ENOMEM;
940 goto err_del_component;
941 }
933 942
934 ctx->dev = dev; 943 ctx->dev = dev;
935 ctx->suspended = true; 944 ctx->suspended = true;
@@ -942,32 +951,37 @@ static int fimd_probe(struct platform_device *pdev)
942 ctx->bus_clk = devm_clk_get(dev, "fimd"); 951 ctx->bus_clk = devm_clk_get(dev, "fimd");
943 if (IS_ERR(ctx->bus_clk)) { 952 if (IS_ERR(ctx->bus_clk)) {
944 dev_err(dev, "failed to get bus clock\n"); 953 dev_err(dev, "failed to get bus clock\n");
945 return PTR_ERR(ctx->bus_clk); 954 ret = PTR_ERR(ctx->bus_clk);
955 goto err_del_component;
946 } 956 }
947 957
948 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd"); 958 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd");
949 if (IS_ERR(ctx->lcd_clk)) { 959 if (IS_ERR(ctx->lcd_clk)) {
950 dev_err(dev, "failed to get lcd clock\n"); 960 dev_err(dev, "failed to get lcd clock\n");
951 return PTR_ERR(ctx->lcd_clk); 961 ret = PTR_ERR(ctx->lcd_clk);
962 goto err_del_component;
952 } 963 }
953 964
954 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 965 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
955 966
956 ctx->regs = devm_ioremap_resource(dev, res); 967 ctx->regs = devm_ioremap_resource(dev, res);
957 if (IS_ERR(ctx->regs)) 968 if (IS_ERR(ctx->regs)) {
958 return PTR_ERR(ctx->regs); 969 ret = PTR_ERR(ctx->regs);
970 goto err_del_component;
971 }
959 972
960 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync"); 973 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
961 if (!res) { 974 if (!res) {
962 dev_err(dev, "irq request failed.\n"); 975 dev_err(dev, "irq request failed.\n");
963 return -ENXIO; 976 ret = -ENXIO;
977 goto err_del_component;
964 } 978 }
965 979
966 ret = devm_request_irq(dev, res->start, fimd_irq_handler, 980 ret = devm_request_irq(dev, res->start, fimd_irq_handler,
967 0, "drm_fimd", ctx); 981 0, "drm_fimd", ctx);
968 if (ret) { 982 if (ret) {
969 dev_err(dev, "irq request failed.\n"); 983 dev_err(dev, "irq request failed.\n");
970 return ret; 984 goto err_del_component;
971 } 985 }
972 986
973 ctx->driver_data = drm_fimd_get_driver_data(pdev); 987 ctx->driver_data = drm_fimd_get_driver_data(pdev);
@@ -984,14 +998,27 @@ static int fimd_probe(struct platform_device *pdev)
984 998
985 pm_runtime_enable(&pdev->dev); 999 pm_runtime_enable(&pdev->dev);
986 1000
987 return exynos_drm_component_add(&pdev->dev, &fimd_component_ops); 1001 ret = component_add(&pdev->dev, &fimd_component_ops);
1002 if (ret)
1003 goto err_disable_pm_runtime;
1004
1005 return ret;
1006
1007err_disable_pm_runtime:
1008 pm_runtime_disable(&pdev->dev);
1009
1010err_del_component:
1011 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1012 return ret;
988} 1013}
989 1014
990static int fimd_remove(struct platform_device *pdev) 1015static int fimd_remove(struct platform_device *pdev)
991{ 1016{
992 pm_runtime_disable(&pdev->dev); 1017 pm_runtime_disable(&pdev->dev);
993 1018
994 exynos_drm_component_del(&pdev->dev, &fimd_component_ops); 1019 component_del(&pdev->dev, &fimd_component_ops);
1020 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1021
995 return 0; 1022 return 0;
996} 1023}
997 1024
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index d0f4f5d5a9f9..c104d0c9b385 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2162,26 +2162,31 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
2162 res->hdmi = devm_clk_get(dev, "hdmi"); 2162 res->hdmi = devm_clk_get(dev, "hdmi");
2163 if (IS_ERR(res->hdmi)) { 2163 if (IS_ERR(res->hdmi)) {
2164 DRM_ERROR("failed to get clock 'hdmi'\n"); 2164 DRM_ERROR("failed to get clock 'hdmi'\n");
2165 ret = PTR_ERR(res->hdmi);
2165 goto fail; 2166 goto fail;
2166 } 2167 }
2167 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 2168 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
2168 if (IS_ERR(res->sclk_hdmi)) { 2169 if (IS_ERR(res->sclk_hdmi)) {
2169 DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); 2170 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2171 ret = PTR_ERR(res->sclk_hdmi);
2170 goto fail; 2172 goto fail;
2171 } 2173 }
2172 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel"); 2174 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
2173 if (IS_ERR(res->sclk_pixel)) { 2175 if (IS_ERR(res->sclk_pixel)) {
2174 DRM_ERROR("failed to get clock 'sclk_pixel'\n"); 2176 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2177 ret = PTR_ERR(res->sclk_pixel);
2175 goto fail; 2178 goto fail;
2176 } 2179 }
2177 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy"); 2180 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
2178 if (IS_ERR(res->sclk_hdmiphy)) { 2181 if (IS_ERR(res->sclk_hdmiphy)) {
2179 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); 2182 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
2183 ret = PTR_ERR(res->sclk_hdmiphy);
2180 goto fail; 2184 goto fail;
2181 } 2185 }
2182 res->mout_hdmi = devm_clk_get(dev, "mout_hdmi"); 2186 res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
2183 if (IS_ERR(res->mout_hdmi)) { 2187 if (IS_ERR(res->mout_hdmi)) {
2184 DRM_ERROR("failed to get clock 'mout_hdmi'\n"); 2188 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
2189 ret = PTR_ERR(res->mout_hdmi);
2185 goto fail; 2190 goto fail;
2186 } 2191 }
2187 2192
@@ -2189,8 +2194,10 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
2189 2194
2190 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) * 2195 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
2191 sizeof(res->regul_bulk[0]), GFP_KERNEL); 2196 sizeof(res->regul_bulk[0]), GFP_KERNEL);
2192 if (!res->regul_bulk) 2197 if (!res->regul_bulk) {
2198 ret = -ENOMEM;
2193 goto fail; 2199 goto fail;
2200 }
2194 for (i = 0; i < ARRAY_SIZE(supply); ++i) { 2201 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
2195 res->regul_bulk[i].supply = supply[i]; 2202 res->regul_bulk[i].supply = supply[i];
2196 res->regul_bulk[i].consumer = NULL; 2203 res->regul_bulk[i].consumer = NULL;
@@ -2198,14 +2205,14 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
2198 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk); 2205 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2199 if (ret) { 2206 if (ret) {
2200 DRM_ERROR("failed to get regulators\n"); 2207 DRM_ERROR("failed to get regulators\n");
2201 goto fail; 2208 return ret;
2202 } 2209 }
2203 res->regul_count = ARRAY_SIZE(supply); 2210 res->regul_count = ARRAY_SIZE(supply);
2204 2211
2205 return 0; 2212 return ret;
2206fail: 2213fail:
2207 DRM_ERROR("HDMI resource init - failed\n"); 2214 DRM_ERROR("HDMI resource init - failed\n");
2208 return -ENODEV; 2215 return ret;
2209} 2216}
2210 2217
2211static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata 2218static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
@@ -2303,24 +2310,37 @@ static int hdmi_probe(struct platform_device *pdev)
2303 struct resource *res; 2310 struct resource *res;
2304 int ret; 2311 int ret;
2305 2312
2306 if (!dev->of_node) 2313 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2307 return -ENODEV; 2314 hdmi_display.type);
2315 if (ret)
2316 return ret;
2317
2318 if (!dev->of_node) {
2319 ret = -ENODEV;
2320 goto err_del_component;
2321 }
2308 2322
2309 pdata = drm_hdmi_dt_parse_pdata(dev); 2323 pdata = drm_hdmi_dt_parse_pdata(dev);
2310 if (!pdata) 2324 if (!pdata) {
2311 return -EINVAL; 2325 ret = -EINVAL;
2326 goto err_del_component;
2327 }
2312 2328
2313 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL); 2329 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2314 if (!hdata) 2330 if (!hdata) {
2315 return -ENOMEM; 2331 ret = -ENOMEM;
2332 goto err_del_component;
2333 }
2316 2334
2317 mutex_init(&hdata->hdmi_mutex); 2335 mutex_init(&hdata->hdmi_mutex);
2318 2336
2319 platform_set_drvdata(pdev, &hdmi_display); 2337 platform_set_drvdata(pdev, &hdmi_display);
2320 2338
2321 match = of_match_node(hdmi_match_types, dev->of_node); 2339 match = of_match_node(hdmi_match_types, dev->of_node);
2322 if (!match) 2340 if (!match) {
2323 return -ENODEV; 2341 ret = -ENODEV;
2342 goto err_del_component;
2343 }
2324 2344
2325 drv_data = (struct hdmi_driver_data *)match->data; 2345 drv_data = (struct hdmi_driver_data *)match->data;
2326 hdata->type = drv_data->type; 2346 hdata->type = drv_data->type;
@@ -2333,18 +2353,20 @@ static int hdmi_probe(struct platform_device *pdev)
2333 ret = hdmi_resources_init(hdata); 2353 ret = hdmi_resources_init(hdata);
2334 if (ret) { 2354 if (ret) {
2335 DRM_ERROR("hdmi_resources_init failed\n"); 2355 DRM_ERROR("hdmi_resources_init failed\n");
2336 return -EINVAL; 2356 return ret;
2337 } 2357 }
2338 2358
2339 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2359 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2340 hdata->regs = devm_ioremap_resource(dev, res); 2360 hdata->regs = devm_ioremap_resource(dev, res);
2341 if (IS_ERR(hdata->regs)) 2361 if (IS_ERR(hdata->regs)) {
2342 return PTR_ERR(hdata->regs); 2362 ret = PTR_ERR(hdata->regs);
2363 goto err_del_component;
2364 }
2343 2365
2344 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD"); 2366 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
2345 if (ret) { 2367 if (ret) {
2346 DRM_ERROR("failed to request HPD gpio\n"); 2368 DRM_ERROR("failed to request HPD gpio\n");
2347 return ret; 2369 goto err_del_component;
2348 } 2370 }
2349 2371
2350 ddc_node = hdmi_legacy_ddc_dt_binding(dev); 2372 ddc_node = hdmi_legacy_ddc_dt_binding(dev);
@@ -2355,14 +2377,15 @@ static int hdmi_probe(struct platform_device *pdev)
2355 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); 2377 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
2356 if (!ddc_node) { 2378 if (!ddc_node) {
2357 DRM_ERROR("Failed to find ddc node in device tree\n"); 2379 DRM_ERROR("Failed to find ddc node in device tree\n");
2358 return -ENODEV; 2380 ret = -ENODEV;
2381 goto err_del_component;
2359 } 2382 }
2360 2383
2361out_get_ddc_adpt: 2384out_get_ddc_adpt:
2362 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node); 2385 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
2363 if (!hdata->ddc_adpt) { 2386 if (!hdata->ddc_adpt) {
2364 DRM_ERROR("Failed to get ddc i2c adapter by node\n"); 2387 DRM_ERROR("Failed to get ddc i2c adapter by node\n");
2365 return -ENODEV; 2388 return -EPROBE_DEFER;
2366 } 2389 }
2367 2390
2368 phy_node = hdmi_legacy_phy_dt_binding(dev); 2391 phy_node = hdmi_legacy_phy_dt_binding(dev);
@@ -2389,7 +2412,7 @@ out_get_phy_port:
2389 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node); 2412 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
2390 if (!hdata->hdmiphy_port) { 2413 if (!hdata->hdmiphy_port) {
2391 DRM_ERROR("Failed to get hdmi phy i2c client\n"); 2414 DRM_ERROR("Failed to get hdmi phy i2c client\n");
2392 ret = -ENODEV; 2415 ret = -EPROBE_DEFER;
2393 goto err_ddc; 2416 goto err_ddc;
2394 } 2417 }
2395 } 2418 }
@@ -2418,19 +2441,31 @@ out_get_phy_port:
2418 "samsung,syscon-phandle"); 2441 "samsung,syscon-phandle");
2419 if (IS_ERR(hdata->pmureg)) { 2442 if (IS_ERR(hdata->pmureg)) {
2420 DRM_ERROR("syscon regmap lookup failed.\n"); 2443 DRM_ERROR("syscon regmap lookup failed.\n");
2444 ret = -EPROBE_DEFER;
2421 goto err_hdmiphy; 2445 goto err_hdmiphy;
2422 } 2446 }
2423 2447
2424 pm_runtime_enable(dev); 2448 pm_runtime_enable(dev);
2425 hdmi_display.ctx = hdata; 2449 hdmi_display.ctx = hdata;
2426 2450
2427 return exynos_drm_component_add(&pdev->dev, &hdmi_component_ops); 2451 ret = component_add(&pdev->dev, &hdmi_component_ops);
2452 if (ret)
2453 goto err_disable_pm_runtime;
2454
2455 return ret;
2456
2457err_disable_pm_runtime:
2458 pm_runtime_disable(dev);
2428 2459
2429err_hdmiphy: 2460err_hdmiphy:
2430 if (hdata->hdmiphy_port) 2461 if (hdata->hdmiphy_port)
2431 put_device(&hdata->hdmiphy_port->dev); 2462 put_device(&hdata->hdmiphy_port->dev);
2432err_ddc: 2463err_ddc:
2433 put_device(&hdata->ddc_adpt->dev); 2464 put_device(&hdata->ddc_adpt->dev);
2465
2466err_del_component:
2467 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2468
2434 return ret; 2469 return ret;
2435} 2470}
2436 2471
@@ -2444,8 +2479,9 @@ static int hdmi_remove(struct platform_device *pdev)
2444 put_device(&hdata->ddc_adpt->dev); 2479 put_device(&hdata->ddc_adpt->dev);
2445 2480
2446 pm_runtime_disable(&pdev->dev); 2481 pm_runtime_disable(&pdev->dev);
2482 component_del(&pdev->dev, &hdmi_component_ops);
2447 2483
2448 exynos_drm_component_del(&pdev->dev, &hdmi_component_ops); 2484 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2449 return 0; 2485 return 0;
2450} 2486}
2451 2487
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 483d7c08384a..4c5aed7e54c8 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1273,12 +1273,25 @@ static const struct component_ops mixer_component_ops = {
1273 1273
1274static int mixer_probe(struct platform_device *pdev) 1274static int mixer_probe(struct platform_device *pdev)
1275{ 1275{
1276 return exynos_drm_component_add(&pdev->dev, &mixer_component_ops); 1276 int ret;
1277
1278 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1279 mixer_manager.type);
1280 if (ret)
1281 return ret;
1282
1283 ret = component_add(&pdev->dev, &mixer_component_ops);
1284 if (ret)
1285 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1286
1287 return ret;
1277} 1288}
1278 1289
1279static int mixer_remove(struct platform_device *pdev) 1290static int mixer_remove(struct platform_device *pdev)
1280{ 1291{
1281 exynos_drm_component_del(&pdev->dev, &mixer_component_ops); 1292 component_del(&pdev->dev, &mixer_component_ops);
1293 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1294
1282 return 0; 1295 return 0;
1283} 1296}
1284 1297