Message ID | 1385085414-9034-2-git-send-email-joelf@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
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
* 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
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
* 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 --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
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