diff options
Diffstat (limited to 'drivers/pnp/quirks.c')
-rw-r--r-- | drivers/pnp/quirks.c | 71 |
1 files changed, 27 insertions, 44 deletions
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 48e60171b3ba..e8515ce0d296 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -121,34 +121,46 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) | |||
121 | struct pnp_option *res; | 121 | struct pnp_option *res; |
122 | 122 | ||
123 | /* | 123 | /* |
124 | * Build a functional IRQ-less variant of each MPU option. | 124 | * Build a functional IRQ-optional variant of each MPU option. |
125 | */ | 125 | */ |
126 | 126 | ||
127 | for (res = dev->dependent; res; res = res->next) { | 127 | for (res = dev->dependent; res; res = res->next) { |
128 | struct pnp_option *curr; | 128 | struct pnp_option *curr; |
129 | struct pnp_port *port; | 129 | struct pnp_port *port; |
130 | struct pnp_port *copy; | 130 | struct pnp_port *copy_port; |
131 | struct pnp_irq *irq; | ||
132 | struct pnp_irq *copy_irq; | ||
131 | 133 | ||
132 | port = res->port; | 134 | port = res->port; |
133 | if (!port || !res->irq) | 135 | irq = res->irq; |
136 | if (!port || !irq) | ||
134 | continue; | 137 | continue; |
135 | 138 | ||
136 | copy = pnp_alloc(sizeof *copy); | 139 | copy_port = pnp_alloc(sizeof *copy_port); |
137 | if (!copy) | 140 | if (!copy_port) |
141 | break; | ||
142 | |||
143 | copy_irq = pnp_alloc(sizeof *copy_irq); | ||
144 | if (!copy_irq) { | ||
145 | kfree(copy_port); | ||
138 | break; | 146 | break; |
147 | } | ||
148 | |||
149 | *copy_port = *port; | ||
150 | copy_port->next = NULL; | ||
139 | 151 | ||
140 | copy->min = port->min; | 152 | *copy_irq = *irq; |
141 | copy->max = port->max; | 153 | copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL; |
142 | copy->align = port->align; | 154 | copy_irq->next = NULL; |
143 | copy->size = port->size; | ||
144 | copy->flags = port->flags; | ||
145 | 155 | ||
146 | curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); | 156 | curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); |
147 | if (!curr) { | 157 | if (!curr) { |
148 | kfree(copy); | 158 | kfree(copy_port); |
159 | kfree(copy_irq); | ||
149 | break; | 160 | break; |
150 | } | 161 | } |
151 | curr->port = copy; | 162 | curr->port = copy_port; |
163 | curr->irq = copy_irq; | ||
152 | 164 | ||
153 | if (prev) | 165 | if (prev) |
154 | prev->next = curr; | 166 | prev->next = curr; |
@@ -157,7 +169,7 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) | |||
157 | prev = curr; | 169 | prev = curr; |
158 | } | 170 | } |
159 | if (head) | 171 | if (head) |
160 | dev_info(&dev->dev, "adding IRQ-less MPU options\n"); | 172 | dev_info(&dev->dev, "adding IRQ-optional MPU options\n"); |
161 | 173 | ||
162 | return head; | 174 | return head; |
163 | } | 175 | } |
@@ -167,10 +179,6 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) | |||
167 | struct pnp_option *res; | 179 | struct pnp_option *res; |
168 | struct pnp_irq *irq; | 180 | struct pnp_irq *irq; |
169 | 181 | ||
170 | /* | ||
171 | * Distribute the independent IRQ over the dependent options | ||
172 | */ | ||
173 | |||
174 | res = dev->independent; | 182 | res = dev->independent; |
175 | if (!res) | 183 | if (!res) |
176 | return; | 184 | return; |
@@ -179,33 +187,8 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) | |||
179 | if (!irq || irq->next) | 187 | if (!irq || irq->next) |
180 | return; | 188 | return; |
181 | 189 | ||
182 | res = dev->dependent; | 190 | irq->flags |= IORESOURCE_IRQ_OPTIONAL; |
183 | if (!res) | 191 | dev_info(&dev->dev, "made independent IRQ optional\n"); |
184 | return; | ||
185 | |||
186 | while (1) { | ||
187 | struct pnp_irq *copy; | ||
188 | |||
189 | copy = pnp_alloc(sizeof *copy); | ||
190 | if (!copy) | ||
191 | break; | ||
192 | |||
193 | bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR); | ||
194 | copy->flags = irq->flags; | ||
195 | |||
196 | copy->next = res->irq; /* Yes, this is NULL */ | ||
197 | res->irq = copy; | ||
198 | |||
199 | if (!res->next) | ||
200 | break; | ||
201 | res = res->next; | ||
202 | } | ||
203 | kfree(irq); | ||
204 | |||
205 | res->next = quirk_isapnp_mpu_options(dev); | ||
206 | |||
207 | res = dev->independent; | ||
208 | res->irq = NULL; | ||
209 | } | 192 | } |
210 | 193 | ||
211 | static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) | 194 | static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) |