diff options
Diffstat (limited to 'drivers/pwm')
70 files changed, 1675 insertions, 1660 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index f2728ee787d7..d70f793ce4b3 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -24,310 +24,11 @@ #define CREATE_TRACE_POINTS #include <trace/events/pwm.h> -static DEFINE_MUTEX(pwm_lookup_lock); -static LIST_HEAD(pwm_lookup_list); - /* protects access to pwm_chips */ static DEFINE_MUTEX(pwm_lock); static DEFINE_IDR(pwm_chips); -static struct pwm_chip *pwmchip_find_by_name(const char *name) -{ - struct pwm_chip *chip; - unsigned long id, tmp; - - if (!name) - return NULL; - - mutex_lock(&pwm_lock); - - idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) { - const char *chip_name = dev_name(chip->dev); - - if (chip_name && strcmp(chip_name, name) == 0) { - mutex_unlock(&pwm_lock); - return chip; - } - } - - mutex_unlock(&pwm_lock); - - return NULL; -} - -static int pwm_device_request(struct pwm_device *pwm, const char *label) -{ - int err; - struct pwm_chip *chip = pwm->chip; - const struct pwm_ops *ops = chip->ops; - - if (test_bit(PWMF_REQUESTED, &pwm->flags)) - return -EBUSY; - - if (!try_module_get(chip->owner)) - return -ENODEV; - - if (ops->request) { - err = ops->request(chip, pwm); - if (err) { - module_put(chip->owner); - return err; - } - } - - if (ops->get_state) { - /* - * Zero-initialize state because most drivers are unaware of - * .usage_power. The other members of state are supposed to be - * set by lowlevel drivers. We still initialize the whole - * structure for simplicity even though this might paper over - * faulty implementations of .get_state(). - */ - struct pwm_state state = { 0, }; - - err = ops->get_state(chip, pwm, &state); - trace_pwm_get(pwm, &state, err); - - if (!err) - pwm->state = state; - - if (IS_ENABLED(CONFIG_PWM_DEBUG)) - pwm->last = pwm->state; - } - - set_bit(PWMF_REQUESTED, &pwm->flags); - pwm->label = label; - - return 0; -} - -struct pwm_device * -of_pwm_xlate_with_flags(struct pwm_chip *chip, const struct of_phandle_args *args) -{ - struct pwm_device *pwm; - - if (chip->of_pwm_n_cells < 2) - return ERR_PTR(-EINVAL); - - /* flags in the third cell are optional */ - if (args->args_count < 2) - return ERR_PTR(-EINVAL); - - if (args->args[0] >= chip->npwm) - return ERR_PTR(-EINVAL); - - pwm = pwm_request_from_chip(chip, args->args[0], NULL); - if (IS_ERR(pwm)) - return pwm; - - pwm->args.period = args->args[1]; - pwm->args.polarity = PWM_POLARITY_NORMAL; - - if (chip->of_pwm_n_cells >= 3) { - if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED) - pwm->args.polarity = PWM_POLARITY_INVERSED; - } - - return pwm; -} -EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags); - -struct pwm_device * -of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args) -{ - struct pwm_device *pwm; - - if (chip->of_pwm_n_cells < 1) - return ERR_PTR(-EINVAL); - - /* validate that one cell is specified, optionally with flags */ - if (args->args_count != 1 && args->args_count != 2) - return ERR_PTR(-EINVAL); - - pwm = pwm_request_from_chip(chip, 0, NULL); - if (IS_ERR(pwm)) - return pwm; - - pwm->args.period = args->args[0]; - pwm->args.polarity = PWM_POLARITY_NORMAL; - - if (args->args_count == 2 && args->args[1] & PWM_POLARITY_INVERTED) - pwm->args.polarity = PWM_POLARITY_INVERSED; - - return pwm; -} -EXPORT_SYMBOL_GPL(of_pwm_single_xlate); - -static void of_pwmchip_add(struct pwm_chip *chip) -{ - if (!chip->dev || !chip->dev->of_node) - return; - - if (!chip->of_xlate) { - u32 pwm_cells; - - if (of_property_read_u32(chip->dev->of_node, "#pwm-cells", - &pwm_cells)) - pwm_cells = 2; - - chip->of_xlate = of_pwm_xlate_with_flags; - chip->of_pwm_n_cells = pwm_cells; - } - - of_node_get(chip->dev->of_node); -} - -static void of_pwmchip_remove(struct pwm_chip *chip) -{ - if (chip->dev) - of_node_put(chip->dev->of_node); -} - -static bool pwm_ops_check(const struct pwm_chip *chip) -{ - const struct pwm_ops *ops = chip->ops; - - if (!ops->apply) - return false; - - if (IS_ENABLED(CONFIG_PWM_DEBUG) && !ops->get_state) - dev_warn(chip->dev, - "Please implement the .get_state() callback\n"); - - return true; -} - -/** - * __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. @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, struct module *owner) -{ - unsigned int i; - int ret; - - if (!chip || !chip->dev || !chip->ops || !chip->npwm) - return -EINVAL; - - if (!pwm_ops_check(chip)) - return -EINVAL; - - chip->owner = owner; - - chip->pwms = kcalloc(chip->npwm, sizeof(*chip->pwms), GFP_KERNEL); - if (!chip->pwms) - return -ENOMEM; - - mutex_lock(&pwm_lock); - - ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL); - if (ret < 0) { - mutex_unlock(&pwm_lock); - kfree(chip->pwms); - return ret; - } - - chip->id = ret; - - for (i = 0; i < chip->npwm; i++) { - struct pwm_device *pwm = &chip->pwms[i]; - - pwm->chip = chip; - pwm->hwpwm = i; - } - - mutex_unlock(&pwm_lock); - - if (IS_ENABLED(CONFIG_OF)) - of_pwmchip_add(chip); - - pwmchip_sysfs_export(chip); - - return 0; -} -EXPORT_SYMBOL_GPL(__pwmchip_add); - -/** - * pwmchip_remove() - remove a PWM chip - * @chip: the PWM chip to remove - * - * Removes a PWM chip. - */ -void pwmchip_remove(struct pwm_chip *chip) -{ - pwmchip_sysfs_unexport(chip); - - if (IS_ENABLED(CONFIG_OF)) - of_pwmchip_remove(chip); - - mutex_lock(&pwm_lock); - - idr_remove(&pwm_chips, chip->id); - - mutex_unlock(&pwm_lock); - - kfree(chip->pwms); -} -EXPORT_SYMBOL_GPL(pwmchip_remove); - -static void devm_pwmchip_remove(void *data) -{ - struct pwm_chip *chip = data; - - pwmchip_remove(chip); -} - -int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner) -{ - int ret; - - 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); - -/** - * pwm_request_from_chip() - request a PWM device relative to a PWM chip - * @chip: PWM chip - * @index: per-chip index of the PWM to request - * @label: a literal description string of this PWM - * - * Returns: A pointer to the PWM device at the given index of the given PWM - * chip. A negative error code is returned if the index is not valid for the - * specified PWM chip or if the PWM device cannot be requested. - */ -struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, - unsigned int index, - const char *label) -{ - struct pwm_device *pwm; - int err; - - if (!chip || index >= chip->npwm) - return ERR_PTR(-EINVAL); - - mutex_lock(&pwm_lock); - pwm = &chip->pwms[index]; - - err = pwm_device_request(pwm, label); - if (err < 0) - pwm = ERR_PTR(err); - - mutex_unlock(&pwm_lock); - return pwm; -} -EXPORT_SYMBOL_GPL(pwm_request_from_chip); - static void pwm_apply_debug(struct pwm_device *pwm, const struct pwm_state *state) { @@ -370,18 +71,18 @@ static void pwm_apply_debug(struct pwm_device *pwm, if (s2.polarity != state->polarity && state->duty_cycle < state->period) - dev_warn(chip->dev, ".apply ignored .polarity\n"); + dev_warn(pwmchip_parent(chip), ".apply ignored .polarity\n"); if (state->enabled && last->polarity == state->polarity && last->period > s2.period && last->period <= state->period) - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), ".apply didn't pick the best available period (requested: %llu, applied: %llu, possible: %llu)\n", state->period, s2.period, last->period); if (state->enabled && state->period < s2.period) - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), ".apply is supposed to round down period (requested: %llu, applied: %llu)\n", state->period, s2.period); @@ -390,20 +91,20 @@ static void pwm_apply_debug(struct pwm_device *pwm, last->period == s2.period && last->duty_cycle > s2.duty_cycle && last->duty_cycle <= state->duty_cycle) - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), ".apply didn't pick the best available duty cycle (requested: %llu/%llu, applied: %llu/%llu, possible: %llu/%llu)\n", state->duty_cycle, state->period, s2.duty_cycle, s2.period, last->duty_cycle, last->period); if (state->enabled && state->duty_cycle < s2.duty_cycle) - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), ".apply is supposed to round down duty_cycle (requested: %llu/%llu, applied: %llu/%llu)\n", state->duty_cycle, state->period, s2.duty_cycle, s2.period); if (!state->enabled && s2.enabled && s2.duty_cycle > 0) - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), "requested disabled, but yielded enabled with duty > 0\n"); /* reapply the state that the driver reported being configured. */ @@ -411,7 +112,7 @@ static void pwm_apply_debug(struct pwm_device *pwm, trace_pwm_apply(pwm, &s1, err); if (err) { *last = s1; - dev_err(chip->dev, "failed to reapply current setting\n"); + dev_err(pwmchip_parent(chip), "failed to reapply current setting\n"); return; } @@ -426,7 +127,7 @@ static void pwm_apply_debug(struct pwm_device *pwm, s1.polarity != last->polarity || (s1.enabled && s1.period != last->period) || (s1.enabled && s1.duty_cycle != last->duty_cycle)) { - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), ".apply is not idempotent (ena=%d pol=%d %llu/%llu) -> (ena=%d pol=%d %llu/%llu)\n", s1.enabled, s1.polarity, s1.duty_cycle, s1.period, last->enabled, last->polarity, last->duty_cycle, @@ -524,33 +225,6 @@ int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state) EXPORT_SYMBOL_GPL(pwm_apply_atomic); /** - * pwm_capture() - capture and report a PWM signal - * @pwm: PWM device - * @result: structure to fill with capture result - * @timeout: time to wait, in milliseconds, before giving up on capture - * - * Returns: 0 on success or a negative error code on failure. - */ -int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, - unsigned long timeout) -{ - int err; - - if (!pwm || !pwm->chip->ops) - return -EINVAL; - - if (!pwm->chip->ops->capture) - return -ENOSYS; - - mutex_lock(&pwm_lock); - err = pwm->chip->ops->capture(pwm->chip, pwm, result, timeout); - mutex_unlock(&pwm_lock); - - return err; -} -EXPORT_SYMBOL_GPL(pwm_capture); - -/** * pwm_adjust_config() - adjust the current PWM config to the PWM arguments * @pwm: PWM device * @@ -606,24 +280,367 @@ int pwm_adjust_config(struct pwm_device *pwm) } EXPORT_SYMBOL_GPL(pwm_adjust_config); -static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode) +/** + * pwm_capture() - capture and report a PWM signal + * @pwm: PWM device + * @result: structure to fill with capture result + * @timeout: time to wait, in milliseconds, before giving up on capture + * + * Returns: 0 on success or a negative error code on failure. + */ +int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, + unsigned long timeout) +{ + int err; + + if (!pwm || !pwm->chip->ops) + return -EINVAL; + + if (!pwm->chip->ops->capture) + return -ENOSYS; + + mutex_lock(&pwm_lock); + err = pwm->chip->ops->capture(pwm->chip, pwm, result, timeout); + mutex_unlock(&pwm_lock); + + return err; +} +EXPORT_SYMBOL_GPL(pwm_capture); + +static struct pwm_chip *pwmchip_find_by_name(const char *name) { struct pwm_chip *chip; unsigned long id, tmp; + if (!name) + return NULL; + mutex_lock(&pwm_lock); - idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) - if (chip->dev && device_match_fwnode(chip->dev, fwnode)) { + idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) { + const char *chip_name = dev_name(pwmchip_parent(chip)); + + if (chip_name && strcmp(chip_name, name) == 0) { mutex_unlock(&pwm_lock); return chip; } + } mutex_unlock(&pwm_lock); - return ERR_PTR(-EPROBE_DEFER); + return NULL; +} + +static int pwm_device_request(struct pwm_device *pwm, const char *label) +{ + int err; + struct pwm_chip *chip = pwm->chip; + const struct pwm_ops *ops = chip->ops; + + if (test_bit(PWMF_REQUESTED, &pwm->flags)) + return -EBUSY; + + if (!try_module_get(chip->owner)) + return -ENODEV; + + if (ops->request) { + err = ops->request(chip, pwm); + if (err) { + module_put(chip->owner); + return err; + } + } + + if (ops->get_state) { + /* + * Zero-initialize state because most drivers are unaware of + * .usage_power. The other members of state are supposed to be + * set by lowlevel drivers. We still initialize the whole + * structure for simplicity even though this might paper over + * faulty implementations of .get_state(). + */ + struct pwm_state state = { 0, }; + + err = ops->get_state(chip, pwm, &state); + trace_pwm_get(pwm, &state, err); + + if (!err) + pwm->state = state; + + if (IS_ENABLED(CONFIG_PWM_DEBUG)) + pwm->last = pwm->state; + } + + set_bit(PWMF_REQUESTED, &pwm->flags); + pwm->label = label; + + return 0; +} + +/** + * pwm_request_from_chip() - request a PWM device relative to a PWM chip + * @chip: PWM chip + * @index: per-chip index of the PWM to request + * @label: a literal description string of this PWM + * + * Returns: A pointer to the PWM device at the given index of the given PWM + * chip. A negative error code is returned if the index is not valid for the + * specified PWM chip or if the PWM device cannot be requested. + */ +struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, + unsigned int index, + const char *label) +{ + struct pwm_device *pwm; + int err; + + if (!chip || index >= chip->npwm) + return ERR_PTR(-EINVAL); + + mutex_lock(&pwm_lock); + pwm = &chip->pwms[index]; + + err = pwm_device_request(pwm, label); + if (err < 0) + pwm = ERR_PTR(err); + + mutex_unlock(&pwm_lock); + return pwm; +} +EXPORT_SYMBOL_GPL(pwm_request_from_chip); + + +struct pwm_device * +of_pwm_xlate_with_flags(struct pwm_chip *chip, const struct of_phandle_args *args) +{ + struct pwm_device *pwm; + + /* period in the second cell and flags in the third cell are optional */ + if (args->args_count < 1) + return ERR_PTR(-EINVAL); + + pwm = pwm_request_from_chip(chip, args->args[0], NULL); + if (IS_ERR(pwm)) + return pwm; + + if (args->args_count > 1) + pwm->args.period = args->args[1]; + + pwm->args.polarity = PWM_POLARITY_NORMAL; + if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED) + pwm->args.polarity = PWM_POLARITY_INVERSED; + + return pwm; +} +EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags); + +struct pwm_device * +of_pwm_single_xlate(struct pwm_chip *chip, const struct of_phandle_args *args) +{ + struct pwm_device *pwm; + + pwm = pwm_request_from_chip(chip, 0, NULL); + if (IS_ERR(pwm)) + return pwm; + + if (args->args_count > 1) + pwm->args.period = args->args[0]; + + pwm->args.polarity = PWM_POLARITY_NORMAL; + if (args->args_count > 1 && args->args[1] & PWM_POLARITY_INVERTED) + pwm->args.polarity = PWM_POLARITY_INVERSED; + + return pwm; +} +EXPORT_SYMBOL_GPL(of_pwm_single_xlate); + +#define PWMCHIP_ALIGN ARCH_DMA_MINALIGN + +static void *pwmchip_priv(struct pwm_chip *chip) +{ + return (void *)chip + ALIGN(sizeof(*chip), PWMCHIP_ALIGN); +} + +/* This is the counterpart to pwmchip_alloc() */ +void pwmchip_put(struct pwm_chip *chip) +{ + kfree(chip); +} +EXPORT_SYMBOL_GPL(pwmchip_put); + +struct pwm_chip *pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv) +{ + struct pwm_chip *chip; + size_t alloc_size; + + alloc_size = size_add(ALIGN(sizeof(*chip), PWMCHIP_ALIGN), sizeof_priv); + + chip = kzalloc(alloc_size, GFP_KERNEL); + if (!chip) + return ERR_PTR(-ENOMEM); + + chip->dev = parent; + chip->npwm = npwm; + + pwmchip_set_drvdata(chip, pwmchip_priv(chip)); + + return chip; +} +EXPORT_SYMBOL_GPL(pwmchip_alloc); + +static void devm_pwmchip_put(void *data) +{ + struct pwm_chip *chip = data; + + pwmchip_put(chip); +} + +struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, size_t sizeof_priv) +{ + struct pwm_chip *chip; + int ret; + + chip = pwmchip_alloc(parent, npwm, sizeof_priv); + if (IS_ERR(chip)) + return chip; + + ret = devm_add_action_or_reset(parent, devm_pwmchip_put, chip); + if (ret) + return ERR_PTR(ret); + + return chip; +} +EXPORT_SYMBOL_GPL(devm_pwmchip_alloc); + +static void of_pwmchip_add(struct pwm_chip *chip) +{ + if (!pwmchip_parent(chip) || !pwmchip_parent(chip)->of_node) + return; + + if (!chip->of_xlate) + chip->of_xlate = of_pwm_xlate_with_flags; + + of_node_get(pwmchip_parent(chip)->of_node); +} + +static void of_pwmchip_remove(struct pwm_chip *chip) +{ + if (pwmchip_parent(chip)) + of_node_put(pwmchip_parent(chip)->of_node); +} + +static bool pwm_ops_check(const struct pwm_chip *chip) +{ + const struct pwm_ops *ops = chip->ops; + + if (!ops->apply) + return false; + + if (IS_ENABLED(CONFIG_PWM_DEBUG) && !ops->get_state) + dev_warn(pwmchip_parent(chip), + "Please implement the .get_state() callback\n"); + + return true; } +/** + * __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. @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, struct module *owner) +{ + unsigned int i; + int ret; + + if (!chip || !pwmchip_parent(chip) || !chip->ops || !chip->npwm) + return -EINVAL; + + if (!pwm_ops_check(chip)) + return -EINVAL; + + chip->owner = owner; + + chip->pwms = kcalloc(chip->npwm, sizeof(*chip->pwms), GFP_KERNEL); + if (!chip->pwms) + return -ENOMEM; + + mutex_lock(&pwm_lock); + + ret = idr_alloc(&pwm_chips, chip, 0, 0, GFP_KERNEL); + if (ret < 0) { + mutex_unlock(&pwm_lock); + kfree(chip->pwms); + return ret; + } + + chip->id = ret; + + for (i = 0; i < chip->npwm; i++) { + struct pwm_device *pwm = &chip->pwms[i]; + + pwm->chip = chip; + pwm->hwpwm = i; + } + + mutex_unlock(&pwm_lock); + + if (IS_ENABLED(CONFIG_OF)) + of_pwmchip_add(chip); + + pwmchip_sysfs_export(chip); + + return 0; +} +EXPORT_SYMBOL_GPL(__pwmchip_add); + +/** + * pwmchip_remove() - remove a PWM chip + * @chip: the PWM chip to remove + * + * Removes a PWM chip. + */ +void pwmchip_remove(struct pwm_chip *chip) +{ + pwmchip_sysfs_unexport(chip); + + if (IS_ENABLED(CONFIG_OF)) + of_pwmchip_remove(chip); + + mutex_lock(&pwm_lock); + + idr_remove(&pwm_chips, chip->id); + + mutex_unlock(&pwm_lock); + + kfree(chip->pwms); +} +EXPORT_SYMBOL_GPL(pwmchip_remove); + +static void devm_pwmchip_remove(void *data) +{ + struct pwm_chip *chip = data; + + pwmchip_remove(chip); +} + +int __devm_pwmchip_add(struct device *dev, struct pwm_chip *chip, struct module *owner) +{ + int ret; + + 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); + static struct device_link *pwm_device_link_add(struct device *dev, struct pwm_device *pwm) { @@ -635,21 +652,39 @@ static struct device_link *pwm_device_link_add(struct device *dev, * impact the PM sequence ordering: the PWM supplier may get * suspended before the consumer. */ - dev_warn(pwm->chip->dev, + dev_warn(pwmchip_parent(pwm->chip), "No consumer device specified to create a link to\n"); return NULL; } - dl = device_link_add(dev, pwm->chip->dev, DL_FLAG_AUTOREMOVE_CONSUMER); + dl = device_link_add(dev, pwmchip_parent(pwm->chip), DL_FLAG_AUTOREMOVE_CONSUMER); if (!dl) { dev_err(dev, "failed to create device link to %s\n", - dev_name(pwm->chip->dev)); + dev_name(pwmchip_parent(pwm->chip))); return ERR_PTR(-EINVAL); } return dl; } +static struct pwm_chip *fwnode_to_pwmchip(struct fwnode_handle *fwnode) +{ + struct pwm_chip *chip; + unsigned long id, tmp; + + mutex_lock(&pwm_lock); + + idr_for_each_entry_ul(&pwm_chips, chip, tmp, id) + if (pwmchip_parent(chip) && device_match_fwnode(pwmchip_parent(chip), fwnode)) { + mutex_unlock(&pwm_lock); + return chip; + } + + mutex_unlock(&pwm_lock); + + return ERR_PTR(-EPROBE_DEFER); +} + /** * of_pwm_get() - request a PWM via the PWM framework * @dev: device for PWM consumer @@ -784,6 +819,9 @@ static struct pwm_device *acpi_pwm_get(const struct fwnode_handle *fwnode) return pwm; } +static DEFINE_MUTEX(pwm_lookup_lock); +static LIST_HEAD(pwm_lookup_list); + /** * pwm_add_table() - register PWM device consumers * @table: array of consumers to register @@ -1105,8 +1143,8 @@ static int pwm_seq_show(struct seq_file *s, void *v) seq_printf(s, "%s%d: %s/%s, %d PWM device%s\n", (char *)s->private, chip->id, - chip->dev->bus ? chip->dev->bus->name : "no-bus", - dev_name(chip->dev), chip->npwm, + pwmchip_parent(chip)->bus ? pwmchip_parent(chip)->bus->name : "no-bus", + dev_name(pwmchip_parent(chip)), chip->npwm, (chip->npwm != 1) ? "s" : ""); pwm_dbg_show(chip, s); diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c index 670d33daea84..f000adab85b0 100644 --- a/drivers/pwm/pwm-ab8500.c +++ b/drivers/pwm/pwm-ab8500.c @@ -24,13 +24,12 @@ #define AB8500_PWM_CLKRATE 9600000 struct ab8500_pwm_chip { - struct pwm_chip chip; unsigned int hwid; }; static struct ab8500_pwm_chip *ab8500_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct ab8500_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -92,12 +91,12 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, * when disabled. */ if (!state->enabled || duty_steps == 0) { - ret = abx500_mask_and_set_register_interruptible(chip->dev, + ret = abx500_mask_and_set_register_interruptible(pwmchip_parent(chip), AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 1 << ab8500->hwid, 0); if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM, Error %d\n", pwm->label, ret); return ret; } @@ -115,22 +114,22 @@ static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2); - ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, + ret = abx500_set_register_interruptible(pwmchip_parent(chip), AB8500_MISC, reg, lower_val); if (ret < 0) return ret; - ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, + ret = abx500_set_register_interruptible(pwmchip_parent(chip), AB8500_MISC, (reg + 1), higher_val); if (ret < 0) return ret; /* enable */ - ret = abx500_mask_and_set_register_interruptible(chip->dev, + ret = abx500_mask_and_set_register_interruptible(pwmchip_parent(chip), AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 1 << ab8500->hwid, 1 << ab8500->hwid); if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM, Error %d\n", pwm->label, ret); return ret; @@ -144,7 +143,7 @@ static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); unsigned int div, duty_steps; - ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + ret = abx500_get_register_interruptible(pwmchip_parent(chip), AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, &ctrl7); if (ret) @@ -157,13 +156,13 @@ static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + ret = abx500_get_register_interruptible(pwmchip_parent(chip), AB8500_MISC, AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2), &lower_val); if (ret) return ret; - ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, + ret = abx500_get_register_interruptible(pwmchip_parent(chip), AB8500_MISC, AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2), &higher_val); if (ret) @@ -185,6 +184,7 @@ static const struct pwm_ops ab8500_pwm_ops = { static int ab8500_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct ab8500_pwm_chip *ab8500; int err; @@ -195,16 +195,16 @@ static int ab8500_pwm_probe(struct platform_device *pdev) * Nothing to be done in probe, this is required to get the * device which is required for ab8500 read and write */ - ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); - if (ab8500 == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*ab8500)); + if (IS_ERR(chip)) + return PTR_ERR(chip); - ab8500->chip.dev = &pdev->dev; - ab8500->chip.ops = &ab8500_pwm_ops; - ab8500->chip.npwm = 1; + ab8500 = ab8500_pwm_from_chip(chip); + + chip->ops = &ab8500_pwm_ops; ab8500->hwid = pdev->id - 1; - err = devm_pwmchip_add(&pdev->dev, &ab8500->chip); + err = devm_pwmchip_add(&pdev->dev, chip); if (err < 0) return dev_err_probe(&pdev->dev, err, "Failed to add pwm chip\n"); diff --git a/drivers/pwm/pwm-apple.c b/drivers/pwm/pwm-apple.c index 4d755b628d9e..6e58aca2f13c 100644 --- a/drivers/pwm/pwm-apple.c +++ b/drivers/pwm/pwm-apple.c @@ -32,14 +32,13 @@ #define APPLE_PWM_CTRL_OUTPUT_ENABLE BIT(14) struct apple_pwm { - struct pwm_chip chip; void __iomem *base; u64 clkrate; }; static inline struct apple_pwm *to_apple_pwm(struct pwm_chip *chip) { - return container_of(chip, struct apple_pwm, chip); + return pwmchip_get_drvdata(chip); } static int apple_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -103,13 +102,16 @@ static const struct pwm_ops apple_pwm_ops = { static int apple_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct apple_pwm *fpwm; struct clk *clk; int ret; - fpwm = devm_kzalloc(&pdev->dev, sizeof(*fpwm), GFP_KERNEL); - if (!fpwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*fpwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + fpwm = to_apple_pwm(chip); fpwm->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fpwm->base)) @@ -129,11 +131,9 @@ static int apple_pwm_probe(struct platform_device *pdev) if (fpwm->clkrate > NSEC_PER_SEC) return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock out of range"); - fpwm->chip.dev = &pdev->dev; - fpwm->chip.npwm = 1; - fpwm->chip.ops = &apple_pwm_ops; + chip->ops = &apple_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &fpwm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "unable to add pwm chip"); diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c index 3f2c5031a3ba..2afb302be02c 100644 --- a/drivers/pwm/pwm-atmel-hlcdc.c +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -28,7 +28,6 @@ struct atmel_hlcdc_pwm_errata { }; struct atmel_hlcdc_pwm { - struct pwm_chip chip; struct atmel_hlcdc *hlcdc; struct clk *cur_clk; const struct atmel_hlcdc_pwm_errata *errata; @@ -36,7 +35,7 @@ struct atmel_hlcdc_pwm { static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip) { - return container_of(chip, struct atmel_hlcdc_pwm, chip); + return pwmchip_get_drvdata(chip); } static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -182,10 +181,12 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = { static int atmel_hlcdc_pwm_suspend(struct device *dev) { - struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip); + struct pwm_device *pwm = &chip->pwms[0]; /* Keep the periph clock enabled if the PWM is still running. */ - if (pwm_is_enabled(&atmel->chip.pwms[0])) + if (!pwm->state.enabled) clk_disable_unprepare(atmel->hlcdc->periph_clk); return 0; @@ -193,21 +194,19 @@ static int atmel_hlcdc_pwm_suspend(struct device *dev) static int atmel_hlcdc_pwm_resume(struct device *dev) { - struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev); - struct pwm_state state; + struct pwm_chip *chip = dev_get_drvdata(dev); + struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip); + struct pwm_device *pwm = &chip->pwms[0]; int ret; - pwm_get_state(&atmel->chip.pwms[0], &state); - /* Re-enable the periph clock it was stopped during suspend. */ - if (!state.enabled) { + if (!pwm->state.enabled) { ret = clk_prepare_enable(atmel->hlcdc->periph_clk); if (ret) return ret; } - return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0], - &state); + return atmel_hlcdc_pwm_apply(chip, pwm, &pwm->state); } static DEFINE_SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops, @@ -243,15 +242,17 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) { const struct of_device_id *match; struct device *dev = &pdev->dev; + struct pwm_chip *chip; struct atmel_hlcdc_pwm *atmel; struct atmel_hlcdc *hlcdc; int ret; hlcdc = dev_get_drvdata(dev->parent); - atmel = devm_kzalloc(dev, sizeof(*atmel), GFP_KERNEL); - if (!atmel) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, 1, sizeof(*atmel)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + atmel = to_atmel_hlcdc_pwm(chip); ret = clk_prepare_enable(hlcdc->periph_clk); if (ret) @@ -262,26 +263,25 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) atmel->errata = match->data; atmel->hlcdc = hlcdc; - atmel->chip.ops = &atmel_hlcdc_pwm_ops; - atmel->chip.dev = dev; - atmel->chip.npwm = 1; + chip->ops = &atmel_hlcdc_pwm_ops; - ret = pwmchip_add(&atmel->chip); + ret = pwmchip_add(chip); if (ret) { clk_disable_unprepare(hlcdc->periph_clk); return ret; } - platform_set_drvdata(pdev, atmel); + platform_set_drvdata(pdev, chip); return 0; } static void atmel_hlcdc_pwm_remove(struct platform_device *pdev) { - struct atmel_hlcdc_pwm *atmel = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip); - pwmchip_remove(&atmel->chip); + pwmchip_remove(chip); clk_disable_unprepare(atmel->hlcdc->periph_clk); } diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index d42c897cb85e..528e54c5999d 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -47,7 +47,6 @@ struct atmel_tcb_channel { }; struct atmel_tcb_pwm_chip { - struct pwm_chip chip; spinlock_t lock; u8 channel; u8 width; @@ -63,7 +62,7 @@ static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128, 0, }; static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip) { - return container_of(chip, struct atmel_tcb_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int atmel_tcb_pwm_request(struct pwm_chip *chip, @@ -327,7 +326,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if ((atcbpwm && atcbpwm->duty > 0 && atcbpwm->duty != atcbpwm->period) && (atcbpwm->div != i || atcbpwm->period != period)) { - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), "failed to configure period_ns: PWM group already configured with a different value\n"); return -EINVAL; } @@ -388,6 +387,7 @@ static const struct of_device_id atmel_tcb_of_match[] = { static int atmel_tcb_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; const struct of_device_id *match; struct atmel_tcb_pwm_chip *tcbpwm; const struct atmel_tcb_config *config; @@ -396,9 +396,10 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) int err; int channel; - tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); - if (tcbpwm == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, NPWM, sizeof(*tcbpwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + tcbpwm = to_tcb_chip(chip); err = of_property_read_u32(np, "reg", &channel); if (err < 0) { @@ -436,9 +437,7 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) } } - tcbpwm->chip.dev = &pdev->dev; - tcbpwm->chip.ops = &atmel_tcb_pwm_ops; - tcbpwm->chip.npwm = NPWM; + chip->ops = &atmel_tcb_pwm_ops; tcbpwm->channel = channel; tcbpwm->width = config->counter_width; @@ -448,11 +447,11 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) spin_lock_init(&tcbpwm->lock); - err = pwmchip_add(&tcbpwm->chip); + err = pwmchip_add(chip); if (err < 0) goto err_disable_clk; - platform_set_drvdata(pdev, tcbpwm); + platform_set_drvdata(pdev, chip); return 0; @@ -473,9 +472,10 @@ err_slow_clk: static void atmel_tcb_pwm_remove(struct platform_device *pdev) { - struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip); - pwmchip_remove(&tcbpwm->chip); + pwmchip_remove(chip); clk_disable_unprepare(tcbpwm->slow_clk); clk_put(tcbpwm->gclk); @@ -491,7 +491,8 @@ MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids); static int atmel_tcb_pwm_suspend(struct device *dev) { - struct atmel_tcb_pwm_chip *tcbpwm = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip); struct atmel_tcb_channel *chan = &tcbpwm->bkup; unsigned int channel = tcbpwm->channel; @@ -505,7 +506,8 @@ static int atmel_tcb_pwm_suspend(struct device *dev) static int atmel_tcb_pwm_resume(struct device *dev) { - struct atmel_tcb_pwm_chip *tcbpwm = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct atmel_tcb_pwm_chip *tcbpwm = to_tcb_chip(chip); struct atmel_tcb_channel *chan = &tcbpwm->bkup; unsigned int channel = tcbpwm->channel; diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index 47bcc8a3bf9d..b2f0abbbad63 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c @@ -77,7 +77,6 @@ struct atmel_pwm_data { }; struct atmel_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; const struct atmel_pwm_data *data; @@ -99,7 +98,7 @@ struct atmel_pwm_chip { static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct atmel_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline u32 atmel_pwm_readl(struct atmel_pwm_chip *chip, @@ -210,7 +209,7 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip, shift = fls(cycles) - atmel_pwm->data->cfg.period_bits; if (shift > PWM_MAX_PRES) { - dev_err(chip->dev, "pres exceeds the maximum value\n"); + dev_err(pwmchip_parent(chip), "pres exceeds the maximum value\n"); return -EINVAL; } else if (shift > 0) { *pres = shift; @@ -294,19 +293,16 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); - struct pwm_state cstate; unsigned long cprd, cdty; u32 pres, val; int ret; - pwm_get_state(pwm, &cstate); - if (state->enabled) { unsigned long clkrate = clk_get_rate(atmel_pwm->clk); - if (cstate.enabled && - cstate.polarity == state->polarity && - cstate.period == state->period) { + if (pwm->state.enabled && + pwm->state.polarity == state->polarity && + pwm->state.period == state->period) { u32 cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR); cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, @@ -321,19 +317,19 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ret = atmel_pwm_calculate_cprd_and_pres(chip, clkrate, state, &cprd, &pres); if (ret) { - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), "failed to calculate cprd and prescaler\n"); return ret; } atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty); - if (cstate.enabled) { + if (pwm->state.enabled) { atmel_pwm_disable(chip, pwm, false); } else { ret = clk_enable(atmel_pwm->clk); if (ret) { - dev_err(chip->dev, "failed to enable clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable clock\n"); return ret; } } @@ -348,7 +344,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val); atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty); atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm); - } else if (cstate.enabled) { + } else if (pwm->state.enabled) { atmel_pwm_disable(chip, pwm, true); } @@ -462,8 +458,9 @@ static const struct of_device_id atmel_pwm_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids); -static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on) +static int atmel_pwm_enable_clk_if_on(struct pwm_chip *chip, bool on) { + struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); unsigned int i, cnt = 0; unsigned long sr; int ret = 0; @@ -472,7 +469,7 @@ static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on) if (!sr) return 0; - cnt = bitmap_weight(&sr, atmel_pwm->chip.npwm); + cnt = bitmap_weight(&sr, chip->npwm); if (!on) goto disable_clk; @@ -480,7 +477,7 @@ static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on) for (i = 0; i < cnt; i++) { ret = clk_enable(atmel_pwm->clk); if (ret) { - dev_err(atmel_pwm->chip.dev, + dev_err(pwmchip_parent(chip), "failed to enable clock for pwm %pe\n", ERR_PTR(ret)); @@ -501,12 +498,14 @@ disable_clk: static int atmel_pwm_probe(struct platform_device *pdev) { struct atmel_pwm_chip *atmel_pwm; + struct pwm_chip *chip; int ret; - atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL); - if (!atmel_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*atmel_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + atmel_pwm = to_atmel_pwm_chip(chip); atmel_pwm->data = of_device_get_match_data(&pdev->dev); atmel_pwm->update_pending = 0; @@ -521,15 +520,13 @@ static int atmel_pwm_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(atmel_pwm->clk), "failed to get prepared PWM clock\n"); - atmel_pwm->chip.dev = &pdev->dev; - atmel_pwm->chip.ops = &atmel_pwm_ops; - atmel_pwm->chip.npwm = 4; + chip->ops = &atmel_pwm_ops; - ret = atmel_pwm_enable_clk_if_on(atmel_pwm, true); + ret = atmel_pwm_enable_clk_if_on(chip, true); if (ret < 0) return ret; - ret = devm_pwmchip_add(&pdev->dev, &atmel_pwm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); goto disable_clk; @@ -538,7 +535,7 @@ static int atmel_pwm_probe(struct platform_device *pdev) return 0; disable_clk: - atmel_pwm_enable_clk_if_on(atmel_pwm, false); + atmel_pwm_enable_clk_if_on(chip, false); return ret; } diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c index 758254025683..f4c9f10e490e 100644 --- a/drivers/pwm/pwm-bcm-iproc.c +++ b/drivers/pwm/pwm-bcm-iproc.c @@ -34,14 +34,13 @@ #define IPROC_PWM_PRESCALE_MAX 0x3f struct iproc_pwmc { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; static inline struct iproc_pwmc *to_iproc_pwmc(struct pwm_chip *chip) { - return container_of(chip, struct iproc_pwmc, chip); + return pwmchip_get_drvdata(chip); } static void iproc_pwmc_enable(struct iproc_pwmc *ip, unsigned int channel) @@ -187,20 +186,20 @@ static const struct pwm_ops iproc_pwm_ops = { static int iproc_pwmc_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct iproc_pwmc *ip; unsigned int i; u32 value; int ret; - ip = devm_kzalloc(&pdev->dev, sizeof(*ip), GFP_KERNEL); - if (!ip) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 4, sizeof(*ip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + ip = to_iproc_pwmc(chip); platform_set_drvdata(pdev, ip); - ip->chip.dev = &pdev->dev; - ip->chip.ops = &iproc_pwm_ops; - ip->chip.npwm = 4; + chip->ops = &iproc_pwm_ops; ip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ip->base)) @@ -214,14 +213,14 @@ static int iproc_pwmc_probe(struct platform_device *pdev) /* Set full drive and normal polarity for all channels */ value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); - for (i = 0; i < ip->chip.npwm; i++) { + for (i = 0; i < chip->npwm; i++) { value &= ~(1 << IPROC_PWM_CTRL_TYPE_SHIFT(i)); value |= 1 << IPROC_PWM_CTRL_POLARITY_SHIFT(i); } writel(value, ip->base + IPROC_PWM_CTRL_OFFSET); - ret = devm_pwmchip_add(&pdev->dev, &ip->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c index 45046a5c20a5..022c078aae84 100644 --- a/drivers/pwm/pwm-bcm-kona.c +++ b/drivers/pwm/pwm-bcm-kona.c @@ -56,14 +56,13 @@ #define DUTY_CYCLE_HIGH_MAX 0x00ffffff struct kona_pwmc { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; static inline struct kona_pwmc *to_kona_pwmc(struct pwm_chip *chip) { - return container_of(chip, struct kona_pwmc, chip); + return pwmchip_get_drvdata(chip); } /* @@ -164,7 +163,7 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, ret = clk_prepare_enable(kp->clk); if (ret < 0) { - dev_err(chip->dev, "failed to enable clock: %d\n", ret); + dev_err(pwmchip_parent(chip), "failed to enable clock: %d\n", ret); return ret; } @@ -193,7 +192,7 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = clk_prepare_enable(kp->clk); if (ret < 0) { - dev_err(chip->dev, "failed to enable clock: %d\n", ret); + dev_err(pwmchip_parent(chip), "failed to enable clock: %d\n", ret); return ret; } @@ -273,18 +272,18 @@ static const struct pwm_ops kona_pwm_ops = { static int kona_pwmc_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct kona_pwmc *kp; unsigned int chan; unsigned int value = 0; int ret = 0; - kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); - if (kp == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 6, sizeof(*kp)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + kp = to_kona_pwmc(chip); - kp->chip.dev = &pdev->dev; - kp->chip.ops = &kona_pwm_ops; - kp->chip.npwm = 6; + chip->ops = &kona_pwm_ops; kp->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(kp->base)) @@ -304,14 +303,14 @@ static int kona_pwmc_probe(struct platform_device *pdev) } /* Set push/pull for all channels */ - for (chan = 0; chan < kp->chip.npwm; chan++) + for (chan = 0; chan < chip->npwm; chan++) value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan)); writel(value, kp->base + PWM_CONTROL_OFFSET); clk_disable_unprepare(kp->clk); - ret = devm_pwmchip_add(&pdev->dev, &kp->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index 283cf27f25ba..aa35acbb0cbc 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -24,8 +24,6 @@ #define PERIOD_MIN 0x2 struct bcm2835_pwm { - struct pwm_chip chip; - struct device *dev; void __iomem *base; struct clk *clk; unsigned long rate; @@ -33,7 +31,7 @@ struct bcm2835_pwm { static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) { - return container_of(chip, struct bcm2835_pwm, chip); + return pwmchip_get_drvdata(chip); } static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) @@ -135,14 +133,14 @@ static void devm_clk_rate_exclusive_put(void *data) static int bcm2835_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct bcm2835_pwm *pc; int ret; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; - - pc->dev = &pdev->dev; + chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_bcm2835_pwm(chip); pc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->base)) @@ -168,14 +166,12 @@ static int bcm2835_pwm_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, -EINVAL, "failed to get clock rate\n"); - pc->chip.dev = &pdev->dev; - pc->chip.ops = &bcm2835_pwm_ops; - pc->chip.atomic = true; - pc->chip.npwm = 2; + chip->ops = &bcm2835_pwm_ops; + chip->atomic = true; platform_set_drvdata(pdev, pc); - ret = devm_pwmchip_add(&pdev->dev, &pc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "failed to add pwmchip\n"); diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c index 442913232dc0..831aed228caf 100644 --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -49,7 +49,6 @@ struct berlin_pwm_channel { }; struct berlin_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; struct berlin_pwm_channel channel[BERLIN_PWM_NUMPWMS]; @@ -57,7 +56,7 @@ struct berlin_pwm_chip { static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct berlin_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *bpc, @@ -198,12 +197,14 @@ MODULE_DEVICE_TABLE(of, berlin_pwm_match); static int berlin_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct berlin_pwm_chip *bpc; int ret; - bpc = devm_kzalloc(&pdev->dev, sizeof(*bpc), GFP_KERNEL); - if (!bpc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, BERLIN_PWM_NUMPWMS, sizeof(*bpc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + bpc = to_berlin_pwm_chip(chip); bpc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(bpc->base)) @@ -213,25 +214,24 @@ static int berlin_pwm_probe(struct platform_device *pdev) if (IS_ERR(bpc->clk)) return PTR_ERR(bpc->clk); - bpc->chip.dev = &pdev->dev; - bpc->chip.ops = &berlin_pwm_ops; - bpc->chip.npwm = BERLIN_PWM_NUMPWMS; + chip->ops = &berlin_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &bpc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); - platform_set_drvdata(pdev, bpc); + platform_set_drvdata(pdev, chip); return 0; } static int berlin_pwm_suspend(struct device *dev) { - struct berlin_pwm_chip *bpc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip); unsigned int i; - for (i = 0; i < bpc->chip.npwm; i++) { + for (i = 0; i < chip->npwm; i++) { struct berlin_pwm_channel *channel = &bpc->channel[i]; channel->enable = berlin_pwm_readl(bpc, i, BERLIN_PWM_ENABLE); @@ -247,7 +247,8 @@ static int berlin_pwm_suspend(struct device *dev) static int berlin_pwm_resume(struct device *dev) { - struct berlin_pwm_chip *bpc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct berlin_pwm_chip *bpc = to_berlin_pwm_chip(chip); unsigned int i; int ret; @@ -255,7 +256,7 @@ static int berlin_pwm_resume(struct device *dev) if (ret) return ret; - for (i = 0; i < bpc->chip.npwm; i++) { + for (i = 0; i < chip->npwm; i++) { struct berlin_pwm_channel *channel = &bpc->channel[i]; berlin_pwm_writel(bpc, i, channel->ctrl, BERLIN_PWM_CONTROL); diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c index 0fdeb0b2dbf3..82d27d07ba91 100644 --- a/drivers/pwm/pwm-brcmstb.c +++ b/drivers/pwm/pwm-brcmstb.c @@ -54,7 +54,6 @@ struct brcmstb_pwm { void __iomem *base; struct clk *clk; - struct pwm_chip chip; }; static inline u32 brcmstb_pwm_readl(struct brcmstb_pwm *p, @@ -77,7 +76,7 @@ static inline void brcmstb_pwm_writel(struct brcmstb_pwm *p, u32 value, static inline struct brcmstb_pwm *to_brcmstb_pwm(struct pwm_chip *chip) { - return container_of(chip, struct brcmstb_pwm, chip); + return pwmchip_get_drvdata(chip); } /* @@ -230,12 +229,14 @@ MODULE_DEVICE_TABLE(of, brcmstb_pwm_of_match); static int brcmstb_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct brcmstb_pwm *p; int ret; - p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); - if (!p) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*p)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + p = to_brcmstb_pwm(chip); p->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(p->clk)) @@ -244,15 +245,13 @@ static int brcmstb_pwm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, p); - p->chip.dev = &pdev->dev; - p->chip.ops = &brcmstb_pwm_ops; - p->chip.npwm = 2; + chip->ops = &brcmstb_pwm_ops; p->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(p->base)) return PTR_ERR(p->base); - ret = devm_pwmchip_add(&pdev->dev, &p->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-clk.c b/drivers/pwm/pwm-clk.c index 9dd88b386907..c19a482d7e28 100644 --- a/drivers/pwm/pwm-clk.c +++ b/drivers/pwm/pwm-clk.c @@ -28,12 +28,14 @@ #include <linux/pwm.h> struct pwm_clk_chip { - struct pwm_chip chip; struct clk *clk; bool clk_enabled; }; -#define to_pwm_clk_chip(_chip) container_of(_chip, struct pwm_clk_chip, chip) +static inline struct pwm_clk_chip *to_pwm_clk_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static int pwm_clk_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) @@ -81,35 +83,36 @@ static const struct pwm_ops pwm_clk_ops = { static int pwm_clk_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct pwm_clk_chip *pcchip; int ret; - pcchip = devm_kzalloc(&pdev->dev, sizeof(*pcchip), GFP_KERNEL); - if (!pcchip) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pcchip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pcchip = to_pwm_clk_chip(chip); pcchip->clk = devm_clk_get_prepared(&pdev->dev, NULL); if (IS_ERR(pcchip->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(pcchip->clk), "Failed to get clock\n"); - pcchip->chip.dev = &pdev->dev; - pcchip->chip.ops = &pwm_clk_ops; - pcchip->chip.npwm = 1; + chip->ops = &pwm_clk_ops; - ret = pwmchip_add(&pcchip->chip); + ret = pwmchip_add(chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "Failed to add pwm chip\n"); - platform_set_drvdata(pdev, pcchip); + platform_set_drvdata(pdev, chip); return 0; } static void pwm_clk_remove(struct platform_device *pdev) { - struct pwm_clk_chip *pcchip = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct pwm_clk_chip *pcchip = to_pwm_clk_chip(chip); - pwmchip_remove(&pcchip->chip); + pwmchip_remove(chip); if (pcchip->clk_enabled) clk_disable(pcchip->clk); diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c index 42179b3f7ec3..c950e1dbd2b8 100644 --- a/drivers/pwm/pwm-clps711x.c +++ b/drivers/pwm/pwm-clps711x.c @@ -12,7 +12,6 @@ #include <linux/pwm.h> struct clps711x_chip { - struct pwm_chip chip; void __iomem *pmpcon; struct clk *clk; spinlock_t lock; @@ -20,7 +19,7 @@ struct clps711x_chip { static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip) { - return container_of(chip, struct clps711x_chip, chip); + return pwmchip_get_drvdata(chip); } static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) @@ -74,22 +73,15 @@ static const struct pwm_ops clps711x_pwm_ops = { .apply = clps711x_pwm_apply, }; -static struct pwm_device *clps711x_pwm_xlate(struct pwm_chip *chip, - const struct of_phandle_args *args) -{ - if (args->args[0] >= chip->npwm) - return ERR_PTR(-EINVAL); - - return pwm_request_from_chip(chip, args->args[0], NULL); -} - static int clps711x_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct clps711x_chip *priv; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = to_clps711x_chip(chip); priv->pmpcon = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->pmpcon)) @@ -99,15 +91,11 @@ static int clps711x_pwm_probe(struct platform_device *pdev) if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); - priv->chip.ops = &clps711x_pwm_ops; - priv->chip.dev = &pdev->dev; - priv->chip.npwm = 2; - priv->chip.of_xlate = clps711x_pwm_xlate; - priv->chip.of_pwm_n_cells = 1; + chip->ops = &clps711x_pwm_ops; spin_lock_init(&priv->lock); - return devm_pwmchip_add(&pdev->dev, &priv->chip); + return devm_pwmchip_add(&pdev->dev, chip); } static const struct of_device_id __maybe_unused clps711x_pwm_dt_ids[] = { diff --git a/drivers/pwm/pwm-crc.c b/drivers/pwm/pwm-crc.c index e09358901ab5..98ee5cdbd0ba 100644 --- a/drivers/pwm/pwm-crc.c +++ b/drivers/pwm/pwm-crc.c @@ -26,17 +26,15 @@ /** * struct crystalcove_pwm - Crystal Cove PWM controller - * @chip: the abstract pwm_chip structure. * @regmap: the regmap from the parent device. */ struct crystalcove_pwm { - struct pwm_chip chip; struct regmap *regmap; }; static inline struct crystalcove_pwm *to_crc_pwm(struct pwm_chip *chip) { - return container_of(chip, struct crystalcove_pwm, chip); + return pwmchip_get_drvdata(chip); } static int crc_pwm_calc_clk_div(int period_ns) @@ -55,7 +53,7 @@ static int crc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip); - struct device *dev = crc_pwm->chip.dev; + struct device *dev = pwmchip_parent(chip); int err; if (state->period > PWM_MAX_PERIOD_NS) { @@ -125,7 +123,7 @@ static int crc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { struct crystalcove_pwm *crc_pwm = to_crc_pwm(chip); - struct device *dev = crc_pwm->chip.dev; + struct device *dev = pwmchip_parent(chip); unsigned int clk_div, clk_div_reg, duty_cycle_reg; int error; @@ -160,22 +158,22 @@ static const struct pwm_ops crc_pwm_ops = { static int crystalcove_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct crystalcove_pwm *crc_pwm; struct device *dev = pdev->dev.parent; struct intel_soc_pmic *pmic = dev_get_drvdata(dev); - crc_pwm = devm_kzalloc(&pdev->dev, sizeof(*crc_pwm), GFP_KERNEL); - if (!crc_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*crc_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + crc_pwm = to_crc_pwm(chip); - crc_pwm->chip.dev = &pdev->dev; - crc_pwm->chip.ops = &crc_pwm_ops; - crc_pwm->chip.npwm = 1; + chip->ops = &crc_pwm_ops; /* get the PMIC regmap */ crc_pwm->regmap = pmic->regmap; - return devm_pwmchip_add(&pdev->dev, &crc_pwm->chip); + return devm_pwmchip_add(&pdev->dev, chip); } static struct platform_driver crystalcove_pwm_driver = { diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 5fe303b8656d..606ccfdaf4cc 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -19,13 +19,11 @@ * struct cros_ec_pwm_device - Driver data for EC PWM * * @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 cros_ec_device *ec; - struct pwm_chip chip; bool use_pwm_type; struct cros_ec_pwm *channel; }; @@ -40,7 +38,7 @@ struct cros_ec_pwm { static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *chip) { - return container_of(chip, struct cros_ec_pwm_device, chip); + return pwmchip_get_drvdata(chip); } static int cros_ec_dt_type_to_pwm_type(u8 dt_index, u8 *pwm_type) @@ -93,9 +91,8 @@ static int cros_ec_pwm_set_duty(struct cros_ec_pwm_device *ec_pwm, u8 index, return cros_ec_cmd_xfer_status(ec, msg); } -static int cros_ec_pwm_get_duty(struct cros_ec_pwm_device *ec_pwm, u8 index) +static int cros_ec_pwm_get_duty(struct cros_ec_device *ec, bool use_pwm_type, u8 index) { - struct cros_ec_device *ec = ec_pwm->ec; struct { struct cros_ec_command msg; union { @@ -115,7 +112,7 @@ static int cros_ec_pwm_get_duty(struct cros_ec_pwm_device *ec_pwm, u8 index) msg->insize = sizeof(*resp); msg->outsize = sizeof(*params); - if (ec_pwm->use_pwm_type) { + if (use_pwm_type) { ret = cros_ec_dt_type_to_pwm_type(index, ¶ms->pwm_type); if (ret) { dev_err(ec->dev, "Invalid PWM type index: %d\n", index); @@ -171,9 +168,9 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct cros_ec_pwm *channel = &ec_pwm->channel[pwm->hwpwm]; int ret; - ret = cros_ec_pwm_get_duty(ec_pwm, pwm->hwpwm); + ret = cros_ec_pwm_get_duty(ec_pwm->ec, ec_pwm->use_pwm_type, pwm->hwpwm); if (ret < 0) { - dev_err(chip->dev, "error getting initial duty: %d\n", ret); + dev_err(pwmchip_parent(chip), "error getting initial duty: %d\n", ret); return ret; } @@ -226,13 +223,17 @@ static const struct pwm_ops cros_ec_pwm_ops = { * of PWMs it supports directly, so we have to read the pwm duty cycle for * subsequent channels until we get an error. */ -static int cros_ec_num_pwms(struct cros_ec_pwm_device *ec_pwm) +static int cros_ec_num_pwms(struct cros_ec_device *ec) { int i, ret; /* The index field is only 8 bits */ for (i = 0; i <= U8_MAX; i++) { - ret = cros_ec_pwm_get_duty(ec_pwm, i); + /* + * Note that this function is only called when use_pwm_type is + * false. With use_pwm_type == true the number of PWMs is fixed. + */ + ret = cros_ec_pwm_get_duty(ec, false, i); /* * We look for SUCCESS, INVALID_COMMAND, or INVALID_PARAM * responses; everything else is treated as an error. @@ -261,34 +262,34 @@ static int cros_ec_pwm_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct cros_ec_pwm_device *ec_pwm; struct pwm_chip *chip; + bool use_pwm_type = false; + unsigned int npwm; int ret; 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) - return -ENOMEM; - chip = &ec_pwm->chip; - ec_pwm->ec = ec; + if (of_device_is_compatible(np, "google,cros-ec-pwm-type")) { + use_pwm_type = true; + npwm = CROS_EC_PWM_DT_COUNT; + } else { + ret = cros_ec_num_pwms(ec); + if (ret < 0) + return dev_err_probe(dev, ret, "Couldn't find PWMs\n"); + npwm = ret; + } + + chip = devm_pwmchip_alloc(dev, npwm, sizeof(*ec_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); - if (of_device_is_compatible(np, "google,cros-ec-pwm-type")) - ec_pwm->use_pwm_type = true; + ec_pwm = pwm_to_cros_ec_pwm(chip); + ec_pwm->use_pwm_type = use_pwm_type; + ec_pwm->ec = ec; /* PWM chip */ - chip->dev = dev; chip->ops = &cros_ec_pwm_ops; chip->of_xlate = cros_ec_pwm_xlate; - chip->of_pwm_n_cells = 1; - - if (ec_pwm->use_pwm_type) { - chip->npwm = CROS_EC_PWM_DT_COUNT; - } else { - ret = cros_ec_num_pwms(ec_pwm); - 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); diff --git a/drivers/pwm/pwm-dwc-core.c b/drivers/pwm/pwm-dwc-core.c index ea63dd741f5c..043736972cb9 100644 --- a/drivers/pwm/pwm-dwc-core.c +++ b/drivers/pwm/pwm-dwc-core.c @@ -105,12 +105,12 @@ static int dwc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->enabled) { if (!pwm->state.enabled) - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); 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); + pm_runtime_put_sync(pwmchip_parent(chip)); } } @@ -124,7 +124,7 @@ static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, u64 duty, period; u32 ctrl, ld, ld2; - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(pwm->hwpwm)); ld = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(pwm->hwpwm)); @@ -149,7 +149,7 @@ static int dwc_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, state->period = period; state->duty_cycle = duty; - pm_runtime_put_sync(chip->dev); + pm_runtime_put_sync(pwmchip_parent(chip)); return 0; } @@ -159,21 +159,21 @@ static const struct pwm_ops dwc_pwm_ops = { .get_state = dwc_pwm_get_state, }; -struct dwc_pwm *dwc_pwm_alloc(struct device *dev) +struct pwm_chip *dwc_pwm_alloc(struct device *dev) { + struct pwm_chip *chip; struct dwc_pwm *dwc; - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); - if (!dwc) - return NULL; + chip = devm_pwmchip_alloc(dev, DWC_TIMERS_TOTAL, sizeof(*dwc)); + if (IS_ERR(chip)) + return chip; + dwc = to_dwc_pwm(chip); dwc->clk_ns = 10; - dwc->chip.dev = dev; - dwc->chip.ops = &dwc_pwm_ops; - dwc->chip.npwm = DWC_TIMERS_TOTAL; + chip->ops = &dwc_pwm_ops; - dev_set_drvdata(dev, dwc); - return dwc; + dev_set_drvdata(dev, chip); + return chip; } EXPORT_SYMBOL_GPL(dwc_pwm_alloc); diff --git a/drivers/pwm/pwm-dwc.c b/drivers/pwm/pwm-dwc.c index 4929354f8cd9..676eaf8d7a53 100644 --- a/drivers/pwm/pwm-dwc.c +++ b/drivers/pwm/pwm-dwc.c @@ -25,39 +25,54 @@ #include "pwm-dwc.h" -static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) +/* Elkhart Lake */ +static const struct dwc_pwm_info ehl_pwm_info = { + .nr = 2, + .size = 0x1000, +}; + +static int dwc_pwm_init_one(struct device *dev, void __iomem *base, unsigned int offset) { - struct device *dev = &pci->dev; + struct pwm_chip *chip; struct dwc_pwm *dwc; - int ret; - dwc = dwc_pwm_alloc(dev); - if (!dwc) - return -ENOMEM; + chip = dwc_pwm_alloc(dev); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + dwc = to_dwc_pwm(chip); + dwc->base = base + offset; + + return devm_pwmchip_add(dev, chip); +} + +static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) +{ + const struct dwc_pwm_info *info; + struct device *dev = &pci->dev; + int i, ret; ret = pcim_enable_device(pci); - if (ret) { - dev_err(dev, "Failed to enable device (%pe)\n", ERR_PTR(ret)); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to enable device\n"); pci_set_master(pci); ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci)); - if (ret) { - dev_err(dev, "Failed to iomap PCI BAR (%pe)\n", ERR_PTR(ret)); - return ret; - } - - dwc->base = pcim_iomap_table(pci)[0]; - if (!dwc->base) { - dev_err(dev, "Base address missing\n"); - return -ENOMEM; - } - - ret = devm_pwmchip_add(dev, &dwc->chip); if (ret) - return ret; + return dev_err_probe(dev, ret, "Failed to iomap PCI BAR\n"); + + info = (const struct dwc_pwm_info *)id->driver_data; + + for (i = 0; i < info->nr; i++) { + /* + * No need to check for pcim_iomap_table() failure, + * pcim_iomap_regions() already does it for us. + */ + ret = dwc_pwm_init_one(dev, pcim_iomap_table(pci)[0], i * info->size); + if (ret) + return ret; + } pm_runtime_put(dev); pm_runtime_allow(dev); @@ -73,14 +88,14 @@ static void dwc_pwm_remove(struct pci_dev *pci) static int dwc_pwm_suspend(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); - struct dwc_pwm *dwc = pci_get_drvdata(pdev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct dwc_pwm *dwc = to_dwc_pwm(chip); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { - if (dwc->chip.pwms[i].state.enabled) { + if (chip->pwms[i].state.enabled) { dev_err(dev, "PWM %u in use by consumer (%s)\n", - i, dwc->chip.pwms[i].label); + i, chip->pwms[i].label); return -EBUSY; } dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i)); @@ -93,8 +108,8 @@ static int dwc_pwm_suspend(struct device *dev) static int dwc_pwm_resume(struct device *dev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); - struct dwc_pwm *dwc = pci_get_drvdata(pdev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct dwc_pwm *dwc = to_dwc_pwm(chip); int i; for (i = 0; i < DWC_TIMERS_TOTAL; i++) { @@ -109,7 +124,7 @@ static int dwc_pwm_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume); static const struct pci_device_id dwc_pwm_id_table[] = { - { PCI_VDEVICE(INTEL, 0x4bb7) }, /* Elkhart Lake */ + { PCI_VDEVICE(INTEL, 0x4bb7), (kernel_ulong_t)&ehl_pwm_info }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table); @@ -120,7 +135,7 @@ static struct pci_driver dwc_pwm_driver = { .remove = dwc_pwm_remove, .id_table = dwc_pwm_id_table, .driver = { - .pm = pm_ptr(&dwc_pwm_pm_ops), + .pm = pm_sleep_ptr(&dwc_pwm_pm_ops), }, }; diff --git a/drivers/pwm/pwm-dwc.h b/drivers/pwm/pwm-dwc.h index 64795247c54c..a8b074841ae8 100644 --- a/drivers/pwm/pwm-dwc.h +++ b/drivers/pwm/pwm-dwc.h @@ -33,6 +33,11 @@ MODULE_IMPORT_NS(dwc_pwm); #define DWC_TIM_CTRL_INT_MASK BIT(2) #define DWC_TIM_CTRL_PWM BIT(3) +struct dwc_pwm_info { + unsigned int nr; + unsigned int size; +}; + struct dwc_pwm_ctx { u32 cnt; u32 cnt2; @@ -40,12 +45,15 @@ struct dwc_pwm_ctx { }; 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 struct dwc_pwm *to_dwc_pwm(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static inline u32 dwc_pwm_readl(struct dwc_pwm *dwc, u32 offset) { @@ -57,4 +65,4 @@ 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); +extern struct pwm_chip *dwc_pwm_alloc(struct device *dev); diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c index 51e072572a87..666f2954133c 100644 --- a/drivers/pwm/pwm-ep93xx.c +++ b/drivers/pwm/pwm-ep93xx.c @@ -36,24 +36,23 @@ struct ep93xx_pwm { void __iomem *base; struct clk *clk; - struct pwm_chip chip; }; static inline struct ep93xx_pwm *to_ep93xx_pwm(struct pwm_chip *chip) { - return container_of(chip, struct ep93xx_pwm, chip); + return pwmchip_get_drvdata(chip); } static int ep93xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) { - struct platform_device *pdev = to_platform_device(chip->dev); + struct platform_device *pdev = to_platform_device(pwmchip_parent(chip)); return ep93xx_pwm_acquire_gpio(pdev); } static void ep93xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { - struct platform_device *pdev = to_platform_device(chip->dev); + struct platform_device *pdev = to_platform_device(pwmchip_parent(chip)); ep93xx_pwm_release_gpio(pdev); } @@ -163,12 +162,14 @@ static const struct pwm_ops ep93xx_pwm_ops = { static int ep93xx_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct ep93xx_pwm *ep93xx_pwm; int ret; - ep93xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_pwm), GFP_KERNEL); - if (!ep93xx_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*ep93xx_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + ep93xx_pwm = to_ep93xx_pwm(chip); ep93xx_pwm->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ep93xx_pwm->base)) @@ -178,11 +179,9 @@ static int ep93xx_pwm_probe(struct platform_device *pdev) if (IS_ERR(ep93xx_pwm->clk)) return PTR_ERR(ep93xx_pwm->clk); - ep93xx_pwm->chip.dev = &pdev->dev; - ep93xx_pwm->chip.ops = &ep93xx_pwm_ops; - ep93xx_pwm->chip.npwm = 1; + chip->ops = &ep93xx_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &ep93xx_pwm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return ret; diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c index d1b6d1aa4773..2510c10ca473 100644 --- a/drivers/pwm/pwm-fsl-ftm.c +++ b/drivers/pwm/pwm-fsl-ftm.c @@ -40,7 +40,6 @@ struct fsl_pwm_periodcfg { }; struct fsl_pwm_chip { - struct pwm_chip chip; struct mutex lock; struct regmap *regmap; @@ -55,7 +54,7 @@ struct fsl_pwm_chip { static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip) { - return container_of(chip, struct fsl_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc) @@ -221,10 +220,11 @@ static bool fsl_pwm_is_other_pwm_enabled(struct fsl_pwm_chip *fpc, return false; } -static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc, +static int fsl_pwm_apply_config(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *newstate) { + struct fsl_pwm_chip *fpc = to_fsl_chip(chip); unsigned int duty; u32 reg_polarity; @@ -232,7 +232,7 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc, bool do_write_period = false; if (!fsl_pwm_calculate_period(fpc, newstate->period, &periodcfg)) { - dev_err(fpc->chip.dev, "failed to calculate new period\n"); + dev_err(pwmchip_parent(chip), "failed to calculate new period\n"); return -EINVAL; } @@ -246,7 +246,7 @@ static int fsl_pwm_apply_config(struct fsl_pwm_chip *fpc, */ else if (!fsl_pwm_periodcfg_are_equal(&fpc->period, &periodcfg)) { if (fsl_pwm_is_other_pwm_enabled(fpc, pwm)) { - dev_err(fpc->chip.dev, + dev_err(pwmchip_parent(chip), "Cannot change period for PWM %u, disable other PWMs first\n", pwm->hwpwm); return -EBUSY; @@ -322,7 +322,7 @@ static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, goto end_mutex; } - ret = fsl_pwm_apply_config(fpc, pwm, newstate); + ret = fsl_pwm_apply_config(chip, pwm, newstate); if (ret) goto end_mutex; @@ -392,18 +392,19 @@ static const struct regmap_config fsl_pwm_regmap_config = { static int fsl_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct fsl_pwm_chip *fpc; void __iomem *base; int ret; - fpc = devm_kzalloc(&pdev->dev, sizeof(*fpc), GFP_KERNEL); - if (!fpc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 8, sizeof(*fpc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + fpc = to_fsl_chip(chip); mutex_init(&fpc->lock); fpc->soc = of_device_get_match_data(&pdev->dev); - fpc->chip.dev = &pdev->dev; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) @@ -422,16 +423,16 @@ static int fsl_pwm_probe(struct platform_device *pdev) return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]); } - fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(fpc->chip.dev, "ftm_fix"); + fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(&pdev->dev, "ftm_fix"); if (IS_ERR(fpc->clk[FSL_PWM_CLK_FIX])) return PTR_ERR(fpc->clk[FSL_PWM_CLK_FIX]); - fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(fpc->chip.dev, "ftm_ext"); + fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(&pdev->dev, "ftm_ext"); if (IS_ERR(fpc->clk[FSL_PWM_CLK_EXT])) return PTR_ERR(fpc->clk[FSL_PWM_CLK_EXT]); fpc->clk[FSL_PWM_CLK_CNTEN] = - devm_clk_get(fpc->chip.dev, "ftm_cnt_clk_en"); + devm_clk_get(&pdev->dev, "ftm_cnt_clk_en"); if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN])) return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]); @@ -443,17 +444,15 @@ static int fsl_pwm_probe(struct platform_device *pdev) if (IS_ERR(fpc->ipg_clk)) fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS]; + chip->ops = &fsl_pwm_ops; - fpc->chip.ops = &fsl_pwm_ops; - fpc->chip.npwm = 8; - - ret = devm_pwmchip_add(&pdev->dev, &fpc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); return ret; } - platform_set_drvdata(pdev, fpc); + platform_set_drvdata(pdev, chip); return fsl_pwm_init(fpc); } @@ -461,14 +460,15 @@ static int fsl_pwm_probe(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int fsl_pwm_suspend(struct device *dev) { - struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct fsl_pwm_chip *fpc = to_fsl_chip(chip); int i; regcache_cache_only(fpc->regmap, true); regcache_mark_dirty(fpc->regmap); - for (i = 0; i < fpc->chip.npwm; i++) { - struct pwm_device *pwm = &fpc->chip.pwms[i]; + for (i = 0; i < chip->npwm; i++) { + struct pwm_device *pwm = &chip->pwms[i]; if (!test_bit(PWMF_REQUESTED, &pwm->flags)) continue; @@ -487,11 +487,12 @@ static int fsl_pwm_suspend(struct device *dev) static int fsl_pwm_resume(struct device *dev) { - struct fsl_pwm_chip *fpc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct fsl_pwm_chip *fpc = to_fsl_chip(chip); int i; - for (i = 0; i < fpc->chip.npwm; i++) { - struct pwm_device *pwm = &fpc->chip.pwms[i]; + for (i = 0; i < chip->npwm; i++) { + struct pwm_device *pwm = &chip->pwms[i]; if (!test_bit(PWMF_REQUESTED, &pwm->flags)) continue; diff --git a/drivers/pwm/pwm-hibvt.c b/drivers/pwm/pwm-hibvt.c index c435776e2f78..2eb0b13d4e10 100644 --- a/drivers/pwm/pwm-hibvt.c +++ b/drivers/pwm/pwm-hibvt.c @@ -33,7 +33,6 @@ #define PWM_DUTY_MASK GENMASK(31, 0) struct hibvt_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; struct reset_control *rstc; @@ -65,7 +64,7 @@ static const struct hibvt_pwm_soc hi3559v100_soc_info = { static inline struct hibvt_pwm_chip *to_hibvt_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct hibvt_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static void hibvt_pwm_set_bits(void __iomem *base, u32 offset, @@ -191,72 +190,71 @@ static int hibvt_pwm_probe(struct platform_device *pdev) { const struct hibvt_pwm_soc *soc = of_device_get_match_data(&pdev->dev); - struct hibvt_pwm_chip *pwm_chip; + struct pwm_chip *chip; + struct hibvt_pwm_chip *hi_pwm_chip; int ret, i; - pwm_chip = devm_kzalloc(&pdev->dev, sizeof(*pwm_chip), GFP_KERNEL); - if (pwm_chip == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*hi_pwm_chip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + hi_pwm_chip = to_hibvt_pwm_chip(chip); - pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pwm_chip->clk)) { + hi_pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(hi_pwm_chip->clk)) { dev_err(&pdev->dev, "getting clock failed with %ld\n", - PTR_ERR(pwm_chip->clk)); - return PTR_ERR(pwm_chip->clk); + PTR_ERR(hi_pwm_chip->clk)); + return PTR_ERR(hi_pwm_chip->clk); } - pwm_chip->chip.ops = &hibvt_pwm_ops; - pwm_chip->chip.dev = &pdev->dev; - pwm_chip->chip.npwm = soc->num_pwms; - pwm_chip->soc = soc; + chip->ops = &hibvt_pwm_ops; + hi_pwm_chip->soc = soc; - pwm_chip->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(pwm_chip->base)) - return PTR_ERR(pwm_chip->base); + hi_pwm_chip->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hi_pwm_chip->base)) + return PTR_ERR(hi_pwm_chip->base); - ret = clk_prepare_enable(pwm_chip->clk); + ret = clk_prepare_enable(hi_pwm_chip->clk); if (ret < 0) return ret; - pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(pwm_chip->rstc)) { - clk_disable_unprepare(pwm_chip->clk); - return PTR_ERR(pwm_chip->rstc); + hi_pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(hi_pwm_chip->rstc)) { + clk_disable_unprepare(hi_pwm_chip->clk); + return PTR_ERR(hi_pwm_chip->rstc); } - reset_control_assert(pwm_chip->rstc); + reset_control_assert(hi_pwm_chip->rstc); msleep(30); - reset_control_deassert(pwm_chip->rstc); + reset_control_deassert(hi_pwm_chip->rstc); - ret = pwmchip_add(&pwm_chip->chip); + ret = pwmchip_add(chip); if (ret < 0) { - clk_disable_unprepare(pwm_chip->clk); + clk_disable_unprepare(hi_pwm_chip->clk); return ret; } - for (i = 0; i < pwm_chip->chip.npwm; i++) { - hibvt_pwm_set_bits(pwm_chip->base, PWM_CTRL_ADDR(i), + for (i = 0; i < chip->npwm; i++) { + hibvt_pwm_set_bits(hi_pwm_chip->base, PWM_CTRL_ADDR(i), PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT)); } - platform_set_drvdata(pdev, pwm_chip); + platform_set_drvdata(pdev, chip); return 0; } static void hibvt_pwm_remove(struct platform_device *pdev) { - struct hibvt_pwm_chip *pwm_chip; - - pwm_chip = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct hibvt_pwm_chip *hi_pwm_chip = to_hibvt_pwm_chip(chip); - pwmchip_remove(&pwm_chip->chip); + pwmchip_remove(chip); - reset_control_assert(pwm_chip->rstc); + reset_control_assert(hi_pwm_chip->rstc); msleep(30); - reset_control_deassert(pwm_chip->rstc); + reset_control_deassert(hi_pwm_chip->rstc); - clk_disable_unprepare(pwm_chip->clk); + clk_disable_unprepare(hi_pwm_chip->clk); } static const struct of_device_id hibvt_pwm_of_match[] = { diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index 5965ac35b32e..d79a96679a26 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -59,8 +59,6 @@ struct img_pwm_soc_data { }; struct img_pwm_chip { - struct device *dev; - struct pwm_chip chip; struct clk *pwm_clk; struct clk *sys_clk; void __iomem *base; @@ -74,7 +72,7 @@ struct img_pwm_chip { static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct img_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline void img_pwm_writel(struct img_pwm_chip *imgchip, @@ -99,7 +97,7 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (period_ns < imgchip->min_period_ns || period_ns > imgchip->max_period_ns) { - dev_err(chip->dev, "configured period not in range\n"); + dev_err(pwmchip_parent(chip), "configured period not in range\n"); return -ERANGE; } @@ -120,14 +118,14 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, div = PWM_CTRL_CFG_SUB_DIV0_DIV1; timebase = DIV_ROUND_UP(mul, 512); } else { - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), "failed to configure timebase steps/divider value\n"); return -EINVAL; } duty = DIV_ROUND_UP(timebase * duty_ns, period_ns); - ret = pm_runtime_resume_and_get(chip->dev); + ret = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (ret < 0) return ret; @@ -141,8 +139,8 @@ static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, (timebase << PWM_CH_CFG_TMBASE_SHIFT); img_pwm_writel(imgchip, PWM_CH_CFG(pwm->hwpwm), val); - pm_runtime_mark_last_busy(chip->dev); - pm_runtime_put_autosuspend(chip->dev); + pm_runtime_mark_last_busy(pwmchip_parent(chip)); + pm_runtime_put_autosuspend(pwmchip_parent(chip)); return 0; } @@ -153,7 +151,7 @@ static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct img_pwm_chip *imgchip = to_img_pwm_chip(chip); int ret; - ret = pm_runtime_resume_and_get(chip->dev); + ret = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (ret < 0) return ret; @@ -177,8 +175,8 @@ static void img_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) val &= ~BIT(pwm->hwpwm); img_pwm_writel(imgchip, PWM_CTRL_CFG, val); - pm_runtime_mark_last_busy(chip->dev); - pm_runtime_put_autosuspend(chip->dev); + pm_runtime_mark_last_busy(pwmchip_parent(chip)); + pm_runtime_put_autosuspend(pwmchip_parent(chip)); } static int img_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -225,7 +223,8 @@ MODULE_DEVICE_TABLE(of, img_pwm_of_match); static int img_pwm_runtime_suspend(struct device *dev) { - struct img_pwm_chip *imgchip = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct img_pwm_chip *imgchip = to_img_pwm_chip(chip); clk_disable_unprepare(imgchip->pwm_clk); clk_disable_unprepare(imgchip->sys_clk); @@ -235,7 +234,8 @@ static int img_pwm_runtime_suspend(struct device *dev) static int img_pwm_runtime_resume(struct device *dev) { - struct img_pwm_chip *imgchip = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct img_pwm_chip *imgchip = to_img_pwm_chip(chip); int ret; ret = clk_prepare_enable(imgchip->sys_clk); @@ -259,13 +259,13 @@ static int img_pwm_probe(struct platform_device *pdev) int ret; u64 val; unsigned long clk_rate; + struct pwm_chip *chip; struct img_pwm_chip *imgchip; - imgchip = devm_kzalloc(&pdev->dev, sizeof(*imgchip), GFP_KERNEL); - if (!imgchip) - return -ENOMEM; - - imgchip->dev = &pdev->dev; + chip = devm_pwmchip_alloc(&pdev->dev, IMG_PWM_NPWM, sizeof(*imgchip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + imgchip = to_img_pwm_chip(chip); imgchip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(imgchip->base)) @@ -290,7 +290,7 @@ static int img_pwm_probe(struct platform_device *pdev) return PTR_ERR(imgchip->pwm_clk); } - platform_set_drvdata(pdev, imgchip); + platform_set_drvdata(pdev, chip); pm_runtime_set_autosuspend_delay(&pdev->dev, IMG_PWM_PM_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); @@ -317,11 +317,9 @@ static int img_pwm_probe(struct platform_device *pdev) do_div(val, clk_rate); imgchip->min_period_ns = val; - imgchip->chip.dev = &pdev->dev; - imgchip->chip.ops = &img_pwm_ops; - imgchip->chip.npwm = IMG_PWM_NPWM; + chip->ops = &img_pwm_ops; - ret = pwmchip_add(&imgchip->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret); goto err_suspend; @@ -340,19 +338,20 @@ err_pm_disable: static void img_pwm_remove(struct platform_device *pdev) { - struct img_pwm_chip *imgchip = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) img_pwm_runtime_suspend(&pdev->dev); - pwmchip_remove(&imgchip->chip); + pwmchip_remove(chip); } #ifdef CONFIG_PM_SLEEP static int img_pwm_suspend(struct device *dev) { - struct img_pwm_chip *imgchip = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct img_pwm_chip *imgchip = to_img_pwm_chip(chip); int i, ret; if (pm_runtime_status_suspended(dev)) { @@ -361,7 +360,7 @@ static int img_pwm_suspend(struct device *dev) return ret; } - for (i = 0; i < imgchip->chip.npwm; i++) + for (i = 0; i < chip->npwm; i++) imgchip->suspend_ch_cfg[i] = img_pwm_readl(imgchip, PWM_CH_CFG(i)); @@ -374,7 +373,8 @@ static int img_pwm_suspend(struct device *dev) static int img_pwm_resume(struct device *dev) { - struct img_pwm_chip *imgchip = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct img_pwm_chip *imgchip = to_img_pwm_chip(chip); int ret; int i; @@ -382,13 +382,13 @@ static int img_pwm_resume(struct device *dev) if (ret) return ret; - for (i = 0; i < imgchip->chip.npwm; i++) + for (i = 0; i < chip->npwm; i++) img_pwm_writel(imgchip, PWM_CH_CFG(i), imgchip->suspend_ch_cfg[i]); img_pwm_writel(imgchip, PWM_CTRL_CFG, imgchip->suspend_ctrl_cfg); - for (i = 0; i < imgchip->chip.npwm; i++) + for (i = 0; i < chip->npwm; i++) if (imgchip->suspend_ctrl_cfg & BIT(i)) regmap_clear_bits(imgchip->periph_regs, PERIP_PWM_PDM_CONTROL, diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c index 9fc290e647e1..c50ddbac43c8 100644 --- a/drivers/pwm/pwm-imx-tpm.c +++ b/drivers/pwm/pwm-imx-tpm.c @@ -57,7 +57,6 @@ #define PWM_IMX_TPM_MOD_MOD GENMASK(PWM_IMX_TPM_MOD_WIDTH - 1, 0) struct imx_tpm_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; struct mutex lock; @@ -75,7 +74,7 @@ struct imx_tpm_pwm_param { static inline struct imx_tpm_pwm_chip * to_imx_tpm_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct imx_tpm_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } /* @@ -336,35 +335,42 @@ static const struct pwm_ops imx_tpm_pwm_ops = { static int pwm_imx_tpm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct imx_tpm_pwm_chip *tpm; + struct clk *clk; + void __iomem *base; int ret; + unsigned int npwm; u32 val; - tpm = devm_kzalloc(&pdev->dev, sizeof(*tpm), GFP_KERNEL); - if (!tpm) - return -ENOMEM; + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); - platform_set_drvdata(pdev, tpm); + clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk), + "failed to get PWM clock\n"); - tpm->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(tpm->base)) - return PTR_ERR(tpm->base); + /* get number of channels */ + val = readl(base + PWM_IMX_TPM_PARAM); + npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val); - 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"); + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*tpm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + tpm = to_imx_tpm_pwm_chip(chip); + + platform_set_drvdata(pdev, tpm); - tpm->chip.dev = &pdev->dev; - tpm->chip.ops = &imx_tpm_pwm_ops; + tpm->base = base; + tpm->clk = clk; - /* get number of channels */ - val = readl(tpm->base + PWM_IMX_TPM_PARAM); - tpm->chip.npwm = FIELD_GET(PWM_IMX_TPM_PARAM_CHAN, val); + chip->ops = &imx_tpm_pwm_ops; mutex_init(&tpm->lock); - ret = devm_pwmchip_add(&pdev->dev, &tpm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-imx1.c b/drivers/pwm/pwm-imx1.c index d175d895f22a..1d2aae2d278f 100644 --- a/drivers/pwm/pwm-imx1.c +++ b/drivers/pwm/pwm-imx1.c @@ -28,10 +28,12 @@ struct pwm_imx1_chip { struct clk *clk_ipg; struct clk *clk_per; void __iomem *mmio_base; - struct pwm_chip chip; }; -#define to_pwm_imx1_chip(chip) container_of(chip, struct pwm_imx1_chip, chip) +static inline struct pwm_imx1_chip *to_pwm_imx1_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static int pwm_imx1_clk_prepare_enable(struct pwm_chip *chip) { @@ -156,11 +158,13 @@ MODULE_DEVICE_TABLE(of, pwm_imx1_dt_ids); static int pwm_imx1_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct pwm_imx1_chip *imx; - imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); - if (!imx) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + imx = to_pwm_imx1_chip(chip); imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(imx->clk_ipg)) @@ -172,15 +176,13 @@ static int pwm_imx1_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per), "failed to get peripheral clock\n"); - imx->chip.ops = &pwm_imx1_ops; - imx->chip.dev = &pdev->dev; - imx->chip.npwm = 1; + chip->ops = &pwm_imx1_ops; imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); - return devm_pwmchip_add(&pdev->dev, &imx->chip); + return devm_pwmchip_add(&pdev->dev, chip); } static struct platform_driver pwm_imx1_driver = { diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 7d9bc43f12b0..e1412116ef65 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -83,7 +83,6 @@ struct pwm_imx27_chip { struct clk *clk_ipg; struct clk *clk_per; void __iomem *mmio_base; - struct pwm_chip chip; /* * The driver cannot read the current duty cycle from the hardware if @@ -93,7 +92,10 @@ struct pwm_imx27_chip { unsigned int duty_cycle; }; -#define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip) +static inline struct pwm_imx27_chip *to_pwm_imx27_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static int pwm_imx27_clk_prepare_enable(struct pwm_imx27_chip *imx) { @@ -145,7 +147,7 @@ static int pwm_imx27_get_state(struct pwm_chip *chip, state->polarity = PWM_POLARITY_INVERSED; break; default: - dev_warn(chip->dev, "can't set polarity, output disconnected"); + dev_warn(pwmchip_parent(chip), "can't set polarity, output disconnected"); } prescaler = MX3_PWMCR_PRESCALER_GET(val); @@ -177,7 +179,7 @@ static int pwm_imx27_get_state(struct pwm_chip *chip, static void pwm_imx27_sw_reset(struct pwm_chip *chip) { struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - struct device *dev = chip->dev; + struct device *dev = pwmchip_parent(chip); int wait_count = 0; u32 cr; @@ -196,7 +198,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, struct pwm_device *pwm) { struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - struct device *dev = chip->dev; + struct device *dev = pwmchip_parent(chip); unsigned int period_ms; int fifoav; u32 sr; @@ -204,8 +206,8 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, sr = readl(imx->mmio_base + MX3_PWMSR); fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr); if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) { - period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm), - NSEC_PER_MSEC); + period_ms = DIV_ROUND_UP_ULL(pwm->state.period, + NSEC_PER_MSEC); msleep(period_ms); sr = readl(imx->mmio_base + MX3_PWMSR); @@ -219,14 +221,11 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, { unsigned long period_cycles, duty_cycles, prescale; struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - struct pwm_state cstate; unsigned long long c; unsigned long long clkrate; int ret; u32 cr; - pwm_get_state(pwm, &cstate); - clkrate = clk_get_rate(imx->clk_per); c = clkrate * state->period; @@ -254,7 +253,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, * Wait for a free FIFO slot if the PWM is already enabled, and flush * the FIFO if the PWM was disabled and is about to be enabled. */ - if (cstate.enabled) { + if (pwm->state.enabled) { pwm_imx27_wait_fifo_slot(chip, pwm); } else { ret = pwm_imx27_clk_prepare_enable(imx); @@ -306,13 +305,15 @@ MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids); static int pwm_imx27_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct pwm_imx27_chip *imx; int ret; u32 pwmcr; - imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); - if (imx == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + imx = to_pwm_imx27_chip(chip); imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(imx->clk_ipg)) @@ -324,9 +325,7 @@ static int pwm_imx27_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per), "failed to get peripheral clock\n"); - imx->chip.ops = &pwm_imx27_ops; - imx->chip.dev = &pdev->dev; - imx->chip.npwm = 1; + chip->ops = &pwm_imx27_ops; imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(imx->mmio_base)) @@ -341,7 +340,7 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (!(pwmcr & MX3_PWMCR_EN)) pwm_imx27_clk_disable_unprepare(imx); - return devm_pwmchip_add(&pdev->dev, &imx->chip); + return devm_pwmchip_add(&pdev->dev, chip); } static struct platform_driver imx_pwm_driver = { diff --git a/drivers/pwm/pwm-intel-lgm.c b/drivers/pwm/pwm-intel-lgm.c index 54ecae7f937e..f9cc7c17c8f0 100644 --- a/drivers/pwm/pwm-intel-lgm.c +++ b/drivers/pwm/pwm-intel-lgm.c @@ -42,14 +42,13 @@ #define LGM_PWM_PERIOD_2WIRE_NS (40 * NSEC_PER_MSEC) struct lgm_pwm_chip { - struct pwm_chip chip; struct regmap *regmap; u32 period; }; static inline struct lgm_pwm_chip *to_lgm_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct lgm_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int lgm_pwm_enable(struct pwm_chip *chip, bool enable) @@ -168,14 +167,16 @@ static int lgm_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct reset_control *rst; + struct pwm_chip *chip; struct lgm_pwm_chip *pc; void __iomem *io_base; struct clk *clk; int ret; - pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, 1, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_lgm_pwm_chip(chip); io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(io_base)) @@ -203,13 +204,11 @@ static int lgm_pwm_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "cannot deassert reset control\n"); - pc->chip.dev = dev; - pc->chip.ops = &lgm_pwm_ops; - pc->chip.npwm = 1; + chip->ops = &lgm_pwm_ops; lgm_pwm_init(pc); - ret = devm_pwmchip_add(dev, &pc->chip); + ret = devm_pwmchip_add(dev, chip); if (ret < 0) return dev_err_probe(dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c index 378ab036edfe..13e5e138c8e9 100644 --- a/drivers/pwm/pwm-iqs620a.c +++ b/drivers/pwm/pwm-iqs620a.c @@ -34,12 +34,17 @@ struct iqs620_pwm_private { struct iqs62x_core *iqs62x; - struct pwm_chip chip; + struct device *dev; struct notifier_block notifier; struct mutex lock; unsigned int duty_scale; }; +static inline struct iqs620_pwm_private *iqs620_pwm_from_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} + static int iqs620_pwm_init(struct iqs620_pwm_private *iqs620_pwm, unsigned int duty_scale) { @@ -73,7 +78,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->period < IQS620_PWM_PERIOD_NS) return -EINVAL; - iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip); + iqs620_pwm = iqs620_pwm_from_chip(chip); /* * The duty cycle generated by the device is calculated as follows: @@ -109,7 +114,7 @@ static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, { struct iqs620_pwm_private *iqs620_pwm; - iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip); + iqs620_pwm = iqs620_pwm_from_chip(chip); mutex_lock(&iqs620_pwm->lock); @@ -155,7 +160,7 @@ static int iqs620_pwm_notifier(struct notifier_block *notifier, mutex_unlock(&iqs620_pwm->lock); if (ret) { - dev_err(iqs620_pwm->chip.dev, + dev_err(iqs620_pwm->dev, "Failed to re-initialize device: %d\n", ret); return NOTIFY_BAD; } @@ -176,21 +181,24 @@ static void iqs620_pwm_notifier_unregister(void *context) ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh, &iqs620_pwm->notifier); if (ret) - dev_err(iqs620_pwm->chip.dev, + dev_err(iqs620_pwm->dev, "Failed to unregister notifier: %d\n", ret); } static int iqs620_pwm_probe(struct platform_device *pdev) { struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); + struct pwm_chip *chip; struct iqs620_pwm_private *iqs620_pwm; unsigned int val; int ret; - iqs620_pwm = devm_kzalloc(&pdev->dev, sizeof(*iqs620_pwm), GFP_KERNEL); - if (!iqs620_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*iqs620_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + iqs620_pwm = iqs620_pwm_from_chip(chip); + iqs620_pwm->dev = &pdev->dev; iqs620_pwm->iqs62x = iqs62x; ret = regmap_read(iqs62x->regmap, IQS620_PWR_SETTINGS, &val); @@ -205,9 +213,7 @@ static int iqs620_pwm_probe(struct platform_device *pdev) iqs620_pwm->duty_scale = val + 1; } - iqs620_pwm->chip.dev = &pdev->dev; - iqs620_pwm->chip.ops = &iqs620_pwm_ops; - iqs620_pwm->chip.npwm = 1; + chip->ops = &iqs620_pwm_ops; mutex_init(&iqs620_pwm->lock); @@ -225,7 +231,7 @@ static int iqs620_pwm_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_pwmchip_add(&pdev->dev, &iqs620_pwm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) dev_err(&pdev->dev, "Failed to add device: %d\n", ret); diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c index 3933418e551b..da4bf543d357 100644 --- a/drivers/pwm/pwm-jz4740.c +++ b/drivers/pwm/pwm-jz4740.c @@ -25,23 +25,21 @@ 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) { - return container_of(chip, struct jz4740_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } -static bool jz4740_pwm_can_use_chn(struct jz4740_pwm_chip *jz, - unsigned int channel) +static bool jz4740_pwm_can_use_chn(struct pwm_chip *chip, unsigned int channel) { /* Enable all TCU channels for PWM use by default except channels 0/1 */ - u32 pwm_channels_mask = GENMASK(jz->chip.npwm - 1, 2); + u32 pwm_channels_mask = GENMASK(chip->npwm - 1, 2); - device_property_read_u32(jz->chip.dev->parent, + device_property_read_u32(pwmchip_parent(chip)->parent, "ingenic,pwm-channels-mask", &pwm_channels_mask); @@ -55,14 +53,15 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) char name[16]; int err; - if (!jz4740_pwm_can_use_chn(jz, pwm->hwpwm)) + if (!jz4740_pwm_can_use_chn(chip, pwm->hwpwm)) return -EBUSY; snprintf(name, sizeof(name), "timer%u", pwm->hwpwm); - clk = clk_get(chip->dev, name); + clk = clk_get(pwmchip_parent(chip), name); if (IS_ERR(clk)) { - dev_err(chip->dev, "error %pe: Failed to get clock\n", clk); + dev_err(pwmchip_parent(chip), + "error %pe: Failed to get clock\n", clk); return PTR_ERR(clk); } @@ -150,7 +149,7 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, */ rate = clk_round_rate(clk, tmp); if (rate < 0) { - dev_err(chip->dev, "Unable to round rate: %ld\n", rate); + dev_err(pwmchip_parent(chip), "Unable to round rate: %ld\n", rate); return rate; } @@ -171,7 +170,7 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, err = clk_set_rate(clk, rate); if (err) { - dev_err(chip->dev, "Unable to set rate: %d\n", err); + dev_err(pwmchip_parent(chip), "Unable to set rate: %d\n", err); return err; } @@ -224,6 +223,7 @@ static const struct pwm_ops jz4740_pwm_ops = { static int jz4740_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct pwm_chip *chip; struct jz4740_pwm_chip *jz; const struct soc_info *info; @@ -231,10 +231,10 @@ static int jz4740_pwm_probe(struct platform_device *pdev) if (!info) return -EINVAL; - jz = devm_kzalloc(dev, struct_size(jz, clk, info->num_pwms), - GFP_KERNEL); - if (!jz) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, info->num_pwms, struct_size(jz, clk, info->num_pwms)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + jz = to_jz4740(chip); jz->map = device_node_to_regmap(dev->parent->of_node); if (IS_ERR(jz->map)) { @@ -242,11 +242,9 @@ static int jz4740_pwm_probe(struct platform_device *pdev) return PTR_ERR(jz->map); } - jz->chip.dev = dev; - jz->chip.ops = &jz4740_pwm_ops; - jz->chip.npwm = info->num_pwms; + chip->ops = &jz4740_pwm_ops; - return devm_pwmchip_add(dev, &jz->chip); + return devm_pwmchip_add(dev, chip); } static const struct soc_info jz4740_soc_info = { diff --git a/drivers/pwm/pwm-keembay.c b/drivers/pwm/pwm-keembay.c index ac824ecc3f64..35b641f3f6ed 100644 --- a/drivers/pwm/pwm-keembay.c +++ b/drivers/pwm/pwm-keembay.c @@ -36,7 +36,6 @@ #define KMB_PWM_HIGHLOW_OFFSET(ch) (0x20 + 4 * (ch)) struct keembay_pwm { - struct pwm_chip chip; struct device *dev; struct clk *clk; void __iomem *base; @@ -44,7 +43,7 @@ struct keembay_pwm { static inline struct keembay_pwm *to_keembay_pwm_dev(struct pwm_chip *chip) { - return container_of(chip, struct keembay_pwm, chip); + return pwmchip_get_drvdata(chip); } static void keembay_clk_unprepare(void *data) @@ -185,12 +184,14 @@ static const struct pwm_ops keembay_pwm_ops = { static int keembay_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct pwm_chip *chip; struct keembay_pwm *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, KMB_TOTAL_PWM_CHANNELS, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = to_keembay_pwm_dev(chip); priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) @@ -204,11 +205,9 @@ static int keembay_pwm_probe(struct platform_device *pdev) if (ret) return ret; - priv->chip.dev = dev; - priv->chip.ops = &keembay_pwm_ops; - priv->chip.npwm = KMB_TOTAL_PWM_CHANNELS; + chip->ops = &keembay_pwm_ops; - ret = devm_pwmchip_add(dev, &priv->chip); + ret = devm_pwmchip_add(dev, chip); if (ret) return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 32350a357278..61189cea1046 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c @@ -20,7 +20,6 @@ #define LP3943_MAX_PERIOD 1600000 struct lp3943_pwm { - struct pwm_chip chip; struct lp3943 *lp3943; struct lp3943_platform_data *pdata; struct lp3943_pwm_map pwm_map[LP3943_NUM_PWMS]; @@ -28,7 +27,7 @@ struct lp3943_pwm { static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *chip) { - return container_of(chip, struct lp3943_pwm, chip); + return pwmchip_get_drvdata(chip); } static struct lp3943_pwm_map * @@ -273,12 +272,14 @@ static int lp3943_pwm_parse_dt(struct device *dev, static int lp3943_pwm_probe(struct platform_device *pdev) { struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent); + struct pwm_chip *chip; struct lp3943_pwm *lp3943_pwm; int ret; - lp3943_pwm = devm_kzalloc(&pdev->dev, sizeof(*lp3943_pwm), GFP_KERNEL); - if (!lp3943_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, LP3943_NUM_PWMS, sizeof(*lp3943_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + lp3943_pwm = to_lp3943_pwm(chip); lp3943_pwm->pdata = lp3943->pdata; if (!lp3943_pwm->pdata) { @@ -292,11 +293,9 @@ static int lp3943_pwm_probe(struct platform_device *pdev) } lp3943_pwm->lp3943 = lp3943; - lp3943_pwm->chip.dev = &pdev->dev; - lp3943_pwm->chip.ops = &lp3943_pwm_ops; - lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; + chip->ops = &lp3943_pwm_ops; - return devm_pwmchip_add(&pdev->dev, &lp3943_pwm->chip); + return devm_pwmchip_add(&pdev->dev, chip); } #ifdef CONFIG_OF diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c index fe891fa71a1d..04b76d257fd8 100644 --- a/drivers/pwm/pwm-lpc18xx-sct.c +++ b/drivers/pwm/pwm-lpc18xx-sct.c @@ -92,8 +92,6 @@ struct lpc18xx_pwm_data { }; struct lpc18xx_pwm_chip { - struct device *dev; - struct pwm_chip chip; void __iomem *base; struct clk *pwm_clk; unsigned long clk_rate; @@ -110,7 +108,7 @@ struct lpc18xx_pwm_chip { static inline struct lpc18xx_pwm_chip * to_lpc18xx_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct lpc18xx_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline void lpc18xx_pwm_writel(struct lpc18xx_pwm_chip *lpc18xx_pwm, @@ -198,7 +196,7 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (period_ns < lpc18xx_pwm->min_period_ns || period_ns > lpc18xx_pwm->max_period_ns) { - dev_err(chip->dev, "period %d not in range\n", period_ns); + dev_err(pwmchip_parent(chip), "period %d not in range\n", period_ns); return -ERANGE; } @@ -214,7 +212,7 @@ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, */ if (requested_events > 2 && lpc18xx_pwm->period_ns != period_ns && lpc18xx_pwm->period_ns) { - dev_err(chip->dev, "conflicting period requested for PWM %u\n", + dev_err(pwmchip_parent(chip), "conflicting period requested for PWM %u\n", pwm->hwpwm); mutex_unlock(&lpc18xx_pwm->period_lock); return -EBUSY; @@ -289,7 +287,7 @@ static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) LPC18XX_PWM_EVENT_MAX); if (event >= LPC18XX_PWM_EVENT_MAX) { - dev_err(lpc18xx_pwm->dev, + dev_err(pwmchip_parent(chip), "maximum number of simultaneous channels reached\n"); return -EBUSY; } @@ -349,16 +347,15 @@ MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match); static int lpc18xx_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct lpc18xx_pwm_chip *lpc18xx_pwm; int ret; u64 val; - lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm), - GFP_KERNEL); - if (!lpc18xx_pwm) - return -ENOMEM; - - lpc18xx_pwm->dev = &pdev->dev; + chip = devm_pwmchip_alloc(&pdev->dev, LPC18XX_NUM_PWMS, sizeof(*lpc18xx_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + lpc18xx_pwm = to_lpc18xx_pwm_chip(chip); lpc18xx_pwm->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(lpc18xx_pwm->base)) @@ -389,9 +386,7 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev) lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, lpc18xx_pwm->clk_rate); - lpc18xx_pwm->chip.dev = &pdev->dev; - lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops; - lpc18xx_pwm->chip.npwm = LPC18XX_NUM_PWMS; + chip->ops = &lpc18xx_pwm_ops; /* SCT counter must be in unify (32 bit) mode */ lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG, @@ -423,21 +418,22 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev) val |= LPC18XX_PWM_PRE(0); lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val); - ret = pwmchip_add(&lpc18xx_pwm->chip); + ret = pwmchip_add(chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "pwmchip_add failed\n"); - platform_set_drvdata(pdev, lpc18xx_pwm); + platform_set_drvdata(pdev, chip); return 0; } static void lpc18xx_pwm_remove(struct platform_device *pdev) { - struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip); u32 val; - pwmchip_remove(&lpc18xx_pwm->chip); + pwmchip_remove(chip); val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL); lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index 1d9f3e7a2434..c748537e57d1 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -15,7 +15,6 @@ #include <linux/slab.h> struct lpc32xx_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; }; @@ -23,8 +22,10 @@ struct lpc32xx_pwm_chip { #define PWM_ENABLE BIT(31) #define PWM_PIN_LEVEL BIT(30) -#define to_lpc32xx_pwm_chip(_chip) \ - container_of(_chip, struct lpc32xx_pwm_chip, chip) +static inline struct lpc32xx_pwm_chip *to_lpc32xx_pwm_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) @@ -119,13 +120,15 @@ static const struct pwm_ops lpc32xx_pwm_ops = { static int lpc32xx_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct lpc32xx_pwm_chip *lpc32xx; int ret; u32 val; - lpc32xx = devm_kzalloc(&pdev->dev, sizeof(*lpc32xx), GFP_KERNEL); - if (!lpc32xx) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*lpc32xx)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + lpc32xx = to_lpc32xx_pwm_chip(chip); lpc32xx->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(lpc32xx->base)) @@ -135,16 +138,14 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) if (IS_ERR(lpc32xx->clk)) return PTR_ERR(lpc32xx->clk); - lpc32xx->chip.dev = &pdev->dev; - lpc32xx->chip.ops = &lpc32xx_pwm_ops; - lpc32xx->chip.npwm = 1; + chip->ops = &lpc32xx_pwm_ops; /* If PWM is disabled, configure the output to the default value */ val = readl(lpc32xx->base); val &= ~PWM_PIN_LEVEL; writel(val, lpc32xx->base); - ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret); return ret; diff --git a/drivers/pwm/pwm-lpss-pci.c b/drivers/pwm/pwm-lpss-pci.c index b4134bee2863..25045c229520 100644 --- a/drivers/pwm/pwm-lpss-pci.c +++ b/drivers/pwm/pwm-lpss-pci.c @@ -18,7 +18,7 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev, const struct pci_device_id *id) { const struct pwm_lpss_boardinfo *info; - struct pwm_lpss_chip *lpwm; + struct pwm_chip *chip; int err; err = pcim_enable_device(pdev); @@ -30,11 +30,9 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev, return err; info = (struct pwm_lpss_boardinfo *)id->driver_data; - lpwm = devm_pwm_lpss_probe(&pdev->dev, pcim_iomap_table(pdev)[0], info); - if (IS_ERR(lpwm)) - return PTR_ERR(lpwm); - - pci_set_drvdata(pdev, lpwm); + chip = devm_pwm_lpss_probe(&pdev->dev, pcim_iomap_table(pdev)[0], info); + if (IS_ERR(chip)) + return PTR_ERR(chip); pm_runtime_put(&pdev->dev); pm_runtime_allow(&pdev->dev); diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c index 319809aac2c4..dbc9f5b17bdc 100644 --- a/drivers/pwm/pwm-lpss-platform.c +++ b/drivers/pwm/pwm-lpss-platform.c @@ -20,7 +20,7 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev) { const struct pwm_lpss_boardinfo *info; - struct pwm_lpss_chip *lpwm; + struct pwm_chip *chip; void __iomem *base; info = device_get_match_data(&pdev->dev); @@ -31,11 +31,9 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - lpwm = devm_pwm_lpss_probe(&pdev->dev, base, info); - if (IS_ERR(lpwm)) - return PTR_ERR(lpwm); - - platform_set_drvdata(pdev, lpwm); + chip = devm_pwm_lpss_probe(&pdev->dev, base, info); + if (IS_ERR(chip)) + return PTR_ERR(chip); /* * On Cherry Trail devices the GFX0._PS0 AML checks if the controller diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index a6ea3ce7e019..867e2bc8c601 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c @@ -68,7 +68,7 @@ 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); + return pwmchip_get_drvdata(chip); } static inline u32 pwm_lpss_read(const struct pwm_device *pwm) @@ -106,7 +106,7 @@ static int pwm_lpss_wait_for_update(struct pwm_device *pwm) */ err = readl_poll_timeout(addr, val, !(val & PWM_SW_UPDATE), 40, ms); if (err) - dev_err(pwm->chip->dev, "PWM_SW_UPDATE was not cleared\n"); + dev_err(pwmchip_parent(pwm->chip), "PWM_SW_UPDATE was not cleared\n"); return err; } @@ -114,7 +114,7 @@ static int pwm_lpss_wait_for_update(struct pwm_device *pwm) static inline int pwm_lpss_is_updating(struct pwm_device *pwm) { if (pwm_lpss_read(pwm) & PWM_SW_UPDATE) { - dev_err(pwm->chip->dev, "PWM_SW_UPDATE is still set, skipping update\n"); + dev_err(pwmchip_parent(pwm->chip), "PWM_SW_UPDATE is still set, skipping update\n"); return -EBUSY; } @@ -190,16 +190,16 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->enabled) { if (!pwm_is_enabled(pwm)) { - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); ret = pwm_lpss_prepare_enable(lpwm, pwm, state); if (ret) - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); } else { ret = pwm_lpss_prepare_enable(lpwm, pwm, state); } } else if (pwm_is_enabled(pwm)) { pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE); - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); } return ret; @@ -213,7 +213,7 @@ static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long long base_unit, freq, on_time_div; u32 ctrl; - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); base_unit_range = BIT(lpwm->info->base_unit_bits); @@ -235,7 +235,7 @@ static int pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, state->polarity = PWM_POLARITY_NORMAL; state->enabled = !!(ctrl & PWM_ENABLE); - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); return 0; } @@ -245,10 +245,11 @@ static const struct pwm_ops pwm_lpss_ops = { .get_state = pwm_lpss_get_state, }; -struct pwm_lpss_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base, - const struct pwm_lpss_boardinfo *info) +struct pwm_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base, + const struct pwm_lpss_boardinfo *info) { struct pwm_lpss_chip *lpwm; + struct pwm_chip *chip; unsigned long c; int i, ret; u32 ctrl; @@ -256,9 +257,10 @@ struct pwm_lpss_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base if (WARN_ON(info->npwm > LPSS_MAX_PWMS)) return ERR_PTR(-ENODEV); - lpwm = devm_kzalloc(dev, sizeof(*lpwm), GFP_KERNEL); - if (!lpwm) - return ERR_PTR(-ENOMEM); + chip = devm_pwmchip_alloc(dev, info->npwm, sizeof(*lpwm)); + if (IS_ERR(chip)) + return chip; + lpwm = to_lpwm(chip); lpwm->regs = base; lpwm->info = info; @@ -267,23 +269,21 @@ struct pwm_lpss_chip *devm_pwm_lpss_probe(struct device *dev, void __iomem *base if (!c) return ERR_PTR(-EINVAL); - lpwm->chip.dev = dev; - lpwm->chip.ops = &pwm_lpss_ops; - lpwm->chip.npwm = info->npwm; + chip->ops = &pwm_lpss_ops; - ret = devm_pwmchip_add(dev, &lpwm->chip); + ret = devm_pwmchip_add(dev, chip); if (ret) { dev_err(dev, "failed to add PWM chip: %d\n", ret); return ERR_PTR(ret); } for (i = 0; i < lpwm->info->npwm; i++) { - ctrl = pwm_lpss_read(&lpwm->chip.pwms[i]); + ctrl = pwm_lpss_read(&chip->pwms[i]); if (ctrl & PWM_ENABLE) pm_runtime_get(dev); } - return lpwm; + return chip; } EXPORT_SYMBOL_GPL(devm_pwm_lpss_probe); diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h index bf841250385f..b5267ab5193b 100644 --- a/drivers/pwm/pwm-lpss.h +++ b/drivers/pwm/pwm-lpss.h @@ -18,7 +18,6 @@ #define LPSS_MAX_PWMS 4 struct pwm_lpss_chip { - struct pwm_chip chip; void __iomem *regs; const struct pwm_lpss_boardinfo *info; }; diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 17d290f847af..19a87873ad60 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -42,16 +42,13 @@ struct pwm_mediatek_of_data { /** * struct pwm_mediatek_chip - struct representing PWM chip - * @chip: linux PWM chip representation * @regs: base address of PWM chip * @clk_top: the top clock generator * @clk_main: the clock used by PWM core * @clk_pwms: the clock used by each PWM channel - * @clk_freq: the fix clock frequency of legacy MIPS SoC * @soc: pointer to chip's platform data */ struct pwm_mediatek_chip { - struct pwm_chip chip; void __iomem *regs; struct clk *clk_top; struct clk *clk_main; @@ -70,7 +67,7 @@ static const unsigned int mtk_pwm_reg_offset_v2[] = { static inline struct pwm_mediatek_chip * to_pwm_mediatek_chip(struct pwm_chip *chip) { - return container_of(chip, struct pwm_mediatek_chip, chip); + return pwmchip_get_drvdata(chip); } static int pwm_mediatek_clk_enable(struct pwm_chip *chip, @@ -150,7 +147,7 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, if (clkdiv > PWM_CLK_DIV_MAX) { pwm_mediatek_clk_disable(chip, pwm); - dev_err(chip->dev, "period of %d ns not supported\n", period_ns); + dev_err(pwmchip_parent(chip), "period of %d ns not supported\n", period_ns); return -EINVAL; } @@ -233,21 +230,26 @@ static const struct pwm_ops pwm_mediatek_ops = { static int pwm_mediatek_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct pwm_mediatek_chip *pc; + const struct pwm_mediatek_of_data *soc; unsigned int i; int ret; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + soc = of_device_get_match_data(&pdev->dev); + + chip = devm_pwmchip_alloc(&pdev->dev, soc->num_pwms, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_pwm_mediatek_chip(chip); - pc->soc = of_device_get_match_data(&pdev->dev); + pc->soc = soc; pc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->regs)) return PTR_ERR(pc->regs); - pc->clk_pwms = devm_kmalloc_array(&pdev->dev, pc->soc->num_pwms, + pc->clk_pwms = devm_kmalloc_array(&pdev->dev, soc->num_pwms, sizeof(*pc->clk_pwms), GFP_KERNEL); if (!pc->clk_pwms) return -ENOMEM; @@ -262,7 +264,7 @@ static int pwm_mediatek_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_main), "Failed to get main clock\n"); - for (i = 0; i < pc->soc->num_pwms; i++) { + for (i = 0; i < soc->num_pwms; i++) { char name[8]; snprintf(name, sizeof(name), "pwm%d", i + 1); @@ -273,11 +275,9 @@ static int pwm_mediatek_probe(struct platform_device *pdev) "Failed to get %s clock\n", name); } - pc->chip.dev = &pdev->dev; - pc->chip.ops = &pwm_mediatek_ops; - pc->chip.npwm = pc->soc->num_pwms; + chip->ops = &pwm_mediatek_ops; - ret = devm_pwmchip_add(&pdev->dev, &pc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n"); @@ -340,6 +340,13 @@ static const struct pwm_mediatek_of_data mt7986_pwm_data = { .reg_offset = mtk_pwm_reg_offset_v1, }; +static const struct pwm_mediatek_of_data mt7988_pwm_data = { + .num_pwms = 8, + .pwm45_fixup = false, + .has_ck_26m_sel = false, + .reg_offset = mtk_pwm_reg_offset_v2, +}; + static const struct pwm_mediatek_of_data mt8183_pwm_data = { .num_pwms = 4, .pwm45_fixup = false, @@ -370,6 +377,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = { { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data }, { .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data }, { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data }, + { .compatible = "mediatek,mt7988-pwm", .data = &mt7988_pwm_data }, { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data }, { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data }, { .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data }, diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index 2971bbf3b5e7..a02fdbc61256 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -60,7 +60,7 @@ #define MISC_A_EN BIT(0) #define MESON_NUM_PWMS 2 -#define MESON_MAX_MUX_PARENTS 4 +#define MESON_NUM_MUX_PARENTS 4 static struct meson_pwm_channel_data { u8 reg_offset; @@ -97,12 +97,10 @@ struct meson_pwm_channel { }; struct meson_pwm_data { - const char * const *parent_names; - unsigned int num_parents; + const char *const parent_names[MESON_NUM_MUX_PARENTS]; }; struct meson_pwm { - struct pwm_chip chip; const struct meson_pwm_data *data; struct meson_pwm_channel channels[MESON_NUM_PWMS]; void __iomem *base; @@ -115,14 +113,14 @@ struct meson_pwm { static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip) { - return container_of(chip, struct meson_pwm, chip); + return pwmchip_get_drvdata(chip); } static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) { struct meson_pwm *meson = to_meson_pwm(chip); struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; - struct device *dev = chip->dev; + struct device *dev = pwmchip_parent(chip); int err; err = clk_prepare_enable(channel->clk); @@ -143,9 +141,10 @@ static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) clk_disable_unprepare(channel->clk); } -static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, +static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { + struct meson_pwm *meson = to_meson_pwm(chip); struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; unsigned int cnt, duty_cnt; unsigned long fin_freq; @@ -169,19 +168,19 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, fin_freq = clk_round_rate(channel->clk, freq); if (fin_freq == 0) { - dev_err(meson->chip.dev, "invalid source clock frequency\n"); + dev_err(pwmchip_parent(chip), "invalid source clock frequency\n"); return -EINVAL; } - dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq); + dev_dbg(pwmchip_parent(chip), "fin_freq: %lu Hz\n", fin_freq); cnt = div_u64(fin_freq * period, NSEC_PER_SEC); if (cnt > 0xffff) { - dev_err(meson->chip.dev, "unable to get period cnt\n"); + dev_err(pwmchip_parent(chip), "unable to get period cnt\n"); return -EINVAL; } - dev_dbg(meson->chip.dev, "period=%llu cnt=%u\n", period, cnt); + dev_dbg(pwmchip_parent(chip), "period=%llu cnt=%u\n", period, cnt); if (duty == period) { channel->hi = cnt; @@ -192,7 +191,7 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, } else { duty_cnt = div_u64(fin_freq * duty, NSEC_PER_SEC); - dev_dbg(meson->chip.dev, "duty=%llu duty_cnt=%u\n", duty, duty_cnt); + dev_dbg(pwmchip_parent(chip), "duty=%llu duty_cnt=%u\n", duty, duty_cnt); channel->hi = duty_cnt; channel->lo = cnt - duty_cnt; @@ -203,8 +202,9 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, return 0; } -static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm) +static void meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { + struct meson_pwm *meson = to_meson_pwm(chip); struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; struct meson_pwm_channel_data *channel_data; unsigned long flags; @@ -215,7 +215,7 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm) err = clk_set_rate(channel->clk, channel->rate); if (err) - dev_err(meson->chip.dev, "setting clock rate failed\n"); + dev_err(pwmchip_parent(chip), "setting clock rate failed\n"); spin_lock_irqsave(&meson->lock, flags); @@ -230,8 +230,9 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm) spin_unlock_irqrestore(&meson->lock, flags); } -static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm) +static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) { + struct meson_pwm *meson = to_meson_pwm(chip); unsigned long flags; u32 value; @@ -269,16 +270,16 @@ static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, channel->hi = ~0; channel->lo = 0; - meson_pwm_enable(meson, pwm); + meson_pwm_enable(chip, pwm); } else { - meson_pwm_disable(meson, pwm); + meson_pwm_disable(chip, pwm); } } else { - err = meson_pwm_calc(meson, pwm, state); + err = meson_pwm_calc(chip, pwm, state); if (err < 0) return err; - meson_pwm_enable(meson, pwm); + meson_pwm_enable(chip, pwm); } return 0; @@ -337,62 +338,32 @@ static const struct pwm_ops meson_pwm_ops = { .get_state = meson_pwm_get_state, }; -static const char * const pwm_meson8b_parent_names[] = { - "xtal", NULL, "fclk_div4", "fclk_div3" -}; - static const struct meson_pwm_data pwm_meson8b_data = { - .parent_names = pwm_meson8b_parent_names, - .num_parents = ARRAY_SIZE(pwm_meson8b_parent_names), + .parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" }, }; /* * Only the 2 first inputs of the GXBB AO PWMs are valid * The last 2 are grounded */ -static const char * const pwm_gxbb_ao_parent_names[] = { - "xtal", "clk81" -}; - static const struct meson_pwm_data pwm_gxbb_ao_data = { - .parent_names = pwm_gxbb_ao_parent_names, - .num_parents = ARRAY_SIZE(pwm_gxbb_ao_parent_names), -}; - -static const char * const pwm_axg_ee_parent_names[] = { - "xtal", "fclk_div5", "fclk_div4", "fclk_div3" + .parent_names = { "xtal", "clk81", NULL, NULL }, }; static const struct meson_pwm_data pwm_axg_ee_data = { - .parent_names = pwm_axg_ee_parent_names, - .num_parents = ARRAY_SIZE(pwm_axg_ee_parent_names), -}; - -static const char * const pwm_axg_ao_parent_names[] = { - "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" + .parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" }, }; static const struct meson_pwm_data pwm_axg_ao_data = { - .parent_names = pwm_axg_ao_parent_names, - .num_parents = ARRAY_SIZE(pwm_axg_ao_parent_names), -}; - -static const char * const pwm_g12a_ao_ab_parent_names[] = { - "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" + .parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" }, }; static const struct meson_pwm_data pwm_g12a_ao_ab_data = { - .parent_names = pwm_g12a_ao_ab_parent_names, - .num_parents = ARRAY_SIZE(pwm_g12a_ao_ab_parent_names), -}; - -static const char * const pwm_g12a_ao_cd_parent_names[] = { - "xtal", "g12a_ao_clk81", + .parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" }, }; static const struct meson_pwm_data pwm_g12a_ao_cd_data = { - .parent_names = pwm_g12a_ao_cd_parent_names, - .num_parents = ARRAY_SIZE(pwm_g12a_ao_cd_parent_names), + .parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL }, }; static const struct of_device_id meson_pwm_matches[] = { @@ -432,20 +403,21 @@ static const struct of_device_id meson_pwm_matches[] = { }; MODULE_DEVICE_TABLE(of, meson_pwm_matches); -static int meson_pwm_init_channels(struct meson_pwm *meson) +static int meson_pwm_init_channels(struct pwm_chip *chip) { - struct clk_parent_data mux_parent_data[MESON_MAX_MUX_PARENTS] = {}; - struct device *dev = meson->chip.dev; + struct meson_pwm *meson = to_meson_pwm(chip); + struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {}; + struct device *dev = pwmchip_parent(chip); unsigned int i; char name[255]; int err; - for (i = 0; i < meson->data->num_parents; i++) { + for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) { mux_parent_data[i].index = -1; mux_parent_data[i].name = meson->data->parent_names[i]; } - for (i = 0; i < meson->chip.npwm; i++) { + for (i = 0; i < chip->npwm; i++) { struct meson_pwm_channel *channel = &meson->channels[i]; struct clk_parent_data div_parent = {}, gate_parent = {}; struct clk_init_data init = {}; @@ -456,7 +428,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson) init.ops = &clk_mux_ops; init.flags = 0; init.parent_data = mux_parent_data; - init.num_parents = meson->data->num_parents; + init.num_parents = MESON_NUM_MUX_PARENTS; channel->mux.reg = meson->base + REG_MISC_AB; channel->mux.shift = @@ -525,29 +497,29 @@ static int meson_pwm_init_channels(struct meson_pwm *meson) static int meson_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct meson_pwm *meson; int err; - meson = devm_kzalloc(&pdev->dev, sizeof(*meson), GFP_KERNEL); - if (!meson) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, MESON_NUM_PWMS, sizeof(*meson)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + meson = to_meson_pwm(chip); meson->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(meson->base)) return PTR_ERR(meson->base); spin_lock_init(&meson->lock); - meson->chip.dev = &pdev->dev; - meson->chip.ops = &meson_pwm_ops; - meson->chip.npwm = MESON_NUM_PWMS; + chip->ops = &meson_pwm_ops; meson->data = of_device_get_match_data(&pdev->dev); - err = meson_pwm_init_channels(meson); + err = meson_pwm_init_channels(chip); if (err < 0) return err; - err = devm_pwmchip_add(&pdev->dev, &meson->chip); + err = devm_pwmchip_add(&pdev->dev, chip); if (err < 0) return dev_err_probe(&pdev->dev, err, "failed to register PWM chip\n"); diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c index c0c53968f3e9..c1f2287b8e97 100644 --- a/drivers/pwm/pwm-microchip-core.c +++ b/drivers/pwm/pwm-microchip-core.c @@ -54,7 +54,6 @@ #define MCHPCOREPWM_TIMEOUT_MS 100u struct mchp_core_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; struct mutex lock; /* protects the shared period */ @@ -65,7 +64,7 @@ struct mchp_core_pwm_chip { static inline struct mchp_core_pwm_chip *to_mchp_core_pwm(struct pwm_chip *chip) { - return container_of(chip, struct mchp_core_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static void mchp_core_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, @@ -447,13 +446,15 @@ MODULE_DEVICE_TABLE(of, mchp_core_of_match); static int mchp_core_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct mchp_core_pwm_chip *mchp_core_pwm; struct resource *regs; int ret; - mchp_core_pwm = devm_kzalloc(&pdev->dev, sizeof(*mchp_core_pwm), GFP_KERNEL); - if (!mchp_core_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 16, sizeof(*mchp_core_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + mchp_core_pwm = to_mchp_core_pwm(chip); mchp_core_pwm->base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); if (IS_ERR(mchp_core_pwm->base)) @@ -470,9 +471,7 @@ static int mchp_core_pwm_probe(struct platform_device *pdev) mutex_init(&mchp_core_pwm->lock); - mchp_core_pwm->chip.dev = &pdev->dev; - mchp_core_pwm->chip.ops = &mchp_core_pwm_ops; - mchp_core_pwm->chip.npwm = 16; + chip->ops = &mchp_core_pwm_ops; mchp_core_pwm->channel_enabled = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_EN(0)); mchp_core_pwm->channel_enabled |= @@ -485,7 +484,7 @@ static int mchp_core_pwm_probe(struct platform_device *pdev) writel_relaxed(1U, mchp_core_pwm->base + MCHPCOREPWM_SYNC_UPD); mchp_core_pwm->update_timestamp = ktime_get(); - ret = devm_pwmchip_add(&pdev->dev, &mchp_core_pwm->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to add pwmchip\n"); diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index a72f7be36996..bafd6b6195f6 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -42,7 +42,6 @@ struct mtk_pwm_data { }; struct mtk_disp_pwm { - struct pwm_chip chip; const struct mtk_pwm_data *data; struct clk *clk_main; struct clk *clk_mm; @@ -52,7 +51,7 @@ struct mtk_disp_pwm { static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip) { - return container_of(chip, struct mtk_disp_pwm, chip); + return pwmchip_get_drvdata(chip); } static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset, @@ -91,14 +90,14 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (!mdp->enabled) { err = clk_prepare_enable(mdp->clk_main); if (err < 0) { - dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", + dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); return err; } err = clk_prepare_enable(mdp->clk_mm); if (err < 0) { - dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", + dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); clk_disable_unprepare(mdp->clk_main); return err; @@ -181,13 +180,13 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, err = clk_prepare_enable(mdp->clk_main); if (err < 0) { - dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); + dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); return err; } err = clk_prepare_enable(mdp->clk_mm); if (err < 0) { - dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + dev_err(pwmchip_parent(chip), "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); clk_disable_unprepare(mdp->clk_main); return err; } @@ -231,12 +230,14 @@ static const struct pwm_ops mtk_disp_pwm_ops = { static int mtk_disp_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct mtk_disp_pwm *mdp; int ret; - mdp = devm_kzalloc(&pdev->dev, sizeof(*mdp), GFP_KERNEL); - if (!mdp) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*mdp)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + mdp = to_mtk_disp_pwm(chip); mdp->data = of_device_get_match_data(&pdev->dev); @@ -254,11 +255,9 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) 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; + chip->ops = &mtk_disp_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &mdp->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n"); diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c index 1b5e787d78f1..8cad214b1c29 100644 --- a/drivers/pwm/pwm-mxs.c +++ b/drivers/pwm/pwm-mxs.c @@ -37,12 +37,14 @@ static const u8 cdiv_shift[PERIOD_CDIV_MAX] = { }; struct mxs_pwm_chip { - struct pwm_chip chip; struct clk *clk; void __iomem *base; }; -#define to_mxs_pwm_chip(_chip) container_of(_chip, struct mxs_pwm_chip, chip) +static inline struct mxs_pwm_chip *to_mxs_pwm_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) @@ -120,12 +122,21 @@ static const struct pwm_ops mxs_pwm_ops = { static int mxs_pwm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct pwm_chip *chip; struct mxs_pwm_chip *mxs; + u32 npwm; int ret; - mxs = devm_kzalloc(&pdev->dev, sizeof(*mxs), GFP_KERNEL); - if (!mxs) - return -ENOMEM; + ret = of_property_read_u32(np, "fsl,pwm-number", &npwm); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret); + return ret; + } + + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*mxs)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + mxs = to_mxs_pwm_chip(chip); mxs->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mxs->base)) @@ -135,21 +146,14 @@ static int mxs_pwm_probe(struct platform_device *pdev) if (IS_ERR(mxs->clk)) return PTR_ERR(mxs->clk); - mxs->chip.dev = &pdev->dev; - mxs->chip.ops = &mxs_pwm_ops; - - ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get pwm number: %d\n", ret); - return ret; - } + chip->ops = &mxs_pwm_ops; /* FIXME: Only do this if the PWM isn't already running */ ret = stmp_reset_block(mxs->base); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to reset PWM\n"); - ret = devm_pwmchip_add(&pdev->dev, &mxs->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add pwm chip %d\n", ret); return ret; diff --git a/drivers/pwm/pwm-ntxec.c b/drivers/pwm/pwm-ntxec.c index 78606039eda2..28d1c2e5a98f 100644 --- a/drivers/pwm/pwm-ntxec.c +++ b/drivers/pwm/pwm-ntxec.c @@ -25,12 +25,11 @@ struct ntxec_pwm { struct ntxec *ec; - struct pwm_chip chip; }; static struct ntxec_pwm *ntxec_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct ntxec_pwm, chip); + return pwmchip_get_drvdata(chip); } #define NTXEC_REG_AUTO_OFF_HI 0xa1 @@ -141,16 +140,13 @@ static int ntxec_pwm_probe(struct platform_device *pdev) device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = ntxec_pwm_from_chip(chip); priv->ec = ec; - - chip = &priv->chip; - chip->dev = &pdev->dev; chip->ops = &ntxec_pwm_ops; - chip->npwm = 1; return devm_pwmchip_add(&pdev->dev, chip); } diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 496bd73d29fe..cd51c4a938f5 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -53,13 +53,11 @@ /** * struct pwm_omap_dmtimer_chip - Structure representing a pwm chip * corresponding to omap dmtimer. - * @chip: PWM chip structure representing PWM controller * @dm_timer: Pointer to omap dm timer. * @pdata: Pointer to omap dm timer ops. * @dm_timer_pdev: Pointer to omap dm timer platform device */ struct pwm_omap_dmtimer_chip { - struct pwm_chip chip; /* Mutex to protect pwm apply state */ struct omap_dm_timer *dm_timer; const struct omap_dm_timer_ops *pdata; @@ -69,7 +67,7 @@ struct pwm_omap_dmtimer_chip { static inline struct pwm_omap_dmtimer_chip * to_pwm_omap_dmtimer_chip(struct pwm_chip *chip) { - return container_of(chip, struct pwm_omap_dmtimer_chip, chip); + return pwmchip_get_drvdata(chip); } /** @@ -155,7 +153,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, unsigned long clk_rate; struct clk *fclk; - dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n", + dev_dbg(pwmchip_parent(chip), "requested duty cycle: %d ns, period: %d ns\n", duty_ns, period_ns); if (duty_ns == pwm_get_duty_cycle(pwm) && @@ -164,17 +162,17 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, fclk = omap->pdata->get_fclk(omap->dm_timer); if (!fclk) { - dev_err(chip->dev, "invalid pmtimer fclk\n"); + dev_err(pwmchip_parent(chip), "invalid pmtimer fclk\n"); return -EINVAL; } clk_rate = clk_get_rate(fclk); if (!clk_rate) { - dev_err(chip->dev, "invalid pmtimer fclk rate\n"); + dev_err(pwmchip_parent(chip), "invalid pmtimer fclk rate\n"); return -EINVAL; } - dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); + dev_dbg(pwmchip_parent(chip), "clk rate: %luHz\n", clk_rate); /* * Calculate the appropriate load and match values based on the @@ -196,27 +194,27 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns); if (period_cycles < 2) { - dev_info(chip->dev, + dev_info(pwmchip_parent(chip), "period %d ns too short for clock rate %lu Hz\n", period_ns, clk_rate); return -EINVAL; } if (duty_cycles < 1) { - dev_dbg(chip->dev, + dev_dbg(pwmchip_parent(chip), "duty cycle %d ns is too short for clock rate %lu Hz\n", duty_ns, clk_rate); - dev_dbg(chip->dev, "using minimum of 1 clock cycle\n"); + dev_dbg(pwmchip_parent(chip), "using minimum of 1 clock cycle\n"); duty_cycles = 1; } else if (duty_cycles >= period_cycles) { - dev_dbg(chip->dev, + dev_dbg(pwmchip_parent(chip), "duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n", duty_ns, period_ns, clk_rate); - dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n"); + dev_dbg(pwmchip_parent(chip), "using maximum of 1 clock cycle less than period\n"); duty_cycles = period_cycles - 1; } - dev_dbg(chip->dev, "effective duty cycle: %lld ns, period: %lld ns\n", + dev_dbg(pwmchip_parent(chip), "effective duty cycle: %lld ns, period: %lld ns\n", DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * duty_cycles, clk_rate), DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * period_cycles, @@ -228,7 +226,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, omap->pdata->set_load(omap->dm_timer, load_value); omap->pdata->set_match(omap->dm_timer, true, match_value); - dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n", + dev_dbg(pwmchip_parent(chip), "load value: %#08x (%d), match value: %#08x (%d)\n", load_value, load_value, match_value, match_value); return 0; @@ -311,6 +309,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) struct dmtimer_platform_data *timer_pdata; const struct omap_dm_timer_ops *pdata; struct platform_device *timer_pdev; + struct pwm_chip *chip; struct pwm_omap_dmtimer_chip *omap; struct omap_dm_timer *dm_timer; struct device_node *timer; @@ -368,11 +367,12 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) goto err_request_timer; } - omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); - if (!omap) { - ret = -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*omap)); + if (IS_ERR(chip)) { + ret = PTR_ERR(chip); goto err_alloc_omap; } + omap = to_pwm_omap_dmtimer_chip(chip); omap->pdata = pdata; omap->dm_timer = dm_timer; @@ -392,11 +392,9 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) omap->pdata->set_source(omap->dm_timer, v); - omap->chip.dev = &pdev->dev; - omap->chip.ops = &pwm_omap_dmtimer_ops; - omap->chip.npwm = 1; + chip->ops = &pwm_omap_dmtimer_ops; - ret = pwmchip_add(&omap->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM\n"); goto err_pwmchip_add; @@ -404,7 +402,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) of_node_put(timer); - platform_set_drvdata(pdev, omap); + platform_set_drvdata(pdev, chip); return 0; @@ -432,9 +430,10 @@ err_find_timer_pdev: static void pwm_omap_dmtimer_remove(struct platform_device *pdev) { - struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); - pwmchip_remove(&omap->chip); + pwmchip_remove(chip); if (pm_runtime_active(&omap->dm_timer_pdev->dev)) omap->pdata->stop(omap->dm_timer); diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c index e79b1de8c4d8..c5da2a6ed846 100644 --- a/drivers/pwm/pwm-pca9685.c +++ b/drivers/pwm/pwm-pca9685.c @@ -76,7 +76,6 @@ #define REG_OFF_L(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_OFF_L : LED_N_OFF_L((C))) struct pca9685 { - struct pwm_chip chip; struct regmap *regmap; struct mutex lock; DECLARE_BITMAP(pwms_enabled, PCA9685_MAXCHAN + 1); @@ -88,7 +87,7 @@ struct pca9685 { static inline struct pca9685 *to_pca(struct pwm_chip *chip) { - return container_of(chip, struct pca9685, chip); + return pwmchip_get_drvdata(chip); } /* This function is supposed to be called with the lock mutex held */ @@ -107,9 +106,10 @@ static bool pca9685_prescaler_can_change(struct pca9685 *pca, int channel) return test_bit(channel, pca->pwms_enabled); } -static int pca9685_read_reg(struct pca9685 *pca, unsigned int reg, unsigned int *val) +static int pca9685_read_reg(struct pwm_chip *chip, unsigned int reg, unsigned int *val) { - struct device *dev = pca->chip.dev; + struct pca9685 *pca = to_pca(chip); + struct device *dev = pwmchip_parent(chip); int err; err = regmap_read(pca->regmap, reg, val); @@ -119,9 +119,10 @@ static int pca9685_read_reg(struct pca9685 *pca, unsigned int reg, unsigned int return err; } -static int pca9685_write_reg(struct pca9685 *pca, unsigned int reg, unsigned int val) +static int pca9685_write_reg(struct pwm_chip *chip, unsigned int reg, unsigned int val) { - struct device *dev = pca->chip.dev; + struct pca9685 *pca = to_pca(chip); + struct device *dev = pwmchip_parent(chip); int err; err = regmap_write(pca->regmap, reg, val); @@ -132,19 +133,19 @@ static int pca9685_write_reg(struct pca9685 *pca, unsigned int reg, unsigned int } /* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 -> 50%) */ -static void pca9685_pwm_set_duty(struct pca9685 *pca, int channel, unsigned int duty) +static void pca9685_pwm_set_duty(struct pwm_chip *chip, int channel, unsigned int duty) { - struct pwm_device *pwm = &pca->chip.pwms[channel]; + struct pwm_device *pwm = &chip->pwms[channel]; unsigned int on, off; if (duty == 0) { /* Set the full OFF bit, which has the highest precedence */ - pca9685_write_reg(pca, REG_OFF_H(channel), LED_FULL); + pca9685_write_reg(chip, REG_OFF_H(channel), LED_FULL); return; } else if (duty >= PCA9685_COUNTER_RANGE) { /* Set the full ON bit and clear the full OFF bit */ - pca9685_write_reg(pca, REG_ON_H(channel), LED_FULL); - pca9685_write_reg(pca, REG_OFF_H(channel), 0); + pca9685_write_reg(chip, REG_ON_H(channel), LED_FULL); + pca9685_write_reg(chip, REG_OFF_H(channel), 0); return; } @@ -164,16 +165,16 @@ static void pca9685_pwm_set_duty(struct pca9685 *pca, int channel, unsigned int off = (on + duty) % PCA9685_COUNTER_RANGE; /* Set ON time (clears full ON bit) */ - pca9685_write_reg(pca, REG_ON_L(channel), on & 0xff); - pca9685_write_reg(pca, REG_ON_H(channel), (on >> 8) & 0xf); + pca9685_write_reg(chip, REG_ON_L(channel), on & 0xff); + pca9685_write_reg(chip, REG_ON_H(channel), (on >> 8) & 0xf); /* Set OFF time (clears full OFF bit) */ - pca9685_write_reg(pca, REG_OFF_L(channel), off & 0xff); - pca9685_write_reg(pca, REG_OFF_H(channel), (off >> 8) & 0xf); + pca9685_write_reg(chip, REG_OFF_L(channel), off & 0xff); + pca9685_write_reg(chip, REG_OFF_H(channel), (off >> 8) & 0xf); } -static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel) +static unsigned int pca9685_pwm_get_duty(struct pwm_chip *chip, int channel) { - struct pwm_device *pwm = &pca->chip.pwms[channel]; + struct pwm_device *pwm = &chip->pwms[channel]; unsigned int off = 0, on = 0, val = 0; if (WARN_ON(channel >= PCA9685_MAXCHAN)) { @@ -181,25 +182,25 @@ static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel) return 0; } - pca9685_read_reg(pca, LED_N_OFF_H(channel), &off); + pca9685_read_reg(chip, LED_N_OFF_H(channel), &off); if (off & LED_FULL) { /* Full OFF bit is set */ return 0; } - pca9685_read_reg(pca, LED_N_ON_H(channel), &on); + pca9685_read_reg(chip, LED_N_ON_H(channel), &on); if (on & LED_FULL) { /* Full ON bit is set */ return PCA9685_COUNTER_RANGE; } - pca9685_read_reg(pca, LED_N_OFF_L(channel), &val); + pca9685_read_reg(chip, LED_N_OFF_L(channel), &val); off = ((off & 0xf) << 8) | (val & 0xff); if (!pwm->state.usage_power) return off; /* Read ON register to calculate duty cycle of staggered output */ - if (pca9685_read_reg(pca, LED_N_ON_L(channel), &val)) { + if (pca9685_read_reg(chip, LED_N_ON_L(channel), &val)) { /* Reset val to 0 in case reading LED_N_ON_L failed */ val = 0; } @@ -247,35 +248,37 @@ static void pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) static int pca9685_pwm_gpio_request(struct gpio_chip *gpio, unsigned int offset) { - struct pca9685 *pca = gpiochip_get_data(gpio); + struct pwm_chip *chip = gpiochip_get_data(gpio); + struct pca9685 *pca = to_pca(chip); if (pca9685_pwm_test_and_set_inuse(pca, offset)) return -EBUSY; - pm_runtime_get_sync(pca->chip.dev); + pm_runtime_get_sync(pwmchip_parent(chip)); return 0; } static int pca9685_pwm_gpio_get(struct gpio_chip *gpio, unsigned int offset) { - struct pca9685 *pca = gpiochip_get_data(gpio); + struct pwm_chip *chip = gpiochip_get_data(gpio); - return pca9685_pwm_get_duty(pca, offset) != 0; + return pca9685_pwm_get_duty(chip, offset) != 0; } static void pca9685_pwm_gpio_set(struct gpio_chip *gpio, unsigned int offset, int value) { - struct pca9685 *pca = gpiochip_get_data(gpio); + struct pwm_chip *chip = gpiochip_get_data(gpio); - pca9685_pwm_set_duty(pca, offset, value ? PCA9685_COUNTER_RANGE : 0); + pca9685_pwm_set_duty(chip, offset, value ? PCA9685_COUNTER_RANGE : 0); } static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset) { - struct pca9685 *pca = gpiochip_get_data(gpio); + struct pwm_chip *chip = gpiochip_get_data(gpio); + struct pca9685 *pca = to_pca(chip); - pca9685_pwm_set_duty(pca, offset, 0); - pm_runtime_put(pca->chip.dev); + pca9685_pwm_set_duty(chip, offset, 0); + pm_runtime_put(pwmchip_parent(chip)); pca9685_pwm_clear_inuse(pca, offset); } @@ -306,9 +309,10 @@ static int pca9685_pwm_gpio_direction_output(struct gpio_chip *gpio, * expose a GPIO chip here which can exclusively take over the underlying * PWM channel. */ -static int pca9685_pwm_gpio_probe(struct pca9685 *pca) +static int pca9685_pwm_gpio_probe(struct pwm_chip *chip) { - struct device *dev = pca->chip.dev; + struct pca9685 *pca = to_pca(chip); + struct device *dev = pwmchip_parent(chip); pca->gpio.label = dev_name(dev); pca->gpio.parent = dev; @@ -323,7 +327,7 @@ static int pca9685_pwm_gpio_probe(struct pca9685 *pca) pca->gpio.ngpio = PCA9685_MAXCHAN; pca->gpio.can_sleep = true; - return devm_gpiochip_add_data(dev, &pca->gpio, pca); + return devm_gpiochip_add_data(dev, &pca->gpio, chip); } #else static inline bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca, @@ -337,15 +341,16 @@ pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) { } -static inline int pca9685_pwm_gpio_probe(struct pca9685 *pca) +static inline int pca9685_pwm_gpio_probe(struct pwm_chip *chip) { return 0; } #endif -static void pca9685_set_sleep_mode(struct pca9685 *pca, bool enable) +static void pca9685_set_sleep_mode(struct pwm_chip *chip, bool enable) { - struct device *dev = pca->chip.dev; + struct device *dev = pwmchip_parent(chip); + struct pca9685 *pca = to_pca(chip); int err = regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP, enable ? MODE1_SLEEP : 0); if (err) { @@ -373,19 +378,19 @@ static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, prescale = DIV_ROUND_CLOSEST_ULL(PCA9685_OSC_CLOCK_MHZ * state->period, PCA9685_COUNTER_RANGE * 1000) - 1; if (prescale < PCA9685_PRESCALE_MIN || prescale > PCA9685_PRESCALE_MAX) { - dev_err(chip->dev, "pwm not changed: period out of bounds!\n"); + dev_err(pwmchip_parent(chip), "pwm not changed: period out of bounds!\n"); return -EINVAL; } if (!state->enabled) { - pca9685_pwm_set_duty(pca, pwm->hwpwm, 0); + pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); return 0; } - pca9685_read_reg(pca, PCA9685_PRESCALE, &val); + pca9685_read_reg(chip, PCA9685_PRESCALE, &val); if (prescale != val) { if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) { - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), "pwm not changed: periods of enabled pwms must match!\n"); return -EBUSY; } @@ -397,18 +402,18 @@ static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, * state is guaranteed active here. */ /* Put chip into sleep mode */ - pca9685_set_sleep_mode(pca, true); + pca9685_set_sleep_mode(chip, true); /* Change the chip-wide output frequency */ - pca9685_write_reg(pca, PCA9685_PRESCALE, prescale); + pca9685_write_reg(chip, PCA9685_PRESCALE, prescale); /* Wake the chip up */ - pca9685_set_sleep_mode(pca, false); + pca9685_set_sleep_mode(chip, false); } duty = PCA9685_COUNTER_RANGE * state->duty_cycle; duty = DIV_ROUND_UP_ULL(duty, state->period); - pca9685_pwm_set_duty(pca, pwm->hwpwm, duty); + pca9685_pwm_set_duty(chip, pwm->hwpwm, duty); return 0; } @@ -434,12 +439,11 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { - struct pca9685 *pca = to_pca(chip); unsigned long long duty; unsigned int val = 0; /* Calculate (chip-wide) period from prescale value */ - pca9685_read_reg(pca, PCA9685_PRESCALE, &val); + pca9685_read_reg(chip, PCA9685_PRESCALE, &val); /* * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000. * The following calculation is therefore only a multiplication @@ -462,7 +466,7 @@ static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, } state->enabled = true; - duty = pca9685_pwm_get_duty(pca, pwm->hwpwm); + duty = pca9685_pwm_get_duty(chip, pwm->hwpwm); state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE); return 0; @@ -482,7 +486,7 @@ static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) mutex_unlock(&pca->lock); } - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); return 0; } @@ -492,11 +496,11 @@ static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) struct pca9685 *pca = to_pca(chip); mutex_lock(&pca->lock); - pca9685_pwm_set_duty(pca, pwm->hwpwm, 0); + pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); clear_bit(pwm->hwpwm, pca->pwms_enabled); mutex_unlock(&pca->lock); - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); pca9685_pwm_clear_inuse(pca, pwm->hwpwm); } @@ -516,13 +520,16 @@ static const struct regmap_config pca9685_regmap_i2c_config = { static int pca9685_pwm_probe(struct i2c_client *client) { + struct pwm_chip *chip; struct pca9685 *pca; unsigned int reg; int ret; - pca = devm_kzalloc(&client->dev, sizeof(*pca), GFP_KERNEL); - if (!pca) - return -ENOMEM; + /* Add an extra channel for ALL_LED */ + chip = devm_pwmchip_alloc(&client->dev, PCA9685_MAXCHAN + 1, sizeof(*pca)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pca = to_pca(chip); pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config); if (IS_ERR(pca->regmap)) { @@ -532,11 +539,11 @@ static int pca9685_pwm_probe(struct i2c_client *client) return ret; } - i2c_set_clientdata(client, pca); + i2c_set_clientdata(client, chip); mutex_init(&pca->lock); - ret = pca9685_read_reg(pca, PCA9685_MODE2, ®); + ret = pca9685_read_reg(chip, PCA9685_MODE2, ®); if (ret) return ret; @@ -550,34 +557,30 @@ static int pca9685_pwm_probe(struct i2c_client *client) else reg |= MODE2_OUTDRV; - ret = pca9685_write_reg(pca, PCA9685_MODE2, reg); + ret = pca9685_write_reg(chip, PCA9685_MODE2, reg); if (ret) return ret; /* Disable all LED ALLCALL and SUBx addresses to avoid bus collisions */ - pca9685_read_reg(pca, PCA9685_MODE1, ®); + pca9685_read_reg(chip, PCA9685_MODE1, ®); reg &= ~(MODE1_ALLCALL | MODE1_SUB1 | MODE1_SUB2 | MODE1_SUB3); - pca9685_write_reg(pca, PCA9685_MODE1, reg); + pca9685_write_reg(chip, PCA9685_MODE1, reg); /* Reset OFF/ON registers to POR default */ - pca9685_write_reg(pca, PCA9685_ALL_LED_OFF_L, 0); - pca9685_write_reg(pca, PCA9685_ALL_LED_OFF_H, LED_FULL); - pca9685_write_reg(pca, PCA9685_ALL_LED_ON_L, 0); - pca9685_write_reg(pca, PCA9685_ALL_LED_ON_H, LED_FULL); - - pca->chip.ops = &pca9685_pwm_ops; - /* Add an extra channel for ALL_LED */ - pca->chip.npwm = PCA9685_MAXCHAN + 1; + pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_L, 0); + pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_H, LED_FULL); + pca9685_write_reg(chip, PCA9685_ALL_LED_ON_L, 0); + pca9685_write_reg(chip, PCA9685_ALL_LED_ON_H, LED_FULL); - pca->chip.dev = &client->dev; + chip->ops = &pca9685_pwm_ops; - ret = pwmchip_add(&pca->chip); + ret = pwmchip_add(chip); if (ret < 0) return ret; - ret = pca9685_pwm_gpio_probe(pca); + ret = pca9685_pwm_gpio_probe(chip); if (ret < 0) { - pwmchip_remove(&pca->chip); + pwmchip_remove(chip); return ret; } @@ -588,11 +591,11 @@ static int pca9685_pwm_probe(struct i2c_client *client) * Although the chip comes out of power-up in the sleep state, * we force it to sleep in case it was woken up before */ - pca9685_set_sleep_mode(pca, true); + pca9685_set_sleep_mode(chip, true); pm_runtime_set_suspended(&client->dev); } else { /* Wake the chip up if runtime PM is disabled */ - pca9685_set_sleep_mode(pca, false); + pca9685_set_sleep_mode(chip, false); } return 0; @@ -600,13 +603,13 @@ static int pca9685_pwm_probe(struct i2c_client *client) static void pca9685_pwm_remove(struct i2c_client *client) { - struct pca9685 *pca = i2c_get_clientdata(client); + struct pwm_chip *chip = i2c_get_clientdata(client); - pwmchip_remove(&pca->chip); + pwmchip_remove(chip); if (!pm_runtime_enabled(&client->dev)) { /* Put chip in sleep state if runtime PM is disabled */ - pca9685_set_sleep_mode(pca, true); + pca9685_set_sleep_mode(chip, true); } pm_runtime_disable(&client->dev); @@ -615,18 +618,18 @@ static void pca9685_pwm_remove(struct i2c_client *client) static int __maybe_unused pca9685_pwm_runtime_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - struct pca9685 *pca = i2c_get_clientdata(client); + struct pwm_chip *chip = i2c_get_clientdata(client); - pca9685_set_sleep_mode(pca, true); + pca9685_set_sleep_mode(chip, true); return 0; } static int __maybe_unused pca9685_pwm_runtime_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - struct pca9685 *pca = i2c_get_clientdata(client); + struct pwm_chip *chip = i2c_get_clientdata(client); - pca9685_set_sleep_mode(pca, false); + pca9685_set_sleep_mode(chip, false); return 0; } diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index 76685f926c75..bb7bb48b2e6d 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -49,7 +49,6 @@ MODULE_DEVICE_TABLE(platform, pwm_id_table); #define PWMDCR_FD (1 << 10) struct pxa_pwm_chip { - struct pwm_chip chip; struct device *dev; struct clk *clk; @@ -58,7 +57,7 @@ struct pxa_pwm_chip { static inline struct pxa_pwm_chip *to_pxa_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct pxa_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } /* @@ -159,6 +158,7 @@ MODULE_DEVICE_TABLE(of, pwm_of_match); static int pwm_probe(struct platform_device *pdev) { const struct platform_device_id *id = platform_get_device_id(pdev); + struct pwm_chip *chip; struct pxa_pwm_chip *pc; int ret = 0; @@ -168,28 +168,27 @@ static int pwm_probe(struct platform_device *pdev) if (id == NULL) return -EINVAL; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (pc == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, + (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1, + sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_pxa_pwm_chip(chip); pc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pc->clk)) return PTR_ERR(pc->clk); - pc->chip.dev = &pdev->dev; - pc->chip.ops = &pxa_pwm_ops; - pc->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; + chip->ops = &pxa_pwm_ops; - if (IS_ENABLED(CONFIG_OF)) { - pc->chip.of_xlate = of_pwm_single_xlate; - pc->chip.of_pwm_n_cells = 1; - } + if (IS_ENABLED(CONFIG_OF)) + chip->of_xlate = of_pwm_single_xlate; pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->mmio_base)) return PTR_ERR(pc->mmio_base); - ret = devm_pwmchip_add(&pdev->dev, &pc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); return ret; diff --git a/drivers/pwm/pwm-raspberrypi-poe.c b/drivers/pwm/pwm-raspberrypi-poe.c index 1ad814fdec6b..8921e7ea2cea 100644 --- a/drivers/pwm/pwm-raspberrypi-poe.c +++ b/drivers/pwm/pwm-raspberrypi-poe.c @@ -27,7 +27,6 @@ struct raspberrypi_pwm { struct rpi_firmware *firmware; - struct pwm_chip chip; unsigned int duty_cycle; }; @@ -40,7 +39,7 @@ struct raspberrypi_pwm_prop { static inline struct raspberrypi_pwm *raspberrypi_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct raspberrypi_pwm, chip); + return pwmchip_get_drvdata(chip); } static int raspberrypi_pwm_set_property(struct rpi_firmware *firmware, @@ -122,7 +121,7 @@ static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG, duty_cycle); if (ret) { - dev_err(chip->dev, "Failed to set duty cycle: %pe\n", + dev_err(pwmchip_parent(chip), "Failed to set duty cycle: %pe\n", ERR_PTR(ret)); return ret; } @@ -142,6 +141,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev) struct device_node *firmware_node; struct device *dev = &pdev->dev; struct rpi_firmware *firmware; + struct pwm_chip *chip; struct raspberrypi_pwm *rpipwm; int ret; @@ -157,14 +157,14 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev) return dev_err_probe(dev, -EPROBE_DEFER, "Failed to get firmware handle\n"); - rpipwm = devm_kzalloc(&pdev->dev, sizeof(*rpipwm), GFP_KERNEL); - if (!rpipwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, RASPBERRYPI_FIRMWARE_PWM_NUM, + sizeof(*rpipwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + rpipwm = raspberrypi_pwm_from_chip(chip); rpipwm->firmware = firmware; - rpipwm->chip.dev = dev; - rpipwm->chip.ops = &raspberrypi_pwm_ops; - rpipwm->chip.npwm = RASPBERRYPI_FIRMWARE_PWM_NUM; + chip->ops = &raspberrypi_pwm_ops; ret = raspberrypi_pwm_get_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG, &rpipwm->duty_cycle); @@ -173,7 +173,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev) return ret; } - return devm_pwmchip_add(dev, &rpipwm->chip); + return devm_pwmchip_add(dev, chip); } static const struct of_device_id raspberrypi_pwm_of_match[] = { diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c index 13269f55fccf..4cfecd88ede0 100644 --- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -38,14 +38,13 @@ #define RCAR_PWMCNT_PH0_SHIFT 0 struct rcar_pwm_chip { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; static inline struct rcar_pwm_chip *to_rcar_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct rcar_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static void rcar_pwm_write(struct rcar_pwm_chip *rp, u32 data, @@ -132,12 +131,12 @@ static int rcar_pwm_set_counter(struct rcar_pwm_chip *rp, int div, int duty_ns, static int rcar_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) { - return pm_runtime_get_sync(chip->dev); + return pm_runtime_get_sync(pwmchip_parent(chip)); } static void rcar_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); } static int rcar_pwm_enable(struct rcar_pwm_chip *rp) @@ -202,12 +201,14 @@ static const struct pwm_ops rcar_pwm_ops = { static int rcar_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct rcar_pwm_chip *rcar_pwm; int ret; - rcar_pwm = devm_kzalloc(&pdev->dev, sizeof(*rcar_pwm), GFP_KERNEL); - if (rcar_pwm == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*rcar_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + rcar_pwm = to_rcar_pwm_chip(chip); rcar_pwm->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rcar_pwm->base)) @@ -219,15 +220,13 @@ static int rcar_pwm_probe(struct platform_device *pdev) return PTR_ERR(rcar_pwm->clk); } - platform_set_drvdata(pdev, rcar_pwm); + chip->ops = &rcar_pwm_ops; - rcar_pwm->chip.dev = &pdev->dev; - rcar_pwm->chip.ops = &rcar_pwm_ops; - rcar_pwm->chip.npwm = 1; + platform_set_drvdata(pdev, chip); pm_runtime_enable(&pdev->dev); - ret = pwmchip_add(&rcar_pwm->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret); pm_runtime_disable(&pdev->dev); @@ -239,9 +238,9 @@ static int rcar_pwm_probe(struct platform_device *pdev) static void rcar_pwm_remove(struct platform_device *pdev) { - struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); - pwmchip_remove(&rcar_pwm->chip); + pwmchip_remove(chip); pm_runtime_disable(&pdev->dev); } diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 28265fdfc92a..2196080b4177 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -79,7 +79,6 @@ struct tpu_pwm_device { struct tpu_device { struct platform_device *pdev; - struct pwm_chip chip; spinlock_t lock; void __iomem *base; @@ -87,7 +86,10 @@ struct tpu_device { struct tpu_pwm_device tpd[TPU_CHANNEL_MAX]; }; -#define to_tpu_device(c) container_of(c, struct tpu_device, chip) +static inline struct tpu_device *to_tpu_device(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} static void tpu_pwm_write(struct tpu_pwm_device *tpd, int reg_nr, u16 value) { @@ -438,12 +440,14 @@ static const struct pwm_ops tpu_pwm_ops = { static int tpu_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct tpu_device *tpu; int ret; - tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL); - if (tpu == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, TPU_CHANNEL_MAX, sizeof(*tpu)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + tpu = to_tpu_device(chip); spin_lock_init(&tpu->lock); tpu->pdev = pdev; @@ -460,15 +464,13 @@ static int tpu_probe(struct platform_device *pdev) /* Initialize and register the device. */ platform_set_drvdata(pdev, tpu); - tpu->chip.dev = &pdev->dev; - tpu->chip.ops = &tpu_pwm_ops; - tpu->chip.npwm = TPU_CHANNEL_MAX; + chip->ops = &tpu_pwm_ops; ret = devm_pm_runtime_enable(&pdev->dev); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "Failed to enable runtime PM\n"); - ret = devm_pwmchip_add(&pdev->dev, &tpu->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "Failed to register PWM chip\n"); diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index a7c647e37837..0fa7575dbb54 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -30,7 +30,6 @@ #define PWM_LP_DISABLE (0 << 8) struct rockchip_pwm_chip { - struct pwm_chip chip; struct clk *clk; struct clk *pclk; const struct rockchip_pwm_data *data; @@ -54,7 +53,7 @@ struct rockchip_pwm_data { static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct rockchip_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int rockchip_pwm_get_state(struct pwm_chip *chip, @@ -296,14 +295,16 @@ MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids); static int rockchip_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct rockchip_pwm_chip *pc; u32 enable_conf, ctrl; bool enabled; int ret, count; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_rockchip_pwm_chip(chip); pc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->base)) @@ -337,18 +338,16 @@ static int rockchip_pwm_probe(struct platform_device *pdev) goto err_clk; } - platform_set_drvdata(pdev, pc); + platform_set_drvdata(pdev, chip); pc->data = device_get_match_data(&pdev->dev); - pc->chip.dev = &pdev->dev; - pc->chip.ops = &rockchip_pwm_ops; - pc->chip.npwm = 1; + chip->ops = &rockchip_pwm_ops; enable_conf = pc->data->enable_conf; ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl); enabled = (ctrl & enable_conf) == enable_conf; - ret = pwmchip_add(&pc->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n"); goto err_pclk; @@ -372,9 +371,10 @@ err_clk: static void rockchip_pwm_remove(struct platform_device *pdev) { - struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); - pwmchip_remove(&pc->chip); + pwmchip_remove(chip); clk_unprepare(pc->pclk); clk_unprepare(pc->clk); diff --git a/drivers/pwm/pwm-rz-mtu3.c b/drivers/pwm/pwm-rz-mtu3.c index bdda315b3bd3..ab39bd37edaf 100644 --- a/drivers/pwm/pwm-rz-mtu3.c +++ b/drivers/pwm/pwm-rz-mtu3.c @@ -61,7 +61,6 @@ struct rz_mtu3_pwm_channel { /** * struct rz_mtu3_pwm_chip - MTU3 pwm private data * - * @chip: MTU3 pwm chip data * @clk: MTU3 module clock * @lock: Lock to prevent concurrent access for usage count * @rate: MTU3 clock rate @@ -72,7 +71,6 @@ struct rz_mtu3_pwm_channel { */ struct rz_mtu3_pwm_chip { - struct pwm_chip chip; struct clk *clk; struct mutex lock; unsigned long rate; @@ -92,7 +90,7 @@ static const struct rz_mtu3_channel_io_map channel_map[] = { static inline struct rz_mtu3_pwm_chip *to_rz_mtu3_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct rz_mtu3_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static void rz_mtu3_pwm_read_tgr_registers(struct rz_mtu3_pwm_channel *priv, @@ -211,15 +209,15 @@ static void rz_mtu3_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) mutex_unlock(&rz_mtu3_pwm->lock); } -static int rz_mtu3_pwm_enable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, - struct pwm_device *pwm) +static int rz_mtu3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { + struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); struct rz_mtu3_pwm_channel *priv; u32 ch; u8 val; int rc; - rc = pm_runtime_resume_and_get(rz_mtu3_pwm->chip.dev); + rc = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (rc) return rc; @@ -243,9 +241,9 @@ static int rz_mtu3_pwm_enable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, return 0; } -static void rz_mtu3_pwm_disable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, - struct pwm_device *pwm) +static void rz_mtu3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) { + struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); struct rz_mtu3_pwm_channel *priv; u32 ch; @@ -265,7 +263,7 @@ static void rz_mtu3_pwm_disable(struct rz_mtu3_pwm_chip *rz_mtu3_pwm, mutex_unlock(&rz_mtu3_pwm->lock); - pm_runtime_put_sync(rz_mtu3_pwm->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } static int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, @@ -274,7 +272,7 @@ static int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); int rc; - rc = pm_runtime_resume_and_get(chip->dev); + rc = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (rc) return rc; @@ -307,7 +305,7 @@ static int rz_mtu3_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, } state->polarity = PWM_POLARITY_NORMAL; - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); return 0; } @@ -362,7 +360,7 @@ static int rz_mtu3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (!pwm->state.enabled) { int rc; - rc = pm_runtime_resume_and_get(chip->dev); + rc = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (rc) return rc; } @@ -399,7 +397,7 @@ static int rz_mtu3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, /* If the PWM is not enabled, turn the clock off again to save power. */ if (!pwm->state.enabled) - pm_runtime_put(chip->dev); + pm_runtime_put(pwmchip_parent(chip)); return 0; } @@ -416,7 +414,7 @@ static int rz_mtu3_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (!state->enabled) { if (enabled) - rz_mtu3_pwm_disable(rz_mtu3_pwm, pwm); + rz_mtu3_pwm_disable(chip, pwm); return 0; } @@ -428,7 +426,7 @@ static int rz_mtu3_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return ret; if (!enabled) - ret = rz_mtu3_pwm_enable(rz_mtu3_pwm, pwm); + ret = rz_mtu3_pwm_enable(chip, pwm); return ret; } @@ -442,7 +440,8 @@ static const struct pwm_ops rz_mtu3_pwm_ops = { static int rz_mtu3_pwm_pm_runtime_suspend(struct device *dev) { - struct rz_mtu3_pwm_chip *rz_mtu3_pwm = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); clk_disable_unprepare(rz_mtu3_pwm->clk); @@ -451,7 +450,8 @@ static int rz_mtu3_pwm_pm_runtime_suspend(struct device *dev) static int rz_mtu3_pwm_pm_runtime_resume(struct device *dev) { - struct rz_mtu3_pwm_chip *rz_mtu3_pwm = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); return clk_prepare_enable(rz_mtu3_pwm->clk); } @@ -462,24 +462,28 @@ static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_pwm_pm_ops, static void rz_mtu3_pwm_pm_disable(void *data) { - struct rz_mtu3_pwm_chip *rz_mtu3_pwm = data; + struct pwm_chip *chip = data; + struct rz_mtu3_pwm_chip *rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); clk_rate_exclusive_put(rz_mtu3_pwm->clk); - pm_runtime_disable(rz_mtu3_pwm->chip.dev); - pm_runtime_set_suspended(rz_mtu3_pwm->chip.dev); + pm_runtime_disable(pwmchip_parent(chip)); + pm_runtime_set_suspended(pwmchip_parent(chip)); } static int rz_mtu3_pwm_probe(struct platform_device *pdev) { struct rz_mtu3 *parent_ddata = dev_get_drvdata(pdev->dev.parent); struct rz_mtu3_pwm_chip *rz_mtu3_pwm; + struct pwm_chip *chip; struct device *dev = &pdev->dev; unsigned int i, j = 0; int ret; - rz_mtu3_pwm = devm_kzalloc(&pdev->dev, sizeof(*rz_mtu3_pwm), GFP_KERNEL); - if (!rz_mtu3_pwm) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, RZ_MTU3_MAX_PWM_CHANNELS, + sizeof(*rz_mtu3_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + rz_mtu3_pwm = to_rz_mtu3_pwm_chip(chip); rz_mtu3_pwm->clk = parent_ddata->clk; @@ -494,7 +498,7 @@ static int rz_mtu3_pwm_probe(struct platform_device *pdev) } mutex_init(&rz_mtu3_pwm->lock); - platform_set_drvdata(pdev, rz_mtu3_pwm); + platform_set_drvdata(pdev, chip); ret = clk_prepare_enable(rz_mtu3_pwm->clk); if (ret) return dev_err_probe(dev, ret, "Clock enable failed\n"); @@ -514,15 +518,13 @@ static int rz_mtu3_pwm_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - rz_mtu3_pwm->chip.dev = &pdev->dev; ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_pwm_pm_disable, - rz_mtu3_pwm); + chip); if (ret < 0) return ret; - rz_mtu3_pwm->chip.ops = &rz_mtu3_pwm_ops; - rz_mtu3_pwm->chip.npwm = RZ_MTU3_MAX_PWM_CHANNELS; - ret = devm_pwmchip_add(&pdev->dev, &rz_mtu3_pwm->chip); + chip->ops = &rz_mtu3_pwm_ops; + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index 6e77302f7368..efb60c9f0cb3 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -69,7 +69,6 @@ struct samsung_pwm_channel { /** * struct samsung_pwm_chip - private data of PWM chip - * @chip: generic PWM chip * @variant: local copy of hardware variant data * @inverter_mask: inverter status for all channels - one bit per channel * @disabled_mask: disabled status for all channels - one bit per channel @@ -80,7 +79,6 @@ struct samsung_pwm_channel { * @channel: per channel driver data */ struct samsung_pwm_chip { - struct pwm_chip chip; struct samsung_pwm_variant variant; u8 inverter_mask; u8 disabled_mask; @@ -110,7 +108,7 @@ static DEFINE_SPINLOCK(samsung_pwm_lock); static inline struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct samsung_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline unsigned int to_tcon_channel(unsigned int channel) @@ -181,9 +179,10 @@ static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *our_chip, return rate / (reg + 1); } -static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *our_chip, +static unsigned long pwm_samsung_calc_tin(struct pwm_chip *chip, unsigned int chan, unsigned long freq) { + struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); struct samsung_pwm_variant *variant = &our_chip->variant; unsigned long rate; struct clk *clk; @@ -197,12 +196,12 @@ static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *our_chip, return rate; } - dev_warn(our_chip->chip.dev, + dev_warn(pwmchip_parent(chip), "tclk of PWM %d is inoperational, using tdiv\n", chan); } rate = pwm_samsung_get_tin_rate(our_chip, chan); - dev_dbg(our_chip->chip.dev, "tin parent at %lu\n", rate); + dev_dbg(pwmchip_parent(chip), "tin parent at %lu\n", rate); /* * Compare minimum PWM frequency that can be achieved with possible @@ -232,7 +231,7 @@ static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm) struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) { - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), "tried to request PWM channel %d without output\n", pwm->hwpwm); return -EINVAL; @@ -326,12 +325,12 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, period = NSEC_PER_SEC / period_ns; - dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n", + dev_dbg(pwmchip_parent(chip), "duty_ns=%d, period_ns=%d (%u)\n", duty_ns, period_ns, period); - tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period); + tin_rate = pwm_samsung_calc_tin(chip, pwm->hwpwm, period); - dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate); + dev_dbg(pwmchip_parent(chip), "tin_rate=%lu\n", tin_rate); tin_ns = NSEC_PER_SEC / tin_rate; tcnt = period_ns / tin_ns; @@ -355,8 +354,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, /* -1UL will give 100% duty. */ --tcmp; - dev_dbg(our_chip->chip.dev, - "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt); + dev_dbg(pwmchip_parent(chip), "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt); /* Update PWM registers. */ writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm)); @@ -368,7 +366,7 @@ static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, * shortly afer this update (before it autoreloaded the new values). */ if (oldtcmp == (u32) -1) { - dev_dbg(our_chip->chip.dev, "Forcing manual update"); + dev_dbg(pwmchip_parent(chip), "Forcing manual update"); pwm_samsung_manual_update(our_chip, pwm); } @@ -507,9 +505,10 @@ 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 *our_chip) +static int pwm_samsung_parse_dt(struct pwm_chip *chip) { - struct device_node *np = our_chip->chip.dev->of_node; + struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); + struct device_node *np = pwmchip_parent(chip)->of_node; const struct of_device_id *match; struct property *prop; const __be32 *cur; @@ -523,7 +522,7 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip) of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { if (val >= SAMSUNG_PWM_NUM) { - dev_err(our_chip->chip.dev, + dev_err(pwmchip_parent(chip), "%s: invalid channel index in samsung,pwm-outputs property\n", __func__); continue; @@ -534,7 +533,7 @@ static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip) return 0; } #else -static int pwm_samsung_parse_dt(struct samsung_pwm_chip *our_chip) +static int pwm_samsung_parse_dt(struct pwm_chip *chip) { return -ENODEV; } @@ -544,27 +543,26 @@ static int pwm_samsung_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct samsung_pwm_chip *our_chip; + struct pwm_chip *chip; unsigned int chan; int ret; - our_chip = devm_kzalloc(&pdev->dev, sizeof(*our_chip), GFP_KERNEL); - if (our_chip == NULL) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, SAMSUNG_PWM_NUM, sizeof(*our_chip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + our_chip = to_samsung_pwm_chip(chip); - our_chip->chip.dev = &pdev->dev; - our_chip->chip.ops = &pwm_samsung_ops; - our_chip->chip.npwm = SAMSUNG_PWM_NUM; + chip->ops = &pwm_samsung_ops; our_chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1; if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { - ret = pwm_samsung_parse_dt(our_chip); + ret = pwm_samsung_parse_dt(chip); if (ret) return ret; } else { - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "no platform data specified\n"); - return -EINVAL; - } + if (!pdev->dev.platform_data) + return dev_err_probe(&pdev->dev, -EINVAL, + "no platform data specified\n"); memcpy(&our_chip->variant, pdev->dev.platform_data, sizeof(our_chip->variant)); @@ -574,17 +572,10 @@ static int pwm_samsung_probe(struct platform_device *pdev) if (IS_ERR(our_chip->base)) return PTR_ERR(our_chip->base); - 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(our_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; - } + our_chip->base_clk = devm_clk_get_enabled(&pdev->dev, "timers"); + if (IS_ERR(our_chip->base_clk)) + return dev_err_probe(dev, PTR_ERR(our_chip->base_clk), + "failed to get timer base clk\n"); for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) if (our_chip->variant.output_mask & BIT(chan)) @@ -594,14 +585,11 @@ static int pwm_samsung_probe(struct platform_device *pdev) our_chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0"); our_chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1"); - platform_set_drvdata(pdev, our_chip); + platform_set_drvdata(pdev, chip); - ret = pwmchip_add(&our_chip->chip); - if (ret < 0) { - dev_err(dev, "failed to register PWM chip\n"); - clk_disable_unprepare(our_chip->base_clk); - return ret; - } + ret = devm_pwmchip_add(&pdev->dev, chip); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to register PWM chip\n"); dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n", clk_get_rate(our_chip->base_clk), @@ -611,19 +599,10 @@ static int pwm_samsung_probe(struct platform_device *pdev) return 0; } -static void pwm_samsung_remove(struct platform_device *pdev) -{ - struct samsung_pwm_chip *our_chip = platform_get_drvdata(pdev); - - pwmchip_remove(&our_chip->chip); - - clk_disable_unprepare(our_chip->base_clk); -} - static int pwm_samsung_resume(struct device *dev) { - struct samsung_pwm_chip *our_chip = dev_get_drvdata(dev); - struct pwm_chip *chip = &our_chip->chip; + struct pwm_chip *chip = dev_get_drvdata(dev); + struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); unsigned int i; for (i = 0; i < SAMSUNG_PWM_NUM; i++) { @@ -662,7 +641,6 @@ static struct platform_driver pwm_samsung_driver = { .of_match_table = of_match_ptr(samsung_pwm_matches), }, .probe = pwm_samsung_probe, - .remove_new = pwm_samsung_remove, }; module_platform_driver(pwm_samsung_driver); diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index 089e50bdbbf0..ed7957cc51fd 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -41,7 +41,7 @@ #define PWM_SIFIVE_DEFAULT_PERIOD 10000000 struct pwm_sifive_ddata { - struct pwm_chip chip; + struct device *parent; struct mutex lock; /* lock to protect user_count and approx_period */ struct notifier_block notifier; struct clk *clk; @@ -54,7 +54,7 @@ struct pwm_sifive_ddata { static inline struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *chip) { - return container_of(chip, struct pwm_sifive_ddata, chip); + return pwmchip_get_drvdata(chip); } static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *pwm) @@ -102,7 +102,7 @@ static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata, /* As scale <= 15 the shift operation cannot overflow. */ num = (unsigned long long)NSEC_PER_SEC << (PWM_SIFIVE_CMPWIDTH + scale); ddata->real_period = div64_ul(num, rate); - dev_dbg(ddata->chip.dev, + dev_dbg(ddata->parent, "New real_period = %u ns\n", ddata->real_period); } @@ -185,7 +185,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (!enabled) { ret = clk_enable(ddata->clk); if (ret) { - dev_err(ddata->chip.dev, "Enable clk failed\n"); + dev_err(pwmchip_parent(chip), "Enable clk failed\n"); return ret; } } @@ -230,15 +230,14 @@ static int pwm_sifive_probe(struct platform_device *pdev) u32 val; unsigned int enabled_pwms = 0, enabled_clks = 1; - ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); - if (!ddata) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, 4, sizeof(*ddata)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + ddata = pwm_sifive_chip_to_ddata(chip); + ddata->parent = dev; mutex_init(&ddata->lock); - chip = &ddata->chip; - chip->dev = dev; chip->ops = &pwm_sifive_ops; - chip->npwm = 4; ddata->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(ddata->regs)) @@ -296,7 +295,7 @@ static int pwm_sifive_probe(struct platform_device *pdev) goto unregister_clk; } - platform_set_drvdata(pdev, ddata); + platform_set_drvdata(pdev, chip); dev_dbg(dev, "SiFive PWM chip registered %d PWMs\n", chip->npwm); return 0; @@ -314,15 +313,16 @@ disable_clk: static void pwm_sifive_remove(struct platform_device *dev) { - struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev); + struct pwm_chip *chip = platform_get_drvdata(dev); + struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip); struct pwm_device *pwm; int ch; - pwmchip_remove(&ddata->chip); + pwmchip_remove(chip); clk_notifier_unregister(ddata->clk, &ddata->notifier); - for (ch = 0; ch < ddata->chip.npwm; ch++) { - pwm = &ddata->chip.pwms[ch]; + for (ch = 0; ch < chip->npwm; ch++) { + pwm = &chip->pwms[ch]; if (pwm->state.enabled) clk_disable(ddata->clk); } diff --git a/drivers/pwm/pwm-sl28cpld.c b/drivers/pwm/pwm-sl28cpld.c index 88b01ff9e460..934378d6a002 100644 --- a/drivers/pwm/pwm-sl28cpld.c +++ b/drivers/pwm/pwm-sl28cpld.c @@ -81,14 +81,13 @@ regmap_write((priv)->regmap, (priv)->offset + (reg), (val)) struct sl28cpld_pwm { - struct pwm_chip chip; struct regmap *regmap; u32 offset; }; static inline struct sl28cpld_pwm *sl28cpld_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct sl28cpld_pwm, chip); + return pwmchip_get_drvdata(chip); } static int sl28cpld_pwm_get_state(struct pwm_chip *chip, @@ -213,9 +212,10 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev) return -ENODEV; } - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = sl28cpld_pwm_from_chip(chip); priv->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!priv->regmap) { @@ -231,10 +231,7 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev) } /* Initialize the pwm_chip structure */ - chip = &priv->chip; - chip->dev = &pdev->dev; chip->ops = &sl28cpld_pwm_ops; - chip->npwm = 1; ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) { diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index ff991319feef..6c6f3b38c835 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -48,17 +48,15 @@ * * @mmio_base: base address of pwm chip * @clk: pointer to clk structure of pwm chip - * @chip: linux pwm chip representation */ struct spear_pwm_chip { void __iomem *mmio_base; struct clk *clk; - struct pwm_chip chip; }; static inline struct spear_pwm_chip *to_spear_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct spear_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline u32 spear_pwm_readl(struct spear_pwm_chip *chip, unsigned int num, @@ -194,13 +192,15 @@ static const struct pwm_ops spear_pwm_ops = { static int spear_pwm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct pwm_chip *chip; struct spear_pwm_chip *pc; int ret; u32 val; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, NUM_PWM, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_spear_pwm_chip(chip); pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->mmio_base)) @@ -211,9 +211,7 @@ static int spear_pwm_probe(struct platform_device *pdev) 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; + chip->ops = &spear_pwm_ops; if (of_device_is_compatible(np, "st,spear1340-pwm")) { ret = clk_enable(pc->clk); @@ -232,7 +230,7 @@ static int spear_pwm_probe(struct platform_device *pdev) clk_disable(pc->clk); } - ret = devm_pwmchip_add(&pdev->dev, &pc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n"); diff --git a/drivers/pwm/pwm-sprd.c b/drivers/pwm/pwm-sprd.c index 77939e161006..4c76ca5e4cdd 100644 --- a/drivers/pwm/pwm-sprd.c +++ b/drivers/pwm/pwm-sprd.c @@ -34,15 +34,12 @@ struct sprd_pwm_chn { struct sprd_pwm_chip { void __iomem *base; - struct device *dev; - struct pwm_chip chip; - int num_pwms; 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); + return pwmchip_get_drvdata(chip); } /* @@ -86,7 +83,7 @@ static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, */ ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); if (ret) { - dev_err(spc->dev, "failed to enable pwm%u clocks\n", + dev_err(pwmchip_parent(chip), "failed to enable pwm%u clocks\n", pwm->hwpwm); return ret; } @@ -183,7 +180,7 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ret = clk_bulk_prepare_enable(SPRD_PWM_CHN_CLKS_NUM, chn->clks); if (ret) { - dev_err(spc->dev, + dev_err(pwmchip_parent(chip), "failed to enable pwm%u clocks\n", pwm->hwpwm); return ret; @@ -215,65 +212,64 @@ static const struct pwm_ops sprd_pwm_ops = { .get_state = sprd_pwm_get_state, }; -static int sprd_pwm_clk_init(struct sprd_pwm_chip *spc) +static int sprd_pwm_clk_init(struct device *dev, + struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM]) { struct clk *clk_pwm; int ret, i; for (i = 0; i < SPRD_PWM_CHN_NUM; i++) { - struct sprd_pwm_chn *chn = &spc->chn[i]; int j; for (j = 0; j < SPRD_PWM_CHN_CLKS_NUM; ++j) - chn->clks[j].id = + chn[i].clks[j].id = sprd_pwm_clks[i * SPRD_PWM_CHN_CLKS_NUM + j]; - ret = devm_clk_bulk_get(spc->dev, SPRD_PWM_CHN_CLKS_NUM, - chn->clks); + ret = devm_clk_bulk_get(dev, SPRD_PWM_CHN_CLKS_NUM, + chn[i].clks); if (ret) { if (ret == -ENOENT) break; - return dev_err_probe(spc->dev, ret, + return dev_err_probe(dev, ret, "failed to get channel clocks\n"); } - clk_pwm = chn->clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; - chn->clk_rate = clk_get_rate(clk_pwm); + clk_pwm = chn[i].clks[SPRD_PWM_CHN_OUTPUT_CLK].clk; + chn[i].clk_rate = clk_get_rate(clk_pwm); } if (!i) - return dev_err_probe(spc->dev, -ENODEV, "no available PWM channels\n"); + return dev_err_probe(dev, -ENODEV, "no available PWM channels\n"); - spc->num_pwms = i; - - return 0; + return i; } static int sprd_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct sprd_pwm_chip *spc; - int ret; + struct sprd_pwm_chn chn[SPRD_PWM_CHN_NUM]; + int ret, npwm; - spc = devm_kzalloc(&pdev->dev, sizeof(*spc), GFP_KERNEL); - if (!spc) - return -ENOMEM; + npwm = sprd_pwm_clk_init(&pdev->dev, chn); + if (npwm < 0) + return npwm; + + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*spc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + spc = sprd_pwm_from_chip(chip); spc->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(spc->base)) return PTR_ERR(spc->base); - spc->dev = &pdev->dev; - - ret = sprd_pwm_clk_init(spc); - if (ret) - return ret; + memcpy(spc->chn, chn, sizeof(chn)); - spc->chip.dev = &pdev->dev; - spc->chip.ops = &sprd_pwm_ops; - spc->chip.npwm = spc->num_pwms; + chip->ops = &sprd_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &spc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) dev_err(&pdev->dev, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index 6cf55cf34d39..39d80da0e14a 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c @@ -94,7 +94,6 @@ struct sti_pwm_chip { struct regmap_field *pwm_cpt_en; struct regmap_field *pwm_cpt_int_en; struct regmap_field *pwm_cpt_int_stat; - struct pwm_chip chip; struct pwm_device *cur; unsigned long configured; unsigned int en_count; @@ -114,7 +113,7 @@ static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) { - return container_of(chip, struct sti_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } /* @@ -395,8 +394,17 @@ out: static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { + struct sti_pwm_chip *pc = to_sti_pwmchip(chip); + struct sti_pwm_compat_data *cdata = pc->cdata; + struct device *dev = pc->dev; int err; + if (pwm->hwpwm >= cdata->pwm_num_devs) { + dev_err(dev, "device %u is not valid for pwm mode\n", + pwm->hwpwm); + return -EINVAL; + } + if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL; @@ -498,23 +506,7 @@ static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) { struct device *dev = pc->dev; const struct reg_field *reg_fields; - struct device_node *np = dev->of_node; struct sti_pwm_compat_data *cdata = pc->cdata; - u32 num_devs; - int ret; - - ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs); - if (!ret) - cdata->pwm_num_devs = num_devs; - - ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs); - if (!ret) - cdata->cpt_num_devs = num_devs; - - if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) { - dev_err(dev, "No channels configured\n"); - return -EINVAL; - } reg_fields = cdata->reg_fields; @@ -560,14 +552,33 @@ static const struct regmap_config sti_pwm_regmap_config = { static int sti_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + u32 num_devs; + unsigned int pwm_num_devs = 0; + unsigned int cpt_num_devs = 0; struct sti_pwm_compat_data *cdata; + struct pwm_chip *chip; struct sti_pwm_chip *pc; unsigned int i; int irq, ret; - pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs); + if (!ret) + pwm_num_devs = num_devs; + + ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs); + if (!ret) + cpt_num_devs = num_devs; + + if (!pwm_num_devs && !cpt_num_devs) { + dev_err(dev, "No channels configured\n"); + return -EINVAL; + } + + chip = devm_pwmchip_alloc(dev, max(pwm_num_devs, cpt_num_devs), sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_sti_pwmchip(chip); cdata = devm_kzalloc(dev, sizeof(*cdata), GFP_KERNEL); if (!cdata) @@ -600,8 +611,8 @@ static int sti_pwm_probe(struct platform_device *pdev) cdata->reg_fields = sti_pwm_regfields; cdata->max_prescale = 0xff; cdata->max_pwm_cnt = 255; - cdata->pwm_num_devs = 0; - cdata->cpt_num_devs = 0; + cdata->pwm_num_devs = pwm_num_devs; + cdata->cpt_num_devs = cpt_num_devs; pc->cdata = cdata; pc->dev = dev; @@ -644,9 +655,7 @@ static int sti_pwm_probe(struct platform_device *pdev) return -ENOMEM; } - pc->chip.dev = dev; - pc->chip.ops = &sti_pwm_ops; - pc->chip.npwm = pc->cdata->pwm_num_devs; + chip->ops = &sti_pwm_ops; for (i = 0; i < cdata->cpt_num_devs; i++) { struct sti_cpt_ddata *ddata = &cdata->ddata[i]; @@ -655,23 +664,24 @@ static int sti_pwm_probe(struct platform_device *pdev) mutex_init(&ddata->lock); } - ret = pwmchip_add(&pc->chip); + ret = pwmchip_add(chip); if (ret < 0) { clk_unprepare(pc->pwm_clk); clk_unprepare(pc->cpt_clk); return ret; } - platform_set_drvdata(pdev, pc); + platform_set_drvdata(pdev, chip); return 0; } static void sti_pwm_remove(struct platform_device *pdev) { - struct sti_pwm_chip *pc = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct sti_pwm_chip *pc = to_sti_pwmchip(chip); - pwmchip_remove(&pc->chip); + pwmchip_remove(chip); clk_unprepare(pc->pwm_clk); clk_unprepare(pc->cpt_clk); diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c index 439068f3eca1..989731256f50 100644 --- a/drivers/pwm/pwm-stm32-lp.c +++ b/drivers/pwm/pwm-stm32-lp.c @@ -18,14 +18,13 @@ #include <linux/pwm.h> struct stm32_pwm_lp { - struct pwm_chip chip; struct clk *clk; struct regmap *regmap; }; static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip) { - return container_of(chip, struct stm32_pwm_lp, chip); + return pwmchip_get_drvdata(chip); } /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */ @@ -61,7 +60,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, do_div(div, NSEC_PER_SEC); if (!div) { /* Clock is too slow to achieve requested period. */ - dev_dbg(priv->chip.dev, "Can't reach %llu ns\n", state->period); + dev_dbg(pwmchip_parent(chip), "Can't reach %llu ns\n", state->period); return -EINVAL; } @@ -69,7 +68,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, while (div > STM32_LPTIM_MAX_ARR) { presc++; if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) { - dev_err(priv->chip.dev, "max prescaler exceeded\n"); + dev_err(pwmchip_parent(chip), "max prescaler exceeded\n"); return -EINVAL; } div = prd >> presc; @@ -130,7 +129,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 100, 1000); if (ret) { - dev_err(priv->chip.dev, "ARR/CMP registers write issue\n"); + dev_err(pwmchip_parent(chip), "ARR/CMP registers write issue\n"); goto err; } ret = regmap_write(priv->regmap, STM32_LPTIM_ICR, @@ -197,36 +196,36 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev) { struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_pwm_lp *priv; + struct pwm_chip *chip; int ret; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = to_stm32_pwm_lp(chip); priv->regmap = ddata->regmap; priv->clk = ddata->clk; - priv->chip.dev = &pdev->dev; - priv->chip.ops = &stm32_pwm_lp_ops; - priv->chip.npwm = 1; + chip->ops = &stm32_pwm_lp_ops; - ret = devm_pwmchip_add(&pdev->dev, &priv->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return ret; - platform_set_drvdata(pdev, priv); + platform_set_drvdata(pdev, chip); return 0; } static int stm32_pwm_lp_suspend(struct device *dev) { - struct stm32_pwm_lp *priv = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); struct pwm_state state; - pwm_get_state(&priv->chip.pwms[0], &state); + pwm_get_state(&chip->pwms[0], &state); if (state.enabled) { dev_err(dev, "The consumer didn't stop us (%s)\n", - priv->chip.pwms[0].label); + chip->pwms[0].label); return -EBUSY; } diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 5f10cba492ec..0c028d17c075 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -27,7 +27,6 @@ struct stm32_breakinput { }; struct stm32_pwm { - struct pwm_chip chip; struct mutex lock; /* protect pwm config/enable */ struct clk *clk; struct regmap *regmap; @@ -40,7 +39,7 @@ struct stm32_pwm { static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip) { - return container_of(chip, struct stm32_pwm, chip); + return pwmchip_get_drvdata(chip); } static u32 active_channels(struct stm32_pwm *dev) @@ -90,11 +89,12 @@ static u32 active_channels(struct stm32_pwm *dev) * - Period = t2 - t0 * - Duty cycle = t1 - t0 */ -static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, +static int stm32_pwm_raw_capture(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long tmo_ms, u32 *raw_prd, u32 *raw_dty) { - struct device *parent = priv->chip.dev->parent; + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); + struct device *parent = pwmchip_parent(chip)->parent; enum stm32_timers_dmas dma_id; u32 ccen, ccr; int ret; @@ -170,7 +170,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, ret = clk_enable(priv->clk); if (ret) { - dev_err(priv->chip.dev, "failed to enable counter clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable counter clock\n"); goto unlock; } @@ -208,7 +208,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ? TIM_CCER_CC2P : TIM_CCER_CC4P); - ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); + ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd, &raw_dty); if (ret) goto stop; @@ -229,7 +229,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, /* 2nd measure with new scale */ psc /= scale; regmap_write(priv->regmap, TIM_PSC, psc); - ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, + ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd, &raw_dty); if (ret) goto stop; @@ -257,7 +257,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, FIELD_PREP(TIM_CCMR_IC1PSC, icpsc) | FIELD_PREP(TIM_CCMR_IC2PSC, icpsc)); - ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); + ret = stm32_pwm_raw_capture(chip, pwm, tmo_ms, &raw_prd, &raw_dty); if (ret) goto stop; @@ -605,7 +605,7 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) priv->have_complementary_output = (ccer != 0); } -static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, +static unsigned int stm32_pwm_detect_channels(struct regmap *regmap, unsigned int *num_enabled) { u32 ccer, ccer_backup; @@ -614,10 +614,10 @@ static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, * If channels enable bits don't exist writing 1 will have no * effect so we can detect and count them. */ - regmap_read(priv->regmap, TIM_CCER, &ccer_backup); - regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); - regmap_read(priv->regmap, TIM_CCER, &ccer); - regmap_write(priv->regmap, TIM_CCER, ccer_backup); + regmap_read(regmap, TIM_CCER, &ccer_backup); + regmap_set_bits(regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_read(regmap, TIM_CCER, &ccer); + regmap_write(regmap, TIM_CCER, ccer_backup); *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); @@ -629,14 +629,18 @@ static int stm32_pwm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); + struct pwm_chip *chip; struct stm32_pwm *priv; - unsigned int num_enabled; + unsigned int npwm, num_enabled; unsigned int i; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled); + + chip = devm_pwmchip_alloc(dev, npwm, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = to_stm32_pwm_dev(chip); mutex_init(&priv->lock); priv->regmap = ddata->regmap; @@ -652,37 +656,36 @@ static int stm32_pwm_probe(struct platform_device *pdev) stm32_pwm_detect_complementary(priv); - priv->chip.dev = dev; - priv->chip.ops = &stm32pwm_ops; - priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); + chip->ops = &stm32pwm_ops; /* Initialize clock refcount to number of enabled PWM channels. */ for (i = 0; i < num_enabled; i++) clk_enable(priv->clk); - ret = devm_pwmchip_add(dev, &priv->chip); + ret = devm_pwmchip_add(dev, chip); if (ret < 0) return ret; - platform_set_drvdata(pdev, priv); + platform_set_drvdata(pdev, chip); return 0; } static int stm32_pwm_suspend(struct device *dev) { - struct stm32_pwm *priv = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); unsigned int i; u32 ccer, mask; /* Look for active channels */ ccer = active_channels(priv); - for (i = 0; i < priv->chip.npwm; i++) { + for (i = 0; i < chip->npwm; i++) { mask = TIM_CCER_CC1E << (i * 4); if (ccer & mask) { dev_err(dev, "PWM %u still in use by consumer %s\n", - i, priv->chip.pwms[i].label); + i, chip->pwms[i].label); return -EBUSY; } } @@ -692,7 +695,8 @@ static int stm32_pwm_suspend(struct device *dev) static int stm32_pwm_resume(struct device *dev) { - struct stm32_pwm *priv = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); int ret; ret = pinctrl_pm_select_default_state(dev); diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c index 19c0c0f39675..bb91062d5f1d 100644 --- a/drivers/pwm/pwm-stmpe.c +++ b/drivers/pwm/pwm-stmpe.c @@ -27,13 +27,12 @@ struct stmpe_pwm { struct stmpe *stmpe; - struct pwm_chip chip; u8 last_duty; }; static inline struct stmpe_pwm *to_stmpe_pwm(struct pwm_chip *chip) { - return container_of(chip, struct stmpe_pwm, chip); + return pwmchip_get_drvdata(chip); } static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) @@ -44,7 +43,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS); if (ret < 0) { - dev_dbg(chip->dev, "error reading PWM#%u control\n", + dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n", pwm->hwpwm); return ret; } @@ -53,7 +52,7 @@ static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value); if (ret) { - dev_dbg(chip->dev, "error writing PWM#%u control\n", + dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n", pwm->hwpwm); return ret; } @@ -70,7 +69,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip, ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS); if (ret < 0) { - dev_dbg(chip->dev, "error reading PWM#%u control\n", + dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n", pwm->hwpwm); return ret; } @@ -79,7 +78,7 @@ static int stmpe_24xx_pwm_disable(struct pwm_chip *chip, ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value); if (ret) - dev_dbg(chip->dev, "error writing PWM#%u control\n", + dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n", pwm->hwpwm); return ret; } @@ -125,7 +124,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = stmpe_set_altfunc(stmpe_pwm->stmpe, BIT(pin), STMPE_BLOCK_PWM); if (ret) { - dev_err(chip->dev, "unable to connect PWM#%u to pin\n", + dev_err(pwmchip_parent(chip), "unable to connect PWM#%u to pin\n", pwm->hwpwm); return ret; } @@ -150,7 +149,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, return -ENODEV; } - dev_dbg(chip->dev, "PWM#%u: config duty %d ns, period %d ns\n", + dev_dbg(pwmchip_parent(chip), "PWM#%u: config duty %d ns, period %d ns\n", pwm->hwpwm, duty_ns, period_ns); if (duty_ns == 0) { @@ -216,7 +215,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, program[1] = BRANCH; } - dev_dbg(chip->dev, + dev_dbg(pwmchip_parent(chip), "PWM#%u: value = %02x, last_duty = %02x, program=%04x,%04x,%04x\n", pwm->hwpwm, value, last, program[0], program[1], program[2]); @@ -233,7 +232,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value); if (ret) { - dev_dbg(chip->dev, "error writing register %02x: %d\n", + dev_dbg(pwmchip_parent(chip), "error writing register %02x: %d\n", offset, ret); return ret; } @@ -242,7 +241,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value); if (ret) { - dev_dbg(chip->dev, "error writing register %02x: %d\n", + dev_dbg(pwmchip_parent(chip), "error writing register %02x: %d\n", offset, ret); return ret; } @@ -255,7 +254,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, /* Sleep for 200ms so we're sure it will take effect */ msleep(200); - dev_dbg(chip->dev, "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i); + dev_dbg(pwmchip_parent(chip), "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i); return 0; } @@ -292,33 +291,36 @@ static const struct pwm_ops stmpe_24xx_pwm_ops = { static int __init stmpe_pwm_probe(struct platform_device *pdev) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); + struct pwm_chip *chip; struct stmpe_pwm *stmpe_pwm; int ret; - stmpe_pwm = devm_kzalloc(&pdev->dev, sizeof(*stmpe_pwm), GFP_KERNEL); - if (!stmpe_pwm) - return -ENOMEM; + switch (stmpe->partnum) { + case STMPE2401: + case STMPE2403: + break; + case STMPE1601: + return dev_err_probe(&pdev->dev, -ENODEV, + "STMPE1601 not yet supported\n"); + default: + return dev_err_probe(&pdev->dev, -ENODEV, + "Unknown STMPE PWM\n"); + } - stmpe_pwm->stmpe = stmpe; - stmpe_pwm->chip.dev = &pdev->dev; + chip = devm_pwmchip_alloc(&pdev->dev, 3, sizeof(*stmpe_pwm)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + stmpe_pwm = to_stmpe_pwm(chip); - if (stmpe->partnum == STMPE2401 || stmpe->partnum == STMPE2403) { - stmpe_pwm->chip.ops = &stmpe_24xx_pwm_ops; - stmpe_pwm->chip.npwm = 3; - } else { - if (stmpe->partnum == STMPE1601) - dev_err(&pdev->dev, "STMPE1601 not yet supported\n"); - else - dev_err(&pdev->dev, "Unknown STMPE PWM\n"); + stmpe_pwm->stmpe = stmpe; - return -ENODEV; - } + chip->ops = &stmpe_24xx_pwm_ops; ret = stmpe_enable(stmpe, STMPE_BLOCK_PWM); if (ret) return ret; - ret = pwmchip_add(&stmpe_pwm->chip); + ret = pwmchip_add(chip); if (ret) { stmpe_disable(stmpe, STMPE_BLOCK_PWM); return ret; diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 1a439025540d..5c29590d1821 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -81,7 +81,6 @@ struct sun4i_pwm_data { }; struct sun4i_pwm_chip { - struct pwm_chip chip; struct clk *bus_clk; struct clk *clk; struct reset_control *rst; @@ -92,35 +91,35 @@ struct sun4i_pwm_chip { static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct sun4i_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } -static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip, +static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *sun4ichip, unsigned long offset) { - return readl(chip->base + offset); + return readl(sun4ichip->base + offset); } -static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip, +static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *sun4ichip, u32 val, unsigned long offset) { - writel(val, chip->base + offset); + writel(val, sun4ichip->base + offset); } static int sun4i_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { - struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip); + struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip); u64 clk_rate, tmp; u32 val; unsigned int prescaler; - clk_rate = clk_get_rate(sun4i_pwm->clk); + clk_rate = clk_get_rate(sun4ichip->clk); if (!clk_rate) return -EINVAL; - val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); + val = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG); /* * PWM chapter in H6 manual has a diagram which explains that if bypass @@ -128,7 +127,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip, * proved that also enable bit is ignored in this case. */ if ((val & BIT_CH(PWM_BYPASS, pwm->hwpwm)) && - sun4i_pwm->data->has_direct_mod_clk_output) { + sun4ichip->data->has_direct_mod_clk_output) { state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, clk_rate); state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2); state->polarity = PWM_POLARITY_NORMAL; @@ -137,7 +136,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip, } if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) && - sun4i_pwm->data->has_prescaler_bypass) + sun4ichip->data->has_prescaler_bypass) prescaler = 1; else prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)]; @@ -156,7 +155,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip, else state->enabled = false; - val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm)); + val = sun4i_pwm_readl(sun4ichip, PWM_CH_PRD(pwm->hwpwm)); tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val); state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); @@ -167,7 +166,7 @@ static int sun4i_pwm_get_state(struct pwm_chip *chip, return 0; } -static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, +static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4ichip, const struct pwm_state *state, u32 *dty, u32 *prd, unsigned int *prsclr, bool *bypass) @@ -175,9 +174,9 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, u64 clk_rate, div = 0; unsigned int prescaler = 0; - clk_rate = clk_get_rate(sun4i_pwm->clk); + clk_rate = clk_get_rate(sun4ichip->clk); - *bypass = sun4i_pwm->data->has_direct_mod_clk_output && + *bypass = sun4ichip->data->has_direct_mod_clk_output && state->enabled && (state->period * clk_rate >= NSEC_PER_SEC) && (state->period * clk_rate < 2 * NSEC_PER_SEC) && @@ -187,7 +186,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, if (*bypass) return 0; - if (sun4i_pwm->data->has_prescaler_bypass) { + if (sun4ichip->data->has_prescaler_bypass) { /* First, test without any prescaler when available */ prescaler = PWM_PRESCAL_MASK; /* @@ -233,7 +232,7 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { - struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip); + struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip); struct pwm_state cstate; u32 ctrl, duty = 0, period = 0, val; int ret; @@ -243,31 +242,31 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, pwm_get_state(pwm, &cstate); if (!cstate.enabled) { - ret = clk_prepare_enable(sun4i_pwm->clk); + ret = clk_prepare_enable(sun4ichip->clk); if (ret) { - dev_err(chip->dev, "failed to enable PWM clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable PWM clock\n"); return ret; } } - ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, + ret = sun4i_pwm_calculate(sun4ichip, state, &duty, &period, &prescaler, &bypass); if (ret) { - dev_err(chip->dev, "period exceeds the maximum value\n"); + dev_err(pwmchip_parent(chip), "period exceeds the maximum value\n"); if (!cstate.enabled) - clk_disable_unprepare(sun4i_pwm->clk); + clk_disable_unprepare(sun4ichip->clk); return ret; } - spin_lock(&sun4i_pwm->ctrl_lock); - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); + spin_lock(&sun4ichip->ctrl_lock); + ctrl = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG); - if (sun4i_pwm->data->has_direct_mod_clk_output) { + if (sun4ichip->data->has_direct_mod_clk_output) { if (bypass) { ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); /* We can skip other parameter */ - sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); - spin_unlock(&sun4i_pwm->ctrl_lock); + sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG); + spin_unlock(&sun4ichip->ctrl_lock); return 0; } @@ -277,14 +276,14 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) { /* Prescaler changed, the clock has to be gated */ ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); - sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); + sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG); ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm); ctrl |= BIT_CH(prescaler, pwm->hwpwm); } val = (duty & PWM_DTY_MASK) | PWM_PRD(period); - sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm)); + sun4i_pwm_writel(sun4ichip, val, PWM_CH_PRD(pwm->hwpwm)); if (state->polarity != PWM_POLARITY_NORMAL) ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm); @@ -296,9 +295,9 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->enabled) ctrl |= BIT_CH(PWM_EN, pwm->hwpwm); - sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); + sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG); - spin_unlock(&sun4i_pwm->ctrl_lock); + spin_unlock(&sun4ichip->ctrl_lock); if (state->enabled) return 0; @@ -310,14 +309,14 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, else usleep_range(delay_us, delay_us * 2); - spin_lock(&sun4i_pwm->ctrl_lock); - ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); + spin_lock(&sun4ichip->ctrl_lock); + ctrl = sun4i_pwm_readl(sun4ichip, PWM_CTRL_REG); ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); ctrl &= ~BIT_CH(PWM_EN, pwm->hwpwm); - sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); - spin_unlock(&sun4i_pwm->ctrl_lock); + sun4i_pwm_writel(sun4ichip, ctrl, PWM_CTRL_REG); + spin_unlock(&sun4ichip->ctrl_lock); - clk_disable_unprepare(sun4i_pwm->clk); + clk_disable_unprepare(sun4ichip->clk); return 0; } @@ -384,17 +383,21 @@ MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids); static int sun4i_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; + const struct sun4i_pwm_data *data; struct sun4i_pwm_chip *sun4ichip; int ret; - sun4ichip = devm_kzalloc(&pdev->dev, sizeof(*sun4ichip), GFP_KERNEL); - if (!sun4ichip) - return -ENOMEM; - - sun4ichip->data = of_device_get_match_data(&pdev->dev); - if (!sun4ichip->data) + data = of_device_get_match_data(&pdev->dev); + if (!data) return -ENODEV; + chip = devm_pwmchip_alloc(&pdev->dev, data->npwm, sizeof(*sun4ichip)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + sun4ichip = to_sun4i_pwm_chip(chip); + + sun4ichip->data = data; sun4ichip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sun4ichip->base)) return PTR_ERR(sun4ichip->base); @@ -451,19 +454,17 @@ static int sun4i_pwm_probe(struct platform_device *pdev) goto err_bus; } - sun4ichip->chip.dev = &pdev->dev; - sun4ichip->chip.ops = &sun4i_pwm_ops; - sun4ichip->chip.npwm = sun4ichip->data->npwm; + chip->ops = &sun4i_pwm_ops; spin_lock_init(&sun4ichip->ctrl_lock); - ret = pwmchip_add(&sun4ichip->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); goto err_pwm_add; } - platform_set_drvdata(pdev, sun4ichip); + platform_set_drvdata(pdev, chip); return 0; @@ -477,9 +478,10 @@ err_bus: static void sun4i_pwm_remove(struct platform_device *pdev) { - struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct sun4i_pwm_chip *sun4ichip = to_sun4i_pwm_chip(chip); - pwmchip_remove(&sun4ichip->chip); + pwmchip_remove(chip); clk_disable_unprepare(sun4ichip->bus_clk); reset_control_assert(sun4ichip->rst); diff --git a/drivers/pwm/pwm-sunplus.c b/drivers/pwm/pwm-sunplus.c index 773e2f80526e..b342b843247b 100644 --- a/drivers/pwm/pwm-sunplus.c +++ b/drivers/pwm/pwm-sunplus.c @@ -43,14 +43,13 @@ #define SP7021_PWM_NUM 4 struct sunplus_pwm { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; static inline struct sunplus_pwm *to_sunplus_pwm(struct pwm_chip *chip) { - return container_of(chip, struct sunplus_pwm, chip); + return pwmchip_get_drvdata(chip); } static int sunplus_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -175,12 +174,14 @@ static void sunplus_pwm_clk_release(void *data) static int sunplus_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct pwm_chip *chip; struct sunplus_pwm *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, SP7021_PWM_NUM, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = to_sunplus_pwm(chip); priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) @@ -203,11 +204,9 @@ static int sunplus_pwm_probe(struct platform_device *pdev) return ret; } - priv->chip.dev = dev; - priv->chip.ops = &sunplus_pwm_ops; - priv->chip.npwm = SP7021_PWM_NUM; + chip->ops = &sunplus_pwm_ops; - ret = devm_pwmchip_add(dev, &priv->chip); + ret = devm_pwmchip_add(dev, chip); if (ret < 0) return dev_err_probe(dev, ret, "Cannot register sunplus PWM\n"); diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 82ee2f0754f9..a3d69976148f 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -65,9 +65,6 @@ struct tegra_pwm_soc { }; struct tegra_pwm_chip { - struct pwm_chip chip; - struct device *dev; - struct clk *clk; struct reset_control*rst; @@ -81,7 +78,7 @@ struct tegra_pwm_chip { static inline struct tegra_pwm_chip *to_tegra_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct tegra_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline u32 pwm_readl(struct tegra_pwm_chip *pc, unsigned int offset) @@ -158,7 +155,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, */ required_clk_rate *= 2; - err = dev_pm_opp_set_rate(pc->dev, required_clk_rate); + err = dev_pm_opp_set_rate(pwmchip_parent(chip), required_clk_rate); if (err < 0) return -EINVAL; @@ -194,7 +191,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, * before writing the register. Otherwise, keep it enabled. */ if (!pwm_is_enabled(pwm)) { - err = pm_runtime_resume_and_get(pc->dev); + err = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (err) return err; } else @@ -206,7 +203,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, * If the PWM is not enabled, turn the clock off again to save power. */ if (!pwm_is_enabled(pwm)) - pm_runtime_put(pc->dev); + pm_runtime_put(pwmchip_parent(chip)); return 0; } @@ -217,7 +214,7 @@ static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) int rc = 0; u32 val; - rc = pm_runtime_resume_and_get(pc->dev); + rc = pm_runtime_resume_and_get(pwmchip_parent(chip)); if (rc) return rc; @@ -237,7 +234,7 @@ static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) val &= ~PWM_ENABLE; pwm_writel(pc, pwm->hwpwm, val); - pm_runtime_put_sync(pc->dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } static int tegra_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -272,21 +269,25 @@ static const struct pwm_ops tegra_pwm_ops = { static int tegra_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct tegra_pwm_chip *pc; + const struct tegra_pwm_soc *soc; int ret; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + soc = of_device_get_match_data(&pdev->dev); + + chip = devm_pwmchip_alloc(&pdev->dev, soc->num_channels, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_tegra_pwm_chip(chip); - pc->soc = of_device_get_match_data(&pdev->dev); - pc->dev = &pdev->dev; + pc->soc = soc; pc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->regs)) return PTR_ERR(pc->regs); - platform_set_drvdata(pdev, pc); + platform_set_drvdata(pdev, chip); pc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pc->clk)) @@ -302,7 +303,7 @@ static int tegra_pwm_probe(struct platform_device *pdev) return ret; /* Set maximum frequency of the IP */ - ret = dev_pm_opp_set_rate(pc->dev, pc->soc->max_frequency); + ret = dev_pm_opp_set_rate(&pdev->dev, pc->soc->max_frequency); if (ret < 0) { dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret); goto put_pm; @@ -328,11 +329,9 @@ static int tegra_pwm_probe(struct platform_device *pdev) reset_control_deassert(pc->rst); - pc->chip.dev = &pdev->dev; - pc->chip.ops = &tegra_pwm_ops; - pc->chip.npwm = pc->soc->num_channels; + chip->ops = &tegra_pwm_ops; - ret = pwmchip_add(&pc->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); reset_control_assert(pc->rst); @@ -350,9 +349,10 @@ put_pm: static void tegra_pwm_remove(struct platform_device *pdev) { - struct tegra_pwm_chip *pc = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip); - pwmchip_remove(&pc->chip); + pwmchip_remove(chip); reset_control_assert(pc->rst); @@ -361,7 +361,8 @@ static void tegra_pwm_remove(struct platform_device *pdev) static int __maybe_unused tegra_pwm_runtime_suspend(struct device *dev) { - struct tegra_pwm_chip *pc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip); int err; clk_disable_unprepare(pc->clk); @@ -377,7 +378,8 @@ static int __maybe_unused tegra_pwm_runtime_suspend(struct device *dev) static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev) { - struct tegra_pwm_chip *pc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); + struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip); int err; err = pinctrl_pm_select_default_state(dev); diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index d974f4414ac9..d6c2b1b1387e 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -32,7 +32,6 @@ struct ecap_context { }; struct ecap_pwm_chip { - struct pwm_chip chip; unsigned int clk_rate; void __iomem *mmio_base; struct ecap_context ctx; @@ -40,7 +39,7 @@ struct ecap_pwm_chip { static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct ecap_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } /* @@ -70,7 +69,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, duty_cycles = (u32)c; } - pm_runtime_get_sync(pc->chip.dev); + pm_runtime_get_sync(pwmchip_parent(chip)); value = readw(pc->mmio_base + ECCTL2); @@ -100,7 +99,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, writew(value, pc->mmio_base + ECCTL2); } - pm_runtime_put_sync(pc->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); return 0; } @@ -111,7 +110,7 @@ static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip); u16 value; - pm_runtime_get_sync(pc->chip.dev); + pm_runtime_get_sync(pwmchip_parent(chip)); value = readw(pc->mmio_base + ECCTL2); @@ -124,7 +123,7 @@ static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, writew(value, pc->mmio_base + ECCTL2); - pm_runtime_put_sync(pc->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); return 0; } @@ -135,7 +134,7 @@ static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) u16 value; /* Leave clock enabled on enabling PWM */ - pm_runtime_get_sync(pc->chip.dev); + pm_runtime_get_sync(pwmchip_parent(chip)); /* * Enable 'Free run Time stamp counter mode' to start counter @@ -162,7 +161,7 @@ static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) writew(value, pc->mmio_base + ECCTL2); /* Disable clock on PWM disable */ - pm_runtime_put_sync(pc->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -218,12 +217,14 @@ static int ecap_pwm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct ecap_pwm_chip *pc; + struct pwm_chip *chip; struct clk *clk; int ret; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_ecap_pwm_chip(chip); clk = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(clk)) { @@ -244,21 +245,19 @@ static int ecap_pwm_probe(struct platform_device *pdev) return -EINVAL; } - pc->chip.dev = &pdev->dev; - pc->chip.ops = &ecap_pwm_ops; - pc->chip.npwm = 1; + chip->ops = &ecap_pwm_ops; pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->mmio_base)) return PTR_ERR(pc->mmio_base); - ret = devm_pwmchip_add(&pdev->dev, &pc->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); return ret; } - platform_set_drvdata(pdev, pc); + platform_set_drvdata(pdev, chip); pm_runtime_enable(&pdev->dev); return 0; @@ -269,17 +268,21 @@ static void ecap_pwm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static void ecap_pwm_save_context(struct ecap_pwm_chip *pc) +static void ecap_pwm_save_context(struct pwm_chip *chip) { - pm_runtime_get_sync(pc->chip.dev); + struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip); + + pm_runtime_get_sync(pwmchip_parent(chip)); pc->ctx.ecctl2 = readw(pc->mmio_base + ECCTL2); pc->ctx.cap4 = readl(pc->mmio_base + CAP4); pc->ctx.cap3 = readl(pc->mmio_base + CAP3); - pm_runtime_put_sync(pc->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } -static void ecap_pwm_restore_context(struct ecap_pwm_chip *pc) +static void ecap_pwm_restore_context(struct pwm_chip *chip) { + struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip); + writel(pc->ctx.cap3, pc->mmio_base + CAP3); writel(pc->ctx.cap4, pc->mmio_base + CAP4); writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2); @@ -287,10 +290,10 @@ static void ecap_pwm_restore_context(struct ecap_pwm_chip *pc) static int ecap_pwm_suspend(struct device *dev) { - struct ecap_pwm_chip *pc = dev_get_drvdata(dev); - struct pwm_device *pwm = pc->chip.pwms; + struct pwm_chip *chip = dev_get_drvdata(dev); + struct pwm_device *pwm = chip->pwms; - ecap_pwm_save_context(pc); + ecap_pwm_save_context(chip); /* Disable explicitly if PWM is running */ if (pwm_is_enabled(pwm)) @@ -301,14 +304,14 @@ static int ecap_pwm_suspend(struct device *dev) static int ecap_pwm_resume(struct device *dev) { - struct ecap_pwm_chip *pc = dev_get_drvdata(dev); - struct pwm_device *pwm = pc->chip.pwms; + struct pwm_chip *chip = dev_get_drvdata(dev); + struct pwm_device *pwm = chip->pwms; /* Enable explicitly if PWM was running */ if (pwm_is_enabled(pwm)) pm_runtime_get_sync(dev); - ecap_pwm_restore_context(pc); + ecap_pwm_restore_context(chip); return 0; } diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index af231fa74fa9..e5104725d9b7 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -105,7 +105,6 @@ struct ehrpwm_context { }; struct ehrpwm_pwm_chip { - struct pwm_chip chip; unsigned long clk_rate; void __iomem *mmio_base; unsigned long period_cycles[NUM_PWM_CHANNEL]; @@ -116,7 +115,7 @@ struct ehrpwm_pwm_chip { static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) { - return container_of(chip, struct ehrpwm_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static inline u16 ehrpwm_read(void __iomem *base, unsigned int offset) @@ -256,7 +255,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (i == pwm->hwpwm) continue; - dev_err(chip->dev, + dev_err(pwmchip_parent(chip), "period value conflicts with channel %u\n", i); return -EINVAL; @@ -268,11 +267,11 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, /* Configure clock prescaler to support Low frequency PWM wave */ if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, &tb_divval)) { - dev_err(chip->dev, "Unsupported values\n"); + dev_err(pwmchip_parent(chip), "Unsupported values\n"); return -EINVAL; } - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); /* Update clock prescaler values */ ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CLKDIV_MASK, tb_divval); @@ -299,7 +298,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles); - pm_runtime_put_sync(chip->dev); + pm_runtime_put_sync(pwmchip_parent(chip)); return 0; } @@ -323,7 +322,7 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) int ret; /* Leave clock enabled on enabling PWM */ - pm_runtime_get_sync(chip->dev); + pm_runtime_get_sync(pwmchip_parent(chip)); /* Disabling Action Qualifier on PWM output */ if (pwm->hwpwm) { @@ -346,8 +345,8 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) /* Enable TBCLK */ ret = clk_enable(pc->tbclk); if (ret) { - dev_err(chip->dev, "Failed to enable TBCLK for %s: %d\n", - dev_name(pc->chip.dev), ret); + dev_err(pwmchip_parent(chip), "Failed to enable TBCLK for %s: %d\n", + dev_name(pwmchip_parent(chip)), ret); return ret; } @@ -385,7 +384,7 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) clk_disable(pc->tbclk); /* Disable clock on PWM disable */ - pm_runtime_put_sync(chip->dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) @@ -393,8 +392,8 @@ static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); if (pwm_is_enabled(pwm)) { - dev_warn(chip->dev, "Removing PWM device without disabling\n"); - pm_runtime_put_sync(chip->dev); + dev_warn(pwmchip_parent(chip), "Removing PWM device without disabling\n"); + pm_runtime_put_sync(pwmchip_parent(chip)); } /* set period value to zero on free */ @@ -450,12 +449,14 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct ehrpwm_pwm_chip *pc; + struct pwm_chip *chip; struct clk *clk; int ret; - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, NUM_PWM_CHANNEL, sizeof(*pc)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + pc = to_ehrpwm_pwm_chip(chip); clk = devm_clk_get(&pdev->dev, "fck"); if (IS_ERR(clk)) { @@ -474,9 +475,7 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) return -EINVAL; } - pc->chip.dev = &pdev->dev; - pc->chip.ops = &ehrpwm_pwm_ops; - pc->chip.npwm = NUM_PWM_CHANNEL; + chip->ops = &ehrpwm_pwm_ops; pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pc->mmio_base)) @@ -493,13 +492,13 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) return ret; } - ret = pwmchip_add(&pc->chip); + ret = pwmchip_add(chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); goto err_clk_unprepare; } - platform_set_drvdata(pdev, pc); + platform_set_drvdata(pdev, chip); pm_runtime_enable(&pdev->dev); return 0; @@ -512,18 +511,21 @@ err_clk_unprepare: static void ehrpwm_pwm_remove(struct platform_device *pdev) { - struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); - pwmchip_remove(&pc->chip); + pwmchip_remove(chip); clk_unprepare(pc->tbclk); pm_runtime_disable(&pdev->dev); } -static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc) +static void ehrpwm_pwm_save_context(struct pwm_chip *chip) { - pm_runtime_get_sync(pc->chip.dev); + struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); + + pm_runtime_get_sync(pwmchip_parent(chip)); pc->ctx.tbctl = ehrpwm_read(pc->mmio_base, TBCTL); pc->ctx.tbprd = ehrpwm_read(pc->mmio_base, TBPRD); @@ -534,11 +536,13 @@ static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc) pc->ctx.aqsfrc = ehrpwm_read(pc->mmio_base, AQSFRC); pc->ctx.aqcsfrc = ehrpwm_read(pc->mmio_base, AQCSFRC); - pm_runtime_put_sync(pc->chip.dev); + pm_runtime_put_sync(pwmchip_parent(chip)); } -static void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc) +static void ehrpwm_pwm_restore_context(struct pwm_chip *chip) { + struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); + ehrpwm_write(pc->mmio_base, TBPRD, pc->ctx.tbprd); ehrpwm_write(pc->mmio_base, CMPA, pc->ctx.cmpa); ehrpwm_write(pc->mmio_base, CMPB, pc->ctx.cmpb); @@ -551,13 +555,13 @@ static void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc) static int ehrpwm_pwm_suspend(struct device *dev) { - struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); unsigned int i; - ehrpwm_pwm_save_context(pc); + ehrpwm_pwm_save_context(chip); - for (i = 0; i < pc->chip.npwm; i++) { - struct pwm_device *pwm = &pc->chip.pwms[i]; + for (i = 0; i < chip->npwm; i++) { + struct pwm_device *pwm = &chip->pwms[i]; if (!pwm_is_enabled(pwm)) continue; @@ -571,11 +575,11 @@ static int ehrpwm_pwm_suspend(struct device *dev) static int ehrpwm_pwm_resume(struct device *dev) { - struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev); + struct pwm_chip *chip = dev_get_drvdata(dev); unsigned int i; - for (i = 0; i < pc->chip.npwm; i++) { - struct pwm_device *pwm = &pc->chip.pwms[i]; + for (i = 0; i < chip->npwm; i++) { + struct pwm_device *pwm = &chip->pwms[i]; if (!pwm_is_enabled(pwm)) continue; @@ -584,7 +588,7 @@ static int ehrpwm_pwm_resume(struct device *dev) pm_runtime_get_sync(dev); } - ehrpwm_pwm_restore_context(pc); + ehrpwm_pwm_restore_context(chip); return 0; } diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c index c670ccb81653..4b10a8dab312 100644 --- a/drivers/pwm/pwm-twl-led.c +++ b/drivers/pwm/pwm-twl-led.c @@ -62,13 +62,12 @@ #define TWL6040_LED_MODE_MASK 0x03 struct twl_pwmled_chip { - struct pwm_chip chip; struct mutex mutex; }; static inline struct twl_pwmled_chip *to_twl(struct pwm_chip *chip) { - return container_of(chip, struct twl_pwmled_chip, chip); + return pwmchip_get_drvdata(chip); } static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, @@ -100,7 +99,7 @@ static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = twl_i2c_write(TWL4030_MODULE_LED, pwm_config, base, 2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to configure PWM\n", pwm->label); return ret; } @@ -114,7 +113,7 @@ static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read LEDEN\n", pwm->label); goto out; } @@ -122,7 +121,7 @@ static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -139,7 +138,7 @@ static void twl4030_pwmled_disable(struct pwm_chip *chip, mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read LEDEN\n", pwm->label); goto out; } @@ -147,7 +146,7 @@ static void twl4030_pwmled_disable(struct pwm_chip *chip, ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -203,7 +202,7 @@ static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, on_time, TWL6030_LED_PWM_CTRL1); if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to configure PWM\n", pwm->label); return ret; } @@ -217,7 +216,7 @@ static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", + dev_err(pwmchip_parent(chip), "%s: Failed to read PWM_CTRL2\n", pwm->label); goto out; } @@ -227,7 +226,7 @@ static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -244,7 +243,7 @@ static void twl6030_pwmled_disable(struct pwm_chip *chip, mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", + dev_err(pwmchip_parent(chip), "%s: Failed to read PWM_CTRL2\n", pwm->label); goto out; } @@ -254,7 +253,7 @@ static void twl6030_pwmled_disable(struct pwm_chip *chip, ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -295,7 +294,7 @@ static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", + dev_err(pwmchip_parent(chip), "%s: Failed to read PWM_CTRL2\n", pwm->label); goto out; } @@ -305,7 +304,7 @@ static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to request PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -321,7 +320,7 @@ static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", + dev_err(pwmchip_parent(chip), "%s: Failed to read PWM_CTRL2\n", pwm->label); goto out; } @@ -331,7 +330,7 @@ static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to free PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -345,25 +344,29 @@ static const struct pwm_ops twl6030_pwmled_ops = { static int twl_pwmled_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct twl_pwmled_chip *twl; - - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; + unsigned int npwm; + const struct pwm_ops *ops; if (twl_class_is_4030()) { - twl->chip.ops = &twl4030_pwmled_ops; - twl->chip.npwm = 2; + ops = &twl4030_pwmled_ops; + npwm = 2; } else { - twl->chip.ops = &twl6030_pwmled_ops; - twl->chip.npwm = 1; + ops = &twl6030_pwmled_ops; + npwm = 1; } - twl->chip.dev = &pdev->dev; + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*twl)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + twl = to_twl(chip); + + chip->ops = ops; mutex_init(&twl->mutex); - return devm_pwmchip_add(&pdev->dev, &twl->chip); + return devm_pwmchip_add(&pdev->dev, chip); } #ifdef CONFIG_OF diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c index 68e02c9a6bf9..8f981ffff4b4 100644 --- a/drivers/pwm/pwm-twl.c +++ b/drivers/pwm/pwm-twl.c @@ -46,7 +46,6 @@ #define TWL6030_PWM_TOGGLE(pwm, x) ((x) << (pwm * 3)) struct twl_pwm_chip { - struct pwm_chip chip; struct mutex mutex; u8 twl6030_toggle3; u8 twl4030_pwm_mux; @@ -54,7 +53,7 @@ struct twl_pwm_chip { static inline struct twl_pwm_chip *to_twl(struct pwm_chip *chip) { - return container_of(chip, struct twl_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, @@ -86,7 +85,7 @@ static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ret = twl_i2c_write(TWL_MODULE_PWM, pwm_config, base, 2); if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to configure PWM\n", pwm->label); return ret; } @@ -100,7 +99,7 @@ static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read GPBR1\n", pwm->label); goto out; } @@ -108,13 +107,13 @@ static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM\n", pwm->label); val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE); ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -130,7 +129,7 @@ static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read GPBR1\n", pwm->label); goto out; } @@ -138,13 +137,13 @@ static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE); ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -167,7 +166,7 @@ static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read PMBR1\n", pwm->label); goto out; } @@ -181,7 +180,7 @@ static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to request PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -202,7 +201,7 @@ static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) mutex_lock(&twl->mutex); ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to read PMBR1\n", pwm->label); goto out; } @@ -212,7 +211,7 @@ static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); if (ret < 0) - dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to free PWM\n", pwm->label); out: mutex_unlock(&twl->mutex); @@ -231,7 +230,7 @@ static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to enable PWM\n", pwm->label); goto out; } @@ -254,7 +253,7 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); goto out; } @@ -262,7 +261,7 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); goto out; } @@ -270,7 +269,7 @@ static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); if (ret < 0) { - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); goto out; } @@ -341,23 +340,22 @@ static const struct pwm_ops twl6030_pwm_ops = { static int twl_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct twl_pwm_chip *twl; - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, 2, sizeof(*twl)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + twl = to_twl(chip); if (twl_class_is_4030()) - twl->chip.ops = &twl4030_pwm_ops; + chip->ops = &twl4030_pwm_ops; else - twl->chip.ops = &twl6030_pwm_ops; - - twl->chip.dev = &pdev->dev; - twl->chip.npwm = 2; + chip->ops = &twl6030_pwm_ops; mutex_init(&twl->mutex); - return devm_pwmchip_add(&pdev->dev, &twl->chip); + return devm_pwmchip_add(&pdev->dev, chip); } #ifdef CONFIG_OF diff --git a/drivers/pwm/pwm-visconti.c b/drivers/pwm/pwm-visconti.c index 8d736d558122..9e55380957be 100644 --- a/drivers/pwm/pwm-visconti.c +++ b/drivers/pwm/pwm-visconti.c @@ -34,13 +34,12 @@ #define PIPGM_PWMC_POLARITY_MASK GENMASK(5, 5) struct visconti_pwm_chip { - struct pwm_chip chip; void __iomem *base; }; static inline struct visconti_pwm_chip *visconti_pwm_from_chip(struct pwm_chip *chip) { - return container_of(chip, struct visconti_pwm_chip, chip); + return pwmchip_get_drvdata(chip); } static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -134,22 +133,22 @@ static const struct pwm_ops visconti_pwm_ops = { static int visconti_pwm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct pwm_chip *chip; struct visconti_pwm_chip *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + chip = devm_pwmchip_alloc(dev, 4, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = visconti_pwm_from_chip(chip); priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - priv->chip.dev = dev; - priv->chip.ops = &visconti_pwm_ops; - priv->chip.npwm = 4; + chip->ops = &visconti_pwm_ops; - ret = devm_pwmchip_add(&pdev->dev, &priv->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n"); diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 7bfeacee05d0..016c82d65527 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -45,16 +45,19 @@ #define STATUS_ALL_UPDATE 0x0F struct vt8500_chip { - struct pwm_chip chip; void __iomem *base; struct clk *clk; }; -#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip) +static inline struct vt8500_chip *to_vt8500_chip(struct pwm_chip *chip) +{ + return pwmchip_get_drvdata(chip); +} #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) -static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask) +static inline void vt8500_pwm_busy_wait(struct pwm_chip *chip, int nr, u8 bitmask) { + struct vt8500_chip *vt8500 = to_vt8500_chip(chip); int loops = msecs_to_loops(10); u32 mask = bitmask << (nr << 8); @@ -62,7 +65,7 @@ static inline void vt8500_pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 b cpu_relax(); if (unlikely(!loops)) - dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n", + dev_warn(pwmchip_parent(chip), "Waiting for status bits 0x%x to clear timed out\n", mask); } @@ -77,7 +80,7 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, err = clk_enable(vt8500->clk); if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable clock\n"); return err; } @@ -103,18 +106,18 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, dc = div64_u64(c, period_ns); writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_SCALAR_UPDATE); writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_PERIOD_UPDATE); writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_DUTY_UPDATE); val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val |= CTRL_AUTOLOAD; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); clk_disable(vt8500->clk); return 0; @@ -128,14 +131,14 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) err = clk_enable(vt8500->clk); if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); + dev_err(pwmchip_parent(chip), "failed to enable clock\n"); return err; } val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val |= CTRL_ENABLE; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); return 0; } @@ -148,7 +151,7 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); val &= ~CTRL_ENABLE; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); clk_disable(vt8500->clk); } @@ -168,7 +171,7 @@ static int vt8500_pwm_set_polarity(struct pwm_chip *chip, val &= ~CTRL_INVERT; writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); - vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); + vt8500_pwm_busy_wait(chip, pwm->hwpwm, STATUS_CTRL_UPDATE); return 0; } @@ -231,6 +234,7 @@ MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids); static int vt8500_pwm_probe(struct platform_device *pdev) { + struct pwm_chip *chip; struct vt8500_chip *vt8500; struct device_node *np = pdev->dev.of_node; int ret; @@ -238,13 +242,12 @@ static int vt8500_pwm_probe(struct platform_device *pdev) 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) - return -ENOMEM; + chip = devm_pwmchip_alloc(&pdev->dev, VT8500_NR_PWMS, sizeof(*vt8500)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + vt8500 = to_vt8500_chip(chip); - vt8500->chip.dev = &pdev->dev; - vt8500->chip.ops = &vt8500_pwm_ops; - vt8500->chip.npwm = VT8500_NR_PWMS; + chip->ops = &vt8500_pwm_ops; vt8500->clk = devm_clk_get_prepared(&pdev->dev, NULL); if (IS_ERR(vt8500->clk)) @@ -254,7 +257,7 @@ static int vt8500_pwm_probe(struct platform_device *pdev) if (IS_ERR(vt8500->base)) return PTR_ERR(vt8500->base); - ret = devm_pwmchip_add(&pdev->dev, &vt8500->chip); + ret = devm_pwmchip_add(&pdev->dev, chip); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n"); diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c index 5f3c2a6fed11..3a7deebb0d0c 100644 --- a/drivers/pwm/pwm-xilinx.c +++ b/drivers/pwm/pwm-xilinx.c @@ -80,15 +80,10 @@ unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv, #define TCSR_PWM_CLEAR (TCSR_MDT | TCSR_LOAD) #define TCSR_PWM_MASK (TCSR_PWM_SET | TCSR_PWM_CLEAR) -struct xilinx_pwm_device { - struct pwm_chip chip; - struct xilinx_timer_priv priv; -}; - static inline struct xilinx_timer_priv *xilinx_pwm_chip_to_priv(struct pwm_chip *chip) { - return &container_of(chip, struct xilinx_pwm_device, chip)->priv; + return pwmchip_get_drvdata(chip); } static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1) @@ -214,7 +209,7 @@ static int xilinx_pwm_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct xilinx_timer_priv *priv; - struct xilinx_pwm_device *xilinx_pwm; + struct pwm_chip *chip; u32 pwm_cells, one_timer, width; void __iomem *regs; @@ -225,11 +220,11 @@ static int xilinx_pwm_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "could not read #pwm-cells\n"); - xilinx_pwm = devm_kzalloc(dev, sizeof(*xilinx_pwm), GFP_KERNEL); - if (!xilinx_pwm) - return -ENOMEM; - platform_set_drvdata(pdev, xilinx_pwm); - priv = &xilinx_pwm->priv; + chip = devm_pwmchip_alloc(dev, 1, sizeof(*priv)); + if (IS_ERR(chip)) + return PTR_ERR(chip); + priv = xilinx_pwm_chip_to_priv(chip); + platform_set_drvdata(pdev, chip); regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) @@ -278,10 +273,8 @@ static int xilinx_pwm_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "Clock enable failed\n"); clk_rate_exclusive_get(priv->clk); - xilinx_pwm->chip.dev = dev; - xilinx_pwm->chip.ops = &xilinx_pwm_ops; - xilinx_pwm->chip.npwm = 1; - ret = pwmchip_add(&xilinx_pwm->chip); + chip->ops = &xilinx_pwm_ops; + ret = pwmchip_add(chip); if (ret) { clk_rate_exclusive_put(priv->clk); clk_disable_unprepare(priv->clk); @@ -293,11 +286,12 @@ static int xilinx_pwm_probe(struct platform_device *pdev) static void xilinx_pwm_remove(struct platform_device *pdev) { - struct xilinx_pwm_device *xilinx_pwm = platform_get_drvdata(pdev); + struct pwm_chip *chip = platform_get_drvdata(pdev); + struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip); - pwmchip_remove(&xilinx_pwm->chip); - clk_rate_exclusive_put(xilinx_pwm->priv.clk); - clk_disable_unprepare(xilinx_pwm->priv.clk); + pwmchip_remove(chip); + clk_rate_exclusive_put(priv->clk); + clk_disable_unprepare(priv->clk); } static const struct of_device_id xilinx_pwm_of_match[] = { diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index 1698609d91c8..3f434a771fb5 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -509,10 +509,10 @@ void pwmchip_sysfs_export(struct pwm_chip *chip) * If device_create() fails the pwm_chip is still usable by * the kernel it's just not exported. */ - parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, + parent = device_create(&pwm_class, pwmchip_parent(chip), MKDEV(0, 0), chip, "pwmchip%d", chip->id); if (IS_ERR(parent)) { - dev_warn(chip->dev, + dev_warn(pwmchip_parent(chip), "device_create failed for pwm_chip sysfs export\n"); } } |