]> git.sur5r.net Git - freertos/blob
1c34ca447c28dd75f26dc0af963269ef5efe0e8d
[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_LOCAL_EXTERNAL_INTERRUPTS0
7
8 #include <metal/io.h>
9 #include <metal/drivers/sifive_local-external-interrupts0.h>
10 #include <metal/machine.h>
11
12 void __metal_driver_sifive_local_external_interrupt_init(struct metal_interrupt *controller)
13 {
14     struct __metal_driver_sifive_local_external_interrupts0 *local0;
15
16     local0 = (struct __metal_driver_sifive_local_external_interrupts0 *)(controller);
17     if ( !local0->init_done ) {
18         struct metal_interrupt *intc =
19             __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller);
20
21         if (intc) {
22             /* Register its interruptswith with parent controller, aka all external to default isr */
23             for (int i = 0;
24                  i < __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller);
25                  i++) {
26                 intc->vtable->interrupt_register(intc,
27                     __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, i),
28                                            NULL, controller);
29             }
30             local0->init_done = 1;
31         }
32     }
33 }
34
35 int __metal_driver_sifive_local_external_interrupt_register(struct metal_interrupt *controller,
36                                                           int id, metal_interrupt_handler_t isr,
37                                                           void *priv)
38 {
39     int rc = -1;
40
41     if (id != 0) {
42         struct metal_interrupt *intc =
43             __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller);
44
45         /* Enable its interrupts with parent controller */
46         if (intc) {
47             rc = intc->vtable->interrupt_register(intc, id, isr, priv);
48         }
49     }
50     return rc;
51 }
52
53 int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt *controller, int id)
54 {
55     int rc = -1;
56
57     if (id != 0) {
58         struct metal_interrupt *intc =
59             __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller);
60
61         /* Enable its interrupts with parent controller */
62         if (intc) {
63             rc = intc->vtable->interrupt_enable(intc, id);
64         }
65     }
66     return rc;
67 }
68
69 int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrupt *controller, int id)
70 {
71     int rc = -1;
72
73     if (id != 0) {
74         struct metal_interrupt *intc =
75             __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller);
76
77         /* Enable its interrupts with parent controller */
78         if (intc) {
79             rc = intc->vtable->interrupt_disable(intc, id);
80         }
81     }
82     return rc;
83 }
84
85 int __metal_driver_sifive_local_external_interrupt_set_threshold(struct metal_interrupt *controller,
86                                                                   unsigned int threshold)
87 {
88     /* Core controller does not support threshold configuration */
89     return -1;
90 }
91
92 unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold(struct metal_interrupt *controller)
93 {
94     /* Core controller does not support threshold configuration */
95     return 0;
96 }
97
98
99 int __metal_driver_sifive_local_external_interrupt_set_priority(struct metal_interrupt *controller,
100                                                                 int id, unsigned int priority)
101 {
102     /* Core controller does not support priority configuration */
103     return -1;
104 }
105
106 unsigned int __metal_driver_sifive_local_external_interrupt_get_priority(struct metal_interrupt *controller, int id)
107 {
108     /* Core controller does not support priority configuration */
109     return 0;
110 }
111
112 int __metal_driver_sifive_local_external_command_request (struct metal_interrupt *controller,
113                                                         int command, void *data)
114 {
115     int idx;
116     int rc = -1;
117
118     switch (command) {
119     case METAL_MAX_INTERRUPT_GET:
120         rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller);
121         break;
122     case METAL_INDEX_INTERRUPT_GET:
123         rc = 0;
124         if (data) {
125             idx = *(int *)data;
126             rc = __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, idx);
127         }
128         break;
129     default:
130         break;
131     }
132
133     return rc;
134 }
135
136 __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) = {
137     .local0_vtable.interrupt_init     = __metal_driver_sifive_local_external_interrupt_init,
138     .local0_vtable.interrupt_register = __metal_driver_sifive_local_external_interrupt_register,
139     .local0_vtable.interrupt_enable   = __metal_driver_sifive_local_external_interrupt_enable,
140     .local0_vtable.interrupt_disable  = __metal_driver_sifive_local_external_interrupt_disable,
141     .local0_vtable.interrupt_get_threshold  = __metal_driver_sifive_local_external_interrupt_get_threshold,
142     .local0_vtable.interrupt_set_threshold  = __metal_driver_sifive_local_external_interrupt_set_threshold,
143     .local0_vtable.interrupt_get_priority   = __metal_driver_sifive_local_external_interrupt_get_priority,
144     .local0_vtable.interrupt_set_priority   = __metal_driver_sifive_local_external_interrupt_set_priority,
145     .local0_vtable.command_request    = __metal_driver_sifive_local_external_command_request,
146 };
147
148 #endif
149
150 typedef int no_empty_translation_units;
151