]> git.sur5r.net Git - freertos/blob
0d56bafeffaa6d6de7a0c1d9b4691a362d2e54d3
[freertos] /
1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
3
4 #include <metal/machine/platform.h>
5
6 #ifdef METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0
7
8 #include <metal/io.h>
9 #include <metal/shutdown.h>
10 #include <metal/drivers/sifive_global-external-interrupts0.h>
11 #include <metal/machine.h>
12
13 void __metal_driver_sifive_global_external_interrupt_init(struct metal_interrupt *controller)
14 {
15     struct __metal_driver_sifive_global_external_interrupts0 *global0;
16
17     global0 = (struct __metal_driver_sifive_global_external_interrupts0 *)(controller);
18     if ( !global0->init_done ) {
19         struct metal_interrupt *intc =
20             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
21
22         if (intc) {
23             intc->vtable->interrupt_init(intc);
24             /* Register its interrupts with with parent controller */
25             for (int i = 0;
26                  i < __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller);
27                  i++) {
28                 intc->vtable->interrupt_register(intc,
29                     __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, i),
30                                                  NULL, controller);
31             }
32             global0->init_done = 1;
33         }
34     }
35 }
36
37 int __metal_driver_sifive_global_external_interrupt_register(struct metal_interrupt *controller,
38                                                            int id, metal_interrupt_handler_t isr,
39                                                            void *priv)
40 {
41     int rc = -1;
42
43     if (id != 0) {
44         struct metal_interrupt *intc =
45             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
46
47         /* Enable its interrupts with parent controller */
48         if (intc) {
49             rc = intc->vtable->interrupt_register(intc, id, isr, priv);
50         }
51     }
52     return rc;
53 }
54
55 int __metal_driver_sifive_global_external_interrupt_enable(struct metal_interrupt *controller, int id)
56 {
57     int rc = -1;
58
59     if (id != 0) {
60         struct metal_interrupt *intc =
61             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
62
63         /* Enable its interrupts with parent controller */
64         if (intc) {
65             rc = intc->vtable->interrupt_enable(intc, id);
66         }
67     }
68     return rc;
69 }
70
71 int __metal_driver_sifive_global_external_interrupt_disable(struct metal_interrupt *controller, int id)
72 {
73     int rc = -1;
74
75     if (id != 0) {
76         struct metal_interrupt *intc =
77             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
78
79         /* Enable its interrupts with parent controller */
80         if (intc) {
81             rc = intc->vtable->interrupt_disable(intc, id);
82         }
83     }
84     return rc;
85 }
86
87 int __metal_driver_sifive_global_external_interrupt_set_threshold(struct metal_interrupt *controller,
88                                                                   unsigned int threshold)
89 {
90     struct metal_interrupt *intc =
91             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
92     if (intc) {
93         return intc->vtable->interrupt_set_threshold(intc, threshold);
94     }
95     return -1;
96 }
97
98 unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struct metal_interrupt *controller)
99 {
100     struct metal_interrupt *intc =
101             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
102
103     if (intc) {
104         return intc->vtable->interrupt_get_threshold(intc);
105     }
106     return 0;
107 }
108
109 int __metal_driver_sifive_global_external_interrupt_set_priority(struct metal_interrupt *controller,
110                                                                              int id, unsigned int priority)
111 {
112     struct metal_interrupt *intc =
113             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
114     if (intc) {
115         return intc->vtable->interrupt_set_priority(intc, id, priority);
116     }
117     return -1;
118 }
119
120 unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct metal_interrupt *controller, int id)
121 {
122     struct metal_interrupt *intc =
123             __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller);
124
125     if (intc) {
126         return intc->vtable->interrupt_get_priority(intc, id);
127     }
128     return 0;
129 }
130
131 int __metal_driver_sifive_global_external_command_request (struct metal_interrupt *controller,
132                                                          int command, void *data)
133 {
134     int idx;
135     int rc = -1;
136
137     switch (command) {
138     case METAL_MAX_INTERRUPT_GET:
139         rc = __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller);
140         break;
141     case METAL_INDEX_INTERRUPT_GET:
142         rc = 0;
143         if (data) {
144             idx = *(int *)data;
145             rc = __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, idx);
146         }
147         break;
148     default:
149         break;
150     }
151
152     return rc;
153 }
154
155 __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) = {
156     .global0_vtable.interrupt_init     = __metal_driver_sifive_global_external_interrupt_init,
157     .global0_vtable.interrupt_register = __metal_driver_sifive_global_external_interrupt_register,
158     .global0_vtable.interrupt_enable   = __metal_driver_sifive_global_external_interrupt_enable,
159     .global0_vtable.interrupt_disable  = __metal_driver_sifive_global_external_interrupt_disable,
160     .global0_vtable.interrupt_get_threshold  = __metal_driver_sifive_global_external_interrupt_get_threshold,
161     .global0_vtable.interrupt_set_threshold  = __metal_driver_sifive_global_external_interrupt_set_threshold,
162     .global0_vtable.interrupt_get_priority   = __metal_driver_sifive_global_external_interrupt_get_priority,
163     .global0_vtable.interrupt_set_priority   = __metal_driver_sifive_global_external_interrupt_set_priority,
164     .global0_vtable.command_request    = __metal_driver_sifive_global_external_command_request,
165 };
166
167 #endif
168
169 typedef int no_empty_translation_units;