^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2012 NeilBrown <neilb@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Heavily based on earlier code which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Also based on pwm-samsung.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This file is the core OMAP support for the generic, Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * PWM driver / controller, using the OMAP's dual-mode timers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * with a timer counter that goes up. When it overflows it gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * reloaded with the load value and the pwm output goes up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * When counter matches with match register, the output goes down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Reference Manual: https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Limitations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - When PWM is stopped, timer counter gets stopped immediately. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * doesn't allow the current PWM period to complete and stops abruptly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - When PWM is running and changing both duty cycle and period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * we cannot prevent in software that the output might produce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * a period with mixed settings. Especially when period/duty_cyle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * is updated while the pwm pin is high, current pwm period/duty_cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * can get updated as below based on the current timer counter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - period for current cycle = current_period + new period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * - duty_cycle for current period = current period + new duty_cycle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * - PWM OMAP DM timer cannot change the polarity when pwm is active. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * user requests a change in polarity when in active state:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * - PWM is stopped abruptly(without completing the current cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * - Polarity is changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * - A fresh cycle is started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <clocksource/timer-ti-dm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/platform_data/dmtimer-omap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DM_TIMER_LOAD_MIN 0xfffffffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DM_TIMER_MAX 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * struct pwm_omap_dmtimer_chip - Structure representing a pwm chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * corresponding to omap dmtimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @chip: PWM chip structure representing PWM controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @mutex: Mutex to protect pwm apply state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @dm_timer: Pointer to omap dm timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @pdata: Pointer to omap dm timer ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @dm_timer_pdev: Pointer to omap dm timer platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct pwm_omap_dmtimer_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct pwm_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Mutex to protect pwm apply state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct omap_dm_timer *dm_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const struct omap_dm_timer_ops *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct platform_device *dm_timer_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static inline struct pwm_omap_dmtimer_chip *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) to_pwm_omap_dmtimer_chip(struct pwm_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return container_of(chip, struct pwm_omap_dmtimer_chip, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * pwm_omap_dmtimer_get_clock_cycles() - Get clock cycles in a time frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @clk_rate: pwm timer clock rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @ns: time frame in nano seconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Return number of clock cycles in a given period(ins ns).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static u32 pwm_omap_dmtimer_get_clock_cycles(unsigned long clk_rate, int ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return DIV_ROUND_CLOSEST_ULL((u64)clk_rate * ns, NSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * pwm_omap_dmtimer_start() - Start the pwm omap dm timer in pwm mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @omap: Pointer to pwm omap dm timer chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * According to OMAP 4 TRM section 22.2.4.10 the counter should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * started at 0xFFFFFFFE when overflow and match is used to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * that the PWM line is toggled on the first event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Note that omap_dm_timer_enable/disable is for register access and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * not the timer counter itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) omap->pdata->enable(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) omap->pdata->disable(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) omap->pdata->start(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * pwm_omap_dmtimer_is_enabled() - Detect if the pwm is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @omap: Pointer to pwm omap dm timer chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Return true if pwm is enabled else false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static bool pwm_omap_dmtimer_is_enabled(struct pwm_omap_dmtimer_chip *omap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) status = omap->pdata->get_pwm_status(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return !!(status & OMAP_TIMER_CTRL_ST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * pwm_omap_dmtimer_polarity() - Detect the polarity of pwm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @omap: Pointer to pwm omap dm timer chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Return the polarity of pwm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int pwm_omap_dmtimer_polarity(struct pwm_omap_dmtimer_chip *omap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) status = omap->pdata->get_pwm_status(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return !!(status & OMAP_TIMER_CTRL_SCPWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * pwm_omap_dmtimer_config() - Update the configuration of pwm omap dm timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @chip: Pointer to PWM controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @pwm: Pointer to PWM channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @duty_ns: New duty cycle in nano seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @period_ns: New period in nano seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * Return 0 if successfully changed the period/duty_cycle else appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int duty_ns, int period_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u32 period_cycles, duty_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u32 load_value, match_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned long clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct clk *fclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) duty_ns, period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (duty_ns == pwm_get_duty_cycle(pwm) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) period_ns == pwm_get_period(pwm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) fclk = omap->pdata->get_fclk(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!fclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_err(chip->dev, "invalid pmtimer fclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) clk_rate = clk_get_rate(fclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!clk_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev_err(chip->dev, "invalid pmtimer fclk rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * Calculate the appropriate load and match values based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * specified period and duty cycle. The load value determines the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * period time and the match value determines the duty time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * The period lasts for (DM_TIMER_MAX-load_value+1) clock cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * Similarly, the active time lasts (match_value-load_value+1) cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * The non-active time is the remainder: (DM_TIMER_MAX-match_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * clock cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * NOTE: It is required that: load_value <= match_value < DM_TIMER_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * References:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (period_cycles < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dev_info(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) "period %d ns too short for clock rate %lu Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) period_ns, clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (duty_cycles < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_dbg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "duty cycle %d ns is too short for clock rate %lu Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) duty_ns, clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dev_dbg(chip->dev, "using minimum of 1 clock cycle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) duty_cycles = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) } else if (duty_cycles >= period_cycles) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_dbg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) duty_ns, period_ns, clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) duty_cycles = period_cycles - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev_dbg(chip->dev, "effective duty cycle: %lld ns, period: %lld ns\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * duty_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) clk_rate),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * period_cycles,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) clk_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) load_value = (DM_TIMER_MAX - period_cycles) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) match_value = load_value + duty_cycles - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) omap->pdata->set_load(omap->dm_timer, load_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) omap->pdata->set_match(omap->dm_timer, true, match_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) load_value, load_value, match_value, match_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * pwm_omap_dmtimer_set_polarity() - Changes the polarity of the pwm dm timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @chip: Pointer to PWM controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @pwm: Pointer to PWM channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @polarity: New pwm polarity to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) enum pwm_polarity polarity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) bool enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Disable the PWM before changing the polarity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) enabled = pwm_omap_dmtimer_is_enabled(omap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) omap->pdata->stop(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) omap->pdata->set_pwm(omap->dm_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) polarity == PWM_POLARITY_INVERSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) true, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pwm_omap_dmtimer_start(omap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * pwm_omap_dmtimer_apply() - Changes the state of the pwm omap dm timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @chip: Pointer to PWM controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @pwm: Pointer to PWM channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @state: New state to apply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Return 0 if successfully changed the state else appropriate error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int pwm_omap_dmtimer_apply(struct pwm_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) const struct pwm_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mutex_lock(&omap->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (pwm_omap_dmtimer_is_enabled(omap) && !state->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) omap->pdata->stop(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto unlock_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (pwm_omap_dmtimer_polarity(omap) != state->polarity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pwm_omap_dmtimer_set_polarity(chip, pwm, state->polarity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = pwm_omap_dmtimer_config(chip, pwm, state->duty_cycle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) state->period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) goto unlock_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!pwm_omap_dmtimer_is_enabled(omap) && state->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) omap->pdata->set_pwm(omap->dm_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) state->polarity == PWM_POLARITY_INVERSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pwm_omap_dmtimer_start(omap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unlock_mutex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mutex_unlock(&omap->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static const struct pwm_ops pwm_omap_dmtimer_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .apply = pwm_omap_dmtimer_apply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct dmtimer_platform_data *timer_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const struct omap_dm_timer_ops *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct platform_device *timer_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct pwm_omap_dmtimer_chip *omap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct omap_dm_timer *dm_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct device_node *timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) timer = of_parse_phandle(np, "ti,timers", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) timer_pdev = of_find_device_by_node(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!timer_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err(&pdev->dev, "Unable to find Timer pdev\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) goto err_find_timer_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) timer_pdata = dev_get_platdata(&timer_pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!timer_pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dev_dbg(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) "dmtimer pdata structure NULL, deferring probe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto err_platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pdata = timer_pdata->timer_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!pdata || !pdata->request_by_node ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) !pdata->free ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) !pdata->enable ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) !pdata->disable ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) !pdata->get_fclk ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) !pdata->start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) !pdata->stop ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) !pdata->set_load ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) !pdata->set_match ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) !pdata->set_pwm ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) !pdata->get_pwm_status ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) !pdata->set_prescaler ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) !pdata->write_counter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto err_platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto err_timer_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dm_timer = pdata->request_by_node(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!dm_timer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto err_request_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!omap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto err_alloc_omap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) omap->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) omap->dm_timer = dm_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) omap->dm_timer_pdev = timer_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * Ensure that the timer is stopped before we allow PWM core to call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * pwm_enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (pm_runtime_active(&omap->dm_timer_pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) omap->pdata->stop(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) omap->pdata->set_prescaler(omap->dm_timer, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* setup dmtimer clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) omap->pdata->set_source(omap->dm_timer, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) omap->chip.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) omap->chip.ops = &pwm_omap_dmtimer_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) omap->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) omap->chip.npwm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) omap->chip.of_xlate = of_pwm_xlate_with_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) omap->chip.of_pwm_n_cells = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) mutex_init(&omap->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ret = pwmchip_add(&omap->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dev_err(&pdev->dev, "failed to register PWM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto err_pwmchip_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) of_node_put(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) platform_set_drvdata(pdev, omap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err_pwmchip_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * *omap is allocated using devm_kzalloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * so no free necessary here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) err_alloc_omap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pdata->free(dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) err_request_timer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) err_timer_property:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) err_platdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) put_device(&timer_pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err_find_timer_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) of_node_put(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = pwmchip_remove(&omap->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (pm_runtime_active(&omap->dm_timer_pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) omap->pdata->stop(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) omap->pdata->free(omap->dm_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) put_device(&omap->dm_timer_pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mutex_destroy(&omap->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {.compatible = "ti,omap-dmtimer-pwm"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static struct platform_driver pwm_omap_dmtimer_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .name = "omap-dmtimer-pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .probe = pwm_omap_dmtimer_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .remove = pwm_omap_dmtimer_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) module_platform_driver(pwm_omap_dmtimer_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers");