pwm: Changes for v6.7-rc1

This contains a few fixes and a bunch of cleanups, a lot of which is in
 preparation for Uwe's character device support that may be ready in time
 for the next merge window.
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmVLhGsZHHRoaWVycnku
 cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zoazOD/oDjIcP4lSkAdcRLuEPsHor
 47INsdzm84g7CcUhFVY8a1ODjXNtVWcoXeLsJ69lJ3CJW9cjHlUaeFcP5KW5YhMN
 nE3Kk8MsAyeaN6QgSVeqsMj8t64WvUve3/M0M/bmaPt3mO8hxYTuSQlK5v+JfEyO
 Px8JH/U2f7W2zdVbdK3YtpcRtMiqYlYw2mu/ILumlZhZvxXEPWPs6lH8J3VHW9nU
 L8Up1dQB7TQcZiw4M2cdP/oSieQ+2PhWKbyWxdutArNxdMlE6xDurzIDzvwXL5kt
 cMWZtU0/kPu9cuH+19wqvRyFgGHSCjvP/smuu87/JvHc3Nbjxt//H3bQuDFLyiGc
 ZPfyNJOQ4vGSQ9gHQbedEsBnnX9qeZZecrd9PteUAqbAuRh/53bij0buXvzIwWzr
 36/nHyjO9oEDcXgxGI75ATd7yd51ipyIEmYmzDGWoUGF8TK61wUYVaI0+x6I8JFO
 vQu1/pxcwjnQ/4r87opmx7E1UK/v5hYugpZIA39d5yM2djikZTTcNEhQchnN0RHN
 ih8ZyQ/A0XGHr2ICRFsgTPVFzKM0JyjCCVGvuEdkEN2dtk4dJlJTPz0xpNRIaALU
 dhsqziUT0FqqeLprwKBWjXZLbzWwwXWrOzAbbsXkoPny8BRYE60Pp5qqjPrLgj5Z
 2z8rCDBaoILeFl5utV0rzw==
 =S2DI
 -----END PGP SIGNATURE-----

Merge tag 'pwm/for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "This contains a few fixes and a bunch of cleanups, a lot of which is
  in preparation for Uwe's character device support that may be ready in
  time for the next merge window"

* tag 'pwm/for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (37 commits)
  pwm: samsung: Document new member .channel in struct samsung_pwm_chip
  pwm: bcm2835: Add support for suspend/resume
  pwm: brcmstb: Checked clk_prepare_enable() return value
  pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume
  pwm: pxa: Explicitly include correct DT includes
  pwm: cros-ec: Simplify using devm_pwmchip_add() and dev_err_probe()
  pwm: samsung: Consistently use the same name for driver data
  pwm: vt8500: Simplify using devm functions
  pwm: sprd: Simplify using devm_pwmchip_add() and dev_err_probe()
  pwm: sprd: Provide a helper to cast a chip to driver data
  pwm: spear: Simplify using devm functions
  pwm: mtk-disp: Simplify using devm_pwmchip_add()
  pwm: imx-tpm: Simplify using devm functions
  pwm: brcmstb: Simplify using devm functions
  pwm: bcm2835: Simplify using devm functions
  pwm: bcm-iproc: Simplify using devm functions
  pwm: Adapt sysfs API documentation to reality
  pwm: dwc: add PWM bit unset in get_state call
  pwm: dwc: make timer clock configurable
  pwm: dwc: split pci out of core driver
  ...
This commit is contained in:
Linus Torvalds 2023-11-09 13:47:52 -08:00
commit f3bfe64330
74 changed files with 537 additions and 776 deletions

View File

@ -15,12 +15,19 @@ allOf:
properties:
compatible:
enum:
- fsl,imx23-pwm
oneOf:
- const: fsl,imx23-pwm
- items:
- enum:
- fsl,imx28-pwm
- const: fsl,imx23-pwm
reg:
maxItems: 1
clocks:
maxItems: 1
"#pwm-cells":
const: 3
@ -31,6 +38,7 @@ properties:
required:
- compatible
- reg
- clocks
- fsl,pwm-number
additionalProperties: false
@ -40,6 +48,7 @@ examples:
pwm@80064000 {
compatible = "fsl,imx23-pwm";
reg = <0x80064000 0x2000>;
clocks = <&clks 30>;
#pwm-cells = <3>;
fsl,pwm-number = <8>;
};

View File

@ -757,7 +757,6 @@ static const struct pwm_ops mvebu_pwm_ops = {
.free = mvebu_pwm_free,
.get_state = mvebu_pwm_get_state,
.apply = mvebu_pwm_apply,
.owner = THIS_MODULE,
};
static void __maybe_unused mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip)

View File

@ -1580,7 +1580,6 @@ static const struct pwm_ops ti_sn_pwm_ops = {
.free = ti_sn_pwm_free,
.apply = ti_sn_pwm_apply,
.get_state = ti_sn_pwm_get_state,
.owner = THIS_MODULE,
};
static int ti_sn_pwm_probe(struct auxiliary_device *adev,

View File

@ -1085,7 +1085,6 @@ static const struct pwm_ops lpg_pwm_ops = {
.request = lpg_pwm_request,
.apply = lpg_pwm_apply,
.get_state = lpg_pwm_get_state,
.owner = THIS_MODULE,
};
static int lpg_add_pwm(struct lpg *lpg)

View File

@ -173,8 +173,8 @@ config PWM_CLPS711X
will be called pwm-clps711x.
config PWM_CRC
bool "Intel Crystalcove (CRC) PWM support"
depends on X86 && INTEL_SOC_PMIC
tristate "Intel Crystalcove (CRC) PWM support"
depends on INTEL_SOC_PMIC
help
Generic PWM framework driver for Crystalcove (CRC) PMIC based PWM
control.
@ -186,9 +186,19 @@ config PWM_CROS_EC
PWM driver for exposing a PWM attached to the ChromeOS Embedded
Controller.
config PWM_DWC_CORE
tristate
depends on HAS_IOMEM
help
PWM driver for Synopsys DWC PWM Controller.
To compile this driver as a module, build the dependecies as
modules, this will be called pwm-dwc-core.
config PWM_DWC
tristate "DesignWare PWM Controller"
depends on PCI
tristate "DesignWare PWM Controller (PCI bus)"
depends on HAS_IOMEM && PCI
select PWM_DWC_CORE
help
PWM driver for Synopsys DWC PWM Controller attached to a PCI bus.
@ -407,7 +417,7 @@ config PWM_MEDIATEK
config PWM_MICROCHIP_CORE
tristate "Microchip corePWM PWM support"
depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
depends on HAS_IOMEM && OF
help
PWM driver for Microchip FPGA soft IP core.

View File

@ -15,6 +15,7 @@ obj-$(CONFIG_PWM_CLK) += pwm-clk.o
obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o
obj-$(CONFIG_PWM_CRC) += pwm-crc.o
obj-$(CONFIG_PWM_CROS_EC) += pwm-cros-ec.o
obj-$(CONFIG_PWM_DWC_CORE) += pwm-dwc-core.o
obj-$(CONFIG_PWM_DWC) += pwm-dwc.o
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o

View File

@ -89,13 +89,13 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
if (test_bit(PWMF_REQUESTED, &pwm->flags))
return -EBUSY;
if (!try_module_get(pwm->chip->ops->owner))
if (!try_module_get(pwm->chip->owner))
return -ENODEV;
if (pwm->chip->ops->request) {
err = pwm->chip->ops->request(pwm->chip, pwm);
if (err) {
module_put(pwm->chip->ops->owner);
module_put(pwm->chip->owner);
return err;
}
}
@ -208,36 +208,6 @@ static void of_pwmchip_remove(struct pwm_chip *chip)
of_node_put(chip->dev->of_node);
}
/**
* pwm_set_chip_data() - set private chip data for a PWM
* @pwm: PWM device
* @data: pointer to chip-specific data
*
* Returns: 0 on success or a negative error code on failure.
*/
int pwm_set_chip_data(struct pwm_device *pwm, void *data)
{
if (!pwm)
return -EINVAL;
pwm->chip_data = data;
return 0;
}
EXPORT_SYMBOL_GPL(pwm_set_chip_data);
/**
* pwm_get_chip_data() - get private chip data for a PWM
* @pwm: PWM device
*
* Returns: A pointer to the chip-private data for the PWM device.
*/
void *pwm_get_chip_data(struct pwm_device *pwm)
{
return pwm ? pwm->chip_data : NULL;
}
EXPORT_SYMBOL_GPL(pwm_get_chip_data);
static bool pwm_ops_check(const struct pwm_chip *chip)
{
const struct pwm_ops *ops = chip->ops;
@ -253,14 +223,16 @@ static bool pwm_ops_check(const struct pwm_chip *chip)
}
/**
* pwmchip_add() - register a new PWM chip
* __pwmchip_add() - register a new PWM chip
* @chip: the PWM chip to add
* @owner: reference to the module providing the chip.
*
* Register a new PWM chip.
* Register a new PWM chip. @owner is supposed to be THIS_MODULE, use the
* pwmchip_add wrapper to do this right.
*
* Returns: 0 on success or a negative error code on failure.
*/
int pwmchip_add(struct pwm_chip *chip)
int __pwmchip_add(struct pwm_chip *chip, struct module *owner)
{
struct pwm_device *pwm;
unsigned int i;
@ -272,6 +244,8 @@ int pwmchip_add(struct pwm_chip *chip)
if (!pwm_ops_check(chip))
return -EINVAL;
chip->owner = owner;
chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
if (!chip->pwms)
return -ENOMEM;
@ -306,7 +280,7 @@ int pwmchip_add(struct pwm_chip *chip)
return 0;
}
EXPORT_SYMBOL_GPL(pwmchip_add);
EXPORT_SYMBOL_GPL(__pwmchip_add);
/**
* pwmchip_remove() - remove a PWM chip
@ -338,17 +312,17 @@ static void devm_pwmchip_remove(void *data)
pwmchip_remove(chip);
}
int devm_pwmchip_add(struct device *dev, struct pwm_chip *chip)
int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner)
{
int ret;
ret = pwmchip_add(chip);
ret = __pwmchip_add(chip, owner);
if (ret)
return ret;
return devm_add_action_or_reset(dev, devm_pwmchip_remove, chip);
}
EXPORT_SYMBOL_GPL(devm_pwmchip_add);
EXPORT_SYMBOL_GPL(__devm_pwmchip_add);
/**
* pwm_request_from_chip() - request a PWM device relative to a PWM chip
@ -976,10 +950,9 @@ void pwm_put(struct pwm_device *pwm)
if (pwm->chip->ops->free)
pwm->chip->ops->free(pwm->chip, pwm);
pwm_set_chip_data(pwm, NULL);
pwm->label = NULL;
module_put(pwm->chip->ops->owner);
module_put(pwm->chip->owner);
out:
mutex_unlock(&pwm_lock);
}

View File

@ -181,7 +181,6 @@ static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops ab8500_pwm_ops = {
.apply = ab8500_pwm_apply,
.get_state = ab8500_pwm_get_state,
.owner = THIS_MODULE,
};
static int ab8500_pwm_probe(struct platform_device *pdev)

View File

@ -99,7 +99,6 @@ static int apple_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops apple_pwm_ops = {
.apply = apple_pwm_apply,
.get_state = apple_pwm_get_state,
.owner = THIS_MODULE,
};
static int apple_pwm_probe(struct platform_device *pdev)

View File

@ -170,7 +170,6 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops atmel_hlcdc_pwm_ops = {
.apply = atmel_hlcdc_pwm_apply,
.owner = THIS_MODULE,
};
static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_at91sam9x5_errata = {

View File

@ -364,7 +364,6 @@ static const struct pwm_ops atmel_tcb_pwm_ops = {
.request = atmel_tcb_pwm_request,
.free = atmel_tcb_pwm_free,
.apply = atmel_tcb_pwm_apply,
.owner = THIS_MODULE,
};
static struct atmel_tcb_config tcb_rm9200_config = {

View File

@ -402,7 +402,6 @@ static int atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops atmel_pwm_ops = {
.apply = atmel_pwm_apply,
.get_state = atmel_pwm_get_state,
.owner = THIS_MODULE,
};
static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {
@ -547,7 +546,7 @@ disable_clk:
static struct platform_driver atmel_pwm_driver = {
.driver = {
.name = "atmel-pwm",
.of_match_table = of_match_ptr(atmel_pwm_dt_ids),
.of_match_table = atmel_pwm_dt_ids,
},
.probe = atmel_pwm_probe,
};

View File

@ -183,7 +183,6 @@ static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops iproc_pwm_ops = {
.apply = iproc_pwmc_apply,
.get_state = iproc_pwmc_get_state,
.owner = THIS_MODULE,
};
static int iproc_pwmc_probe(struct platform_device *pdev)
@ -207,18 +206,10 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
if (IS_ERR(ip->base))
return PTR_ERR(ip->base);
ip->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ip->clk)) {
dev_err(&pdev->dev, "failed to get clock: %ld\n",
PTR_ERR(ip->clk));
return PTR_ERR(ip->clk);
}
ret = clk_prepare_enable(ip->clk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
return ret;
}
ip->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(ip->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(ip->clk),
"failed to get clock\n");
/* Set full drive and normal polarity for all channels */
value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
@ -230,22 +221,12 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
writel(value, ip->base + IPROC_PWM_CTRL_OFFSET);
ret = pwmchip_add(&ip->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
clk_disable_unprepare(ip->clk);
}
ret = devm_pwmchip_add(&pdev->dev, &ip->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"failed to add PWM chip\n");
return ret;
}
static void iproc_pwmc_remove(struct platform_device *pdev)
{
struct iproc_pwmc *ip = platform_get_drvdata(pdev);
pwmchip_remove(&ip->chip);
clk_disable_unprepare(ip->clk);
return 0;
}
static const struct of_device_id bcm_iproc_pwmc_dt[] = {
@ -260,7 +241,6 @@ static struct platform_driver iproc_pwmc_driver = {
.of_match_table = bcm_iproc_pwmc_dt,
},
.probe = iproc_pwmc_probe,
.remove_new = iproc_pwmc_remove,
};
module_platform_driver(iproc_pwmc_driver);

View File

@ -269,7 +269,6 @@ static int kona_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops kona_pwm_ops = {
.apply = kona_pwmc_apply,
.owner = THIS_MODULE,
};
static int kona_pwmc_probe(struct platform_device *pdev)

View File

@ -129,7 +129,6 @@ static const struct pwm_ops bcm2835_pwm_ops = {
.request = bcm2835_pwm_request,
.free = bcm2835_pwm_free,
.apply = bcm2835_pwm_apply,
.owner = THIS_MODULE,
};
static int bcm2835_pwm_probe(struct platform_device *pdev)
@ -147,41 +146,42 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
pc->clk = devm_clk_get(&pdev->dev, NULL);
pc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(pc->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
"clock not found\n");
ret = clk_prepare_enable(pc->clk);
if (ret)
return ret;
pc->chip.dev = &pdev->dev;
pc->chip.ops = &bcm2835_pwm_ops;
pc->chip.npwm = 2;
platform_set_drvdata(pdev, pc);
ret = pwmchip_add(&pc->chip);
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
if (ret < 0)
goto add_fail;
return dev_err_probe(&pdev->dev, ret,
"failed to add pwmchip\n");
return 0;
add_fail:
clk_disable_unprepare(pc->clk);
return ret;
}
static void bcm2835_pwm_remove(struct platform_device *pdev)
static int bcm2835_pwm_suspend(struct device *dev)
{
struct bcm2835_pwm *pc = platform_get_drvdata(pdev);
pwmchip_remove(&pc->chip);
struct bcm2835_pwm *pc = dev_get_drvdata(dev);
clk_disable_unprepare(pc->clk);
return 0;
}
static int bcm2835_pwm_resume(struct device *dev)
{
struct bcm2835_pwm *pc = dev_get_drvdata(dev);
return clk_prepare_enable(pc->clk);
}
static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835_pwm_pm_ops, bcm2835_pwm_suspend,
bcm2835_pwm_resume);
static const struct of_device_id bcm2835_pwm_of_match[] = {
{ .compatible = "brcm,bcm2835-pwm", },
{ /* sentinel */ }
@ -192,9 +192,9 @@ static struct platform_driver bcm2835_pwm_driver = {
.driver = {
.name = "bcm2835-pwm",
.of_match_table = bcm2835_pwm_of_match,
.pm = pm_ptr(&bcm2835_pwm_pm_ops),
},
.probe = bcm2835_pwm_probe,
.remove_new = bcm2835_pwm_remove,
};
module_platform_driver(bcm2835_pwm_driver);

View File

@ -39,6 +39,8 @@
#define BERLIN_PWM_TCNT 0xc
#define BERLIN_PWM_MAX_TCNT 65535
#define BERLIN_PWM_NUMPWMS 4
struct berlin_pwm_channel {
u32 enable;
u32 ctrl;
@ -50,6 +52,7 @@ struct berlin_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
void __iomem *base;
struct berlin_pwm_channel channel[BERLIN_PWM_NUMPWMS];
};
static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
@ -70,24 +73,6 @@ static inline void berlin_pwm_writel(struct berlin_pwm_chip *bpc,
writel_relaxed(value, bpc->base + channel * 0x10 + offset);
}
static int berlin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct berlin_pwm_channel *channel;
channel = kzalloc(sizeof(*channel), GFP_KERNEL);
if (!channel)
return -ENOMEM;
return pwm_set_chip_data(pwm, channel);
}
static void berlin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm);
kfree(channel);
}
static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u64 duty_ns, u64 period_ns)
{
@ -202,10 +187,7 @@ static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
}
static const struct pwm_ops berlin_pwm_ops = {
.request = berlin_pwm_request,
.free = berlin_pwm_free,
.apply = berlin_pwm_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id berlin_pwm_match[] = {
@ -227,39 +209,23 @@ static int berlin_pwm_probe(struct platform_device *pdev)
if (IS_ERR(bpc->base))
return PTR_ERR(bpc->base);
bpc->clk = devm_clk_get(&pdev->dev, NULL);
bpc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(bpc->clk))
return PTR_ERR(bpc->clk);
ret = clk_prepare_enable(bpc->clk);
if (ret)
return ret;
bpc->chip.dev = &pdev->dev;
bpc->chip.ops = &berlin_pwm_ops;
bpc->chip.npwm = 4;
bpc->chip.npwm = BERLIN_PWM_NUMPWMS;
ret = pwmchip_add(&bpc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
clk_disable_unprepare(bpc->clk);
return ret;
}
ret = devm_pwmchip_add(&pdev->dev, &bpc->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
platform_set_drvdata(pdev, bpc);
return 0;
}
static void berlin_pwm_remove(struct platform_device *pdev)
{
struct berlin_pwm_chip *bpc = platform_get_drvdata(pdev);
pwmchip_remove(&bpc->chip);
clk_disable_unprepare(bpc->clk);
}
#ifdef CONFIG_PM_SLEEP
static int berlin_pwm_suspend(struct device *dev)
{
@ -267,11 +233,7 @@ static int berlin_pwm_suspend(struct device *dev)
unsigned int i;
for (i = 0; i < bpc->chip.npwm; i++) {
struct berlin_pwm_channel *channel;
channel = pwm_get_chip_data(&bpc->chip.pwms[i]);
if (!channel)
continue;
struct berlin_pwm_channel *channel = &bpc->channel[i];
channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE);
channel->ctrl = berlin_pwm_readl(bpc, i, BERLIN_PWM_CONTROL);
@ -295,11 +257,7 @@ static int berlin_pwm_resume(struct device *dev)
return ret;
for (i = 0; i < bpc->chip.npwm; i++) {
struct berlin_pwm_channel *channel;
channel = pwm_get_chip_data(&bpc->chip.pwms[i]);
if (!channel)
continue;
struct berlin_pwm_channel *channel = &bpc->channel[i];
berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL);
berlin_pwm_writel(bpc, i, channel->duty, BERLIN_PWM_DUTY);
@ -316,7 +274,6 @@ static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,
static struct platform_driver berlin_pwm_driver = {
.probe = berlin_pwm_probe,
.remove_new = berlin_pwm_remove,
.driver = {
.name = "berlin-pwm",
.of_match_table = berlin_pwm_match,

View File

@ -220,7 +220,6 @@ static int brcmstb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops brcmstb_pwm_ops = {
.apply = brcmstb_pwm_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id brcmstb_pwm_of_match[] = {
@ -238,17 +237,10 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
if (!p)
return -ENOMEM;
p->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(p->clk)) {
dev_err(&pdev->dev, "failed to obtain clock\n");
return PTR_ERR(p->clk);
}
ret = clk_prepare_enable(p->clk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
return ret;
}
p->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(p->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(p->clk),
"failed to obtain clock\n");
platform_set_drvdata(pdev, p);
@ -257,30 +249,14 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
p->chip.npwm = 2;
p->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(p->base)) {
ret = PTR_ERR(p->base);
goto out_clk;
}
if (IS_ERR(p->base))
return PTR_ERR(p->base);
ret = pwmchip_add(&p->chip);
if (ret) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
goto out_clk;
}
ret = devm_pwmchip_add(&pdev->dev, &p->chip);
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
return 0;
out_clk:
clk_disable_unprepare(p->clk);
return ret;
}
static void brcmstb_pwm_remove(struct platform_device *pdev)
{
struct brcmstb_pwm *p = platform_get_drvdata(pdev);
pwmchip_remove(&p->chip);
clk_disable_unprepare(p->clk);
}
#ifdef CONFIG_PM_SLEEP
@ -288,7 +264,7 @@ static int brcmstb_pwm_suspend(struct device *dev)
{
struct brcmstb_pwm *p = dev_get_drvdata(dev);
clk_disable(p->clk);
clk_disable_unprepare(p->clk);
return 0;
}
@ -297,9 +273,7 @@ static int brcmstb_pwm_resume(struct device *dev)
{
struct brcmstb_pwm *p = dev_get_drvdata(dev);
clk_enable(p->clk);
return 0;
return clk_prepare_enable(p->clk);
}
#endif
@ -308,7 +282,6 @@ static SIMPLE_DEV_PM_OPS(brcmstb_pwm_pm_ops, brcmstb_pwm_suspend,
static struct platform_driver brcmstb_pwm_driver = {
.probe = brcmstb_pwm_probe,
.remove_new = brcmstb_pwm_remove,
.driver = {
.name = "pwm-brcmstb",
.of_match_table = brcmstb_pwm_of_match,

View File

@ -77,7 +77,6 @@ static int pwm_clk_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_clk_ops = {
.apply = pwm_clk_apply,
.owner = THIS_MODULE,
};
static int pwm_clk_probe(struct platform_device *pdev)

View File

@ -72,7 +72,6 @@ static int clps711x_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops clps711x_pwm_ops = {
.request = clps711x_pwm_request,
.apply = clps711x_pwm_apply,
.owner = THIS_MODULE,
};
static struct pwm_device *clps711x_pwm_xlate(struct pwm_chip *chip,

View File

@ -184,5 +184,8 @@ static struct platform_driver crystalcove_pwm_driver = {
.name = "crystal_cove_pwm",
},
};
module_platform_driver(crystalcove_pwm_driver);
builtin_platform_driver(crystalcove_pwm_driver);
MODULE_ALIAS("platform:crystal_cove_pwm");
MODULE_DESCRIPTION("Intel Crystalcove (CRC) PWM support");
MODULE_LICENSE("GPL");

View File

@ -22,12 +22,14 @@
* @ec: Pointer to EC device
* @chip: PWM controller chip
* @use_pwm_type: Use PWM types instead of generic channels
* @channel: array with per-channel data
*/
struct cros_ec_pwm_device {
struct device *dev;
struct cros_ec_device *ec;
struct pwm_chip chip;
bool use_pwm_type;
struct cros_ec_pwm *channel;
};
/**
@ -43,26 +45,6 @@ static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *chi
return container_of(chip, struct cros_ec_pwm_device, chip);
}
static int cros_ec_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct cros_ec_pwm *channel;
channel = kzalloc(sizeof(*channel), GFP_KERNEL);
if (!channel)
return -ENOMEM;
pwm_set_chip_data(pwm, channel);
return 0;
}
static void cros_ec_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
kfree(channel);
}
static int cros_ec_dt_type_to_pwm_type(u8 dt_index, u8 *pwm_type)
{
switch (dt_index) {
@ -158,7 +140,7 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
struct cros_ec_pwm *channel = &ec_pwm->channel[pwm->hwpwm];
u16 duty_cycle;
int ret;
@ -188,7 +170,7 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
struct cros_ec_pwm *channel = &ec_pwm->channel[pwm->hwpwm];
int ret;
ret = cros_ec_pwm_get_duty(ec_pwm, pwm->hwpwm);
@ -237,11 +219,8 @@ cros_ec_pwm_xlate(struct pwm_chip *chip, const struct of_phandle_args *args)
}
static const struct pwm_ops cros_ec_pwm_ops = {
.request = cros_ec_pwm_request,
.free = cros_ec_pwm_free,
.get_state = cros_ec_pwm_get_state,
.apply = cros_ec_pwm_apply,
.owner = THIS_MODULE,
};
/*
@ -286,10 +265,8 @@ static int cros_ec_pwm_probe(struct platform_device *pdev)
struct pwm_chip *chip;
int ret;
if (!ec) {
dev_err(dev, "no parent EC device\n");
return -EINVAL;
}
if (!ec)
return dev_err_probe(dev, -EINVAL, "no parent EC device\n");
ec_pwm = devm_kzalloc(dev, sizeof(*ec_pwm), GFP_KERNEL);
if (!ec_pwm)
@ -310,32 +287,23 @@ static int cros_ec_pwm_probe(struct platform_device *pdev)
chip->npwm = CROS_EC_PWM_DT_COUNT;
} else {
ret = cros_ec_num_pwms(ec_pwm);
if (ret < 0) {
dev_err(dev, "Couldn't find PWMs: %d\n", ret);
return ret;
}
if (ret < 0)
return dev_err_probe(dev, ret, "Couldn't find PWMs\n");
chip->npwm = ret;
}
ec_pwm->channel = devm_kcalloc(dev, chip->npwm, sizeof(*ec_pwm->channel),
GFP_KERNEL);
if (!ec_pwm->channel)
return -ENOMEM;
dev_dbg(dev, "Probed %u PWMs\n", chip->npwm);
ret = pwmchip_add(chip);
if (ret < 0) {
dev_err(dev, "cannot register PWM: %d\n", ret);
return ret;
}
ret = devm_pwmchip_add(dev, chip);
if (ret < 0)
return dev_err_probe(dev, ret, "cannot register PWM\n");
platform_set_drvdata(pdev, ec_pwm);
return ret;
}
static void cros_ec_pwm_remove(struct platform_device *dev)
{
struct cros_ec_pwm_device *ec_pwm = platform_get_drvdata(dev);
struct pwm_chip *chip = &ec_pwm->chip;
pwmchip_remove(chip);
return 0;
}
#ifdef CONFIG_OF
@ -349,7 +317,6 @@ MODULE_DEVICE_TABLE(of, cros_ec_pwm_of_match);
static struct platform_driver cros_ec_pwm_driver = {
.probe = cros_ec_pwm_probe,
.remove_new = cros_ec_pwm_remove,
.driver = {
.name = "cros-ec-pwm",
.of_match_table = of_match_ptr(cros_ec_pwm_of_match),

184
drivers/pwm/pwm-dwc-core.c Normal file
View File

@ -0,0 +1,184 @@
// SPDX-License-Identifier: GPL-2.0
/*
* DesignWare PWM Controller driver core
*
* Copyright (C) 2018-2020 Intel Corporation
*
* Author: Felipe Balbi (Intel)
* Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
* Author: Raymond Tan <raymond.tan@intel.com>
*/
#define DEFAULT_SYMBOL_NAMESPACE dwc_pwm
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
#include "pwm-dwc.h"
static void __dwc_pwm_set_enable(struct dwc_pwm *dwc, int pwm, int enabled)
{
u32 reg;
reg = dwc_pwm_readl(dwc, DWC_TIM_CTRL(pwm));
if (enabled)
reg |= DWC_TIM_CTRL_EN;
else
reg &= ~DWC_TIM_CTRL_EN;
dwc_pwm_writel(dwc, reg, DWC_TIM_CTRL(pwm));
}
static int __dwc_pwm_configure_timer(struct dwc_pwm *dwc,
struct pwm_device *pwm,
const struct pwm_state *state)
{
u64 tmp;
u32 ctrl;
u32 high;
u32 low;
/*
* Calculate width of low and high period in terms of input clock
* periods and check are the result within HW limits between 1 and
* 2^32 periods.
*/
tmp = DIV_ROUND_CLOSEST_ULL(state->duty_cycle, dwc->clk_ns);
if (tmp < 1 || tmp > (1ULL << 32))
return -ERANGE;
low = tmp - 1;
tmp = DIV_ROUND_CLOSEST_ULL(state->period - state->duty_cycle,
dwc->clk_ns);
if (tmp < 1 || tmp > (1ULL << 32))
return -ERANGE;
high = tmp - 1;
/*
* Specification says timer usage flow is to disable timer, then
* program it followed by enable. It also says Load Count is loaded
* into timer after it is enabled - either after a disable or
* a reset. Based on measurements it happens also without disable
* whenever Load Count is updated. But follow the specification.
*/
__dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
/*
* Write Load Count and Load Count 2 registers. Former defines the
* width of low period and latter the width of high period in terms
* multiple of input clock periods:
* Width = ((Count + 1) * input clock period).
*/
dwc_pwm_writel(dwc, low, DWC_TIM_LD_CNT(pwm->hwpwm));
dwc_pwm_writel(dwc, high, DWC_TIM_LD_CNT2(pwm->hwpwm));
/*
* Set user-defined mode, timer reloads from Load Count registers
* when it counts down to 0.
* Set PWM mode, it makes output to toggle and width of low and high
* periods are set by Load Count registers.
*/
ctrl = DWC_TIM_CTRL_MODE_USER | DWC_TIM_CTRL_PWM;
dwc_pwm_writel(dwc, ctrl, DWC_TIM_CTRL(pwm->hwpwm));
/*
* Enable timer. Output starts from low period.
*/
__dwc_pwm_set_enable(dwc, pwm->hwpwm, state->enabled);
return 0;
}
static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct dwc_pwm *dwc = to_dwc_pwm(chip);
if (state->polarity != PWM_POLARITY_INVERSED)
return -EINVAL;
if (state->enabled) {
if (!pwm->state.enabled)
pm_runtime_get_sync(chip->dev);
return __dwc_pwm_configure_timer(dwc, pwm, state);
} else {
if (pwm->state.enabled) {
__dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
pm_runtime_put_sync(chip->dev);
}
}
return 0;
}
static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct dwc_pwm *dwc = to_dwc_pwm(chip);
u64 duty, period;
u32 ctrl, ld, ld2;
pm_runtime_get_sync(chip->dev);
ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(pwm->hwpwm));
ld = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(pwm->hwpwm));
ld2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(pwm->hwpwm));
state->enabled = !!(ctrl & DWC_TIM_CTRL_EN);
/*
* If we're not in PWM, technically the output is a 50-50
* based on the timer load-count only.
*/
if (ctrl & DWC_TIM_CTRL_PWM) {
duty = (ld + 1) * dwc->clk_ns;
period = (ld2 + 1) * dwc->clk_ns;
period += duty;
} else {
duty = (ld + 1) * dwc->clk_ns;
period = duty * 2;
}
state->polarity = PWM_POLARITY_INVERSED;
state->period = period;
state->duty_cycle = duty;
pm_runtime_put_sync(chip->dev);
return 0;
}
static const struct pwm_ops dwc_pwm_ops = {
.apply = dwc_pwm_apply,
.get_state = dwc_pwm_get_state,
};
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->clk_ns = 10;
dwc->chip.dev = dev;
dwc->chip.ops = &dwc_pwm_ops;
dwc->chip.npwm = DWC_TIMERS_TOTAL;
dev_set_drvdata(dev, dwc);
return dwc;
}
EXPORT_SYMBOL_GPL(dwc_pwm_alloc);
MODULE_AUTHOR("Felipe Balbi (Intel)");
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
MODULE_DESCRIPTION("DesignWare PWM Controller");
MODULE_LICENSE("GPL");

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* DesignWare PWM Controller driver
* DesignWare PWM Controller driver (PCI part)
*
* Copyright (C) 2018-2020 Intel Corporation
*
@ -13,6 +13,8 @@
* periods are one or more input clock periods long.
*/
#define DEFAULT_MOUDLE_NAMESPACE dwc_pwm
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/kernel.h>
@ -21,198 +23,7 @@
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
#define DWC_TIM_LD_CNT(n) ((n) * 0x14)
#define DWC_TIM_LD_CNT2(n) (((n) * 4) + 0xb0)
#define DWC_TIM_CUR_VAL(n) (((n) * 0x14) + 0x04)
#define DWC_TIM_CTRL(n) (((n) * 0x14) + 0x08)
#define DWC_TIM_EOI(n) (((n) * 0x14) + 0x0c)
#define DWC_TIM_INT_STS(n) (((n) * 0x14) + 0x10)
#define DWC_TIMERS_INT_STS 0xa0
#define DWC_TIMERS_EOI 0xa4
#define DWC_TIMERS_RAW_INT_STS 0xa8
#define DWC_TIMERS_COMP_VERSION 0xac
#define DWC_TIMERS_TOTAL 8
#define DWC_CLK_PERIOD_NS 10
/* Timer Control Register */
#define DWC_TIM_CTRL_EN BIT(0)
#define DWC_TIM_CTRL_MODE BIT(1)
#define DWC_TIM_CTRL_MODE_FREE (0 << 1)
#define DWC_TIM_CTRL_MODE_USER (1 << 1)
#define DWC_TIM_CTRL_INT_MASK BIT(2)
#define DWC_TIM_CTRL_PWM BIT(3)
struct dwc_pwm_ctx {
u32 cnt;
u32 cnt2;
u32 ctrl;
};
struct dwc_pwm {
struct pwm_chip chip;
void __iomem *base;
struct dwc_pwm_ctx ctx[DWC_TIMERS_TOTAL];
};
#define to_dwc_pwm(p) (container_of((p), struct dwc_pwm, chip))
static inline u32 dwc_pwm_readl(struct dwc_pwm *dwc, u32 offset)
{
return readl(dwc->base + offset);
}
static inline void dwc_pwm_writel(struct dwc_pwm *dwc, u32 value, u32 offset)
{
writel(value, dwc->base + offset);
}
static void __dwc_pwm_set_enable(struct dwc_pwm *dwc, int pwm, int enabled)
{
u32 reg;
reg = dwc_pwm_readl(dwc, DWC_TIM_CTRL(pwm));
if (enabled)
reg |= DWC_TIM_CTRL_EN;
else
reg &= ~DWC_TIM_CTRL_EN;
dwc_pwm_writel(dwc, reg, DWC_TIM_CTRL(pwm));
}
static int __dwc_pwm_configure_timer(struct dwc_pwm *dwc,
struct pwm_device *pwm,
const struct pwm_state *state)
{
u64 tmp;
u32 ctrl;
u32 high;
u32 low;
/*
* Calculate width of low and high period in terms of input clock
* periods and check are the result within HW limits between 1 and
* 2^32 periods.
*/
tmp = DIV_ROUND_CLOSEST_ULL(state->duty_cycle, DWC_CLK_PERIOD_NS);
if (tmp < 1 || tmp > (1ULL << 32))
return -ERANGE;
low = tmp - 1;
tmp = DIV_ROUND_CLOSEST_ULL(state->period - state->duty_cycle,
DWC_CLK_PERIOD_NS);
if (tmp < 1 || tmp > (1ULL << 32))
return -ERANGE;
high = tmp - 1;
/*
* Specification says timer usage flow is to disable timer, then
* program it followed by enable. It also says Load Count is loaded
* into timer after it is enabled - either after a disable or
* a reset. Based on measurements it happens also without disable
* whenever Load Count is updated. But follow the specification.
*/
__dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
/*
* Write Load Count and Load Count 2 registers. Former defines the
* width of low period and latter the width of high period in terms
* multiple of input clock periods:
* Width = ((Count + 1) * input clock period).
*/
dwc_pwm_writel(dwc, low, DWC_TIM_LD_CNT(pwm->hwpwm));
dwc_pwm_writel(dwc, high, DWC_TIM_LD_CNT2(pwm->hwpwm));
/*
* Set user-defined mode, timer reloads from Load Count registers
* when it counts down to 0.
* Set PWM mode, it makes output to toggle and width of low and high
* periods are set by Load Count registers.
*/
ctrl = DWC_TIM_CTRL_MODE_USER | DWC_TIM_CTRL_PWM;
dwc_pwm_writel(dwc, ctrl, DWC_TIM_CTRL(pwm->hwpwm));
/*
* Enable timer. Output starts from low period.
*/
__dwc_pwm_set_enable(dwc, pwm->hwpwm, state->enabled);
return 0;
}
static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct dwc_pwm *dwc = to_dwc_pwm(chip);
if (state->polarity != PWM_POLARITY_INVERSED)
return -EINVAL;
if (state->enabled) {
if (!pwm->state.enabled)
pm_runtime_get_sync(chip->dev);
return __dwc_pwm_configure_timer(dwc, pwm, state);
} else {
if (pwm->state.enabled) {
__dwc_pwm_set_enable(dwc, pwm->hwpwm, false);
pm_runtime_put_sync(chip->dev);
}
}
return 0;
}
static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct dwc_pwm *dwc = to_dwc_pwm(chip);
u64 duty, period;
pm_runtime_get_sync(chip->dev);
state->enabled = !!(dwc_pwm_readl(dwc,
DWC_TIM_CTRL(pwm->hwpwm)) & DWC_TIM_CTRL_EN);
duty = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(pwm->hwpwm));
duty += 1;
duty *= DWC_CLK_PERIOD_NS;
state->duty_cycle = duty;
period = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(pwm->hwpwm));
period += 1;
period *= DWC_CLK_PERIOD_NS;
period += duty;
state->period = period;
state->polarity = PWM_POLARITY_INVERSED;
pm_runtime_put_sync(chip->dev);
return 0;
}
static const struct pwm_ops dwc_pwm_ops = {
.apply = dwc_pwm_apply,
.get_state = dwc_pwm_get_state,
.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;
}
#include "pwm-dwc.h"
static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
{

60
drivers/pwm/pwm-dwc.h Normal file
View File

@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0
/*
* DesignWare PWM Controller driver
*
* Copyright (C) 2018-2020 Intel Corporation
*
* Author: Felipe Balbi (Intel)
* Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
* Author: Raymond Tan <raymond.tan@intel.com>
*/
MODULE_IMPORT_NS(dwc_pwm);
#define DWC_TIM_LD_CNT(n) ((n) * 0x14)
#define DWC_TIM_LD_CNT2(n) (((n) * 4) + 0xb0)
#define DWC_TIM_CUR_VAL(n) (((n) * 0x14) + 0x04)
#define DWC_TIM_CTRL(n) (((n) * 0x14) + 0x08)
#define DWC_TIM_EOI(n) (((n) * 0x14) + 0x0c)
#define DWC_TIM_INT_STS(n) (((n) * 0x14) + 0x10)
#define DWC_TIMERS_INT_STS 0xa0
#define DWC_TIMERS_EOI 0xa4
#define DWC_TIMERS_RAW_INT_STS 0xa8
#define DWC_TIMERS_COMP_VERSION 0xac
#define DWC_TIMERS_TOTAL 8
/* Timer Control Register */
#define DWC_TIM_CTRL_EN BIT(0)
#define DWC_TIM_CTRL_MODE BIT(1)
#define DWC_TIM_CTRL_MODE_FREE (0 << 1)
#define DWC_TIM_CTRL_MODE_USER (1 << 1)
#define DWC_TIM_CTRL_INT_MASK BIT(2)
#define DWC_TIM_CTRL_PWM BIT(3)
struct dwc_pwm_ctx {
u32 cnt;
u32 cnt2;
u32 ctrl;
};
struct dwc_pwm {
struct pwm_chip chip;
void __iomem *base;
unsigned int clk_ns;
struct dwc_pwm_ctx ctx[DWC_TIMERS_TOTAL];
};
#define to_dwc_pwm(p) (container_of((p), struct dwc_pwm, chip))
static inline u32 dwc_pwm_readl(struct dwc_pwm *dwc, u32 offset)
{
return readl(dwc->base + offset);
}
static inline void dwc_pwm_writel(struct dwc_pwm *dwc, u32 value, u32 offset)
{
writel(value, dwc->base + offset);
}
extern struct dwc_pwm *dwc_pwm_alloc(struct device *dev);

View File

@ -159,7 +159,6 @@ static const struct pwm_ops ep93xx_pwm_ops = {
.request = ep93xx_pwm_request,
.free = ep93xx_pwm_free,
.apply = ep93xx_pwm_apply,
.owner = THIS_MODULE,
};
static int ep93xx_pwm_probe(struct platform_device *pdev)

View File

@ -350,7 +350,6 @@ static const struct pwm_ops fsl_pwm_ops = {
.request = fsl_pwm_request,
.free = fsl_pwm_free,
.apply = fsl_pwm_apply,
.owner = THIS_MODULE,
};
static int fsl_pwm_init(struct fsl_pwm_chip *fpc)

View File

@ -185,7 +185,6 @@ static const struct pwm_ops hibvt_pwm_ops = {
.get_state = hibvt_pwm_get_state,
.apply = hibvt_pwm_apply,
.owner = THIS_MODULE,
};
static int hibvt_pwm_probe(struct platform_device *pdev)

View File

@ -208,7 +208,6 @@ static int img_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops img_pwm_ops = {
.apply = img_pwm_apply,
.owner = THIS_MODULE,
};
static const struct img_pwm_soc_data pistachio_pwm = {

View File

@ -332,7 +332,6 @@ static const struct pwm_ops imx_tpm_pwm_ops = {
.free = pwm_imx_tpm_free,
.get_state = pwm_imx_tpm_get_state,
.apply = pwm_imx_tpm_apply,
.owner = THIS_MODULE,
};
static int pwm_imx_tpm_probe(struct platform_device *pdev)
@ -351,18 +350,11 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
if (IS_ERR(tpm->base))
return PTR_ERR(tpm->base);
tpm->clk = devm_clk_get(&pdev->dev, NULL);
tpm->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(tpm->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(tpm->clk),
"failed to get PWM clock\n");
ret = clk_prepare_enable(tpm->clk);
if (ret) {
dev_err(&pdev->dev,
"failed to prepare or enable clock: %d\n", ret);
return ret;
}
tpm->chip.dev = &pdev->dev;
tpm->chip.ops = &imx_tpm_pwm_ops;
@ -372,22 +364,11 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
mutex_init(&tpm->lock);
ret = pwmchip_add(&tpm->chip);
if (ret) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
clk_disable_unprepare(tpm->clk);
}
ret = devm_pwmchip_add(&pdev->dev, &tpm->chip);
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
return ret;
}
static void pwm_imx_tpm_remove(struct platform_device *pdev)
{
struct imx_tpm_pwm_chip *tpm = platform_get_drvdata(pdev);
pwmchip_remove(&tpm->chip);
clk_disable_unprepare(tpm->clk);
return 0;
}
static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev)
@ -437,7 +418,6 @@ static struct platform_driver imx_tpm_pwm_driver = {
.pm = &imx_tpm_pwm_pm,
},
.probe = pwm_imx_tpm_probe,
.remove_new = pwm_imx_tpm_remove,
};
module_platform_driver(imx_tpm_pwm_driver);

View File

@ -146,7 +146,6 @@ static int pwm_imx1_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_imx1_ops = {
.apply = pwm_imx1_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id pwm_imx1_dt_ids[] = {

View File

@ -296,7 +296,6 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_imx27_ops = {
.apply = pwm_imx27_apply,
.get_state = pwm_imx27_get_state,
.owner = THIS_MODULE,
};
static const struct of_device_id pwm_imx27_dt_ids[] = {

View File

@ -107,7 +107,6 @@ static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops lgm_pwm_ops = {
.get_state = lgm_pwm_get_state,
.apply = lgm_pwm_apply,
.owner = THIS_MODULE,
};
static void lgm_pwm_init(struct lgm_pwm_chip *pc)

View File

@ -166,7 +166,6 @@ static int iqs620_pwm_notifier(struct notifier_block *notifier,
static const struct pwm_ops iqs620_pwm_ops = {
.apply = iqs620_pwm_apply,
.get_state = iqs620_pwm_get_state,
.owner = THIS_MODULE,
};
static void iqs620_pwm_notifier_unregister(void *context)

View File

@ -27,6 +27,7 @@ struct soc_info {
struct jz4740_pwm_chip {
struct pwm_chip chip;
struct regmap *map;
struct clk *clk[];
};
static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
@ -70,14 +71,15 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
return err;
}
pwm_set_chip_data(pwm, clk);
jz->clk[pwm->hwpwm] = clk;
return 0;
}
static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct clk *clk = pwm_get_chip_data(pwm);
struct jz4740_pwm_chip *jz = to_jz4740(chip);
struct clk *clk = jz->clk[pwm->hwpwm];
clk_disable_unprepare(clk);
clk_put(clk);
@ -121,9 +123,9 @@ static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
struct jz4740_pwm_chip *jz = to_jz4740(pwm->chip);
unsigned long long tmp = 0xffffull * NSEC_PER_SEC;
struct clk *clk = pwm_get_chip_data(pwm);
struct clk *clk = jz->clk[pwm->hwpwm];
unsigned long period, duty;
long rate;
int err;
@ -173,16 +175,16 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
}
/* Reset counter to 0 */
regmap_write(jz4740->map, TCU_REG_TCNTc(pwm->hwpwm), 0);
regmap_write(jz->map, TCU_REG_TCNTc(pwm->hwpwm), 0);
/* Set duty */
regmap_write(jz4740->map, TCU_REG_TDHRc(pwm->hwpwm), duty);
regmap_write(jz->map, TCU_REG_TDHRc(pwm->hwpwm), duty);
/* Set period */
regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
regmap_write(jz->map, TCU_REG_TDFRc(pwm->hwpwm), period);
/* Set abrupt shutdown */
regmap_set_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
regmap_set_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_SD);
/*
@ -199,10 +201,10 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
* state instead of its inactive state.
*/
if ((state->polarity == PWM_POLARITY_NORMAL) ^ state->enabled)
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_INITL_HIGH, 0);
else
regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
TCU_TCSR_PWM_INITL_HIGH,
TCU_TCSR_PWM_INITL_HIGH);
@ -216,34 +218,34 @@ static const struct pwm_ops jz4740_pwm_ops = {
.request = jz4740_pwm_request,
.free = jz4740_pwm_free,
.apply = jz4740_pwm_apply,
.owner = THIS_MODULE,
};
static int jz4740_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct jz4740_pwm_chip *jz4740;
struct jz4740_pwm_chip *jz;
const struct soc_info *info;
info = device_get_match_data(dev);
if (!info)
return -EINVAL;
jz4740 = devm_kzalloc(dev, sizeof(*jz4740), GFP_KERNEL);
if (!jz4740)
jz = devm_kzalloc(dev, struct_size(jz, clk, info->num_pwms),
GFP_KERNEL);
if (!jz)
return -ENOMEM;
jz4740->map = device_node_to_regmap(dev->parent->of_node);
if (IS_ERR(jz4740->map)) {
dev_err(dev, "regmap not found: %ld\n", PTR_ERR(jz4740->map));
return PTR_ERR(jz4740->map);
jz->map = device_node_to_regmap(dev->parent->of_node);
if (IS_ERR(jz->map)) {
dev_err(dev, "regmap not found: %ld\n", PTR_ERR(jz->map));
return PTR_ERR(jz->map);
}
jz4740->chip.dev = dev;
jz4740->chip.ops = &jz4740_pwm_ops;
jz4740->chip.npwm = info->num_pwms;
jz->chip.dev = dev;
jz->chip.ops = &jz4740_pwm_ops;
jz->chip.npwm = info->num_pwms;
return devm_pwmchip_add(dev, &jz4740->chip);
return devm_pwmchip_add(dev, &jz->chip);
}
static const struct soc_info jz4740_soc_info = {

View File

@ -178,7 +178,6 @@ static int keembay_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
}
static const struct pwm_ops keembay_pwm_ops = {
.owner = THIS_MODULE,
.apply = keembay_pwm_apply,
.get_state = keembay_pwm_get_state,
};

View File

@ -23,6 +23,7 @@ struct lp3943_pwm {
struct pwm_chip chip;
struct lp3943 *lp3943;
struct lp3943_platform_data *pdata;
struct lp3943_pwm_map pwm_map[LP3943_NUM_PWMS];
};
static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *chip)
@ -35,13 +36,9 @@ lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
{
struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
struct lp3943 *lp3943 = lp3943_pwm->lp3943;
struct lp3943_pwm_map *pwm_map;
struct lp3943_pwm_map *pwm_map = &lp3943_pwm->pwm_map[hwpwm];
int i, offset;
pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
if (!pwm_map)
return ERR_PTR(-ENOMEM);
pwm_map->output = pdata->pwms[hwpwm]->output;
pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
@ -49,10 +46,8 @@ lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
offset = pwm_map->output[i];
/* Return an error if the pin is already assigned */
if (test_and_set_bit(offset, &lp3943->pin_used)) {
kfree(pwm_map);
if (test_and_set_bit(offset, &lp3943->pin_used))
return ERR_PTR(-EBUSY);
}
}
return pwm_map;
@ -67,7 +62,7 @@ static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
if (IS_ERR(pwm_map))
return PTR_ERR(pwm_map);
return pwm_set_chip_data(pwm, pwm_map);
return 0;
}
static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
@ -80,14 +75,12 @@ static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
offset = pwm_map->output[i];
clear_bit(offset, &lp3943->pin_used);
}
kfree(pwm_map);
}
static void lp3943_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
struct lp3943_pwm_map *pwm_map = &lp3943_pwm->pwm_map[pwm->hwpwm];
lp3943_pwm_free_map(lp3943_pwm, pwm_map);
}
@ -159,7 +152,7 @@ static int lp3943_pwm_set_mode(struct lp3943_pwm *lp3943_pwm,
static int lp3943_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
struct lp3943_pwm_map *pwm_map = &lp3943_pwm->pwm_map[pwm->hwpwm];
u8 val;
if (pwm->hwpwm == 0)
@ -178,7 +171,7 @@ static int lp3943_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
static void lp3943_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
struct lp3943_pwm_map *pwm_map = &lp3943_pwm->pwm_map[pwm->hwpwm];
/*
* LP3943 outputs are open-drain, so the pin should be configured
@ -216,7 +209,6 @@ static const struct pwm_ops lp3943_pwm_ops = {
.request = lp3943_pwm_request,
.free = lp3943_pwm_free,
.apply = lp3943_pwm_apply,
.owner = THIS_MODULE,
};
static int lp3943_pwm_parse_dt(struct device *dev,

View File

@ -341,7 +341,6 @@ static const struct pwm_ops lpc18xx_pwm_ops = {
.apply = lpc18xx_pwm_apply,
.request = lpc18xx_pwm_request,
.free = lpc18xx_pwm_free,
.owner = THIS_MODULE,
};
static const struct of_device_id lpc18xx_pwm_of_match[] = {

View File

@ -115,7 +115,6 @@ static int lpc32xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops lpc32xx_pwm_ops = {
.apply = lpc32xx_pwm_apply,
.owner = THIS_MODULE,
};
static int lpc32xx_pwm_probe(struct platform_device *pdev)

View File

@ -243,7 +243,6 @@ static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_lpss_ops = {
.apply = pwm_lpss_apply,
.get_state = pwm_lpss_get_state,
.owner = THIS_MODULE,
};
struct pwm_lpss_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base,

View File

@ -229,7 +229,6 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_mediatek_ops = {
.apply = pwm_mediatek_apply,
.owner = THIS_MODULE,
};
static int pwm_mediatek_probe(struct platform_device *pdev)

View File

@ -335,7 +335,6 @@ static const struct pwm_ops meson_pwm_ops = {
.free = meson_pwm_free,
.apply = meson_pwm_apply,
.get_state = meson_pwm_get_state,
.owner = THIS_MODULE,
};
static const char * const pwm_meson8b_parent_names[] = {

View File

@ -435,7 +435,6 @@ static int mchp_core_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm
static const struct pwm_ops mchp_core_pwm_ops = {
.apply = mchp_core_pwm_apply,
.get_state = mchp_core_pwm_get_state,
.owner = THIS_MODULE,
};
static const struct of_device_id mchp_core_of_match[] = {

View File

@ -227,7 +227,6 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
static const struct pwm_ops mtk_disp_pwm_ops = {
.apply = mtk_disp_pwm_apply,
.get_state = mtk_disp_pwm_get_state,
.owner = THIS_MODULE,
};
static int mtk_disp_pwm_probe(struct platform_device *pdev)
@ -247,34 +246,25 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
mdp->clk_main = devm_clk_get(&pdev->dev, "main");
if (IS_ERR(mdp->clk_main))
return PTR_ERR(mdp->clk_main);
return dev_err_probe(&pdev->dev, PTR_ERR(mdp->clk_main),
"Failed to get main clock\n");
mdp->clk_mm = devm_clk_get(&pdev->dev, "mm");
if (IS_ERR(mdp->clk_mm))
return PTR_ERR(mdp->clk_mm);
return dev_err_probe(&pdev->dev, PTR_ERR(mdp->clk_mm),
"Failed to get mm clock\n");
mdp->chip.dev = &pdev->dev;
mdp->chip.ops = &mtk_disp_pwm_ops;
mdp->chip.npwm = 1;
ret = pwmchip_add(&mdp->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
return ret;
}
platform_set_drvdata(pdev, mdp);
ret = devm_pwmchip_add(&pdev->dev, &mdp->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
return 0;
}
static void mtk_disp_pwm_remove(struct platform_device *pdev)
{
struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
pwmchip_remove(&mdp->chip);
}
static const struct mtk_pwm_data mt2701_pwm_data = {
.enable_mask = BIT(16),
.con0 = 0xa8,
@ -320,7 +310,6 @@ static struct platform_driver mtk_disp_pwm_driver = {
.of_match_table = mtk_disp_pwm_of_match,
},
.probe = mtk_disp_pwm_probe,
.remove_new = mtk_disp_pwm_remove,
};
module_platform_driver(mtk_disp_pwm_driver);

View File

@ -115,7 +115,6 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops mxs_pwm_ops = {
.apply = mxs_pwm_apply,
.owner = THIS_MODULE,
};
static int mxs_pwm_probe(struct platform_device *pdev)

View File

@ -126,7 +126,6 @@ static int ntxec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm_dev,
}
static const struct pwm_ops ntxec_pwm_ops = {
.owner = THIS_MODULE,
.apply = ntxec_pwm_apply,
/*
* No .get_state callback, because the current state cannot be read

View File

@ -311,7 +311,6 @@ unlock_mutex:
static const struct pwm_ops pwm_omap_dmtimer_ops = {
.apply = pwm_omap_dmtimer_apply,
.owner = THIS_MODULE,
};
static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
@ -466,7 +465,7 @@ MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match);
static struct platform_driver pwm_omap_dmtimer_driver = {
.driver = {
.name = "omap-dmtimer-pwm",
.of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match),
.of_match_table = pwm_omap_dmtimer_of_match,
},
.probe = pwm_omap_dmtimer_probe,
.remove_new = pwm_omap_dmtimer_remove,

View File

@ -505,7 +505,6 @@ static const struct pwm_ops pca9685_pwm_ops = {
.get_state = pca9685_pwm_get_state,
.request = pca9685_pwm_request,
.free = pca9685_pwm_free,
.owner = THIS_MODULE,
};
static const struct regmap_config pca9685_regmap_i2c_config = {

View File

@ -24,7 +24,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <asm/div64.h>
@ -135,7 +135,6 @@ static int pxa_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pxa_pwm_ops = {
.apply = pxa_pwm_apply,
.owner = THIS_MODULE,
};
#ifdef CONFIG_OF

View File

@ -135,7 +135,6 @@ static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops raspberrypi_pwm_ops = {
.get_state = raspberrypi_pwm_get_state,
.apply = raspberrypi_pwm_apply,
.owner = THIS_MODULE,
};
static int raspberrypi_pwm_probe(struct platform_device *pdev)

View File

@ -198,7 +198,6 @@ static const struct pwm_ops rcar_pwm_ops = {
.request = rcar_pwm_request,
.free = rcar_pwm_free,
.apply = rcar_pwm_apply,
.owner = THIS_MODULE,
};
static int rcar_pwm_probe(struct platform_device *pdev)

View File

@ -85,6 +85,7 @@ struct tpu_device {
void __iomem *base;
struct clk *clk;
struct tpu_pwm_device tpd[TPU_CHANNEL_MAX];
};
#define to_tpu_device(c) container_of(c, struct tpu_device, chip)
@ -215,9 +216,7 @@ static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
if (pwm->hwpwm >= TPU_CHANNEL_MAX)
return -EINVAL;
tpd = kzalloc(sizeof(*tpd), GFP_KERNEL);
if (tpd == NULL)
return -ENOMEM;
tpd = &tpu->tpd[pwm->hwpwm];
tpd->tpu = tpu;
tpd->channel = pwm->hwpwm;
@ -228,24 +227,22 @@ static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
tpd->timer_on = false;
pwm_set_chip_data(pwm, tpd);
return 0;
}
static void tpu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct tpu_pwm_device *tpd = pwm_get_chip_data(pwm);
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
tpu_pwm_timer_stop(tpd);
kfree(tpd);
}
static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u64 duty_ns, u64 period_ns, bool enabled)
{
struct tpu_pwm_device *tpd = pwm_get_chip_data(pwm);
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
unsigned int prescaler;
bool duty_only = false;
u32 clk_rate;
@ -353,7 +350,8 @@ static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
static int tpu_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
enum pwm_polarity polarity)
{
struct tpu_pwm_device *tpd = pwm_get_chip_data(pwm);
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
tpd->polarity = polarity;
@ -362,7 +360,8 @@ static int tpu_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct tpu_pwm_device *tpd = pwm_get_chip_data(pwm);
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
int ret;
ret = tpu_pwm_timer_start(tpd);
@ -384,7 +383,8 @@ static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct tpu_pwm_device *tpd = pwm_get_chip_data(pwm);
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
/* The timer must be running to modify the pin output configuration. */
tpu_pwm_timer_start(tpd);
@ -431,7 +431,6 @@ static const struct pwm_ops tpu_pwm_ops = {
.request = tpu_pwm_request,
.free = tpu_pwm_free,
.apply = tpu_pwm_apply,
.owner = THIS_MODULE,
};
/* -----------------------------------------------------------------------------

View File

@ -228,7 +228,6 @@ out:
static const struct pwm_ops rockchip_pwm_ops = {
.get_state = rockchip_pwm_get_state,
.apply = rockchip_pwm_apply,
.owner = THIS_MODULE,
};
static const struct rockchip_pwm_data pwm_data_v1 = {

View File

@ -438,7 +438,6 @@ static const struct pwm_ops rz_mtu3_pwm_ops = {
.free = rz_mtu3_pwm_free,
.get_state = rz_mtu3_pwm_get_state,
.apply = rz_mtu3_pwm_apply,
.owner = THIS_MODULE,
};
static int rz_mtu3_pwm_pm_runtime_suspend(struct device *dev)

View File

@ -77,6 +77,7 @@ struct samsung_pwm_channel {
* @base_clk: base clock used to drive the timers
* @tclk0: external clock 0 (can be ERR_PTR if not present)
* @tclk1: external clock 1 (can be ERR_PTR if not present)
* @channel: per channel driver data
*/
struct samsung_pwm_chip {
struct pwm_chip chip;
@ -88,6 +89,7 @@ struct samsung_pwm_chip {
struct clk *base_clk;
struct clk *tclk0;
struct clk *tclk1;
struct samsung_pwm_channel channel[SAMSUNG_PWM_NUM];
};
#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
@ -117,21 +119,21 @@ static inline unsigned int to_tcon_channel(unsigned int channel)
return (channel == 0) ? 0 : (channel + 1);
}
static void __pwm_samsung_manual_update(struct samsung_pwm_chip *chip,
static void __pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip,
struct pwm_device *pwm)
{
unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
u32 tcon;
tcon = readl(chip->base + REG_TCON);
tcon = readl(our_chip->base + REG_TCON);
tcon |= TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
writel(tcon, our_chip->base + REG_TCON);
tcon &= ~TCON_MANUALUPDATE(tcon_chan);
writel(tcon, chip->base + REG_TCON);
writel(tcon, our_chip->base + REG_TCON);
}
static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
static void pwm_samsung_set_divisor(struct samsung_pwm_chip *our_chip,
unsigned int channel, u8 divisor)
{
u8 shift = TCFG1_SHIFT(channel);
@ -139,39 +141,39 @@ static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
u32 reg;
u8 bits;
bits = (fls(divisor) - 1) - pwm->variant.div_base;
bits = (fls(divisor) - 1) - our_chip->variant.div_base;
spin_lock_irqsave(&samsung_pwm_lock, flags);
reg = readl(pwm->base + REG_TCFG1);
reg = readl(our_chip->base + REG_TCFG1);
reg &= ~(TCFG1_MUX_MASK << shift);
reg |= bits << shift;
writel(reg, pwm->base + REG_TCFG1);
writel(reg, our_chip->base + REG_TCFG1);
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
}
static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *our_chip, unsigned int chan)
{
struct samsung_pwm_variant *variant = &chip->variant;
struct samsung_pwm_variant *variant = &our_chip->variant;
u32 reg;
reg = readl(chip->base + REG_TCFG1);
reg = readl(our_chip->base + REG_TCFG1);
reg >>= TCFG1_SHIFT(chan);
reg &= TCFG1_MUX_MASK;
return (BIT(reg) & variant->tclk_mask) == 0;
}
static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *our_chip,
unsigned int chan)
{
unsigned long rate;
u32 reg;
rate = clk_get_rate(chip->base_clk);
rate = clk_get_rate(our_chip->base_clk);
reg = readl(chip->base + REG_TCFG0);
reg = readl(our_chip->base + REG_TCFG0);
if (chan >= 2)
reg >>= TCFG0_PRESCALER1_SHIFT;
reg &= TCFG0_PRESCALER_MASK;
@ -179,28 +181,28 @@ static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
return rate / (reg + 1);
}
static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *our_chip,
unsigned int chan, unsigned long freq)
{
struct samsung_pwm_variant *variant = &chip->variant;
struct samsung_pwm_variant *variant = &our_chip->variant;
unsigned long rate;
struct clk *clk;
u8 div;
if (!pwm_samsung_is_tdiv(chip, chan)) {
clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
if (!pwm_samsung_is_tdiv(our_chip, chan)) {
clk = (chan < 2) ? our_chip->tclk0 : our_chip->tclk1;
if (!IS_ERR(clk)) {
rate = clk_get_rate(clk);
if (rate)
return rate;
}
dev_warn(chip->chip.dev,
dev_warn(our_chip->chip.dev,
"tclk of PWM %d is inoperational, using tdiv\n", chan);
}
rate = pwm_samsung_get_tin_rate(chip, chan);
dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
rate = pwm_samsung_get_tin_rate(our_chip, chan);
dev_dbg(our_chip->chip.dev, "tin parent at %lu\n", rate);
/*
* Compare minimum PWM frequency that can be achieved with possible
@ -220,7 +222,7 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
div = variant->div_base;
}
pwm_samsung_set_divisor(chip, chan, BIT(div));
pwm_samsung_set_divisor(our_chip, chan, BIT(div));
return rate >> div;
}
@ -228,7 +230,6 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
struct samsung_pwm_channel *our_chan;
if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
dev_warn(chip->dev,
@ -237,20 +238,11 @@ static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
return -EINVAL;
}
our_chan = kzalloc(sizeof(*our_chan), GFP_KERNEL);
if (!our_chan)
return -ENOMEM;
pwm_set_chip_data(pwm, our_chan);
memset(&our_chip->channel[pwm->hwpwm], 0, sizeof(our_chip->channel[pwm->hwpwm]));
return 0;
}
static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
kfree(pwm_get_chip_data(pwm));
}
static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
@ -302,14 +294,14 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
}
static void pwm_samsung_manual_update(struct samsung_pwm_chip *chip,
static void pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip,
struct pwm_device *pwm)
{
unsigned long flags;
spin_lock_irqsave(&samsung_pwm_lock, flags);
__pwm_samsung_manual_update(chip, pwm);
__pwm_samsung_manual_update(our_chip, pwm);
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
}
@ -318,7 +310,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns, bool force_period)
{
struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
struct samsung_pwm_channel *chan = &our_chip->channel[pwm->hwpwm];
u32 tin_ns = chan->tin_ns, tcnt, tcmp, oldtcmp;
tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
@ -393,7 +385,7 @@ static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
return __pwm_samsung_config(chip, pwm, duty_ns, period_ns, false);
}
static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
static void pwm_samsung_set_invert(struct samsung_pwm_chip *our_chip,
unsigned int channel, bool invert)
{
unsigned int tcon_chan = to_tcon_channel(channel);
@ -402,17 +394,17 @@ static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
spin_lock_irqsave(&samsung_pwm_lock, flags);
tcon = readl(chip->base + REG_TCON);
tcon = readl(our_chip->base + REG_TCON);
if (invert) {
chip->inverter_mask |= BIT(channel);
our_chip->inverter_mask |= BIT(channel);
tcon |= TCON_INVERT(tcon_chan);
} else {
chip->inverter_mask &= ~BIT(channel);
our_chip->inverter_mask &= ~BIT(channel);
tcon &= ~TCON_INVERT(tcon_chan);
}
writel(tcon, chip->base + REG_TCON);
writel(tcon, our_chip->base + REG_TCON);
spin_unlock_irqrestore(&samsung_pwm_lock, flags);
}
@ -473,9 +465,7 @@ static int pwm_samsung_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops pwm_samsung_ops = {
.request = pwm_samsung_request,
.free = pwm_samsung_free,
.apply = pwm_samsung_apply,
.owner = THIS_MODULE,
};
#ifdef CONFIG_OF
@ -517,9 +507,9 @@ static const struct of_device_id samsung_pwm_matches[] = {
};
MODULE_DEVICE_TABLE(of, samsung_pwm_matches);
static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
{
struct device_node *np = chip->chip.dev->of_node;
struct device_node *np = our_chip->chip.dev->of_node;
const struct of_device_id *match;
struct property *prop;
const __be32 *cur;
@ -529,22 +519,22 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
if (!match)
return -ENODEV;
memcpy(&chip->variant, match->data, sizeof(chip->variant));
memcpy(&our_chip->variant, match->data, sizeof(our_chip->variant));
of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
if (val >= SAMSUNG_PWM_NUM) {
dev_err(chip->chip.dev,
dev_err(our_chip->chip.dev,
"%s: invalid channel index in samsung,pwm-outputs property\n",
__func__);
continue;
}
chip->variant.output_mask |= BIT(val);
our_chip->variant.output_mask |= BIT(val);
}
return 0;
}
#else
static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip)
{
return -ENODEV;
}
@ -553,21 +543,21 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
static int pwm_samsung_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct samsung_pwm_chip *chip;
struct samsung_pwm_chip *our_chip;
unsigned int chan;
int ret;
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
our_chip = devm_kzalloc(&pdev->dev, sizeof(*our_chip), GFP_KERNEL);
if (our_chip == NULL)
return -ENOMEM;
chip->chip.dev = &pdev->dev;
chip->chip.ops = &pwm_samsung_ops;
chip->chip.npwm = SAMSUNG_PWM_NUM;
chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
our_chip->chip.dev = &pdev->dev;
our_chip->chip.ops = &pwm_samsung_ops;
our_chip->chip.npwm = SAMSUNG_PWM_NUM;
our_chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
ret = pwm_samsung_parse_dt(chip);
ret = pwm_samsung_parse_dt(our_chip);
if (ret)
return ret;
} else {
@ -576,58 +566,58 @@ static int pwm_samsung_probe(struct platform_device *pdev)
return -EINVAL;
}
memcpy(&chip->variant, pdev->dev.platform_data,
sizeof(chip->variant));
memcpy(&our_chip->variant, pdev->dev.platform_data,
sizeof(our_chip->variant));
}
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
our_chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(our_chip->base))
return PTR_ERR(our_chip->base);
chip->base_clk = devm_clk_get(&pdev->dev, "timers");
if (IS_ERR(chip->base_clk)) {
our_chip->base_clk = devm_clk_get(&pdev->dev, "timers");
if (IS_ERR(our_chip->base_clk)) {
dev_err(dev, "failed to get timer base clk\n");
return PTR_ERR(chip->base_clk);
return PTR_ERR(our_chip->base_clk);
}
ret = clk_prepare_enable(chip->base_clk);
ret = clk_prepare_enable(our_chip->base_clk);
if (ret < 0) {
dev_err(dev, "failed to enable base clock\n");
return ret;
}
for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
if (chip->variant.output_mask & BIT(chan))
pwm_samsung_set_invert(chip, chan, true);
if (our_chip->variant.output_mask & BIT(chan))
pwm_samsung_set_invert(our_chip, chan, true);
/* Following clocks are optional. */
chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
our_chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
our_chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
platform_set_drvdata(pdev, chip);
platform_set_drvdata(pdev, our_chip);
ret = pwmchip_add(&chip->chip);
ret = pwmchip_add(&our_chip->chip);
if (ret < 0) {
dev_err(dev, "failed to register PWM chip\n");
clk_disable_unprepare(chip->base_clk);
clk_disable_unprepare(our_chip->base_clk);
return ret;
}
dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
clk_get_rate(chip->base_clk),
!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
clk_get_rate(our_chip->base_clk),
!IS_ERR(our_chip->tclk0) ? clk_get_rate(our_chip->tclk0) : 0,
!IS_ERR(our_chip->tclk1) ? clk_get_rate(our_chip->tclk1) : 0);
return 0;
}
static void pwm_samsung_remove(struct platform_device *pdev)
{
struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
struct samsung_pwm_chip *our_chip = platform_get_drvdata(pdev);
pwmchip_remove(&chip->chip);
pwmchip_remove(&our_chip->chip);
clk_disable_unprepare(chip->base_clk);
clk_disable_unprepare(our_chip->base_clk);
}
#ifdef CONFIG_PM_SLEEP
@ -639,9 +629,9 @@ static int pwm_samsung_resume(struct device *dev)
for (i = 0; i < SAMSUNG_PWM_NUM; i++) {
struct pwm_device *pwm = &chip->pwms[i];
struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
struct samsung_pwm_channel *chan = &our_chip->channel[i];
if (!chan)
if (!(pwm->flags & PWMF_REQUESTED))
continue;
if (our_chip->variant.output_mask & BIT(i))

View File

@ -203,7 +203,6 @@ static const struct pwm_ops pwm_sifive_ops = {
.free = pwm_sifive_free,
.get_state = pwm_sifive_get_state,
.apply = pwm_sifive_apply,
.owner = THIS_MODULE,
};
static int pwm_sifive_clock_notifier(struct notifier_block *nb,

View File

@ -200,7 +200,6 @@ static int sl28cpld_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops sl28cpld_pwm_ops = {
.apply = sl28cpld_pwm_apply,
.get_state = sl28cpld_pwm_get_state,
.owner = THIS_MODULE,
};
static int sl28cpld_pwm_probe(struct platform_device *pdev)

View File

@ -189,7 +189,6 @@ static int spear_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops spear_pwm_ops = {
.apply = spear_pwm_apply,
.owner = THIS_MODULE,
};
static int spear_pwm_probe(struct platform_device *pdev)
@ -207,26 +206,21 @@ static int spear_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->mmio_base))
return PTR_ERR(pc->mmio_base);
pc->clk = devm_clk_get(&pdev->dev, NULL);
pc->clk = devm_clk_get_prepared(&pdev->dev, NULL);
if (IS_ERR(pc->clk))
return PTR_ERR(pc->clk);
platform_set_drvdata(pdev, pc);
return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk),
"Failed to get clock\n");
pc->chip.dev = &pdev->dev;
pc->chip.ops = &spear_pwm_ops;
pc->chip.npwm = NUM_PWM;
ret = clk_prepare(pc->clk);
if (ret)
return ret;
if (of_device_is_compatible(np, "st,spear1340-pwm")) {
ret = clk_enable(pc->clk);
if (ret) {
clk_unprepare(pc->clk);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to enable clk\n");
/*
* Following enables PWM chip, channels would still be
* enabled individually through their control register
@ -238,23 +232,11 @@ static int spear_pwm_probe(struct platform_device *pdev)
clk_disable(pc->clk);
}
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
clk_unprepare(pc->clk);
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
}
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
return ret;
}
static void spear_pwm_remove(struct platform_device *pdev)
{
struct spear_pwm_chip *pc = platform_get_drvdata(pdev);
pwmchip_remove(&pc->chip);
/* clk was prepared in probe, hence unprepare it here */
clk_unprepare(pc->clk);
return 0;
}
static const struct of_device_id spear_pwm_of_match[] = {
@ -271,7 +253,6 @@ static struct platform_driver spear_pwm_driver = {
.of_match_table = spear_pwm_of_match,
},
.probe = spear_pwm_probe,
.remove_new = spear_pwm_remove,
};
module_platform_driver(spear_pwm_driver);

View File

@ -40,6 +40,11 @@ struct sprd_pwm_chip {
struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM];
};
static inline struct sprd_pwm_chip* sprd_pwm_from_chip(struct pwm_chip *chip)
{
return container_of(chip, struct sprd_pwm_chip, chip);
}
/*
* The list of clocks required by PWM channels, and each channel has 2 clocks:
* enable clock and pwm clock.
@ -69,8 +74,7 @@ static void sprd_pwm_write(struct sprd_pwm_chip *spc, u32 hwid,
static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct sprd_pwm_chip *spc =
container_of(chip, struct sprd_pwm_chip, chip);
struct sprd_pwm_chip *spc = sprd_pwm_from_chip(chip);
struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm];
u32 val, duty, prescale;
u64 tmp;
@ -162,8 +166,7 @@ static int sprd_pwm_config(struct sprd_pwm_chip *spc, struct pwm_device *pwm,
static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct sprd_pwm_chip *spc =
container_of(chip, struct sprd_pwm_chip, chip);
struct sprd_pwm_chip *spc = sprd_pwm_from_chip(chip);
struct sprd_pwm_chn *chn = &spc->chn[pwm->hwpwm];
struct pwm_state *cstate = &pwm->state;
int ret;
@ -210,7 +213,6 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops sprd_pwm_ops = {
.apply = sprd_pwm_apply,
.get_state = sprd_pwm_get_state,
.owner = THIS_MODULE,
};
static int sprd_pwm_clk_init(struct sprd_pwm_chip *spc)
@ -240,10 +242,8 @@ static int sprd_pwm_clk_init(struct sprd_pwm_chip *spc)
chn->clk_rate = clk_get_rate(clk_pwm);
}
if (!i) {
dev_err(spc->dev, "no available PWM channels\n");
return -ENODEV;
}
if (!i)
return dev_err_probe(spc->dev, -ENODEV, "no available PWM channels\n");
spc->num_pwms = i;
@ -264,7 +264,6 @@ static int sprd_pwm_probe(struct platform_device *pdev)
return PTR_ERR(spc->base);
spc->dev = &pdev->dev;
platform_set_drvdata(pdev, spc);
ret = sprd_pwm_clk_init(spc);
if (ret)
@ -274,20 +273,13 @@ static int sprd_pwm_probe(struct platform_device *pdev)
spc->chip.ops = &sprd_pwm_ops;
spc->chip.npwm = spc->num_pwms;
ret = pwmchip_add(&spc->chip);
ret = devm_pwmchip_add(&pdev->dev, &spc->chip);
if (ret)
dev_err(&pdev->dev, "failed to add PWM chip\n");
return ret;
}
static void sprd_pwm_remove(struct platform_device *pdev)
{
struct sprd_pwm_chip *spc = platform_get_drvdata(pdev);
pwmchip_remove(&spc->chip);
}
static const struct of_device_id sprd_pwm_of_match[] = {
{ .compatible = "sprd,ums512-pwm", },
{ },
@ -300,7 +292,6 @@ static struct platform_driver sprd_pwm_driver = {
.of_match_table = sprd_pwm_of_match,
},
.probe = sprd_pwm_probe,
.remove_new = sprd_pwm_remove,
};
module_platform_driver(sprd_pwm_driver);

View File

@ -79,6 +79,7 @@ struct sti_pwm_compat_data {
unsigned int cpt_num_devs;
unsigned int max_pwm_cnt;
unsigned int max_prescale;
struct sti_cpt_ddata *ddata;
};
struct sti_pwm_chip {
@ -314,7 +315,7 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
{
struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
struct sti_pwm_compat_data *cdata = pc->cdata;
struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm);
struct sti_cpt_ddata *ddata = &cdata->ddata[pwm->hwpwm];
struct device *dev = pc->dev;
unsigned int effective_ticks;
unsigned long long high, low;
@ -420,7 +421,6 @@ static const struct pwm_ops sti_pwm_ops = {
.capture = sti_pwm_capture,
.apply = sti_pwm_apply,
.free = sti_pwm_free,
.owner = THIS_MODULE,
};
static irqreturn_t sti_pwm_interrupt(int irq, void *data)
@ -440,7 +440,7 @@ static irqreturn_t sti_pwm_interrupt(int irq, void *data)
while (cpt_int_stat) {
devicenum = ffs(cpt_int_stat) - 1;
ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]);
ddata = &pc->cdata->ddata[devicenum];
/*
* Capture input:
@ -638,12 +638,23 @@ static int sti_pwm_probe(struct platform_device *pdev)
dev_err(dev, "failed to prepare clock\n");
return ret;
}
cdata->ddata = devm_kzalloc(dev, cdata->cpt_num_devs * sizeof(*cdata->ddata), GFP_KERNEL);
if (!cdata->ddata)
return -ENOMEM;
}
pc->chip.dev = dev;
pc->chip.ops = &sti_pwm_ops;
pc->chip.npwm = pc->cdata->pwm_num_devs;
for (i = 0; i < cdata->cpt_num_devs; i++) {
struct sti_cpt_ddata *ddata = &cdata->ddata[i];
init_waitqueue_head(&ddata->wait);
mutex_init(&ddata->lock);
}
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
clk_unprepare(pc->pwm_clk);
@ -651,19 +662,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
return ret;
}
for (i = 0; i < cdata->cpt_num_devs; i++) {
struct sti_cpt_ddata *ddata;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
init_waitqueue_head(&ddata->wait);
mutex_init(&ddata->lock);
pwm_set_chip_data(&pc->chip.pwms[i], ddata);
}
platform_set_drvdata(pdev, pc);
return 0;

View File

@ -189,7 +189,6 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
}
static const struct pwm_ops stm32_pwm_lp_ops = {
.owner = THIS_MODULE,
.apply = stm32_pwm_lp_apply,
.get_state = stm32_pwm_lp_get_state,
};

View File

@ -487,7 +487,6 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm,
}
static const struct pwm_ops stm32pwm_ops = {
.owner = THIS_MODULE,
.apply = stm32_pwm_apply_locked,
.capture = IS_ENABLED(CONFIG_DMA_ENGINE) ? stm32_pwm_capture : NULL,
};

View File

@ -287,7 +287,6 @@ static int stmpe_24xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops stmpe_24xx_pwm_ops = {
.apply = stmpe_24xx_pwm_apply,
.owner = THIS_MODULE,
};
static int __init stmpe_pwm_probe(struct platform_device *pdev)

View File

@ -325,7 +325,6 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops sun4i_pwm_ops = {
.apply = sun4i_pwm_apply,
.get_state = sun4i_pwm_get_state,
.owner = THIS_MODULE,
};
static const struct sun4i_pwm_data sun4i_pwm_dual_nobypass = {

View File

@ -163,7 +163,6 @@ static int sunplus_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops sunplus_pwm_ops = {
.apply = sunplus_pwm_apply,
.get_state = sunplus_pwm_get_state,
.owner = THIS_MODULE,
};
static void sunplus_pwm_clk_release(void *data)

View File

@ -268,7 +268,6 @@ static int tegra_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops tegra_pwm_ops = {
.apply = tegra_pwm_apply,
.owner = THIS_MODULE,
};
static int tegra_pwm_probe(struct platform_device *pdev)

View File

@ -205,7 +205,6 @@ static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops ecap_pwm_ops = {
.apply = ecap_pwm_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id ecap_of_match[] = {

View File

@ -437,7 +437,6 @@ static int ehrpwm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops ehrpwm_pwm_ops = {
.free = ehrpwm_pwm_free,
.apply = ehrpwm_pwm_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id ehrpwm_of_match[] = {

View File

@ -189,7 +189,6 @@ static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops twl4030_pwmled_ops = {
.apply = twl4030_pwmled_apply,
.owner = THIS_MODULE,
};
static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm,
@ -342,7 +341,6 @@ static const struct pwm_ops twl6030_pwmled_ops = {
.apply = twl6030_pwmled_apply,
.request = twl6030_pwmled_request,
.free = twl6030_pwmled_free,
.owner = THIS_MODULE,
};
static int twl_pwmled_probe(struct platform_device *pdev)

View File

@ -333,12 +333,10 @@ static const struct pwm_ops twl4030_pwm_ops = {
.apply = twl4030_pwm_apply,
.request = twl4030_pwm_request,
.free = twl4030_pwm_free,
.owner = THIS_MODULE,
};
static const struct pwm_ops twl6030_pwm_ops = {
.apply = twl6030_pwm_apply,
.owner = THIS_MODULE,
};
static int twl_pwm_probe(struct platform_device *pdev)

View File

@ -129,7 +129,6 @@ static int visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops visconti_pwm_ops = {
.apply = visconti_pwm_apply,
.get_state = visconti_pwm_get_state,
.owner = THIS_MODULE,
};
static int visconti_pwm_probe(struct platform_device *pdev)

View File

@ -221,7 +221,6 @@ static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
static const struct pwm_ops vt8500_pwm_ops = {
.apply = vt8500_pwm_apply,
.owner = THIS_MODULE,
};
static const struct of_device_id vt8500_pwm_dt_ids[] = {
@ -236,10 +235,8 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
int ret;
if (!np) {
dev_err(&pdev->dev, "invalid devicetree node\n");
return -EINVAL;
}
if (!np)
return dev_err_probe(&pdev->dev, -EINVAL, "invalid devicetree node\n");
vt8500 = devm_kzalloc(&pdev->dev, sizeof(*vt8500), GFP_KERNEL);
if (vt8500 == NULL)
@ -249,45 +246,23 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
vt8500->chip.ops = &vt8500_pwm_ops;
vt8500->chip.npwm = VT8500_NR_PWMS;
vt8500->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(vt8500->clk)) {
dev_err(&pdev->dev, "clock source not specified\n");
return PTR_ERR(vt8500->clk);
}
vt8500->clk = devm_clk_get_prepared(&pdev->dev, NULL);
if (IS_ERR(vt8500->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(vt8500->clk), "clock source not specified\n");
vt8500->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vt8500->base))
return PTR_ERR(vt8500->base);
ret = clk_prepare(vt8500->clk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to prepare clock\n");
return ret;
}
ret = devm_pwmchip_add(&pdev->dev, &vt8500->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
ret = pwmchip_add(&vt8500->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip\n");
clk_unprepare(vt8500->clk);
return ret;
}
platform_set_drvdata(pdev, vt8500);
return ret;
}
static void vt8500_pwm_remove(struct platform_device *pdev)
{
struct vt8500_chip *vt8500 = platform_get_drvdata(pdev);
pwmchip_remove(&vt8500->chip);
clk_unprepare(vt8500->clk);
return 0;
}
static struct platform_driver vt8500_pwm_driver = {
.probe = vt8500_pwm_probe,
.remove_new = vt8500_pwm_remove,
.driver = {
.name = "vt8500-pwm",
.of_match_table = vt8500_pwm_dt_ids,

View File

@ -198,7 +198,6 @@ static int xilinx_pwm_get_state(struct pwm_chip *chip,
static const struct pwm_ops xilinx_pwm_ops = {
.apply = xilinx_pwm_apply,
.get_state = xilinx_pwm_get_state,
.owner = THIS_MODULE,
};
static const struct regmap_config xilinx_pwm_regmap_config = {

View File

@ -258,7 +258,6 @@ static const struct pwm_ops gb_pwm_ops = {
.request = gb_pwm_request,
.free = gb_pwm_free,
.apply = gb_pwm_apply,
.owner = THIS_MODULE,
};
static int gb_pwm_probe(struct gbphy_device *gbphy_dev,

View File

@ -71,7 +71,6 @@ struct pwm_state {
* @hwpwm: per-chip relative index of the PWM device
* @pwm: global index of the PWM device
* @chip: PWM chip providing this PWM device
* @chip_data: chip-private data associated with the PWM device
* @args: PWM arguments
* @state: last applied state
* @last: last implemented state (for PWM_DEBUG)
@ -82,7 +81,6 @@ struct pwm_device {
unsigned int hwpwm;
unsigned int pwm;
struct pwm_chip *chip;
void *chip_data;
struct pwm_args args;
struct pwm_state state;
@ -267,7 +265,6 @@ struct pwm_capture {
* @get_state: get the current PWM state. This function is only
* called once per PWM device when the PWM chip is
* registered.
* @owner: helps prevent removal of modules exporting active PWMs
*/
struct pwm_ops {
int (*request)(struct pwm_chip *chip, struct pwm_device *pwm);
@ -278,13 +275,13 @@ struct pwm_ops {
const struct pwm_state *state);
int (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state);
struct module *owner;
};
/**
* struct pwm_chip - abstract a PWM controller
* @dev: device providing the PWMs
* @ops: callbacks for this PWM controller
* @owner: module providing this chip
* @base: number of first PWM controlled by this chip
* @npwm: number of PWMs controlled by this chip
* @of_xlate: request a PWM device given a device tree PWM specifier
@ -295,6 +292,7 @@ struct pwm_ops {
struct pwm_chip {
struct device *dev;
const struct pwm_ops *ops;
struct module *owner;
int base;
unsigned int npwm;
@ -383,13 +381,13 @@ static inline void pwm_disable(struct pwm_device *pwm)
/* PWM provider APIs */
int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
unsigned long timeout);
int pwm_set_chip_data(struct pwm_device *pwm, void *data);
void *pwm_get_chip_data(struct pwm_device *pwm);
int pwmchip_add(struct pwm_chip *chip);
int __pwmchip_add(struct pwm_chip *chip, struct module *owner);
#define pwmchip_add(chip) __pwmchip_add(chip, THIS_MODULE)
void pwmchip_remove(struct pwm_chip *chip);
int devm_pwmchip_add(struct device *dev, struct pwm_chip *chip);
int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner);
#define devm_pwmchip_add(dev, chip) __devm_pwmchip_add(dev, chip, THIS_MODULE)
struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
unsigned int index,
@ -445,16 +443,6 @@ static inline int pwm_capture(struct pwm_device *pwm,
return -EINVAL;
}
static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
{
return -EINVAL;
}
static inline void *pwm_get_chip_data(struct pwm_device *pwm)
{
return NULL;
}
static inline int pwmchip_add(struct pwm_chip *chip)
{
return -EINVAL;