aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp/quirks.c')
-rw-r--r--drivers/pnp/quirks.c71
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
211static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) 194static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)