2005-09-09 03:32:14 +04:00
/***************************************************************************/
/*
2012-12-05 03:04:49 +04:00
* timers . c - Generic hardware timer support .
2005-09-09 03:32:14 +04:00
*
* Copyright ( C ) 1993 Hamish Macdonald
* Copyright ( C ) 1999 D . Jeff Dionne
* Copyright ( C ) 2001 Georges Menie , Ken Desmet
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file COPYING in the main directory of this archive
* for more details .
*/
/***************************************************************************/
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/mm.h>
2007-03-07 04:28:13 +03:00
# include <linux/interrupt.h>
2007-07-26 19:09:00 +04:00
# include <linux/irq.h>
2008-02-01 10:40:17 +03:00
# include <linux/clocksource.h>
2012-01-23 07:25:56 +04:00
# include <linux/rtc.h>
2005-09-09 03:32:14 +04:00
# include <asm/setup.h>
# include <asm/pgtable.h>
# include <asm/machdep.h>
# include <asm/MC68VZ328.h>
/***************************************************************************/
# if defined(CONFIG_DRAGEN2)
/* with a 33.16 MHz clock, this will give usec resolution to the time functions */
# define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
# define CLOCK_PRE 7
# define TICKS_PER_JIFFY 41450
# elif defined(CONFIG_XCOPILOT_BUGS)
/*
* The only thing I know is that CLK32 is not available on Xcopilot
* I have little idea about what frequency SYSCLK has on Xcopilot .
* The values for prescaler and compare registers were simply
* taken from the original source
*/
# define CLOCK_SOURCE TCTL_CLKSOURCE_SYSCLK
# define CLOCK_PRE 2
# define TICKS_PER_JIFFY 0xd7e4
# else
/* default to using the 32Khz clock */
# define CLOCK_SOURCE TCTL_CLKSOURCE_32KHZ
# define CLOCK_PRE 31
# define TICKS_PER_JIFFY 10
# endif
2008-02-01 10:40:17 +03:00
static u32 m68328_tick_cnt ;
2012-05-23 07:27:18 +04:00
static irq_handler_t timer_interrupt ;
2008-02-01 10:40:17 +03:00
/***************************************************************************/
static irqreturn_t hw_tick ( int irq , void * dummy )
{
/* Reset Timer1 */
TSTAT & = 0 ;
m68328_tick_cnt + = TICKS_PER_JIFFY ;
2012-05-23 07:27:18 +04:00
return timer_interrupt ( irq , dummy ) ;
2008-02-01 10:40:17 +03:00
}
2005-09-09 03:32:14 +04:00
/***************************************************************************/
2007-07-26 19:09:00 +04:00
static struct irqaction m68328_timer_irq = {
2007-10-24 06:03:20 +04:00
. name = " timer " ,
2013-09-07 09:43:08 +04:00
. flags = IRQF_TIMER ,
2007-10-24 06:03:20 +04:00
. handler = hw_tick ,
2007-07-26 19:09:00 +04:00
} ;
2008-02-01 10:40:17 +03:00
/***************************************************************************/
2009-04-21 23:24:00 +04:00
static cycle_t m68328_read_clk ( struct clocksource * cs )
2008-02-01 10:40:17 +03:00
{
unsigned long flags ;
u32 cycles ;
local_irq_save ( flags ) ;
cycles = m68328_tick_cnt + TCN ;
local_irq_restore ( flags ) ;
return cycles ;
}
/***************************************************************************/
static struct clocksource m68328_clk = {
. name = " timer " ,
. rating = 250 ,
. read = m68328_read_clk ,
. mask = CLOCKSOURCE_MASK ( 32 ) ,
. flags = CLOCK_SOURCE_IS_CONTINUOUS ,
} ;
/***************************************************************************/
2012-05-23 07:27:18 +04:00
void hw_timer_init ( irq_handler_t handler )
2005-09-09 03:32:14 +04:00
{
/* disable timer 1 */
TCTL = 0 ;
/* set ISR */
2007-07-26 19:09:00 +04:00
setup_irq ( TMR_IRQ_NUM , & m68328_timer_irq ) ;
2005-09-09 03:32:14 +04:00
/* Restart mode, Enable int, Set clock source */
TCTL = TCTL_OM | TCTL_IRQEN | CLOCK_SOURCE ;
TPRER = CLOCK_PRE ;
TCMP = TICKS_PER_JIFFY ;
/* Enable timer 1 */
TCTL | = TCTL_TEN ;
2010-04-27 07:21:52 +04:00
clocksource_register_hz ( & m68328_clk , TICKS_PER_JIFFY * HZ ) ;
2012-05-23 07:27:18 +04:00
timer_interrupt = handler ;
2005-09-09 03:32:14 +04:00
}
/***************************************************************************/
2012-01-23 07:25:56 +04:00
int m68328_hwclk ( int set , struct rtc_time * t )
2005-09-09 03:32:14 +04:00
{
2012-01-23 07:25:56 +04:00
if ( ! set ) {
long now = RTCTIME ;
t - > tm_year = t - > tm_mon = t - > tm_mday = 1 ;
t - > tm_hour = ( now > > 24 ) % 24 ;
t - > tm_min = ( now > > 16 ) % 60 ;
t - > tm_sec = now % 60 ;
}
return 0 ;
2005-09-09 03:32:14 +04:00
}
/***************************************************************************/