Commit Graph

35 Commits

Author SHA1 Message Date
Uwe Kleine-König
790a8bae62 pwm: rockchip: Propagate errors in .get_state() to the caller
.get_state() can return an error indication. Make use of it to propagate
failing hardware accesses.

Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20221130152148.2769768-10-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2022-12-06 12:46:28 +01:00
Uwe Kleine-König
6c452cff79 pwm: Make .get_state() callback return an error code
.get_state() might fail in some cases. To make it possible that a driver
signals such a failure change the prototype of .get_state() to return an
error code.

This patch was created using coccinelle and the following semantic patch:

@p1@
identifier getstatefunc;
identifier driver;
@@
 struct pwm_ops driver = {
        ...,
        .get_state = getstatefunc
        ,...
 };

@p2@
identifier p1.getstatefunc;
identifier chip, pwm, state;
@@
-void
+int
 getstatefunc(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state)
 {
   ...
-  return;
+  return 0;
   ...
 }

plus the actual change of the prototype in include/linux/pwm.h (plus some
manual fixing of indentions and empty lines).

So for now all drivers return success unconditionally. They are adapted
in the following patches to make the changes easier reviewable.

Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Acked-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20221130152148.2769768-2-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2022-12-06 12:46:22 +01:00
zhaoxiao
4b8857c3ca pwm: rockchip: Convert to use dev_err_probe()
It's fine to call dev_err_probe() in ->probe() when error code is known.
Convert the driver to use dev_err_probe().

Signed-off-by: zhaoxiao <zhaoxiao@uniontech.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2022-09-28 14:01:19 +02:00
Uwe Kleine-König
84ea61f65d pwm: rockchip: Unprepare clocks only after the PWM was unregistered
The driver is supposed to stay functional until pwmchip_remove()
returns. So disable clocks only after that.

pwmchip_remove() always returns 0, so the return code can be ignored
which keeps rockchip_pwm_remove() a bit simpler and allows to eventually
make pwmchip_remove() return void.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-09-02 21:38:38 +02:00
Uwe Kleine-König
9d768cd7fd pwm: rockchip: Don't modify HW state in .remove() callback
A consumer is expected to disable a PWM before calling pwm_put(). And if
they didn't there is hopefully a good reason (or the consumer needs
fixing). Also if disabling an enabled PWM was the right thing to do,
this should better be done in the framework instead of in each low level
driver.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-09-02 21:38:37 +02:00
Uwe Kleine-König
e9fdf122cf pwm: Simplify all drivers with explicit of_pwm_n_cells = 3
With the previous commit there is no need for the lowlevel driver any
more to specify it it uses two or three cells. So simplify accordingly.

The only non-trival change affects the pwm-rockchip driver: It used to only
support three cells if the hardware supports polarity. Now the default
number depends on the device tree which has to match hardware anyhow
(and if it doesn't the error is just a bit delayed as a PWM handle with
an inverted setting is catched when pwm_apply_state() is called).

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-05-25 18:19:15 +02:00
Uwe Kleine-König
f9a8ee8c8b pwm: Always allocate PWM chip base ID dynamically
Since commit 5e5da1e9fb ("pwm: ab8500: Explicitly allocate pwm chip
base dynamically") all drivers use dynamic ID allocation explicitly. New
drivers are supposed to do the same, so remove support for driver
specified base IDs and drop all assignments in the low-level drivers.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-03-22 11:53:00 +01:00
Simon South
11be938ae0 pwm: rockchip: Enable clock before calling clk_get_rate()
The documentation for clk_get_rate() in include/linux/clk.h states the
function's result is valid only for a clock source that has been
enabled. However, the Rockchip PWM driver uses this function in two places
to query the rate of a clock without first ensuring it is enabled.

Fix this by modifying rockchip_pwm_get_state() and rockchip_pwm_apply() so
they enable a device's PWM clock before querying its rate (in the latter
case, the querying is actually done in rockchip_pwm_config()) and disable
the clock again before returning.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Simon South <simon@simonsouth.net>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-01-20 18:13:32 +01:00
Simon South
d21ba5d621 pwm: rockchip: Eliminate potential race condition when probing
Commit 48cf973cae ("pwm: rockchip: Avoid glitches on already running
PWMs") introduced a potential race condition in rockchip_pwm_probe(): A
consumer could enable an inactive PWM, or disable a running one, between
rockchip_pwm_probe() registering the device via pwmchip_add() and checking
whether it is enabled (to determine whether it was started by a
bootloader). This could result in a device's PWM clock being either enabled
once more than necessary, potentially causing it to continue running when
no longer needed, or disabled once more than necessary, producing a warning
from the kernel.

Eliminate these possibilities by modifying rockchip_pwm_probe() so it
checks whether a device is enabled before registering it rather than after.

Fixes: 48cf973cae ("pwm: rockchip: Avoid glitches on already running PWMs")
Reported-by: Trent Piepho <tpiepho@gmail.com>
Signed-off-by: Simon South <simon@simonsouth.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-01-20 18:13:15 +01:00
Simon South
c9f809d0db pwm: rockchip: Replace "bus clk" with "PWM clk"
Clarify the Rockchip PWM driver's error messages by referring to the clock
that operates a PWM device as the "PWM" clock, matching its name in the
device tree, rather than the "bus" clock (which is especially misleading in
the case of devices that also use a separate clock for bus access).

Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Simon South <simon@simonsouth.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-01-20 18:12:59 +01:00
Simon South
d5d8d67586 pwm: rockchip: rockchip_pwm_probe(): Remove superfluous clk_unprepare()
If rockchip_pwm_probe() fails to register a PWM device it calls
clk_unprepare() for the device's PWM clock, without having first disabled
the clock and before jumping to an error handler that also unprepares
it. This is likely to produce warnings from the kernel about the clock
being unprepared when it is still enabled, and then being unprepared when
it has already been unprepared.

Prevent these warnings by removing this unnecessary call to
clk_unprepare().

Fixes: 48cf973cae ("pwm: rockchip: Avoid glitches on already running PWMs")
Signed-off-by: Simon South <simon@simonsouth.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-01-20 18:12:46 +01:00
Simon South
d9b657a5cd pwm: rockchip: Enable APB clock during register access while probing
Commit 457f74abbe ("pwm: rockchip: Keep enabled PWMs running while
probing") modified rockchip_pwm_probe() to access a PWM device's registers
directly to check whether or not the device is enabled, but did not also
change the function so it first enables the device's APB clock to be
certain the device can respond. This risks hanging the kernel on systems
with PWM devices that use more than a single clock.

Avoid this by enabling the device's APB clock before accessing its
registers (and disabling the clock when register access is complete).

Fixes: 457f74abbe ("pwm: rockchip: Keep enabled PWMs running while probing")
Reported-by: Thierry Reding <thierry.reding@gmail.com>
Suggested-by: Trent Piepho <tpiepho@gmail.com>
Signed-off-by: Simon South <simon@simonsouth.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2021-01-20 18:12:31 +01:00
Yangtao Li
5119ee9eff pwm: rockchip: Convert to devm_platform_ioremap_resource()
Use devm_platform_ioremap_resource() to simplify code.

Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-12-17 14:18:42 +01:00
Krzysztof Kozlowski
836719f894 pwm: rockchip: Simplify with dev_err_probe()
Common pattern of handling deferred probe can be simplified with
dev_err_probe().  Less code and also it prints the error value.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-09-24 09:18:10 +02:00
Simon South
457f74abbe pwm: rockchip: Keep enabled PWMs running while probing
Following commit cfc4c189bc ("pwm: Read initial hardware state at
request time") the Rockchip PWM driver can no longer assume a device's
pwm_state structure has been populated after a call to pwmchip_add().
Consequently, the test in rockchip_pwm_probe() intended to prevent the
driver from stopping PWM devices already enabled by the bootloader no
longer functions reliably and this can lead to the kernel hanging
during startup, particularly on devices like the Pinebook Pro that use
a PWM-controlled backlight for their display.

Avoid this by querying the device directly at probe time to determine
whether or not it is enabled.

Fixes: cfc4c189bc ("pwm: Read initial hardware state at request time")
Signed-off-by: Simon South <simon@simonsouth.net>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-09-24 09:18:08 +02:00
Rasmus Villemoes
cad0f29606 pwm: rockchip: Simplify rockchip_pwm_get_state()
The way state->enabled is computed is rather convoluted and hard to
read - both branches of the if() actually do the exact same thing. So
remove the if(), and further simplify "<boolean condition> ? true :
false" to "<boolean condition>".

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2020-06-02 15:50:52 +02:00
Uwe Kleine-König
71523d1812 pwm: Ensure pwm_apply_state() doesn't modify the state argument
It is surprising for a PWM consumer when the variable holding the
requested state is modified by pwm_apply_state(). Consider for example a
driver doing:

        #define PERIOD 5000000
        #define DUTY_LITTLE 10
        ...
        struct pwm_state state = {
                .period = PERIOD,
                .duty_cycle = DUTY_LITTLE,
                .polarity = PWM_POLARITY_NORMAL,
                .enabled = true,
        };

        pwm_apply_state(mypwm, &state);
        ...
        state.duty_cycle = PERIOD / 2;
        pwm_apply_state(mypwm, &state);

For sure the second call to pwm_apply_state() should still have
state.period = PERIOD and not something the hardware driver chose for a
reason that doesn't necessarily apply to the second call.

So declare the state argument as a pointer to a const type and adapt all
drivers' .apply callbacks.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2019-09-21 03:25:10 +02:00
Uwe Kleine-König
797a5ebc26 pwm: rockchip: Don't update the state for the caller of pwm_apply_state()
The pwm-rockchip driver is one of only three PWM drivers which updates
the state for the caller of pwm_apply_state(). This might have
surprising results if the caller reuses the values expecting them to
still represent the same state.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2019-09-21 01:48:55 +02:00
Uwe Kleine-König
ba73deb16f pwm: rockchip: Set polarity unconditionally in .get_state()
Don't rely on *state being zero initialized and PWM_POLARITY_NORMAL
being zero. So always assign .polarity.

Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2019-09-21 01:48:54 +02:00
Thomas Gleixner
d2912cb15b treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500
Based on 2 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 as
  published by the free software foundation

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 as
  published by the free software foundation #

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 4122 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Enrico Weigelt <info@metux.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190604081206.933168790@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-19 17:09:55 +02:00
David Wu
3f9a363133 pwm: rockchip: Add rk3328 support
The rk3328 SoC supports atomic update, we could lock the configuration
of period and duty at first, after unlock is configured, the period and
duty are effective at the same time.

If the polarity, period and duty need to be configured together,
the way for atomic update is "configure lock and old polarity" ->
"configure period and duty" -> "configure unlock and new polarity".

Signed-off-by: David Wu <david.wu@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:44:34 +02:00
David Wu
831b279050 pwm: rockchip: Use same PWM ops for each IP
Just use the same PWM ops for each IP, and get rid of the ops in struct
rockchip_pwm_data, but still define the three different instances of the
struct to use common interface for each IP.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:42:30 +02:00
David Wu
bc834d7b07 pwm: rockchip: Move the configuration of polarity
It is usually possible to configure the polarity, cycle and duty all at
once, so that the polarity and cycle and duty are applied atomically.
Move it from rockchip_pwm_set_enable() into rockchip_pwm_config(), as
well as prepare for the next atomic update commit.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:40:05 +02:00
David Wu
ed054693d7 pwm: rockchip: Use pwm_apply() instead of pwm_enable()
Drop the custom hook of pwm_enable() and implement pwm_apply_v1() and
pwm_apply_v2() instead.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:36:56 +02:00
David Wu
f90df9cda6 pwm: rockchip: Remove the judge from return value of pwm_config()
It seems the rockchip_pwm_config() always returns the result 0, so
remove the judge.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:33:07 +02:00
David Wu
27922ff598 pwm: rockchip: Add APB and function both clocks support
New PWM module provides two individual clocks for APB clock and function
clock.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-08-18 17:31:56 +02:00
David Wu
a900152b5c pwm: rockchip: State of PWM clock should synchronize with PWM enabled state
If the PWM was not enabled at U-Boot loader, PWM could not work for
clock always disabled at PWM driver. The PWM clock is enabled at
beginning of pwm_apply(), but disabled at end of pwm_apply().

If the PWM was enabled at U-Boot loader, PWM clock is always enabled
unless closed by ATF. The pwm-backlight might turn off the power at
early suspend, should disable PWM clock for saving power consume.

It is important to provide opportunity to enable/disable clock at PWM
driver, the PWM consumer should ensure correct order to call PWM enable
and disable, and PWM driver ensure state of PWM clock synchronized with
PWM enabled state.

Fixes: 2bf1c98aa5 ("pwm: rockchip: Add support for atomic update")
Cc: stable@vger.kernel.org
Signed-off-by: David Wu <david.wu@rock-chips.com>
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2017-04-06 15:08:52 +02:00
Boris Brezillon
2bf1c98aa5 pwm: rockchip: Add support for atomic update
Implement the ->apply() function to add support for atomic update.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11 12:49:28 +02:00
Boris Brezillon
48cf973cae pwm: rockchip: Avoid glitches on already running PWMs
The current logic will disable the PWM clk even if the PWM was left
enabled by the bootloader (because it's controlling a critical device
like a regulator for example).
Keep the PWM clk enabled if the PWM is enabled to avoid any glitches.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11 12:49:27 +02:00
Boris Brezillon
1ebb74cf35 pwm: rockchip: Add support for hardware readout
Implement the ->get_state() function to expose initial state.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11 12:49:27 +02:00
Boris Brezillon
12f9ce4a51 pwm: rockchip: Fix period and duty cycle approximation
The current implementation always round down the duty and period values,
while it would be better to round them to the closest integer.

These changes are needed in preparation of atomic update support to
prevent a period/duty cycle drift when executing several times the
'pwm_get_state() / modify / pwm_apply_state()' sequence.

Say you have an expected period of 3.333 us and a clk rate of
112.666667 MHz -- the clock frequency doesn't divide evenly, so the
period (stashed in nanoseconds) shrinks when we convert to the register
value and back, as follows:

  pwm_apply_state(): register = period * 112666667 / 1000000000;
  pwm_get_state(): period = register * 1000000000 / 112666667;

or in other words:

  period = period * 112666667 / 1000000000 * 1000000000 / 112666667;

which yields a sequence like:

  3333 -> 3328
  3328 -> 3319
  3319 -> 3310
  3310 -> 3301
  3301 -> 3292
  3292 -> ... (etc) ...

With this patch, we'd see instead:

  period = div_round_closest(period * 112666667, 1000000000) *
                   1000000000 / 112666667;

which yields a stable sequence:

  3333 -> 3337
  3337 -> 3337
  3337 -> ... (etc) ...

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2016-07-11 12:49:26 +02:00
Boris Brezillon
15da7b5001 pwm: Make use of pwm_get_xxx() helpers where appropriate
Use the pwm_get_xxx() helpers instead of directly accessing the fields
in struct pwm_device. This will allow us to smoothly move to the atomic
update approach.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2015-07-20 09:53:22 +02:00
Doug Anderson
7264354c0c pwm: rockchip: Allow polarity invert on rk3288
The rk3288 has the ability to invert the polarity of the PWM.  Let's
enable that ability.  Note that this increases pwm_cells to 3 for
rk3288.

Signed-off-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Caesar Wang <caesar.wang@rock-chips.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2014-08-26 10:44:08 +02:00
Caesar Wang
f630629908 pwm: rockchip: Added to support for RK3288 SoC
This patch added to support the PWM controller found on
RK3288 SoC.

Signed-off-by: Caesar Wang <caesar.wang@rock-chips.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2014-08-08 13:12:47 +02:00
Beniamino Galvani
101353c82a pwm: add Rockchip SoC PWM support
This commit adds a driver for the PWM controller found on Rockchip
RK29, RK30 and RK31 SoCs.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
2014-07-11 15:54:51 +02:00