Received: by 2002:ab2:620c:0:b0:1ef:ffd0:ce49 with SMTP id o12csp1184443lqt; Tue, 19 Mar 2024 15:53:19 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXqqmmLW3MXK5FUcjmGMgMtPVdbPcC9RbTAQsmNmyUJZXBladChB4Di8aiAJTEpNr1dwEaJTNa/OwDuTcCV0chY5QguQcgL71aZ+biglg== X-Google-Smtp-Source: AGHT+IG5CO//xfPuAekiFyW5CkW+xR4j8iPuy3yUzG/L0xDRgv0ywXgIxaGGwxYkcIsTK4pYKjws X-Received: by 2002:a25:ae83:0:b0:dc7:48d7:9ed8 with SMTP id b3-20020a25ae83000000b00dc748d79ed8mr15704188ybj.20.1710888799309; Tue, 19 Mar 2024 15:53:19 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710888799; cv=pass; d=google.com; s=arc-20160816; b=PvPMuNSBQPXp86KOPJWRHTOUVM9WfMwO6ocfizal/UWUOMAW4Ic33qEFqsgSZ5AdzH qoFcb1pMhViDXPLTMOgTwB48uM7p5XvWEOS/szYJd5rv1q5N07RYGhnXmfADHnK1Vm1+ rQH70r2VEGCKxzlu5dZtzCVthaL1M3L1pQbOwo+lgvvFnqKxf3MWcbJFu2WFBYRlbJAT +BerfgUNA89LqcVZCI9RrBYrSbTd2BHdbpgtO0cADOsSlxt99xo/u1uzHbGX4iyLgZiu LrVR+zotmG1Yd8Sss5M/mNky1HM+kNtA0UIqRM4EdDzuj/CCbIJqv6T3gquJ2bZRGDAJ zbBQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=gbbS0pBK3xdjrDUeEKHRjTqg7WQ0JcXZhe6RO8jCpjQ=; fh=QE5KDpQBDaw6TTdTDvqDjBOLgOLBm0Tl23jUjnXnKrk=; b=Ikd4/0CNij07ox1Yy0DlnJr3nTdfxe0qWvUSKEVZVUl0ETnewrzcAA4y1biwgob8/V 6Hx4NzQtB0FXgFVEHFbqsNzSrZWW0hZOlr1yD9HLby5u6580aeO4bgaWA7tvzag79Btm kKwxvK+TunqR6d0t0ZweW0aeB/AOR/syUEp4YdbzR3nGvgMfDBGrdtJe8e2ATXeXMNPm CkyEZVWIqAMGhjQO9HN7GBd23mJMwuBU5BTzajaBaihylUIw0DzBOxSeqhk7+fIG13ik 8HLXKm/wnR7iSAwdd4iGnpVncET+DHYIVwgNcA++ijWInreFDpL/eUq7j92t6va1gNak g5qQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=kwBXvRg9; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-108206-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-108206-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id ci25-20020a05622a261900b0042f2127fa75si10035325qtb.683.2024.03.19.15.53.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Mar 2024 15:53:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-108206-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=kwBXvRg9; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-kernel+bounces-108206-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-108206-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id E534E1C215B9 for ; Tue, 19 Mar 2024 22:53:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF704604D9; Tue, 19 Mar 2024 22:51:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="kwBXvRg9" Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08B3A6027F for ; Tue, 19 Mar 2024 22:51:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710888712; cv=none; b=APZgrVPLXVzM1BUUH32E3rkUZCOf5ik0wI0j/e4erPiF/B4CYoLUUmqsk9sGw514NTv0UwAJF0YZRoBr0LNDaxi3VtBo8tIzuUd5LujFrlUhLfW4ZhD6zkoWD0WICF7xrT05L4UuUThA6f01ul+H/IOu0EP5d4FMR4ZBMtb5oEc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710888712; c=relaxed/simple; bh=nJ8CbNkAG/BmaSRncKkZ/+7BTMXJDdSw1avUJoW2A2k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AD47iTeozIqvQZj2v4ApgA94ZBjYbUeOANWNHPbQIOAikIWXPZym6PRScKpF/QBp8CZH3etUTXsJkqPjOOoGfVa0Z7Sn2Xt4O0I7ceT0TyQpb2zPzrz+ff/hkfLJKK6/zvPI4SPp5XN8fH3e8y1vY+jm/eODipR6BQ6ghcrLzKE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=kwBXvRg9; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1710888709; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gbbS0pBK3xdjrDUeEKHRjTqg7WQ0JcXZhe6RO8jCpjQ=; b=kwBXvRg9NKjKqGA50mh+d3boJd+N+HIZP68cCjfxTvzmaNUJMceErO5bKdkk29dLnY/IMt DYrpwTWnw40UhmUn2dSaJbAHKyLA4cmbNRvopQivX6t9EJbR+lzSfesphph/zsUt116ahq PswVZM/XsSsFpeVtWAY/cSu70Q5fnPo= From: Sean Anderson To: Laurent Pinchart , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , dri-devel@lists.freedesktop.org Cc: Michal Simek , David Airlie , linux-kernel@vger.kernel.org, Daniel Vetter , linux-arm-kernel@lists.infradead.org, Sean Anderson Subject: [PATCH v2 6/8] drm: zynqmp_dp: Add locking Date: Tue, 19 Mar 2024 18:51:19 -0400 Message-Id: <20240319225122.3048400-7-sean.anderson@linux.dev> In-Reply-To: <20240319225122.3048400-1-sean.anderson@linux.dev> References: <20240319225122.3048400-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT Add some locking to prevent the IRQ/workers/bridge API calls from stepping on each other's toes. This lock protects: - Non-atomic registers configuring the link. That is, everything but the IRQ registers (since these are accessed in an atomic fashion), and the DP AUX registers (since these don't affect the link). We also access AUX while holding this lock, so it would be very tricky to support. - Link configuration. This is effectively everything in zynqmp_dp which isn't read-only after probe time. So from next_bridge onward. This lock is designed to protect configuration changes so we don't have to do anything tricky. Configuration should never be in the hot path, so I'm not worried about performance. Signed-off-by: Sean Anderson --- Changes in v2: - Split off the HPD IRQ work into another commit - Expand the commit message drivers/gpu/drm/xlnx/zynqmp_dp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index f3fcdbf662fa..a90ab5c0f5cf 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -279,6 +279,7 @@ struct zynqmp_dp_config { * @dpsub: Display subsystem * @iomem: device I/O memory for register access * @reset: reset controller + * @lock: Mutex protecting this struct and register access (but not AUX) * @irq: irq * @bridge: DRM bridge for the DP encoder * @next_bridge: The downstream bridge @@ -294,12 +295,17 @@ struct zynqmp_dp_config { * @link_config: common link configuration between IP core and sink device * @mode: current mode between IP core and sink device * @train_set: set of training data + * + * @lock covers the link configuration in this struct and the device's + * registers. It does not cover @aux. It is not strictly required for any of + * the members which are only modified at probe/remove time (e.g. @dev). */ struct zynqmp_dp { struct drm_dp_aux aux; struct drm_bridge bridge; struct delayed_work hpd_work; struct delayed_work hpd_irq_work; + struct mutex lock; struct drm_bridge *next_bridge; struct device *dev; @@ -1373,8 +1379,10 @@ zynqmp_dp_bridge_mode_valid(struct drm_bridge *bridge, } /* Check with link rate and lane count */ + mutex_lock(&dp->lock); rate = zynqmp_dp_max_rate(dp->link_config.max_rate, dp->link_config.max_lanes, dp->config.bpp); + mutex_unlock(&dp->lock); if (mode->clock > rate) { dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", mode->name); @@ -1401,6 +1409,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge, pm_runtime_get_sync(dp->dev); + mutex_lock(&dp->lock); zynqmp_dp_disp_enable(dp, old_bridge_state); /* @@ -1461,6 +1470,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge, zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, ZYNQMP_DP_SOFTWARE_RESET_ALL); zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); + mutex_unlock(&dp->lock); } static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, @@ -1468,6 +1478,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, { struct zynqmp_dp *dp = bridge_to_dp(bridge); + mutex_lock(&dp->lock); dp->enabled = false; cancel_delayed_work(&dp->hpd_work); zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); @@ -1478,6 +1489,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); zynqmp_dp_disp_disable(dp, old_bridge_state); + mutex_unlock(&dp->lock); pm_runtime_put_sync(dp->dev); } @@ -1520,6 +1532,8 @@ static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *brid u32 state, i; int ret; + mutex_lock(&dp->lock); + /* * This is from heuristic. It takes some delay (ex, 100 ~ 500 msec) to * get the HPD signal with some monitors. @@ -1547,11 +1561,13 @@ static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *brid dp->num_lanes); dp->status = connector_status_connected; + mutex_unlock(&dp->lock); return connector_status_connected; } disconnected: dp->status = connector_status_disconnected; + mutex_unlock(&dp->lock); return connector_status_disconnected; } @@ -1620,6 +1636,7 @@ static void zynqmp_dp_hpd_irq_work_func(struct work_struct *work) u8 status[DP_LINK_STATUS_SIZE + 2]; int err; + mutex_lock(&dp->lock); err = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, DP_LINK_STATUS_SIZE + 2); if (err < 0) { @@ -1632,6 +1649,7 @@ static void zynqmp_dp_hpd_irq_work_func(struct work_struct *work) zynqmp_dp_train_loop(dp); } } + mutex_unlock(&dp->lock); } static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) @@ -1683,6 +1701,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) dp->dev = &pdev->dev; dp->dpsub = dpsub; dp->status = connector_status_disconnected; + mutex_init(&dp->lock); INIT_DELAYED_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); INIT_DELAYED_WORK(&dp->hpd_irq_work, zynqmp_dp_hpd_irq_work_func); @@ -1793,4 +1812,5 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) zynqmp_dp_phy_exit(dp); zynqmp_dp_reset(dp, true); + mutex_destroy(&dp->lock); } -- 2.35.1.1320.gc452695387.dirty