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
nexedi
linux
Commits
41bd61a8
Commit
41bd61a8
authored
Oct 15, 2007
by
Ralf Baechle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MIPS] Alchemy: cleanup interrupt code.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
a5ccfe5c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
313 additions
and
341 deletions
+313
-341
arch/mips/au1000/common/irq.c
arch/mips/au1000/common/irq.c
+313
-341
No files found.
arch/mips/au1000/common/irq.c
View file @
41bd61a8
...
@@ -26,39 +26,18 @@
...
@@ -26,39 +26,18 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <linux/
errno
.h>
#include <linux/
bitops
.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_MIPS_PB1000
#ifdef CONFIG_MIPS_PB1000
#include <asm/mach-pb1x00/pb1000.h>
#include <asm/mach-pb1x00/pb1000.h>
#endif
#endif
#undef DEBUG_IRQ
#ifdef DEBUG_IRQ
/* note: prints function name for you */
#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK(fmt, args...)
#endif
#define EXT_INTC0_REQ0 2
/* IP 2 */
#define EXT_INTC0_REQ0 2
/* IP 2 */
#define EXT_INTC0_REQ1 3
/* IP 3 */
#define EXT_INTC0_REQ1 3
/* IP 3 */
#define EXT_INTC1_REQ0 4
/* IP 4 */
#define EXT_INTC1_REQ0 4
/* IP 4 */
...
@@ -69,16 +48,98 @@ void (*board_init_irq)(void);
...
@@ -69,16 +48,98 @@ void (*board_init_irq)(void);
static
DEFINE_SPINLOCK
(
irq_lock
);
static
DEFINE_SPINLOCK
(
irq_lock
);
#ifdef CONFIG_PM
/*
* Save/restore the interrupt controller state.
* Called from the save/restore core registers as part of the
* au_sleep function in power.c.....maybe I should just pm_register()
* them instead?
*/
static
unsigned
int
sleep_intctl_config0
[
2
];
static
unsigned
int
sleep_intctl_config1
[
2
];
static
unsigned
int
sleep_intctl_config2
[
2
];
static
unsigned
int
sleep_intctl_src
[
2
];
static
unsigned
int
sleep_intctl_assign
[
2
];
static
unsigned
int
sleep_intctl_wake
[
2
];
static
unsigned
int
sleep_intctl_mask
[
2
];
void
save_au1xxx_intctl
(
void
)
{
sleep_intctl_config0
[
0
]
=
au_readl
(
IC0_CFG0RD
);
sleep_intctl_config1
[
0
]
=
au_readl
(
IC0_CFG1RD
);
sleep_intctl_config2
[
0
]
=
au_readl
(
IC0_CFG2RD
);
sleep_intctl_src
[
0
]
=
au_readl
(
IC0_SRCRD
);
sleep_intctl_assign
[
0
]
=
au_readl
(
IC0_ASSIGNRD
);
sleep_intctl_wake
[
0
]
=
au_readl
(
IC0_WAKERD
);
sleep_intctl_mask
[
0
]
=
au_readl
(
IC0_MASKRD
);
sleep_intctl_config0
[
1
]
=
au_readl
(
IC1_CFG0RD
);
sleep_intctl_config1
[
1
]
=
au_readl
(
IC1_CFG1RD
);
sleep_intctl_config2
[
1
]
=
au_readl
(
IC1_CFG2RD
);
sleep_intctl_src
[
1
]
=
au_readl
(
IC1_SRCRD
);
sleep_intctl_assign
[
1
]
=
au_readl
(
IC1_ASSIGNRD
);
sleep_intctl_wake
[
1
]
=
au_readl
(
IC1_WAKERD
);
sleep_intctl_mask
[
1
]
=
au_readl
(
IC1_MASKRD
);
}
/*
* For most restore operations, we clear the entire register and
* then set the bits we found during the save.
*/
void
restore_au1xxx_intctl
(
void
)
{
au_writel
(
0xffffffff
,
IC0_MASKCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG0CLR
);
au_sync
();
au_writel
(
sleep_intctl_config0
[
0
],
IC0_CFG0SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG1CLR
);
au_sync
();
au_writel
(
sleep_intctl_config1
[
0
],
IC0_CFG1SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG2CLR
);
au_sync
();
au_writel
(
sleep_intctl_config2
[
0
],
IC0_CFG2SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_SRCCLR
);
au_sync
();
au_writel
(
sleep_intctl_src
[
0
],
IC0_SRCSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_ASSIGNCLR
);
au_sync
();
au_writel
(
sleep_intctl_assign
[
0
],
IC0_ASSIGNSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_WAKECLR
);
au_sync
();
au_writel
(
sleep_intctl_wake
[
0
],
IC0_WAKESET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_RISINGCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_FALLINGCLR
);
au_sync
();
au_writel
(
0x00000000
,
IC0_TESTBIT
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_MASKCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG0CLR
);
au_sync
();
au_writel
(
sleep_intctl_config0
[
1
],
IC1_CFG0SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG1CLR
);
au_sync
();
au_writel
(
sleep_intctl_config1
[
1
],
IC1_CFG1SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG2CLR
);
au_sync
();
au_writel
(
sleep_intctl_config2
[
1
],
IC1_CFG2SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_SRCCLR
);
au_sync
();
au_writel
(
sleep_intctl_src
[
1
],
IC1_SRCSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_ASSIGNCLR
);
au_sync
();
au_writel
(
sleep_intctl_assign
[
1
],
IC1_ASSIGNSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_WAKECLR
);
au_sync
();
au_writel
(
sleep_intctl_wake
[
1
],
IC1_WAKESET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_RISINGCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_FALLINGCLR
);
au_sync
();
au_writel
(
0x00000000
,
IC1_TESTBIT
);
au_sync
();
au_writel
(
sleep_intctl_mask
[
1
],
IC1_MASKSET
);
au_sync
();
au_writel
(
sleep_intctl_mask
[
0
],
IC0_MASKSET
);
au_sync
();
}
#endif
/* CONFIG_PM */
inline
void
local_enable_irq
(
unsigned
int
irq_nr
)
inline
void
local_enable_irq
(
unsigned
int
irq_nr
)
{
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKESET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKESET
);
}
}
else
{
else
{
au_writel
(
1
<<
irq_nr
,
IC0_MASKSET
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKSET
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKESET
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKESET
);
}
}
au_sync
();
au_sync
();
}
}
...
@@ -87,12 +148,11 @@ inline void local_enable_irq(unsigned int irq_nr)
...
@@ -87,12 +148,11 @@ inline void local_enable_irq(unsigned int irq_nr)
inline
void
local_disable_irq
(
unsigned
int
irq_nr
)
inline
void
local_disable_irq
(
unsigned
int
irq_nr
)
{
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKECLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKECLR
);
}
}
else
{
else
{
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKECLR
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKECLR
);
}
}
au_sync
();
au_sync
();
}
}
...
@@ -101,12 +161,11 @@ inline void local_disable_irq(unsigned int irq_nr)
...
@@ -101,12 +161,11 @@ inline void local_disable_irq(unsigned int irq_nr)
static
inline
void
mask_and_ack_rise_edge_irq
(
unsigned
int
irq_nr
)
static
inline
void
mask_and_ack_rise_edge_irq
(
unsigned
int
irq_nr
)
{
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_RISINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_RISINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
}
}
else
{
else
{
au_writel
(
1
<<
irq_nr
,
IC0_RISINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_RISINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
}
}
au_sync
();
au_sync
();
}
}
...
@@ -115,12 +174,11 @@ static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
...
@@ -115,12 +174,11 @@ static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
static
inline
void
mask_and_ack_fall_edge_irq
(
unsigned
int
irq_nr
)
static
inline
void
mask_and_ack_fall_edge_irq
(
unsigned
int
irq_nr
)
{
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_FALLINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_FALLINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
}
}
else
{
else
{
au_writel
(
1
<<
irq_nr
,
IC0_FALLINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_FALLINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
}
}
au_sync
();
au_sync
();
}
}
...
@@ -132,14 +190,13 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
...
@@ -132,14 +190,13 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
* both edges at once, or if we do, that we don't care.
* both edges at once, or if we do, that we don't care.
*/
*/
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_FALLINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_FALLINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_RISINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_RISINGCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
}
}
else
{
else
{
au_writel
(
1
<<
irq_nr
,
IC0_FALLINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_FALLINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_RISINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_RISINGCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
}
}
au_sync
();
au_sync
();
}
}
...
@@ -162,9 +219,9 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr)
...
@@ -162,9 +219,9 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr)
static
void
end_irq
(
unsigned
int
irq_nr
)
static
void
end_irq
(
unsigned
int
irq_nr
)
{
{
if
(
!
(
irq_desc
[
irq_nr
].
status
&
(
IRQ_DISABLED
|
IRQ_INPROGRESS
)))
{
if
(
!
(
irq_desc
[
irq_nr
].
status
&
(
IRQ_DISABLED
|
IRQ_INPROGRESS
)))
local_enable_irq
(
irq_nr
);
local_enable_irq
(
irq_nr
);
}
#if defined(CONFIG_MIPS_PB1000)
#if defined(CONFIG_MIPS_PB1000)
if
(
irq_nr
==
AU1000_GPIO_15
)
{
if
(
irq_nr
==
AU1000_GPIO_15
)
{
au_writel
(
0x4000
,
PB1000_MDR
);
/* enable int */
au_writel
(
0x4000
,
PB1000_MDR
);
/* enable int */
...
@@ -181,15 +238,12 @@ unsigned long save_local_and_disable(int controller)
...
@@ -181,15 +238,12 @@ unsigned long save_local_and_disable(int controller)
spin_lock_irqsave
(
&
irq_lock
,
flags
);
spin_lock_irqsave
(
&
irq_lock
,
flags
);
if
(
controller
)
{
if
(
controller
)
{
mask
=
au_readl
(
IC1_MASKSET
);
mask
=
au_readl
(
IC1_MASKSET
);
for
(
i
=
32
;
i
<
64
;
i
++
)
{
for
(
i
=
32
;
i
<
64
;
i
++
)
local_disable_irq
(
i
);
local_disable_irq
(
i
);
}
}
else
{
}
else
{
mask
=
au_readl
(
IC0_MASKSET
);
mask
=
au_readl
(
IC0_MASKSET
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
local_disable_irq
(
i
);
local_disable_irq
(
i
);
}
}
}
spin_unlock_irqrestore
(
&
irq_lock
,
flags
);
spin_unlock_irqrestore
(
&
irq_lock
,
flags
);
...
@@ -202,10 +256,10 @@ void restore_local_and_enable(int controller, unsigned long mask)
...
@@ -202,10 +256,10 @@ void restore_local_and_enable(int controller, unsigned long mask)
unsigned
long
flags
,
new_mask
;
unsigned
long
flags
,
new_mask
;
spin_lock_irqsave
(
&
irq_lock
,
flags
);
spin_lock_irqsave
(
&
irq_lock
,
flags
);
for
(
i
=
0
;
i
<
32
;
i
++
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
mask
&
(
1
<<
i
))
{
if
(
mask
&
(
1
<<
i
))
{
if
(
controller
)
if
(
controller
)
local_enable_irq
(
i
+
32
);
local_enable_irq
(
i
+
32
);
else
else
local_enable_irq
(
i
);
local_enable_irq
(
i
);
}
}
...
@@ -220,39 +274,39 @@ void restore_local_and_enable(int controller, unsigned long mask)
...
@@ -220,39 +274,39 @@ void restore_local_and_enable(int controller, unsigned long mask)
static
struct
irq_chip
rise_edge_irq_type
=
{
static
struct
irq_chip
rise_edge_irq_type
=
{
.
name
=
"Au1000 Rise Edge"
,
.
name
=
"Au1000 Rise Edge"
,
.
ack
=
mask_and_ack_rise_edge_irq
,
.
ack
=
mask_and_ack_rise_edge_irq
,
.
mask
=
local_disable_irq
,
.
mask
=
local_disable_irq
,
.
mask_ack
=
mask_and_ack_rise_edge_irq
,
.
mask_ack
=
mask_and_ack_rise_edge_irq
,
.
unmask
=
local_enable_irq
,
.
unmask
=
local_enable_irq
,
.
end
=
end_irq
,
.
end
=
end_irq
,
};
};
static
struct
irq_chip
fall_edge_irq_type
=
{
static
struct
irq_chip
fall_edge_irq_type
=
{
.
name
=
"Au1000 Fall Edge"
,
.
name
=
"Au1000 Fall Edge"
,
.
ack
=
mask_and_ack_fall_edge_irq
,
.
ack
=
mask_and_ack_fall_edge_irq
,
.
mask
=
local_disable_irq
,
.
mask
=
local_disable_irq
,
.
mask_ack
=
mask_and_ack_fall_edge_irq
,
.
mask_ack
=
mask_and_ack_fall_edge_irq
,
.
unmask
=
local_enable_irq
,
.
unmask
=
local_enable_irq
,
.
end
=
end_irq
,
.
end
=
end_irq
,
};
};
static
struct
irq_chip
either_edge_irq_type
=
{
static
struct
irq_chip
either_edge_irq_type
=
{
.
name
=
"Au1000 Rise or Fall Edge"
,
.
name
=
"Au1000 Rise or Fall Edge"
,
.
ack
=
mask_and_ack_either_edge_irq
,
.
ack
=
mask_and_ack_either_edge_irq
,
.
mask
=
local_disable_irq
,
.
mask
=
local_disable_irq
,
.
mask_ack
=
mask_and_ack_either_edge_irq
,
.
mask_ack
=
mask_and_ack_either_edge_irq
,
.
unmask
=
local_enable_irq
,
.
unmask
=
local_enable_irq
,
.
end
=
end_irq
,
.
end
=
end_irq
,
};
};
static
struct
irq_chip
level_irq_type
=
{
static
struct
irq_chip
level_irq_type
=
{
.
name
=
"Au1000 Level"
,
.
name
=
"Au1000 Level"
,
.
ack
=
mask_and_ack_level_irq
,
.
ack
=
mask_and_ack_level_irq
,
.
mask
=
local_disable_irq
,
.
mask
=
local_disable_irq
,
.
mask_ack
=
mask_and_ack_level_irq
,
.
mask_ack
=
mask_and_ack_level_irq
,
.
unmask
=
local_enable_irq
,
.
unmask
=
local_enable_irq
,
.
end
=
end_irq
,
.
end
=
end_irq
,
};
};
#ifdef CONFIG_PM
#ifdef CONFIG_PM
...
@@ -263,7 +317,8 @@ void startup_match20_interrupt(irq_handler_t handler)
...
@@ -263,7 +317,8 @@ void startup_match20_interrupt(irq_handler_t handler)
static
struct
irqaction
action
;
static
struct
irqaction
action
;
memset
(
&
action
,
0
,
sizeof
(
struct
irqaction
));
memset
(
&
action
,
0
,
sizeof
(
struct
irqaction
));
/* This is a big problem.... since we didn't use request_irq
/*
* This is a big problem.... since we didn't use request_irq
* when kernel/irq.c calls probe_irq_xxx this interrupt will
* when kernel/irq.c calls probe_irq_xxx this interrupt will
* be probed for usage. This will end up disabling the device :(
* be probed for usage. This will end up disabling the device :(
* Give it a bogus "action" pointer -- this will keep it from
* Give it a bogus "action" pointer -- this will keep it from
...
@@ -292,173 +347,112 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
...
@@ -292,173 +347,112 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
/* Config2[n], Config1[n], Config0[n] */
/* Config2[n], Config1[n], Config0[n] */
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
if
(
irq_nr
>
AU1000_LAST_INTC0_INT
)
{
switch
(
type
)
{
switch
(
type
)
{
case
INTC_INT_RISE_EDGE
:
/* 0:0:1 */
case
INTC_INT_RISE_EDGE
:
/* 0:0:1 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
rise_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
rise_edge_irq_type
);
break
;
break
;
case
INTC_INT_FALL_EDGE
:
/* 0:1:0 */
case
INTC_INT_FALL_EDGE
:
/* 0:1:0 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
set_irq_chip
(
irq_nr
,
&
fall_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
fall_edge_irq_type
);
break
;
break
;
case
INTC_INT_RISE_AND_FALL_EDGE
:
/* 0:1:1 */
case
INTC_INT_RISE_AND_FALL_EDGE
:
/* 0:1:1 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
either_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
either_edge_irq_type
);
break
;
break
;
case
INTC_INT_HIGH_LEVEL
:
/* 1:0:1 */
case
INTC_INT_HIGH_LEVEL
:
/* 1:0:1 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
break
;
break
;
case
INTC_INT_LOW_LEVEL
:
/* 1:1:0 */
case
INTC_INT_LOW_LEVEL
:
/* 1:1:0 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1SET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
break
;
break
;
case
INTC_INT_DISABLED
:
/* 0:0:0 */
case
INTC_INT_DISABLED
:
/* 0:0:0 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
break
;
break
;
default:
/* disable the interrupt */
default:
/* disable the interrupt */
printk
(
"unexpected int type %d (irq %d)
\n
"
,
type
,
irq_nr
);
printk
(
KERN_WARNING
"unexpected int type %d (irq %d)
\n
"
,
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
type
,
irq_nr
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG0CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG1CLR
);
return
;
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_CFG2CLR
);
return
;
}
}
if
(
int_req
)
/* assign to interrupt request 1 */
if
(
int_req
)
/* assign to interrupt request 1 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_ASSIGNCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_ASSIGNCLR
);
else
/* assign to interrupt request 0 */
else
/* assign to interrupt request 0 */
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_ASSIGNSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_ASSIGNSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_SRCSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_SRCSET
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_MASKCLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKECLR
);
au_writel
(
1
<<
(
irq_nr
-
32
),
IC1_WAKECLR
);
}
}
else
{
else
{
switch
(
type
)
{
switch
(
type
)
{
case
INTC_INT_RISE_EDGE
:
/* 0:0:1 */
case
INTC_INT_RISE_EDGE
:
/* 0:0:1 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
rise_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
rise_edge_irq_type
);
break
;
break
;
case
INTC_INT_FALL_EDGE
:
/* 0:1:0 */
case
INTC_INT_FALL_EDGE
:
/* 0:1:0 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
set_irq_chip
(
irq_nr
,
&
fall_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
fall_edge_irq_type
);
break
;
break
;
case
INTC_INT_RISE_AND_FALL_EDGE
:
/* 0:1:1 */
case
INTC_INT_RISE_AND_FALL_EDGE
:
/* 0:1:1 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
either_edge_irq_type
);
set_irq_chip
(
irq_nr
,
&
either_edge_irq_type
);
break
;
break
;
case
INTC_INT_HIGH_LEVEL
:
/* 1:0:1 */
case
INTC_INT_HIGH_LEVEL
:
/* 1:0:1 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG2SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0SET
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
break
;
break
;
case
INTC_INT_LOW_LEVEL
:
/* 1:1:0 */
case
INTC_INT_LOW_LEVEL
:
/* 1:1:0 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG2SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1SET
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
set_irq_chip
(
irq_nr
,
&
level_irq_type
);
break
;
break
;
case
INTC_INT_DISABLED
:
/* 0:0:0 */
case
INTC_INT_DISABLED
:
/* 0:0:0 */
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
break
;
break
;
default:
/* disable the interrupt */
default:
/* disable the interrupt */
printk
(
"unexpected int type %d (irq %d)
\n
"
,
type
,
irq_nr
);
printk
(
KERN_WARNING
"unexpected int type %d (irq %d)
\n
"
,
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
type
,
irq_nr
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG0CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
au_writel
(
1
<<
irq_nr
,
IC0_CFG1CLR
);
return
;
au_writel
(
1
<<
irq_nr
,
IC0_CFG2CLR
);
return
;
}
}
if
(
int_req
)
/* assign to interrupt request 1 */
if
(
int_req
)
/* assign to interrupt request 1 */
au_writel
(
1
<<
irq_nr
,
IC0_ASSIGNCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_ASSIGNCLR
);
else
/* assign to interrupt request 0 */
else
/* assign to interrupt request 0 */
au_writel
(
1
<<
irq_nr
,
IC0_ASSIGNSET
);
au_writel
(
1
<<
irq_nr
,
IC0_ASSIGNSET
);
au_writel
(
1
<<
irq_nr
,
IC0_SRCSET
);
au_writel
(
1
<<
irq_nr
,
IC0_SRCSET
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_MASKCLR
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKECLR
);
au_writel
(
1
<<
irq_nr
,
IC0_WAKECLR
);
}
}
au_sync
();
au_sync
();
}
}
void
__init
arch_init_irq
(
void
)
{
int
i
;
unsigned
long
cp0_status
;
au1xxx_irq_map_t
*
imp
;
extern
au1xxx_irq_map_t
au1xxx_irq_map
[];
extern
au1xxx_irq_map_t
au1xxx_ic0_map
[];
extern
int
au1xxx_nr_irqs
;
extern
int
au1xxx_ic0_nr_irqs
;
cp0_status
=
read_c0_status
();
/* Initialize interrupt controllers to a safe state.
*/
au_writel
(
0xffffffff
,
IC0_CFG0CLR
);
au_writel
(
0xffffffff
,
IC0_CFG1CLR
);
au_writel
(
0xffffffff
,
IC0_CFG2CLR
);
au_writel
(
0xffffffff
,
IC0_MASKCLR
);
au_writel
(
0xffffffff
,
IC0_ASSIGNSET
);
au_writel
(
0xffffffff
,
IC0_WAKECLR
);
au_writel
(
0xffffffff
,
IC0_SRCSET
);
au_writel
(
0xffffffff
,
IC0_FALLINGCLR
);
au_writel
(
0xffffffff
,
IC0_RISINGCLR
);
au_writel
(
0x00000000
,
IC0_TESTBIT
);
au_writel
(
0xffffffff
,
IC1_CFG0CLR
);
au_writel
(
0xffffffff
,
IC1_CFG1CLR
);
au_writel
(
0xffffffff
,
IC1_CFG2CLR
);
au_writel
(
0xffffffff
,
IC1_MASKCLR
);
au_writel
(
0xffffffff
,
IC1_ASSIGNSET
);
au_writel
(
0xffffffff
,
IC1_WAKECLR
);
au_writel
(
0xffffffff
,
IC1_SRCSET
);
au_writel
(
0xffffffff
,
IC1_FALLINGCLR
);
au_writel
(
0xffffffff
,
IC1_RISINGCLR
);
au_writel
(
0x00000000
,
IC1_TESTBIT
);
/* Initialize IC0, which is fixed per processor.
*/
imp
=
au1xxx_ic0_map
;
for
(
i
=
0
;
i
<
au1xxx_ic0_nr_irqs
;
i
++
)
{
setup_local_irq
(
imp
->
im_irq
,
imp
->
im_type
,
imp
->
im_request
);
imp
++
;
}
/* Now set up the irq mapping for the board.
*/
imp
=
au1xxx_irq_map
;
for
(
i
=
0
;
i
<
au1xxx_nr_irqs
;
i
++
)
{
setup_local_irq
(
imp
->
im_irq
,
imp
->
im_type
,
imp
->
im_request
);
imp
++
;
}
set_c0_status
(
ALLINTS
);
/* Board specific IRQ initialization.
*/
if
(
board_init_irq
)
(
*
board_init_irq
)();
}
/*
/*
* Interrupts are nested. Even if an interrupt handler is registered
* Interrupts are nested. Even if an interrupt handler is registered
* as "fast", we might get another interrupt before we return from
* as "fast", we might get another interrupt before we return from
...
@@ -468,26 +462,27 @@ void __init arch_init_irq(void)
...
@@ -468,26 +462,27 @@ void __init arch_init_irq(void)
static
void
intc0_req0_irqdispatch
(
void
)
static
void
intc0_req0_irqdispatch
(
void
)
{
{
int
irq
=
0
;
int
irq
=
0
;
static
unsigned
long
intc0_req0
=
0
;
static
unsigned
long
intc0_req0
;
intc0_req0
|=
au_readl
(
IC0_REQ0INT
);
intc0_req0
|=
au_readl
(
IC0_REQ0INT
);
if
(
!
intc0_req0
)
if
(
!
intc0_req0
)
return
;
return
;
#ifdef AU1000_USB_DEV_REQ_INT
#ifdef AU1000_USB_DEV_REQ_INT
/*
/*
* Because of the tight timing of SETUP token to reply
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
* transactions, the USB devices-side packet complete
* interrupt needs the highest priority.
* interrupt needs the highest priority.
*/
*/
if
((
intc0_req0
&
(
1
<<
AU1000_USB_DEV_REQ_INT
)))
{
if
((
intc0_req0
&
(
1
<<
AU1000_USB_DEV_REQ_INT
)))
{
intc0_req0
&=
~
(
1
<<
AU1000_USB_DEV_REQ_INT
);
intc0_req0
&=
~
(
1
<<
AU1000_USB_DEV_REQ_INT
);
do_IRQ
(
AU1000_USB_DEV_REQ_INT
);
do_IRQ
(
AU1000_USB_DEV_REQ_INT
);
return
;
return
;
}
}
#endif
#endif
irq
=
au_ffs
(
intc0_req0
)
-
1
;
irq
=
au_ffs
(
intc0_req0
)
-
1
;
intc0_req0
&=
~
(
1
<<
irq
);
intc0_req0
&=
~
(
1
<<
irq
);
do_IRQ
(
irq
);
do_IRQ
(
irq
);
}
}
...
@@ -495,7 +490,7 @@ static void intc0_req0_irqdispatch(void)
...
@@ -495,7 +490,7 @@ static void intc0_req0_irqdispatch(void)
static
void
intc0_req1_irqdispatch
(
void
)
static
void
intc0_req1_irqdispatch
(
void
)
{
{
int
irq
=
0
;
int
irq
=
0
;
static
unsigned
long
intc0_req1
=
0
;
static
unsigned
long
intc0_req1
;
intc0_req1
|=
au_readl
(
IC0_REQ1INT
);
intc0_req1
|=
au_readl
(
IC0_REQ1INT
);
...
@@ -503,7 +498,7 @@ static void intc0_req1_irqdispatch(void)
...
@@ -503,7 +498,7 @@ static void intc0_req1_irqdispatch(void)
return
;
return
;
irq
=
au_ffs
(
intc0_req1
)
-
1
;
irq
=
au_ffs
(
intc0_req1
)
-
1
;
intc0_req1
&=
~
(
1
<<
irq
);
intc0_req1
&=
~
(
1
<<
irq
);
do_IRQ
(
irq
);
do_IRQ
(
irq
);
}
}
...
@@ -515,7 +510,7 @@ static void intc0_req1_irqdispatch(void)
...
@@ -515,7 +510,7 @@ static void intc0_req1_irqdispatch(void)
static
void
intc1_req0_irqdispatch
(
void
)
static
void
intc1_req0_irqdispatch
(
void
)
{
{
int
irq
=
0
;
int
irq
=
0
;
static
unsigned
long
intc1_req0
=
0
;
static
unsigned
long
intc1_req0
;
intc1_req0
|=
au_readl
(
IC1_REQ0INT
);
intc1_req0
|=
au_readl
(
IC1_REQ0INT
);
...
@@ -523,7 +518,7 @@ static void intc1_req0_irqdispatch(void)
...
@@ -523,7 +518,7 @@ static void intc1_req0_irqdispatch(void)
return
;
return
;
irq
=
au_ffs
(
intc1_req0
)
-
1
;
irq
=
au_ffs
(
intc1_req0
)
-
1
;
intc1_req0
&=
~
(
1
<<
irq
);
intc1_req0
&=
~
(
1
<<
irq
);
irq
+=
32
;
irq
+=
32
;
do_IRQ
(
irq
);
do_IRQ
(
irq
);
}
}
...
@@ -532,7 +527,7 @@ static void intc1_req0_irqdispatch(void)
...
@@ -532,7 +527,7 @@ static void intc1_req0_irqdispatch(void)
static
void
intc1_req1_irqdispatch
(
void
)
static
void
intc1_req1_irqdispatch
(
void
)
{
{
int
irq
=
0
;
int
irq
=
0
;
static
unsigned
long
intc1_req1
=
0
;
static
unsigned
long
intc1_req1
;
intc1_req1
|=
au_readl
(
IC1_REQ1INT
);
intc1_req1
|=
au_readl
(
IC1_REQ1INT
);
...
@@ -540,94 +535,11 @@ static void intc1_req1_irqdispatch(void)
...
@@ -540,94 +535,11 @@ static void intc1_req1_irqdispatch(void)
return
;
return
;
irq
=
au_ffs
(
intc1_req1
)
-
1
;
irq
=
au_ffs
(
intc1_req1
)
-
1
;
intc1_req1
&=
~
(
1
<<
irq
);
intc1_req1
&=
~
(
1
<<
irq
);
irq
+=
32
;
irq
+=
32
;
do_IRQ
(
irq
);
do_IRQ
(
irq
);
}
}
#ifdef CONFIG_PM
/* Save/restore the interrupt controller state.
* Called from the save/restore core registers as part of the
* au_sleep function in power.c.....maybe I should just pm_register()
* them instead?
*/
static
unsigned
int
sleep_intctl_config0
[
2
];
static
unsigned
int
sleep_intctl_config1
[
2
];
static
unsigned
int
sleep_intctl_config2
[
2
];
static
unsigned
int
sleep_intctl_src
[
2
];
static
unsigned
int
sleep_intctl_assign
[
2
];
static
unsigned
int
sleep_intctl_wake
[
2
];
static
unsigned
int
sleep_intctl_mask
[
2
];
void
save_au1xxx_intctl
(
void
)
{
sleep_intctl_config0
[
0
]
=
au_readl
(
IC0_CFG0RD
);
sleep_intctl_config1
[
0
]
=
au_readl
(
IC0_CFG1RD
);
sleep_intctl_config2
[
0
]
=
au_readl
(
IC0_CFG2RD
);
sleep_intctl_src
[
0
]
=
au_readl
(
IC0_SRCRD
);
sleep_intctl_assign
[
0
]
=
au_readl
(
IC0_ASSIGNRD
);
sleep_intctl_wake
[
0
]
=
au_readl
(
IC0_WAKERD
);
sleep_intctl_mask
[
0
]
=
au_readl
(
IC0_MASKRD
);
sleep_intctl_config0
[
1
]
=
au_readl
(
IC1_CFG0RD
);
sleep_intctl_config1
[
1
]
=
au_readl
(
IC1_CFG1RD
);
sleep_intctl_config2
[
1
]
=
au_readl
(
IC1_CFG2RD
);
sleep_intctl_src
[
1
]
=
au_readl
(
IC1_SRCRD
);
sleep_intctl_assign
[
1
]
=
au_readl
(
IC1_ASSIGNRD
);
sleep_intctl_wake
[
1
]
=
au_readl
(
IC1_WAKERD
);
sleep_intctl_mask
[
1
]
=
au_readl
(
IC1_MASKRD
);
}
/* For most restore operations, we clear the entire register and
* then set the bits we found during the save.
*/
void
restore_au1xxx_intctl
(
void
)
{
au_writel
(
0xffffffff
,
IC0_MASKCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG0CLR
);
au_sync
();
au_writel
(
sleep_intctl_config0
[
0
],
IC0_CFG0SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG1CLR
);
au_sync
();
au_writel
(
sleep_intctl_config1
[
0
],
IC0_CFG1SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_CFG2CLR
);
au_sync
();
au_writel
(
sleep_intctl_config2
[
0
],
IC0_CFG2SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_SRCCLR
);
au_sync
();
au_writel
(
sleep_intctl_src
[
0
],
IC0_SRCSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_ASSIGNCLR
);
au_sync
();
au_writel
(
sleep_intctl_assign
[
0
],
IC0_ASSIGNSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_WAKECLR
);
au_sync
();
au_writel
(
sleep_intctl_wake
[
0
],
IC0_WAKESET
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_RISINGCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC0_FALLINGCLR
);
au_sync
();
au_writel
(
0x00000000
,
IC0_TESTBIT
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_MASKCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG0CLR
);
au_sync
();
au_writel
(
sleep_intctl_config0
[
1
],
IC1_CFG0SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG1CLR
);
au_sync
();
au_writel
(
sleep_intctl_config1
[
1
],
IC1_CFG1SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_CFG2CLR
);
au_sync
();
au_writel
(
sleep_intctl_config2
[
1
],
IC1_CFG2SET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_SRCCLR
);
au_sync
();
au_writel
(
sleep_intctl_src
[
1
],
IC1_SRCSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_ASSIGNCLR
);
au_sync
();
au_writel
(
sleep_intctl_assign
[
1
],
IC1_ASSIGNSET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_WAKECLR
);
au_sync
();
au_writel
(
sleep_intctl_wake
[
1
],
IC1_WAKESET
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_RISINGCLR
);
au_sync
();
au_writel
(
0xffffffff
,
IC1_FALLINGCLR
);
au_sync
();
au_writel
(
0x00000000
,
IC1_TESTBIT
);
au_sync
();
au_writel
(
sleep_intctl_mask
[
1
],
IC1_MASKSET
);
au_sync
();
au_writel
(
sleep_intctl_mask
[
0
],
IC0_MASKSET
);
au_sync
();
}
#endif
/* CONFIG_PM */
asmlinkage
void
plat_irq_dispatch
(
void
)
asmlinkage
void
plat_irq_dispatch
(
void
)
{
{
unsigned
int
pending
=
read_c0_status
()
&
read_c0_cause
()
&
ST0_IM
;
unsigned
int
pending
=
read_c0_status
()
&
read_c0_cause
()
&
ST0_IM
;
...
@@ -645,3 +557,63 @@ asmlinkage void plat_irq_dispatch(void)
...
@@ -645,3 +557,63 @@ asmlinkage void plat_irq_dispatch(void)
else
else
spurious_interrupt
();
spurious_interrupt
();
}
}
void
__init
arch_init_irq
(
void
)
{
int
i
;
unsigned
long
cp0_status
;
au1xxx_irq_map_t
*
imp
;
extern
au1xxx_irq_map_t
au1xxx_irq_map
[];
extern
au1xxx_irq_map_t
au1xxx_ic0_map
[];
extern
int
au1xxx_nr_irqs
;
extern
int
au1xxx_ic0_nr_irqs
;
cp0_status
=
read_c0_status
();
/* Initialize interrupt controllers to a safe state.
*/
au_writel
(
0xffffffff
,
IC0_CFG0CLR
);
au_writel
(
0xffffffff
,
IC0_CFG1CLR
);
au_writel
(
0xffffffff
,
IC0_CFG2CLR
);
au_writel
(
0xffffffff
,
IC0_MASKCLR
);
au_writel
(
0xffffffff
,
IC0_ASSIGNSET
);
au_writel
(
0xffffffff
,
IC0_WAKECLR
);
au_writel
(
0xffffffff
,
IC0_SRCSET
);
au_writel
(
0xffffffff
,
IC0_FALLINGCLR
);
au_writel
(
0xffffffff
,
IC0_RISINGCLR
);
au_writel
(
0x00000000
,
IC0_TESTBIT
);
au_writel
(
0xffffffff
,
IC1_CFG0CLR
);
au_writel
(
0xffffffff
,
IC1_CFG1CLR
);
au_writel
(
0xffffffff
,
IC1_CFG2CLR
);
au_writel
(
0xffffffff
,
IC1_MASKCLR
);
au_writel
(
0xffffffff
,
IC1_ASSIGNSET
);
au_writel
(
0xffffffff
,
IC1_WAKECLR
);
au_writel
(
0xffffffff
,
IC1_SRCSET
);
au_writel
(
0xffffffff
,
IC1_FALLINGCLR
);
au_writel
(
0xffffffff
,
IC1_RISINGCLR
);
au_writel
(
0x00000000
,
IC1_TESTBIT
);
/* Initialize IC0, which is fixed per processor.
*/
imp
=
au1xxx_ic0_map
;
for
(
i
=
0
;
i
<
au1xxx_ic0_nr_irqs
;
i
++
)
{
setup_local_irq
(
imp
->
im_irq
,
imp
->
im_type
,
imp
->
im_request
);
imp
++
;
}
/* Now set up the irq mapping for the board.
*/
imp
=
au1xxx_irq_map
;
for
(
i
=
0
;
i
<
au1xxx_nr_irqs
;
i
++
)
{
setup_local_irq
(
imp
->
im_irq
,
imp
->
im_type
,
imp
->
im_request
);
imp
++
;
}
set_c0_status
(
ALLINTS
);
/* Board specific IRQ initialization.
*/
if
(
board_init_irq
)
(
*
board_init_irq
)();
}
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