Skip to content

Commit

Permalink
Merge tag 'pwm/for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "Various cleanups and fixes across the board"

* tag 'pwm/for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (31 commits)
  pwm: lpc32xx: Remove handling of PWM channels
  pwm: atmel: Simplify using devm functions
  dt-bindings: pwm: brcm,kona-pwm: convert to YAML
  pwm: stmpe: Handle errors when disabling the signal
  pwm: stm32: Simplify using devm_pwmchip_add()
  pwm: stm32: Don't modify HW state in .remove() callback
  pwm: Fix order of freeing resources in pwmchip_remove()
  pwm: ntxec: Use device_set_of_node_from_dev()
  pwm: ntxec: Drop a write-only variable from driver data
  pwm: pxa: Don't reimplement of_device_get_match_data()
  pwm: lpc18xx-sct: Simplify using devm_clk_get_enabled()
  pwm: atmel-tcb: Don't track polarity in driver data
  pwm: atmel-tcb: Unroll atmel_tcb_pwm_set_polarity() into only caller
  pwm: atmel-tcb: Put per-channel data into driver data
  pwm: atmel-tcb: Fix resource freeing in error path and remove
  pwm: atmel-tcb: Harmonize resource allocation order
  pwm: Drop unused #include <linux/radix-tree.h>
  pwm: rz-mtu3: Fix build warning 'num_channel_ios' not described
  pwm: Remove outdated documentation for pwmchip_remove()
  pwm: atmel: Enable clk when pwm already enabled in bootloader
  ...
  • Loading branch information
Linus Torvalds committed Sep 8, 2023
2 parents ff6e6de + 4aae44f commit 8d844b3
Show file tree
Hide file tree
Showing 40 changed files with 281 additions and 290 deletions.
21 changes: 0 additions & 21 deletions Documentation/devicetree/bindings/pwm/brcm,kona-pwm.txt

This file was deleted.

51 changes: 51 additions & 0 deletions Documentation/devicetree/bindings/pwm/brcm,kona-pwm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/pwm/brcm,kona-pwm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Broadcom Kona family PWM controller

description:
This controller has 6 channels.

maintainers:
- Florian Fainelli <f.fainelli@gmail.com>

allOf:
- $ref: pwm.yaml#

properties:
compatible:
items:
- enum:
- brcm,bcm11351-pwm
- const: brcm,kona-pwm

reg:
maxItems: 1

clocks:
maxItems: 1

'#pwm-cells':
const: 3

required:
- compatible
- reg
- clocks

unevaluatedProperties: false

examples:
- |
#include <dt-bindings/clock/bcm281xx.h>
pwm@3e01a000 {
compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm";
reg = <0x3e01a000 0xcc>;
clocks = <&slave_ccu BCM281XX_SLAVE_CCU_PWM>;
#pwm-cells = <3>;
};
...
41 changes: 19 additions & 22 deletions drivers/pwm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pwm.h>
#include <linux/radix-tree.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/err.h>
Expand Down Expand Up @@ -127,28 +127,28 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
}

struct pwm_device *
of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
of_pwm_xlate_with_flags(struct pwm_chip *chip, const struct of_phandle_args *args)
{
struct pwm_device *pwm;

if (pc->of_pwm_n_cells < 2)
if (chip->of_pwm_n_cells < 2)
return ERR_PTR(-EINVAL);

/* flags in the third cell are optional */
if (args->args_count < 2)
return ERR_PTR(-EINVAL);

if (args->args[0] >= pc->npwm)
if (args->args[0] >= chip->npwm)
return ERR_PTR(-EINVAL);

pwm = pwm_request_from_chip(pc, args->args[0], NULL);
pwm = pwm_request_from_chip(chip, args->args[0], NULL);
if (IS_ERR(pwm))
return pwm;

pwm->args.period = args->args[1];
pwm->args.polarity = PWM_POLARITY_NORMAL;

if (pc->of_pwm_n_cells >= 3) {
if (chip->of_pwm_n_cells >= 3) {
if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED)
pwm->args.polarity = PWM_POLARITY_INVERSED;
}
Expand All @@ -158,18 +158,18 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);

struct pwm_device *
of_pwm_single_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args)
{
struct pwm_device *pwm;

if (pc->of_pwm_n_cells < 1)
if (chip->of_pwm_n_cells < 1)
return ERR_PTR(-EINVAL);

/* validate that one cell is specified, optionally with flags */
if (args->args_count != 1 && args->args_count != 2)
return ERR_PTR(-EINVAL);

pwm = pwm_request_from_chip(pc, 0, NULL);
pwm = pwm_request_from_chip(chip, 0, NULL);
if (IS_ERR(pwm))
return pwm;

Expand Down Expand Up @@ -312,22 +312,19 @@ EXPORT_SYMBOL_GPL(pwmchip_add);
* pwmchip_remove() - remove a PWM chip
* @chip: the PWM chip to remove
*
* Removes a PWM chip. This function may return busy if the PWM chip provides
* a PWM device that is still requested.
*
* Returns: 0 on success or a negative error code on failure.
* Removes a PWM chip.
*/
void pwmchip_remove(struct pwm_chip *chip)
{
pwmchip_sysfs_unexport(chip);

if (IS_ENABLED(CONFIG_OF))
of_pwmchip_remove(chip);

mutex_lock(&pwm_lock);

list_del_init(&chip->list);

if (IS_ENABLED(CONFIG_OF))
of_pwmchip_remove(chip);

free_pwms(chip);

mutex_unlock(&pwm_lock);
Expand Down Expand Up @@ -692,7 +689,7 @@ static struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
struct pwm_device *pwm = NULL;
struct of_phandle_args args;
struct device_link *dl;
struct pwm_chip *pc;
struct pwm_chip *chip;
int index = 0;
int err;

Expand All @@ -709,16 +706,16 @@ static struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
return ERR_PTR(err);
}

pc = fwnode_to_pwmchip(of_fwnode_handle(args.np));
if (IS_ERR(pc)) {
if (PTR_ERR(pc) != -EPROBE_DEFER)
chip = fwnode_to_pwmchip(of_fwnode_handle(args.np));
if (IS_ERR(chip)) {
if (PTR_ERR(chip) != -EPROBE_DEFER)
pr_err("%s(): PWM chip not found\n", __func__);

pwm = ERR_CAST(pc);
pwm = ERR_CAST(chip);
goto put;
}

pwm = pc->of_xlate(pc, &args);
pwm = chip->of_xlate(chip, &args);
if (IS_ERR(pwm))
goto put;

Expand Down
1 change: 1 addition & 0 deletions drivers/pwm/pwm-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* - When APPLE_PWM_CTRL is set to 0, the output is constant low
*/

#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
Expand Down
66 changes: 34 additions & 32 deletions drivers/pwm/pwm-atmel-hlcdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/mfd/atmel-hlcdc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
Expand Down Expand Up @@ -38,11 +39,11 @@ static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip)
return container_of(chip, struct atmel_hlcdc_pwm, chip);
}

static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c);
struct atmel_hlcdc *hlcdc = chip->hlcdc;
struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip);
struct atmel_hlcdc *hlcdc = atmel->hlcdc;
unsigned int status;
int ret;

Expand All @@ -54,7 +55,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
u32 pwmcfg;
int pres;

if (!chip->errata || !chip->errata->slow_clk_erratum) {
if (!atmel->errata || !atmel->errata->slow_clk_erratum) {
clk_freq = clk_get_rate(new_clk);
if (!clk_freq)
return -EINVAL;
Expand All @@ -64,7 +65,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
}

/* Errata: cannot use slow clk on some IP revisions */
if ((chip->errata && chip->errata->slow_clk_erratum) ||
if ((atmel->errata && atmel->errata->slow_clk_erratum) ||
clk_period_ns > state->period) {
new_clk = hlcdc->sys_clk;
clk_freq = clk_get_rate(new_clk);
Expand All @@ -77,8 +78,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,

for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) {
/* Errata: cannot divide by 1 on some IP revisions */
if (!pres && chip->errata &&
chip->errata->div1_clk_erratum)
if (!pres && atmel->errata &&
atmel->errata->div1_clk_erratum)
continue;

if ((clk_period_ns << pres) >= state->period)
Expand All @@ -90,16 +91,16 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,

pwmcfg = ATMEL_HLCDC_PWMPS(pres);

if (new_clk != chip->cur_clk) {
if (new_clk != atmel->cur_clk) {
u32 gencfg = 0;
int ret;

ret = clk_prepare_enable(new_clk);
if (ret)
return ret;

clk_disable_unprepare(chip->cur_clk);
chip->cur_clk = new_clk;
clk_disable_unprepare(atmel->cur_clk);
atmel->cur_clk = new_clk;

if (new_clk == hlcdc->sys_clk)
gencfg = ATMEL_HLCDC_CLKPWMSEL;
Expand Down Expand Up @@ -160,8 +161,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
if (ret)
return ret;

clk_disable_unprepare(chip->cur_clk);
chip->cur_clk = NULL;
clk_disable_unprepare(atmel->cur_clk);
atmel->cur_clk = NULL;
}

return 0;
Expand All @@ -183,31 +184,32 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = {
#ifdef CONFIG_PM_SLEEP
static int atmel_hlcdc_pwm_suspend(struct device *dev)
{
struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);

/* Keep the periph clock enabled if the PWM is still running. */
if (pwm_is_enabled(&chip->chip.pwms[0]))
clk_disable_unprepare(chip->hlcdc->periph_clk);
if (pwm_is_enabled(&atmel->chip.pwms[0]))
clk_disable_unprepare(atmel->hlcdc->periph_clk);

return 0;
}

static int atmel_hlcdc_pwm_resume(struct device *dev)
{
struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
struct pwm_state state;
int ret;

pwm_get_state(&chip->chip.pwms[0], &state);
pwm_get_state(&atmel->chip.pwms[0], &state);

/* Re-enable the periph clock it was stopped during suspend. */
if (!state.enabled) {
ret = clk_prepare_enable(chip->hlcdc->periph_clk);
ret = clk_prepare_enable(atmel->hlcdc->periph_clk);
if (ret)
return ret;
}

return atmel_hlcdc_pwm_apply(&chip->chip, &chip->chip.pwms[0], &state);
return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0],
&state);
}
#endif

Expand Down Expand Up @@ -244,14 +246,14 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct atmel_hlcdc_pwm *chip;
struct atmel_hlcdc_pwm *atmel;
struct atmel_hlcdc *hlcdc;
int ret;

hlcdc = dev_get_drvdata(dev->parent);

chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
atmel = devm_kzalloc(dev, sizeof(*atmel), GFP_KERNEL);
if (!atmel)
return -ENOMEM;

ret = clk_prepare_enable(hlcdc->periph_clk);
Expand All @@ -260,31 +262,31 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)

match = of_match_node(atmel_hlcdc_dt_ids, dev->parent->of_node);
if (match)
chip->errata = match->data;
atmel->errata = match->data;

chip->hlcdc = hlcdc;
chip->chip.ops = &atmel_hlcdc_pwm_ops;
chip->chip.dev = dev;
chip->chip.npwm = 1;
atmel->hlcdc = hlcdc;
atmel->chip.ops = &atmel_hlcdc_pwm_ops;
atmel->chip.dev = dev;
atmel->chip.npwm = 1;

ret = pwmchip_add(&chip->chip);
ret = pwmchip_add(&atmel->chip);
if (ret) {
clk_disable_unprepare(hlcdc->periph_clk);
return ret;
}

platform_set_drvdata(pdev, chip);
platform_set_drvdata(pdev, atmel);

return 0;
}

static void atmel_hlcdc_pwm_remove(struct platform_device *pdev)
{
struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
struct atmel_hlcdc_pwm *atmel = platform_get_drvdata(pdev);

pwmchip_remove(&chip->chip);
pwmchip_remove(&atmel->chip);

clk_disable_unprepare(chip->hlcdc->periph_clk);
clk_disable_unprepare(atmel->hlcdc->periph_clk);
}

static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = {
Expand Down
Loading

0 comments on commit 8d844b3

Please sign in to comment.