forked from Minki/linux
drm: Don't race connector registration
I was under the misconception that the sysfs dev stuff can be fully set up, and then registered all in one step with device_add. That's true for properties and property groups, but not for parents and child devices. Those must be fully registered before you can register a child. Add a bit of tracking to make sure that asynchronous mst connector hotplugging gets this right. For consistency we rely upon the implicit barriers of the connector->mutex, which is taken anyway, to ensure that at least either the connector or device registration call will work out. Mildly tested since I can't reliably reproduce this on my mst box here. Reported-by: Dave Hansen <dave.hansen@intel.com> Cc: Dave Hansen <dave.hansen@intel.com> Acked-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1484237756-2720-1-git-send-email-daniel.vetter@ffwll.ch
This commit is contained in:
parent
4e5b54f127
commit
e6e7b48b29
@ -379,6 +379,9 @@ int drm_connector_register(struct drm_connector *connector)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!connector->dev->registered)
|
||||||
|
return 0;
|
||||||
|
|
||||||
mutex_lock(&connector->mutex);
|
mutex_lock(&connector->mutex);
|
||||||
if (connector->registered)
|
if (connector->registered)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
@ -745,6 +745,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_minors;
|
goto err_minors;
|
||||||
|
|
||||||
|
dev->registered = true;
|
||||||
|
|
||||||
if (dev->driver->load) {
|
if (dev->driver->load) {
|
||||||
ret = dev->driver->load(dev, flags);
|
ret = dev->driver->load(dev, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -785,6 +787,8 @@ void drm_dev_unregister(struct drm_device *dev)
|
|||||||
|
|
||||||
drm_lastclose(dev);
|
drm_lastclose(dev);
|
||||||
|
|
||||||
|
dev->registered = false;
|
||||||
|
|
||||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||||
drm_modeset_unregister_all(dev);
|
drm_modeset_unregister_all(dev);
|
||||||
|
|
||||||
|
@ -517,6 +517,7 @@ struct drm_device {
|
|||||||
struct drm_minor *control; /**< Control node */
|
struct drm_minor *control; /**< Control node */
|
||||||
struct drm_minor *primary; /**< Primary node */
|
struct drm_minor *primary; /**< Primary node */
|
||||||
struct drm_minor *render; /**< Render node */
|
struct drm_minor *render; /**< Render node */
|
||||||
|
bool registered;
|
||||||
|
|
||||||
/* currently active master for this device. Protected by master_mutex */
|
/* currently active master for this device. Protected by master_mutex */
|
||||||
struct drm_master *master;
|
struct drm_master *master;
|
||||||
|
Loading…
Reference in New Issue
Block a user