Commit f7867cff authored by Daniel Lezcano's avatar Daniel Lezcano

Merge branch 'timers/drivers/timer-ti-dm' into timers/drivers/next

parents 05852445 02e6d546
// SPDX-License-Identifier: GPL-2.0+
/* /*
* linux/arch/arm/plat-omap/dmtimer.c * linux/arch/arm/plat-omap/dmtimer.c
* *
...@@ -15,28 +16,11 @@ ...@@ -15,28 +16,11 @@
* *
* Copyright (C) 2009 Texas Instruments * Copyright (C) 2009 Texas Instruments
* Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/cpu_pm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -109,6 +93,47 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) ...@@ -109,6 +93,47 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer)
timer->context.tclr); timer->context.tclr);
} }
static void omap_timer_save_context(struct omap_dm_timer *timer)
{
timer->context.tclr =
omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
timer->context.twer =
omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG);
timer->context.tldr =
omap_dm_timer_read_reg(timer, OMAP_TIMER_LOAD_REG);
timer->context.tmar =
omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
timer->context.tier = readl_relaxed(timer->irq_ena);
timer->context.tsicr =
omap_dm_timer_read_reg(timer, OMAP_TIMER_IF_CTRL_REG);
}
static int omap_timer_context_notifier(struct notifier_block *nb,
unsigned long cmd, void *v)
{
struct omap_dm_timer *timer;
timer = container_of(nb, struct omap_dm_timer, nb);
switch (cmd) {
case CPU_CLUSTER_PM_ENTER:
if ((timer->capability & OMAP_TIMER_ALWON) ||
!atomic_read(&timer->enabled))
break;
omap_timer_save_context(timer);
break;
case CPU_CLUSTER_PM_ENTER_FAILED:
case CPU_CLUSTER_PM_EXIT:
if ((timer->capability & OMAP_TIMER_ALWON) ||
!atomic_read(&timer->enabled))
break;
omap_timer_restore_context(timer);
break;
}
return NOTIFY_OK;
}
static int omap_dm_timer_reset(struct omap_dm_timer *timer) static int omap_dm_timer_reset(struct omap_dm_timer *timer)
{ {
u32 l, timeout = 100000; u32 l, timeout = 100000;
...@@ -196,21 +221,7 @@ static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) ...@@ -196,21 +221,7 @@ static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
static void omap_dm_timer_enable(struct omap_dm_timer *timer) static void omap_dm_timer_enable(struct omap_dm_timer *timer)
{ {
int c;
pm_runtime_get_sync(&timer->pdev->dev); pm_runtime_get_sync(&timer->pdev->dev);
if (!(timer->capability & OMAP_TIMER_ALWON)) {
if (timer->get_context_loss_count) {
c = timer->get_context_loss_count(&timer->pdev->dev);
if (c != timer->ctx_loss_count) {
omap_timer_restore_context(timer);
timer->ctx_loss_count = c;
}
} else {
omap_timer_restore_context(timer);
}
}
} }
static void omap_dm_timer_disable(struct omap_dm_timer *timer) static void omap_dm_timer_disable(struct omap_dm_timer *timer)
...@@ -477,7 +488,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) ...@@ -477,7 +488,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
int omap_dm_timer_trigger(struct omap_dm_timer *timer) int omap_dm_timer_trigger(struct omap_dm_timer *timer)
{ {
if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__); pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -501,8 +512,6 @@ static int omap_dm_timer_start(struct omap_dm_timer *timer) ...@@ -501,8 +512,6 @@ static int omap_dm_timer_start(struct omap_dm_timer *timer)
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
} }
/* Save the context */
timer->context.tclr = l;
return 0; return 0;
} }
...@@ -518,37 +527,19 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer) ...@@ -518,37 +527,19 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer)
__omap_dm_timer_stop(timer, timer->posted, rate); __omap_dm_timer_stop(timer, timer->posted, rate);
/*
* Since the register values are computed and written within
* __omap_dm_timer_stop, we need to use read to retrieve the
* context.
*/
timer->context.tclr =
omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
unsigned int load) unsigned int load)
{ {
u32 l;
if (unlikely(!timer)) if (unlikely(!timer))
return -EINVAL; return -EINVAL;
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
else
l &= ~OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
/* Save the context */
timer->context.tclr = l;
timer->context.tldr = load;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
...@@ -570,15 +561,12 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, ...@@ -570,15 +561,12 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
/* Save the context */
timer->context.tclr = l;
timer->context.tmar = match;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger) int toggle, int trigger, int autoreload)
{ {
u32 l; u32 l;
...@@ -588,20 +576,34 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, ...@@ -588,20 +576,34 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
OMAP_TIMER_CTRL_PT | (0x03 << 10)); OMAP_TIMER_CTRL_PT | (0x03 << 10) | OMAP_TIMER_CTRL_AR);
if (def_on) if (def_on)
l |= OMAP_TIMER_CTRL_SCPWM; l |= OMAP_TIMER_CTRL_SCPWM;
if (toggle) if (toggle)
l |= OMAP_TIMER_CTRL_PT; l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10; l |= trigger << 10;
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
/* Save the context */
timer->context.tclr = l;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *timer)
{
u32 l;
if (unlikely(!timer))
return -EINVAL;
omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
omap_dm_timer_disable(timer);
return l;
}
static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
int prescaler) int prescaler)
{ {
...@@ -619,8 +621,6 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, ...@@ -619,8 +621,6 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
} }
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
/* Save the context */
timer->context.tclr = l;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
...@@ -634,9 +634,6 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, ...@@ -634,9 +634,6 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
__omap_dm_timer_int_enable(timer, value); __omap_dm_timer_int_enable(timer, value);
/* Save the context */
timer->context.tier = value;
timer->context.twer = value;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
...@@ -664,9 +661,6 @@ static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) ...@@ -664,9 +661,6 @@ static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
/* Save the context */
timer->context.tier &= ~mask;
timer->context.twer &= ~mask;
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
return 0; return 0;
} }
...@@ -675,7 +669,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) ...@@ -675,7 +669,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{ {
unsigned int l; unsigned int l;
if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__); pr_err("%s: timer not available or enabled.\n", __func__);
return 0; return 0;
} }
...@@ -687,7 +681,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) ...@@ -687,7 +681,7 @@ static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{ {
if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) if (unlikely(!timer || !atomic_read(&timer->enabled)))
return -EINVAL; return -EINVAL;
__omap_dm_timer_write_status(timer, value); __omap_dm_timer_write_status(timer, value);
...@@ -697,7 +691,7 @@ static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int ...@@ -697,7 +691,7 @@ static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int
static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{ {
if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not iavailable or enabled.\n", __func__); pr_err("%s: timer not iavailable or enabled.\n", __func__);
return 0; return 0;
} }
...@@ -707,7 +701,7 @@ static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) ...@@ -707,7 +701,7 @@ static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{ {
if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { if (unlikely(!timer || !atomic_read(&timer->enabled))) {
pr_err("%s: timer not available or enabled.\n", __func__); pr_err("%s: timer not available or enabled.\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -735,6 +729,37 @@ int omap_dm_timers_active(void) ...@@ -735,6 +729,37 @@ int omap_dm_timers_active(void)
return 0; return 0;
} }
static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
{
struct omap_dm_timer *timer = dev_get_drvdata(dev);
atomic_set(&timer->enabled, 0);
if (timer->capability & OMAP_TIMER_ALWON || !timer->func_base)
return 0;
omap_timer_save_context(timer);
return 0;
}
static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
{
struct omap_dm_timer *timer = dev_get_drvdata(dev);
if (!(timer->capability & OMAP_TIMER_ALWON) && timer->func_base)
omap_timer_restore_context(timer);
atomic_set(&timer->enabled, 1);
return 0;
}
static const struct dev_pm_ops omap_dm_timer_pm_ops = {
SET_RUNTIME_PM_OPS(omap_dm_timer_runtime_suspend,
omap_dm_timer_runtime_resume, NULL)
};
static const struct of_device_id omap_timer_match[]; static const struct of_device_id omap_timer_match[];
/** /**
...@@ -776,6 +801,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev) ...@@ -776,6 +801,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
if (IS_ERR(timer->io_base)) if (IS_ERR(timer->io_base))
return PTR_ERR(timer->io_base); return PTR_ERR(timer->io_base);
platform_set_drvdata(pdev, timer);
if (dev->of_node) { if (dev->of_node) {
if (of_find_property(dev->of_node, "ti,timer-alwon", NULL)) if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
timer->capability |= OMAP_TIMER_ALWON; timer->capability |= OMAP_TIMER_ALWON;
...@@ -789,7 +816,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev) ...@@ -789,7 +816,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
timer->id = pdev->id; timer->id = pdev->id;
timer->capability = pdata->timer_capability; timer->capability = pdata->timer_capability;
timer->reserved = omap_dm_timer_reserved_systimer(timer->id); timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
timer->get_context_loss_count = pdata->get_context_loss_count; }
if (!(timer->capability & OMAP_TIMER_ALWON)) {
timer->nb.notifier_call = omap_timer_context_notifier;
cpu_pm_register_notifier(&timer->nb);
} }
if (pdata) if (pdata)
...@@ -843,6 +874,8 @@ static int omap_dm_timer_remove(struct platform_device *pdev) ...@@ -843,6 +874,8 @@ static int omap_dm_timer_remove(struct platform_device *pdev)
list_for_each_entry(timer, &omap_timer_list, node) list_for_each_entry(timer, &omap_timer_list, node)
if (!strcmp(dev_name(&timer->pdev->dev), if (!strcmp(dev_name(&timer->pdev->dev),
dev_name(&pdev->dev))) { dev_name(&pdev->dev))) {
if (!(timer->capability & OMAP_TIMER_ALWON))
cpu_pm_unregister_notifier(&timer->nb);
list_del(&timer->node); list_del(&timer->node);
ret = 0; ret = 0;
break; break;
...@@ -871,6 +904,7 @@ static const struct omap_dm_timer_ops dmtimer_ops = { ...@@ -871,6 +904,7 @@ static const struct omap_dm_timer_ops dmtimer_ops = {
.set_load = omap_dm_timer_set_load, .set_load = omap_dm_timer_set_load,
.set_match = omap_dm_timer_set_match, .set_match = omap_dm_timer_set_match,
.set_pwm = omap_dm_timer_set_pwm, .set_pwm = omap_dm_timer_set_pwm,
.get_pwm_status = omap_dm_timer_get_pwm_status,
.set_prescaler = omap_dm_timer_set_prescaler, .set_prescaler = omap_dm_timer_set_prescaler,
.read_counter = omap_dm_timer_read_counter, .read_counter = omap_dm_timer_read_counter,
.write_counter = omap_dm_timer_write_counter, .write_counter = omap_dm_timer_write_counter,
...@@ -921,6 +955,7 @@ static struct platform_driver omap_dm_timer_driver = { ...@@ -921,6 +955,7 @@ static struct platform_driver omap_dm_timer_driver = {
.driver = { .driver = {
.name = "omap_timer", .name = "omap_timer",
.of_match_table = of_match_ptr(omap_timer_match), .of_match_table = of_match_ptr(omap_timer_match),
.pm = &omap_dm_timer_pm_ops,
}, },
}; };
......
...@@ -183,7 +183,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, ...@@ -183,7 +183,7 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
if (timer_active) if (timer_active)
omap->pdata->stop(omap->dm_timer); omap->pdata->stop(omap->dm_timer);
omap->pdata->set_load(omap->dm_timer, true, load_value); omap->pdata->set_load(omap->dm_timer, load_value);
omap->pdata->set_match(omap->dm_timer, true, match_value); omap->pdata->set_match(omap->dm_timer, true, match_value);
dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n", dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n",
...@@ -192,7 +192,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip, ...@@ -192,7 +192,8 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer, omap->pdata->set_pwm(omap->dm_timer,
pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED, pwm_get_polarity(pwm) == PWM_POLARITY_INVERSED,
true, true,
PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
true);
/* If config was called while timer was running it must be reenabled. */ /* If config was called while timer was running it must be reenabled. */
if (timer_active) if (timer_active)
...@@ -222,7 +223,8 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip, ...@@ -222,7 +223,8 @@ static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip,
omap->pdata->set_pwm(omap->dm_timer, omap->pdata->set_pwm(omap->dm_timer,
polarity == PWM_POLARITY_INVERSED, polarity == PWM_POLARITY_INVERSED,
true, true,
PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE,
true);
mutex_unlock(&omap->mutex); mutex_unlock(&omap->mutex);
return 0; return 0;
......
...@@ -105,17 +105,17 @@ struct omap_dm_timer { ...@@ -105,17 +105,17 @@ struct omap_dm_timer {
void __iomem *pend; /* write pending */ void __iomem *pend; /* write pending */
void __iomem *func_base; /* function register base */ void __iomem *func_base; /* function register base */
atomic_t enabled;
unsigned long rate; unsigned long rate;
unsigned reserved:1; unsigned reserved:1;
unsigned posted:1; unsigned posted:1;
struct timer_regs context; struct timer_regs context;
int (*get_context_loss_count)(struct device *);
int ctx_loss_count;
int revision; int revision;
u32 capability; u32 capability;
u32 errata; u32 errata;
struct platform_device *pdev; struct platform_device *pdev;
struct list_head node; struct list_head node;
struct notifier_block nb;
}; };
int omap_dm_timer_reserve_systimer(int id); int omap_dm_timer_reserve_systimer(int id);
......
...@@ -30,12 +30,12 @@ struct omap_dm_timer_ops { ...@@ -30,12 +30,12 @@ struct omap_dm_timer_ops {
int (*stop)(struct omap_dm_timer *timer); int (*stop)(struct omap_dm_timer *timer);
int (*set_source)(struct omap_dm_timer *timer, int source); int (*set_source)(struct omap_dm_timer *timer, int source);
int (*set_load)(struct omap_dm_timer *timer, int autoreload, int (*set_load)(struct omap_dm_timer *timer, unsigned int value);
unsigned int value);
int (*set_match)(struct omap_dm_timer *timer, int enable, int (*set_match)(struct omap_dm_timer *timer, int enable,
unsigned int match); unsigned int match);
int (*set_pwm)(struct omap_dm_timer *timer, int def_on, int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger); int toggle, int trigger, int autoreload);
int (*get_pwm_status)(struct omap_dm_timer *timer);
int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler); int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
unsigned int (*read_counter)(struct omap_dm_timer *timer); unsigned int (*read_counter)(struct omap_dm_timer *timer);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment