#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#define PWM_ENABLE BIT(31)
#define PWM_SW_UPDATE BIT(30)
#define PWM_BASE_UNIT_SHIFT 8
#define PWM_ON_TIME_DIV_MASK 0x000000ff
static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
return container_of(chip, struct pwm_lpss_chip, chip);
static inline u32 pwm_lpss_read(const struct pwm_device *pwm)
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
static int pwm_lpss_wait_for_update(struct pwm_device *pwm)
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
const void __iomem *addr = lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM;
const unsigned int ms = 500 * USEC_PER_MSEC;
err = readl_poll_timeout(addr, val, !(val & PWM_SW_UPDATE), 40, ms);
dev_err(pwm->chip->dev, "PWM_SW_UPDATE was not cleared\n");
static inline int pwm_lpss_is_updating(struct pwm_device *pwm)
return (pwm_lpss_read(pwm) & PWM_SW_UPDATE) ? -EBUSY : 0;
static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
int duty_ns, int period_ns)
unsigned long long on_time_div;
unsigned long c = lpwm->info->clk_rate, base_unit_range;
unsigned long long base_unit, freq = NSEC_PER_SEC;