2011-01-29 01:08:20 +03:00
/*
* sun4m irq support
2005-04-17 02:20:36 +04:00
*
* djhr : Hacked out of irq . c into a CPU dependent version .
*
* Copyright ( C ) 1995 David S . Miller ( davem @ caip . rutgers . edu )
* Copyright ( C ) 1995 Miguel de Icaza ( miguel @ nuclecu . unam . mx )
* Copyright ( C ) 1995 Pete A . Zaitcev ( zaitcev @ yahoo . com )
* Copyright ( C ) 1996 Dave Redman ( djhr @ tadpole . co . uk )
*/
# include <asm/timer.h>
# include <asm/traps.h>
# include <asm/pgalloc.h>
# include <asm/pgtable.h>
# include <asm/irq.h>
# include <asm/io.h>
# include <asm/cacheflush.h>
2007-07-22 06:18:57 +04:00
# include "irq.h"
2011-01-29 01:08:20 +03:00
# include "kernel.h"
/* Sample sun4m IRQ layout:
*
* 0x22 - Power
* 0x24 - ESP SCSI
* 0x26 - Lance ethernet
* 0x2b - Floppy
* 0x2c - Zilog uart
* 0x32 - SBUS level 0
* 0x33 - Parallel port , SBUS level 1
* 0x35 - SBUS level 2
* 0x37 - SBUS level 3
* 0x39 - Audio , Graphics card , SBUS level 4
* 0x3b - SBUS level 5
* 0x3d - SBUS level 6
*
* Each interrupt source has a mask bit in the interrupt registers .
* When the mask bit is set , this blocks interrupt deliver . So you
* clear the bit to enable the interrupt .
*
* Interrupts numbered less than 0x10 are software triggered interrupts
* and unused by Linux .
*
* Interrupt level assignment on sun4m :
*
* level source
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 1 softint - 1
* 2 softint - 2 , VME / SBUS level 1
* 3 softint - 3 , VME / SBUS level 2
* 4 softint - 4 , onboard SCSI
* 5 softint - 5 , VME / SBUS level 3
* 6 softint - 6 , onboard ETHERNET
* 7 softint - 7 , VME / SBUS level 4
* 8 softint - 8 , onboard VIDEO
* 9 softint - 9 , VME / SBUS level 5 , Module Interrupt
* 10 softint - 10 , system counter / timer
* 11 softint - 11 , VME / SBUS level 6 , Floppy
* 12 softint - 12 , Keyboard / Mouse , Serial
* 13 softint - 13 , VME / SBUS level 7 , ISDN Audio
* 14 softint - 14 , per - processor counter / timer
* 15 softint - 15 , Asynchronous Errors ( broadcast )
*
* Each interrupt source is masked distinctly in the sun4m interrupt
* registers . The PIL level alone is therefore ambiguous , since multiple
* interrupt sources map to a single PIL .
*
* This ambiguity is resolved in the ' intr ' property for device nodes
* in the OF device tree . Each ' intr ' property entry is composed of
* two 32 - bit words . The first word is the IRQ priority value , which
* is what we ' re intersted in . The second word is the IRQ vector , which
* is unused .
*
* The low 4 bits of the IRQ priority indicate the PIL , and the upper
* 4 bits indicate onboard vs . SBUS leveled vs . VME leveled . 0x20
* means onboard , 0x30 means SBUS leveled , and 0x40 means VME leveled .
*
* For example , an ' intr ' IRQ priority value of 0x24 is onboard SCSI
* whereas a value of 0x33 is SBUS level 2. Here are some sample
* ' intr ' property IRQ priority values from ss4 , ss5 , ss10 , ss20 , and
* Tadpole S3 GX systems .
*
* esp : 0x24 onboard ESP SCSI
* le : 0x26 onboard Lance ETHERNET
* p9100 : 0x32 SBUS level 1 P9100 video
* bpp : 0x33 SBUS level 2 BPP parallel port device
* DBRI : 0x39 SBUS level 5 DBRI ISDN audio
* SUNW , leo : 0x39 SBUS level 5 LEO video
* pcmcia : 0x3b SBUS level 6 PCMCIA controller
* uctrl : 0x3b SBUS level 6 UCTRL device
* modem : 0x3d SBUS level 7 MODEM
* zs : 0x2c onboard keyboard / mouse / serial
* floppy : 0x2b onboard Floppy
* power : 0x22 onboard power device ( XXX unknown mask bit XXX )
*/
2007-07-22 06:18:57 +04:00
2008-09-20 08:17:43 +04:00
/* Code in entry.S needs to get at these register mappings. */
struct sun4m_irq_percpu __iomem * sun4m_irq_percpu [ SUN4M_NCPUS ] ;
struct sun4m_irq_global __iomem * sun4m_irq_global ;
2005-04-17 02:20:36 +04:00
2011-04-18 15:25:44 +04:00
struct sun4m_handler_data {
bool percpu ;
long mask ;
} ;
2007-07-22 06:18:57 +04:00
/* Dave Redman (djhr@tadpole.co.uk)
* The sun4m interrupt registers .
*/
2011-01-29 01:08:20 +03:00
# define SUN4M_INT_ENABLE 0x80000000
# define SUN4M_INT_E14 0x00000080
# define SUN4M_INT_E10 0x00080000
2007-07-22 06:18:57 +04:00
# define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
# define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
2008-10-08 02:24:02 +04:00
# define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */
# define SUN4M_INT_ECC_ERR 0x10000000 /* ecc memory error */
# define SUN4M_INT_VME_ERR 0x08000000 /* vme async error */
2007-07-22 06:18:57 +04:00
# define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
# define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
# define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
# define SUN4M_INT_REALTIME 0x00080000 /* system timer */
# define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */
# define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */
# define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */
# define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
# define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */
# define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
2008-10-08 02:24:02 +04:00
# define SUN4M_INT_VMEBITS 0x0000007F /* vme int bits */
# define SUN4M_INT_ERROR (SUN4M_INT_MODULE_ERR | \
SUN4M_INT_M2S_WRITE_ERR | \
SUN4M_INT_ECC_ERR | \
SUN4M_INT_VME_ERR )
2007-07-22 06:18:57 +04:00
# define SUN4M_INT_SBUS(x) (1 << (x+7))
# define SUN4M_INT_VME(x) (1 << (x))
2008-10-08 02:24:02 +04:00
/* Interrupt levels used by OBP */
# define OBP_INT_LEVEL_SOFT 0x10
# define OBP_INT_LEVEL_ONBOARD 0x20
# define OBP_INT_LEVEL_SBUS 0x30
# define OBP_INT_LEVEL_VME 0x40
2011-02-26 10:02:11 +03:00
# define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
2011-04-18 15:25:44 +04:00
# define SUN4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14)
2011-02-26 10:02:11 +03:00
2011-04-18 15:25:44 +04:00
static unsigned long sun4m_imask [ 0x50 ] = {
2011-02-26 10:02:11 +03:00
/* 0x00 - SMP */
2008-10-08 02:24:02 +04:00
0 , SUN4M_SOFT_INT ( 1 ) ,
SUN4M_SOFT_INT ( 2 ) , SUN4M_SOFT_INT ( 3 ) ,
SUN4M_SOFT_INT ( 4 ) , SUN4M_SOFT_INT ( 5 ) ,
SUN4M_SOFT_INT ( 6 ) , SUN4M_SOFT_INT ( 7 ) ,
SUN4M_SOFT_INT ( 8 ) , SUN4M_SOFT_INT ( 9 ) ,
SUN4M_SOFT_INT ( 10 ) , SUN4M_SOFT_INT ( 11 ) ,
SUN4M_SOFT_INT ( 12 ) , SUN4M_SOFT_INT ( 13 ) ,
SUN4M_SOFT_INT ( 14 ) , SUN4M_SOFT_INT ( 15 ) ,
2011-02-26 10:02:11 +03:00
/* 0x10 - soft */
2008-10-08 02:24:02 +04:00
0 , SUN4M_SOFT_INT ( 1 ) ,
SUN4M_SOFT_INT ( 2 ) , SUN4M_SOFT_INT ( 3 ) ,
SUN4M_SOFT_INT ( 4 ) , SUN4M_SOFT_INT ( 5 ) ,
SUN4M_SOFT_INT ( 6 ) , SUN4M_SOFT_INT ( 7 ) ,
SUN4M_SOFT_INT ( 8 ) , SUN4M_SOFT_INT ( 9 ) ,
SUN4M_SOFT_INT ( 10 ) , SUN4M_SOFT_INT ( 11 ) ,
SUN4M_SOFT_INT ( 12 ) , SUN4M_SOFT_INT ( 13 ) ,
SUN4M_SOFT_INT ( 14 ) , SUN4M_SOFT_INT ( 15 ) ,
2011-02-26 10:02:11 +03:00
/* 0x20 - onboard */
2008-10-08 02:24:02 +04:00
0 , 0 , 0 , 0 ,
SUN4M_INT_SCSI , 0 , SUN4M_INT_ETHERNET , 0 ,
SUN4M_INT_VIDEO , SUN4M_INT_MODULE ,
SUN4M_INT_REALTIME , SUN4M_INT_FLOPPY ,
( SUN4M_INT_SERIAL | SUN4M_INT_KBDMS ) ,
2011-04-18 15:25:44 +04:00
SUN4M_INT_AUDIO , SUN4M_INT_E14 , SUN4M_INT_MODULE_ERR ,
2011-02-26 10:02:11 +03:00
/* 0x30 - sbus */
2008-10-08 02:24:02 +04:00
0 , 0 , SUN4M_INT_SBUS ( 0 ) , SUN4M_INT_SBUS ( 1 ) ,
0 , SUN4M_INT_SBUS ( 2 ) , 0 , SUN4M_INT_SBUS ( 3 ) ,
0 , SUN4M_INT_SBUS ( 4 ) , 0 , SUN4M_INT_SBUS ( 5 ) ,
0 , SUN4M_INT_SBUS ( 6 ) , 0 , 0 ,
2011-02-26 10:02:11 +03:00
/* 0x40 - vme */
2008-10-08 02:24:02 +04:00
0 , 0 , SUN4M_INT_VME ( 0 ) , SUN4M_INT_VME ( 1 ) ,
0 , SUN4M_INT_VME ( 2 ) , 0 , SUN4M_INT_VME ( 3 ) ,
0 , SUN4M_INT_VME ( 4 ) , 0 , SUN4M_INT_VME ( 5 ) ,
0 , SUN4M_INT_VME ( 6 ) , 0 , 0
2005-04-17 02:20:36 +04:00
} ;
2011-04-18 15:25:44 +04:00
static void sun4m_mask_irq ( struct irq_data * data )
2005-04-17 02:20:36 +04:00
{
2011-04-18 15:25:44 +04:00
struct sun4m_handler_data * handler_data = data - > handler_data ;
int cpu = smp_processor_id ( ) ;
2008-10-08 02:24:02 +04:00
2011-04-18 15:25:44 +04:00
if ( handler_data - > mask ) {
unsigned long flags ;
2008-10-08 02:24:02 +04:00
2011-04-18 15:25:44 +04:00
local_irq_save ( flags ) ;
if ( handler_data - > percpu ) {
sbus_writel ( handler_data - > mask , & sun4m_irq_percpu [ cpu ] - > set ) ;
} else {
sbus_writel ( handler_data - > mask , & sun4m_irq_global - > mask_set ) ;
}
local_irq_restore ( flags ) ;
}
2005-04-17 02:20:36 +04:00
}
2011-04-18 15:25:44 +04:00
static void sun4m_unmask_irq ( struct irq_data * data )
2005-04-17 02:20:36 +04:00
{
2011-04-18 15:25:44 +04:00
struct sun4m_handler_data * handler_data = data - > handler_data ;
2005-04-17 02:20:36 +04:00
int cpu = smp_processor_id ( ) ;
2011-04-18 15:25:44 +04:00
if ( handler_data - > mask ) {
unsigned long flags ;
2005-04-17 02:20:36 +04:00
local_irq_save ( flags ) ;
2011-04-18 15:25:44 +04:00
if ( handler_data - > percpu ) {
sbus_writel ( handler_data - > mask , & sun4m_irq_percpu [ cpu ] - > clear ) ;
} else {
sbus_writel ( handler_data - > mask , & sun4m_irq_global - > mask_clear ) ;
}
2005-04-17 02:20:36 +04:00
local_irq_restore ( flags ) ;
}
}
2011-04-18 15:25:44 +04:00
static unsigned int sun4m_startup_irq ( struct irq_data * data )
{
irq_link ( data - > irq ) ;
sun4m_unmask_irq ( data ) ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
2011-04-18 15:25:44 +04:00
static void sun4m_shutdown_irq ( struct irq_data * data )
2005-04-17 02:20:36 +04:00
{
2011-04-18 15:25:44 +04:00
sun4m_mask_irq ( data ) ;
irq_unlink ( data - > irq ) ;
2005-04-17 02:20:36 +04:00
}
2011-04-18 15:25:44 +04:00
static struct irq_chip sun4m_irq = {
. name = " sun4m " ,
. irq_startup = sun4m_startup_irq ,
. irq_shutdown = sun4m_shutdown_irq ,
. irq_mask = sun4m_mask_irq ,
. irq_unmask = sun4m_unmask_irq ,
} ;
static unsigned int sun4m_build_device_irq ( struct platform_device * op ,
unsigned int real_irq )
2005-04-17 02:20:36 +04:00
{
2011-04-18 15:25:44 +04:00
struct sun4m_handler_data * handler_data ;
unsigned int irq ;
unsigned int pil ;
if ( real_irq > = OBP_INT_LEVEL_VME ) {
prom_printf ( " Bogus sun4m IRQ %u \n " , real_irq ) ;
prom_halt ( ) ;
}
pil = ( real_irq & 0xf ) ;
irq = irq_alloc ( real_irq , pil ) ;
if ( irq = = 0 )
goto out ;
handler_data = irq_get_handler_data ( irq ) ;
if ( unlikely ( handler_data ) )
goto out ;
handler_data = kzalloc ( sizeof ( struct sun4m_handler_data ) , GFP_ATOMIC ) ;
if ( unlikely ( ! handler_data ) ) {
prom_printf ( " IRQ: kzalloc(sun4m_handler_data) failed. \n " ) ;
prom_halt ( ) ;
}
handler_data - > mask = sun4m_imask [ real_irq ] ;
handler_data - > percpu = real_irq < OBP_INT_LEVEL_ONBOARD ;
irq_set_chip_and_handler_name ( irq , & sun4m_irq ,
handle_level_irq , " level " ) ;
irq_set_handler_data ( irq , handler_data ) ;
out :
return irq ;
2005-04-17 02:20:36 +04:00
}
2008-09-12 10:08:30 +04:00
struct sun4m_timer_percpu {
u32 l14_limit ;
u32 l14_count ;
u32 l14_limit_noclear ;
u32 user_timer_start_stop ;
} ;
static struct sun4m_timer_percpu __iomem * timers_percpu [ SUN4M_NCPUS ] ;
struct sun4m_timer_global {
u32 l10_limit ;
u32 l10_count ;
u32 l10_limit_noclear ;
u32 reserved ;
u32 timer_config ;
} ;
static struct sun4m_timer_global __iomem * timers_global ;
2005-04-17 02:20:36 +04:00
static void sun4m_clear_clock_irq ( void )
{
2008-09-12 10:08:30 +04:00
sbus_readl ( & timers_global - > l10_limit ) ;
2005-04-17 02:20:36 +04:00
}
2008-10-08 02:24:02 +04:00
void sun4m_nmi ( struct pt_regs * regs )
{
unsigned long afsr , afar , si ;
printk ( KERN_ERR " Aieee: sun4m NMI received! \n " ) ;
/* XXX HyperSparc hack XXX */
__asm__ __volatile__ ( " mov 0x500, %%g1 \n \t "
" lda [%%g1] 0x4, %0 \n \t "
" mov 0x600, %%g1 \n \t "
" lda [%%g1] 0x4, %1 \n \t " :
" =r " ( afsr ) , " =r " ( afar ) ) ;
printk ( KERN_ERR " afsr=%08lx afar=%08lx \n " , afsr , afar ) ;
si = sbus_readl ( & sun4m_irq_global - > pending ) ;
printk ( KERN_ERR " si=%08lx \n " , si ) ;
if ( si & SUN4M_INT_MODULE_ERR )
printk ( KERN_ERR " Module async error \n " ) ;
if ( si & SUN4M_INT_M2S_WRITE_ERR )
printk ( KERN_ERR " MBus/SBus async error \n " ) ;
if ( si & SUN4M_INT_ECC_ERR )
printk ( KERN_ERR " ECC memory error \n " ) ;
if ( si & SUN4M_INT_VME_ERR )
printk ( KERN_ERR " VME async error \n " ) ;
printk ( KERN_ERR " you lose buddy boy... \n " ) ;
show_regs ( regs ) ;
prom_halt ( ) ;
}
2011-04-18 15:25:44 +04:00
void sun4m_unmask_profile_irq ( void )
{
unsigned long flags ;
local_irq_save ( flags ) ;
sbus_writel ( sun4m_imask [ SUN4M_PROFILE_IRQ ] , & sun4m_irq_global - > mask_clear ) ;
local_irq_restore ( flags ) ;
}
2008-09-14 09:07:56 +04:00
void sun4m_clear_profile_irq ( int cpu )
2005-04-17 02:20:36 +04:00
{
2008-09-12 10:08:30 +04:00
sbus_readl ( & timers_percpu [ cpu ] - > l14_limit ) ;
2005-04-17 02:20:36 +04:00
}
static void sun4m_load_profile_irq ( int cpu , unsigned int limit )
{
2012-04-04 23:49:26 +04:00
unsigned int value = limit ? timer_value ( limit ) : 0 ;
sbus_writel ( value , & timers_percpu [ cpu ] - > l14_limit ) ;
2005-04-17 02:20:36 +04:00
}
2012-04-04 23:49:26 +04:00
static void __init sun4m_init_timers ( void )
2005-04-17 02:20:36 +04:00
{
2008-09-12 10:08:30 +04:00
struct device_node * dp = of_find_node_by_name ( NULL , " counter " ) ;
int i , err , len , num_cpu_timers ;
2011-04-18 15:25:44 +04:00
unsigned int irq ;
2008-09-12 10:08:30 +04:00
const u32 * addr ;
if ( ! dp ) {
printk ( KERN_ERR " sun4m_init_timers: No 'counter' node. \n " ) ;
return ;
2005-04-17 02:20:36 +04:00
}
2008-09-12 10:08:30 +04:00
addr = of_get_property ( dp , " address " , & len ) ;
2008-12-04 08:10:57 +03:00
of_node_put ( dp ) ;
2008-09-12 10:08:30 +04:00
if ( ! addr ) {
printk ( KERN_ERR " sun4m_init_timers: No 'address' prop. \n " ) ;
return ;
2005-04-17 02:20:36 +04:00
}
2008-09-12 10:08:30 +04:00
num_cpu_timers = ( len / sizeof ( u32 ) ) - 1 ;
for ( i = 0 ; i < num_cpu_timers ; i + + ) {
timers_percpu [ i ] = ( void __iomem * )
( unsigned long ) addr [ i ] ;
2005-04-17 02:20:36 +04:00
}
2008-09-12 10:08:30 +04:00
timers_global = ( void __iomem * )
( unsigned long ) addr [ num_cpu_timers ] ;
2012-01-10 17:17:03 +04:00
/* Every per-cpu timer works in timer mode */
sbus_writel ( 0x00000000 , & timers_global - > timer_config ) ;
2012-04-04 23:49:26 +04:00
# ifdef CONFIG_SMP
sparc_config . cs_period = SBUS_CLOCK_RATE * 2 ; /* 2 seconds */
sparc_config . features | = FEAT_L14_ONESHOT ;
# else
sparc_config . cs_period = SBUS_CLOCK_RATE / HZ ; /* 1/HZ sec */
sparc_config . features | = FEAT_L10_CLOCKEVENT ;
# endif
sparc_config . features | = FEAT_L10_CLOCKSOURCE ;
sbus_writel ( timer_value ( sparc_config . cs_period ) ,
& timers_global - > l10_limit ) ;
2008-09-12 10:08:30 +04:00
master_l10_counter = & timers_global - > l10_count ;
2011-04-18 15:25:44 +04:00
irq = sun4m_build_device_irq ( NULL , SUN4M_TIMER_IRQ ) ;
2012-04-04 23:49:26 +04:00
err = request_irq ( irq , timer_interrupt , IRQF_TIMER , " timer " , NULL ) ;
2008-09-12 10:08:30 +04:00
if ( err ) {
printk ( KERN_ERR " sun4m_init_timers: Register IRQ error %d. \n " ,
err ) ;
return ;
2005-04-17 02:20:36 +04:00
}
2008-09-12 10:08:30 +04:00
for ( i = 0 ; i < num_cpu_timers ; i + + )
sbus_writel ( 0 , & timers_percpu [ i ] - > l14_limit ) ;
if ( num_cpu_timers = = 4 )
2008-09-20 08:17:43 +04:00
sbus_writel ( SUN4M_INT_E14 , & sun4m_irq_global - > mask_set ) ;
2008-09-12 10:08:30 +04:00
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_SMP
{
unsigned long flags ;
struct tt_entry * trap_table = & sparc_ttable [ SP_TRAP_IRQ1 + ( 14 - 1 ) ] ;
/* For SMP we use the level 14 ticker, however the bootup code
2007-05-12 00:51:23 +04:00
* has copied the firmware ' s level 14 vector into the boot cpu ' s
2005-04-17 02:20:36 +04:00
* trap table , we must fix this now or we get squashed .
*/
local_irq_save ( flags ) ;
trap_table - > inst_one = lvl14_save [ 0 ] ;
trap_table - > inst_two = lvl14_save [ 1 ] ;
trap_table - > inst_three = lvl14_save [ 2 ] ;
trap_table - > inst_four = lvl14_save [ 3 ] ;
2012-05-14 07:49:31 +04:00
local_ops - > cache_all ( ) ;
2005-04-17 02:20:36 +04:00
local_irq_restore ( flags ) ;
}
# endif
}
void __init sun4m_init_IRQ ( void )
{
2008-09-20 08:17:43 +04:00
struct device_node * dp = of_find_node_by_name ( NULL , " interrupt " ) ;
int len , i , mid , num_cpu_iregs ;
const u32 * addr ;
if ( ! dp ) {
printk ( KERN_ERR " sun4m_init_IRQ: No 'interrupt' node. \n " ) ;
return ;
2005-04-17 02:20:36 +04:00
}
2008-09-20 08:17:43 +04:00
addr = of_get_property ( dp , " address " , & len ) ;
2008-12-04 08:10:57 +03:00
of_node_put ( dp ) ;
2008-09-20 08:17:43 +04:00
if ( ! addr ) {
printk ( KERN_ERR " sun4m_init_IRQ: No 'address' prop. \n " ) ;
return ;
2005-04-17 02:20:36 +04:00
}
2008-09-20 08:17:43 +04:00
num_cpu_iregs = ( len / sizeof ( u32 ) ) - 1 ;
for ( i = 0 ; i < num_cpu_iregs ; i + + ) {
sun4m_irq_percpu [ i ] = ( void __iomem * )
( unsigned long ) addr [ i ] ;
}
sun4m_irq_global = ( void __iomem * )
( unsigned long ) addr [ num_cpu_iregs ] ;
2005-04-17 02:20:36 +04:00
2008-09-20 08:17:43 +04:00
local_irq_disable ( ) ;
2005-04-17 02:20:36 +04:00
2008-09-20 08:17:43 +04:00
sbus_writel ( ~ SUN4M_INT_MASKALL , & sun4m_irq_global - > mask_set ) ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; ! cpu_find_by_instance ( i , NULL , & mid ) ; i + + )
2008-09-20 08:17:43 +04:00
sbus_writel ( ~ 0x17fff , & sun4m_irq_percpu [ mid ] - > clear ) ;
2008-09-14 09:48:41 +04:00
if ( num_cpu_iregs = = 4 )
2008-09-20 08:17:43 +04:00
sbus_writel ( 0 , & sun4m_irq_global - > interrupt_target ) ;
2008-09-14 09:48:41 +04:00
2012-05-14 19:30:35 +04:00
sparc_config . init_timers = sun4m_init_timers ;
2012-04-04 15:21:13 +04:00
sparc_config . build_device_irq = sun4m_build_device_irq ;
2012-04-04 23:49:26 +04:00
sparc_config . clock_rate = SBUS_CLOCK_RATE ;
2012-05-14 19:30:35 +04:00
sparc_config . clear_clock_irq = sun4m_clear_clock_irq ;
sparc_config . load_profile_irq = sun4m_load_profile_irq ;
2011-02-26 10:00:19 +03:00
2005-04-17 02:20:36 +04:00
/* Cannot enable interrupts until OBP ticker is disabled. */
}