From nobody Mon Oct 6 11:53:25 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (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 2C2D52E03E6; Tue, 22 Jul 2025 10:13:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753179209; cv=none; b=jE5SZuMzfzhH22q0SHWYf7ftHz9n/P8t9/XjNxMwmnJy2xNkSN51l2pM6jGvRMRnobOteOtBWD0s1XwWC6tPRRqcV5UvvkM6slsxp1X2OABtYYlJuOXuZrtSKc7dOIlLiZzh0jYR69OYJz6KIvQQpXy/qAGBTygnn04eJGkKz3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753179209; c=relaxed/simple; bh=AXJhbda1yCJyeDidWix2YMh9O5FyfrGCeMY4fxZW2go=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OZc9PU5cey4ct7J4cqmX2wyLqjVZDFtQbuDel0nXxZE/UqCQIuOpPUODtK1I9dqEPlsKqg0uYUD9lnyE3ZupBhYtA2nwpZjLlnMjHYzGLc92cuJyzvE9KSlMEdRFQPs+B9VaCtNh3ePrzH0dU1jODWy3VMy9IcRt6iP+Wc0vMHk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Msqk8/yO; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Msqk8/yO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1753179205; bh=AXJhbda1yCJyeDidWix2YMh9O5FyfrGCeMY4fxZW2go=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Msqk8/yOWmrtdokJAtdoiCxSvigT4NRj0ZDbOHqr/O2fd1rdzlB6MUkUArPzR5ELs 2THO+/Jp0TFoXxTbnsD7AJAqtyaVXg3e9/lNy+2rDMxfpdh/YuwfgdRaKJE5CnOH9q 0qYdPKNYJSwQsjpHD1qeDs1zwbp22HunevRTV57XP8Ymg6vQaEFRLK3oZKWy+K/P9U 7E/4RjdcQOEPZOineUOS77lHCWrX7w7V1sjj0sEF2H15DykgoxKpGSTLkl7nJ9Dva3 ZpUbtsGMncZZCJMKXlNVACmZoGNiNia62FsVAvz3zdA3f0JCALitsMGMM3h00RffMb FNnTJT2SXDkhQ== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kholk11) by bali.collaboradmins.com (Postfix) with ESMTPSA id 4C9D417E1324; Tue, 22 Jul 2025 12:13:24 +0200 (CEST) From: AngeloGioacchino Del Regno To: sboyd@kernel.org Cc: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, arnd@arndb.de, gregkh@linuxfoundation.org, srini@kernel.org, vkoul@kernel.org, kishon@kernel.org, sre@kernel.org, krzysztof.kozlowski@linaro.org, u.kleine-koenig@baylibre.com, angelogioacchino.delregno@collabora.com, linux-arm-msm@vger.kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-pm@vger.kernel.org, kernel@collabora.com, wenst@chromium.org, casey.connolly@linaro.org Subject: [PATCH v2 1/7] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant Date: Tue, 22 Jul 2025 12:13:11 +0200 Message-ID: <20250722101317.76729-2-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250722101317.76729-1-angelogioacchino.delregno@collabora.com> References: <20250722101317.76729-1-angelogioacchino.delregno@collabora.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" Some devices connected over the SPMI bus may be big, in the sense that those may be a complex of devices managed by a single chip over the SPMI bus, reachable through a single SID. Add new functions aimed at managing sub-devices of a SPMI device spmi_subdevice_alloc_and_add() and a spmi_subdevice_put_and_remove() for adding a new subdevice and removing it respectively, and also add their devm_* variants. The need for such functions comes from the existance of those complex Power Management ICs (PMICs), which feature one or many sub-devices, in some cases with these being even addressable on the chip in form of SPMI register ranges. Examples of those devices can be found in both Qualcomm platforms with their PMICs having PON, RTC, SDAM, GPIO controller, and other sub-devices, and in newer MediaTek platforms showing similar HW features and a similar layout with those also having many subdevs. Also, instead of generally exporting symbols, export them with a new "SPMI" namespace: all users will have to import this namespace to make use of the newly introduced exports. Signed-off-by: AngeloGioacchino Del Regno --- drivers/spmi/spmi-devres.c | 23 +++++++++++ drivers/spmi/spmi.c | 83 ++++++++++++++++++++++++++++++++++++++ include/linux/spmi.h | 16 ++++++++ 3 files changed, 122 insertions(+) diff --git a/drivers/spmi/spmi-devres.c b/drivers/spmi/spmi-devres.c index 62c4b3f24d06..7e00e38be2ff 100644 --- a/drivers/spmi/spmi-devres.c +++ b/drivers/spmi/spmi-devres.c @@ -60,5 +60,28 @@ int devm_spmi_controller_add(struct device *parent, stru= ct spmi_controller *ctrl } EXPORT_SYMBOL_GPL(devm_spmi_controller_add); =20 +static void devm_spmi_subdevice_remove(void *res) +{ + spmi_subdevice_remove((struct spmi_subdevice *)res); +} + +struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *de= v, + struct spmi_device *sparent) +{ + struct spmi_subdevice *sub_sdev; + int ret; + + sub_sdev =3D spmi_subdevice_alloc_and_add(sparent); + if (IS_ERR(sub_sdev)) + return sub_sdev; + + ret =3D devm_add_action_or_reset(dev, devm_spmi_subdevice_remove, sub_sde= v); + if (ret) + return ERR_PTR(ret); + + return sub_sdev; +} +EXPORT_SYMBOL_NS_GPL(devm_spmi_subdevice_alloc_and_add, "SPMI"); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SPMI devres helpers"); diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 3cf8d9bd4566..62bb782b2bbc 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -19,6 +19,7 @@ =20 static bool is_registered; static DEFINE_IDA(ctrl_ida); +static DEFINE_IDA(spmi_subdevice_ida); =20 static void spmi_dev_release(struct device *dev) { @@ -31,6 +32,18 @@ static const struct device_type spmi_dev_type =3D { .release =3D spmi_dev_release, }; =20 +static void spmi_subdev_release(struct device *dev) +{ + struct spmi_device *sdev =3D to_spmi_device(dev); + struct spmi_subdevice *sub_sdev =3D container_of(sdev, struct spmi_subdev= ice, sdev); + + kfree(sub_sdev); +} + +static const struct device_type spmi_subdev_type =3D { + .release =3D spmi_subdev_release, +}; + static void spmi_ctrl_release(struct device *dev) { struct spmi_controller *ctrl =3D to_spmi_controller(dev); @@ -90,6 +103,19 @@ void spmi_device_remove(struct spmi_device *sdev) } EXPORT_SYMBOL_GPL(spmi_device_remove); =20 +/** + * spmi_subdevice_remove() - Remove an SPMI subdevice + * @sub_sdev: spmi_device to be removed + */ +void spmi_subdevice_remove(struct spmi_subdevice *sub_sdev) +{ + struct spmi_device *sdev =3D &sub_sdev->sdev; + + device_unregister(&sdev->dev); + ida_free(&spmi_subdevice_ida, sub_sdev->devid); +} +EXPORT_SYMBOL_NS_GPL(spmi_subdevice_remove, "SPMI"); + static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { @@ -431,6 +457,63 @@ struct spmi_device *spmi_device_alloc(struct spmi_cont= roller *ctrl) } EXPORT_SYMBOL_GPL(spmi_device_alloc); =20 +/** + * spmi_subdevice_alloc_and_add(): Allocate and add a new SPMI sub-device + * @sparent: SPMI parent device with previously registered SPMI controller + * + * Returns: + * Pointer to newly allocated SPMI sub-device for success or negative ERR_= PTR. + */ +struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sp= arent) +{ + struct spmi_subdevice *sub_sdev; + struct spmi_device *sdev; + int ret; + + if (!sparent) + return ERR_PTR(-EINVAL); + + sub_sdev =3D kzalloc(sizeof(*sub_sdev), GFP_KERNEL); + if (!sub_sdev) + return ERR_PTR(-ENOMEM); + + ret =3D ida_alloc(&spmi_subdevice_ida, GFP_KERNEL); + if (ret < 0) + goto err_ida_alloc; + + sdev =3D &sub_sdev->sdev; + sdev->ctrl =3D sparent->ctrl; + device_initialize(&sdev->dev); + sdev->dev.parent =3D &sparent->dev; + sdev->dev.bus =3D &spmi_bus_type; + sdev->dev.type =3D &spmi_subdev_type; + + sub_sdev->devid =3D ret; + sdev->usid =3D sparent->usid; + + ret =3D dev_set_name(&sdev->dev, "%d-%02x.%d.auto", + sdev->ctrl->nr, sdev->usid, sub_sdev->devid); + if (ret) + goto err_set_name; + + ret =3D device_add(&sdev->dev); + if (ret) { + dev_err(&sdev->dev, "Can't add %s, status %d\n", + dev_name(&sdev->dev), ret); + put_device(&sdev->dev); + return ERR_PTR(ret); + } + + return sub_sdev; + +err_set_name: + ida_free(&ctrl_ida, sub_sdev->devid); +err_ida_alloc: + kfree(sub_sdev); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_NS_GPL(spmi_subdevice_alloc_and_add, "SPMI"); + /** * spmi_controller_alloc() - Allocate a new SPMI controller * @parent: parent device diff --git a/include/linux/spmi.h b/include/linux/spmi.h index 28e8c8bd3944..7cea0a5b034b 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -69,6 +69,22 @@ int spmi_device_add(struct spmi_device *sdev); =20 void spmi_device_remove(struct spmi_device *sdev); =20 +/** + * struct spmi_subdevice - Basic representation of an SPMI sub-device + * @sdev: Sub-device representation of an SPMI device + * @devid: Platform Device ID of an SPMI sub-device + */ +struct spmi_subdevice { + struct spmi_device sdev; + unsigned int devid; +}; + +struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sp= arent); +void spmi_subdevice_remove(struct spmi_subdevice *sdev); + +struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *de= v, + struct spmi_device *sparent); + /** * struct spmi_controller - interface to the SPMI master controller * @dev: Driver model representation of the device. --=20 2.50.1