diff options
author | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 21:49:07 +0000 |
---|---|---|
committer | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 21:49:07 +0000 |
commit | c10dc130f9559a0cf14432e5877eb7d33e668d4f (patch) | |
tree | 46d68744f688ae8c80da5c7e88136a690d1390f7 /c/src | |
parent | 2007-12-02 Till Straumann <strauman@slac.stanford.edu> (diff) | |
download | rtems-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 '')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ChangeLog | 9 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/i8259.c | 8 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/irq.h | 3 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/irq_supp.h | 38 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c | 35 |
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) { |