Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp587929pxb; Thu, 19 Aug 2021 06:46:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzhzBRsjyTjfAaKJhroy3HZv8XraHgswIVpCXUWukuYMno2cxxuDCDJCoKMtSs9v+6/qQZf X-Received: by 2002:a5e:c00a:: with SMTP id u10mr11464207iol.60.1629380792460; Thu, 19 Aug 2021 06:46:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629380792; cv=none; d=google.com; s=arc-20160816; b=iDv7iRiTL9s8QXmLZr08v5jcBIoRaBtbrn7WfLUGubF8HlTzjFqAUyagtjc3HNbVLG exwZ5I+6qWiCutOU+t/EO11TjlGNKKotlMVZhSaC1KVEnz3vC5tq2Ab0yGFUWr4iBWWc jpOEIEfhEKaKswk5N/sAjCPNF9g/I2RB7yM1R+48oP/+/RI7SQ7Bskk9a8C2xuxT35Eg AGpxRButx562mGi1v8mhHhIFav82b1auw3nyyzwTaFV3KjZCJeqVHlXgJbwUWNbG3E0Z 5Fv2t/lS0hFk0W6LjuY4IUFZGJDEo84WUQ4aNR3IMN6SkXkUHC30xc0lK8UXRuB8aRMp EkSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature:dkim-signature; bh=3StIrRnb5NNmIWozrc+5wA2UqlF1wVymMmWtJfFjZOI=; b=fuGW5GlGP6c0era0MwtjQFv/fhn6340Rp5SZWDel5uM7Cl+lhamGw8hT1aY3ZFxzDO KgyNHEhHoRx6zj6Db91HWiNYPKOjVJ+qYjIn6suWIcP346Vr2l0Z5oznVHL1N0B3dwzF Q3zZnXYlxnt5HJwBj26LE8nKEeDbYQCornQaClKcrIOJyHVinDgxKTIYIcUoacUEdH32 GcZ6yl9M/PtD6ZmqRadcUIa2tzSUOY5TgzAoqgBkHJMo2KwYBncp08G4f6Hmz3nA7GRH P6Gu1pyQtM8KIzSu86rdZ7MsFxCe233cHcV4oC2Eq0lfrreAxQkaWjg2MyICwVmY/mVo 3avg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm3 header.b=RQDlU8bP; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=mLVF6KWw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x5si2891854ior.24.2021.08.19.06.46.19; Thu, 19 Aug 2021 06:46:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm3 header.b=RQDlU8bP; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=mLVF6KWw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240126AbhHSNpi (ORCPT + 99 others); Thu, 19 Aug 2021 09:45:38 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:37315 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240152AbhHSNph (ORCPT ); Thu, 19 Aug 2021 09:45:37 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id E99202B005D0; Thu, 19 Aug 2021 09:44:59 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 19 Aug 2021 09:45:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=fm3; bh=3StIrRnb5NNmIWozrc+5wA2Uql F1wVymMmWtJfFjZOI=; b=RQDlU8bPpcsd2pLAexFk3l8OYwbrOcian+MnXv7yqD sa/M8KqeGrLWdDdwJl3KXtfCUwZx24jeTPIKW3POkyMzc21JlsZyxD2YDDLtgStR uV8a69DTbAMFRs/OYCLrx4K/g5JeWMOs8jegdeKEHskVfDLpJ+bt1w9INn2EKYC5 zkGzIa6vH3ppKkWdQz5KUV7KXGPRLkWdrEn78Lb0fsmG9gtJq2igXwzEjEXHNZcY HCMGPo4EiO0wVkEZtVK7L1u4YEwN1c0cjsREksougGDumENZh6qZsgAGrNmr95/+ NspctjHd1FKe8XaDplipKlOms1WiljWVA2C9aMzRXc9w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=3StIrRnb5NNmIWozr c+5wA2UqlF1wVymMmWtJfFjZOI=; b=mLVF6KWwd5+9H3b9+48E8qpJdlLS8hIvh zg8ydTGd764VwaCdn1Le1n/c1rwRcoPrca8koDV2A2fKqfDuAcofXzh6J94arTnh aVvUIHIz1HyQkziXOYu083+92eZ8S9G0mtRp6wN0B/Epu7Rs5J06UzSUqInEf01J rGYAZ/vEdlooEuNlUv6Cr38O4C8vCP9NW5lYHvQm+LqoB4AMKG7+cz7g7RkNp8+S yn03oW6is8TSftPkCpW3l4bBYD0M2NBu8TuyIReLPPfjd1B4TcD9Kxng6VmwN4IW D2HH928M+R8Ca9AIffZalNjNBuvTLHy2ovEIWisWnR1pjrU38wVxA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrleejgdeiiecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgggfestdekredtredttdenucfhrhhomhepofgrgihimhgvucft ihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtthgvrh hnpeejffehuddvvddvlefhgeelleffgfeijedvhefgieejtdeiueetjeetfeeukeejgeen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrgigih hmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 19 Aug 2021 09:44:56 -0400 (EDT) From: Maxime Ripard To: dri-devel@lists.freedesktop.org, Daniel Vetter , David Airlie , Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard Cc: linux-rpi-kernel@lists.infradead.org, Emma Anholt , bcm-kernel-feedback-list@broadcom.com, Nicolas Saenz Julienne , Dave Stevenson , Phil Elwell , Tim Gover , Dom Cobley , linux-kernel@vger.kernel.org Subject: [PATCH 1/2] drm/probe-helper: Create a HPD IRQ event helper for a single connector Date: Thu, 19 Aug 2021 15:44:53 +0200 Message-Id: <20210819134454.850031-1-maxime@cerno.tech> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The drm_helper_hpd_irq_event() function is iterating over all the connectors when an hotplug event is detected. During that iteration, it will call each connector detect function and figure out if its status changed. Finally, if any connector changed, it will notify the user-space and the clients that something changed on the DRM device. This is supposed to be used for drivers that don't have a hotplug interrupt for individual connectors. However, drivers that can use an interrupt for a single connector are left in the dust and can either reimplement the logic used during the iteration for each connector or use that helper and iterate over all connectors all the time. Since both are suboptimal, let's create a helper that will only perform the status detection on a single connector. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_probe_helper.c | 105 ++++++++++++++++++++--------- include/drm/drm_probe_helper.h | 1 + 2 files changed, 74 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 5606bca3caa8..7e3cbb4333ce 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -795,6 +795,77 @@ void drm_kms_helper_poll_fini(struct drm_device *dev) } EXPORT_SYMBOL(drm_kms_helper_poll_fini); +static bool +_drm_connector_helper_hpd_irq_event(struct drm_connector *connector, + bool notify) +{ + struct drm_device *dev = connector->dev; + enum drm_connector_status old_status; + u64 old_epoch_counter; + bool changed = false; + + /* Only handle HPD capable connectors. */ + drm_WARN_ON(dev, !(connector->polled & DRM_CONNECTOR_POLL_HPD)); + + drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex)); + + old_status = connector->status; + old_epoch_counter = connector->epoch_counter; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", + connector->base.id, + connector->name, + old_epoch_counter); + + connector->status = drm_helper_probe_detect(connector, NULL, + false); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + connector->base.id, + connector->name, + drm_get_connector_status_name(old_status), + drm_get_connector_status_name(connector->status)); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New epoch counter %llu\n", + connector->base.id, + connector->name, + connector->epoch_counter); + + /* + * Check if epoch counter had changed, meaning that we need + * to send a uevent. + */ + if (old_epoch_counter != connector->epoch_counter) + changed = true; + + if (changed && notify) { + drm_kms_helper_hotplug_event(dev); + DRM_DEBUG_KMS("Sent hotplug event\n"); + } + + return changed; +} + +/** + * drm_connector_helper_hpd_irq_event - hotplug processing + * @connector: drm_connector + * + * Drivers can use this helper function to run a detect cycle on a connector + * which has the DRM_CONNECTOR_POLL_HPD flag set in its &polled member. + * + * This helper function is useful for drivers which can track hotplug + * interrupts for a single connector. + * + * This function must be called with the mode setting locks held. + * + * Note that a connector can be both polled and probed from the hotplug + * handler, in case the hotplug interrupt is known to be unreliable. + */ +bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector) +{ + return _drm_connector_helper_hpd_irq_event(connector, true); +} +EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event); + /** * drm_helper_hpd_irq_event - hotplug processing * @dev: drm_device @@ -822,9 +893,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) { struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - enum drm_connector_status old_status; bool changed = false; - u64 old_epoch_counter; if (!dev->mode_config.poll_enabled) return false; @@ -832,37 +901,9 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) mutex_lock(&dev->mode_config.mutex); drm_connector_list_iter_begin(dev, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { - /* Only handle HPD capable connectors. */ - if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) - continue; - - old_status = connector->status; - - old_epoch_counter = connector->epoch_counter; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", connector->base.id, - connector->name, - old_epoch_counter); - - connector->status = drm_helper_probe_detect(connector, NULL, false); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", - connector->base.id, - connector->name, - drm_get_connector_status_name(old_status), - drm_get_connector_status_name(connector->status)); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New epoch counter %llu\n", - connector->base.id, - connector->name, - connector->epoch_counter); - - /* - * Check if epoch counter had changed, meaning that we need - * to send a uevent. - */ - if (old_epoch_counter != connector->epoch_counter) + if (_drm_connector_helper_hpd_irq_event(connector, + false)) changed = true; - } drm_connector_list_iter_end(&conn_iter); mutex_unlock(&dev->mode_config.mutex); diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h index 8d3ed2834d34..04c57564c397 100644 --- a/include/drm/drm_probe_helper.h +++ b/include/drm/drm_probe_helper.h @@ -18,6 +18,7 @@ int drm_helper_probe_detect(struct drm_connector *connector, void drm_kms_helper_poll_init(struct drm_device *dev); void drm_kms_helper_poll_fini(struct drm_device *dev); bool drm_helper_hpd_irq_event(struct drm_device *dev); +bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector); void drm_kms_helper_hotplug_event(struct drm_device *dev); void drm_kms_helper_poll_disable(struct drm_device *dev); -- 2.31.1