pwm->pwm = chip->base + i;
pwm->hwpwm = i;
pwm->polarity = polarity;
+ mutex_init(&pwm->lock);
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
if (!pwm->chip->ops->set_polarity)
return -ENOSYS;
- if (pwm_is_enabled(pwm))
- return -EBUSY;
+ mutex_lock(&pwm->lock);
+
+ if (pwm_is_enabled(pwm)) {
+ err = -EBUSY;
+ goto unlock;
+ }
err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
if (err)
- return err;
+ goto unlock;
pwm->polarity = polarity;
- return 0;
+unlock:
+ mutex_unlock(&pwm->lock);
+ return err;
}
EXPORT_SYMBOL_GPL(pwm_set_polarity);
*/
int pwm_enable(struct pwm_device *pwm)
{
- if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
- return pwm->chip->ops->enable(pwm->chip, pwm);
+ int err = 0;
+
+ if (!pwm)
+ return -EINVAL;
+
+ mutex_lock(&pwm->lock);
+
+ if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+ err = pwm->chip->ops->enable(pwm->chip, pwm);
+ if (err)
+ clear_bit(PWMF_ENABLED, &pwm->flags);
+ }
+
+ mutex_unlock(&pwm->lock);
- return pwm ? 0 : -EINVAL;
+ return err;
}
EXPORT_SYMBOL_GPL(pwm_enable);
#define __LINUX_PWM_H
#include <linux/err.h>
+#include <linux/mutex.h>
#include <linux/of.h>
struct pwm_device;
* @pwm: global index of the PWM device
* @chip: PWM chip providing this PWM device
* @chip_data: chip-private data associated with the PWM device
+ * @lock: used to serialize accesses to the PWM device where necessary
* @period: period of the PWM signal (in nanoseconds)
* @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
* @polarity: polarity of the PWM signal
unsigned int pwm;
struct pwm_chip *chip;
void *chip_data;
+ struct mutex lock;
unsigned int period;
unsigned int duty_cycle;