diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-13 20:51:39 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-13 20:51:39 +0300 |
commit | aeb152910a7aecabde5c5f0477a08b397e94059c (patch) | |
tree | 9509c6f14816048c1ae8f7d4b9ec8ee825c0d2f6 /drivers/staging | |
parent | aa7d6513d68bad539142f9d6c3e2faa629bc27d8 (diff) | |
parent | dd6c6d57ab61d496f6ff7d6ca38611062af142a1 (diff) | |
download | linux-aeb152910a7aecabde5c5f0477a08b397e94059c.tar.xz |
Merge tag 'pwm/for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux
Pull pwm updates from Uwe Kleine-König:
"This contains the usual amount of driver and device tree changes.
Additionally there is a big rework of how pwm lowlevel drivers are
registered to prepare adding character device support.
Thanks to Dharma Balasubiramani, Dong Aisheng, Duje Mihanović, Jerome
Brunet, Raag Jadav and Rafał Miłecki for their contributions. And
sorry for those who still need some patience because I didn't manage
to empty my review queue"
* tag 'pwm/for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: (185 commits)
pwm: imx-tpm: fix probe crash due to access registers without clock
pwm: meson: generalize 4 inputs clock on meson8 pwm type
dt-bindings: pwm: amlogic: Add a new binding for meson8 pwm types
dt-bindings: pwm: amlogic: fix s4 bindings
pwm: dwc: simplify error handling
pwm: dwc: Add 16 channel support for Intel Elkhart Lake
pwm: dwc: drop redundant error check
staging: greybus: pwm: Make use of devm_pwmchip_alloc() function
staging: greybus: pwm: Rework how the number of PWM lines is determined
staging: greybus: pwm: Drop unused gb_connection_set_data()
staging: greybus: pwm: Rely on pwm framework to pass a valid hwpwm
staging: greybus: pwm: Make use of pwmchip_parent() accessor
staging: greybus: pwm: Change prototype of helpers to prepare further changes
leds: qcom-lpg: Make use of devm_pwmchip_alloc() function
drm/bridge: ti-sn65dsi86: Make use of devm_pwmchip_alloc() function
drm/bridge: ti-sn65dsi86: Make use of pwmchip_parent() accessor
gpio: mvebu: Make use of devm_pwmchip_alloc() function
pwm: xilinx: Make use of devm_pwmchip_alloc() function
pwm: xilinx: Prepare removing pwm_chip from driver data
pwm: vt8500: Make use of devm_pwmchip_alloc() function
...
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/greybus/pwm.c | 133 |
1 files changed, 56 insertions, 77 deletions
diff --git a/drivers/staging/greybus/pwm.c b/drivers/staging/greybus/pwm.c index a3cb68cfa0f9..01883fbcd79b 100644 --- a/drivers/staging/greybus/pwm.c +++ b/drivers/staging/greybus/pwm.c @@ -16,8 +16,6 @@ struct gb_pwm_chip { struct gb_connection *connection; - u8 pwm_max; /* max pwm number */ - struct pwm_chip chip; }; @@ -26,32 +24,33 @@ static inline struct gb_pwm_chip *pwm_chip_to_gb_pwm_chip(struct pwm_chip *chip) return container_of(chip, struct gb_pwm_chip, chip); } -static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc) +static int gb_pwm_get_npwm(struct gb_connection *connection) { struct gb_pwm_count_response response; int ret; - ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_PWM_COUNT, + ret = gb_operation_sync(connection, GB_PWM_TYPE_PWM_COUNT, NULL, 0, &response, sizeof(response)); if (ret) return ret; - pwmc->pwm_max = response.count; - return 0; + + /* + * The request returns the highest allowed PWM id parameter. So add one + * to get the number of PWMs. + */ + return response.count + 1; } -static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc, - u8 which) +static int gb_pwm_activate_operation(struct pwm_chip *chip, u8 which) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_activate_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); ret = gbphy_runtime_get_sync(gbphy_dev); if (ret) return ret; @@ -64,19 +63,16 @@ static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc, return ret; } -static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc, - u8 which) +static int gb_pwm_deactivate_operation(struct pwm_chip *chip, u8 which) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_deactivate_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); ret = gbphy_runtime_get_sync(gbphy_dev); if (ret) return ret; @@ -89,21 +85,19 @@ static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc, return ret; } -static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc, +static int gb_pwm_config_operation(struct pwm_chip *chip, u8 which, u32 duty, u32 period) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_config_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; request.duty = cpu_to_le32(duty); request.period = cpu_to_le32(period); - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); ret = gbphy_runtime_get_sync(gbphy_dev); if (ret) return ret; @@ -116,20 +110,18 @@ static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc, return ret; } -static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc, +static int gb_pwm_set_polarity_operation(struct pwm_chip *chip, u8 which, u8 polarity) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_polarity_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; request.polarity = polarity; - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); ret = gbphy_runtime_get_sync(gbphy_dev); if (ret) return ret; @@ -142,19 +134,16 @@ static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc, return ret; } -static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc, - u8 which) +static int gb_pwm_enable_operation(struct pwm_chip *chip, u8 which) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_enable_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); ret = gbphy_runtime_get_sync(gbphy_dev); if (ret) return ret; @@ -167,22 +156,19 @@ static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc, return ret; } -static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc, - u8 which) +static int gb_pwm_disable_operation(struct pwm_chip *chip, u8 which) { + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_disable_request request; struct gbphy_device *gbphy_dev; int ret; - if (which > pwmc->pwm_max) - return -EINVAL; - request.which = which; ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DISABLE, &request, sizeof(request), NULL, 0); - gbphy_dev = to_gbphy_dev(pwmc->chip.dev); + gbphy_dev = to_gbphy_dev(pwmchip_parent(chip)); gbphy_runtime_put_autosuspend(gbphy_dev); return ret; @@ -190,19 +176,15 @@ static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc, static int gb_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) { - struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); - - return gb_pwm_activate_operation(pwmc, pwm->hwpwm); + return gb_pwm_activate_operation(chip, pwm->hwpwm); }; static void gb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { - struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); - if (pwm_is_enabled(pwm)) - dev_warn(chip->dev, "freeing PWM device without disabling\n"); + dev_warn(pwmchip_parent(chip), "freeing PWM device without disabling\n"); - gb_pwm_deactivate_operation(pwmc, pwm->hwpwm); + gb_pwm_deactivate_operation(chip, pwm->hwpwm); } static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -212,22 +194,21 @@ static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, bool enabled = pwm->state.enabled; u64 period = state->period; u64 duty_cycle = state->duty_cycle; - struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); /* Set polarity */ if (state->polarity != pwm->state.polarity) { if (enabled) { - gb_pwm_disable_operation(pwmc, pwm->hwpwm); + gb_pwm_disable_operation(chip, pwm->hwpwm); enabled = false; } - err = gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, state->polarity); + err = gb_pwm_set_polarity_operation(chip, pwm->hwpwm, state->polarity); if (err) return err; } if (!state->enabled) { if (enabled) - gb_pwm_disable_operation(pwmc, pwm->hwpwm); + gb_pwm_disable_operation(chip, pwm->hwpwm); return 0; } @@ -243,13 +224,13 @@ static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (duty_cycle > period) duty_cycle = period; - err = gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_cycle, period); + err = gb_pwm_config_operation(chip, pwm->hwpwm, duty_cycle, period); if (err) return err; /* enable/disable */ if (!enabled) - return gb_pwm_enable_operation(pwmc, pwm->hwpwm); + return gb_pwm_enable_operation(chip, pwm->hwpwm); return 0; } @@ -266,61 +247,59 @@ static int gb_pwm_probe(struct gbphy_device *gbphy_dev, struct gb_connection *connection; struct gb_pwm_chip *pwmc; struct pwm_chip *chip; - int ret; - - pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL); - if (!pwmc) - return -ENOMEM; + int ret, npwm; connection = gb_connection_create(gbphy_dev->bundle, le16_to_cpu(gbphy_dev->cport_desc->id), NULL); - if (IS_ERR(connection)) { - ret = PTR_ERR(connection); - goto exit_pwmc_free; - } - - pwmc->connection = connection; - gb_connection_set_data(connection, pwmc); - gb_gbphy_set_data(gbphy_dev, pwmc); + if (IS_ERR(connection)) + return PTR_ERR(connection); ret = gb_connection_enable(connection); if (ret) goto exit_connection_destroy; /* Query number of pwms present */ - ret = gb_pwm_count_operation(pwmc); - if (ret) + ret = gb_pwm_get_npwm(connection); + if (ret < 0) + goto exit_connection_disable; + npwm = ret; + + chip = pwmchip_alloc(&gbphy_dev->dev, npwm, sizeof(*pwmc)); + if (IS_ERR(chip)) { + ret = PTR_ERR(chip); goto exit_connection_disable; + } + gb_gbphy_set_data(gbphy_dev, chip); - chip = &pwmc->chip; + pwmc = pwm_chip_to_gb_pwm_chip(chip); + pwmc->connection = connection; - chip->dev = &gbphy_dev->dev; chip->ops = &gb_pwm_ops; - chip->npwm = pwmc->pwm_max + 1; ret = pwmchip_add(chip); if (ret) { dev_err(&gbphy_dev->dev, "failed to register PWM: %d\n", ret); - goto exit_connection_disable; + goto exit_pwmchip_put; } gbphy_runtime_put_autosuspend(gbphy_dev); return 0; +exit_pwmchip_put: + pwmchip_put(chip); exit_connection_disable: gb_connection_disable(connection); exit_connection_destroy: gb_connection_destroy(connection); -exit_pwmc_free: - kfree(pwmc); return ret; } static void gb_pwm_remove(struct gbphy_device *gbphy_dev) { - struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev); + struct pwm_chip *chip = gb_gbphy_get_data(gbphy_dev); + struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_connection *connection = pwmc->connection; int ret; @@ -328,10 +307,10 @@ static void gb_pwm_remove(struct gbphy_device *gbphy_dev) if (ret) gbphy_runtime_get_noresume(gbphy_dev); - pwmchip_remove(&pwmc->chip); + pwmchip_remove(chip); + pwmchip_put(chip); gb_connection_disable(connection); gb_connection_destroy(connection); - kfree(pwmc); } static const struct gbphy_device_id gb_pwm_id_table[] = { |