From patchwork Tue Jun 21 09:31:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 70538 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp1919204qgy; Tue, 21 Jun 2016 02:31:58 -0700 (PDT) X-Received: by 10.107.19.169 with SMTP id 41mr32642078iot.11.1466501518085; Tue, 21 Jun 2016 02:31:58 -0700 (PDT) Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTP id b2si20090152pav.216.2016.06.21.02.31.57; Tue, 21 Jun 2016 02:31:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5C4196E617; Tue, 21 Jun 2016 09:31:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lb0-x231.google.com (mail-lb0-x231.google.com [IPv6:2a00:1450:4010:c04::231]) by gabe.freedesktop.org (Postfix) with ESMTPS id C5D386E0E9 for ; Tue, 21 Jun 2016 09:31:48 +0000 (UTC) Received: by mail-lb0-x231.google.com with SMTP id o4so6746731lbp.2 for ; Tue, 21 Jun 2016 02:31:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pK8zu9xnx8QsxZWdhJ3W2Qgc0Fb1YrqTRZVT4WjLUu8=; b=Y0oaVVfIiLqPQ5BglU4VZ/mglyCMig/DMfDyCdhnvPWpSh8pZ6DNilG7NerMT/3sHg B7MIuCkttLSOCIxFWfkl3IAflWF8dJ1nefwcBesJfHAVcl1a8HSHjpmTeGRnymUI5OBY vDJxgB1MggLl3R4qR3NJ+ItmhNRi8TOr7S9TA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pK8zu9xnx8QsxZWdhJ3W2Qgc0Fb1YrqTRZVT4WjLUu8=; b=ZHm0CzHb6K/ZC4KDSfDxelF0A9nULVZxdCqOO0IcxnVVsyXCFWd1n5W3q/qqGPnKZS 1dGNGXU+qI2O2IE/M926Tx7HU1mr0ovXNpHtbqZVk7eed7rJICoh0LEQYbgBBxtimLat JjYxuIGiRgZPBtzogL+xXQRa4SBfZu79GzqUJ6Akv/Dhntk+vjKdb188QTQhrJV+/UyS lC5P/0Hh1wyj2+b4RlFmm6qLcu2gsuhOzitufmHKOVr9NRWSwuwhjaQDSICrpHoYzFjL A17nvaFoX80c8xLEsKMWGICggu6WH5XtxFJ5rjE28frn42cjr/ZhQ0NMeLGFH7y1tE3O GwNQ== X-Gm-Message-State: ALyK8tLECD6HbJNfyxGINrJmJCk3fia86I1DyMxJ/k0+DdLZq6c6aqNxAVl4OAtRsxvf8Kt1 X-Received: by 10.194.216.106 with SMTP id op10mr20797696wjc.178.1466501506388; Tue, 21 Jun 2016 02:31:46 -0700 (PDT) Received: from lmenx321.st.com. ([80.12.59.145]) by smtp.gmail.com with ESMTPSA id ae10sm24103832wjc.13.2016.06.21.02.31.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 Jun 2016 02:31:45 -0700 (PDT) From: Benjamin Gaignard To: dri-devel@lists.freedesktop.org, vincent.abriou@st.com, fabien.dessenne@st.com, ville.syrjala@linux.intel.com, emil.l.velikov@gmail.com Subject: [PATCH v2 1/3] drm: Add callbacks for late registering Date: Tue, 21 Jun 2016 11:31:34 +0200 Message-Id: <1466501496-18852-2-git-send-email-benjamin.gaignard@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466501496-18852-1-git-send-email-benjamin.gaignard@linaro.org> References: <1466501496-18852-1-git-send-email-benjamin.gaignard@linaro.org> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Like what has been done for connectors add callbacks on encoder, crtc and plane to let driver do actions after drm device registration. Correspondingly, add callbacks called before unregister drm device. version 2: add drm_modeset_register_all() and drm_modeset_unregister_all() to centralize all calls Signed-off-by: Benjamin Gaignard --- drivers/gpu/drm/drm_crtc.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_drv.c | 4 +- include/drm/drm_crtc.h | 79 +++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e7c862b..b393feb 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -608,6 +608,31 @@ static unsigned int drm_num_crtcs(struct drm_device *dev) return num; } +static int drm_crtc_register_all(struct drm_device *dev) +{ + struct drm_crtc *crtc; + int ret; + + drm_for_each_crtc(crtc, dev) { + if (crtc->funcs->late_register) + ret = crtc->funcs->late_register(crtc); + if (ret) + return ret; + } + + return 0; +} + +static void drm_crtc_unregister_all(struct drm_device *dev) +{ + struct drm_crtc *crtc; + + drm_for_each_crtc(crtc, dev) { + if (crtc->funcs->early_unregister) + crtc->funcs->early_unregister(crtc); + } +} + /** * drm_crtc_init_with_planes - Initialise a new CRTC object with * specified primary and cursor planes. @@ -1102,6 +1127,31 @@ void drm_connector_unregister_all(struct drm_device *dev) } EXPORT_SYMBOL(drm_connector_unregister_all); +static int drm_encoder_register_all(struct drm_device *dev) +{ + struct drm_encoder *encoder; + int ret; + + drm_for_each_encoder(encoder, dev) { + if (encoder->funcs->late_register) + ret = encoder->funcs->late_register(encoder); + if (ret) + return ret; + } + + return 0; +} + +static void drm_encoder_unregister_all(struct drm_device *dev) +{ + struct drm_encoder *encoder; + + drm_for_each_encoder(encoder, dev) { + if (encoder->funcs->early_unregister) + encoder->funcs->early_unregister(encoder); + } +} + /** * drm_encoder_init - Init a preallocated encoder * @dev: drm device @@ -1290,6 +1340,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, } EXPORT_SYMBOL(drm_universal_plane_init); +static int drm_plane_register_all(struct drm_device *dev) +{ + struct drm_plane *plane; + int ret; + + drm_for_each_plane(plane, dev) { + if (plane->funcs->late_register) + ret = plane->funcs->late_register(plane); + if (ret) + return ret; + } + + return 0; +} + +static void drm_plane_unregister_all(struct drm_device *dev) +{ + struct drm_plane *plane; + + drm_for_each_plane(plane, dev) { + if (plane->funcs->early_unregister) + plane->funcs->early_unregister(plane); + } +} + /** * drm_plane_init - Initialize a legacy plane * @dev: DRM device @@ -1412,6 +1487,53 @@ void drm_plane_force_disable(struct drm_plane *plane) } EXPORT_SYMBOL(drm_plane_force_disable); +/** + * drm_modeset_register_all - do late registration + * @dev: drm device + * + * This function call late_register callback for all planes, + * crcts, encoders and connectors + * + * Returns: + * Zero on success, erro code on failure + */ +int drm_modeset_register_all(struct drm_device *dev) +{ + int ret; + + ret = drm_plane_register_all(dev); + if (ret) + return ret; + + ret = drm_crtc_register_all(dev); + if (ret) + return ret; + + ret = drm_encoder_register_all(dev); + if (ret) + return ret; + + ret = drm_connector_register_all(dev); + return ret; +} +EXPORT_SYMBOL(drm_modeset_register_all); + +/** + * drm_modeset_unregister_all - do early unregistration + * @dev: drm device + * + * This function call early_unregister callbakc for all planes, + * crtcs, encoders and connectors + */ +void drm_modeset_unregister_all(struct drm_device *dev) +{ + drm_plane_unregister_all(dev); + drm_crtc_unregister_all(dev); + drm_encoder_unregister_all(dev); + drm_connector_unregister_all(dev); +} +EXPORT_SYMBOL(drm_modeset_unregister_all); + static int drm_mode_create_standard_properties(struct drm_device *dev) { struct drm_property *prop; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index c7101c0..53eadca 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -688,7 +688,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) } if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_connector_register_all(dev); + drm_modeset_register_all(dev); ret = 0; goto out_unlock; @@ -721,7 +721,7 @@ void drm_dev_unregister(struct drm_device *dev) drm_lastclose(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_connector_unregister_all(dev); + drm_modeset_unregister_all(dev); if (dev->driver->unload) dev->driver->unload(dev); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c273497..9b681f6 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -704,6 +704,32 @@ struct drm_crtc_funcs { const struct drm_crtc_state *state, struct drm_property *property, uint64_t *val); + + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the crtc like debugfs interfaces. + * It is called late in the driver load sequence from drm_dev_register(). + * Everything added from this callback should be unregistered in + * the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_crtc *crtc); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the crtc from + * late_unregister(). It is called from drm_dev_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_crtc *crtc); }; /** @@ -1127,6 +1153,32 @@ struct drm_encoder_funcs { * hotplugged in DRM. */ void (*destroy)(struct drm_encoder *encoder); + + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the encoder like debugfs interfaces. + * It is called late in the driver load sequence from drm_dev_register(). + * Everything added from this callback should be unregistered in + * the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_encoder *encoder); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the encoder from + * late_unregister(). It is called from drm_dev_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_encoder *encoder); }; #define DRM_CONNECTOR_MAX_ENCODER 3 @@ -1570,6 +1622,31 @@ struct drm_plane_funcs { const struct drm_plane_state *state, struct drm_property *property, uint64_t *val); + /** + * @late_register: + * + * This optional hook can be used to register additional userspace + * interfaces attached to the plane like debugfs interfaces. + * It is called late in the driver load sequence from drm_dev_register(). + * Everything added from this callback should be unregistered in + * the early_unregister callback. + * + * Returns: + * + * 0 on success, or a negative error code on failure. + */ + int (*late_register)(struct drm_plane *plane); + + /** + * @early_unregister: + * + * This optional hook should be used to unregister the additional + * userspace interfaces attached to the plane from + * late_unregister(). It is called from drm_dev_unregister(), + * early in the driver unload sequence to disable userspace access + * before data structures are torndown. + */ + void (*early_unregister)(struct drm_plane *plane); }; enum drm_plane_type { @@ -2514,6 +2591,8 @@ static inline unsigned drm_connector_index(struct drm_connector *connector) /* helpers to {un}register all connectors from sysfs for device */ extern int drm_connector_register_all(struct drm_device *dev); extern void drm_connector_unregister_all(struct drm_device *dev); +extern int drm_modeset_register_all(struct drm_device *dev); +extern void drm_modeset_unregister_all(struct drm_device *dev); extern int drm_bridge_add(struct drm_bridge *bridge); extern void drm_bridge_remove(struct drm_bridge *bridge);