aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2007-07-06 05:39:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-06 13:23:43 -0400
commit41a5311465b9de6d18e78b733a2c6e1b33e89be8 (patch)
tree2a16e1e8e4bf2e6a788fcc5d96089736df58a4fc /drivers/pnp
parentd57d973101e87b2e30ccfa899fe36c4b2e32d217 (diff)
PNP SMCf010 quirk: work around Toshiba Portege 4000 ACPI issues
When we enable the SMCf010 IR device, the Toshiba Portege 4000 BIOS claims the device is working, but it really isn't configured correctly. The BIOS *will* configure it, but only if we call _SRS after (1) reversing the order of the SIR and FIR I/O port regions and (2) changing the IRQ from active-high to active-low. This patch addresses the 2.6.22 regression: "no irda0 interface (2.6.21 was OK), smsc does not find chip" I tested this on a Portege 4000. The smsc-ircc2 driver correctly detects the device, and "irattach irda0 -s && irdadump" shows transmitted and received packets. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: Andrey Borzenkov <arvidjaar@mail.ru> Cc: Samuel Ortiz <samuel@sortiz.org> Cc: "Linus Walleij (LD/EAB)" <linus.walleij@ericsson.com> Cc: Michal Piotrowski <michal.k.k.piotrowski@gmail.com> Cc: Adam Belay <ambx1@neo.rr.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pnp')
-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