Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
f3f9ad0e
Commit
f3f9ad0e
authored
Nov 01, 2007
by
Ralf Baechle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MIPS] Sibyte: Fixes for oneshot timer mode.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
faf2782b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
55 additions
and
62 deletions
+55
-62
arch/mips/sibyte/bcm1480/time.c
arch/mips/sibyte/bcm1480/time.c
+26
-25
arch/mips/sibyte/sb1250/time.c
arch/mips/sibyte/sb1250/time.c
+29
-37
No files found.
arch/mips/sibyte/bcm1480/time.c
View file @
f3f9ad0e
...
...
@@ -17,13 +17,11 @@
*/
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/spinlock.h>
#include <asm/addrspace.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/sibyte/bcm1480_regs.h>
#include <asm/sibyte/sb1250_regs.h>
...
...
@@ -45,23 +43,23 @@ static void sibyte_set_mode(enum clock_event_mode mode,
struct
clock_event_device
*
evt
)
{
unsigned
int
cpu
=
smp_processor_id
();
void
__iomem
*
timer_cfg
,
*
timer_
init
;
void
__iomem
*
cfg
,
*
init
;
timer_
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
timer_
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
switch
(
mode
)
{
case
CLOCK_EVT_MODE_PERIODIC
:
__raw_writeq
(
0
,
timer_
cfg
);
__raw_writeq
((
V_SCD_TIMER_FREQ
/
HZ
)
-
1
,
timer_
init
);
__raw_writeq
(
0
,
cfg
);
__raw_writeq
((
V_SCD_TIMER_FREQ
/
HZ
)
-
1
,
init
);
__raw_writeq
(
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
,
timer_
cfg
);
cfg
);
break
;
case
CLOCK_EVT_MODE_ONESHOT
:
/* Stop the timer until we actually program a shot */
case
CLOCK_EVT_MODE_SHUTDOWN
:
__raw_writeq
(
0
,
timer_
cfg
);
__raw_writeq
(
0
,
cfg
);
break
;
case
CLOCK_EVT_MODE_UNUSED
:
/* shuddup gcc */
...
...
@@ -73,30 +71,33 @@ static void sibyte_set_mode(enum clock_event_mode mode,
static
int
sibyte_next_event
(
unsigned
long
delta
,
struct
clock_event_device
*
cd
)
{
unsigned
int
cpu
=
smp_processor_id
();
void
__iomem
*
timer_init
;
unsigned
int
cnt
;
int
res
;
void
__iomem
*
cfg
,
*
init
;
timer_init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
cnt
=
__raw_readq
(
timer_init
);
cnt
+=
delta
;
__raw_writeq
(
cnt
,
timer_init
);
res
=
((
long
)(
__raw_readq
(
timer_init
)
-
cnt
)
>
0
)
?
-
ETIME
:
0
;
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
return
res
;
__raw_writeq
(
delta
-
1
,
init
);
__raw_writeq
(
M_SCD_TIMER_ENABLE
,
cfg
);
return
0
;
}
static
irqreturn_t
sibyte_counter_handler
(
int
irq
,
void
*
dev_id
)
{
unsigned
int
cpu
=
smp_processor_id
();
struct
clock_event_device
*
cd
=
dev_id
;
void
__iomem
*
timer_cfg
;
void
__iomem
*
cfg
;
unsigned
long
tmode
;
if
(
cd
->
mode
==
CLOCK_EVT_MODE_PERIODIC
)
tmode
=
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
;
else
tmode
=
0
;
timer_cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
/* ACK interrupt */
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
____raw_writeq
(
tmode
,
cfg
);
/* Reset the timer */
__raw_writeq
(
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
,
timer_cfg
);
cd
->
event_handler
(
cd
);
return
IRQ_HANDLED
;
...
...
@@ -133,7 +134,7 @@ void __cpuinit sb1480_clockevent_init(void)
bcm1480_mask_irq
(
cpu
,
irq
);
/*
* Map timer interrupt to IP[4] of this cpu
* Map t
he t
imer interrupt to IP[4] of this cpu
*/
__raw_writeq
(
IMR_IP4_VAL
,
IOADDR
(
A_BCM1480_IMR_REGISTER
(
cpu
,
...
...
arch/mips/sibyte/sb1250/time.c
View file @
f3f9ad0e
...
...
@@ -15,33 +15,19 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* These are routines to set up and handle interrupts from the
* sb1250 general purpose timer 0. We're using the timer as a
* system clock, so we set it up to run at 100 Hz. On every
* interrupt, we update our idea of what the time of day is,
* then call do_timer() in the architecture-independent kernel
* code to do general bookkeeping (e.g. update jiffies, run
* bottom halves, etc.)
*/
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/kernel_stat.h>
#include <linux/percpu.h>
#include <asm/irq.h>
#include <asm/addrspace.h>
#include <asm/time.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/sibyte/sb1250.h>
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_int.h>
#include <asm/sibyte/sb1250_scd.h>
#define IMR_IP2_VAL K_INT_MAP_I0
#define IMR_IP3_VAL K_INT_MAP_I1
#define IMR_IP4_VAL K_INT_MAP_I2
...
...
@@ -49,32 +35,31 @@
#define SB1250_HPT_NUM 3
#define SB1250_HPT_VALUE M_SCD_TIMER_CNT
/* max value */
/*
* The general purpose timer ticks at 1
Mh
z independent if
* The general purpose timer ticks at 1
MH
z independent if
* the rest of the system
*/
static
void
sibyte_set_mode
(
enum
clock_event_mode
mode
,
struct
clock_event_device
*
evt
)
{
unsigned
int
cpu
=
smp_processor_id
();
void
__iomem
*
timer_cfg
,
*
timer_
init
;
void
__iomem
*
cfg
,
*
init
;
timer_
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
timer_
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
switch
(
mode
)
{
switch
(
mode
)
{
case
CLOCK_EVT_MODE_PERIODIC
:
__raw_writeq
(
0
,
timer_
cfg
);
__raw_writeq
((
V_SCD_TIMER_FREQ
/
HZ
)
-
1
,
timer_
init
);
__raw_writeq
(
0
,
cfg
);
__raw_writeq
((
V_SCD_TIMER_FREQ
/
HZ
)
-
1
,
init
);
__raw_writeq
(
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
,
timer_
cfg
);
cfg
);
break
;
case
CLOCK_EVT_MODE_ONESHOT
:
/* Stop the timer until we actually program a shot */
case
CLOCK_EVT_MODE_SHUTDOWN
:
__raw_writeq
(
0
,
timer_
cfg
);
__raw_writeq
(
0
,
cfg
);
break
;
case
CLOCK_EVT_MODE_UNUSED
:
/* shuddup gcc */
...
...
@@ -83,18 +68,16 @@ static void sibyte_set_mode(enum clock_event_mode mode,
}
}
static
int
sibyte_next_event
(
unsigned
long
delta
,
struct
clock_event_device
*
evt
)
static
int
sibyte_next_event
(
unsigned
long
delta
,
struct
clock_event_device
*
cd
)
{
unsigned
int
cpu
=
smp_processor_id
();
void
__iomem
*
timer_cfg
,
*
timer_
init
;
void
__iomem
*
cfg
,
*
init
;
timer_
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
timer_
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
init
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_INIT
));
__raw_writeq
(
0
,
timer_cfg
);
__raw_writeq
(
delta
,
timer_init
);
__raw_writeq
(
M_SCD_TIMER_ENABLE
,
timer_cfg
);
__raw_writeq
(
delta
-
1
,
init
);
__raw_writeq
(
M_SCD_TIMER_ENABLE
,
cfg
);
return
0
;
}
...
...
@@ -103,10 +86,17 @@ static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
{
unsigned
int
cpu
=
smp_processor_id
();
struct
clock_event_device
*
cd
=
dev_id
;
void
__iomem
*
cfg
;
unsigned
long
tmode
;
if
(
cd
->
mode
==
CLOCK_EVT_MODE_PERIODIC
)
tmode
=
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
;
else
tmode
=
0
;
/* ACK interrupt */
____raw_writeq
(
M_SCD_TIMER_ENABLE
|
M_SCD_TIMER_MODE_CONTINUOUS
,
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
))
);
cfg
=
IOADDR
(
A_SCD_TIMER_REGISTER
(
cpu
,
R_SCD_TIMER_CFG
));
____raw_writeq
(
tmode
,
cfg
);
cd
->
event_handler
(
cd
);
...
...
@@ -144,7 +134,9 @@ void __cpuinit sb1250_clockevent_init(void)
sb1250_mask_irq
(
cpu
,
irq
);
/* Map the timer interrupt to ip[4] of this cpu */
/*
* Map the timer interrupt to IP[4] of this cpu
*/
__raw_writeq
(
IMR_IP4_VAL
,
IOADDR
(
A_IMR_REGISTER
(
cpu
,
R_IMR_INTERRUPT_MAP_BASE
)
+
(
irq
<<
3
)));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment