summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2007-12-02 21:49:07 +0000
committerTill Straumann <strauman@slac.stanford.edu>2007-12-02 21:49:07 +0000
commitc10dc130f9559a0cf14432e5877eb7d33e668d4f (patch)
tree46d68744f688ae8c80da5c7e88136a690d1390f7 /c
parent2007-12-02 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-c10dc130f9559a0cf14432e5877eb7d33e668d4f.tar.bz2
2007-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/irq/i8259.c, shared/irq/irq.h, shared/irq/irq_supp.h, shared/irq/openpic_i8259_irq.c: BSP_disable_irq_at_pic(), openpic_disable_irq(), BSP_irq_disable_at_i8259s() now return 0/1 if irq was disabled/enabled prior to disabling. irq_supp.h now exports a inline helper routine for scanning a list of shared handlers; to be used by PIC drivers.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/ChangeLog9
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/i8259.c8
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/irq.h3
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h38
-rw-r--r--c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c35
5 files changed, 60 insertions, 33 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog
index 0398ef54a2..f830286056 100644
--- a/c/src/lib/libbsp/powerpc/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/ChangeLog
@@ -1,5 +1,14 @@
2007-12-02 Till Straumann <strauman@slac.stanford.edu>
+ * shared/irq/i8259.c, shared/irq/irq.h, shared/irq/irq_supp.h,
+ shared/irq/openpic_i8259_irq.c: BSP_disable_irq_at_pic(),
+ openpic_disable_irq(), BSP_irq_disable_at_i8259s() now return
+ 0/1 if irq was disabled/enabled prior to disabling.
+ irq_supp.h now exports a inline helper routine for scanning
+ a list of shared handlers; to be used by PIC drivers.
+
+2007-12-02 Till Straumann <strauman@slac.stanford.edu>
+
* shared/openpic/openpic.c shared/openpic/openpic.h,
shared/irq/irq_init.c: added more parameters to
openpic_init() so that more details of the configuration
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/i8259.c b/c/src/lib/libbsp/powerpc/shared/irq/i8259.c
index a133d16898..2e700b006d 100644
--- a/c/src/lib/libbsp/powerpc/shared/irq/i8259.c
+++ b/c/src/lib/libbsp/powerpc/shared/irq/i8259.c
@@ -29,21 +29,23 @@ volatile rtems_i8259_masks i8259s_cache = 0xfffb;
| Description: Mask IRQ line in appropriate PIC chip.
| Global Variables: i8259s_cache
| Arguments: vector_offset - number of IRQ line to mask.
-| Returns: Nothing.
+| Returns: original state or -1 on error.
+--------------------------------------------------------------------------*/
int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine)
{
unsigned short mask;
rtems_interrupt_level level;
+ int rval;
if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) ||
((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET)
)
- return 1;
+ return -1;
rtems_interrupt_disable(level);
mask = 1 << irqLine;
+ rval = i8259s_cache & mask ? 0 : 1;
i8259s_cache |= mask;
if (irqLine < 8)
@@ -56,7 +58,7 @@ int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine)
}
rtems_interrupt_enable(level);
- return 0;
+ return rval;
}
/*-------------------------------------------------------------------------+
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq.h b/c/src/lib/libbsp/powerpc/shared/irq/irq.h
index 78ac3b7def..c27c459388 100644
--- a/c/src/lib/libbsp/powerpc/shared/irq/irq.h
+++ b/c/src/lib/libbsp/powerpc/shared/irq/irq.h
@@ -157,6 +157,9 @@ void BSP_i8259s_init(void);
* function to disable a particular irq at 8259 level. After calling
* this function, even if the device asserts the interrupt line it will
* not be propagated further to the processor
+ *
+ * RETURNS: 1/0 if the interrupt was enabled/disabled originally or
+ * a value < 0 on error.
*/
int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine);
/*
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h b/c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h
index c64d587c9f..3a0cd9a866 100644
--- a/c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h
+++ b/c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h
@@ -30,7 +30,11 @@ extern "C" {
* PIC(s).
*/
extern void BSP_enable_irq_at_pic (const rtems_irq_number irqLine);
-extern void BSP_disable_irq_at_pic (const rtems_irq_number irqLine);
+/*
+ * RETURNS: nonzero (> 0 ) if irq was enabled originally, zero if irq
+ * was off and negative value if there was an error.
+ */
+extern int BSP_disable_irq_at_pic (const rtems_irq_number irqLine);
/*
* Initialize the PIC.
@@ -48,6 +52,38 @@ struct _BSP_Exception_frame;
*/
void C_dispatch_irq_handler (struct _BSP_Exception_frame *frame, unsigned int excNum);
+/*
+ * Snippet to be used by PIC drivers;
+ * enables interrupts, traverses list of
+ * shared handlers for a given interrupt
+ * and restores original irq level
+ */
+
+static inline void
+bsp_irq_dispatch_list(rtems_irq_connect_data *tbl, unsigned irq, rtems_irq_hdl sentinel)
+{
+register uint32_t l_orig;
+
+ l_orig = _ISR_Get_level();
+
+ /* Enable all interrupts */
+ _ISR_Set_level(0);
+
+ /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
+ {
+ rtems_irq_connect_data* vchain;
+ for( vchain = &tbl[irq];
+ ((int)vchain != -1 && vchain->hdl != sentinel);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->hdl(vchain->handle);
+ }
+ }
+
+ /* Restore original level */
+ _ISR_Set_level(l_orig);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c b/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c
index edbe581db8..dcc3b645f5 100644
--- a/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c
+++ b/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c
@@ -118,7 +118,7 @@ BSP_enable_irq_at_pic(const rtems_irq_number name)
}
}
-void
+int
BSP_disable_irq_at_pic(const rtems_irq_number name)
{
#ifdef BSP_PCI_ISA_BRIDGE_IRQ
@@ -126,15 +126,16 @@ BSP_disable_irq_at_pic(const rtems_irq_number name)
/*
* disable interrupt at PIC level
*/
- BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
+ return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
}
#endif
if (is_pci_irq(name)) {
/*
* disable interrupt at OPENPIC level
*/
- openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
+ return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
}
+ return -1;
}
/*
@@ -209,30 +210,6 @@ int _BSP_vme_bridge_irq = -1;
unsigned BSP_spuriousIntr = 0;
-static inline void
-dispatch_list(unsigned int irq)
-{
-register uint32_t l_orig;
-
- l_orig = _ISR_Get_level();
-
- /* Enable all interrupts */
- _ISR_Set_level(0);
-
- /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */
- {
- rtems_irq_connect_data* vchain;
- for( vchain = &rtems_hdl_tbl[irq];
- ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
- vchain = (rtems_irq_connect_data*)vchain->next_handler )
- {
- vchain->hdl(vchain->handle);
- }
- }
-
- /* Restore original level */
- _ISR_Set_level(l_orig);
-}
/*
* High level IRQ handler called from shared_raw_irq_code_entry
*/
@@ -247,7 +224,7 @@ void C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
if (excNum == ASM_DEC_VECTOR) {
- dispatch_list(BSP_DECREMENTER);
+ bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
return;
@@ -282,7 +259,7 @@ void C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
#endif
/* dispatch handlers */
- dispatch_list(irq);
+ bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
#ifdef BSP_PCI_ISA_BRIDGE_IRQ
if (isaIntr) {