diff options
Diffstat (limited to 'drivers/gpu/drm/drm_sysfs.c')
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 96 |
1 files changed, 31 insertions, 65 deletions
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 2290b3b73832..1a35ea53106b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #include <drm/drm_core.h> | 22 | #include <drm/drm_core.h> |
23 | #include <drm/drmP.h> | 23 | #include <drm/drmP.h> |
24 | 24 | ||
25 | #define to_drm_minor(d) container_of(d, struct drm_minor, kdev) | 25 | #define to_drm_minor(d) dev_get_drvdata(d) |
26 | #define to_drm_connector(d) container_of(d, struct drm_connector, kdev) | 26 | #define to_drm_connector(d) dev_get_drvdata(d) |
27 | 27 | ||
28 | static struct device_type drm_sysfs_device_minor = { | 28 | static struct device_type drm_sysfs_device_minor = { |
29 | .name = "drm_minor" | 29 | .name = "drm_minor" |
@@ -162,20 +162,6 @@ void drm_sysfs_destroy(void) | |||
162 | drm_class = NULL; | 162 | drm_class = NULL; |
163 | } | 163 | } |
164 | 164 | ||
165 | /** | ||
166 | * drm_sysfs_device_release - do nothing | ||
167 | * @dev: Linux device | ||
168 | * | ||
169 | * Normally, this would free the DRM device associated with @dev, along | ||
170 | * with cleaning up any other stuff. But we do that in the DRM core, so | ||
171 | * this function can just return and hope that the core does its job. | ||
172 | */ | ||
173 | static void drm_sysfs_device_release(struct device *dev) | ||
174 | { | ||
175 | memset(dev, 0, sizeof(struct device)); | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | /* | 165 | /* |
180 | * Connector properties | 166 | * Connector properties |
181 | */ | 167 | */ |
@@ -380,11 +366,6 @@ static struct bin_attribute edid_attr = { | |||
380 | * properties (so far, connection status, dpms, mode list & edid) and | 366 | * properties (so far, connection status, dpms, mode list & edid) and |
381 | * generate a hotplug event so userspace knows there's a new connector | 367 | * generate a hotplug event so userspace knows there's a new connector |
382 | * available. | 368 | * available. |
383 | * | ||
384 | * Note: | ||
385 | * This routine should only be called *once* for each registered connector. | ||
386 | * A second call for an already registered connector will trigger the BUG_ON | ||
387 | * below. | ||
388 | */ | 369 | */ |
389 | int drm_sysfs_connector_add(struct drm_connector *connector) | 370 | int drm_sysfs_connector_add(struct drm_connector *connector) |
390 | { | 371 | { |
@@ -394,29 +375,25 @@ int drm_sysfs_connector_add(struct drm_connector *connector) | |||
394 | int i; | 375 | int i; |
395 | int ret; | 376 | int ret; |
396 | 377 | ||
397 | /* We shouldn't get called more than once for the same connector */ | 378 | if (connector->kdev) |
398 | BUG_ON(device_is_registered(&connector->kdev)); | 379 | return 0; |
399 | |||
400 | connector->kdev.parent = &dev->primary->kdev; | ||
401 | connector->kdev.class = drm_class; | ||
402 | connector->kdev.release = drm_sysfs_device_release; | ||
403 | 380 | ||
381 | connector->kdev = device_create(drm_class, dev->primary->kdev, | ||
382 | 0, connector, "card%d-%s", | ||
383 | dev->primary->index, drm_get_connector_name(connector)); | ||
404 | DRM_DEBUG("adding \"%s\" to sysfs\n", | 384 | DRM_DEBUG("adding \"%s\" to sysfs\n", |
405 | drm_get_connector_name(connector)); | 385 | drm_get_connector_name(connector)); |
406 | 386 | ||
407 | dev_set_name(&connector->kdev, "card%d-%s", | 387 | if (IS_ERR(connector->kdev)) { |
408 | dev->primary->index, drm_get_connector_name(connector)); | 388 | DRM_ERROR("failed to register connector device: %ld\n", PTR_ERR(connector->kdev)); |
409 | ret = device_register(&connector->kdev); | 389 | ret = PTR_ERR(connector->kdev); |
410 | |||
411 | if (ret) { | ||
412 | DRM_ERROR("failed to register connector device: %d\n", ret); | ||
413 | goto out; | 390 | goto out; |
414 | } | 391 | } |
415 | 392 | ||
416 | /* Standard attributes */ | 393 | /* Standard attributes */ |
417 | 394 | ||
418 | for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) { | 395 | for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) { |
419 | ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]); | 396 | ret = device_create_file(connector->kdev, &connector_attrs[attr_cnt]); |
420 | if (ret) | 397 | if (ret) |
421 | goto err_out_files; | 398 | goto err_out_files; |
422 | } | 399 | } |
@@ -433,7 +410,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) | |||
433 | case DRM_MODE_CONNECTOR_Component: | 410 | case DRM_MODE_CONNECTOR_Component: |
434 | case DRM_MODE_CONNECTOR_TV: | 411 | case DRM_MODE_CONNECTOR_TV: |
435 | for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) { | 412 | for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) { |
436 | ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]); | 413 | ret = device_create_file(connector->kdev, &connector_attrs_opt1[opt_cnt]); |
437 | if (ret) | 414 | if (ret) |
438 | goto err_out_files; | 415 | goto err_out_files; |
439 | } | 416 | } |
@@ -442,7 +419,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) | |||
442 | break; | 419 | break; |
443 | } | 420 | } |
444 | 421 | ||
445 | ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr); | 422 | ret = sysfs_create_bin_file(&connector->kdev->kobj, &edid_attr); |
446 | if (ret) | 423 | if (ret) |
447 | goto err_out_files; | 424 | goto err_out_files; |
448 | 425 | ||
@@ -453,10 +430,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector) | |||
453 | 430 | ||
454 | err_out_files: | 431 | err_out_files: |
455 | for (i = 0; i < opt_cnt; i++) | 432 | for (i = 0; i < opt_cnt; i++) |
456 | device_remove_file(&connector->kdev, &connector_attrs_opt1[i]); | 433 | device_remove_file(connector->kdev, &connector_attrs_opt1[i]); |
457 | for (i = 0; i < attr_cnt; i++) | 434 | for (i = 0; i < attr_cnt; i++) |
458 | device_remove_file(&connector->kdev, &connector_attrs[i]); | 435 | device_remove_file(connector->kdev, &connector_attrs[i]); |
459 | device_unregister(&connector->kdev); | 436 | device_unregister(connector->kdev); |
460 | 437 | ||
461 | out: | 438 | out: |
462 | return ret; | 439 | return ret; |
@@ -480,16 +457,16 @@ void drm_sysfs_connector_remove(struct drm_connector *connector) | |||
480 | { | 457 | { |
481 | int i; | 458 | int i; |
482 | 459 | ||
483 | if (!connector->kdev.parent) | 460 | if (!connector->kdev) |
484 | return; | 461 | return; |
485 | DRM_DEBUG("removing \"%s\" from sysfs\n", | 462 | DRM_DEBUG("removing \"%s\" from sysfs\n", |
486 | drm_get_connector_name(connector)); | 463 | drm_get_connector_name(connector)); |
487 | 464 | ||
488 | for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) | 465 | for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) |
489 | device_remove_file(&connector->kdev, &connector_attrs[i]); | 466 | device_remove_file(connector->kdev, &connector_attrs[i]); |
490 | sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr); | 467 | sysfs_remove_bin_file(&connector->kdev->kobj, &edid_attr); |
491 | device_unregister(&connector->kdev); | 468 | device_unregister(connector->kdev); |
492 | connector->kdev.parent = NULL; | 469 | connector->kdev = NULL; |
493 | } | 470 | } |
494 | EXPORT_SYMBOL(drm_sysfs_connector_remove); | 471 | EXPORT_SYMBOL(drm_sysfs_connector_remove); |
495 | 472 | ||
@@ -508,7 +485,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) | |||
508 | 485 | ||
509 | DRM_DEBUG("generating hotplug event\n"); | 486 | DRM_DEBUG("generating hotplug event\n"); |
510 | 487 | ||
511 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); | 488 | kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); |
512 | } | 489 | } |
513 | EXPORT_SYMBOL(drm_sysfs_hotplug_event); | 490 | EXPORT_SYMBOL(drm_sysfs_hotplug_event); |
514 | 491 | ||
@@ -523,15 +500,8 @@ EXPORT_SYMBOL(drm_sysfs_hotplug_event); | |||
523 | */ | 500 | */ |
524 | int drm_sysfs_device_add(struct drm_minor *minor) | 501 | int drm_sysfs_device_add(struct drm_minor *minor) |
525 | { | 502 | { |
526 | int err; | ||
527 | char *minor_str; | 503 | char *minor_str; |
528 | 504 | ||
529 | minor->kdev.parent = minor->dev->dev; | ||
530 | |||
531 | minor->kdev.class = drm_class; | ||
532 | minor->kdev.release = drm_sysfs_device_release; | ||
533 | minor->kdev.devt = minor->device; | ||
534 | minor->kdev.type = &drm_sysfs_device_minor; | ||
535 | if (minor->type == DRM_MINOR_CONTROL) | 505 | if (minor->type == DRM_MINOR_CONTROL) |
536 | minor_str = "controlD%d"; | 506 | minor_str = "controlD%d"; |
537 | else if (minor->type == DRM_MINOR_RENDER) | 507 | else if (minor->type == DRM_MINOR_RENDER) |
@@ -539,18 +509,14 @@ int drm_sysfs_device_add(struct drm_minor *minor) | |||
539 | else | 509 | else |
540 | minor_str = "card%d"; | 510 | minor_str = "card%d"; |
541 | 511 | ||
542 | dev_set_name(&minor->kdev, minor_str, minor->index); | 512 | minor->kdev = device_create(drm_class, minor->dev->dev, |
543 | 513 | MKDEV(DRM_MAJOR, minor->index), | |
544 | err = device_register(&minor->kdev); | 514 | minor, minor_str, minor->index); |
545 | if (err) { | 515 | if (IS_ERR(minor->kdev)) { |
546 | DRM_ERROR("device add failed: %d\n", err); | 516 | DRM_ERROR("device create failed %ld\n", PTR_ERR(minor->kdev)); |
547 | goto err_out; | 517 | return PTR_ERR(minor->kdev); |
548 | } | 518 | } |
549 | |||
550 | return 0; | 519 | return 0; |
551 | |||
552 | err_out: | ||
553 | return err; | ||
554 | } | 520 | } |
555 | 521 | ||
556 | /** | 522 | /** |
@@ -562,9 +528,9 @@ err_out: | |||
562 | */ | 528 | */ |
563 | void drm_sysfs_device_remove(struct drm_minor *minor) | 529 | void drm_sysfs_device_remove(struct drm_minor *minor) |
564 | { | 530 | { |
565 | if (minor->kdev.parent) | 531 | if (minor->kdev) |
566 | device_unregister(&minor->kdev); | 532 | device_destroy(drm_class, MKDEV(DRM_MAJOR, minor->index)); |
567 | minor->kdev.parent = NULL; | 533 | minor->kdev = NULL; |
568 | } | 534 | } |
569 | 535 | ||
570 | 536 | ||