diff mbox

[1/8] ARM: OMAP: Move public portion of dmtimer.h to include/linux/omap-timer.h

Message ID 1385085414-9034-2-git-send-email-joelf@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Joel Fernandes Nov. 22, 2013, 1:56 a.m. UTC
Multiplatform support has made arch/arm/plat-omap/include/plat/ inaccessible to
drivers outside the plat-omap directory [1]. Due to this the following drivers
are disabled with !CONFIG_ARCH_MULTIPLATFORM:
CONFIG_IR_RX51 (drivers/media/rc/ir-rx51.c)
CONFIG_TIDSPBRIDGE (drivers/staging/tidspbridge/core/dsp-clock.c)

We move the portion of the dmtimer "API" that should be accessible to the
drivers, into include/linux/omap-timer.h

Build tested changes with IR_RX51.

[1] http://marc.info/?l=linux-omap&m=138421692332108&w=2

Signed-off-by: Joel Fernandes <joelf@ti.com>
---
 arch/arm/plat-omap/include/plat/dmtimer.h | 121 +---------------------
 include/linux/omap-timer.h                | 167 ++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+), 120 deletions(-)
 create mode 100644 include/linux/omap-timer.h

Comments

Tony Lindgren Nov. 22, 2013, 3:33 p.m. UTC | #1
Hi,

* Joel Fernandes <joelf@ti.com> [131121 18:00]:
> Multiplatform support has made arch/arm/plat-omap/include/plat/ inaccessible to
> drivers outside the plat-omap directory [1]. Due to this the following drivers
> are disabled with !CONFIG_ARCH_MULTIPLATFORM:
> CONFIG_IR_RX51 (drivers/media/rc/ir-rx51.c)
> CONFIG_TIDSPBRIDGE (drivers/staging/tidspbridge/core/dsp-clock.c)
> 
> We move the portion of the dmtimer "API" that should be accessible to the
> drivers, into include/linux/omap-timer.h

As we chatted earlier, we don't have to expose all these hardware specific
functions and use existing Linux generic frameworks instead.

We can implement an irqchip and a clocksource in the dmtimer code for the
client drivers to use, and after that we only have a couple of dmtimer
specific functions left to export.

I'm thinkging some thing like this for the public API:

omap_dm_timer_request			request_irq
omap_dm_timer_request_specific		request_irq
omap_dm_timer_get_irq			request_irq
omap_dm_timer_set_source		clk_set_rate
omap_dm_timer_stop			disable_irq
omap_dm_timer_start			enable_irq
omap_dm_timer_disable			disable_irq
omap_dm_timer_free			free_irq
omap_dm_timer_set_int_enable		enable_irq

After that, what's left to export are some functions to configure
the hardware timer:

omap_dm_timer_write_counter
omap_dm_timer_set_match
omap_dm_timer_read_counter
omap_dm_timer_read_status
omap_dm_timer_write_status

And for those we can then eventually probably have some Linux generic
hardware timer API :)

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joel Fernandes Nov. 22, 2013, 4:01 p.m. UTC | #2
On 11/22/2013 09:33 AM, Tony Lindgren wrote:
> Hi,
> 
> * Joel Fernandes <joelf@ti.com> [131121 18:00]:
>> Multiplatform support has made arch/arm/plat-omap/include/plat/ inaccessible to
>> drivers outside the plat-omap directory [1]. Due to this the following drivers
>> are disabled with !CONFIG_ARCH_MULTIPLATFORM:
>> CONFIG_IR_RX51 (drivers/media/rc/ir-rx51.c)
>> CONFIG_TIDSPBRIDGE (drivers/staging/tidspbridge/core/dsp-clock.c)
>>
>> We move the portion of the dmtimer "API" that should be accessible to the
>> drivers, into include/linux/omap-timer.h
> 
> As we chatted earlier, we don't have to expose all these hardware specific
> functions and use existing Linux generic frameworks instead.
> 
> We can implement an irqchip and a clocksource in the dmtimer code for the
> client drivers to use, and after that we only have a couple of dmtimer
> specific functions left to export.
> 
> I'm thinkging some thing like this for the public API:
> 
> omap_dm_timer_request			request_irq
> omap_dm_timer_request_specific		request_irq
> omap_dm_timer_get_irq			request_irq
> omap_dm_timer_set_source		clk_set_rate
> omap_dm_timer_stop			disable_irq
> omap_dm_timer_start			enable_irq
> omap_dm_timer_disable			disable_irq
> omap_dm_timer_free			free_irq
> omap_dm_timer_set_int_enable		enable_irq

Hi Tony,

The thing I feel we're trying to fit a square peg into round hole type of thing
here.

Some reasons I feel this is overkill (point 2 makes it even not possible):

1. Ideally IR_RX51 should be using clockevents/hrtimer framework instead of
irqchip. Other than that, dsp bridge is the only other user.

2. These functions will be also be required to be public once mach-omap2/timer.c
moves to drivers/clocksource/ . At such an early point of code, we can't use
irqchip anyway so we'd need these functions public.

3. This is a minor point, but its also not immediately intuitive or clear to
someone who needs a dedicated hardware timer that they need to use an IRQ chip
driver for the same. But we can avoid any discussion about this till we can
discuss/agree on the above 2.

thanks,

-Joel
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joel Fernandes Nov. 26, 2013, 3:02 a.m. UTC | #3
Hi Tony,

Few replies inline below. Adding Suman as well who is planning to use dmtimer
directly for his work with DSP.

On 11/22/2013 09:33 AM, Tony Lindgren wrote:
> Hi,
> 
> * Joel Fernandes <joelf@ti.com> [131121 18:00]:
>> Multiplatform support has made arch/arm/plat-omap/include/plat/ inaccessible to
>> drivers outside the plat-omap directory [1]. Due to this the following drivers
>> are disabled with !CONFIG_ARCH_MULTIPLATFORM:
>> CONFIG_IR_RX51 (drivers/media/rc/ir-rx51.c)
>> CONFIG_TIDSPBRIDGE (drivers/staging/tidspbridge/core/dsp-clock.c)
>>
>> We move the portion of the dmtimer "API" that should be accessible to the
>> drivers, into include/linux/omap-timer.h
> 
> As we chatted earlier, we don't have to expose all these hardware specific
> functions and use existing Linux generic frameworks instead.

I thought over this, and strongly feel that in this case moving to a generic
framework is not the right approach. I mentioned reasons in last post, but
summarizing all of them below:

1. It is not immediately intuitive or obvious unlike GPIO that a timer can be an
irqchip.

2. There are only 1-2 users of the dmtimer directly so moving to linux generic
framework is bit overkill I feel. Further there is already a framework-
clockevents/hrtimer which everyone should be using. For the 1-2 direct dmtimer
users, they should just use the dmtimer public API.

More reasons below...

> 
> We can implement an irqchip and a clocksource in the dmtimer code for the
> client drivers to use, and after that we only have a couple of dmtimer
> specific functions left to export.
> 
> I'm thinkging some thing like this for the public API:
> 
> omap_dm_timer_request			request_irq
> omap_dm_timer_request_specific		request_irq
> omap_dm_timer_get_irq			request_irq
> omap_dm_timer_set_source		clk_set_rate

For clk_set_rate, how would one directly access the timer node if we've hidden
it behind an irq chip abstraction?

per your suggestion, one would have something like:

dsp {
    interrupt-parent = <&timer1>;
}

so how do you clk_set_rate rate something like this given the dsp node?

If the suggestion is to get the timer1 node from the interrupt-parent property,
if I may say- that's a bit ugly because now you're breaking the irq chip
abstraction just to access the timer node..

> omap_dm_timer_stop			disable_irq
> omap_dm_timer_start			enable_irq
> omap_dm_timer_disable			disable_irq
> omap_dm_timer_free			free_irq
> omap_dm_timer_set_int_enable		enable_irq
> 
> After that, what's left to export are some functions to configure
> the hardware timer:
> 
> omap_dm_timer_write_counter
> omap_dm_timer_set_match
> omap_dm_timer_read_counter
> omap_dm_timer_read_status
> omap_dm_timer_write_status

Same comment for clk_set_rate applies here, we've to access interrupt-parent
property to get timer node and call dmtimer API which breaks the abstraction.

Usually I've seen frameworks come up because there is code duplication etc. In
this case there is no duplication as such, and the number of users of the API is
also few. What is the problem with exposing a small set of API to timer users in
drivers/ specially when they are prefixed by a unique name (omap_dm_timer)?

thanks,

-Joel



--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren Nov. 26, 2013, 6:29 p.m. UTC | #4
* Joel Fernandes <joelf@ti.com> [131125 19:03]:
> Hi Tony,
> 
> Few replies inline below. Adding Suman as well who is planning to use dmtimer
> directly for his work with DSP.
> 
> On 11/22/2013 09:33 AM, Tony Lindgren wrote:
> > Hi,
> > 
> > * Joel Fernandes <joelf@ti.com> [131121 18:00]:
> >> Multiplatform support has made arch/arm/plat-omap/include/plat/ inaccessible to
> >> drivers outside the plat-omap directory [1]. Due to this the following drivers
> >> are disabled with !CONFIG_ARCH_MULTIPLATFORM:
> >> CONFIG_IR_RX51 (drivers/media/rc/ir-rx51.c)
> >> CONFIG_TIDSPBRIDGE (drivers/staging/tidspbridge/core/dsp-clock.c)
> >>
> >> We move the portion of the dmtimer "API" that should be accessible to the
> >> drivers, into include/linux/omap-timer.h
> > 
> > As we chatted earlier, we don't have to expose all these hardware specific
> > functions and use existing Linux generic frameworks instead.
> 
> I thought over this, and strongly feel that in this case moving to a generic
> framework is not the right approach. I mentioned reasons in last post, but
> summarizing all of them below:
> 
> 1. It is not immediately intuitive or obvious unlike GPIO that a timer can be an
> irqchip.

But that's what it really is for hadware timers :)
 
> 2. There are only 1-2 users of the dmtimer directly so moving to linux generic
> framework is bit overkill I feel. Further there is already a framework-
> clockevents/hrtimer which everyone should be using. For the 1-2 direct dmtimer
> users, they should just use the dmtimer public API.

But the thing is, we don't want to expose the dmtimer public API. That will
lead to drivers tinkering directly with the hardware timers and then other
SoCs will follow.
 
> More reasons below...
> 
> > 
> > We can implement an irqchip and a clocksource in the dmtimer code for the
> > client drivers to use, and after that we only have a couple of dmtimer
> > specific functions left to export.
> > 
> > I'm thinkging some thing like this for the public API:
> > 
> > omap_dm_timer_request			request_irq
> > omap_dm_timer_request_specific		request_irq
> > omap_dm_timer_get_irq			request_irq
> > omap_dm_timer_set_source		clk_set_rate
> 
> For clk_set_rate, how would one directly access the timer node if we've hidden
> it behind an irq chip abstraction?
> 
> per your suggestion, one would have something like:
> 
> dsp {
>     interrupt-parent = <&timer1>;
> }
> 
> so how do you clk_set_rate rate something like this given the dsp node?

All you have to do is implement a clocksource driver in dmtimer.c code.
 
> If the suggestion is to get the timer1 node from the interrupt-parent property,
> if I may say- that's a bit ugly because now you're breaking the irq chip
> abstraction just to access the timer node..

Hmm sorry I don't follow you here.
 
> > omap_dm_timer_stop			disable_irq
> > omap_dm_timer_start			enable_irq
> > omap_dm_timer_disable			disable_irq
> > omap_dm_timer_free			free_irq
> > omap_dm_timer_set_int_enable		enable_irq
> > 
> > After that, what's left to export are some functions to configure
> > the hardware timer:
> > 
> > omap_dm_timer_write_counter
> > omap_dm_timer_set_match
> > omap_dm_timer_read_counter
> > omap_dm_timer_read_status
> > omap_dm_timer_write_status
> 
> Same comment for clk_set_rate applies here, we've to access interrupt-parent
> property to get timer node and call dmtimer API which breaks the abstraction.

Sorry, I don't follow you here either. I'm sure we'll have some Linux generic
standard for programming hardware timers, but still using request_irq + 
clk_set_rate is very standard behaviour no matter what happens later on.
 
> Usually I've seen frameworks come up because there is code duplication etc. In
> this case there is no duplication as such, and the number of users of the API is
> also few. What is the problem with exposing a small set of API to timer users in
> drivers/ specially when they are prefixed by a unique name (omap_dm_timer)?

Because we don't want to export 27 omap specific functions to drivers:

$ grep EXPORT_SYMBOL arch/arm/plat-omap/dmtimer.c | wc -l
27

Instead, it looks like we can get away with exporting just:

omap_dm_timer_write_counter
omap_dm_timer_set_match
omap_dm_timer_read_counter
omap_dm_timer_read_status
omap_dm_timer_write_status

And I'm sure we'll have some solution for those also later on.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joel Fernandes Nov. 26, 2013, 7:52 p.m. UTC | #5
On 11/26/2013 12:29 PM, Tony Lindgren wrote:
[..]
>>> We can implement an irqchip and a clocksource in the dmtimer code for the
>>> client drivers to use, and after that we only have a couple of dmtimer
>>> specific functions left to export.
>>>
>>> I'm thinkging some thing like this for the public API:
>>>
>>> omap_dm_timer_request			request_irq
>>> omap_dm_timer_request_specific		request_irq
>>> omap_dm_timer_get_irq			request_irq
>>> omap_dm_timer_set_source		clk_set_rate
>>
>> For clk_set_rate, how would one directly access the timer node if we've hidden
>> it behind an irq chip abstraction?
>>
>> per your suggestion, one would have something like:
>>
>> dsp {
>>     interrupt-parent = <&timer1>;
>> }
>>
>> so how do you clk_set_rate rate something like this given the dsp node?
> 
> All you have to do is implement a clocksource driver in dmtimer.c code.
>  
>> If the suggestion is to get the timer1 node from the interrupt-parent property,
>> if I may say- that's a bit ugly because now you're breaking the irq chip
>> abstraction just to access the timer node..
> 
> Hmm sorry I don't follow you here.

I assumed above that you were suggesting implementing interrupt chaining like
gpio-omap driver.

Can you give an example workflow to explain your suggestion?

I'll tell you how I understand what you were suggesting and then you can correct
me, and maybe we can meet somewhere:

Typically *without* irqchip or chaining what you suggested, we would  have
something like (purely an example):
dsp {
    timer = <&timer1>;
}

There is an API:
omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np); that one
would use.

Now moving to your suggestion, the dts would look like:
dsp {
    interrupt-parrent = <&timer1>;
    interrupts = <1>;
}

Naturally some APIs will not fit into the IRQ framework, so these subset of
dmtimer API may need to be exposed as you pointed. To use the API, the timer has
to first be retrieved from interrupt-parent property of "dsp" here to get a
device_node, and then the timer has to be requested and subset API used on it.
This is "hack" that's not acceptable according to me...

thanks,

-Joel

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tony Lindgren Nov. 26, 2013, 8:32 p.m. UTC | #6
* Joel Fernandes <joelf@ti.com> [131126 11:53]:
> On 11/26/2013 12:29 PM, Tony Lindgren wrote:
> [..]
> >>> We can implement an irqchip and a clocksource in the dmtimer code for the
> >>> client drivers to use, and after that we only have a couple of dmtimer
> >>> specific functions left to export.
> >>>
> >>> I'm thinkging some thing like this for the public API:
> >>>
> >>> omap_dm_timer_request			request_irq
> >>> omap_dm_timer_request_specific		request_irq
> >>> omap_dm_timer_get_irq			request_irq
> >>> omap_dm_timer_set_source		clk_set_rate
> >>
> >> For clk_set_rate, how would one directly access the timer node if we've hidden
> >> it behind an irq chip abstraction?
> >>
> >> per your suggestion, one would have something like:
> >>
> >> dsp {
> >>     interrupt-parent = <&timer1>;
> >> }
> >>
> >> so how do you clk_set_rate rate something like this given the dsp node?
> > 
> > All you have to do is implement a clocksource driver in dmtimer.c code.
> >  
> >> If the suggestion is to get the timer1 node from the interrupt-parent property,
> >> if I may say- that's a bit ugly because now you're breaking the irq chip
> >> abstraction just to access the timer node..
> > 
> > Hmm sorry I don't follow you here.
> 
> I assumed above that you were suggesting implementing interrupt chaining like
> gpio-omap driver.
> 
> Can you give an example workflow to explain your suggestion?
> 
> I'll tell you how I understand what you were suggesting and then you can correct
> me, and maybe we can meet somewhere:
> 
> Typically *without* irqchip or chaining what you suggested, we would  have
> something like (purely an example):
> dsp {
>     timer = <&timer1>;
> }
> 
> There is an API:
> omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np); that one
> would use.
> 
> Now moving to your suggestion, the dts would look like:
> dsp {
>     interrupt-parrent = <&timer1>;
>     interrupts = <1>;
> }

Yes something like that.
 
> Naturally some APIs will not fit into the IRQ framework, so these subset of
> dmtimer API may need to be exposed as you pointed. To use the API, the timer has
> to first be retrieved from interrupt-parent property of "dsp" here to get a
> device_node, and then the timer has to be requested and subset API used on it.
> This is "hack" that's not acceptable according to me...

Well it's really the same story with the GPIO framework if you follow the
request_irq analogy for a GPIO pin. You may still need to configure some things
manually that don't fit into the IRQ framework using let's say pinctrl framework.
Sure some of that can be automated eventually for GPIO and also for hardware
timers when we eventually have some generic hardware timer framework,
but the request_irq and clock_set_rate parts will stay valid.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index fb92abb..7d6cff8 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -35,130 +35,11 @@ 
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/omap-timer.h>
 
 #ifndef __ASM_ARCH_DMTIMER_H
 #define __ASM_ARCH_DMTIMER_H
 
-/* clock sources */
-#define OMAP_TIMER_SRC_SYS_CLK			0x00
-#define OMAP_TIMER_SRC_32_KHZ			0x01
-#define OMAP_TIMER_SRC_EXT_CLK			0x02
-
-/* timer interrupt enable bits */
-#define OMAP_TIMER_INT_CAPTURE			(1 << 2)
-#define OMAP_TIMER_INT_OVERFLOW			(1 << 1)
-#define OMAP_TIMER_INT_MATCH			(1 << 0)
-
-/* trigger types */
-#define OMAP_TIMER_TRIGGER_NONE			0x00
-#define OMAP_TIMER_TRIGGER_OVERFLOW		0x01
-#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
-
-/* posted mode types */
-#define OMAP_TIMER_NONPOSTED			0x00
-#define OMAP_TIMER_POSTED			0x01
-
-/* timer capabilities used in hwmod database */
-#define OMAP_TIMER_SECURE				0x80000000
-#define OMAP_TIMER_ALWON				0x40000000
-#define OMAP_TIMER_HAS_PWM				0x20000000
-#define OMAP_TIMER_NEEDS_RESET				0x10000000
-#define OMAP_TIMER_HAS_DSP_IRQ				0x08000000
-
-/*
- * timer errata flags
- *
- * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
- * errata prevents us from using posted mode on these devices, unless the
- * timer counter register is never read. For more details please refer to
- * the OMAP3/4/5 errata documents.
- */
-#define OMAP_TIMER_ERRATA_I103_I767			0x80000000
-
-struct omap_timer_capability_dev_attr {
-	u32 timer_capability;
-};
-
-struct timer_regs {
-	u32 tidr;
-	u32 tier;
-	u32 twer;
-	u32 tclr;
-	u32 tcrr;
-	u32 tldr;
-	u32 ttrg;
-	u32 twps;
-	u32 tmar;
-	u32 tcar1;
-	u32 tsicr;
-	u32 tcar2;
-	u32 tpir;
-	u32 tnir;
-	u32 tcvr;
-	u32 tocr;
-	u32 towr;
-};
-
-struct omap_dm_timer {
-	int id;
-	int irq;
-	struct clk *fclk;
-
-	void __iomem	*io_base;
-	void __iomem	*irq_stat;	/* TISR/IRQSTATUS interrupt status */
-	void __iomem	*irq_ena;	/* irq enable */
-	void __iomem	*irq_dis;	/* irq disable, only on v2 ip */
-	void __iomem	*pend;		/* write pending */
-	void __iomem	*func_base;	/* function register base */
-
-	unsigned long rate;
-	unsigned reserved:1;
-	unsigned posted:1;
-	struct timer_regs context;
-	int (*get_context_loss_count)(struct device *);
-	int ctx_loss_count;
-	int revision;
-	u32 capability;
-	u32 errata;
-	struct platform_device *pdev;
-	struct list_head node;
-};
-
-int omap_dm_timer_reserve_systimer(int id);
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
-struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
-int omap_dm_timer_free(struct omap_dm_timer *timer);
-void omap_dm_timer_enable(struct omap_dm_timer *timer);
-void omap_dm_timer_disable(struct omap_dm_timer *timer);
-
-int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
-
-u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-
-int omap_dm_timer_trigger(struct omap_dm_timer *timer);
-int omap_dm_timer_start(struct omap_dm_timer *timer);
-int omap_dm_timer_stop(struct omap_dm_timer *timer);
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
-
-int omap_dm_timers_active(void);
-
 /*
  * Do not use the defines below, they are not needed. They should be only
  * used by dmtimer.c and sys_timer related code.
diff --git a/include/linux/omap-timer.h b/include/linux/omap-timer.h
new file mode 100644
index 0000000..e21ee18
--- /dev/null
+++ b/include/linux/omap-timer.h
@@ -0,0 +1,167 @@ 
+/*
+ * include/misc/dmtimer.h
+ *
+ * OMAP Dual-Mode Timers public header
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Platform device conversion and hwmod support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * PWM and clock framwork support by Timo Teras.
+ *
+ * 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/io.h>
+#include <linux/platform_device.h>
+
+#ifndef __MISC_DMTIMER_H
+#define __MISC_DMTIMER_H
+
+/* clock sources */
+#define OMAP_TIMER_SRC_SYS_CLK			0x00
+#define OMAP_TIMER_SRC_32_KHZ			0x01
+#define OMAP_TIMER_SRC_EXT_CLK			0x02
+
+/* timer interrupt enable bits */
+#define OMAP_TIMER_INT_CAPTURE			(1 << 2)
+#define OMAP_TIMER_INT_OVERFLOW			(1 << 1)
+#define OMAP_TIMER_INT_MATCH			(1 << 0)
+
+/* trigger types */
+#define OMAP_TIMER_TRIGGER_NONE			0x00
+#define OMAP_TIMER_TRIGGER_OVERFLOW		0x01
+#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02
+
+/* posted mode types */
+#define OMAP_TIMER_NONPOSTED			0x00
+#define OMAP_TIMER_POSTED			0x01
+
+/* timer capabilities used in hwmod database */
+#define OMAP_TIMER_SECURE				0x80000000
+#define OMAP_TIMER_ALWON				0x40000000
+#define OMAP_TIMER_HAS_PWM				0x20000000
+#define OMAP_TIMER_NEEDS_RESET				0x10000000
+#define OMAP_TIMER_HAS_DSP_IRQ				0x08000000
+
+/*
+ * timer errata flags
+ *
+ * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
+ * errata prevents us from using posted mode on these devices, unless the
+ * timer counter register is never read. For more details please refer to
+ * the OMAP3/4/5 errata documents.
+ */
+#define OMAP_TIMER_ERRATA_I103_I767			0x80000000
+
+struct omap_timer_capability_dev_attr {
+	u32 timer_capability;
+};
+
+struct timer_regs {
+	u32 tidr;
+	u32 tier;
+	u32 twer;
+	u32 tclr;
+	u32 tcrr;
+	u32 tldr;
+	u32 ttrg;
+	u32 twps;
+	u32 tmar;
+	u32 tcar1;
+	u32 tsicr;
+	u32 tcar2;
+	u32 tpir;
+	u32 tnir;
+	u32 tcvr;
+	u32 tocr;
+	u32 towr;
+};
+
+struct omap_dm_timer {
+	int id;
+	int irq;
+	struct clk *fclk;
+
+	void __iomem	*io_base;
+	void __iomem	*irq_stat;	/* TISR/IRQSTATUS interrupt status */
+	void __iomem	*irq_ena;	/* irq enable */
+	void __iomem	*irq_dis;	/* irq disable, only on v2 ip */
+	void __iomem	*pend;		/* write pending */
+	void __iomem	*func_base;	/* function register base */
+
+	unsigned long rate;
+	unsigned reserved:1;
+	unsigned posted:1;
+	struct timer_regs context;
+	int (*get_context_loss_count)(struct device *);
+	int ctx_loss_count;
+	int revision;
+	u32 capability;
+	u32 errata;
+	struct platform_device *pdev;
+	struct list_head node;
+};
+
+int omap_dm_timer_reserve_systimer(int id);
+struct omap_dm_timer *omap_dm_timer_request(void);
+struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
+struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
+int omap_dm_timer_free(struct omap_dm_timer *timer);
+void omap_dm_timer_enable(struct omap_dm_timer *timer);
+void omap_dm_timer_disable(struct omap_dm_timer *timer);
+
+int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
+
+u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
+
+int omap_dm_timer_trigger(struct omap_dm_timer *timer);
+int omap_dm_timer_start(struct omap_dm_timer *timer);
+int omap_dm_timer_stop(struct omap_dm_timer *timer);
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+			   unsigned int value);
+int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
+				 unsigned int value);
+int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+			    unsigned int match);
+int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle,
+			  int trigger);
+int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+
+int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+				 unsigned int value);
+int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
+int omap_dm_timer_write_counter(struct omap_dm_timer *timer,
+				unsigned int value);
+
+int omap_dm_timers_active(void);
+
+#endif