ACPICA: Fix for resource descriptor optimization issues for _CRS/_SRC
[linux-2.6] / drivers / acpi / resources / rsirq.c
1 /*******************************************************************************
2  *
3  * Module Name: rsirq - IRQ resource descriptors
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2007, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
46
47 #define _COMPONENT          ACPI_RESOURCES
48 ACPI_MODULE_NAME("rsirq")
49
50 /*******************************************************************************
51  *
52  * acpi_rs_get_irq
53  *
54  ******************************************************************************/
55 struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
56         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
57          ACPI_RS_SIZE(struct acpi_resource_irq),
58          ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
59
60         /* Get the IRQ mask (bytes 1:2) */
61
62         {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
63          AML_OFFSET(irq.irq_mask),
64          ACPI_RS_OFFSET(data.irq.interrupt_count)},
65
66         /* Set default flags (others are zero) */
67
68         {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering),
69          ACPI_EDGE_SENSITIVE,
70          1},
71
72         /* Get the descriptor length (2 or 3 for IRQ descriptor) */
73
74         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length),
75          AML_OFFSET(irq.descriptor_type),
76          0},
77
78         /* All done if no flag byte present in descriptor */
79
80         {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
81
82         /* Get flags: Triggering[0], Polarity[3], Sharing[4] */
83
84         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
85          AML_OFFSET(irq.flags),
86          0},
87
88         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
89          AML_OFFSET(irq.flags),
90          3},
91
92         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
93          AML_OFFSET(irq.flags),
94          4}
95 };
96
97 /*******************************************************************************
98  *
99  * acpi_rs_set_irq
100  *
101  ******************************************************************************/
102
103 struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
104         /* Start with a default descriptor of length 3 */
105
106         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
107          sizeof(struct aml_resource_irq),
108          ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
109
110         /* Convert interrupt list to 16-bit IRQ bitmask */
111
112         {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
113          AML_OFFSET(irq.irq_mask),
114          ACPI_RS_OFFSET(data.irq.interrupt_count)},
115
116         /* Set the flags byte */
117
118         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
119          AML_OFFSET(irq.flags),
120          0},
121
122         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
123          AML_OFFSET(irq.flags),
124          3},
125
126         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
127          AML_OFFSET(irq.flags),
128          4},
129
130         /*
131          * All done if the output descriptor length is required to be 3
132          * (i.e., optimization to 2 bytes cannot be attempted)
133          */
134         {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
135          ACPI_RS_OFFSET(data.irq.descriptor_length),
136          3},
137
138         /* Set length to 2 bytes (no flags byte) */
139
140         {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)},
141
142         /*
143          * All done if the output descriptor length is required to be 2.
144          *
145          * TBD: Perhaps we should check for error if input flags are not
146          * compatible with a 2-byte descriptor.
147          */
148         {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
149          ACPI_RS_OFFSET(data.irq.descriptor_length),
150          2},
151
152         /* Reset length to 3 bytes (descriptor with flags byte) */
153
154         {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
155
156         /*
157          * Check if the flags byte is necessary. Not needed if the flags are:
158          * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
159          */
160         {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
161          ACPI_RS_OFFSET(data.irq.triggering),
162          ACPI_EDGE_SENSITIVE},
163
164         {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
165          ACPI_RS_OFFSET(data.irq.polarity),
166          ACPI_ACTIVE_HIGH},
167
168         {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
169          ACPI_RS_OFFSET(data.irq.sharable),
170          ACPI_EXCLUSIVE},
171
172         /* We can optimize to a 2-byte irq_no_flags() descriptor */
173
174         {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
175 };
176
177 /*******************************************************************************
178  *
179  * acpi_rs_convert_ext_irq
180  *
181  ******************************************************************************/
182
183 struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
184         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
185          ACPI_RS_SIZE(struct acpi_resource_extended_irq),
186          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)},
187
188         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ,
189          sizeof(struct aml_resource_extended_irq),
190          0},
191
192         /* Flag bits */
193
194         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer),
195          AML_OFFSET(extended_irq.flags),
196          0},
197
198         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering),
199          AML_OFFSET(extended_irq.flags),
200          1},
201
202         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity),
203          AML_OFFSET(extended_irq.flags),
204          2},
205
206         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable),
207          AML_OFFSET(extended_irq.flags),
208          3},
209
210         /* IRQ Table length (Byte4) */
211
212         {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count),
213          AML_OFFSET(extended_irq.interrupt_count),
214          sizeof(u32)}
215         ,
216
217         /* Copy every IRQ in the table, each is 32 bits */
218
219         {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
220          AML_OFFSET(extended_irq.interrupts[0]),
221          0}
222         ,
223
224         /* Optional resource_source (Index and String) */
225
226         {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source),
227          ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
228          sizeof(struct aml_resource_extended_irq)}
229 };
230
231 /*******************************************************************************
232  *
233  * acpi_rs_convert_dma
234  *
235  ******************************************************************************/
236
237 struct acpi_rsconvert_info acpi_rs_convert_dma[6] = {
238         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA,
239          ACPI_RS_SIZE(struct acpi_resource_dma),
240          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)},
241
242         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA,
243          sizeof(struct aml_resource_dma),
244          0},
245
246         /* Flags: transfer preference, bus mastering, channel speed */
247
248         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer),
249          AML_OFFSET(dma.flags),
250          0},
251
252         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master),
253          AML_OFFSET(dma.flags),
254          2},
255
256         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type),
257          AML_OFFSET(dma.flags),
258          5},
259
260         /* DMA channel mask bits */
261
262         {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]),
263          AML_OFFSET(dma.dma_channel_mask),
264          ACPI_RS_OFFSET(data.dma.channel_count)}
265 };