Merge tag 'mac80211-for-davem-2016-06-09' of git://git.kernel.org/pub/scm/linux/kerne...
[cascardo/linux.git] / drivers / pwm / sysfs.c
index 9c90886..d985992 100644 (file)
@@ -26,6 +26,7 @@
 struct pwm_export {
        struct device child;
        struct pwm_device *pwm;
+       struct mutex lock;
 };
 
 static struct pwm_export *child_to_pwm_export(struct device *child)
@@ -45,15 +46,20 @@ static ssize_t period_show(struct device *child,
                           char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_state state;
 
-       return sprintf(buf, "%u\n", pwm_get_period(pwm));
+       pwm_get_state(pwm, &state);
+
+       return sprintf(buf, "%u\n", state.period);
 }
 
 static ssize_t period_store(struct device *child,
                            struct device_attribute *attr,
                            const char *buf, size_t size)
 {
-       struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_export *export = child_to_pwm_export(child);
+       struct pwm_device *pwm = export->pwm;
+       struct pwm_state state;
        unsigned int val;
        int ret;
 
@@ -61,7 +67,11 @@ static ssize_t period_store(struct device *child,
        if (ret)
                return ret;
 
-       ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val);
+       mutex_lock(&export->lock);
+       pwm_get_state(pwm, &state);
+       state.period = val;
+       ret = pwm_apply_state(pwm, &state);
+       mutex_unlock(&export->lock);
 
        return ret ? : size;
 }
@@ -71,15 +81,20 @@ static ssize_t duty_cycle_show(struct device *child,
                               char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_state state;
+
+       pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm));
+       return sprintf(buf, "%u\n", state.duty_cycle);
 }
 
 static ssize_t duty_cycle_store(struct device *child,
                                struct device_attribute *attr,
                                const char *buf, size_t size)
 {
-       struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_export *export = child_to_pwm_export(child);
+       struct pwm_device *pwm = export->pwm;
+       struct pwm_state state;
        unsigned int val;
        int ret;
 
@@ -87,7 +102,11 @@ static ssize_t duty_cycle_store(struct device *child,
        if (ret)
                return ret;
 
-       ret = pwm_config(pwm, val, pwm_get_period(pwm));
+       mutex_lock(&export->lock);
+       pwm_get_state(pwm, &state);
+       state.duty_cycle = val;
+       ret = pwm_apply_state(pwm, &state);
+       mutex_unlock(&export->lock);
 
        return ret ? : size;
 }
@@ -97,33 +116,46 @@ static ssize_t enable_show(struct device *child,
                           char *buf)
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_state state;
+
+       pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%d\n", pwm_is_enabled(pwm));
+       return sprintf(buf, "%d\n", state.enabled);
 }
 
 static ssize_t enable_store(struct device *child,
                            struct device_attribute *attr,
                            const char *buf, size_t size)
 {
-       struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_export *export = child_to_pwm_export(child);
+       struct pwm_device *pwm = export->pwm;
+       struct pwm_state state;
        int val, ret;
 
        ret = kstrtoint(buf, 0, &val);
        if (ret)
                return ret;
 
+       mutex_lock(&export->lock);
+
+       pwm_get_state(pwm, &state);
+
        switch (val) {
        case 0:
-               pwm_disable(pwm);
+               state.enabled = false;
                break;
        case 1:
-               ret = pwm_enable(pwm);
+               state.enabled = true;
                break;
        default:
                ret = -EINVAL;
-               break;
+               goto unlock;
        }
 
+       pwm_apply_state(pwm, &state);
+
+unlock:
+       mutex_unlock(&export->lock);
        return ret ? : size;
 }
 
@@ -133,8 +165,11 @@ static ssize_t polarity_show(struct device *child,
 {
        const struct pwm_device *pwm = child_to_pwm_device(child);
        const char *polarity = "unknown";
+       struct pwm_state state;
+
+       pwm_get_state(pwm, &state);
 
-       switch (pwm_get_polarity(pwm)) {
+       switch (state.polarity) {
        case PWM_POLARITY_NORMAL:
                polarity = "normal";
                break;
@@ -151,8 +186,10 @@ static ssize_t polarity_store(struct device *child,
                              struct device_attribute *attr,
                              const char *buf, size_t size)
 {
-       struct pwm_device *pwm = child_to_pwm_device(child);
+       struct pwm_export *export = child_to_pwm_export(child);
+       struct pwm_device *pwm = export->pwm;
        enum pwm_polarity polarity;
+       struct pwm_state state;
        int ret;
 
        if (sysfs_streq(buf, "normal"))
@@ -162,7 +199,11 @@ static ssize_t polarity_store(struct device *child,
        else
                return -EINVAL;
 
-       ret = pwm_set_polarity(pwm, polarity);
+       mutex_lock(&export->lock);
+       pwm_get_state(pwm, &state);
+       state.polarity = polarity;
+       ret = pwm_apply_state(pwm, &state);
+       mutex_unlock(&export->lock);
 
        return ret ? : size;
 }
@@ -203,6 +244,7 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
        }
 
        export->pwm = pwm;
+       mutex_init(&export->lock);
 
        export->child.release = pwm_export_release;
        export->child.parent = parent;