pwm: Changes for v6.6-rc1
This contains various cleanups and fixes across the board. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmT55DMZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zoZHtEACJJRp36f/VBNHIkdIHlgnY OA1ScjwsLSmavWo6IJtGM/iAawnNBnKyMNymWjjs6240cNlXmIjQBvEX0zkRVsrp kuREZS0o5yS1kaM9QMXpur6HLNqwKxFGIzvUlcN2IB+myCBxfEQ/KlR3u3vRdQyH yB+9dvpAS1iRU957WcmdAtnid1j3mwxbFnNBMPp9iV7iH0Lg1TDSHuf1OCxc8lnP BZhS0zOjLUY8Eyo/pDkI9IIA4lXIg/JH9Ux4n88Ag84UiU/Q12APyT6R5nClK8Cr 0+LUHzjL4ZJbGdUkHyJtfzIGaO0Qy8TTgn7irPQChdIVTehhH5T4Uzl7v0EFudWi qz3BeGnOlFlhQG0WdAwH8pYYeTIVOn5HjjXQunmk36e1b+FNg5baQZ7gInry172b HT9KmDGfFBaDME1mZ4IayCvmjRIuoFWI6GtS/ykPBOTd58CjytMJD+khuTUwkUSd D5KAakc70JYBHQLzsRZExiP5RwxJ8LChmwF4yBfROF0S7KCL84R4pbEMLZ0ko08g bcxyZ8yHoTEpRxg332B1M/A/KFAMPiit0qK3LnuGdP0B73GFBb9mGvgwb6vwzRx1 Vo6Ewr8A3wZAL56rzXPFvabnMblzvHbuNQTMFkJLhA+doI4n3Oq+KW1u7Cf4ygEF qGOFsQsphAHZFrIob8xleg== =kax5 -----END PGP SIGNATURE----- Merge tag 'pwm/for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/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 ...
This commit is contained in:
commit
8d844b3518
@ -1,21 +0,0 @@
|
||||
Broadcom Kona PWM controller device tree bindings
|
||||
|
||||
This controller has 6 channels.
|
||||
|
||||
Required Properties :
|
||||
- compatible: should contain "brcm,kona-pwm"
|
||||
- reg: physical base address and length of the controller's registers
|
||||
- clocks: phandle + clock specifier pair for the external clock
|
||||
- #pwm-cells: Should be 3. See pwm.yaml in this directory for a
|
||||
description of the cells format.
|
||||
|
||||
Refer to clocks/clock-bindings.txt for generic clock consumer properties.
|
||||
|
||||
Example:
|
||||
|
||||
pwm: pwm@3e01a000 {
|
||||
compatible = "brcm,bcm11351-pwm", "brcm,kona-pwm";
|
||||
reg = <0x3e01a000 0xc4>;
|
||||
clocks = <&pwm_clk>;
|
||||
#pwm-cells = <3>;
|
||||
};
|
51
Documentation/devicetree/bindings/pwm/brcm,kona-pwm.yaml
Normal file
51
Documentation/devicetree/bindings/pwm/brcm,kona-pwm.yaml
Normal file
@ -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>;
|
||||
};
|
||||
...
|
@ -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>
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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)
|
||||
@ -90,7 +91,7 @@ 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;
|
||||
|
||||
@ -98,8 +99,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 = new_clk;
|
||||
clk_disable_unprepare(atmel->cur_clk);
|
||||
atmel->cur_clk = new_clk;
|
||||
|
||||
if (new_clk == hlcdc->sys_clk)
|
||||
gencfg = ATMEL_HLCDC_CLKPWMSEL;
|
||||
@ -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;
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
@ -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[] = {
|
||||
|
@ -19,8 +19,7 @@
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <soc/at91/atmel_tcb.h>
|
||||
@ -34,7 +33,6 @@
|
||||
ATMEL_TC_BEEVT | ATMEL_TC_BSWTRG)
|
||||
|
||||
struct atmel_tcb_pwm_device {
|
||||
enum pwm_polarity polarity; /* PWM polarity */
|
||||
unsigned div; /* PWM clock divider */
|
||||
unsigned duty; /* PWM duty expressed in clk cycles */
|
||||
unsigned period; /* PWM period expressed in clk cycles */
|
||||
@ -57,7 +55,7 @@ struct atmel_tcb_pwm_chip {
|
||||
struct clk *clk;
|
||||
struct clk *gclk;
|
||||
struct clk *slow_clk;
|
||||
struct atmel_tcb_pwm_device *pwms[NPWM];
|
||||
struct atmel_tcb_pwm_device pwms[NPWM];
|
||||
struct atmel_tcb_channel bkup;
|
||||
};
|
||||
|
||||
@ -68,37 +66,18 @@ static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip)
|
||||
return container_of(chip, struct atmel_tcb_pwm_chip, chip);
|
||||
}
|
||||
|
||||
static int atmel_tcb_pwm_set_polarity(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
enum pwm_polarity polarity)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
|
||||
|
||||
tcbpwm->polarity = polarity;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_tcb_pwm_request(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm;
|
||||
struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
|
||||
unsigned cmr;
|
||||
int ret;
|
||||
|
||||
tcbpwm = devm_kzalloc(chip->dev, sizeof(*tcbpwm), GFP_KERNEL);
|
||||
if (!tcbpwm)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = clk_prepare_enable(tcbpwmc->clk);
|
||||
if (ret) {
|
||||
devm_kfree(chip->dev, tcbpwm);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
tcbpwm->polarity = PWM_POLARITY_NORMAL;
|
||||
tcbpwm->duty = 0;
|
||||
tcbpwm->period = 0;
|
||||
tcbpwm->div = 0;
|
||||
@ -131,27 +110,22 @@ static int atmel_tcb_pwm_request(struct pwm_chip *chip,
|
||||
regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr);
|
||||
spin_unlock(&tcbpwmc->lock);
|
||||
|
||||
tcbpwmc->pwms[pwm->hwpwm] = tcbpwm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atmel_tcb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
|
||||
|
||||
clk_disable_unprepare(tcbpwmc->clk);
|
||||
tcbpwmc->pwms[pwm->hwpwm] = NULL;
|
||||
devm_kfree(chip->dev, tcbpwm);
|
||||
}
|
||||
|
||||
static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
enum pwm_polarity polarity)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
|
||||
struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
|
||||
unsigned cmr;
|
||||
enum pwm_polarity polarity = tcbpwm->polarity;
|
||||
|
||||
/*
|
||||
* If duty is 0 the timer will be stopped and we have to
|
||||
@ -203,12 +177,12 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
spin_unlock(&tcbpwmc->lock);
|
||||
}
|
||||
|
||||
static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
enum pwm_polarity polarity)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
|
||||
struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
|
||||
u32 cmr;
|
||||
enum pwm_polarity polarity = tcbpwm->polarity;
|
||||
|
||||
/*
|
||||
* If duty is 0 the timer will be stopped and we have to
|
||||
@ -291,7 +265,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
int duty_ns, int period_ns)
|
||||
{
|
||||
struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
|
||||
struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
|
||||
struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
|
||||
struct atmel_tcb_pwm_device *atcbpwm = NULL;
|
||||
int i = 0;
|
||||
int slowclk = 0;
|
||||
@ -338,9 +312,9 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
period = div_u64(period_ns, min);
|
||||
|
||||
if (pwm->hwpwm == 0)
|
||||
atcbpwm = tcbpwmc->pwms[1];
|
||||
atcbpwm = &tcbpwmc->pwms[1];
|
||||
else
|
||||
atcbpwm = tcbpwmc->pwms[0];
|
||||
atcbpwm = &tcbpwmc->pwms[0];
|
||||
|
||||
/*
|
||||
* PWM devices provided by the TCB driver are grouped by 2.
|
||||
@ -371,11 +345,8 @@ static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
int duty_cycle, period;
|
||||
int ret;
|
||||
|
||||
/* This function only sets a flag in driver data */
|
||||
atmel_tcb_pwm_set_polarity(chip, pwm, state->polarity);
|
||||
|
||||
if (!state->enabled) {
|
||||
atmel_tcb_pwm_disable(chip, pwm);
|
||||
atmel_tcb_pwm_disable(chip, pwm, state->polarity);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -386,7 +357,7 @@ static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return atmel_tcb_pwm_enable(chip, pwm);
|
||||
return atmel_tcb_pwm_enable(chip, pwm, state->polarity);
|
||||
}
|
||||
|
||||
static const struct pwm_ops atmel_tcb_pwm_ops = {
|
||||
@ -422,13 +393,14 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
|
||||
struct atmel_tcb_pwm_chip *tcbpwm;
|
||||
const struct atmel_tcb_config *config;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk, *gclk = NULL;
|
||||
struct clk *slow_clk;
|
||||
char clk_name[] = "t0_clk";
|
||||
int err;
|
||||
int channel;
|
||||
|
||||
tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
|
||||
if (tcbpwm == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
err = of_property_read_u32(np, "reg", &channel);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
@ -437,49 +409,43 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
regmap = syscon_node_to_regmap(np->parent);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
tcbpwm->regmap = syscon_node_to_regmap(np->parent);
|
||||
if (IS_ERR(tcbpwm->regmap))
|
||||
return PTR_ERR(tcbpwm->regmap);
|
||||
|
||||
slow_clk = of_clk_get_by_name(np->parent, "slow_clk");
|
||||
if (IS_ERR(slow_clk))
|
||||
return PTR_ERR(slow_clk);
|
||||
tcbpwm->slow_clk = of_clk_get_by_name(np->parent, "slow_clk");
|
||||
if (IS_ERR(tcbpwm->slow_clk))
|
||||
return PTR_ERR(tcbpwm->slow_clk);
|
||||
|
||||
clk_name[1] += channel;
|
||||
clk = of_clk_get_by_name(np->parent, clk_name);
|
||||
if (IS_ERR(clk))
|
||||
clk = of_clk_get_by_name(np->parent, "t0_clk");
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
tcbpwm->clk = of_clk_get_by_name(np->parent, clk_name);
|
||||
if (IS_ERR(tcbpwm->clk))
|
||||
tcbpwm->clk = of_clk_get_by_name(np->parent, "t0_clk");
|
||||
if (IS_ERR(tcbpwm->clk)) {
|
||||
err = PTR_ERR(tcbpwm->clk);
|
||||
goto err_slow_clk;
|
||||
}
|
||||
|
||||
match = of_match_node(atmel_tcb_of_match, np->parent);
|
||||
config = match->data;
|
||||
|
||||
if (config->has_gclk) {
|
||||
gclk = of_clk_get_by_name(np->parent, "gclk");
|
||||
if (IS_ERR(gclk))
|
||||
return PTR_ERR(gclk);
|
||||
}
|
||||
|
||||
tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
|
||||
if (tcbpwm == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto err_slow_clk;
|
||||
tcbpwm->gclk = of_clk_get_by_name(np->parent, "gclk");
|
||||
if (IS_ERR(tcbpwm->gclk)) {
|
||||
err = PTR_ERR(tcbpwm->gclk);
|
||||
goto err_clk;
|
||||
}
|
||||
}
|
||||
|
||||
tcbpwm->chip.dev = &pdev->dev;
|
||||
tcbpwm->chip.ops = &atmel_tcb_pwm_ops;
|
||||
tcbpwm->chip.npwm = NPWM;
|
||||
tcbpwm->channel = channel;
|
||||
tcbpwm->regmap = regmap;
|
||||
tcbpwm->clk = clk;
|
||||
tcbpwm->gclk = gclk;
|
||||
tcbpwm->slow_clk = slow_clk;
|
||||
tcbpwm->width = config->counter_width;
|
||||
|
||||
err = clk_prepare_enable(slow_clk);
|
||||
err = clk_prepare_enable(tcbpwm->slow_clk);
|
||||
if (err)
|
||||
goto err_slow_clk;
|
||||
goto err_gclk;
|
||||
|
||||
spin_lock_init(&tcbpwm->lock);
|
||||
|
||||
@ -494,8 +460,14 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(tcbpwm->slow_clk);
|
||||
|
||||
err_gclk:
|
||||
clk_put(tcbpwm->gclk);
|
||||
|
||||
err_clk:
|
||||
clk_put(tcbpwm->clk);
|
||||
|
||||
err_slow_clk:
|
||||
clk_put(slow_clk);
|
||||
clk_put(tcbpwm->slow_clk);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -507,8 +479,9 @@ static void atmel_tcb_pwm_remove(struct platform_device *pdev)
|
||||
pwmchip_remove(&tcbpwm->chip);
|
||||
|
||||
clk_disable_unprepare(tcbpwm->slow_clk);
|
||||
clk_put(tcbpwm->slow_clk);
|
||||
clk_put(tcbpwm->gclk);
|
||||
clk_put(tcbpwm->clk);
|
||||
clk_put(tcbpwm->slow_clk);
|
||||
}
|
||||
|
||||
static const struct of_device_id atmel_tcb_pwm_dt_ids[] = {
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
@ -36,7 +35,7 @@
|
||||
#define PWM_SR 0x0C
|
||||
#define PWM_ISR 0x1C
|
||||
/* Bit field in SR */
|
||||
#define PWM_SR_ALL_CH_ON 0x0F
|
||||
#define PWM_SR_ALL_CH_MASK 0x0F
|
||||
|
||||
/* The following register is PWM channel related registers */
|
||||
#define PWM_CH_REG_OFFSET 0x200
|
||||
@ -464,6 +463,42 @@ static const struct of_device_id atmel_pwm_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
|
||||
|
||||
static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on)
|
||||
{
|
||||
unsigned int i, cnt = 0;
|
||||
unsigned long sr;
|
||||
int ret = 0;
|
||||
|
||||
sr = atmel_pwm_readl(atmel_pwm, PWM_SR) & PWM_SR_ALL_CH_MASK;
|
||||
if (!sr)
|
||||
return 0;
|
||||
|
||||
cnt = bitmap_weight(&sr, atmel_pwm->chip.npwm);
|
||||
|
||||
if (!on)
|
||||
goto disable_clk;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
ret = clk_enable(atmel_pwm->clk);
|
||||
if (ret) {
|
||||
dev_err(atmel_pwm->chip.dev,
|
||||
"failed to enable clock for pwm %pe\n",
|
||||
ERR_PTR(ret));
|
||||
|
||||
cnt = i;
|
||||
goto disable_clk;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
while (cnt--)
|
||||
clk_disable(atmel_pwm->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct atmel_pwm_chip *atmel_pwm;
|
||||
@ -482,42 +517,31 @@ static int atmel_pwm_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(atmel_pwm->base))
|
||||
return PTR_ERR(atmel_pwm->base);
|
||||
|
||||
atmel_pwm->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
atmel_pwm->clk = devm_clk_get_prepared(&pdev->dev, NULL);
|
||||
if (IS_ERR(atmel_pwm->clk))
|
||||
return PTR_ERR(atmel_pwm->clk);
|
||||
|
||||
ret = clk_prepare(atmel_pwm->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to prepare PWM clock\n");
|
||||
return ret;
|
||||
}
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(atmel_pwm->clk),
|
||||
"failed to get prepared PWM clock\n");
|
||||
|
||||
atmel_pwm->chip.dev = &pdev->dev;
|
||||
atmel_pwm->chip.ops = &atmel_pwm_ops;
|
||||
atmel_pwm->chip.npwm = 4;
|
||||
|
||||
ret = pwmchip_add(&atmel_pwm->chip);
|
||||
ret = atmel_pwm_enable_clk_if_on(atmel_pwm, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_pwmchip_add(&pdev->dev, &atmel_pwm->chip);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to add PWM chip %d\n", ret);
|
||||
goto unprepare_clk;
|
||||
dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, atmel_pwm);
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
atmel_pwm_enable_clk_if_on(atmel_pwm, false);
|
||||
|
||||
return ret;
|
||||
|
||||
unprepare_clk:
|
||||
clk_unprepare(atmel_pwm->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atmel_pwm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
|
||||
|
||||
pwmchip_remove(&atmel_pwm->chip);
|
||||
|
||||
clk_unprepare(atmel_pwm->clk);
|
||||
}
|
||||
|
||||
static struct platform_driver atmel_pwm_driver = {
|
||||
@ -526,7 +550,6 @@ static struct platform_driver atmel_pwm_driver = {
|
||||
.of_match_table = of_match_ptr(atmel_pwm_dt_ids),
|
||||
},
|
||||
.probe = atmel_pwm_probe,
|
||||
.remove_new = atmel_pwm_remove,
|
||||
};
|
||||
module_platform_driver(atmel_pwm_driver);
|
||||
|
||||
|
@ -61,9 +61,9 @@ struct kona_pwmc {
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *_chip)
|
||||
static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(_chip, struct kona_pwmc, chip);
|
||||
return container_of(chip, struct kona_pwmc, chip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
@ -34,9 +34,9 @@ struct crystalcove_pwm {
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static inline struct crystalcove_pwm *to_crc_pwm(struct pwm_chip *pc)
|
||||
static inline struct crystalcove_pwm *to_crc_pwm(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(pc, struct crystalcove_pwm, chip);
|
||||
return container_of(chip, struct crystalcove_pwm, chip);
|
||||
}
|
||||
|
||||
static int crc_pwm_calc_clk_div(int period_ns)
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_data/cros_ec_commands.h>
|
||||
#include <linux/platform_data/cros_ec_proto.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -37,9 +38,9 @@ struct cros_ec_pwm {
|
||||
u16 duty_cycle;
|
||||
};
|
||||
|
||||
static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *c)
|
||||
static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(c, struct cros_ec_pwm_device, chip);
|
||||
return container_of(chip, struct cros_ec_pwm_device, chip);
|
||||
}
|
||||
|
||||
static int cros_ec_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
@ -218,14 +219,14 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
}
|
||||
|
||||
static struct pwm_device *
|
||||
cros_ec_pwm_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
|
||||
cros_ec_pwm_xlate(struct pwm_chip *chip, const struct of_phandle_args *args)
|
||||
{
|
||||
struct pwm_device *pwm;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pwm.h>
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/reset.h>
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/mfd/ingenic-tcu.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/mfd/lp3943.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
@ -24,9 +25,9 @@ struct lp3943_pwm {
|
||||
struct lp3943_platform_data *pdata;
|
||||
};
|
||||
|
||||
static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
|
||||
static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(_chip, struct lp3943_pwm, chip);
|
||||
return container_of(chip, struct lp3943_pwm, chip);
|
||||
}
|
||||
|
||||
static struct lp3943_pwm_map *
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
@ -366,30 +367,21 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(lpc18xx_pwm->base))
|
||||
return PTR_ERR(lpc18xx_pwm->base);
|
||||
|
||||
lpc18xx_pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
|
||||
lpc18xx_pwm->pwm_clk = devm_clk_get_enabled(&pdev->dev, "pwm");
|
||||
if (IS_ERR(lpc18xx_pwm->pwm_clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(lpc18xx_pwm->pwm_clk),
|
||||
"failed to get pwm clock\n");
|
||||
|
||||
ret = clk_prepare_enable(lpc18xx_pwm->pwm_clk);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"could not prepare or enable pwm clock\n");
|
||||
|
||||
lpc18xx_pwm->clk_rate = clk_get_rate(lpc18xx_pwm->pwm_clk);
|
||||
if (!lpc18xx_pwm->clk_rate) {
|
||||
ret = dev_err_probe(&pdev->dev,
|
||||
-EINVAL, "pwm clock has no frequency\n");
|
||||
goto disable_pwmclk;
|
||||
}
|
||||
if (!lpc18xx_pwm->clk_rate)
|
||||
return dev_err_probe(&pdev->dev,
|
||||
-EINVAL, "pwm clock has no frequency\n");
|
||||
|
||||
/*
|
||||
* If clkrate is too fast, the calculations in .apply() might overflow.
|
||||
*/
|
||||
if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) {
|
||||
ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
|
||||
goto disable_pwmclk;
|
||||
}
|
||||
if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
|
||||
|
||||
mutex_init(&lpc18xx_pwm->res_lock);
|
||||
mutex_init(&lpc18xx_pwm->period_lock);
|
||||
@ -435,18 +427,12 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
|
||||
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
|
||||
|
||||
ret = pwmchip_add(&lpc18xx_pwm->chip);
|
||||
if (ret < 0) {
|
||||
dev_err_probe(&pdev->dev, ret, "pwmchip_add failed\n");
|
||||
goto disable_pwmclk;
|
||||
}
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret, "pwmchip_add failed\n");
|
||||
|
||||
platform_set_drvdata(pdev, lpc18xx_pwm);
|
||||
|
||||
return 0;
|
||||
|
||||
disable_pwmclk:
|
||||
clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lpc18xx_pwm_remove(struct platform_device *pdev)
|
||||
@ -459,8 +445,6 @@ static void lpc18xx_pwm_remove(struct platform_device *pdev)
|
||||
val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
|
||||
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
|
||||
val | LPC18XX_PWM_CTRL_HALT);
|
||||
|
||||
clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
|
||||
}
|
||||
|
||||
static struct platform_driver lpc18xx_pwm_driver = {
|
||||
|
@ -51,10 +51,10 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (duty_cycles > 255)
|
||||
duty_cycles = 255;
|
||||
|
||||
val = readl(lpc32xx->base + (pwm->hwpwm << 2));
|
||||
val = readl(lpc32xx->base);
|
||||
val &= ~0xFFFF;
|
||||
val |= (period_cycles << 8) | duty_cycles;
|
||||
writel(val, lpc32xx->base + (pwm->hwpwm << 2));
|
||||
writel(val, lpc32xx->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -69,9 +69,9 @@ static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = readl(lpc32xx->base + (pwm->hwpwm << 2));
|
||||
val = readl(lpc32xx->base);
|
||||
val |= PWM_ENABLE;
|
||||
writel(val, lpc32xx->base + (pwm->hwpwm << 2));
|
||||
writel(val, lpc32xx->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -81,9 +81,9 @@ static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip);
|
||||
u32 val;
|
||||
|
||||
val = readl(lpc32xx->base + (pwm->hwpwm << 2));
|
||||
val = readl(lpc32xx->base);
|
||||
val &= ~PWM_ENABLE;
|
||||
writel(val, lpc32xx->base + (pwm->hwpwm << 2));
|
||||
writel(val, lpc32xx->base);
|
||||
|
||||
clk_disable_unprepare(lpc32xx->clk);
|
||||
}
|
||||
@ -141,9 +141,9 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
|
||||
lpc32xx->chip.npwm = 1;
|
||||
|
||||
/* If PWM is disabled, configure the output to the default value */
|
||||
val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
|
||||
val = readl(lpc32xx->base);
|
||||
val &= ~PWM_PIN_LEVEL;
|
||||
writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2));
|
||||
writel(val, lpc32xx->base);
|
||||
|
||||
ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip);
|
||||
if (ret < 0) {
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <linux/math64.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <linux/math.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
struct ntxec_pwm {
|
||||
struct device *dev;
|
||||
struct ntxec *ec;
|
||||
struct pwm_chip chip;
|
||||
};
|
||||
@ -141,14 +140,13 @@ static int ntxec_pwm_probe(struct platform_device *pdev)
|
||||
struct ntxec_pwm *priv;
|
||||
struct pwm_chip *chip;
|
||||
|
||||
pdev->dev.of_node = pdev->dev.parent->of_node;
|
||||
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->ec = ec;
|
||||
priv->dev = &pdev->dev;
|
||||
|
||||
chip = &priv->chip;
|
||||
chip->dev = &pdev->dev;
|
||||
|
@ -15,6 +15,7 @@
|
||||
* input clock (PWMCR_SD is set) and the output is driven to inactive.
|
||||
*/
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -156,13 +157,6 @@ MODULE_DEVICE_TABLE(of, pwm_of_match);
|
||||
#define pwm_of_match NULL
|
||||
#endif
|
||||
|
||||
static const struct platform_device_id *pxa_pwm_get_id_dt(struct device *dev)
|
||||
{
|
||||
const struct of_device_id *id = of_match_device(pwm_of_match, dev);
|
||||
|
||||
return id ? id->data : NULL;
|
||||
}
|
||||
|
||||
static int pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *id = platform_get_device_id(pdev);
|
||||
@ -170,7 +164,7 @@ static int pwm_probe(struct platform_device *pdev)
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF) && id == NULL)
|
||||
id = pxa_pwm_get_id_dt(&pdev->dev);
|
||||
id = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
if (id == NULL)
|
||||
return -EINVAL;
|
||||
|
@ -52,9 +52,9 @@ struct rockchip_pwm_data {
|
||||
u32 enable_conf;
|
||||
};
|
||||
|
||||
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
|
||||
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(c, struct rockchip_pwm_chip, chip);
|
||||
return container_of(chip, struct rockchip_pwm_chip, chip);
|
||||
}
|
||||
|
||||
static int rockchip_pwm_get_state(struct pwm_chip *chip,
|
||||
|
@ -40,7 +40,7 @@
|
||||
* struct rz_mtu3_channel_io_map - MTU3 pwm channel map
|
||||
*
|
||||
* @base_pwm_number: First PWM of a channel
|
||||
* @num: number of IOs on the HW channel.
|
||||
* @num_channel_ios: number of IOs on the HW channel.
|
||||
*/
|
||||
struct rz_mtu3_channel_io_map {
|
||||
u8 base_pwm_number;
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
@ -51,9 +52,9 @@ struct pwm_sifive_ddata {
|
||||
};
|
||||
|
||||
static inline
|
||||
struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c)
|
||||
struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(c, struct pwm_sifive_ddata, chip);
|
||||
return container_of(chip, struct pwm_sifive_ddata, chip);
|
||||
}
|
||||
|
||||
static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
@ -80,12 +81,15 @@
|
||||
regmap_write((priv)->regmap, (priv)->offset + (reg), (val))
|
||||
|
||||
struct sl28cpld_pwm {
|
||||
struct pwm_chip pwm_chip;
|
||||
struct pwm_chip chip;
|
||||
struct regmap *regmap;
|
||||
u32 offset;
|
||||
};
|
||||
#define sl28cpld_pwm_from_chip(_chip) \
|
||||
container_of(_chip, struct sl28cpld_pwm, pwm_chip)
|
||||
|
||||
static inline struct sl28cpld_pwm *sl28cpld_pwm_from_chip(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(chip, struct sl28cpld_pwm, chip);
|
||||
}
|
||||
|
||||
static int sl28cpld_pwm_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
@ -228,12 +232,12 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Initialize the pwm_chip structure */
|
||||
chip = &priv->pwm_chip;
|
||||
chip = &priv->chip;
|
||||
chip->dev = &pdev->dev;
|
||||
chip->ops = &sl28cpld_pwm_ops;
|
||||
chip->npwm = 1;
|
||||
|
||||
ret = devm_pwmchip_add(&pdev->dev, &priv->pwm_chip);
|
||||
ret = devm_pwmchip_add(&pdev->dev, chip);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add PWM chip (%pe)",
|
||||
ERR_PTR(ret));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
@ -637,7 +637,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
|
||||
priv->chip.ops = &stm32pwm_ops;
|
||||
priv->chip.npwm = stm32_pwm_detect_channels(priv);
|
||||
|
||||
ret = pwmchip_add(&priv->chip);
|
||||
ret = devm_pwmchip_add(dev, &priv->chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -646,17 +646,6 @@ static int stm32_pwm_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stm32_pwm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_pwm *priv = platform_get_drvdata(pdev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < priv->chip.npwm; i++)
|
||||
pwm_disable(&priv->chip.pwms[i]);
|
||||
|
||||
pwmchip_remove(&priv->chip);
|
||||
}
|
||||
|
||||
static int __maybe_unused stm32_pwm_suspend(struct device *dev)
|
||||
{
|
||||
struct stm32_pwm *priv = dev_get_drvdata(dev);
|
||||
@ -701,7 +690,6 @@ MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
|
||||
|
||||
static struct platform_driver stm32_pwm_driver = {
|
||||
.probe = stm32_pwm_probe,
|
||||
.remove_new = stm32_pwm_remove,
|
||||
.driver = {
|
||||
.name = "stm32-pwm",
|
||||
.of_match_table = stm32_pwm_of_match,
|
||||
|
@ -61,8 +61,8 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stmpe_24xx_pwm_disable(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm)
|
||||
static int stmpe_24xx_pwm_disable(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm)
|
||||
{
|
||||
struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
|
||||
u8 value;
|
||||
@ -72,17 +72,16 @@ static void stmpe_24xx_pwm_disable(struct pwm_chip *chip,
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "error reading PWM#%u control\n",
|
||||
pwm->hwpwm);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
value = ret & ~BIT(pwm->hwpwm);
|
||||
|
||||
ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
dev_err(chip->dev, "error writing PWM#%u control\n",
|
||||
pwm->hwpwm);
|
||||
return;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* STMPE 24xx PWM instructions */
|
||||
@ -111,7 +110,9 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
/* Make sure we are disabled */
|
||||
if (pwm_is_enabled(pwm)) {
|
||||
stmpe_24xx_pwm_disable(chip, pwm);
|
||||
ret = stmpe_24xx_pwm_disable(chip, pwm);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
/* Connect the PWM to the pin */
|
||||
pin = pwm->hwpwm;
|
||||
@ -269,7 +270,7 @@ static int stmpe_24xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
if (!state->enabled) {
|
||||
if (pwm->state.enabled)
|
||||
stmpe_24xx_pwm_disable(chip, pwm);
|
||||
return stmpe_24xx_pwm_disable(chip, pwm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/reset.h>
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/* ECAP registers and bits definitions */
|
||||
#define CAP1 0x08
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/* EHRPWM registers and bits definitions */
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -18,10 +19,6 @@
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
/*
|
||||
* SoC architecture allocates register space for 4 PWMs but only
|
||||
* 2 are currently implemented.
|
||||
|
@ -266,7 +266,7 @@ static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
|
||||
{
|
||||
struct gb_connection *connection;
|
||||
struct gb_pwm_chip *pwmc;
|
||||
struct pwm_chip *pwm;
|
||||
struct pwm_chip *chip;
|
||||
int ret;
|
||||
|
||||
pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
|
||||
@ -294,13 +294,13 @@ static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
|
||||
if (ret)
|
||||
goto exit_connection_disable;
|
||||
|
||||
pwm = &pwmc->chip;
|
||||
chip = &pwmc->chip;
|
||||
|
||||
pwm->dev = &gbphy_dev->dev;
|
||||
pwm->ops = &gb_pwm_ops;
|
||||
pwm->npwm = pwmc->pwm_max + 1;
|
||||
chip->dev = &gbphy_dev->dev;
|
||||
chip->ops = &gb_pwm_ops;
|
||||
chip->npwm = pwmc->pwm_max + 1;
|
||||
|
||||
ret = pwmchip_add(pwm);
|
||||
ret = pwmchip_add(chip);
|
||||
if (ret) {
|
||||
dev_err(&gbphy_dev->dev,
|
||||
"failed to register PWM: %d\n", ret);
|
||||
|
@ -298,7 +298,7 @@ struct pwm_chip {
|
||||
int base;
|
||||
unsigned int npwm;
|
||||
|
||||
struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
|
||||
struct pwm_device * (*of_xlate)(struct pwm_chip *chip,
|
||||
const struct of_phandle_args *args);
|
||||
unsigned int of_pwm_n_cells;
|
||||
|
||||
@ -395,9 +395,9 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
|
||||
unsigned int index,
|
||||
const char *label);
|
||||
|
||||
struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc,
|
||||
struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *chip,
|
||||
const struct of_phandle_args *args);
|
||||
struct pwm_device *of_pwm_single_xlate(struct pwm_chip *pc,
|
||||
struct pwm_device *of_pwm_single_xlate(struct pwm_chip *chip,
|
||||
const struct of_phandle_args *args);
|
||||
|
||||
struct pwm_device *pwm_get(struct device *dev, const char *con_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user