pwm: Add sysfs interface

Add a simple sysfs interface to the generic PWM framework.

  /sys/class/pwm/
  `-- pwmchipN/           for each PWM chip
      |-- export          (w/o) ask the kernel to export a PWM channel
      |-- npwm            (r/o) number of PWM channels in this PWM chip
      |-- pwmX/           for each exported PWM channel
      |   |-- duty_cycle  (r/w) duty cycle (in nanoseconds)
      |   |-- enable      (r/w) enable/disable PWM
      |   |-- period      (r/w) period (in nanoseconds)
      |   `-- polarity    (r/w) polarity of PWM (normal/inversed)
      `-- unexport        (w/o) return a PWM channel to the kernel

Based on work by Lars Poeschel.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Lars Poeschel <poeschel@lemonage.de>
Cc: Ryan Mallon <rmallon@gmail.com>
Cc: Rob Landley <rob@landley.net>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 0cf0f65..dfbfbc5 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -274,6 +274,8 @@
 	if (IS_ENABLED(CONFIG_OF))
 		of_pwmchip_add(chip);
 
+	pwmchip_sysfs_export(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -310,6 +312,8 @@
 
 	free_pwms(chip);
 
+	pwmchip_sysfs_unexport(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -402,10 +406,19 @@
  */
 int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 {
+	int err;
+
 	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
 		return -EINVAL;
 
-	return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
+	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
+	if (err)
+		return err;
+
+	pwm->duty_cycle = duty_ns;
+	pwm->period = period_ns;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(pwm_config);
 
@@ -418,6 +431,8 @@
  */
 int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
 {
+	int err;
+
 	if (!pwm || !pwm->chip->ops)
 		return -EINVAL;
 
@@ -427,7 +442,13 @@
 	if (test_bit(PWMF_ENABLED, &pwm->flags))
 		return -EBUSY;
 
-	return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+	if (err)
+		return err;
+
+	pwm->polarity = polarity;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(pwm_set_polarity);