Commit 3fb55dd1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pwm/for-6.1-rc1' of...

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

Pull pwm updates from Thierry Reding:
 "The Rockchip and Mediatek drivers gain support for more chips and the
  LPSS driver undergoes some refactoring and receives some improvements.

  Other than that there are various cleanups of the core"

* tag 'pwm/for-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: sysfs: Replace sprintf() with sysfs_emit()
  pwm: core: Replace custom implementation of device_match_fwnode()
  pwm: lpss: Add a comment to the bypass field
  pwm: lpss: Make use of bits.h macros for all masks
  pwm: lpss: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
  pwm: lpss: Use device_get_match_data() to get device data
  pwm: lpss: Move resource mapping to the glue drivers
  pwm: lpss: Move exported symbols to PWM_LPSS namespace
  pwm: lpss: Deduplicate board info data structures
  dt-bindings: pwm: Add compatible for Mediatek MT8188
  dt-bindings: pwm: rockchip: Add rockchip,rk3128-pwm
  dt-bindings: pwm: rockchip: Add description for rk3588
  pwm: sysfs: Switch to DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr()
  pwm: rockchip: Convert to use dev_err_probe()
parents ae955959 4709f9ea
......@@ -27,6 +27,7 @@ properties:
- items:
- enum:
- mediatek,mt8186-disp-pwm
- mediatek,mt8188-disp-pwm
- mediatek,mt8192-disp-pwm
- mediatek,mt8195-disp-pwm
- const: mediatek,mt8183-disp-pwm
......
......@@ -21,6 +21,7 @@ properties:
- const: rockchip,rk2928-pwm
- items:
- enum:
- rockchip,rk3128-pwm
- rockchip,rk3368-pwm
- rockchip,rk3399-pwm
- rockchip,rv1108-pwm
......@@ -30,6 +31,7 @@ properties:
- rockchip,px30-pwm
- rockchip,rk3308-pwm
- rockchip,rk3568-pwm
- rockchip,rk3588-pwm
- const: rockchip,rk3328-pwm
reg:
......
......@@ -678,7 +678,7 @@ static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode)
mutex_lock(&pwm_lock);
list_for_each_entry(chip, &pwm_chips, list)
if (chip->dev && dev_fwnode(chip->dev) == fwnode) {
if (chip->dev && device_match_fwnode(chip->dev, fwnode)) {
mutex_unlock(&pwm_lock);
return chip;
}
......
......@@ -14,35 +14,6 @@
#include "pwm-lpss.h"
/* BayTrail */
static const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000,
.npwm = 1,
.base_unit_bits = 16,
};
/* Braswell */
static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000,
.npwm = 1,
.base_unit_bits = 16,
};
/* Broxton */
static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
.bypass = true,
};
/* Tangier */
static const struct pwm_lpss_boardinfo pwm_lpss_tng_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
};
static int pwm_lpss_probe_pci(struct pci_dev *pdev,
const struct pci_device_id *id)
{
......@@ -54,8 +25,12 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev,
if (err < 0)
return err;
err = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
if (err)
return err;
info = (struct pwm_lpss_boardinfo *)id->driver_data;
lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
lpwm = pwm_lpss_probe(&pdev->dev, pcim_iomap_table(pdev)[0], info);
if (IS_ERR(lpwm))
return PTR_ERR(lpwm);
......@@ -73,7 +48,6 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
pm_runtime_get_sync(&pdev->dev);
}
#ifdef CONFIG_PM
static int pwm_lpss_runtime_suspend_pci(struct device *dev)
{
/*
......@@ -87,12 +61,11 @@ static int pwm_lpss_runtime_resume_pci(struct device *dev)
{
return 0;
}
#endif
static const struct dev_pm_ops pwm_lpss_pci_pm = {
SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
pwm_lpss_runtime_resume_pci, NULL)
};
static DEFINE_RUNTIME_DEV_PM_OPS(pwm_lpss_pci_pm,
pwm_lpss_runtime_suspend_pci,
pwm_lpss_runtime_resume_pci,
NULL);
static const struct pci_device_id pwm_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
......@@ -114,10 +87,11 @@ static struct pci_driver pwm_lpss_driver_pci = {
.probe = pwm_lpss_probe_pci,
.remove = pwm_lpss_remove_pci,
.driver = {
.pm = &pwm_lpss_pci_pm,
.pm = pm_ptr(&pwm_lpss_pci_pm),
},
};
module_pci_driver(pwm_lpss_driver_pci);
MODULE_DESCRIPTION("PWM PCI driver for Intel LPSS");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(PWM_LPSS);
......@@ -7,52 +7,31 @@
* Derived from the original pwm-lpss.c
*/
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include "pwm-lpss.h"
/* BayTrail */
static const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000,
.npwm = 1,
.base_unit_bits = 16,
};
/* Braswell */
static const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000,
.npwm = 1,
.base_unit_bits = 16,
.other_devices_aml_touches_pwm_regs = true,
};
/* Broxton */
static const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
.bypass = true,
};
static int pwm_lpss_probe_platform(struct platform_device *pdev)
{
const struct pwm_lpss_boardinfo *info;
const struct acpi_device_id *id;
struct pwm_lpss_chip *lpwm;
struct resource *r;
void __iomem *base;
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (!id)
info = device_get_match_data(&pdev->dev);
if (!info)
return -ENODEV;
info = (const struct pwm_lpss_boardinfo *)id->driver_data;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
lpwm = pwm_lpss_probe(&pdev->dev, r, info);
lpwm = pwm_lpss_probe(&pdev->dev, base, info);
if (IS_ERR(lpwm))
return PTR_ERR(lpwm);
......@@ -110,4 +89,5 @@ module_platform_driver(pwm_lpss_driver_platform);
MODULE_DESCRIPTION("PWM platform driver for Intel LPSS");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(PWM_LPSS);
MODULE_ALIAS("platform:pwm-lpss");
......@@ -10,6 +10,7 @@
* Author: Alan Cox <alan@linux.intel.com>
*/
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iopoll.h>
......@@ -18,17 +19,53 @@
#include <linux/pm_runtime.h>
#include <linux/time.h>
#define DEFAULT_SYMBOL_NAMESPACE PWM_LPSS
#include "pwm-lpss.h"
#define PWM 0x00000000
#define PWM_ENABLE BIT(31)
#define PWM_SW_UPDATE BIT(30)
#define PWM_BASE_UNIT_SHIFT 8
#define PWM_ON_TIME_DIV_MASK 0x000000ff
#define PWM_ON_TIME_DIV_MASK GENMASK(7, 0)
/* Size of each PWM register space if multiple */
#define PWM_SIZE 0x400
/* BayTrail */
const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000,
.npwm = 1,
.base_unit_bits = 16,
};
EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
/* Braswell */
const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000,
.npwm = 1,
.base_unit_bits = 16,
.other_devices_aml_touches_pwm_regs = true,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
/* Broxton */
const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
.bypass = true,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
/* Tangier */
const struct pwm_lpss_boardinfo pwm_lpss_tng_info = {
.clk_rate = 19200000,
.npwm = 4,
.base_unit_bits = 22,
};
EXPORT_SYMBOL_GPL(pwm_lpss_tng_info);
static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
{
return container_of(chip, struct pwm_lpss_chip, chip);
......@@ -207,7 +244,7 @@ static const struct pwm_ops pwm_lpss_ops = {
.owner = THIS_MODULE,
};
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, void __iomem *base,
const struct pwm_lpss_boardinfo *info)
{
struct pwm_lpss_chip *lpwm;
......@@ -222,10 +259,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
if (!lpwm)
return ERR_PTR(-ENOMEM);
lpwm->regs = devm_ioremap_resource(dev, r);
if (IS_ERR(lpwm->regs))
return ERR_CAST(lpwm->regs);
lpwm->regs = base;
lpwm->info = info;
c = lpwm->info->clk_rate;
......
......@@ -25,6 +25,11 @@ struct pwm_lpss_boardinfo {
unsigned long clk_rate;
unsigned int npwm;
unsigned long base_unit_bits;
/*
* Some versions of the IP may stuck in the state machine if enable
* bit is not set, and hence update bit will show busy status till
* the reset. For the rest it may be otherwise.
*/
bool bypass;
/*
* On some devices the _PS0/_PS3 AML code of the GPU (GFX0) device
......@@ -33,7 +38,12 @@ struct pwm_lpss_boardinfo {
bool other_devices_aml_touches_pwm_regs;
};
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
extern const struct pwm_lpss_boardinfo pwm_lpss_bsw_info;
extern const struct pwm_lpss_boardinfo pwm_lpss_bxt_info;
extern const struct pwm_lpss_boardinfo pwm_lpss_tng_info;
struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, void __iomem *base,
const struct pwm_lpss_boardinfo *info);
#endif /* __PWM_LPSS_H */
......@@ -328,22 +328,16 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
else
pc->pclk = pc->clk;
if (IS_ERR(pc->pclk)) {
ret = PTR_ERR(pc->pclk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Can't get APB clk: %d\n", ret);
return ret;
}
if (IS_ERR(pc->pclk))
return dev_err_probe(&pdev->dev, PTR_ERR(pc->pclk), "Can't get APB clk\n");
ret = clk_prepare_enable(pc->clk);
if (ret) {
dev_err(&pdev->dev, "Can't prepare enable PWM clk: %d\n", ret);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret, "Can't prepare enable PWM clk\n");
ret = clk_prepare_enable(pc->pclk);
if (ret) {
dev_err(&pdev->dev, "Can't prepare enable APB clk: %d\n", ret);
dev_err_probe(&pdev->dev, ret, "Can't prepare enable APB clk\n");
goto err_clk;
}
......@@ -360,7 +354,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
goto err_pclk;
}
......
......@@ -42,7 +42,7 @@ static ssize_t period_show(struct device *child,
pwm_get_state(pwm, &state);
return sprintf(buf, "%llu\n", state.period);
return sysfs_emit(buf, "%llu\n", state.period);
}
static ssize_t period_store(struct device *child,
......@@ -77,7 +77,7 @@ static ssize_t duty_cycle_show(struct device *child,
pwm_get_state(pwm, &state);
return sprintf(buf, "%llu\n", state.duty_cycle);
return sysfs_emit(buf, "%llu\n", state.duty_cycle);
}
static ssize_t duty_cycle_store(struct device *child,
......@@ -112,7 +112,7 @@ static ssize_t enable_show(struct device *child,
pwm_get_state(pwm, &state);
return sprintf(buf, "%d\n", state.enabled);
return sysfs_emit(buf, "%d\n", state.enabled);
}
static ssize_t enable_store(struct device *child,
......@@ -171,7 +171,7 @@ static ssize_t polarity_show(struct device *child,
break;
}
return sprintf(buf, "%s\n", polarity);
return sysfs_emit(buf, "%s\n", polarity);
}
static ssize_t polarity_store(struct device *child,
......@@ -212,7 +212,7 @@ static ssize_t capture_show(struct device *child,
if (ret)
return ret;
return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
return sysfs_emit(buf, "%u %u\n", result.period, result.duty_cycle);
}
static DEVICE_ATTR_RW(period);
......@@ -361,7 +361,7 @@ static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
{
const struct pwm_chip *chip = dev_get_drvdata(parent);
return sprintf(buf, "%u\n", chip->npwm);
return sysfs_emit(buf, "%u\n", chip->npwm);
}
static DEVICE_ATTR_RO(npwm);
......@@ -433,7 +433,7 @@ static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
return ret;
}
static int __maybe_unused pwm_class_suspend(struct device *parent)
static int pwm_class_suspend(struct device *parent)
{
struct pwm_chip *chip = dev_get_drvdata(parent);
unsigned int i;
......@@ -464,20 +464,20 @@ static int __maybe_unused pwm_class_suspend(struct device *parent)
return ret;
}
static int __maybe_unused pwm_class_resume(struct device *parent)
static int pwm_class_resume(struct device *parent)
{
struct pwm_chip *chip = dev_get_drvdata(parent);
return pwm_class_resume_npwm(parent, chip->npwm);
}
static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
static DEFINE_SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
static struct class pwm_class = {
.name = "pwm",
.owner = THIS_MODULE,
.dev_groups = pwm_chip_groups,
.pm = &pwm_class_pm_ops,
.pm = pm_sleep_ptr(&pwm_class_pm_ops),
};
static int pwmchip_sysfs_match(struct device *parent, const void *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment