1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: rsirq - IRQ resource descriptors
5  *
6  ******************************************************************************/
7 
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acresrc.h"
11 
12 #define _COMPONENT          ACPI_RESOURCES
13 ACPI_MODULE_NAME("rsirq")
14 
15 /*******************************************************************************
16  *
17  * acpi_rs_get_irq
18  *
19  ******************************************************************************/
20 struct acpi_rsconvert_info acpi_rs_get_irq[9] = {
21 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
22 	 ACPI_RS_SIZE(struct acpi_resource_irq),
23 	 ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
24 
25 	/* Get the IRQ mask (bytes 1:2) */
26 
27 	{ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
28 	 AML_OFFSET(irq.irq_mask),
29 	 ACPI_RS_OFFSET(data.irq.interrupt_count)},
30 
31 	/* Set default flags (others are zero) */
32 
33 	{ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering),
34 	 ACPI_EDGE_SENSITIVE,
35 	 1},
36 
37 	/* Get the descriptor length (2 or 3 for IRQ descriptor) */
38 
39 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length),
40 	 AML_OFFSET(irq.descriptor_type),
41 	 0},
42 
43 	/* All done if no flag byte present in descriptor */
44 
45 	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
46 
47 	/* Get flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
48 
49 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
50 	 AML_OFFSET(irq.flags),
51 	 0},
52 
53 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
54 	 AML_OFFSET(irq.flags),
55 	 3},
56 
57 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.shareable),
58 	 AML_OFFSET(irq.flags),
59 	 4},
60 
61 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.wake_capable),
62 	 AML_OFFSET(irq.flags),
63 	 5}
64 };
65 
66 /*******************************************************************************
67  *
68  * acpi_rs_set_irq
69  *
70  ******************************************************************************/
71 
72 struct acpi_rsconvert_info acpi_rs_set_irq[14] = {
73 	/* Start with a default descriptor of length 3 */
74 
75 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
76 	 sizeof(struct aml_resource_irq),
77 	 ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
78 
79 	/* Convert interrupt list to 16-bit IRQ bitmask */
80 
81 	{ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
82 	 AML_OFFSET(irq.irq_mask),
83 	 ACPI_RS_OFFSET(data.irq.interrupt_count)},
84 
85 	/* Set flags: Triggering[0], Polarity[3], Sharing[4], Wake[5] */
86 
87 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
88 	 AML_OFFSET(irq.flags),
89 	 0},
90 
91 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
92 	 AML_OFFSET(irq.flags),
93 	 3},
94 
95 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.shareable),
96 	 AML_OFFSET(irq.flags),
97 	 4},
98 
99 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.wake_capable),
100 	 AML_OFFSET(irq.flags),
101 	 5},
102 
103 	/*
104 	 * All done if the output descriptor length is required to be 3
105 	 * (i.e., optimization to 2 bytes cannot be attempted)
106 	 */
107 	{ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
108 	 ACPI_RS_OFFSET(data.irq.descriptor_length),
109 	 3},
110 
111 	/* Set length to 2 bytes (no flags byte) */
112 
113 	{ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)},
114 
115 	/*
116 	 * All done if the output descriptor length is required to be 2.
117 	 *
118 	 * TBD: Perhaps we should check for error if input flags are not
119 	 * compatible with a 2-byte descriptor.
120 	 */
121 	{ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
122 	 ACPI_RS_OFFSET(data.irq.descriptor_length),
123 	 2},
124 
125 	/* Reset length to 3 bytes (descriptor with flags byte) */
126 
127 	{ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
128 
129 	/*
130 	 * Check if the flags byte is necessary. Not needed if the flags are:
131 	 * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
132 	 */
133 	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
134 	 ACPI_RS_OFFSET(data.irq.triggering),
135 	 ACPI_EDGE_SENSITIVE},
136 
137 	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
138 	 ACPI_RS_OFFSET(data.irq.polarity),
139 	 ACPI_ACTIVE_HIGH},
140 
141 	{ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
142 	 ACPI_RS_OFFSET(data.irq.shareable),
143 	 ACPI_EXCLUSIVE},
144 
145 	/* We can optimize to a 2-byte irq_no_flags() descriptor */
146 
147 	{ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
148 };
149 
150 /*******************************************************************************
151  *
152  * acpi_rs_convert_ext_irq
153  *
154  ******************************************************************************/
155 
156 struct acpi_rsconvert_info acpi_rs_convert_ext_irq[10] = {
157 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
158 	 ACPI_RS_SIZE(struct acpi_resource_extended_irq),
159 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)},
160 
161 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ,
162 	 sizeof(struct aml_resource_extended_irq),
163 	 0},
164 
165 	/*
166 	 * Flags: Producer/Consumer[0], Triggering[1], Polarity[2],
167 	 *        Sharing[3], Wake[4]
168 	 */
169 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer),
170 	 AML_OFFSET(extended_irq.flags),
171 	 0},
172 
173 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering),
174 	 AML_OFFSET(extended_irq.flags),
175 	 1},
176 
177 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity),
178 	 AML_OFFSET(extended_irq.flags),
179 	 2},
180 
181 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.shareable),
182 	 AML_OFFSET(extended_irq.flags),
183 	 3},
184 
185 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.wake_capable),
186 	 AML_OFFSET(extended_irq.flags),
187 	 4},
188 
189 	/* IRQ Table length (Byte4) */
190 
191 	{ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count),
192 	 AML_OFFSET(extended_irq.interrupt_count),
193 	 sizeof(u32)},
194 
195 	/* Copy every IRQ in the table, each is 32 bits */
196 
197 	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
198 	 AML_OFFSET(extended_irq.interrupts[0]),
199 	 0},
200 
201 	/* Optional resource_source (Index and String) */
202 
203 	{ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source),
204 	 ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
205 	 sizeof(struct aml_resource_extended_irq)}
206 };
207 
208 /*******************************************************************************
209  *
210  * acpi_rs_convert_dma
211  *
212  ******************************************************************************/
213 
214 struct acpi_rsconvert_info acpi_rs_convert_dma[6] = {
215 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA,
216 	 ACPI_RS_SIZE(struct acpi_resource_dma),
217 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)},
218 
219 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA,
220 	 sizeof(struct aml_resource_dma),
221 	 0},
222 
223 	/* Flags: transfer preference, bus mastering, channel speed */
224 
225 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer),
226 	 AML_OFFSET(dma.flags),
227 	 0},
228 
229 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master),
230 	 AML_OFFSET(dma.flags),
231 	 2},
232 
233 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type),
234 	 AML_OFFSET(dma.flags),
235 	 5},
236 
237 	/* DMA channel mask bits */
238 
239 	{ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]),
240 	 AML_OFFSET(dma.dma_channel_mask),
241 	 ACPI_RS_OFFSET(data.dma.channel_count)}
242 };
243 
244 /*******************************************************************************
245  *
246  * acpi_rs_convert_fixed_dma
247  *
248  ******************************************************************************/
249 
250 struct acpi_rsconvert_info acpi_rs_convert_fixed_dma[4] = {
251 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_DMA,
252 	 ACPI_RS_SIZE(struct acpi_resource_fixed_dma),
253 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_dma)},
254 
255 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_DMA,
256 	 sizeof(struct aml_resource_fixed_dma),
257 	 0},
258 
259 	/*
260 	 * These fields are contiguous in both the source and destination:
261 	 * request_lines
262 	 * Channels
263 	 */
264 	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_dma.request_lines),
265 	 AML_OFFSET(fixed_dma.request_lines),
266 	 2},
267 
268 	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_dma.width),
269 	 AML_OFFSET(fixed_dma.width),
270 	 1},
271 };
272