@@ -91,55 +91,62 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
9191 */
9292static u32 timer_clock ;
9393
94- static void tc_mode ( enum clock_event_mode m , struct clock_event_device * d )
94+ static int tc_shutdown ( struct clock_event_device * d )
9595{
9696 struct tc_clkevt_device * tcd = to_tc_clkevt (d );
9797 void __iomem * regs = tcd -> regs ;
9898
99- if (tcd -> clkevt .mode == CLOCK_EVT_MODE_PERIODIC
100- || tcd -> clkevt .mode == CLOCK_EVT_MODE_ONESHOT ) {
101- __raw_writel (0xff , regs + ATMEL_TC_REG (2 , IDR ));
102- __raw_writel (ATMEL_TC_CLKDIS , regs + ATMEL_TC_REG (2 , CCR ));
103- clk_disable (tcd -> clk );
104- }
99+ __raw_writel (0xff , regs + ATMEL_TC_REG (2 , IDR ));
100+ __raw_writel (ATMEL_TC_CLKDIS , regs + ATMEL_TC_REG (2 , CCR ));
101+ clk_disable (tcd -> clk );
105102
106- switch (m ) {
103+ return 0 ;
104+ }
107105
108- /* By not making the gentime core emulate periodic mode on top
109- * of oneshot, we get lower overhead and improved accuracy.
110- */
111- case CLOCK_EVT_MODE_PERIODIC :
112- clk_enable (tcd -> clk );
106+ static int tc_set_oneshot (struct clock_event_device * d )
107+ {
108+ struct tc_clkevt_device * tcd = to_tc_clkevt (d );
109+ void __iomem * regs = tcd -> regs ;
113110
114- /* slow clock, count up to RC, then irq and restart */
115- __raw_writel (timer_clock
116- | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO ,
117- regs + ATMEL_TC_REG (2 , CMR ));
118- __raw_writel ((32768 + HZ /2 ) / HZ , tcaddr + ATMEL_TC_REG (2 , RC ));
111+ if (clockevent_state_oneshot (d ) || clockevent_state_periodic (d ))
112+ tc_shutdown (d );
119113
120- /* Enable clock and interrupts on RC compare */
121- __raw_writel (ATMEL_TC_CPCS , regs + ATMEL_TC_REG (2 , IER ));
114+ clk_enable (tcd -> clk );
122115
123- /* go go gadget! */
124- __raw_writel (ATMEL_TC_CLKEN | ATMEL_TC_SWTRG ,
125- regs + ATMEL_TC_REG (2 , CCR ));
126- break ;
116+ /* slow clock, count up to RC, then irq and stop */
117+ __raw_writel (timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
118+ ATMEL_TC_WAVESEL_UP_AUTO , regs + ATMEL_TC_REG (2 , CMR ));
119+ __raw_writel ( ATMEL_TC_CPCS , regs + ATMEL_TC_REG ( 2 , IER )) ;
127120
128- case CLOCK_EVT_MODE_ONESHOT :
129- clk_enable (tcd -> clk );
121+ /* set_next_event() configures and starts the timer */
122+ return 0 ;
123+ }
130124
131- /* slow clock, count up to RC, then irq and stop */
132- __raw_writel (timer_clock | ATMEL_TC_CPCSTOP
133- | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO ,
134- regs + ATMEL_TC_REG (2 , CMR ));
135- __raw_writel (ATMEL_TC_CPCS , regs + ATMEL_TC_REG (2 , IER ));
125+ static int tc_set_periodic (struct clock_event_device * d )
126+ {
127+ struct tc_clkevt_device * tcd = to_tc_clkevt (d );
128+ void __iomem * regs = tcd -> regs ;
136129
137- /* set_next_event() configures and starts the timer */
138- break ;
130+ if ( clockevent_state_oneshot ( d ) || clockevent_state_periodic ( d ))
131+ tc_shutdown ( d ) ;
139132
140- default :
141- break ;
142- }
133+ /* By not making the gentime core emulate periodic mode on top
134+ * of oneshot, we get lower overhead and improved accuracy.
135+ */
136+ clk_enable (tcd -> clk );
137+
138+ /* slow clock, count up to RC, then irq and restart */
139+ __raw_writel (timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO ,
140+ regs + ATMEL_TC_REG (2 , CMR ));
141+ __raw_writel ((32768 + HZ / 2 ) / HZ , tcaddr + ATMEL_TC_REG (2 , RC ));
142+
143+ /* Enable clock and interrupts on RC compare */
144+ __raw_writel (ATMEL_TC_CPCS , regs + ATMEL_TC_REG (2 , IER ));
145+
146+ /* go go gadget! */
147+ __raw_writel (ATMEL_TC_CLKEN | ATMEL_TC_SWTRG , regs +
148+ ATMEL_TC_REG (2 , CCR ));
149+ return 0 ;
143150}
144151
145152static int tc_next_event (unsigned long delta , struct clock_event_device * d )
@@ -154,13 +161,15 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
154161
155162static struct tc_clkevt_device clkevt = {
156163 .clkevt = {
157- .name = "tc_clkevt" ,
158- .features = CLOCK_EVT_FEAT_PERIODIC
159- | CLOCK_EVT_FEAT_ONESHOT ,
164+ .name = "tc_clkevt" ,
165+ .features = CLOCK_EVT_FEAT_PERIODIC |
166+ CLOCK_EVT_FEAT_ONESHOT ,
160167 /* Should be lower than at91rm9200's system timer */
161- .rating = 125 ,
162- .set_next_event = tc_next_event ,
163- .set_mode = tc_mode ,
168+ .rating = 125 ,
169+ .set_next_event = tc_next_event ,
170+ .set_state_shutdown = tc_shutdown ,
171+ .set_state_periodic = tc_set_periodic ,
172+ .set_state_oneshot = tc_set_oneshot ,
164173 },
165174};
166175
0 commit comments