mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
pwm: Changes for v6.3-rc1
This rather small set of changes includes some minor fixes and improvements. The AB8500 driver gained support for reading the initial hardware state and the Synopsys DesignWare driver received some work to prepare for device tree and platform support. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmP+DlQZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zoaNvD/46MIgjveZf/+SltL1MF5Th RcudsTk4U5k2MHwVp7UV6UAKq45uu6b88CRWkfKCoN0V9c+JaItMurSI1VPRJf5L 9rW9axRd3EUSfPqu8WuqpcTocjhILuWIHFr2feGdlRGeEbUmBc1Jsj89MTePmp3n BNMIU9QU3or31VAE99GRb0ALrPkTW4fnHqH7dHEUxfrQ2Aaa7CAy5TuWSsS9nWDt NaP1MQHHkSr4viUjmDVzcD6trK4C3nDXhtU9GjzHRGuA8FVk0PvsE8JuSpiNmCUj 1oibqZNwBeVn+BWPabbGQmkWHmBp5GkKtXohcFiibqivIUOx469dgjzHwIA71i8w wA3AnIm9Mga9sCDON0d6XzR3yjl6/ZC4igHtUxY6PTy4Gh3sKcXxlu6GSj7SZA4N xOCykGxOaGYoiPFtVNWwTfkTApYezp+gi5xLzxk+InGCHFtJpaMwRu+PsBwL311K GTxrr4NR49W/4ogE8/epeunh8flmzBSA8cWQJiKRD0q/Xtl0AnrVPDCN1wZHTqqm LFivsq13vn0yDNnfwc12whhA1DaG08Mesec4QSemhAMlErs1Oqud77wdBIa9oK5w iPe3ienzvvow7Y8Ek4fqBFYY8ACHoyoMt5aINe8ZV7DYXE79HInY/q9RKSvYT+0x X4V5ihcowNXt6Kl67PsNBA== =PQhV -----END PGP SIGNATURE----- Merge tag 'pwm/for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm Pull pwm updates from Thierry Reding: "This rather small set of changes includes some minor fixes and improvements. The AB8500 driver gained support for reading the initial hardware state and the Synopsys DesignWare driver received some work to prepare for device tree and platform support" * tag 'pwm/for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: dwc: Use devm_pwmchip_add() pwm: dwc: Move memory allocation to own function pwm: dwc: Change &pci->dev to dev in probe dt-bindings: pwm: Document Synopsys DesignWare snps,pwm-dw-apb-timers-pwm2 pwm: iqs620a: Replace one remaining instance of regmap_update_bits() pwm: ab8500: Implement .get_state() pwm: ab8500: Fix calculation of duty and period pwm: lp3943: Drop unused i2c include dt-bindings: pwm: mediatek: Convert pwm-mediatek to DT schema pwm: stm32-lp: fix the check on arr and cmp registers update pwm: Move pwm_capture() dummy to restore order pwm: sifive: Always let the first pwm_apply_state succeed
This commit is contained in:
commit
e492250d52
@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pwm/mediatek,mt2712-pwm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek PWM Controller
|
||||
|
||||
maintainers:
|
||||
- John Crispin <john@phrozen.org>
|
||||
|
||||
allOf:
|
||||
- $ref: pwm.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt2712-pwm
|
||||
- mediatek,mt6795-pwm
|
||||
- mediatek,mt7622-pwm
|
||||
- mediatek,mt7623-pwm
|
||||
- mediatek,mt7628-pwm
|
||||
- mediatek,mt7629-pwm
|
||||
- mediatek,mt8183-pwm
|
||||
- mediatek,mt8365-pwm
|
||||
- mediatek,mt8516-pwm
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8195-pwm
|
||||
- const: mediatek,mt8183-pwm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 10
|
||||
|
||||
clock-names:
|
||||
description:
|
||||
This controller needs two input clocks for its core and one
|
||||
clock for each PWM output.
|
||||
minItems: 2
|
||||
items:
|
||||
- const: top
|
||||
- const: main
|
||||
- const: pwm1
|
||||
- const: pwm2
|
||||
- const: pwm3
|
||||
- const: pwm4
|
||||
- const: pwm5
|
||||
- const: pwm6
|
||||
- const: pwm7
|
||||
- const: pwm8
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#pwm-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/mt2712-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
pwm0: pwm@11006000 {
|
||||
compatible = "mediatek,mt2712-pwm";
|
||||
reg = <0x11006000 0x1000>;
|
||||
#pwm-cells = <2>;
|
||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_PWM_SEL>, <&pericfg CLK_PERI_PWM>,
|
||||
<&pericfg CLK_PERI_PWM0>, <&pericfg CLK_PERI_PWM1>,
|
||||
<&pericfg CLK_PERI_PWM2>, <&pericfg CLK_PERI_PWM3>,
|
||||
<&pericfg CLK_PERI_PWM4>, <&pericfg CLK_PERI_PWM5>,
|
||||
<&pericfg CLK_PERI_PWM6>, <&pericfg CLK_PERI_PWM7>;
|
||||
clock-names = "top", "main",
|
||||
"pwm1", "pwm2",
|
||||
"pwm3", "pwm4",
|
||||
"pwm5", "pwm6",
|
||||
"pwm7", "pwm8";
|
||||
};
|
@ -1,52 +0,0 @@
|
||||
MediaTek PWM controller
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "mediatek,<name>-pwm":
|
||||
- "mediatek,mt2712-pwm": found on mt2712 SoC.
|
||||
- "mediatek,mt6795-pwm": found on mt6795 SoC.
|
||||
- "mediatek,mt7622-pwm": found on mt7622 SoC.
|
||||
- "mediatek,mt7623-pwm": found on mt7623 SoC.
|
||||
- "mediatek,mt7628-pwm": found on mt7628 SoC.
|
||||
- "mediatek,mt7629-pwm": found on mt7629 SoC.
|
||||
- "mediatek,mt8183-pwm": found on mt8183 SoC.
|
||||
- "mediatek,mt8195-pwm", "mediatek,mt8183-pwm": found on mt8195 SoC.
|
||||
- "mediatek,mt8365-pwm": found on mt8365 SoC.
|
||||
- "mediatek,mt8516-pwm": found on mt8516 SoC.
|
||||
- reg: physical base address and length of the controller's registers.
|
||||
- #pwm-cells: must be 2. See pwm.yaml in this directory for a description of
|
||||
the cell format.
|
||||
- clocks: phandle and clock specifier of the PWM reference clock.
|
||||
- clock-names: must contain the following, except for MT7628 which
|
||||
has no clocks
|
||||
- "top": the top clock generator
|
||||
- "main": clock used by the PWM core
|
||||
- "pwm1-3": the three per PWM clocks for mt8365
|
||||
- "pwm1-8": the eight per PWM clocks for mt2712
|
||||
- "pwm1-6": the six per PWM clocks for mt7622
|
||||
- "pwm1-5": the five per PWM clocks for mt7623
|
||||
- "pwm1" : the PWM1 clock for mt7629
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-0: One property must exist for each entry in pinctrl-names.
|
||||
See pinctrl/pinctrl-bindings.txt for details of the property values.
|
||||
|
||||
Optional properties:
|
||||
- assigned-clocks: Reference to the PWM clock entries.
|
||||
- assigned-clock-parents: The phandle of the parent clock of PWM clock.
|
||||
|
||||
Example:
|
||||
pwm0: pwm@11006000 {
|
||||
compatible = "mediatek,mt7623-pwm";
|
||||
reg = <0 0x11006000 0 0x1000>;
|
||||
#pwm-cells = <2>;
|
||||
clocks = <&topckgen CLK_TOP_PWM_SEL>,
|
||||
<&pericfg CLK_PERI_PWM>,
|
||||
<&pericfg CLK_PERI_PWM1>,
|
||||
<&pericfg CLK_PERI_PWM2>,
|
||||
<&pericfg CLK_PERI_PWM3>,
|
||||
<&pericfg CLK_PERI_PWM4>,
|
||||
<&pericfg CLK_PERI_PWM5>;
|
||||
clock-names = "top", "main", "pwm1", "pwm2",
|
||||
"pwm3", "pwm4", "pwm5";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pwm0_pins>;
|
||||
};
|
@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2022 SiFive, Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pwm/snps,dw-apb-timers-pwm2.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Synopsys DW-APB timers PWM controller
|
||||
|
||||
maintainers:
|
||||
- Ben Dooks <ben.dooks@sifive.com>
|
||||
|
||||
description:
|
||||
This describes the DesignWare APB timers module when used in the PWM
|
||||
mode. The IP core can be generated with various options which can
|
||||
control the functionality, the number of PWMs available and other
|
||||
internal controls the designer requires.
|
||||
|
||||
The IP block has a version register so this can be used for detection
|
||||
instead of having to encode the IP version number in the device tree
|
||||
comaptible.
|
||||
|
||||
allOf:
|
||||
- $ref: pwm.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: snps,dw-apb-timers-pwm2
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#pwm-cells":
|
||||
const: 3
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Interface bus clock
|
||||
- description: PWM reference clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: timer
|
||||
|
||||
snps,pwm-number:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: The number of PWM channels configured for this instance
|
||||
enum: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#pwm-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
pwm: pwm@180000 {
|
||||
compatible = "snps,dw-apb-timers-pwm2";
|
||||
reg = <0x180000 0x200>;
|
||||
#pwm-cells = <3>;
|
||||
clocks = <&bus>, <&timer>;
|
||||
clock-names = "bus", "timer";
|
||||
};
|
@ -3,6 +3,7 @@
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Arun R Murthy <arun.murthy@stericsson.com>
|
||||
* Datasheet: https://web.archive.org/web/20130614115108/http://www.stericsson.com/developers/CD00291561_UM1031_AB8500_user_manual-rev5_CTDS_public.pdf
|
||||
*/
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -20,6 +21,8 @@
|
||||
#define AB8500_PWM_OUT_CTRL2_REG 0x61
|
||||
#define AB8500_PWM_OUT_CTRL7_REG 0x66
|
||||
|
||||
#define AB8500_PWM_CLKRATE 9600000
|
||||
|
||||
struct ab8500_pwm_chip {
|
||||
struct pwm_chip chip;
|
||||
unsigned int hwid;
|
||||
@ -35,13 +38,60 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
{
|
||||
int ret;
|
||||
u8 reg;
|
||||
unsigned int higher_val, lower_val;
|
||||
u8 higher_val, lower_val;
|
||||
unsigned int duty_steps, div;
|
||||
struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip);
|
||||
|
||||
if (state->polarity != PWM_POLARITY_NORMAL)
|
||||
return -EINVAL;
|
||||
|
||||
if (!state->enabled) {
|
||||
if (state->enabled) {
|
||||
/*
|
||||
* A time quantum is
|
||||
* q = (32 - FreqPWMOutx[3:0]) / AB8500_PWM_CLKRATE
|
||||
* The period is always 1024 q, duty_cycle is between 1q and 1024q.
|
||||
*
|
||||
* FreqPWMOutx[3:0] | output frequency | output frequency | 1024q = period
|
||||
* | (from manual) | (1 / 1024q) | = 1 / freq
|
||||
* -----------------+------------------+------------------+--------------
|
||||
* b0000 | 293 Hz | 292.968750 Hz | 3413333.33 ns
|
||||
* b0001 | 302 Hz | 302.419355 Hz | 3306666.66 ns
|
||||
* b0010 | 312 Hz | 312.500000 Hz | 3200000 ns
|
||||
* b0011 | 323 Hz | 323.275862 Hz | 3093333.33 ns
|
||||
* b0100 | 334 Hz | 334.821429 Hz | 2986666.66 ns
|
||||
* b0101 | 347 Hz | 347.222222 Hz | 2880000 ns
|
||||
* b0110 | 360 Hz | 360.576923 Hz | 2773333.33 ns
|
||||
* b0111 | 375 Hz | 375.000000 Hz | 2666666.66 ns
|
||||
* b1000 | 390 Hz | 390.625000 Hz | 2560000 ns
|
||||
* b1001 | 407 Hz | 407.608696 Hz | 2453333.33 ns
|
||||
* b1010 | 426 Hz | 426.136364 Hz | 2346666.66 ns
|
||||
* b1011 | 446 Hz | 446.428571 Hz | 2240000 ns
|
||||
* b1100 | 468 Hz | 468.750000 Hz | 2133333.33 ns
|
||||
* b1101 | 493 Hz | 493.421053 Hz | 2026666.66 ns
|
||||
* b1110 | 520 Hz | 520.833333 Hz | 1920000 ns
|
||||
* b1111 | 551 Hz | 551.470588 Hz | 1813333.33 ns
|
||||
*
|
||||
*
|
||||
* AB8500_PWM_CLKRATE is a multiple of 1024, so the division by
|
||||
* 1024 can be done in this factor without loss of precision.
|
||||
*/
|
||||
div = min_t(u64, mul_u64_u64_div_u64(state->period,
|
||||
AB8500_PWM_CLKRATE >> 10,
|
||||
NSEC_PER_SEC), 32); /* 32 - FreqPWMOutx[3:0] */
|
||||
if (div <= 16)
|
||||
/* requested period < 3413333.33 */
|
||||
return -EINVAL;
|
||||
|
||||
duty_steps = max_t(u64, mul_u64_u64_div_u64(state->duty_cycle,
|
||||
AB8500_PWM_CLKRATE,
|
||||
(u64)NSEC_PER_SEC * div), 1024);
|
||||
}
|
||||
|
||||
/*
|
||||
* The hardware doesn't support duty_steps = 0 explicitly, but emits low
|
||||
* when disabled.
|
||||
*/
|
||||
if (!state->enabled || duty_steps == 0) {
|
||||
ret = abx500_mask_and_set_register_interruptible(chip->dev,
|
||||
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
|
||||
1 << ab8500->hwid, 0);
|
||||
@ -53,28 +103,29 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
}
|
||||
|
||||
/*
|
||||
* get the first 8 bits that are be written to
|
||||
* The lower 8 bits of duty_steps is written to ...
|
||||
* AB8500_PWM_OUT_CTRL1_REG[0:7]
|
||||
*/
|
||||
lower_val = state->duty_cycle & 0x00FF;
|
||||
lower_val = (duty_steps - 1) & 0x00ff;
|
||||
/*
|
||||
* get bits [9:10] that are to be written to
|
||||
* AB8500_PWM_OUT_CTRL2_REG[0:1]
|
||||
* The two remaining high bits to
|
||||
* AB8500_PWM_OUT_CTRL2_REG[0:1]; together with FreqPWMOutx.
|
||||
*/
|
||||
higher_val = ((state->duty_cycle & 0x0300) >> 8);
|
||||
higher_val = ((duty_steps - 1) & 0x0300) >> 8 | (32 - div) << 4;
|
||||
|
||||
reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2);
|
||||
|
||||
ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
|
||||
reg, (u8)lower_val);
|
||||
reg, lower_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
|
||||
(reg + 1), (u8)higher_val);
|
||||
(reg + 1), higher_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* enable */
|
||||
ret = abx500_mask_and_set_register_interruptible(chip->dev,
|
||||
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
|
||||
1 << ab8500->hwid, 1 << ab8500->hwid);
|
||||
@ -85,8 +136,51 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
u8 ctrl7, lower_val, higher_val;
|
||||
int ret;
|
||||
struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip);
|
||||
unsigned int div, duty_steps;
|
||||
|
||||
ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC,
|
||||
AB8500_PWM_OUT_CTRL7_REG,
|
||||
&ctrl7);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
if (!(ctrl7 & 1 << ab8500->hwid)) {
|
||||
state->enabled = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC,
|
||||
AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2),
|
||||
&lower_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC,
|
||||
AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2),
|
||||
&higher_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
div = 32 - ((higher_val & 0xf0) >> 4);
|
||||
duty_steps = ((higher_val & 3) << 8 | lower_val) + 1;
|
||||
|
||||
state->period = DIV64_U64_ROUND_UP((u64)div << 10, AB8500_PWM_CLKRATE);
|
||||
state->duty_cycle = DIV64_U64_ROUND_UP((u64)div * duty_steps, AB8500_PWM_CLKRATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_ops ab8500_pwm_ops = {
|
||||
.apply = ab8500_pwm_apply,
|
||||
.get_state = ab8500_pwm_get_state,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -198,20 +198,35 @@ static const struct pwm_ops dwc_pwm_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct dwc_pwm *dwc_pwm_alloc(struct device *dev)
|
||||
{
|
||||
struct dwc_pwm *dwc;
|
||||
|
||||
dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
|
||||
if (!dwc)
|
||||
return NULL;
|
||||
|
||||
dwc->chip.dev = dev;
|
||||
dwc->chip.ops = &dwc_pwm_ops;
|
||||
dwc->chip.npwm = DWC_TIMERS_TOTAL;
|
||||
|
||||
dev_set_drvdata(dev, dwc);
|
||||
return dwc;
|
||||
}
|
||||
|
||||
static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
{
|
||||
struct device *dev = &pci->dev;
|
||||
struct dwc_pwm *dwc;
|
||||
int ret;
|
||||
|
||||
dwc = devm_kzalloc(&pci->dev, sizeof(*dwc), GFP_KERNEL);
|
||||
dwc = dwc_pwm_alloc(dev);
|
||||
if (!dwc)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pcim_enable_device(pci);
|
||||
if (ret) {
|
||||
dev_err(&pci->dev,
|
||||
"Failed to enable device (%pe)\n", ERR_PTR(ret));
|
||||
dev_err(dev, "Failed to enable device (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -219,24 +234,17 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
|
||||
ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
|
||||
if (ret) {
|
||||
dev_err(&pci->dev,
|
||||
"Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret));
|
||||
dev_err(dev, "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
dwc->base = pcim_iomap_table(pci)[0];
|
||||
if (!dwc->base) {
|
||||
dev_err(&pci->dev, "Base address missing\n");
|
||||
dev_err(dev, "Base address missing\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pci, dwc);
|
||||
|
||||
dwc->chip.dev = dev;
|
||||
dwc->chip.ops = &dwc_pwm_ops;
|
||||
dwc->chip.npwm = DWC_TIMERS_TOTAL;
|
||||
|
||||
ret = pwmchip_add(&dwc->chip);
|
||||
ret = devm_pwmchip_add(dev, &dwc->chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -248,12 +256,8 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
|
||||
static void dwc_pwm_remove(struct pci_dev *pci)
|
||||
{
|
||||
struct dwc_pwm *dwc = pci_get_drvdata(pci);
|
||||
|
||||
pm_runtime_forbid(&pci->dev);
|
||||
pm_runtime_get_noresume(&pci->dev);
|
||||
|
||||
pwmchip_remove(&dwc->chip);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -55,8 +55,8 @@ static int iqs620_pwm_init(struct iqs620_pwm_private *iqs620_pwm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
|
||||
IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
|
||||
return regmap_set_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
|
||||
IQS620_PWR_SETTINGS_PWM_OUT);
|
||||
}
|
||||
|
||||
static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/lp3943.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -161,7 +161,13 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
mutex_lock(&ddata->lock);
|
||||
if (state->period != ddata->approx_period) {
|
||||
if (ddata->user_count != 1) {
|
||||
/*
|
||||
* Don't let a 2nd user change the period underneath the 1st user.
|
||||
* However if ddate->approx_period == 0 this is the first time we set
|
||||
* any period, so let whoever gets here first set the period so other
|
||||
* users who agree on the period won't fail.
|
||||
*/
|
||||
if (ddata->user_count != 1 && ddata->approx_period) {
|
||||
mutex_unlock(&ddata->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
/* ensure CMP & ARR registers are properly written */
|
||||
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
|
||||
(val & STM32_LPTIM_CMPOK_ARROK),
|
||||
(val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
|
||||
100, 1000);
|
||||
if (ret) {
|
||||
dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
|
||||
|
@ -440,13 +440,6 @@ static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int pwm_capture(struct pwm_device *pwm,
|
||||
struct pwm_capture *result,
|
||||
unsigned long timeout)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int pwm_enable(struct pwm_device *pwm)
|
||||
{
|
||||
might_sleep();
|
||||
@ -458,6 +451,13 @@ static inline void pwm_disable(struct pwm_device *pwm)
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
static inline int pwm_capture(struct pwm_device *pwm,
|
||||
struct pwm_capture *result,
|
||||
unsigned long timeout)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user