Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/exynos: add component framework support

This patch adds component framework support to resolve
the probe order issue.

Until now, exynos drm had used codes specific to exynos drm
to resolve that issue so with this patch, the specific codes
are removed.

Signed-off-by: Inki Dae <inki.dae@samsung.com>

authored by

Inki Dae and committed by
Inki Dae
f37cd5e8 121692eb

+663 -485
+30 -19
drivers/gpu/drm/exynos/exynos_dp_core.c
··· 18 18 #include <linux/interrupt.h> 19 19 #include <linux/delay.h> 20 20 #include <linux/of.h> 21 + #include <linux/component.h> 21 22 #include <linux/phy/phy.h> 22 23 #include <video/of_display_timing.h> 23 24 #include <video/of_videomode.h> ··· 963 962 .best_encoder = exynos_dp_best_encoder, 964 963 }; 965 964 966 - static int exynos_dp_initialize(struct exynos_drm_display *display, 967 - struct drm_device *drm_dev) 968 - { 969 - struct exynos_dp_device *dp = display->ctx; 970 - 971 - dp->drm_dev = drm_dev; 972 - 973 - return 0; 974 - } 975 - 976 965 static bool find_bridge(const char *compat, struct bridge_init *bridge) 977 966 { 978 967 bridge->client = NULL; ··· 1090 1099 } 1091 1100 1092 1101 static struct exynos_drm_display_ops exynos_dp_display_ops = { 1093 - .initialize = exynos_dp_initialize, 1094 1102 .create_connector = exynos_dp_create_connector, 1095 1103 .dpms = exynos_dp_dpms, 1096 1104 }; ··· 1211 1221 return 0; 1212 1222 } 1213 1223 1214 - static int exynos_dp_probe(struct platform_device *pdev) 1224 + static int exynos_dp_bind(struct device *dev, struct device *master, void *data) 1215 1225 { 1226 + struct platform_device *pdev = to_platform_device(dev); 1227 + struct drm_device *drm_dev = data; 1216 1228 struct resource *res; 1217 1229 struct exynos_dp_device *dp; 1218 1230 ··· 1274 1282 } 1275 1283 disable_irq(dp->irq); 1276 1284 1285 + dp->drm_dev = drm_dev; 1277 1286 exynos_dp_display.ctx = dp; 1278 1287 1279 1288 platform_set_drvdata(pdev, &exynos_dp_display); 1280 - exynos_drm_display_register(&exynos_dp_display); 1281 1289 1282 - return 0; 1290 + return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display); 1291 + } 1292 + 1293 + static void exynos_dp_unbind(struct device *dev, struct device *master, 1294 + void *data) 1295 + { 1296 + struct exynos_drm_display *display = dev_get_drvdata(dev); 1297 + struct exynos_dp_device *dp = display->ctx; 1298 + struct drm_encoder *encoder = dp->encoder; 1299 + 1300 + exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); 1301 + 1302 + encoder->funcs->destroy(encoder); 1303 + drm_connector_cleanup(&dp->connector); 1304 + } 1305 + 1306 + static const struct component_ops exynos_dp_ops = { 1307 + .bind = exynos_dp_bind, 1308 + .unbind = exynos_dp_unbind, 1309 + }; 1310 + 1311 + static int exynos_dp_probe(struct platform_device *pdev) 1312 + { 1313 + return exynos_drm_component_add(&pdev->dev, &exynos_dp_ops); 1283 1314 } 1284 1315 1285 1316 static int exynos_dp_remove(struct platform_device *pdev) 1286 1317 { 1287 - struct exynos_drm_display *display = platform_get_drvdata(pdev); 1288 - 1289 - exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); 1290 - exynos_drm_display_unregister(&exynos_dp_display); 1291 - 1318 + exynos_drm_component_del(&pdev->dev, &exynos_dp_ops); 1292 1319 return 0; 1293 1320 } 1294 1321
+54 -198
drivers/gpu/drm/exynos/exynos_drm_core.c
··· 19 19 #include "exynos_drm_fbdev.h" 20 20 21 21 static LIST_HEAD(exynos_drm_subdrv_list); 22 - static LIST_HEAD(exynos_drm_manager_list); 23 - static LIST_HEAD(exynos_drm_display_list); 24 22 25 - static int exynos_drm_create_enc_conn(struct drm_device *dev, 23 + int exynos_drm_create_enc_conn(struct drm_device *dev, 26 24 struct exynos_drm_display *display) 27 25 { 28 26 struct drm_encoder *encoder; 29 - struct exynos_drm_manager *manager; 30 27 int ret; 31 28 unsigned long possible_crtcs = 0; 32 29 33 - /* Find possible crtcs for this display */ 34 - list_for_each_entry(manager, &exynos_drm_manager_list, list) 35 - if (manager->type == display->type) 36 - possible_crtcs |= 1 << manager->pipe; 30 + ret = exynos_drm_crtc_get_pipe_from_type(dev, display->type); 31 + if (ret < 0) 32 + return ret; 33 + 34 + possible_crtcs |= 1 << ret; 37 35 38 36 /* create and initialize a encoder for this sub driver. */ 39 37 encoder = exynos_drm_encoder_create(dev, display, possible_crtcs); ··· 55 57 return ret; 56 58 } 57 59 58 - static int exynos_drm_subdrv_probe(struct drm_device *dev, 59 - struct exynos_drm_subdrv *subdrv) 60 - { 61 - if (subdrv->probe) { 62 - int ret; 63 - 64 - subdrv->drm_dev = dev; 65 - 66 - /* 67 - * this probe callback would be called by sub driver 68 - * after setting of all resources to this sub driver, 69 - * such as clock, irq and register map are done or by load() 70 - * of exynos drm driver. 71 - * 72 - * P.S. note that this driver is considered for modularization. 73 - */ 74 - ret = subdrv->probe(dev, subdrv->dev); 75 - if (ret) 76 - return ret; 77 - } 78 - 79 - return 0; 80 - } 81 - 82 - static void exynos_drm_subdrv_remove(struct drm_device *dev, 83 - struct exynos_drm_subdrv *subdrv) 84 - { 85 - if (subdrv->remove) 86 - subdrv->remove(dev, subdrv->dev); 87 - } 88 - 89 - int exynos_drm_initialize_managers(struct drm_device *dev) 90 - { 91 - struct exynos_drm_manager *manager, *n; 92 - int ret, pipe = 0; 93 - 94 - list_for_each_entry(manager, &exynos_drm_manager_list, list) { 95 - if (manager->ops->initialize) { 96 - ret = manager->ops->initialize(manager, dev, pipe); 97 - if (ret) { 98 - DRM_ERROR("Mgr init [%d] failed with %d\n", 99 - manager->type, ret); 100 - goto err; 101 - } 102 - } 103 - 104 - manager->drm_dev = dev; 105 - manager->pipe = pipe++; 106 - 107 - ret = exynos_drm_crtc_create(manager); 108 - if (ret) { 109 - DRM_ERROR("CRTC create [%d] failed with %d\n", 110 - manager->type, ret); 111 - goto err; 112 - } 113 - } 114 - return 0; 115 - 116 - err: 117 - list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list) { 118 - if (pipe-- > 0) 119 - exynos_drm_manager_unregister(manager); 120 - else 121 - list_del(&manager->list); 122 - } 123 - return ret; 124 - } 125 - 126 - void exynos_drm_remove_managers(struct drm_device *dev) 127 - { 128 - struct exynos_drm_manager *manager, *n; 129 - 130 - list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list) 131 - exynos_drm_manager_unregister(manager); 132 - } 133 - 134 - int exynos_drm_initialize_displays(struct drm_device *dev) 135 - { 136 - struct exynos_drm_display *display, *n; 137 - int ret, initialized = 0; 138 - 139 - list_for_each_entry(display, &exynos_drm_display_list, list) { 140 - if (display->ops->initialize) { 141 - ret = display->ops->initialize(display, dev); 142 - if (ret) { 143 - DRM_ERROR("Display init [%d] failed with %d\n", 144 - display->type, ret); 145 - goto err; 146 - } 147 - } 148 - 149 - initialized++; 150 - 151 - ret = exynos_drm_create_enc_conn(dev, display); 152 - if (ret) { 153 - DRM_ERROR("Encoder create [%d] failed with %d\n", 154 - display->type, ret); 155 - goto err; 156 - } 157 - } 158 - return 0; 159 - 160 - err: 161 - list_for_each_entry_safe(display, n, &exynos_drm_display_list, list) { 162 - if (initialized-- > 0) 163 - exynos_drm_display_unregister(display); 164 - else 165 - list_del(&display->list); 166 - } 167 - return ret; 168 - } 169 - 170 - void exynos_drm_remove_displays(struct drm_device *dev) 171 - { 172 - struct exynos_drm_display *display, *n; 173 - 174 - list_for_each_entry_safe(display, n, &exynos_drm_display_list, list) 175 - exynos_drm_display_unregister(display); 176 - } 177 - 178 - int exynos_drm_device_register(struct drm_device *dev) 179 - { 180 - struct exynos_drm_subdrv *subdrv, *n; 181 - int err; 182 - 183 - if (!dev) 184 - return -EINVAL; 185 - 186 - list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 187 - err = exynos_drm_subdrv_probe(dev, subdrv); 188 - if (err) { 189 - DRM_DEBUG("exynos drm subdrv probe failed.\n"); 190 - list_del(&subdrv->list); 191 - continue; 192 - } 193 - } 194 - 195 - return 0; 196 - } 197 - EXPORT_SYMBOL_GPL(exynos_drm_device_register); 198 - 199 - int exynos_drm_device_unregister(struct drm_device *dev) 200 - { 201 - struct exynos_drm_subdrv *subdrv; 202 - 203 - if (!dev) { 204 - WARN(1, "Unexpected drm device unregister!\n"); 205 - return -EINVAL; 206 - } 207 - 208 - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { 209 - exynos_drm_subdrv_remove(dev, subdrv); 210 - } 211 - 212 - return 0; 213 - } 214 - EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); 215 - 216 - int exynos_drm_manager_register(struct exynos_drm_manager *manager) 217 - { 218 - BUG_ON(!manager->ops); 219 - list_add_tail(&manager->list, &exynos_drm_manager_list); 220 - return 0; 221 - } 222 - 223 - int exynos_drm_manager_unregister(struct exynos_drm_manager *manager) 224 - { 225 - if (manager->ops->remove) 226 - manager->ops->remove(manager); 227 - 228 - list_del(&manager->list); 229 - return 0; 230 - } 231 - 232 - int exynos_drm_display_register(struct exynos_drm_display *display) 233 - { 234 - BUG_ON(!display->ops); 235 - list_add_tail(&display->list, &exynos_drm_display_list); 236 - return 0; 237 - } 238 - 239 - int exynos_drm_display_unregister(struct exynos_drm_display *display) 240 - { 241 - if (display->ops->remove) 242 - display->ops->remove(display); 243 - 244 - list_del(&display->list); 245 - return 0; 246 - } 247 - 248 60 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) 249 61 { 250 62 if (!subdrv) ··· 76 268 return 0; 77 269 } 78 270 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); 271 + 272 + int exynos_drm_device_subdrv_probe(struct drm_device *dev) 273 + { 274 + struct exynos_drm_subdrv *subdrv, *n; 275 + int err; 276 + 277 + if (!dev) 278 + return -EINVAL; 279 + 280 + list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 281 + if (subdrv->probe) { 282 + subdrv->drm_dev = dev; 283 + 284 + /* 285 + * this probe callback would be called by sub driver 286 + * after setting of all resources to this sub driver, 287 + * such as clock, irq and register map are done. 288 + */ 289 + err = subdrv->probe(dev, subdrv->dev); 290 + if (err) { 291 + DRM_DEBUG("exynos drm subdrv probe failed.\n"); 292 + list_del(&subdrv->list); 293 + continue; 294 + } 295 + } 296 + } 297 + 298 + return 0; 299 + } 300 + EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_probe); 301 + 302 + int exynos_drm_device_subdrv_remove(struct drm_device *dev) 303 + { 304 + struct exynos_drm_subdrv *subdrv; 305 + 306 + if (!dev) { 307 + WARN(1, "Unexpected drm device unregister!\n"); 308 + return -EINVAL; 309 + } 310 + 311 + list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { 312 + if (subdrv->remove) 313 + subdrv->remove(dev, subdrv->dev); 314 + } 315 + 316 + return 0; 317 + } 318 + EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_remove); 79 319 80 320 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) 81 321 {
+17
drivers/gpu/drm/exynos/exynos_drm_crtc.c
··· 368 368 return -ENOMEM; 369 369 } 370 370 371 + manager->crtc = &exynos_crtc->drm_crtc; 371 372 crtc = &exynos_crtc->drm_crtc; 372 373 373 374 private->crtc[manager->pipe] = crtc; ··· 491 490 if (manager->ops->wait_for_vblank) 492 491 manager->ops->wait_for_vblank(manager); 493 492 } 493 + } 494 + 495 + int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, 496 + unsigned int out_type) 497 + { 498 + struct drm_crtc *crtc; 499 + 500 + list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) { 501 + struct exynos_drm_crtc *exynos_crtc; 502 + 503 + exynos_crtc = to_exynos_crtc(crtc); 504 + if (exynos_crtc->manager->type == out_type) 505 + return exynos_crtc->manager->pipe; 506 + } 507 + 508 + return -EPERM; 494 509 }
+4
drivers/gpu/drm/exynos/exynos_drm_crtc.h
··· 32 32 void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos); 33 33 void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos); 34 34 35 + /* This function gets pipe value to crtc device matched with out_type. */ 36 + int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, 37 + unsigned int out_type); 38 + 35 39 #endif
+9 -7
drivers/gpu/drm/exynos/exynos_drm_dpi.c
··· 248 248 FIMD_PORT_WRB, 249 249 }; 250 250 251 - static struct device_node *exynos_dpi_of_find_panel_node(struct device *dev) 251 + struct device_node *exynos_dpi_of_find_panel_node(struct device *dev) 252 252 { 253 253 struct device_node *np, *ep; 254 254 ··· 301 301 return 0; 302 302 } 303 303 304 - int exynos_dpi_probe(struct device *dev) 304 + int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev) 305 305 { 306 306 struct exynos_dpi *ctx; 307 307 int ret; ··· 318 318 if (ret < 0) 319 319 return ret; 320 320 321 - exynos_drm_display_register(&exynos_dpi_display); 322 - 323 - return 0; 321 + return exynos_drm_create_enc_conn(drm_dev, &exynos_dpi_display); 324 322 } 325 323 326 - int exynos_dpi_remove(struct device *dev) 324 + int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev) 327 325 { 326 + struct drm_encoder *encoder = exynos_dpi_display.encoder; 327 + struct exynos_dpi *ctx = exynos_dpi_display.ctx; 328 + 328 329 exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); 329 - exynos_drm_display_unregister(&exynos_dpi_display); 330 + encoder->funcs->destroy(encoder); 331 + drm_connector_cleanup(&ctx->connector); 330 332 331 333 return 0; 332 334 }
+200 -110
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 16 16 #include <drm/drm_crtc_helper.h> 17 17 18 18 #include <linux/anon_inodes.h> 19 + #include <linux/component.h> 19 20 20 21 #include <drm/exynos_drm.h> 21 22 ··· 41 40 42 41 #define VBLANK_OFF_DELAY 50000 43 42 44 - /* platform device pointer for eynos drm device. */ 45 43 static struct platform_device *exynos_drm_pdev; 44 + 45 + static DEFINE_MUTEX(drm_component_lock); 46 + static LIST_HEAD(drm_component_list); 47 + 48 + struct component_dev { 49 + struct list_head list; 50 + struct device *dev; 51 + }; 46 52 47 53 static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 48 54 { ··· 81 73 82 74 exynos_drm_mode_config_init(dev); 83 75 84 - ret = exynos_drm_initialize_managers(dev); 85 - if (ret) 86 - goto err_mode_config_cleanup; 87 - 88 76 for (nr = 0; nr < MAX_PLANE; nr++) { 89 77 struct drm_plane *plane; 90 78 unsigned long possible_crtcs = (1 << MAX_CRTC) - 1; 91 79 92 80 plane = exynos_plane_init(dev, possible_crtcs, false); 93 81 if (!plane) 94 - goto err_manager_cleanup; 82 + goto err_mode_config_cleanup; 95 83 } 96 - 97 - ret = exynos_drm_initialize_displays(dev); 98 - if (ret) 99 - goto err_manager_cleanup; 100 84 101 85 /* init kms poll for handling hpd */ 102 86 drm_kms_helper_poll_init(dev); 103 87 104 88 ret = drm_vblank_init(dev, MAX_CRTC); 105 89 if (ret) 106 - goto err_display_cleanup; 107 - 108 - /* 109 - * probe sub drivers such as display controller and hdmi driver, 110 - * that were registered at probe() of platform driver 111 - * to the sub driver and create encoder and connector for them. 112 - */ 113 - ret = exynos_drm_device_register(dev); 114 - if (ret) 115 - goto err_vblank; 90 + goto err_mode_config_cleanup; 116 91 117 92 /* setup possible_clones. */ 118 93 exynos_drm_encoder_setup(dev); ··· 104 113 105 114 platform_set_drvdata(dev->platformdev, dev); 106 115 116 + /* Try to bind all sub drivers. */ 117 + ret = component_bind_all(dev->dev, dev); 118 + if (ret) 119 + goto err_cleanup_vblank; 120 + 121 + /* Probe non kms sub drivers. */ 122 + ret = exynos_drm_device_subdrv_probe(dev); 123 + if (ret) 124 + goto err_unbind_all; 125 + 107 126 /* force connectors detection */ 108 127 drm_helper_hpd_irq_event(dev); 109 128 110 129 return 0; 111 130 112 - err_vblank: 131 + err_unbind_all: 132 + component_unbind_all(dev->dev, dev); 133 + err_cleanup_vblank: 113 134 drm_vblank_cleanup(dev); 114 - err_display_cleanup: 115 - exynos_drm_remove_displays(dev); 116 - err_manager_cleanup: 117 - exynos_drm_remove_managers(dev); 118 135 err_mode_config_cleanup: 119 136 drm_mode_config_cleanup(dev); 120 137 drm_release_iommu_mapping(dev); ··· 134 135 135 136 static int exynos_drm_unload(struct drm_device *dev) 136 137 { 138 + exynos_drm_device_subdrv_remove(dev); 139 + 137 140 exynos_drm_fbdev_fini(dev); 138 - exynos_drm_device_unregister(dev); 139 141 drm_vblank_cleanup(dev); 140 142 drm_kms_helper_poll_fini(dev); 141 - exynos_drm_remove_displays(dev); 142 - exynos_drm_remove_managers(dev); 143 143 drm_mode_config_cleanup(dev); 144 144 145 145 drm_release_iommu_mapping(dev); 146 146 kfree(dev->dev_private); 147 147 148 + component_unbind_all(dev->dev, dev); 148 149 dev->dev_private = NULL; 149 150 150 151 return 0; ··· 353 354 .minor = DRIVER_MINOR, 354 355 }; 355 356 356 - static int exynos_drm_platform_probe(struct platform_device *pdev) 357 - { 358 - int ret; 359 - 360 - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 361 - if (ret) 362 - return ret; 363 - 364 - pm_runtime_enable(&pdev->dev); 365 - pm_runtime_get_sync(&pdev->dev); 366 - 367 - return drm_platform_init(&exynos_drm_driver, pdev); 368 - } 369 - 370 - static int exynos_drm_platform_remove(struct platform_device *pdev) 371 - { 372 - drm_put_dev(platform_get_drvdata(pdev)); 373 - 374 - return 0; 375 - } 376 - 377 357 #ifdef CONFIG_PM_SLEEP 378 358 static int exynos_drm_sys_suspend(struct device *dev) 379 359 { ··· 407 429 exynos_drm_runtime_resume, NULL) 408 430 }; 409 431 410 - static struct platform_driver exynos_drm_platform_driver = { 411 - .probe = exynos_drm_platform_probe, 412 - .remove = exynos_drm_platform_remove, 413 - .driver = { 414 - .owner = THIS_MODULE, 415 - .name = "exynos-drm", 416 - .pm = &exynos_drm_pm_ops, 417 - }, 432 + int exynos_drm_component_add(struct device *dev, 433 + const struct component_ops *ops) 434 + { 435 + struct component_dev *cdev; 436 + int ret; 437 + 438 + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 439 + if (!cdev) 440 + return -ENOMEM; 441 + 442 + ret = component_add(dev, ops); 443 + if (ret) { 444 + kfree(cdev); 445 + return ret; 446 + } 447 + 448 + cdev->dev = dev; 449 + 450 + mutex_lock(&drm_component_lock); 451 + list_add_tail(&cdev->list, &drm_component_list); 452 + mutex_unlock(&drm_component_lock); 453 + 454 + return 0; 455 + } 456 + 457 + void exynos_drm_component_del(struct device *dev, 458 + const struct component_ops *ops) 459 + { 460 + struct component_dev *cdev, *next; 461 + 462 + mutex_lock(&drm_component_lock); 463 + 464 + list_for_each_entry_safe(cdev, next, &drm_component_list, list) { 465 + if (dev == cdev->dev) { 466 + list_del(&cdev->list); 467 + kfree(cdev); 468 + mutex_unlock(&drm_component_lock); 469 + break; 470 + } 471 + } 472 + 473 + mutex_unlock(&drm_component_lock); 474 + 475 + component_del(dev, ops); 476 + } 477 + 478 + static int compare_of(struct device *dev, void *data) 479 + { 480 + return dev == (struct device *)data; 481 + } 482 + 483 + static int exynos_drm_add_components(struct device *dev, struct master *m) 484 + { 485 + unsigned int attached_cnt = 0; 486 + struct component_dev *cdev; 487 + 488 + mutex_lock(&drm_component_lock); 489 + 490 + list_for_each_entry(cdev, &drm_component_list, list) { 491 + int ret; 492 + 493 + mutex_unlock(&drm_component_lock); 494 + 495 + ret = component_master_add_child(m, compare_of, cdev->dev); 496 + if (!ret) 497 + attached_cnt++; 498 + 499 + mutex_lock(&drm_component_lock); 500 + } 501 + 502 + mutex_unlock(&drm_component_lock); 503 + 504 + if (!attached_cnt) 505 + return -ENXIO; 506 + 507 + return 0; 508 + } 509 + 510 + static int exynos_drm_bind(struct device *dev) 511 + { 512 + pm_runtime_enable(dev); 513 + pm_runtime_get_sync(dev); 514 + 515 + return drm_platform_init(&exynos_drm_driver, to_platform_device(dev)); 516 + } 517 + 518 + static void exynos_drm_unbind(struct device *dev) 519 + { 520 + drm_put_dev(dev_get_drvdata(dev)); 521 + } 522 + 523 + static const struct component_master_ops exynos_drm_ops = { 524 + .add_components = exynos_drm_add_components, 525 + .bind = exynos_drm_bind, 526 + .unbind = exynos_drm_unbind, 418 527 }; 419 528 420 - static int __init exynos_drm_init(void) 529 + static int exynos_drm_platform_probe(struct platform_device *pdev) 421 530 { 422 531 int ret; 532 + 533 + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 534 + exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); 535 + 536 + #ifdef CONFIG_DRM_EXYNOS_FIMD 537 + ret = platform_driver_register(&fimd_driver); 538 + if (ret < 0) 539 + return ret; 540 + #endif 423 541 424 542 #ifdef CONFIG_DRM_EXYNOS_DP 425 543 ret = platform_driver_register(&dp_driver); 426 544 if (ret < 0) 427 - return ret; 545 + goto err_unregister_fimd_drv; 428 546 #endif 429 547 430 548 #ifdef CONFIG_DRM_EXYNOS_DSI ··· 529 455 goto err_unregister_dp_drv; 530 456 #endif 531 457 532 - #ifdef CONFIG_DRM_EXYNOS_FIMD 533 - ret = platform_driver_register(&fimd_driver); 534 - if (ret < 0) 535 - goto err_unregister_dsi_drv; 536 - #endif 537 - 538 458 #ifdef CONFIG_DRM_EXYNOS_HDMI 539 - ret = platform_driver_register(&hdmi_driver); 540 - if (ret < 0) 541 - goto err_unregister_fimd_drv; 542 459 ret = platform_driver_register(&mixer_driver); 543 460 if (ret < 0) 544 - goto err_unregister_hdmi_drv; 545 - #endif 546 - 547 - #ifdef CONFIG_DRM_EXYNOS_VIDI 548 - ret = platform_driver_register(&vidi_driver); 461 + goto err_unregister_dsi_drv; 462 + ret = platform_driver_register(&hdmi_driver); 549 463 if (ret < 0) 550 464 goto err_unregister_mixer_drv; 551 465 #endif ··· 541 479 #ifdef CONFIG_DRM_EXYNOS_G2D 542 480 ret = platform_driver_register(&g2d_driver); 543 481 if (ret < 0) 544 - goto err_unregister_vidi_drv; 482 + goto err_unregister_hdmi_drv; 545 483 #endif 546 484 547 485 #ifdef CONFIG_DRM_EXYNOS_FIMC ··· 572 510 goto err_unregister_ipp_drv; 573 511 #endif 574 512 575 - ret = platform_driver_register(&exynos_drm_platform_driver); 513 + ret = component_master_add(&pdev->dev, &exynos_drm_ops); 576 514 if (ret < 0) 577 - goto err_unregister_ipp_dev; 578 - 579 - exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, 580 - NULL, 0); 581 - if (IS_ERR(exynos_drm_pdev)) { 582 - ret = PTR_ERR(exynos_drm_pdev); 583 - goto err_unregister_drm_drv; 584 - } 515 + DRM_DEBUG_KMS("re-tried by last sub driver probed later.\n"); 585 516 586 517 return 0; 587 518 588 - err_unregister_drm_drv: 589 - platform_driver_unregister(&exynos_drm_platform_driver); 590 - 591 - err_unregister_ipp_dev: 592 519 #ifdef CONFIG_DRM_EXYNOS_IPP 593 - exynos_platform_device_ipp_unregister(); 594 520 err_unregister_ipp_drv: 595 521 platform_driver_unregister(&ipp_driver); 596 522 err_unregister_gsc_drv: ··· 601 551 602 552 #ifdef CONFIG_DRM_EXYNOS_G2D 603 553 platform_driver_unregister(&g2d_driver); 604 - err_unregister_vidi_drv: 605 - #endif 606 - 607 - #ifdef CONFIG_DRM_EXYNOS_VIDI 608 - platform_driver_unregister(&vidi_driver); 609 - err_unregister_mixer_drv: 554 + err_unregister_hdmi_drv: 610 555 #endif 611 556 612 557 #ifdef CONFIG_DRM_EXYNOS_HDMI 613 - platform_driver_unregister(&mixer_driver); 614 - err_unregister_hdmi_drv: 615 558 platform_driver_unregister(&hdmi_driver); 616 - err_unregister_fimd_drv: 617 - #endif 618 - 619 - #ifdef CONFIG_DRM_EXYNOS_FIMD 620 - platform_driver_unregister(&fimd_driver); 559 + err_unregister_mixer_drv: 560 + platform_driver_unregister(&mixer_driver); 621 561 err_unregister_dsi_drv: 622 562 #endif 623 563 ··· 618 578 619 579 #ifdef CONFIG_DRM_EXYNOS_DP 620 580 platform_driver_unregister(&dp_driver); 581 + err_unregister_fimd_drv: 582 + #endif 583 + 584 + #ifdef CONFIG_DRM_EXYNOS_FIMD 585 + platform_driver_unregister(&fimd_driver); 621 586 #endif 622 587 return ret; 623 588 } 624 589 625 - static void __exit exynos_drm_exit(void) 590 + static int exynos_drm_platform_remove(struct platform_device *pdev) 626 591 { 627 - platform_device_unregister(exynos_drm_pdev); 628 - 629 - platform_driver_unregister(&exynos_drm_platform_driver); 630 - 631 592 #ifdef CONFIG_DRM_EXYNOS_IPP 632 593 exynos_platform_device_ipp_unregister(); 633 594 platform_driver_unregister(&ipp_driver); ··· 655 614 platform_driver_unregister(&hdmi_driver); 656 615 #endif 657 616 658 - #ifdef CONFIG_DRM_EXYNOS_VIDI 659 - platform_driver_unregister(&vidi_driver); 660 - #endif 661 - 662 617 #ifdef CONFIG_DRM_EXYNOS_FIMD 663 618 platform_driver_unregister(&fimd_driver); 664 619 #endif ··· 666 629 #ifdef CONFIG_DRM_EXYNOS_DP 667 630 platform_driver_unregister(&dp_driver); 668 631 #endif 632 + component_master_del(&pdev->dev, &exynos_drm_ops); 633 + return 0; 634 + } 635 + 636 + static struct platform_driver exynos_drm_platform_driver = { 637 + .probe = exynos_drm_platform_probe, 638 + .remove = exynos_drm_platform_remove, 639 + .driver = { 640 + .owner = THIS_MODULE, 641 + .name = "exynos-drm", 642 + .pm = &exynos_drm_pm_ops, 643 + }, 644 + }; 645 + 646 + static int exynos_drm_init(void) 647 + { 648 + int ret; 649 + 650 + exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, 651 + NULL, 0); 652 + if (IS_ERR(exynos_drm_pdev)) 653 + return PTR_ERR(exynos_drm_pdev); 654 + 655 + #ifdef CONFIG_DRM_EXYNOS_VIDI 656 + ret = exynos_drm_probe_vidi(); 657 + if (ret < 0) 658 + goto err_unregister_pd; 659 + #endif 660 + 661 + ret = platform_driver_register(&exynos_drm_platform_driver); 662 + if (ret) 663 + goto err_remove_vidi; 664 + 665 + return 0; 666 + 667 + err_unregister_pd: 668 + platform_device_unregister(exynos_drm_pdev); 669 + 670 + err_remove_vidi: 671 + #ifdef CONFIG_DRM_EXYNOS_VIDI 672 + exynos_drm_remove_vidi(); 673 + #endif 674 + 675 + return ret; 676 + } 677 + 678 + static void exynos_drm_exit(void) 679 + { 680 + #ifdef CONFIG_DRM_EXYNOS_VIDI 681 + exynos_drm_remove_vidi(); 682 + #endif 683 + platform_device_unregister(exynos_drm_pdev); 684 + platform_driver_unregister(&exynos_drm_platform_driver); 669 685 } 670 686 671 687 module_init(exynos_drm_init);
+44 -45
drivers/gpu/drm/exynos/exynos_drm_drv.h
··· 122 122 * Exynos DRM Display Structure. 123 123 * - this structure is common to analog tv, digital tv and lcd panel. 124 124 * 125 - * @initialize: initializes the display with drm_dev 126 125 * @remove: cleans up the display for removal 127 126 * @mode_fixup: fix mode data comparing to hw specific display mode. 128 127 * @mode_set: convert drm_display_mode to hw specific display mode and ··· 132 133 */ 133 134 struct exynos_drm_display; 134 135 struct exynos_drm_display_ops { 135 - int (*initialize)(struct exynos_drm_display *display, 136 - struct drm_device *drm_dev); 137 136 int (*create_connector)(struct exynos_drm_display *display, 138 137 struct drm_encoder *encoder); 139 138 void (*remove)(struct exynos_drm_display *display); ··· 169 172 /* 170 173 * Exynos drm manager ops 171 174 * 172 - * @initialize: initializes the manager with drm_dev 173 - * @remove: cleans up the manager for removal 174 175 * @dpms: control device power. 175 176 * @mode_fixup: fix mode data before applying it 176 177 * @mode_set: set the given mode to the manager ··· 184 189 */ 185 190 struct exynos_drm_manager; 186 191 struct exynos_drm_manager_ops { 187 - int (*initialize)(struct exynos_drm_manager *mgr, 188 - struct drm_device *drm_dev, int pipe); 189 - void (*remove)(struct exynos_drm_manager *mgr); 190 192 void (*dpms)(struct exynos_drm_manager *mgr, int mode); 191 193 bool (*mode_fixup)(struct exynos_drm_manager *mgr, 192 194 const struct drm_display_mode *mode, ··· 207 215 * @list: the list entry for this manager 208 216 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. 209 217 * @drm_dev: pointer to the drm device 218 + * @crtc: crtc object. 210 219 * @pipe: the pipe number for this crtc/manager 211 220 * @ops: pointer to callbacks for exynos drm specific functionality 212 221 * @ctx: A pointer to the manager's implementation specific context ··· 216 223 struct list_head list; 217 224 enum exynos_drm_output_type type; 218 225 struct drm_device *drm_dev; 226 + struct drm_crtc *crtc; 219 227 int pipe; 220 228 struct exynos_drm_manager_ops *ops; 221 229 void *ctx; ··· 248 254 * otherwise default one. 249 255 * @da_space_size: size of device address space. 250 256 * if 0 then default value is used for it. 257 + * @pipe: the pipe number for this crtc/manager. 251 258 */ 252 259 struct exynos_drm_private { 253 260 struct drm_fb_helper *fb_helper; ··· 266 271 267 272 unsigned long da_start; 268 273 unsigned long da_space_size; 274 + 275 + unsigned int pipe; 269 276 }; 270 277 271 278 /* ··· 278 281 * @drm_dev: pointer to drm_device and this pointer would be set 279 282 * when sub driver calls exynos_drm_subdrv_register(). 280 283 * @manager: subdrv has its own manager to control a hardware appropriately 281 - * and we can access a hardware drawing on this manager. 284 + * and we can access a hardware drawing on this manager. 282 285 * @probe: this callback would be called by exynos drm driver after 283 - * subdrv is registered to it. 286 + * subdrv is registered to it. 284 287 * @remove: this callback is used to release resources created 285 - * by probe callback. 288 + * by probe callback. 286 289 * @open: this would be called with drm device file open. 287 290 * @close: this would be called with drm device file close. 288 291 */ ··· 299 302 struct drm_file *file); 300 303 }; 301 304 302 - /* 303 - * this function calls a probe callback registered to sub driver list and 304 - * create its own encoder and connector and then set drm_device object 305 - * to global one. 306 - */ 307 - int exynos_drm_device_register(struct drm_device *dev); 308 - /* 309 - * this function calls a remove callback registered to sub driver list and 310 - * destroy its own encoder and connetor. 311 - */ 312 - int exynos_drm_device_unregister(struct drm_device *dev); 313 - 314 - int exynos_drm_initialize_managers(struct drm_device *dev); 315 - void exynos_drm_remove_managers(struct drm_device *dev); 316 - int exynos_drm_initialize_displays(struct drm_device *dev); 317 - void exynos_drm_remove_displays(struct drm_device *dev); 318 - 319 - int exynos_drm_manager_register(struct exynos_drm_manager *manager); 320 - int exynos_drm_manager_unregister(struct exynos_drm_manager *manager); 321 - int exynos_drm_display_register(struct exynos_drm_display *display); 322 - int exynos_drm_display_unregister(struct exynos_drm_display *display); 323 - 324 - /* 325 - * this function would be called by sub drivers such as display controller 326 - * or hdmi driver to register this sub driver object to exynos drm driver 327 - * and when a sub driver is registered to exynos drm driver a probe callback 328 - * of the sub driver is called and creates its own encoder and connector. 329 - */ 305 + /* This function would be called by non kms drivers such as g2d and ipp. */ 330 306 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); 331 307 332 308 /* this function removes subdrv list from exynos drm driver */ 333 309 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); 334 310 311 + int exynos_drm_device_subdrv_probe(struct drm_device *dev); 312 + int exynos_drm_device_subdrv_remove(struct drm_device *dev); 335 313 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); 336 314 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); 337 315 ··· 332 360 void exynos_platform_device_ipp_unregister(void); 333 361 334 362 #ifdef CONFIG_DRM_EXYNOS_DPI 335 - int exynos_dpi_probe(struct device *dev); 336 - int exynos_dpi_remove(struct device *dev); 363 + int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev); 364 + int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev); 365 + struct device_node *exynos_dpi_of_find_panel_node(struct device *dev); 337 366 #else 338 - static inline int exynos_dpi_probe(struct device *dev) { return 0; } 339 - static inline int exynos_dpi_remove(struct device *dev) { return 0; } 367 + static inline int exynos_dpi_probe(struct drm_device *drm_dev, 368 + struct device *dev) { return 0; } 369 + static inline int exynos_dpi_remove(struct drm_device *drm_dev, 370 + struct device *dev) { return 0; } 371 + static inline struct device_node 372 + *exynos_dpi_of_find_panel_node(struct device *dev) 373 + { return NULL; } 340 374 #endif 341 375 376 + /* 377 + * this function registers exynos drm vidi platform device/driver. 378 + */ 379 + int exynos_drm_probe_vidi(void); 380 + 381 + /* 382 + * this function unregister exynos drm vidi platform device/driver. 383 + */ 384 + void exynos_drm_remove_vidi(void); 385 + 386 + /* This function creates a encoder and a connector, and initializes them. */ 387 + int exynos_drm_create_enc_conn(struct drm_device *dev, 388 + struct exynos_drm_display *display); 389 + 390 + struct component_ops; 391 + int exynos_drm_component_add(struct device *dev, 392 + const struct component_ops *ops); 393 + 394 + void exynos_drm_component_del(struct device *dev, 395 + const struct component_ops *ops); 396 + 397 + extern struct platform_driver fimd_driver; 342 398 extern struct platform_driver dp_driver; 343 399 extern struct platform_driver dsi_driver; 344 - extern struct platform_driver fimd_driver; 345 - extern struct platform_driver hdmi_driver; 346 400 extern struct platform_driver mixer_driver; 401 + extern struct platform_driver hdmi_driver; 347 402 extern struct platform_driver exynos_drm_common_hdmi_driver; 348 403 extern struct platform_driver vidi_driver; 349 404 extern struct platform_driver g2d_driver;
+71 -39
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 19 19 #include <linux/irq.h> 20 20 #include <linux/phy/phy.h> 21 21 #include <linux/regulator/consumer.h> 22 + #include <linux/component.h> 22 23 23 24 #include <video/mipi_display.h> 24 25 #include <video/videomode.h> ··· 1379 1378 return ret; 1380 1379 } 1381 1380 1381 + static int exynos_dsi_bind(struct device *dev, struct device *master, 1382 + void *data) 1383 + { 1384 + struct drm_device *drm_dev = data; 1385 + struct exynos_dsi *dsi; 1386 + int ret; 1387 + 1388 + ret = exynos_drm_create_enc_conn(drm_dev, &exynos_dsi_display); 1389 + if (ret) { 1390 + DRM_ERROR("Encoder create [%d] failed with %d\n", 1391 + exynos_dsi_display.type, ret); 1392 + return ret; 1393 + } 1394 + 1395 + dsi = exynos_dsi_display.ctx; 1396 + 1397 + return mipi_dsi_host_register(&dsi->dsi_host); 1398 + } 1399 + 1400 + static void exynos_dsi_unbind(struct device *dev, struct device *master, 1401 + void *data) 1402 + { 1403 + struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1404 + struct drm_encoder *encoder = dsi->encoder; 1405 + 1406 + exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); 1407 + 1408 + mipi_dsi_host_unregister(&dsi->dsi_host); 1409 + 1410 + encoder->funcs->destroy(encoder); 1411 + drm_connector_cleanup(&dsi->connector); 1412 + } 1413 + 1414 + #if CONFIG_PM_SLEEP 1415 + static int exynos_dsi_resume(struct device *dev) 1416 + { 1417 + struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1418 + 1419 + if (dsi->state & DSIM_STATE_ENABLED) { 1420 + dsi->state &= ~DSIM_STATE_ENABLED; 1421 + exynos_dsi_enable(dsi); 1422 + } 1423 + 1424 + return 0; 1425 + } 1426 + 1427 + static int exynos_dsi_suspend(struct device *dev) 1428 + { 1429 + struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1430 + 1431 + if (dsi->state & DSIM_STATE_ENABLED) { 1432 + exynos_dsi_disable(dsi); 1433 + dsi->state |= DSIM_STATE_ENABLED; 1434 + } 1435 + 1436 + return 0; 1437 + } 1438 + #endif 1439 + 1440 + static const struct dev_pm_ops exynos_dsi_pm_ops = { 1441 + SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume) 1442 + }; 1443 + 1444 + static const struct component_ops exynos_dsi_component_ops = { 1445 + .bind = exynos_dsi_bind, 1446 + .unbind = exynos_dsi_unbind, 1447 + }; 1448 + 1382 1449 static int exynos_dsi_probe(struct platform_device *pdev) 1383 1450 { 1384 1451 struct resource *res; ··· 1524 1455 exynos_dsi_display.ctx = dsi; 1525 1456 1526 1457 platform_set_drvdata(pdev, &exynos_dsi_display); 1527 - exynos_drm_display_register(&exynos_dsi_display); 1528 1458 1529 - return mipi_dsi_host_register(&dsi->dsi_host); 1459 + return exynos_drm_component_add(&pdev->dev, &exynos_dsi_component_ops); 1530 1460 } 1531 1461 1532 1462 static int exynos_dsi_remove(struct platform_device *pdev) 1533 1463 { 1534 - struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1535 - 1536 - exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); 1537 - 1538 - exynos_drm_display_unregister(&exynos_dsi_display); 1539 - mipi_dsi_host_unregister(&dsi->dsi_host); 1540 - 1464 + exynos_drm_component_del(&pdev->dev, &exynos_dsi_component_ops); 1541 1465 return 0; 1542 1466 } 1543 - 1544 - #if CONFIG_PM_SLEEP 1545 - static int exynos_dsi_resume(struct device *dev) 1546 - { 1547 - struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1548 - 1549 - if (dsi->state & DSIM_STATE_ENABLED) { 1550 - dsi->state &= ~DSIM_STATE_ENABLED; 1551 - exynos_dsi_enable(dsi); 1552 - } 1553 - 1554 - return 0; 1555 - } 1556 - 1557 - static int exynos_dsi_suspend(struct device *dev) 1558 - { 1559 - struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1560 - 1561 - if (dsi->state & DSIM_STATE_ENABLED) { 1562 - exynos_dsi_disable(dsi); 1563 - dsi->state |= DSIM_STATE_ENABLED; 1564 - } 1565 - 1566 - return 0; 1567 - } 1568 - #endif 1569 - 1570 - static const struct dev_pm_ops exynos_dsi_pm_ops = { 1571 - SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume) 1572 - }; 1573 1467 1574 1468 static struct of_device_id exynos_dsi_of_match[] = { 1575 1469 { .compatible = "samsung,exynos4210-mipi-dsi" },
+69 -16
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 19 19 #include <linux/of.h> 20 20 #include <linux/of_device.h> 21 21 #include <linux/pm_runtime.h> 22 + #include <linux/component.h> 22 23 23 24 #include <video/of_display_timing.h> 24 25 #include <video/of_videomode.h> 25 26 #include <video/samsung_fimd.h> 27 + #include <drm/drm_panel.h> 26 28 #include <drm/exynos_drm.h> 27 29 28 30 #include "exynos_drm_drv.h" ··· 188 186 } 189 187 190 188 static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, 191 - struct drm_device *drm_dev, int pipe) 189 + struct drm_device *drm_dev) 192 190 { 193 191 struct fimd_context *ctx = mgr->ctx; 192 + struct exynos_drm_private *priv; 193 + priv = drm_dev->dev_private; 194 194 195 - ctx->drm_dev = drm_dev; 196 - ctx->pipe = pipe; 195 + mgr->drm_dev = ctx->drm_dev = drm_dev; 196 + mgr->pipe = ctx->pipe = priv->pipe++; 197 197 198 198 /* 199 199 * enable drm irq mode. ··· 836 832 } 837 833 838 834 static struct exynos_drm_manager_ops fimd_manager_ops = { 839 - .initialize = fimd_mgr_initialize, 840 - .remove = fimd_mgr_remove, 841 835 .dpms = fimd_dpms, 842 836 .mode_fixup = fimd_mode_fixup, 843 837 .mode_set = fimd_mode_set, ··· 880 878 return IRQ_HANDLED; 881 879 } 882 880 883 - static int fimd_probe(struct platform_device *pdev) 881 + static int fimd_bind(struct device *dev, struct device *master, void *data) 884 882 { 885 - struct device *dev = &pdev->dev; 883 + struct platform_device *pdev = to_platform_device(dev); 884 + struct drm_device *drm_dev = data; 886 885 struct fimd_context *ctx; 886 + struct device_node *dn; 887 887 struct resource *res; 888 888 int win; 889 889 int ret = -EINVAL; ··· 943 939 platform_set_drvdata(pdev, &fimd_manager); 944 940 945 941 fimd_manager.ctx = ctx; 946 - exynos_drm_manager_register(&fimd_manager); 942 + fimd_mgr_initialize(&fimd_manager, drm_dev); 947 943 948 - exynos_dpi_probe(ctx->dev); 944 + exynos_drm_crtc_create(&fimd_manager); 949 945 950 - pm_runtime_enable(dev); 946 + dn = exynos_dpi_of_find_panel_node(&pdev->dev); 947 + if (dn) { 948 + /* 949 + * It should be called after exynos_drm_crtc_create call 950 + * because exynos_dpi_probe call will try to find same lcd 951 + * type of manager to setup possible_crtcs. 952 + */ 953 + exynos_dpi_probe(drm_dev, dev); 954 + } 951 955 952 956 for (win = 0; win < WINDOWS_NR; win++) 953 957 fimd_clear_win(ctx, win); ··· 963 951 return 0; 964 952 } 965 953 966 - static int fimd_remove(struct platform_device *pdev) 954 + static void fimd_unbind(struct device *dev, struct device *master, 955 + void *data) 967 956 { 968 - struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); 969 - 970 - exynos_dpi_remove(&pdev->dev); 971 - 972 - exynos_drm_manager_unregister(&fimd_manager); 957 + struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 958 + struct drm_crtc *crtc = mgr->crtc; 959 + struct device_node *dn; 973 960 974 961 fimd_dpms(mgr, DRM_MODE_DPMS_OFF); 975 962 963 + dn = exynos_dpi_of_find_panel_node(dev); 964 + if (dn) 965 + exynos_dpi_remove(mgr->drm_dev, dev); 966 + 967 + fimd_mgr_remove(mgr); 968 + 969 + crtc->funcs->destroy(crtc); 970 + } 971 + 972 + static const struct component_ops fimd_component_ops = { 973 + .bind = fimd_bind, 974 + .unbind = fimd_unbind, 975 + }; 976 + 977 + static int fimd_probe(struct platform_device *pdev) 978 + { 979 + struct device_node *dn; 980 + 981 + /* Check if fimd node has port node. */ 982 + dn = exynos_dpi_of_find_panel_node(&pdev->dev); 983 + if (dn) { 984 + struct drm_panel *panel; 985 + 986 + /* 987 + * Do not bind if there is the port node but a drm_panel 988 + * isn't added to panel_list yet. 989 + * In this case, fimd_probe will be called by defered probe 990 + * again after the drm_panel is added to panel_list. 991 + */ 992 + panel = of_drm_find_panel(dn); 993 + if (!panel) 994 + return -EPROBE_DEFER; 995 + } 996 + 997 + pm_runtime_enable(&pdev->dev); 998 + 999 + return exynos_drm_component_add(&pdev->dev, &fimd_component_ops); 1000 + } 1001 + 1002 + static int fimd_remove(struct platform_device *pdev) 1003 + { 976 1004 pm_runtime_disable(&pdev->dev); 977 1005 1006 + exynos_drm_component_del(&pdev->dev, &fimd_component_ops); 978 1007 return 0; 979 1008 } 980 1009
+84 -17
drivers/gpu/drm/exynos/exynos_drm_vidi.c
··· 51 51 struct drm_crtc *crtc; 52 52 struct drm_encoder *encoder; 53 53 struct drm_connector connector; 54 + struct exynos_drm_subdrv subdrv; 54 55 struct vidi_win_data win_data[WINDOWS_NR]; 55 56 struct edid *raw_edid; 56 57 unsigned int clkdiv; ··· 295 294 } 296 295 297 296 static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, 298 - struct drm_device *drm_dev, int pipe) 297 + struct drm_device *drm_dev) 299 298 { 300 299 struct vidi_context *ctx = mgr->ctx; 300 + struct exynos_drm_private *priv = drm_dev->dev_private; 301 301 302 - DRM_ERROR("vidi initialize ct=%p dev=%p pipe=%d\n", ctx, drm_dev, pipe); 303 - 304 - ctx->drm_dev = drm_dev; 305 - ctx->pipe = pipe; 302 + mgr->drm_dev = ctx->drm_dev = drm_dev; 303 + mgr->pipe = ctx->pipe = priv->pipe++; 306 304 307 305 /* 308 306 * enable drm irq mode. ··· 324 324 } 325 325 326 326 static struct exynos_drm_manager_ops vidi_manager_ops = { 327 - .initialize = vidi_mgr_initialize, 328 327 .dpms = vidi_dpms, 329 328 .commit = vidi_commit, 330 329 .enable_vblank = vidi_enable_vblank, ··· 578 579 .ops = &vidi_display_ops, 579 580 }; 580 581 582 + static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) 583 + { 584 + struct exynos_drm_manager *mgr = get_vidi_mgr(dev); 585 + struct vidi_context *ctx = mgr->ctx; 586 + struct drm_crtc *crtc = ctx->crtc; 587 + int ret; 588 + 589 + vidi_mgr_initialize(mgr, drm_dev); 590 + 591 + ret = exynos_drm_crtc_create(&vidi_manager); 592 + if (ret) { 593 + DRM_ERROR("failed to create crtc.\n"); 594 + return ret; 595 + } 596 + 597 + ret = exynos_drm_create_enc_conn(drm_dev, &vidi_display); 598 + if (ret) { 599 + crtc->funcs->destroy(crtc); 600 + DRM_ERROR("failed to create encoder and connector.\n"); 601 + return ret; 602 + } 603 + 604 + return 0; 605 + } 606 + 581 607 static int vidi_probe(struct platform_device *pdev) 582 608 { 583 - struct device *dev = &pdev->dev; 609 + struct exynos_drm_subdrv *subdrv; 584 610 struct vidi_context *ctx; 585 611 int ret; 586 612 587 - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 613 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 588 614 if (!ctx) 589 615 return -ENOMEM; 590 616 ··· 624 600 625 601 platform_set_drvdata(pdev, &vidi_manager); 626 602 627 - ret = device_create_file(dev, &dev_attr_connection); 628 - if (ret < 0) 629 - DRM_INFO("failed to create connection sysfs.\n"); 603 + subdrv = &ctx->subdrv; 604 + subdrv->dev = &pdev->dev; 605 + subdrv->probe = vidi_subdrv_probe; 630 606 631 - exynos_drm_manager_register(&vidi_manager); 632 - exynos_drm_display_register(&vidi_display); 607 + ret = exynos_drm_subdrv_register(subdrv); 608 + if (ret < 0) { 609 + dev_err(&pdev->dev, "failed to register drm vidi device\n"); 610 + return ret; 611 + } 612 + 613 + ret = device_create_file(&pdev->dev, &dev_attr_connection); 614 + if (ret < 0) { 615 + exynos_drm_subdrv_unregister(subdrv); 616 + DRM_INFO("failed to create connection sysfs.\n"); 617 + } 633 618 634 619 return 0; 635 620 } 636 621 637 622 static int vidi_remove(struct platform_device *pdev) 638 623 { 639 - struct vidi_context *ctx = platform_get_drvdata(pdev); 640 - 641 - exynos_drm_display_unregister(&vidi_display); 642 - exynos_drm_manager_unregister(&vidi_manager); 624 + struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); 625 + struct vidi_context *ctx = mgr->ctx; 626 + struct drm_encoder *encoder = ctx->encoder; 627 + struct drm_crtc *crtc = mgr->crtc; 643 628 644 629 if (ctx->raw_edid != (struct edid *)fake_edid_info) { 645 630 kfree(ctx->raw_edid); 646 631 ctx->raw_edid = NULL; 632 + 633 + return -EINVAL; 647 634 } 635 + 636 + crtc->funcs->destroy(crtc); 637 + encoder->funcs->destroy(encoder); 638 + drm_connector_cleanup(&ctx->connector); 648 639 649 640 return 0; 650 641 } ··· 672 633 .owner = THIS_MODULE, 673 634 }, 674 635 }; 636 + 637 + int exynos_drm_probe_vidi(void) 638 + { 639 + struct platform_device *pdev; 640 + int ret; 641 + 642 + pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0); 643 + if (IS_ERR(pdev)) 644 + return PTR_ERR(pdev); 645 + 646 + ret = platform_driver_register(&vidi_driver); 647 + if (ret) { 648 + platform_device_unregister(pdev); 649 + return ret; 650 + } 651 + 652 + return ret; 653 + } 654 + 655 + void exynos_drm_remove_vidi(void) 656 + { 657 + struct vidi_context *ctx = vidi_manager.ctx; 658 + struct exynos_drm_subdrv *subdrv = &ctx->subdrv; 659 + struct platform_device *pdev = to_platform_device(subdrv->dev); 660 + 661 + platform_driver_unregister(&vidi_driver); 662 + platform_device_unregister(pdev); 663 + }
+37 -22
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 36 36 #include <linux/i2c.h> 37 37 #include <linux/of_gpio.h> 38 38 #include <linux/hdmi.h> 39 + #include <linux/component.h> 39 40 40 41 #include <drm/exynos_drm.h> 41 42 42 43 #include "exynos_drm_drv.h" 44 + #include "exynos_drm_crtc.h" 43 45 #include "exynos_mixer.h" 44 46 45 47 #include <linux/gpio.h> ··· 926 924 drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); 927 925 drm_sysfs_connector_add(connector); 928 926 drm_mode_connector_attach_encoder(connector, encoder); 929 - 930 - return 0; 931 - } 932 - 933 - static int hdmi_initialize(struct exynos_drm_display *display, 934 - struct drm_device *drm_dev) 935 - { 936 - struct hdmi_context *hdata = display->ctx; 937 - 938 - hdata->drm_dev = drm_dev; 939 927 940 928 return 0; 941 929 } ··· 1905 1913 } 1906 1914 1907 1915 static struct exynos_drm_display_ops hdmi_display_ops = { 1908 - .initialize = hdmi_initialize, 1909 1916 .create_connector = hdmi_create_connector, 1910 1917 .mode_fixup = hdmi_mode_fixup, 1911 1918 .mode_set = hdmi_mode_set, ··· 2038 2047 } 2039 2048 }; 2040 2049 2050 + static int hdmi_bind(struct device *dev, struct device *master, void *data) 2051 + { 2052 + struct drm_device *drm_dev = data; 2053 + struct hdmi_context *hdata; 2054 + 2055 + hdata = hdmi_display.ctx; 2056 + hdata->drm_dev = drm_dev; 2057 + 2058 + return exynos_drm_create_enc_conn(drm_dev, &hdmi_display); 2059 + } 2060 + 2061 + static void hdmi_unbind(struct device *dev, struct device *master, void *data) 2062 + { 2063 + struct exynos_drm_display *display = get_hdmi_display(dev); 2064 + struct drm_encoder *encoder = display->encoder; 2065 + struct hdmi_context *hdata = display->ctx; 2066 + 2067 + encoder->funcs->destroy(encoder); 2068 + drm_connector_cleanup(&hdata->connector); 2069 + } 2070 + 2071 + static const struct component_ops hdmi_component_ops = { 2072 + .bind = hdmi_bind, 2073 + .unbind = hdmi_unbind, 2074 + }; 2075 + 2041 2076 static int hdmi_probe(struct platform_device *pdev) 2042 2077 { 2078 + struct device_node *ddc_node, *phy_node; 2079 + struct s5p_hdmi_platform_data *pdata; 2080 + struct hdmi_driver_data *drv_data; 2081 + const struct of_device_id *match; 2043 2082 struct device *dev = &pdev->dev; 2044 2083 struct hdmi_context *hdata; 2045 - struct s5p_hdmi_platform_data *pdata; 2046 2084 struct resource *res; 2047 - const struct of_device_id *match; 2048 - struct device_node *ddc_node, *phy_node; 2049 - struct hdmi_driver_data *drv_data; 2050 2085 int ret; 2051 2086 2052 - if (!dev->of_node) 2087 + if (!dev->of_node) 2053 2088 return -ENODEV; 2054 2089 2055 2090 pdata = drm_hdmi_dt_parse_pdata(dev); ··· 2166 2149 } 2167 2150 2168 2151 pm_runtime_enable(dev); 2169 - 2170 2152 hdmi_display.ctx = hdata; 2171 - exynos_drm_display_register(&hdmi_display); 2172 2153 2173 - return 0; 2154 + return exynos_drm_component_add(&pdev->dev, &hdmi_component_ops); 2174 2155 2175 2156 err_hdmiphy: 2176 2157 put_device(&hdata->hdmiphy_port->dev); ··· 2179 2164 2180 2165 static int hdmi_remove(struct platform_device *pdev) 2181 2166 { 2182 - struct device *dev = &pdev->dev; 2183 - struct exynos_drm_display *display = get_hdmi_display(dev); 2184 - struct hdmi_context *hdata = display->ctx; 2167 + struct hdmi_context *hdata = hdmi_display.ctx; 2185 2168 2186 2169 put_device(&hdata->hdmiphy_port->dev); 2187 2170 put_device(&hdata->ddc_adpt->dev); 2171 + 2188 2172 pm_runtime_disable(&pdev->dev); 2189 2173 2174 + exynos_drm_component_del(&pdev->dev, &hdmi_component_ops); 2190 2175 return 0; 2191 2176 } 2192 2177
+44 -12
drivers/gpu/drm/exynos/exynos_mixer.c
··· 31 31 #include <linux/clk.h> 32 32 #include <linux/regulator/consumer.h> 33 33 #include <linux/of.h> 34 + #include <linux/component.h> 34 35 35 36 #include <drm/exynos_drm.h> 36 37 ··· 831 830 } 832 831 833 832 static int mixer_initialize(struct exynos_drm_manager *mgr, 834 - struct drm_device *drm_dev, int pipe) 833 + struct drm_device *drm_dev) 835 834 { 836 835 int ret; 837 836 struct mixer_context *mixer_ctx = mgr->ctx; 837 + struct exynos_drm_private *priv; 838 + priv = drm_dev->dev_private; 838 839 839 - mixer_ctx->drm_dev = drm_dev; 840 - mixer_ctx->pipe = pipe; 840 + mgr->drm_dev = mixer_ctx->drm_dev = drm_dev; 841 + mgr->pipe = mixer_ctx->pipe = priv->pipe++; 841 842 842 843 /* acquire resources: regs, irqs, clocks */ 843 844 ret = mixer_resources_init(mixer_ctx); ··· 1145 1142 } 1146 1143 1147 1144 static struct exynos_drm_manager_ops mixer_manager_ops = { 1148 - .initialize = mixer_initialize, 1149 - .remove = mixer_mgr_remove, 1150 1145 .dpms = mixer_dpms, 1151 1146 .enable_vblank = mixer_enable_vblank, 1152 1147 .disable_vblank = mixer_disable_vblank, ··· 1201 1200 } 1202 1201 }; 1203 1202 1204 - static int mixer_probe(struct platform_device *pdev) 1203 + static int mixer_bind(struct device *dev, struct device *manager, void *data) 1205 1204 { 1206 - struct device *dev = &pdev->dev; 1205 + struct platform_device *pdev = to_platform_device(dev); 1206 + struct drm_device *drm_dev = data; 1207 1207 struct mixer_context *ctx; 1208 1208 struct mixer_drv_data *drv; 1209 + int ret; 1209 1210 1210 1211 dev_info(dev, "probe start\n"); 1211 1212 ··· 1236 1233 atomic_set(&ctx->wait_vsync_event, 0); 1237 1234 1238 1235 mixer_manager.ctx = ctx; 1236 + ret = mixer_initialize(&mixer_manager, drm_dev); 1237 + if (ret) 1238 + return ret; 1239 + 1239 1240 platform_set_drvdata(pdev, &mixer_manager); 1240 - exynos_drm_manager_register(&mixer_manager); 1241 + ret = exynos_drm_crtc_create(&mixer_manager); 1242 + if (ret) { 1243 + mixer_mgr_remove(&mixer_manager); 1244 + return ret; 1245 + } 1241 1246 1242 1247 pm_runtime_enable(dev); 1243 1248 1244 1249 return 0; 1245 1250 } 1246 1251 1252 + static void mixer_unbind(struct device *dev, struct device *master, void *data) 1253 + { 1254 + struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 1255 + struct drm_crtc *crtc = mgr->crtc; 1256 + 1257 + dev_info(dev, "remove successful\n"); 1258 + 1259 + mixer_mgr_remove(mgr); 1260 + 1261 + pm_runtime_disable(dev); 1262 + 1263 + crtc->funcs->destroy(crtc); 1264 + } 1265 + 1266 + static const struct component_ops mixer_component_ops = { 1267 + .bind = mixer_bind, 1268 + .unbind = mixer_unbind, 1269 + }; 1270 + 1271 + static int mixer_probe(struct platform_device *pdev) 1272 + { 1273 + return exynos_drm_component_add(&pdev->dev, &mixer_component_ops); 1274 + } 1275 + 1247 1276 static int mixer_remove(struct platform_device *pdev) 1248 1277 { 1249 - dev_info(&pdev->dev, "remove successful\n"); 1250 - 1251 - pm_runtime_disable(&pdev->dev); 1252 - 1278 + exynos_drm_component_del(&pdev->dev, &mixer_component_ops); 1253 1279 return 0; 1254 1280 } 1255 1281