diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
index 8aba488..464a663 100644
--- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt
+++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
@@ -22,6 +22,9 @@ Sub-nodes:
   Each led node should contain "reg", which used as LED ID (described below).
   Optional properties "label" and "linux,default-trigger" is described in
   Documentation/devicetree/bindings/leds/common.txt.
+- pwm: For MC34708, contain the PWM controller:
+  - compatible: must be "fsl,mc34708-pwm".
+  - #pwm-cells: must be 2.
 - regulators : Contain the regulator nodes. The regulators are bound using
   their names as listed below with their registers and bits for enabling.
 
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index acf5dd7..71b7d84c 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -599,6 +599,20 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
 	if (!cell.name)
 		return -ENOMEM;
 
+	/* mfd_add_devices won't adds a .of_node to the child's dev if the
+	 * cell's .off_compatible is NULL, which result in
+	 * of_node_to_pwmchip beeing unable to find the pwm device.
+	 */
+	if (!strncmp(format, "%s-pwm", sizeof("%s-pwm"))) {
+		if (snprintf(buf, sizeof(buf),
+			     "fsl,%s", cell.name) > sizeof(buf))
+			return -E2BIG;
+
+		cell.of_compatible = kmemdup(buf, strlen(buf) + 1, GFP_KERNEL);
+		if (!cell.of_compatible)
+			return -ENOMEM;
+	}
+
 	return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL);
 }
 
@@ -681,6 +695,7 @@ int mc13xxx_common_init(struct device *dev)
 			&pdata->regulators, sizeof(pdata->regulators));
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
 				pdata->leds, sizeof(*pdata->leds));
+		mc13xxx_add_subdevice(mc13xxx, "%s-pwm");
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
 				pdata->buttons, sizeof(*pdata->buttons));
 		if (mc13xxx->flags & MC13XXX_USE_CODEC)
@@ -692,6 +707,7 @@ int mc13xxx_common_init(struct device *dev)
 	} else {
 		mc13xxx_add_subdevice(mc13xxx, "%s-regulator");
 		mc13xxx_add_subdevice(mc13xxx, "%s-led");
+		mc13xxx_add_subdevice(mc13xxx, "%s-pwm");
 		mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton");
 		if (mc13xxx->flags & MC13XXX_USE_CODEC)
 			mc13xxx_add_subdevice(mc13xxx, "%s-codec");
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 4ad7b89..a7ca3eb 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -157,6 +157,12 @@ config PWM_LPSS
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-lpss.
 
+config PWM_MC34708
+	tristate "MC34708 PWM support"
+	depends on MFD_MC13XXX
+	help
+	  Generic PWM framework driver for Freescale MC34708 PMIC.
+
 config PWM_MXS
 	tristate "Freescale MXS PWM support"
 	depends on ARCH_MXS && OF
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 5c86a19..0fe5ec5 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_LP3943)	+= pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_LPSS)		+= pwm-lpss.o
+obj-$(CONFIG_PWM_MC34708)	+= pwm-mc34708.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
diff --git a/drivers/pwm/pwm-mc34708.c b/drivers/pwm/pwm-mc34708.c
new file mode 100644
index 0000000..840f4dc
--- /dev/null
+++ b/drivers/pwm/pwm-mc34708.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2014 Eukréa Electromatique <denis@eukrea.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/mc13783.h>
+
+/* PWM register address */
+#define MC134708_PWM		0x37
+
+/* PWM register fields:
+ * Bit #    RegisterName Description
+ *  [0->5]  PWM1DUTY:   PWM1 duty cycle
+ *  [6->11] PWM1CLKDIV: PWM1 duty cycle
+ * [12->17] PWM2DUTY:   PWM2 clock divide setting
+ * [18->23] PWM2CLKDIV: PWM2 clock divide setting
+ */
+#define MC134708_PWM_MASK			0x3f
+#define MC134708_PWM_NUM_OFFSET			0x0c
+
+#define MC134708_PWM_DUTY_OFFSET(pwm_id)	(pwm_id * MC134708_PWM_NUM_OFFSET)
+#define MC134708_PWM_PERIOD_OFFSET(pwm_id)	((pwm_id * MC134708_PWM_NUM_OFFSET) + 0x06)
+
+/* MC34708 PWM Constraints */
+#define MC13708_BASE_CLK_FREQ	2000000
+#define MC13708_PWM_MAX_DUTY	32
+#define MC13708_PWM_MAX_CLKDIV	64
+
+#define MC13708_MIN_PWM_PERIOD	(NSEC_PER_SEC / MC13708_BASE_CLK_FREQ)
+#define MC13708_MAX_PWM_PERIOD	(MC13708_MIN_PWM_PERIOD * MC13708_PWM_MAX_CLKDIV)
+
+#define MC134708_PWMS_NUM	2
+
+struct mc34708_pwm_regs {
+	int enabled;
+	int pwm_duty;
+};
+
+struct mc34708_pwm_chip {
+	struct pwm_chip pwm_chip;
+	struct mc13xxx *mc13xxx;
+	struct mc34708_pwm_regs *pwms[MC134708_PWMS_NUM];
+};
+
+static inline
+struct mc34708_pwm_chip *to_mc34708_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct mc34708_pwm_chip, pwm_chip);
+}
+
+static int
+pwm_mc34708_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct mc34708_pwm_chip *mc34708_chip = to_mc34708_chip(chip);
+	struct mc34708_pwm_regs *pwmr = mc34708_chip->pwms[pwm->hwpwm];
+	struct mc13xxx *mc13xxx = mc34708_chip->mc13xxx;
+
+	int duty_offset = MC134708_PWM_DUTY_OFFSET(pwm->hwpwm);
+	int period_offset = MC134708_PWM_PERIOD_OFFSET(pwm->hwpwm);
+
+	int pwm_clkdiv, pwm_duty, ret = 0;
+
+	/* Period */
+	period_ns = clamp(period_ns, (int)MC13708_MIN_PWM_PERIOD,
+			  (int)MC13708_MAX_PWM_PERIOD);
+	pwm_clkdiv = DIV_ROUND_UP(NSEC_PER_SEC, period_ns); /* Frequency (Hz) */
+	pwm_clkdiv = DIV_ROUND_UP(MC13708_BASE_CLK_FREQ,
+				  pwm_clkdiv) - 1; /* Clock divisor */
+
+	/* Duty cycle */
+	pwm_duty = DIV_ROUND_UP(MC13708_PWM_MAX_DUTY * duty_ns, period_ns);
+
+	/* Actual write to the registers */
+	mc13xxx_lock(mc13xxx);
+
+	ret = mc13xxx_reg_rmw(mc13xxx, MC134708_PWM,
+					MC134708_PWM_MASK << period_offset,
+					pwm_clkdiv << period_offset);
+	if (ret) {
+		mc13xxx_unlock(mc13xxx);
+		return ret;
+	}
+
+	/* The MC34708 doesn't have an enable bit for its PWM unit,
+	 * so we cache the pwm duty value for the .enable()
+	 */
+	pwmr->pwm_duty = pwm_duty;
+
+	if (pwmr->enabled) {
+		ret = mc13xxx_reg_rmw(mc13xxx, MC134708_PWM,
+				MC134708_PWM_MASK << duty_offset,
+				pwm_duty << duty_offset);
+	}
+	mc13xxx_unlock(mc13xxx);
+
+	return ret;
+}
+
+static int pwm_mc34708_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct mc34708_pwm_chip *mc34708_chip = to_mc34708_chip(chip);
+	struct mc34708_pwm_regs *pwmr = mc34708_chip->pwms[pwm->hwpwm];
+	struct mc13xxx *mc13xxx = mc34708_chip->mc13xxx;
+	int duty_offset = MC134708_PWM_DUTY_OFFSET(pwm->hwpwm);
+	int ret;
+
+	mc13xxx_lock(mc13xxx);
+
+	ret = mc13xxx_reg_rmw(mc13xxx, MC134708_PWM,
+			MC134708_PWM_MASK << duty_offset,
+			pwmr->pwm_duty << duty_offset);
+	pwmr->enabled = 1;
+
+	mc13xxx_unlock(mc13xxx);
+
+	return ret;
+}
+
+static void pwm_mc34708_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct mc34708_pwm_chip *mc34708_chip = to_mc34708_chip(chip);
+	struct mc34708_pwm_regs *pwmr = mc34708_chip->pwms[pwm->hwpwm];
+	struct mc13xxx *mc13xxx = mc34708_chip->mc13xxx;
+	int duty_offset = MC134708_PWM_DUTY_OFFSET(pwm->hwpwm);
+
+	mc13xxx_lock(mc13xxx);
+
+	/* To disable the PWM, the duty cycle bits have to be cleared */
+	mc13xxx_reg_rmw(mc13xxx, MC134708_PWM,
+			MC134708_PWM_MASK << duty_offset,
+			0 << duty_offset);
+	pwmr->enabled = 0;
+
+	mc13xxx_unlock(mc13xxx);
+}
+
+static const struct pwm_ops pwm_mc34708_ops = {
+	.enable		= pwm_mc34708_enable,
+	.disable	= pwm_mc34708_disable,
+	.config		= pwm_mc34708_config,
+	.owner		= THIS_MODULE,
+};
+
+static int pwm_mc34708_probe(struct platform_device *pdev)
+{
+	struct mc34708_pwm_chip *chip;
+	struct mc13xxx *mc13xxx;
+	int err, i;
+
+	mc13xxx = dev_get_drvdata(pdev->dev.parent);
+
+	if (!mc13xxx)
+		return -EINVAL;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+			return -ENOMEM;
+
+	for (i = 0; i < MC134708_PWMS_NUM; i++) {
+		chip->pwms[i] = devm_kzalloc(&pdev->dev,
+			sizeof(struct mc34708_pwm_regs), GFP_KERNEL);
+	}
+
+	chip->mc13xxx = mc13xxx;
+	chip->pwm_chip.dev = &pdev->dev;
+	chip->pwm_chip.ops = &pwm_mc34708_ops;
+	chip->pwm_chip.base = -1;
+	chip->pwm_chip.npwm = MC134708_PWMS_NUM;
+
+	err = pwmchip_add(&chip->pwm_chip);
+	if (err < 0)
+		return err;
+
+	platform_set_drvdata(pdev, chip);
+
+	return 0;
+}
+
+static int pwm_mc34708_remove(struct platform_device *pdev)
+{
+	struct mc34708_pwm_chip *chip = platform_get_drvdata(pdev);
+
+	return pwmchip_remove(&chip->pwm_chip);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id pwm_mc34708_of_match[] = {
+	{ .compatible = "fsl,mc34708-pwm" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pwm_mc34708_of_match);
+#endif
+
+static struct platform_driver pwm_mc34708_driver = {
+	.driver	= {
+		.name = "mc34708-pwm",
+		.of_match_table = of_match_ptr(pwm_mc34708_of_match),
+	},
+	.probe = pwm_mc34708_probe,
+	.remove = pwm_mc34708_remove,
+};
+module_platform_driver(pwm_mc34708_driver);
+
+MODULE_ALIAS("platform:mc34708-pwm");
+MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>");
+MODULE_DESCRIPTION("mc34708 Pulse Width Modulation Driver");
+MODULE_LICENSE("GPL");
