diff options
Diffstat (limited to 'drivers/pwm/pwm-twl-led.c')
| -rw-r--r-- | drivers/pwm/pwm-twl-led.c | 106 |
1 files changed, 36 insertions, 70 deletions
diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c index 8fb84b441853..a555cc3be4b3 100644 --- a/drivers/pwm/pwm-twl-led.c +++ b/drivers/pwm/pwm-twl-led.c @@ -61,14 +61,9 @@ #define TWL6040_LED_MODE_OFF 0x02 #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,57 +95,48 @@ 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; } static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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); - goto out; + dev_err(pwmchip_parent(chip), "%s: Failed to read LEDEN\n", pwm->label); + return ret; } val |= TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); 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); return ret; } static void twl4030_pwmled_disable(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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); - goto out; + dev_err(pwmchip_parent(chip), "%s: Failed to read LEDEN\n", pwm->label); + return; } val &= ~TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); 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); - -out: - mutex_unlock(&twl->mutex); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); } static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -172,10 +158,10 @@ static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, * We cannot skip calling ->config even if state->period == * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle * because we might have exited early in the last call to - * pwm_apply_state because of !state->enabled and so the two values in + * pwm_apply_might_sleep because of !state->enabled and so the two values in * pwm->state might not be configured in hardware. */ - ret = twl4030_pwmled_config(pwm->chip, pwm, + ret = twl4030_pwmled_config(chip, pwm, state->duty_cycle, state->period); if (ret) return ret; @@ -189,7 +175,6 @@ static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, static const struct pwm_ops twl4030_pwmled_ops = { .apply = twl4030_pwmled_apply, - .owner = THIS_MODULE, }; static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, @@ -204,23 +189,21 @@ 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; } static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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; + return ret; } val &= ~TWL6040_LED_MODE_MASK; @@ -228,26 +211,22 @@ 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); return ret; } static void twl6030_pwmled_disable(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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; + return; } val &= ~TWL6040_LED_MODE_MASK; @@ -255,10 +234,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); - -out: - mutex_unlock(&twl->mutex); + dev_err(pwmchip_parent(chip), "%s: Failed to disable PWM\n", pwm->label); } static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -276,7 +252,7 @@ static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - err = twl6030_pwmled_config(pwm->chip, pwm, + err = twl6030_pwmled_config(chip, pwm, state->duty_cycle, state->period); if (err) return err; @@ -289,16 +265,14 @@ static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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; + return ret; } val &= ~TWL6040_LED_MODE_MASK; @@ -306,25 +280,21 @@ 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); return ret; } static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm) { - struct twl_pwmled_chip *twl = to_twl(chip); int ret; u8 val; - 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; + return; } val &= ~TWL6040_LED_MODE_MASK; @@ -332,40 +302,36 @@ 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); - -out: - mutex_unlock(&twl->mutex); + dev_err(pwmchip_parent(chip), "%s: Failed to free PWM\n", pwm->label); } static const struct pwm_ops twl6030_pwmled_ops = { .apply = twl6030_pwmled_apply, .request = twl6030_pwmled_request, .free = twl6030_pwmled_free, - .owner = THIS_MODULE, }; static int twl_pwmled_probe(struct platform_device *pdev) { - struct twl_pwmled_chip *twl; - - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; + struct pwm_chip *chip; + 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, 0); + if (IS_ERR(chip)) + return PTR_ERR(chip); - mutex_init(&twl->mutex); + chip->ops = ops; - return devm_pwmchip_add(&pdev->dev, &twl->chip); + return devm_pwmchip_add(&pdev->dev, chip); } #ifdef CONFIG_OF |
