Commit dd243518 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by David S. Miller

[SPARC]: Eric Browers sbus interrupts decoders.

parent 8b6975d3
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <asm/sun4paddr.h> #include <asm/sun4paddr.h>
#include <asm/idprom.h> #include <asm/idprom.h>
#include <asm/machines.h> #include <asm/machines.h>
#include <asm/sbus.h>
#if 0 #if 0
static struct resource sun4c_timer_eb = { "sun4c_timer" }; static struct resource sun4c_timer_eb = { "sun4c_timer" };
...@@ -51,6 +52,17 @@ static struct resource sun4c_intr_eb = { "sun4c_intr" }; ...@@ -51,6 +52,17 @@ static struct resource sun4c_intr_eb = { "sun4c_intr" };
*/ */
unsigned char *interrupt_enable = 0; unsigned char *interrupt_enable = 0;
static int sun4c_pil_map[] = { 0, 1, 2, 3, 5, 7, 8, 9 };
unsigned int sun4c_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
{
if (sbint >= sizeof(sun4c_pil_map)) {
printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
BUG();
}
return sun4c_pil_map[sbint];
}
static void sun4c_disable_irq(unsigned int irq_nr) static void sun4c_disable_irq(unsigned int irq_nr)
{ {
unsigned long flags; unsigned long flags;
...@@ -213,6 +225,7 @@ void __init sun4c_init_IRQ(void) ...@@ -213,6 +225,7 @@ void __init sun4c_init_IRQ(void)
int_regs[0].reg_size, "sun4c_intr"); int_regs[0].reg_size, "sun4c_intr");
} }
BTFIXUPSET_CALL(sbint_to_irq, sun4c_sbint_to_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
......
...@@ -252,6 +252,15 @@ unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq) ...@@ -252,6 +252,15 @@ unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq)
return irq; return irq;
} }
unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
{
if (sbint >= sizeof(sbus_to_pil)) {
printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
BUG();
}
return sun4d_build_irq(sdev, sbus_to_pil[sbint]);
}
int sun4d_request_irq(unsigned int irq, int sun4d_request_irq(unsigned int irq,
void (*handler)(int, void *, struct pt_regs *), void (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id) unsigned long irqflags, const char * devname, void *dev_id)
...@@ -541,6 +550,7 @@ void __init sun4d_init_IRQ(void) ...@@ -541,6 +550,7 @@ void __init sun4d_init_IRQ(void)
{ {
local_irq_disable(); local_irq_disable();
BTFIXUPSET_CALL(sbint_to_irq, sun4d_sbint_to_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sbus.h>
static unsigned long dummy; static unsigned long dummy;
...@@ -77,6 +78,17 @@ static unsigned long irq_mask[] = { ...@@ -77,6 +78,17 @@ static unsigned long irq_mask[] = {
SUN4M_INT_SBUS(6) /* 14 irq 13 */ SUN4M_INT_SBUS(6) /* 14 irq 13 */
}; };
static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 };
unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
{
if (sbint >= sizeof(sun4m_pil_map)) {
printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
BUG();
}
return sun4m_pil_map[sbint] | 0x30;
}
inline unsigned long sun4m_get_irqmask(unsigned int irq) inline unsigned long sun4m_get_irqmask(unsigned int irq)
{ {
unsigned long mask; unsigned long mask;
...@@ -366,6 +378,7 @@ void __init sun4m_init_IRQ(void) ...@@ -366,6 +378,7 @@ void __init sun4m_init_IRQ(void)
&sun4m_interrupts->undirected_target; &sun4m_interrupts->undirected_target;
sun4m_interrupts->undirected_target = 0; sun4m_interrupts->undirected_target = 0;
} }
BTFIXUPSET_CALL(sbint_to_irq, sun4m_sbint_to_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
struct sbus_bus *sbus_root = NULL; struct sbus_bus *sbus_root = NULL;
static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } }; static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } };
static int interrupts[PROMINTR_MAX] __initdata = { 0 };
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
extern int pcic_present(void); extern int pcic_present(void);
...@@ -126,8 +127,7 @@ static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev) ...@@ -126,8 +127,7 @@ static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
#else #else
len = prom_getproperty(prom_node, "intr", len = prom_getproperty(prom_node, "intr",
(char *)irqs, sizeof(irqs)); (char *)irqs, sizeof(irqs));
if (len == -1) if (len != -1) {
len = 0;
sdev->num_irqs = len / 8; sdev->num_irqs = len / 8;
if (sdev->num_irqs == 0) { if (sdev->num_irqs == 0) {
sdev->irqs[0] = 0; sdev->irqs[0] = 0;
...@@ -140,6 +140,24 @@ static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev) ...@@ -140,6 +140,24 @@ static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
for (len = 0; len < sdev->num_irqs; len++) for (len = 0; len < sdev->num_irqs; len++)
sdev->irqs[len] = irqs[len].pri; sdev->irqs[len] = irqs[len].pri;
} }
} else {
/* No "intr" node found-- check for "interrupts" node.
* This node contains SBus interrupt levels, not IPLs
* as in "intr", and no vector values. We convert
* SBus interrupt levels to PILs (platform specific).
*/
len = prom_getproperty(prom_node, "interrupts",
(char *)interrupts, sizeof(interrupts));
if (len == -1) {
sdev->irqs[0] = 0;
sdev->num_irqs = 0;
} else {
sdev->num_irqs = len / sizeof(int);
for (len = 0; len < sdev->num_irqs; len++) {
sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]);
}
}
}
#endif /* !__sparc_v9__ */ #endif /* !__sparc_v9__ */
} }
......
...@@ -121,4 +121,15 @@ extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int); ...@@ -121,4 +121,15 @@ extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int);
extern void sbus_dma_sync_single(struct sbus_dev *, dma_addr_t, size_t, int); extern void sbus_dma_sync_single(struct sbus_dev *, dma_addr_t, size_t, int);
extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int, int); extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int, int);
/* Eric Brower (ebrower@usa.net)
* Translate SBus interrupt levels to ino values--
* this is used when converting sbus "interrupts" OBP
* node values to "intr" node values, and is platform
* dependent. If only we could call OBP with
* "sbus-intr>cpu (sbint -- ino)" from kernel...
* See .../drivers/sbus/sbus.c for details.
*/
BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)
#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)
#endif /* !(_SPARC_SBUS_H) */ #endif /* !(_SPARC_SBUS_H) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment