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
e27b33b0
Commit
e27b33b0
authored
Jun 17, 2004
by
David Woodhouse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for i8259 IRQ controller on WindRiver PowerQUICC II
parent
a4604017
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
163 additions
and
0 deletions
+163
-0
arch/ppc/platforms/sbc82xx.c
arch/ppc/platforms/sbc82xx.c
+154
-0
arch/ppc/platforms/sbc82xx.h
arch/ppc/platforms/sbc82xx.h
+9
-0
No files found.
arch/ppc/platforms/sbc82xx.c
View file @
e27b33b0
...
...
@@ -18,14 +18,18 @@
#include <linux/config.h>
#include <linux/seq_file.h>
#include <linux/stddef.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/mpc8260.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/todc.h>
#include <asm/immap_cpm2.h>
#include <asm/pci.h>
static
void
(
*
callback_setup_arch
)(
void
);
static
void
(
*
callback_init_IRQ
)(
void
);
extern
unsigned
char
__res
[
sizeof
(
bd_t
)];
...
...
@@ -88,6 +92,152 @@ static void sbc82xx_time_init(void)
}
#endif
/* CONFIG_GEN_RTC */
static
volatile
char
*
sbc82xx_i8259_map
;
static
char
sbc82xx_i8259_mask
=
0xff
;
static
spinlock_t
sbc82xx_i8259_lock
=
SPIN_LOCK_UNLOCKED
;
static
void
sbc82xx_i8259_mask_and_ack_irq
(
unsigned
int
irq_nr
)
{
unsigned
long
flags
;
irq_nr
-=
NR_SIU_INTS
;
spin_lock_irqsave
(
&
sbc82xx_i8259_lock
,
flags
);
sbc82xx_i8259_mask
|=
1
<<
irq_nr
;
(
void
)
sbc82xx_i8259_map
[
1
];
/* Dummy read */
sbc82xx_i8259_map
[
1
]
=
sbc82xx_i8259_mask
;
sbc82xx_i8259_map
[
0
]
=
0x20
;
/* OCW2: Non-specific EOI */
spin_unlock_irqrestore
(
&
sbc82xx_i8259_lock
,
flags
);
}
static
void
sbc82xx_i8259_mask_irq
(
unsigned
int
irq_nr
)
{
unsigned
long
flags
;
irq_nr
-=
NR_SIU_INTS
;
spin_lock_irqsave
(
&
sbc82xx_i8259_lock
,
flags
);
sbc82xx_i8259_mask
|=
1
<<
irq_nr
;
sbc82xx_i8259_map
[
1
]
=
sbc82xx_i8259_mask
;
spin_unlock_irqrestore
(
&
sbc82xx_i8259_lock
,
flags
);
}
static
void
sbc82xx_i8259_unmask_irq
(
unsigned
int
irq_nr
)
{
unsigned
long
flags
;
irq_nr
-=
NR_SIU_INTS
;
spin_lock_irqsave
(
&
sbc82xx_i8259_lock
,
flags
);
sbc82xx_i8259_mask
&=
~
(
1
<<
irq_nr
);
sbc82xx_i8259_map
[
1
]
=
sbc82xx_i8259_mask
;
spin_unlock_irqrestore
(
&
sbc82xx_i8259_lock
,
flags
);
}
static
void
sbc82xx_i8259_end_irq
(
unsigned
int
irq
)
{
if
(
!
(
irq_desc
[
irq
].
status
&
(
IRQ_DISABLED
|
IRQ_INPROGRESS
))
&&
irq_desc
[
irq
].
action
)
sbc82xx_i8259_unmask_irq
(
irq
);
}
struct
hw_interrupt_type
sbc82xx_i8259_ic
=
{
.
typename
=
" i8259 "
,
.
enable
=
sbc82xx_i8259_unmask_irq
,
.
disable
=
sbc82xx_i8259_mask_irq
,
.
ack
=
sbc82xx_i8259_mask_and_ack_irq
,
.
end
=
sbc82xx_i8259_end_irq
,
};
static
irqreturn_t
sbc82xx_i8259_demux
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
spin_lock
(
&
sbc82xx_i8259_lock
);
sbc82xx_i8259_map
[
0
]
=
0x0c
;
/* OCW3: Read IR register on RD# pulse */
irq
=
sbc82xx_i8259_map
[
0
]
&
7
;
/* Read IRR */
if
(
irq
==
7
)
{
/* Possible spurious interrupt */
int
isr
;
sbc82xx_i8259_map
[
0
]
=
0x0b
;
/* OCW3: Read IS register on RD# pulse */
isr
=
sbc82xx_i8259_map
[
0
];
/* Read ISR */
if
(
!
(
isr
&
0x80
))
{
printk
(
KERN_INFO
"Spurious i8259 interrupt
\n
"
);
return
IRQ_HANDLED
;
}
}
ppc_irq_dispatch_handler
(
regs
,
NR_SIU_INTS
+
irq
);
return
IRQ_HANDLED
;
}
void
__init
sbc82xx_init_IRQ
(
void
)
{
volatile
memctl_cpm2_t
*
mc
=
&
cpm2_immr
->
im_memctl
;
volatile
intctl_cpm2_t
*
ic
=
&
cpm2_immr
->
im_intctl
;
int
i
;
callback_init_IRQ
();
/* u-boot doesn't always set the board up correctly */
mc
->
memc_br5
=
0
;
mc
->
memc_or5
=
0xfff00856
;
mc
->
memc_br5
=
0x22000801
;
sbc82xx_i8259_map
=
ioremap
(
0x22008000
,
2
);
if
(
!
sbc82xx_i8259_map
)
{
printk
(
KERN_CRIT
"Mapping i8259 interrupt controller failed
\n
"
);
return
;
}
/* Set up the interrupt handlers for the i8259 IRQs */
for
(
i
=
NR_SIU_INTS
;
i
<
NR_SIU_INTS
+
8
;
i
++
)
{
irq_desc
[
i
].
handler
=
&
sbc82xx_i8259_ic
;
irq_desc
[
i
].
status
|=
IRQ_LEVEL
;
}
/* make IRQ6 level sensitive */
ic
->
ic_siexr
&=
~
(
1
<<
(
14
-
(
SIU_INT_IRQ6
-
SIU_INT_IRQ1
)));
irq_desc
[
SIU_INT_IRQ6
].
status
|=
IRQ_LEVEL
;
/* Initialise the i8259 */
sbc82xx_i8259_map
[
0
]
=
0x1b
;
/* ICW1: Level, no cascade, ICW4 */
sbc82xx_i8259_map
[
1
]
=
0x00
;
/* ICW2: vector base */
/* No ICW3 (no cascade) */
sbc82xx_i8259_map
[
1
]
=
0x01
;
/* ICW4: 8086 mode, normal EOI */
sbc82xx_i8259_map
[
0
]
=
0x0b
;
/* OCW3: Read IS register on RD# pulse */
sbc82xx_i8259_map
[
1
]
=
sbc82xx_i8259_mask
;
/* Set interrupt mask */
/* Request cascade IRQ */
if
(
request_irq
(
SIU_INT_IRQ6
,
sbc82xx_i8259_demux
,
SA_INTERRUPT
,
"i8259 demux"
,
0
))
{
printk
(
"Installation of i8259 IRQ demultiplexer failed.
\n
"
);
}
}
static
int
sbc82xx_pci_map_irq
(
struct
pci_dev
*
dev
,
unsigned
char
idsel
,
unsigned
char
pin
)
{
static
char
pci_irq_table
[][
4
]
=
{
/*
* PCI IDSEL/INTPIN->INTLINE
* A B C D
*/
{
SBC82xx_PIRQA
,
SBC82xx_PIRQB
,
SBC82xx_PIRQC
,
SBC82xx_PIRQD
},
/* IDSEL 16 - PMC slot */
{
SBC82xx_PC_IRQA
,
SBC82xx_PC_IRQB
,
-
1
,
-
1
},
/* IDSEL 17 - CardBus */
{
SBC82xx_PIRQA
,
SBC82xx_PIRQB
,
SBC82xx_PIRQC
,
SBC82xx_PIRQD
},
/* IDSEL 18 - PCI-X bridge */
};
const
long
min_idsel
=
16
,
max_idsel
=
18
,
irqs_per_slot
=
4
;
return
PCI_IRQ_TABLE_LOOKUP
;
}
void
__init
platform_init
(
unsigned
long
r3
,
unsigned
long
r4
,
unsigned
long
r5
,
unsigned
long
r6
,
unsigned
long
r7
)
...
...
@@ -103,7 +253,11 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md
.
show_cpuinfo
=
sbc82xx_show_cpuinfo
;
callback_setup_arch
=
ppc_md
.
setup_arch
;
callback_init_IRQ
=
ppc_md
.
init_IRQ
;
ppc_md
.
setup_arch
=
sbc82xx_setup_arch
;
ppc_md
.
init_IRQ
=
sbc82xx_init_IRQ
;
ppc_md
.
pci_map_irq
=
sbc82xx_pci_map_irq
;
#ifdef CONFIG_GEN_RTC
ppc_md
.
time_init
=
NULL
;
ppc_md
.
get_rtc_time
=
NULL
;
...
...
arch/ppc/platforms/sbc82xx.h
View file @
e27b33b0
...
...
@@ -20,4 +20,13 @@
#define BOOTROM_RESTART_ADDR ((uint)0x40000104)
#define SBC82xx_PC_IRQA (NR_SIU_INTS+0)
#define SBC82xx_PC_IRQB (NR_SIU_INTS+1)
#define SBC82xx_MPC185_IRQ (NR_SIU_INTS+2)
#define SBC82xx_ATM_IRQ (NR_SIU_INTS+3)
#define SBC82xx_PIRQA (NR_SIU_INTS+4)
#define SBC82xx_PIRQB (NR_SIU_INTS+5)
#define SBC82xx_PIRQC (NR_SIU_INTS+6)
#define SBC82xx_PIRQD (NR_SIU_INTS+7)
#endif
/* __PPC_SBC82xx_H__ */
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