diff --git a/cpu/kinetis_common/periph/pwm.c b/cpu/kinetis_common/periph/pwm.c
index f6166a1963bebce83488c2842ea4fef2f10eb6a5..6d1d98b3d53f38ec5e212ac09c8c70037eaffb26 100644
--- a/cpu/kinetis_common/periph/pwm.c
+++ b/cpu/kinetis_common/periph/pwm.c
@@ -35,6 +35,22 @@ static inline FTM_Type *ftm(pwm_t pwm)
     return pwm_config[pwm].ftm;
 }
 
+static void poweron(pwm_t pwm)
+{
+    int ftm = pwm_config[pwm].ftm_num;
+
+#ifdef SIM_SCGC6_FTM2_SHIFT
+    BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 1;
+#else
+    if (ftm < 2) {
+        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 1;
+    }
+    else if (ftm == 2) {
+        BITBAND_REG32(SIM->SCGC3, SIM_SCGC3_FTM2_SHIFT) = 1;
+    }
+#endif
+}
+
 uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
 {
     uint8_t pre = 0;
@@ -60,7 +76,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
     }
 
     /* configure the used timer */
-    pwm_poweron(pwm);
+    poweron(pwm);
     /* disable write protect for changing settings */
     ftm(pwm)->MODE = FTM_MODE_WPDIS_MASK;
     /* clear any existing configuration */
@@ -88,7 +104,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
     }
 
     /* and now we start the actual waveform generation */
-    pwm_start(pwm);
+    ftm(pwm)->SC |= FTM_SC_CLKS(1);
 
     /* finally we need to return the actual applied PWM frequency */
     return (CLOCK_BUSCLOCK >> pre) / res;
@@ -106,47 +122,29 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
     ftm(pwm)->CONTROLS[pwm_config[pwm].chan[channel].ftm_chan].CnV = value;
 }
 
-void pwm_start(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    ftm(pwm)->SC |= FTM_SC_CLKS(1);
-}
-
-void pwm_stop(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    ftm(pwm)->SC &= ~(FTM_SC_CLKS_MASK);
-}
-
 void pwm_poweron(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
-    int ftm = pwm_config[pwm].ftm_num;
-
-#ifdef SIM_SCGC6_FTM2_SHIFT
-    BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 1;
-#else
-    if (ftm < 2) {
-        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 1;
-    }
-    else if (ftm == 2) {
-        BITBAND_REG32(SIM->SCGC3, SIM_SCGC3_FTM2_SHIFT) = 1;
-    }
-#endif
+    poweron(pwm);
+    ftm(pwm)->SC |= FTM_SC_CLKS(1);
 }
 
 void pwm_poweroff(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
-    int ftm = pwm_config[pwm].ftm_num;
+    int ftm_num = pwm_config[pwm].ftm_num;
+
+    /* disable PWM generation */
+    ftm(pwm)->SC &= ~(FTM_SC_CLKS_MASK);
 
+    /* and power of the peripheral */
 #ifdef SIM_SCGC6_FTM2_SHIFT
-    BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 0;
+    BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm_num) = 0;
 #else
-    if (ftm < 2) {
-        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm) = 0;
+    if (ftm_num < 2) {
+        BITBAND_REG32(SIM->SCGC6, SIM_SCGC6_FTM0_SHIFT + ftm_num) = 0;
     }
-    else if (ftm == 2) {
+    else if (ftm_num == 2) {
         BITBAND_REG32(SIM->SCGC3, SIM_SCGC3_FTM2_SHIFT) = 0;
     }
 #endif
diff --git a/cpu/lpc11u34/periph/pwm.c b/cpu/lpc11u34/periph/pwm.c
index b405ffe64b068c749c9c8fcbb97954b2f104182e..decb039544ac5443eb1b706a161bc794e93d441a 100644
--- a/cpu/lpc11u34/periph/pwm.c
+++ b/cpu/lpc11u34/periph/pwm.c
@@ -50,7 +50,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
     }
 
     /* power on and configure the timer */
-    pwm_poweron(pwm);
+    LPC_SYSCON->SYSAHBCLKCTRL |= pwm_config[pwm].clk_bit;
     /* enable the timer and keep it in reset state */
     dev(pwm)->TCR = BIT0 | BIT1;
     /* set prescaler */
@@ -85,27 +85,17 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
     dev(pwm)->MR[channel] = dev(pwm)->MR3 - value;
 }
 
-void pwm_start(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    dev(pwm)->TCR &= ~(BIT1);
-}
-
-void pwm_stop(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    dev(pwm)->TCR |= (BIT1);
-}
-
 void pwm_poweron(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
     LPC_SYSCON->SYSAHBCLKCTRL |= pwm_config[pwm].clk_bit;
+    dev(pwm)->TCR &= ~(BIT1);
 }
 
 void pwm_poweroff(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
+    dev(pwm)->TCR |= (BIT1);
     LPC_SYSCON->SYSAHBCLKCTRL &= ~(pwm_config[pwm].clk_bit);
 }
 
diff --git a/cpu/lpc2387/periph/pwm.c b/cpu/lpc2387/periph/pwm.c
index c3146aee3a6de117f8794f35e9e0cdbfa1c17f75..4cd027bde306cf0df61013675f31b763a035f3c8 100644
--- a/cpu/lpc2387/periph/pwm.c
+++ b/cpu/lpc2387/periph/pwm.c
@@ -49,7 +49,7 @@ uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
                 (PWM_FUNC << PWM_CH2_PIN * 2);
 
     /* power on PWM1 */
-    pwm_poweron(dev);
+    PCONP |= PCPWM1;
 
     /* select PWM1 clock */
     PCLKSEL0 &= ~(BIT13);
@@ -108,27 +108,17 @@ void pwm_set(pwm_t dev, uint8_t channel, uint16_t value)
     }
 }
 
-void pwm_start(pwm_t dev)
-{
-    assert(dev == PWM_DEV(0));
-    PWM1TCR |= BIT0;
-}
-
-void pwm_stop(pwm_t dev)
-{
-    assert(dev == PWM_DEV(0));
-    PWM1TCR &= ~(BIT0);
-}
-
 void pwm_poweron(pwm_t dev)
 {
     assert(dev == PWM_DEV(0));
     PCONP |= PCPWM1;
+    PWM1TCR |= BIT0;
 }
 
 void pwm_poweroff(pwm_t dev)
 {
     assert(dev == PWM_DEV(0));
+    PWM1TCR &= ~(BIT0);
     PCONP &= ~(PCPWM1);
 }
 
diff --git a/cpu/sam3/periph/pwm.c b/cpu/sam3/periph/pwm.c
index af694c4174a62e410f928891a9b8723b65bb6e7b..fe84c92af9b2f754a9caaa2a3599d7d86ac77ae3 100644
--- a/cpu/sam3/periph/pwm.c
+++ b/cpu/sam3/periph/pwm.c
@@ -114,34 +114,17 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
     PWM->PWM_CH_NUM[pwm_chan[channel].hwchan].PWM_CDTYUPD = value;
 }
 
-void pwm_start(pwm_t pwm)
-{
-    assert(pwm == PWM_DEV(0));
-    PWM->PWM_ENA = pwm_chan_mask;
-}
-
-void pwm_stop(pwm_t pwm)
-{
-    assert(pwm == PWM_DEV(0));
-    PWM->PWM_ENA = 0;
-}
-
-/*
- * The device is reactivated by by clocking the device block.
- * Operation continues where it has been stopped by poweroff.
- */
 void pwm_poweron(pwm_t pwm)
 {
     assert(pwm == PWM_DEV(0));
     PMC->PMC_PCER1 = PMC_PCDR1_PID36;
+    PWM->PWM_ENA = pwm_chan_mask;
 }
 
-/*
- * The device is set to power saving mode by disabling the clock.
- */
 void pwm_poweroff(pwm_t pwm)
 {
     assert(pwm == PWM_DEV(0));
+    PWM->PWM_ENA = 0;
     PMC->PMC_PCDR1 = PMC_PCDR1_PID36;
 }
 
diff --git a/cpu/samd21/periph/pwm.c b/cpu/samd21/periph/pwm.c
index 2c96f23dfc8b4d20f4a3eb8351e72d55168e47ac..6b073412bb83fa7e3bf1157529fe73ac2735965f 100644
--- a/cpu/samd21/periph/pwm.c
+++ b/cpu/samd21/periph/pwm.c
@@ -87,6 +87,15 @@ static uint8_t get_prescaler(unsigned int target, int *scale)
     return target - 1;
 }
 
+static void poweron(pwm_t dev)
+{
+    PM->APBCMASK.reg |= (PM_APBCMASK_TCC0 << _num(dev));
+    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
+                         GCLK_CLKCTRL_GEN_GCLK0 |
+                         GCLK_CLKCTRL_ID(_clk_id(dev)));
+    while (GCLK->STATUS.bit.SYNCBUSY) {}
+}
+
 uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
 {
     uint8_t prescaler;
@@ -113,7 +122,7 @@ uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
     }
 
     /* power on the device */
-    pwm_poweron(dev);
+    poweron(dev);
 
     /* reset TCC module */
     _tcc(dev)->CTRLA.reg = TCC_CTRLA_SWRST;
@@ -142,7 +151,7 @@ uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
     _tcc(dev)->PER.reg = (res - 1);
     while (_tcc(dev)->SYNCBUSY.reg & TCC_SYNCBUSY_PER) {}
     /* start PWM operation */
-    pwm_start(dev);
+    _tcc(dev)->CTRLA.reg |= (TCC_CTRLA_ENABLE);
     /* return the actual frequency the PWM is running at */
     return f_real;
 }
@@ -162,36 +171,17 @@ void pwm_set(pwm_t dev, uint8_t channel, uint16_t value)
     while (_tcc(dev)->SYNCBUSY.reg & (TCC_SYNCBUSY_CC0 << _chan(dev, channel))) {}
 }
 
-void pwm_start(pwm_t dev)
+void pwm_poweron(pwm_t dev)
 {
+    poweron(dev);
     _tcc(dev)->CTRLA.reg |= (TCC_CTRLA_ENABLE);
 }
 
-void pwm_stop(pwm_t dev)
+void pwm_poweroff(pwm_t dev)
 {
     _tcc(dev)->CTRLA.reg &= ~(TCC_CTRLA_ENABLE);
-}
 
-void pwm_poweron(pwm_t dev)
-{
-    int num = _num(dev);
-    if (num < 0) {
-        return;
-    }
-    PM->APBCMASK.reg |= (PM_APBCMASK_TCC0 << num);
-    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
-                         GCLK_CLKCTRL_GEN_GCLK0 |
-                         GCLK_CLKCTRL_ID(_clk_id(dev)));
-    while (GCLK->STATUS.bit.SYNCBUSY) {}
-}
-
-void pwm_poweroff(pwm_t dev)
-{
-    int num = _num(dev);
-    if (num < 0) {
-        return;
-    }
-    PM->APBCMASK.reg &= ~(PM_APBCMASK_TCC0 << num);
+    PM->APBCMASK.reg &= ~(PM_APBCMASK_TCC0 << _num(dev));
     GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN_GCLK7 |
                          GCLK_CLKCTRL_ID(_clk_id(dev)));
     while (GCLK->STATUS.bit.SYNCBUSY) {}
diff --git a/cpu/stm32_common/periph/pwm.c b/cpu/stm32_common/periph/pwm.c
index 511ecf71ff96de34833193058a7fdad226804b4d..15892d9819b8812f3ca6ad993ca09b76235080be 100644
--- a/cpu/stm32_common/periph/pwm.c
+++ b/cpu/stm32_common/periph/pwm.c
@@ -49,7 +49,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
     assert((pwm < PWM_NUMOF) && ((freq * res) < bus_clk));
 
     /* power on the used timer */
-    pwm_poweron(pwm);
+    periph_clk_en(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask);
     /* reset configuration and CC channels */
     dev(pwm)->CR1 = 0;
     dev(pwm)->CR2 = 0;
@@ -124,27 +124,17 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
     dev(pwm)->CCR[pwm_config[pwm].chan[channel].cc_chan] = value;
 }
 
-void pwm_start(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    dev(pwm)->CR1 |= TIM_CR1_CEN;
-}
-
-void pwm_stop(pwm_t pwm)
-{
-    assert(pwm < PWM_NUMOF);
-    dev(pwm)->CR1 &= ~TIM_CR1_CEN;
-}
-
 void pwm_poweron(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
     periph_clk_en(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask);
+    dev(pwm)->CR1 |= TIM_CR1_CEN;
 }
 
 void pwm_poweroff(pwm_t pwm)
 {
     assert(pwm < PWM_NUMOF);
+    dev(pwm)->CR1 &= ~TIM_CR1_CEN;
     periph_clk_dis(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask);
 }
 
diff --git a/drivers/include/periph/pwm.h b/drivers/include/periph/pwm.h
index 985d544b6835b65a5a8a5e6fae85bb214a4ffcd8..d9ad13ac742560eb507fdcdb58a9786c60c819e9 100644
--- a/drivers/include/periph/pwm.h
+++ b/drivers/include/periph/pwm.h
@@ -11,6 +11,46 @@
  * @ingroup     drivers_periph
  * @brief       Low-level PWM peripheral driver
  *
+ * This interface enables access to CPU peripherals generating PWM signals. On
+ * most platforms, this interface will be implemented based on hardware timers,
+ * though some CPUs provide dedicated PWM peripherals.
+ *
+ * The characteristics of a PWM signal can be defined by three basic parameters,
+ * namely the frequency, the duty cycle, and the operational mode. This
+ * interface supports basic PWM generation in left-aligned, right-aligned, and
+ * center mode. Additionally the interface supports the definition of the used
+ * resolution, defining the granularity with which one can specify the duty
+ * cycle. This brings more flexibility to the configuration of the frequency,
+ * especially on systems with low system clocks.
+ *
+ * Typically, a single PWM device (e.g. hardware timer) supports PWM signal
+ * generation on multiple pins in parallel. While the duty cycle is selectable
+ * for each channel individually, the frequency and resolution are shared for
+ * all channels.
+ *
+ * The mapping/configuration of PWM devices (timers) and the used pins has to be
+ * done in the board configuration (the board's `periph_conf.h).
+ *
+ * When using the PWM interface, first thing you have to do is initialize the
+ * PWM device with the targeted mode, frequency, and resolution settings. Once
+ * the device is initialized, it will start the generation of PWM signals on all
+ * configured pins immediately, with an initial duty cycle of `0`. Use the
+ * pwm_set() function to change the duty cycle for a given channel. If you
+ * want to disable the PWM generation again, simply call pwm_poweroff().
+ *
+ * @section     sec_pm (Low-) power implications
+ *
+ * After initialization, the a PWM peripheral **should** be powered on and
+ * active. When manually stopped using the pwm_poweroff() function, the PWM
+ * generation **should** be stopped for all channels and the PWM peripheral
+ * **should** be fully power off (e.g. through peripheral clock gating). Once
+ * being re-enabled by calling the pwm_poweron() function, the PWM peripheral
+ * **should** transparently continue its previously configured operation,
+ * including the last active duty cycle values.
+ *
+ * While a PWM device is active, some implementations might need to block
+ * certain power modes.
+ *
  * @{
  * @file
  * @brief       Low-level PWM peripheral driver interface definitions
@@ -116,40 +156,25 @@ uint8_t pwm_channels(pwm_t dev);
 void pwm_set(pwm_t dev, uint8_t channel, uint16_t value);
 
 /**
- * @brief   Start PWM generation on the given device
- *
- * @param[in] dev           device to start
- */
-void pwm_start(pwm_t dev);
-
-/**
- * @brief   Stop PWM generation on the given device
+ * @brief   Resume PWM generation on the given device
  *
- * @param[in] dev           device to stop
- */
-void pwm_stop(pwm_t dev);
-
-/**
- * @brief   Power on the PWM device
+ * When this function is called, the given PWM device is powered on and
+ * continues its previously configured operation. The duty cycle of each channel
+ * will be the value that was last set.
  *
- * When the device is powered on the first time, no configuration is set. If
- * the device is powered back on, after having been initialized and powered off
- * before, the PWM device will continue its operation with the previously set
- * configuration. So there is no need in re-initializing then.
+ * This function must not be called before the PWM device was initialized.
  *
- * @param[in] dev           device to power on
+ * @param[in] dev           device to start
  */
 void pwm_poweron(pwm_t dev);
 
 /**
- * @brief   Power off the given PWM device
+ * @brief   Stop PWM generation on the given device
  *
- * This function will power off the given PWM device, which on most platforms
- * means that it will be disabled using clock gating. The implementation must
- * make sure, that any previously configuration will hold when the device is
- * being powered back on.
+ * This function stops the PWM generation on all configured channels for the
+ * given device and powers down the given PWM peripheral.
  *
- * @param[in] dev           device to power off
+ * @param[in] dev           device to stop
  */
 void pwm_poweroff(pwm_t dev);