From nobody Thu Apr 9 08:55:35 2026 Received: from mail.zeus03.de (zeus03.de [194.117.254.33]) (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 2DACA364E82 for ; Tue, 10 Mar 2026 07:56:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=194.117.254.33 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773129373; cv=none; b=SYAxD4woOkhiHmNqO1GR8xu967LHdcMIFlXKXhldHJ8//74cloGkF9jQ3enfB1lDbU05+Gr7B+JatnEtGOZUBi2VVD6EoUiY4zxUvMTAM8ubSIEPIDaS0tsNk266k/eF/Pj3vqsQUFFp6mw4sFm+Ksxxz5vXWiCzuaQzZRAgWxc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773129373; c=relaxed/simple; bh=QdAPQ/wgPjYWXA5UouD20DLZ3JnNeWjKMNF0ZnmgYT8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BSN22MF5ElfsW/29dSD68NcWcqoRhzh+FuK1GvXGVhaUH0MwfvFkyqn33FFFUl6RKawVODgq9UhMSMVsrWCLMm4ND/j2ouvXKy4y79RVbNw6fpCzg5Robp/jHhAPqzq4XX5lnYZmaJawRi6UrhS6t+3/d9JSUWD7Yawz0RGlWNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com; spf=pass smtp.mailfrom=sang-engineering.com; dkim=pass (2048-bit key) header.d=sang-engineering.com header.i=@sang-engineering.com header.b=WUxZQC63; arc=none smtp.client-ip=194.117.254.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=sang-engineering.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sang-engineering.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sang-engineering.com header.i=@sang-engineering.com header.b="WUxZQC63" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= sang-engineering.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=k1; bh=DrYbAeF/DBAGfsthsqCRbLaGggzDcpjeVSk1HFVUxu0=; b=WUxZQC 63ndJu3cy8ghzOVpHbL/TxVuLnSZDeMa3nmXddnpEcDPGzGWJvTDW5+YbDTI8OhG mvBJy3nfTXwUWt26h98bBW2G/974SxMnWVBQpeMkbkIB0QLwgGfqb/w6fG9+CkUY fNav8drcTE8XHbiIWGi5zj2+LkXzuYK8TVYlJDGl8vRmbfJxa913Qp0KBgtQGqZQ hQvEtlfXIWk/M9a8Z9jq2peeXsXro5pUdeTWUX4PWVTBLhTdE9csqC1+ZPYbC9gA XXIMCpogydoswZ8Ky5VXdjyuUkxGINAX5ZlGTCzPSUzxBBKQj7wsPdsv9FyI+big 24j9SMtKQ/rJ+WPQ== Received: (qmail 3112640 invoked from network); 10 Mar 2026 08:55:52 +0100 Received: by mail.zeus03.de with UTF8SMTPSA (TLS_AES_256_GCM_SHA384 encrypted, authenticated); 10 Mar 2026 08:55:52 +0100 X-UD-Smtp-Session: l3s3148p1@B5Yn2aZMtpAujntP From: Wolfram Sang To: linux-renesas-soc@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Wolfram Sang , Bjorn Andersson , Baolin Wang , Orson Zhai , Chunyan Zhang , Maxime Coquelin , Alexandre Torgue , Wilken Gottwalt , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , linux-remoteproc@vger.kernel.org, linux-omap@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v4 04/15] hwspinlock: add callback to fill private data of a hwspinlock Date: Tue, 10 Mar 2026 08:55:19 +0100 Message-ID: <20260310075539.11701-5-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260310075539.11701-1-wsa+renesas@sang-engineering.com> References: <20260310075539.11701-1-wsa+renesas@sang-engineering.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To hide internal core structures from providers, a callback is added to the ops which allows to set the 'priv' field of a hwspinlock. It is called when a hwspinlock device is registered and, thus, iterated over all locks. The register-functions are also extended to pass a data pointer to this callback, so it can do necessary calculations for the priv field of each hwspinlock. Providers are added only an empty placeholder and are converted separately because these changes need dedicated reviews. Signed-off-by: Wolfram Sang --- drivers/hwspinlock/hwspinlock_core.c | 19 +++++++++++++++---- drivers/hwspinlock/hwspinlock_internal.h | 19 +++++++++++-------- drivers/hwspinlock/omap_hwspinlock.c | 2 +- drivers/hwspinlock/qcom_hwspinlock.c | 2 +- drivers/hwspinlock/sprd_hwspinlock.c | 2 +- drivers/hwspinlock/stm32_hwspinlock.c | 2 +- drivers/hwspinlock/sun6i_hwspinlock.c | 2 +- include/linux/hwspinlock.h | 4 ++-- 8 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwsp= inlock_core.c index 2c9eceba7fe8..afe1e7ce2829 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -507,6 +507,7 @@ static struct hwspinlock *hwspin_lock_unregister_single= (unsigned int id) * @ops: hwspinlock handlers for this device * @base_id: id of the first hardware spinlock in this bank * @num_locks: number of hwspinlocks provided by this device + * @init_data: additional data passed on to the init_priv callback * * This function should be called from the underlying platform-specific * implementation, to register a new hwspinlock device instance. @@ -516,10 +517,11 @@ static struct hwspinlock *hwspin_lock_unregister_sing= le(unsigned int id) * Returns: %0 on success, or an appropriate error code on failure */ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *de= v, - const struct hwspinlock_ops *ops, int base_id, int num_locks) + const struct hwspinlock_ops *ops, int base_id, int num_locks, + void *init_data) { struct hwspinlock *hwlock; - int ret =3D 0, i; + int ret, i; =20 if (!bank || !ops || !dev || !num_locks || !ops->trylock || !ops->unlock) { @@ -538,6 +540,14 @@ int hwspin_lock_register(struct hwspinlock_device *ban= k, struct device *dev, spin_lock_init(&hwlock->lock); hwlock->bank =3D bank; =20 + if (ops->init_priv) { + hwlock->priv =3D ops->init_priv(i, init_data); + if (IS_ERR(hwlock->priv)) { + ret =3D PTR_ERR(hwlock->priv); + goto reg_failed; + } + } + ret =3D hwspin_lock_register_single(hwlock, base_id + i); if (ret) goto reg_failed; @@ -633,6 +643,7 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_unregister); * @ops: hwspinlock handlers for this device * @base_id: id of the first hardware spinlock in this bank * @num_locks: number of hwspinlocks provided by this device + * @init_data: additional data passed on to the init_priv callback * * This function should be called from the underlying platform-specific * implementation, to register a new hwspinlock device instance. @@ -644,7 +655,7 @@ EXPORT_SYMBOL_GPL(devm_hwspin_lock_unregister); int devm_hwspin_lock_register(struct device *dev, struct hwspinlock_device *bank, const struct hwspinlock_ops *ops, - int base_id, int num_locks) + int base_id, int num_locks, void *init_data) { struct hwspinlock_device **ptr; int ret; @@ -653,7 +664,7 @@ int devm_hwspin_lock_register(struct device *dev, if (!ptr) return -ENOMEM; =20 - ret =3D hwspin_lock_register(bank, dev, ops, base_id, num_locks); + ret =3D hwspin_lock_register(bank, dev, ops, base_id, num_locks, init_dat= a); if (!ret) { *ptr =3D bank; devres_add(dev, ptr); diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/= hwspinlock_internal.h index f298fc0ee5ad..3c835d96bf86 100644 --- a/drivers/hwspinlock/hwspinlock_internal.h +++ b/drivers/hwspinlock/hwspinlock_internal.h @@ -18,20 +18,23 @@ struct hwspinlock_device; /** * struct hwspinlock_ops - platform-specific hwspinlock handlers * - * @trylock: make a single attempt to take the lock. returns 0 on - * failure and true on success. may _not_ sleep. - * @unlock: release the lock. always succeed. may _not_ sleep. - * @bust: optional, platform-specific bust handler, called by hwspinlock - * core to bust a specific lock. - * @relax: optional, platform-specific relax handler, called by hwspinlo= ck - * core while spinning on a lock, between two successive - * invocations of @trylock. may _not_ sleep. + * @trylock: make a single attempt to take the lock. returns 0 on + * failure and true on success. may _not_ sleep. + * @unlock: release the lock. always succeed. may _not_ sleep. + * @bust: optional, platform-specific bust handler, called by hwspinlock + * core to bust a specific lock. + * @relax: optional, platform-specific relax handler, called by hwspinlock + * core while spinning on a lock, between two successive + * invocations of @trylock. may _not_ sleep. + * @init_priv: optional, callback used when registering the hwspinlock dev= ice. + * Its return value will be used to fill the per-lock 'priv' data. */ struct hwspinlock_ops { int (*trylock)(struct hwspinlock *lock); void (*unlock)(struct hwspinlock *lock); int (*bust)(struct hwspinlock *lock, unsigned int id); void (*relax)(struct hwspinlock *lock); + void *(*init_priv)(int local_id, void *init_data); }; =20 /** diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap= _hwspinlock.c index 5bf0061d3fd6..adff502bcbc4 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -120,7 +120,7 @@ static int omap_hwspinlock_probe(struct platform_device= *pdev) bank->lock[i].priv =3D io_base + LOCK_BASE_OFFSET + sizeof(u32) * i; =20 return devm_hwspin_lock_register(&pdev->dev, bank, &omap_hwspinlock_ops, - base_id, num_locks); + base_id, num_locks, NULL); } =20 static const struct of_device_id omap_hwspinlock_of_match[] =3D { diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom= _hwspinlock.c index 7ff89c3e8c6b..7960a4972eab 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -236,7 +236,7 @@ static int qcom_hwspinlock_probe(struct platform_device= *pdev) } =20 return devm_hwspin_lock_register(&pdev->dev, bank, &qcom_hwspinlock_ops, - 0, QCOM_MUTEX_NUM_LOCKS); + 0, QCOM_MUTEX_NUM_LOCKS, NULL); } =20 static struct platform_driver qcom_hwspinlock_driver =3D { diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd= _hwspinlock.c index 0d08efbdfb07..0b91bdd4303d 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -132,7 +132,7 @@ static int sprd_hwspinlock_probe(struct platform_device= *pdev) =20 return devm_hwspin_lock_register(&pdev->dev, &sprd_hwlock->bank, &sprd_hwspinlock_ops, 0, - SPRD_HWLOCKS_NUM); + SPRD_HWLOCKS_NUM, NULL); } =20 static const struct of_device_id sprd_hwspinlock_of_match[] =3D { diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm= 32_hwspinlock.c index 1d75dc03f4ad..51e8e533ac31 100644 --- a/drivers/hwspinlock/stm32_hwspinlock.c +++ b/drivers/hwspinlock/stm32_hwspinlock.c @@ -110,7 +110,7 @@ static int stm32_hwspinlock_probe(struct platform_devic= e *pdev) hw->bank.lock[i].priv =3D io_base + i * sizeof(u32); =20 ret =3D devm_hwspin_lock_register(dev, &hw->bank, &stm32_hwspinlock_ops, - 0, STM32_MUTEX_NUM_LOCKS); + 0, STM32_MUTEX_NUM_LOCKS, NULL); =20 if (ret) dev_err(dev, "Failed to register hwspinlock\n"); diff --git a/drivers/hwspinlock/sun6i_hwspinlock.c b/drivers/hwspinlock/sun= 6i_hwspinlock.c index 8ff81cb5880a..a0c76bba3f05 100644 --- a/drivers/hwspinlock/sun6i_hwspinlock.c +++ b/drivers/hwspinlock/sun6i_hwspinlock.c @@ -180,7 +180,7 @@ static int sun6i_hwspinlock_probe(struct platform_devic= e *pdev) platform_set_drvdata(pdev, priv); =20 return devm_hwspin_lock_register(&pdev->dev, priv->bank, &sun6i_hwspinloc= k_ops, - SPINLOCK_BASE_ID, priv->nlocks); + SPINLOCK_BASE_ID, priv->nlocks, NULL); =20 bank_fail: clk_disable_unprepare(priv->ahb_clk); diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index dffa1dff7289..094a6d0d39d6 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -30,7 +30,7 @@ struct hwspinlock_ops; void *hwspin_lock_get_priv(struct hwspinlock *hwlock); struct device *hwspin_lock_get_dev(struct hwspinlock *hwlock); int hwspin_lock_register(struct hwspinlock_device *bank, struct device *de= v, - const struct hwspinlock_ops *ops, int base_id, int num_locks); + const struct hwspinlock_ops *ops, int base_id, int num_locks, void *init= _data); int hwspin_lock_unregister(struct hwspinlock_device *bank); struct hwspinlock *hwspin_lock_request_specific(unsigned int id); int hwspin_lock_free(struct hwspinlock *hwlock); @@ -49,7 +49,7 @@ int devm_hwspin_lock_unregister(struct device *dev, int devm_hwspin_lock_register(struct device *dev, struct hwspinlock_device *bank, const struct hwspinlock_ops *ops, - int base_id, int num_locks); + int base_id, int num_locks, void *init_data); =20 #else /* !CONFIG_HWSPINLOCK */ =20 --=20 2.47.3