From patchwork Fri May 29 17:56:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 11579471 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7C30E912 for ; Fri, 29 May 2020 17:57:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 64CC62073B for ; Fri, 29 May 2020 17:57:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 64CC62073B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=tronnes.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C0C2B6E95B; Fri, 29 May 2020 17:57:14 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from asav22.altibox.net (asav22.altibox.net [109.247.116.9]) by gabe.freedesktop.org (Postfix) with ESMTPS id EB3F56E95A for ; Fri, 29 May 2020 17:57:05 +0000 (UTC) Received: from localhost.localdomain (unknown [81.166.168.211]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: noralf.tronnes@ebnett.no) by asav22.altibox.net (Postfix) with ESMTPSA id 2029F200B9; Fri, 29 May 2020 19:57:03 +0200 (CEST) From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org, balbi@kernel.org Subject: [PATCH v3 1/6] drm/client: Add drm_client_init_from_id() Date: Fri, 29 May 2020 19:56:38 +0200 Message-Id: <20200529175643.46094-2-noralf@tronnes.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200529175643.46094-1-noralf@tronnes.org> References: <20200529175643.46094-1-noralf@tronnes.org> MIME-Version: 1.0 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.3 cv=LvK8NEVc c=1 sm=1 tr=0 a=OYZzhG0JTxDrWp/F2OJbnw==:117 a=OYZzhG0JTxDrWp/F2OJbnw==:17 a=IkcTkHD0fZMA:10 a=M51BFTxLslgA:10 a=SJz97ENfAAAA:8 a=K4G_t0gYd1P4o9CfPpEA:9 a=QEXdDO2ut3YA:10 a=vFet0B0WnEQeilDPIY6i:22 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-usb@vger.kernel.org, sam@ravnborg.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" drm_client_init_from_id() provides a way for clients to add a client based on the minor. drm_client_register() is changed to return whether it was registered or not depending on the unplugged status of the DRM device. Its only caller drm_fbdev_generic_setup() runs inside probe() so it doesn't have to check. v2: - Move drm_client_modeset_set() to a separate patch with added functions. - Previous version had drm_client_init_from_id() call drm_client_register(). This put the client in a position where it could receive hotplugs during init in addition to akward error paths. Instead let drm_client_register() return status so clients can know if the DRM device is gone or not. v3: - Forgot to remove locking with the change in the previous version. No need for locking when drm_client_register() is not called. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_client.c | 44 +++++++++++++++++++++++++++++++++++- include/drm/drm_client.h | 4 +++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 8f3d08dc996d..b7a310fef7e2 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -112,6 +112,36 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, } EXPORT_SYMBOL(drm_client_init); +/** + * drm_client_init_from_id - Initialise a DRM client + * @minor_id: DRM minor id + * @client: DRM client + * @name: Client name + * @funcs: DRM client functions (optional) + * + * This function looks up the drm_device using the minor id and initializes the + * client using drm_client_init(). + * + * Returns: + * Zero on success or negative error code on failure. + */ +int drm_client_init_from_id(unsigned int minor_id, struct drm_client_dev *client, + const char *name, const struct drm_client_funcs *funcs) +{ + struct drm_minor *minor; + int ret; + + minor = drm_minor_acquire(minor_id); + if (IS_ERR(minor)) + return PTR_ERR(minor); + + ret = drm_client_init(minor->dev, client, name, funcs); + drm_minor_release(minor); + + return ret; +} +EXPORT_SYMBOL(drm_client_init_from_id); + /** * drm_client_register - Register client * @client: DRM client @@ -121,14 +151,26 @@ EXPORT_SYMBOL(drm_client_init); * drm_client_register() it is no longer permissible to call drm_client_release() * directly (outside the unregister callback), instead cleanup will happen * automatically on driver unload. + * + * Returns: + * True if the client has been registered, false if the DRM device has already + * been unregistered. */ -void drm_client_register(struct drm_client_dev *client) +bool drm_client_register(struct drm_client_dev *client) { struct drm_device *dev = client->dev; + int idx; + + if (!drm_dev_enter(client->dev, &idx)) + return false; mutex_lock(&dev->clientlist_mutex); list_add(&client->list, &dev->clientlist); mutex_unlock(&dev->clientlist_mutex); + + drm_dev_exit(idx); + + return true; } EXPORT_SYMBOL(drm_client_register); diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 9f5a36a8ef24..76704f48fc46 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -109,8 +109,10 @@ struct drm_client_dev { int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, const char *name, const struct drm_client_funcs *funcs); +int drm_client_init_from_id(unsigned int minor_id, struct drm_client_dev *client, + const char *name, const struct drm_client_funcs *funcs); void drm_client_release(struct drm_client_dev *client); -void drm_client_register(struct drm_client_dev *client); +bool drm_client_register(struct drm_client_dev *client); void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev);