source: rtems/c/src/lib/libbsp/arm/beagle/irq.c @ 1c0663b

4.115
Last change on this file since 1c0663b was d4edbdbc, checked in by Sebastian Huber <sebastian.huber@…>, on Mar 20, 2015 at 1:09:26 PM

Replace www.rtems.com with www.rtems.org

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_interrupt
5 * @ingroup arm_beagle
6 *
7 * @brief Interrupt support.
8 */
9
10/*
11 * Copyright (c) 2014 Ben Gras <beng@shrike-systems.com>. All rights reserved.
12 *
13 * The license and distribution terms for this file may be
14 * found in the file LICENSE in this distribution or at
15 * http://www.rtems.org/license/LICENSE.
16 */
17
18#include <bsp.h>
19#include <bsp/irq-generic.h>
20#include <bsp/linker-symbols.h>
21
22#include <rtems/score/armv4.h>
23
24#include <libcpu/arm-cp15.h>
25
26struct omap_intr
27{
28  uint32_t base;
29  int size;
30};
31
32#if IS_DM3730
33static struct omap_intr omap_intr = {
34  .base = OMAP3_DM37XX_INTR_BASE,
35  .size = 0x1000,
36};
37#endif
38
39#if IS_AM335X
40static struct omap_intr omap_intr = {
41  .base = OMAP3_AM335X_INTR_BASE,
42  .size = 0x1000,
43};
44#endif
45
46static int irqs_enabled[BSP_INTERRUPT_VECTOR_MAX+1];
47
48volatile static int level = 0;
49
50void bsp_interrupt_dispatch(void)
51{
52  /* get irq */
53  uint32_t reg = mmio_read(omap_intr.base + OMAP3_INTCPS_SIR_IRQ);
54  int irq;
55  irq = reg & OMAP3_INTR_ACTIVEIRQ_MASK;
56
57  if(!irqs_enabled[irq]) {
58        /* Ignore spurious interrupt */
59  } else {
60    bsp_interrupt_vector_disable(irq);
61
62    /* enable new interrupts, and flush data cache to make sure
63     * it hits the intc
64     */
65    mmio_write(omap_intr.base + OMAP3_INTCPS_CONTROL, OMAP3_INTR_NEWIRQAGR);
66    flush_data_cache();
67    mmio_read(omap_intr.base + OMAP3_INTCPS_SIR_IRQ);
68    flush_data_cache();
69
70    /* keep current irq masked but enable unmasked ones */
71    uint32_t psr = _ARMV4_Status_irq_enable();
72    bsp_interrupt_handler_dispatch(irq);
73
74    _ARMV4_Status_restore(psr);
75
76    bsp_interrupt_vector_enable(irq);
77  }
78}
79
80static uint32_t get_mir_reg(int vector, uint32_t *mask)
81{
82  *mask = 1UL << (vector % 32);
83
84  if(vector <   0) while(1) ;
85  if(vector <  32) return OMAP3_INTCPS_MIR0;
86  if(vector <  64) return OMAP3_INTCPS_MIR1;
87  if(vector <  96) return OMAP3_INTCPS_MIR2;
88  if(vector < 128) return OMAP3_INTCPS_MIR3;
89  while(1) ;
90}
91
92rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
93{
94  uint32_t mask, cur;
95  uint32_t mir_reg = get_mir_reg(vector, &mask);
96
97  cur = mmio_read(omap_intr.base + mir_reg);
98  mmio_write(omap_intr.base + mir_reg, cur & ~mask);
99  flush_data_cache();
100
101  irqs_enabled[vector] = 1;
102
103  return RTEMS_SUCCESSFUL;
104}
105
106rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
107{
108  uint32_t mask, cur;
109  uint32_t mir_reg = get_mir_reg(vector, &mask);
110
111  cur = mmio_read(omap_intr.base + mir_reg);
112  mmio_write(omap_intr.base + mir_reg, cur | mask);
113  flush_data_cache();
114
115  irqs_enabled[vector] = 0;
116
117  return RTEMS_SUCCESSFUL;
118}
119
120rtems_status_code bsp_interrupt_facility_initialize(void)
121{
122  int i;
123  uint32_t intc_ilrx;
124
125  /* AM335X TRM 6.2.1 Initialization Sequence */
126  mmio_write(omap_intr.base + OMAP3_INTCPS_SYSCONFIG, OMAP3_SYSCONFIG_AUTOIDLE);
127  mmio_write(omap_intr.base + OMAP3_INTCPS_IDLE, 0);
128  /* priority 0 to all IRQs */
129  for(intc_ilrx = 0x100; intc_ilrx <= 0x2fc; intc_ilrx += 4) {
130    mmio_write(omap_intr.base + intc_ilrx, 0);
131  }
132
133  /* Mask all interrupts */
134  for(i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; i++)
135    bsp_interrupt_vector_disable(i);
136
137  /* Install generic interrupt handler */
138  arm_cp15_set_exception_handler(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt);
139  arm_cp15_set_vector_base_address(bsp_vector_table_begin);
140
141  return RTEMS_SUCCESSFUL;
142}
Note: See TracBrowser for help on using the repository browser.