aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pnp/quirks.c63
1 files changed, 54 insertions, 9 deletions
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 967a8e22b2da..7c3236690cc3 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -136,11 +136,10 @@ static int quirk_smc_fir_enabled(struct pnp_dev *dev)
136 136
137static void quirk_smc_enable(struct pnp_dev *dev) 137static void quirk_smc_enable(struct pnp_dev *dev)
138{ 138{
139 /* 139 struct resource fir, sir, irq;
140 * If the BIOS left the device disabled, or it is enabled and 140
141 * responding correctly, we're in good shape. 141 pnp_activate_dev(dev);
142 */ 142 if (quirk_smc_fir_enabled(dev))
143 if (!dev->active || quirk_smc_fir_enabled(dev))
144 return; 143 return;
145 144
146 /* 145 /*
@@ -152,16 +151,62 @@ static void quirk_smc_enable(struct pnp_dev *dev)
152 * this. Fortunately, they do fix things up if we auto-configure 151 * this. Fortunately, they do fix things up if we auto-configure
153 * the device using its _PRS and _SRS methods. 152 * the device using its _PRS and _SRS methods.
154 */ 153 */
155 dev_err(&dev->dev, "%s device not responding, auto-configuring " 154 dev_err(&dev->dev, "%s not responding at SIR 0x%lx, FIR 0x%lx; "
156 "resources\n", dev->id->id); 155 "auto-configuring\n", dev->id->id,
156 (unsigned long) pnp_port_start(dev, 0),
157 (unsigned long) pnp_port_start(dev, 1));
157 158
158 pnp_disable_dev(dev); 159 pnp_disable_dev(dev);
159 pnp_init_resource_table(&dev->res); 160 pnp_init_resource_table(&dev->res);
160 pnp_auto_config_dev(dev); 161 pnp_auto_config_dev(dev);
161 pnp_activate_dev(dev); 162 pnp_activate_dev(dev);
163 if (quirk_smc_fir_enabled(dev)) {
164 dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n",
165 (unsigned long) pnp_port_start(dev, 0),
166 (unsigned long) pnp_port_start(dev, 1));
167 return;
168 }
169
170 /*
171 * The Toshiba Portege 4000 _CRS reports the FIR region first,
172 * followed by the SIR region. The BIOS will configure the bridge,
173 * but only if we call _SRS with SIR first, then FIR. It also
174 * reports the IRQ as active high, when it is really active low.
175 */
176 dev_err(&dev->dev, "not responding at SIR 0x%lx, FIR 0x%lx; "
177 "swapping SIR/FIR and reconfiguring\n",
178 (unsigned long) pnp_port_start(dev, 0),
179 (unsigned long) pnp_port_start(dev, 1));
180
181 /*
182 * Clear IORESOURCE_AUTO so pnp_activate_dev() doesn't reassign
183 * these resources any more.
184 */
185 fir = dev->res.port_resource[0];
186 sir = dev->res.port_resource[1];
187 fir.flags &= ~IORESOURCE_AUTO;
188 sir.flags &= ~IORESOURCE_AUTO;
189
190 irq = dev->res.irq_resource[0];
191 irq.flags &= ~IORESOURCE_AUTO;
192 irq.flags &= ~IORESOURCE_BITS;
193 irq.flags |= IORESOURCE_IRQ_LOWEDGE;
194
195 pnp_disable_dev(dev);
196 dev->res.port_resource[0] = sir;
197 dev->res.port_resource[1] = fir;
198 dev->res.irq_resource[0] = irq;
199 pnp_activate_dev(dev);
200
201 if (quirk_smc_fir_enabled(dev)) {
202 dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n",
203 (unsigned long) pnp_port_start(dev, 0),
204 (unsigned long) pnp_port_start(dev, 1));
205 return;
206 }
162 207
163 if (!quirk_smc_fir_enabled(dev)) 208 dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\" and "
164 dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n"); 209 "email bjorn.helgaas@hp.com\n");
165} 210}
166 211
167 212