From nobody Tue Jun 30 09:23:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1A37C43217 for ; Thu, 20 Jan 2022 16:15:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376913AbiATQPE (ORCPT ); Thu, 20 Jan 2022 11:15:04 -0500 Received: from box.trvn.ru ([194.87.146.52]:40881 "EHLO box.trvn.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346641AbiATQPD (ORCPT ); Thu, 20 Jan 2022 11:15:03 -0500 Received: from authenticated-user (box.trvn.ru [194.87.146.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.trvn.ru (Postfix) with ESMTPSA id 4D5C240CAF; Thu, 20 Jan 2022 21:15:00 +0500 (+05) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=trvn.ru; s=mail; t=1642695300; bh=qRBTVa7l5ff9cDGlC0cX/AXh5ZL9DuXAiZdGpUFlRDY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EcTC13JvJaGcwHmO/Cwi99a6NtK7ub1sifv+M8uupubmAPN7sbxQQnnXVe014k5Uf FdjJ9yl9DZG2v4GilGKXGnybJLG55IQPH9iIIkl5GCnXEMeXK4pOLd7cUW9MLzpdoJ kCR9dGPIDlDzTO6EV5eJag5q9dyhhgL2S/I8bOTSboskUYwqwOaEfPaf3o3mgepylj UN5qMnr/UyiwXriimO/i8LTWFZ41iRn58PHNpTnctz5A1iLLmbvsie2H/iMgU62TAO ZGij6xiEqGE8qI2cKwY7wMf3Fcv+RG/xS6LbGZLCLfdAS1AMkJN1/SIIUUpNu5EewG 7L6E86pYCa8xA== From: Nikita Travkin To: thierry.reding@gmail.com, lee.jones@linaro.org Cc: u.kleine-koenig@pengutronix.de, robh+dt@kernel.org, sboyd@kernel.org, krzk@kernel.org, linus.walleij@linaro.org, masneyb@onstation.org, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, ~postmarketos/upstreaming@lists.sr.ht, Nikita Travkin Subject: [PATCH v3 1/3] dt-bindings: pwm: Fix node name pattern Date: Thu, 20 Jan 2022 21:14:40 +0500 Message-Id: <20220120161442.140800-2-nikita@trvn.ru> In-Reply-To: <20220120161442.140800-1-nikita@trvn.ru> References: <20220120161442.140800-1-nikita@trvn.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" It looks like it was intended to allow two types of node names with the binding: - With unit address, e.g. pwm@1f000000 - With a suffix, e.g. pwm-clk However the pattern regex only correctly matches the first variant, as well as some incorrect ones. Fix the regex to match only two patterns shown above. (Either unit address starting with @ and following with one or more hexademical digit or arbitrary suffix stating with - and at least one symbol long) Fixes: 89650a1e3b6f ("dt-bindings: pwm: Convert PWM bindings to json-schema= ") Signed-off-by: Nikita Travkin --- Documentation/devicetree/bindings/pwm/pwm.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pwm/pwm.yaml b/Documentation= /devicetree/bindings/pwm/pwm.yaml index 3c01f85029e5..4926fe65886f 100644 --- a/Documentation/devicetree/bindings/pwm/pwm.yaml +++ b/Documentation/devicetree/bindings/pwm/pwm.yaml @@ -13,7 +13,7 @@ select: false =20 properties: $nodename: - pattern: "^pwm(@.*|-[0-9a-f])*$" + pattern: "^pwm(@[0-9a-f]+|-.+)?$" =20 "#pwm-cells": description: --=20 2.30.2 From nobody Tue Jun 30 09:23:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E73FC433FE for ; Thu, 20 Jan 2022 16:15:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376943AbiATQPH (ORCPT ); Thu, 20 Jan 2022 11:15:07 -0500 Received: from box.trvn.ru ([194.87.146.52]:51099 "EHLO box.trvn.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347315AbiATQPD (ORCPT ); Thu, 20 Jan 2022 11:15:03 -0500 Received: from authenticated-user (box.trvn.ru [194.87.146.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.trvn.ru (Postfix) with ESMTPSA id E2A2641A41; Thu, 20 Jan 2022 21:15:00 +0500 (+05) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=trvn.ru; s=mail; t=1642695301; bh=piWRjtUT3wYbqNm+c4Mr8L9osMBZFVJjWmgW1ZCv6/A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eW8TzQFZBD6TxJqEvibx4E7TBS6PT3euaQYWC0qag2bYIcP1kYKdEwiYIdjogbPcF uiaAy8WXBkEHzedhhFQnFzn/Wl/eKYBvRCjDSkSvrNu+9HZzJobN1vZbI7VBUIV4fg PynclYuMw6H87AGuel3uTAnkQmrPtpMaiKCFTlDQEpZJG3EHiGZY5UhnrlrCp6k2RF 8+jINqcW1S6+HZMQjJHiphpSH+/ZnwTZWx69MGcNUT5g4jowtEOcBhFOrRcj+lfeqs LzMvxbXHnh0K16+uSzT4TUyj1OkRaJRvE4MqX07E0xfi8xqi9Gpw3a6rCvd/4Oi49q BKivwhBOzqwJg== From: Nikita Travkin To: thierry.reding@gmail.com, lee.jones@linaro.org Cc: u.kleine-koenig@pengutronix.de, robh+dt@kernel.org, sboyd@kernel.org, krzk@kernel.org, linus.walleij@linaro.org, masneyb@onstation.org, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, ~postmarketos/upstreaming@lists.sr.ht, Nikita Travkin Subject: [PATCH v3 2/3] dt-bindings: pwm: Document clk based PWM controller Date: Thu, 20 Jan 2022 21:14:41 +0500 Message-Id: <20220120161442.140800-3-nikita@trvn.ru> In-Reply-To: <20220120161442.140800-1-nikita@trvn.ru> References: <20220120161442.140800-1-nikita@trvn.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add YAML devicetree binding for clk based PWM controller Signed-off-by: Nikita Travkin -- Changes in v2: - fix the file name. --- .../devicetree/bindings/pwm/clk-pwm.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/clk-pwm.yaml diff --git a/Documentation/devicetree/bindings/pwm/clk-pwm.yaml b/Documenta= tion/devicetree/bindings/pwm/clk-pwm.yaml new file mode 100644 index 000000000000..4fb2c1baaad4 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/clk-pwm.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/clk-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Clock based PWM controller + +maintainers: + - Nikita Travkin + +description: | + Some systems have clocks that can be exposed to external devices. + (e.g. by muxing them to GPIO pins) + It's often possible to control duty-cycle of such clocks which makes them + suitable for generating PWM signal. + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + const: clk-pwm + + clocks: + description: Clock used to generate the signal. + maxItems: 1 + + "#pwm-cells": + const: 2 + +unevaluatedProperties: false + +required: + - clocks + +examples: + - | + pwm-flash { + compatible =3D "clk-pwm"; + #pwm-cells =3D <2>; + clocks =3D <&gcc 0>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <&pwm_clk_flash_default>; + }; --=20 2.30.2 From nobody Tue Jun 30 09:23:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FB55C433F5 for ; Thu, 20 Jan 2022 16:15:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376991AbiATQPT (ORCPT ); Thu, 20 Jan 2022 11:15:19 -0500 Received: from box.trvn.ru ([194.87.146.52]:50075 "EHLO box.trvn.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376908AbiATQPF (ORCPT ); Thu, 20 Jan 2022 11:15:05 -0500 Received: from authenticated-user (box.trvn.ru [194.87.146.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.trvn.ru (Postfix) with ESMTPSA id BAFD241A43; Thu, 20 Jan 2022 21:15:01 +0500 (+05) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=trvn.ru; s=mail; t=1642695302; bh=R0jpJBls5JmCwVCLpVXHSI9u3DEEXSFznMNecQ1yAeQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dr1dxvmkC6HCPiVCj4aPzEORcXkQGtiSX+Cb5/FNV/ETtkyk5HiR4e05H1x/7NCDv arTYTO5sA2UGv9CbNccDPDHmumCDFMynNSnzrlQcNzYmSUH0q5HXEkp1I/6IVYmWoF Ix2kIKexv/xHrsi1XaAIZk9gL134uft0Kv+yiPCOiyBnLV7q8acZUNKY/A1KpIt+Ys euNmd0SFH2YtTX/XlLhWOYQd5ispMJkO2BBvWR6vReWjx5eBefVlRXtnxpxwUoYiFK 08NBw0XSfme4x5rygnBiPqDRhMA47+G0f7AizYX8ljsRkdlyO1qZA6La+TWKr86zzW Qws06OrEMA3SA== From: Nikita Travkin To: thierry.reding@gmail.com, lee.jones@linaro.org Cc: u.kleine-koenig@pengutronix.de, robh+dt@kernel.org, sboyd@kernel.org, krzk@kernel.org, linus.walleij@linaro.org, masneyb@onstation.org, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, ~postmarketos/upstreaming@lists.sr.ht, Nikita Travkin Subject: [PATCH v3 3/3] pwm: Add clock based PWM output driver Date: Thu, 20 Jan 2022 21:14:42 +0500 Message-Id: <20220120161442.140800-4-nikita@trvn.ru> In-Reply-To: <20220120161442.140800-1-nikita@trvn.ru> References: <20220120161442.140800-1-nikita@trvn.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Some systems have clocks exposed to external devices. If the clock controller supports duty-cycle configuration, such clocks can be used as pwm outputs. In fact PWM and CLK subsystems are interfaced with in a similar way and an "opposite" driver already exists (clk-pwm). Add a driver that would enable pwm devices to be used via clk subsystem. Signed-off-by: Nikita Travkin -- Changes in v2: - Address Uwe's review comments: - Round set clk rate up - Add a description with limitations of the driver - Disable and unprepare clock before removing pwmchip Changes in v3: - Use 64bit version of div round up - Address Uwe's review comments: - Reword the limitations to avoid incorrect claims - Move the clk_enabled flag assignment - Drop unnecessary statements --- drivers/pwm/Kconfig | 10 +++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-clk.c | 139 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/pwm/pwm-clk.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 21e3b05a5153..daa2491a4054 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -140,6 +140,16 @@ config PWM_BRCMSTB To compile this driver as a module, choose M Here: the module will be called pwm-brcmstb.c. =20 +config PWM_CLK + tristate "Clock based PWM support" + depends on HAVE_CLK || COMPILE_TEST + help + Generic PWM framework driver for outputs that can be + muxed to clocks. + + To compile this driver as a module, choose M here: the module + will be called pwm-clk. + config PWM_CLPS711X tristate "CLPS711X PWM support" depends on ARCH_CLPS711X || COMPILE_TEST diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 708840b7fba8..4a860103c470 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PWM_BCM_KONA) +=3D pwm-bcm-kona.o obj-$(CONFIG_PWM_BCM2835) +=3D pwm-bcm2835.o obj-$(CONFIG_PWM_BERLIN) +=3D pwm-berlin.o obj-$(CONFIG_PWM_BRCMSTB) +=3D pwm-brcmstb.o +obj-$(CONFIG_PWM_CLK) +=3D pwm-clk.o obj-$(CONFIG_PWM_CLPS711X) +=3D pwm-clps711x.o obj-$(CONFIG_PWM_CRC) +=3D pwm-crc.o obj-$(CONFIG_PWM_CROS_EC) +=3D pwm-cros-ec.o diff --git a/drivers/pwm/pwm-clk.c b/drivers/pwm/pwm-clk.c new file mode 100644 index 000000000000..b3bfa12a0e73 --- /dev/null +++ b/drivers/pwm/pwm-clk.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Clock based PWM controller + * + * Copyright (c) 2021 Nikita Travkin + * + * This is an "adapter" driver that allows PWM consumers to use + * system clocks with duty cycle control as PWM outputs. + * + * Limitations: + * - Glitches are possible when new pwm state is applied. + * - Due to the fact that exact behavior depends on the underlying + * clock driver, various limitations are possible. + * - Period depends on the clock and, in general, not guaranteed. + * - Underlying clock may not be able to give 0% or 100% duty cycle + * (constant off or on), exact behavior will depend on the clock. + * - When the PWM is disabled, the clock will be disabled as well, + * line state will depend on the clock. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct pwm_clk_chip { + struct pwm_chip chip; + struct clk *clk; + bool clk_enabled; +}; + +#define to_pwm_clk_chip(_chip) container_of(_chip, struct pwm_clk_chip, ch= ip) + +static int pwm_clk_apply(struct pwm_chip *pwm_chip, struct pwm_device *pwm, + const struct pwm_state *state) +{ + struct pwm_clk_chip *chip =3D to_pwm_clk_chip(pwm_chip); + int ret; + u32 rate; + u64 period =3D state->period; + u64 duty_cycle =3D state->duty_cycle; + + if (!state->enabled) { + if (pwm->state.enabled) { + clk_disable(chip->clk); + chip->clk_enabled =3D false; + } + return 0; + } else if (!pwm->state.enabled) { + ret =3D clk_enable(chip->clk); + if (ret) + return ret; + chip->clk_enabled =3D true; + } + + rate =3D DIV64_U64_ROUND_UP(NSEC_PER_SEC, period); + ret =3D clk_set_rate(chip->clk, rate); + if (ret) + return ret; + + if (state->polarity =3D=3D PWM_POLARITY_INVERSED) + duty_cycle =3D period - duty_cycle; + + return clk_set_duty_cycle(chip->clk, duty_cycle, period); +} + +static const struct pwm_ops pwm_clk_ops =3D { + .apply =3D pwm_clk_apply, + .owner =3D THIS_MODULE, +}; + +static int pwm_clk_probe(struct platform_device *pdev) +{ + struct pwm_clk_chip *chip; + int ret; + + chip =3D devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->clk =3D devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(chip->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(chip->clk), + "Failed to get clock\n"); + + chip->chip.dev =3D &pdev->dev; + chip->chip.ops =3D &pwm_clk_ops; + chip->chip.npwm =3D 1; + + ret =3D clk_prepare(chip->clk); + if (ret < 0) + dev_err_probe(&pdev->dev, ret, "Failed to prepare clock\n"); + + ret =3D pwmchip_add(&chip->chip); + if (ret < 0) + dev_err_probe(&pdev->dev, ret, "Failed to add pwm chip\n"); + + platform_set_drvdata(pdev, chip); + return 0; +} + +static int pwm_clk_remove(struct platform_device *pdev) +{ + struct pwm_clk_chip *chip =3D platform_get_drvdata(pdev); + + pwmchip_remove(&chip->chip); + + if (chip->clk_enabled) + clk_disable(chip->clk); + + clk_unprepare(chip->clk); + + return 0; +} + +static const struct of_device_id pwm_clk_dt_ids[] =3D { + { .compatible =3D "clk-pwm", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, pwm_clk_dt_ids); + +static struct platform_driver pwm_clk_driver =3D { + .driver =3D { + .name =3D "pwm-clk", + .of_match_table =3D pwm_clk_dt_ids, + }, + .probe =3D pwm_clk_probe, + .remove =3D pwm_clk_remove, +}; +module_platform_driver(pwm_clk_driver); + +MODULE_ALIAS("platform:pwm-clk"); +MODULE_AUTHOR("Nikita Travkin "); +MODULE_DESCRIPTION("Clock based PWM driver"); +MODULE_LICENSE("GPL"); --=20 2.30.2