This code wraps the struct device so that the drm class callbacks can
differentiate between different types of drm sysfs devices. It fixes a
case where a struct drm_connecor is cast to a struct drm_minor in the
drm_sysfs[suspend|resume] code.
It also opens up for adding driver-specific device entries to the drm
sysfs class, where the struct device need not be embedded within a
struct drm_minor. A new include drm_sysfs.h is added so that drivers
don't need to include the full drmP.h to access this feature.
Signed-off-by: Thomas Hellstrom thellst...@vmware.com
---
drivers/gpu/drm/drm_sysfs.c | 134 --
include/drm/drmP.h |3 +-
include/drm/drm_crtc.h |3 +-
include/drm/drm_sysfs.h | 37
4 files changed, 130 insertions(+), 47 deletions(-)
create mode 100644 include/drm/drm_sysfs.h
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index adc1794..ba54b4c 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -16,11 +16,13 @@
#include linux/kdev_t.h
#include linux/err.h
+#include drm_sysfs.h
#include drm_core.h
#include drmP.h
-#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
-#define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
+#define to_drm_minor(d) container_of(d, struct drm_minor, dsdev)
+#define to_drm_connector(d) container_of(d, struct drm_connector, dsdev)
+#define to_dsdev(d) container_of(d, struct drm_sysfs_device, kdev)
/**
* drm_sysfs_suspend - DRM class suspend hook
@@ -32,13 +34,23 @@
*/
static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
{
- struct drm_minor *drm_minor = to_drm_minor(dev);
- struct drm_device *drm_dev = drm_minor-dev;
-
- if (drm_minor-type == DRM_MINOR_LEGACY
- !drm_core_check_feature(drm_dev, DRIVER_MODESET)
- drm_dev-driver-suspend)
- return drm_dev-driver-suspend(drm_dev, state);
+ struct drm_sysfs_device *dsdev = to_dsdev(dev);
+
+ BUG_ON(dsdev-type = DRM_DEVICE_TYPE_NUM);
+ switch (dsdev-type) {
+ case DRM_DEVICE_TYPE_MINOR:
+ {
+ struct drm_minor *drm_minor = to_drm_minor(dsdev);
+ struct drm_device *drm_dev = drm_minor-dev;
+
+ if (drm_minor-type == DRM_MINOR_LEGACY
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET)
+ drm_dev-driver-suspend)
+ return drm_dev-driver-suspend(drm_dev, state);
+ }
+ default:
+ break;
+ }
return 0;
}
@@ -52,16 +64,38 @@ static int drm_sysfs_suspend(struct device *dev,
pm_message_t state)
*/
static int drm_sysfs_resume(struct device *dev)
{
- struct drm_minor *drm_minor = to_drm_minor(dev);
- struct drm_device *drm_dev = drm_minor-dev;
+ struct drm_sysfs_device *dsdev = to_dsdev(dev);
+
+ BUG_ON(dsdev-type = DRM_DEVICE_TYPE_NUM);
+ switch (dsdev-type) {
+ case DRM_DEVICE_TYPE_MINOR:
+ {
+ struct drm_minor *drm_minor = to_drm_minor(dsdev);
+ struct drm_device *drm_dev = drm_minor-dev;
+
+ if (drm_minor-type == DRM_MINOR_LEGACY
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET)
+ drm_dev-driver-resume)
+ return drm_dev-driver-resume(drm_dev);
+ }
+ default:
+ break;
+ }
+ return 0;
+}
- if (drm_minor-type == DRM_MINOR_LEGACY
- !drm_core_check_feature(drm_dev, DRIVER_MODESET)
- drm_dev-driver-resume)
- return drm_dev-driver-resume(drm_dev);
+int drm_sysfs_device_register(struct drm_sysfs_device *dsdev)
+{
+ dsdev-kdev.class = drm_class;
+ return device_register(dsdev-kdev);
+}
+EXPORT_SYMBOL(drm_sysfs_device_register);
- return 0;
+void drm_sysfs_device_unregister(struct drm_sysfs_device *dsdev)
+{
+ device_unregister(dsdev-kdev);
}
+EXPORT_SYMBOL(drm_sysfs_device_unregister);
/* Display the version of drm_core. This doesn't work right in current design
*/
static ssize_t version_show(struct class *dev, char *buf)
@@ -150,7 +184,8 @@ static ssize_t status_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
- struct drm_connector *connector = to_drm_connector(device);
+ struct drm_sysfs_device *dsdev = to_dsdev(device);
+ struct drm_connector *connector = to_drm_connector(dsdev);
enum drm_connector_status status;
status = connector-funcs-detect(connector);
@@ -162,7 +197,8 @@ static ssize_t dpms_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
- struct drm_connector *connector = to_drm_connector(device);
+ struct drm_sysfs_device *dsdev = to_dsdev(device);
+ struct