Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=41a5311465b9de6d18e78b733a2c6e1b33e89be8
Commit:     41a5311465b9de6d18e78b733a2c6e1b33e89be8
Parent:     d57d973101e87b2e30ccfa899fe36c4b2e32d217
Author:     Bjorn Helgaas <[EMAIL PROTECTED]>
AuthorDate: Fri Jul 6 02:39:54 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri Jul 6 10:23:43 2007 -0700

    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 <[EMAIL PROTECTED]>
    Cc: Andrey Borzenkov <[EMAIL PROTECTED]>
    Cc: Samuel Ortiz <[EMAIL PROTECTED]>
    Cc: "Linus Walleij (LD/EAB)" <[EMAIL PROTECTED]>
    Cc: Michal Piotrowski <[EMAIL PROTECTED]>
    Cc: Adam Belay <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/pnp/quirks.c |   63 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 967a8e2..7c32366 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)
 
 static void quirk_smc_enable(struct pnp_dev *dev)
 {
-       /*
-        * If the BIOS left the device disabled, or it is enabled and
-        * responding correctly, we're in good shape.
-        */
-       if (!dev->active || quirk_smc_fir_enabled(dev))
+       struct resource fir, sir, irq;
+
+       pnp_activate_dev(dev);
+       if (quirk_smc_fir_enabled(dev))
                return;
 
        /*
@@ -152,16 +151,62 @@ static void quirk_smc_enable(struct pnp_dev *dev)
         * this.  Fortunately, they do fix things up if we auto-configure
         * the device using its _PRS and _SRS methods.
         */
-       dev_err(&dev->dev, "%s device not responding, auto-configuring "
-               "resources\n", dev->id->id);
+       dev_err(&dev->dev, "%s not responding at SIR 0x%lx, FIR 0x%lx; "
+               "auto-configuring\n", dev->id->id,
+               (unsigned long) pnp_port_start(dev, 0),
+               (unsigned long) pnp_port_start(dev, 1));
 
        pnp_disable_dev(dev);
        pnp_init_resource_table(&dev->res);
        pnp_auto_config_dev(dev);
        pnp_activate_dev(dev);
+       if (quirk_smc_fir_enabled(dev)) {
+               dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n",
+                       (unsigned long) pnp_port_start(dev, 0),
+                       (unsigned long) pnp_port_start(dev, 1));
+               return;
+       }
+
+       /*
+        * The Toshiba Portege 4000 _CRS reports the FIR region first,
+        * followed by the SIR region.  The BIOS will configure the bridge,
+        * but only if we call _SRS with SIR first, then FIR.  It also
+        * reports the IRQ as active high, when it is really active low.
+        */
+       dev_err(&dev->dev, "not responding at SIR 0x%lx, FIR 0x%lx; "
+               "swapping SIR/FIR and reconfiguring\n",
+               (unsigned long) pnp_port_start(dev, 0),
+               (unsigned long) pnp_port_start(dev, 1));
+
+       /*
+        * Clear IORESOURCE_AUTO so pnp_activate_dev() doesn't reassign
+        * these resources any more.
+        */
+       fir = dev->res.port_resource[0];
+       sir = dev->res.port_resource[1];
+       fir.flags &= ~IORESOURCE_AUTO;
+       sir.flags &= ~IORESOURCE_AUTO;
+
+       irq = dev->res.irq_resource[0];
+       irq.flags &= ~IORESOURCE_AUTO;
+       irq.flags &= ~IORESOURCE_BITS;
+       irq.flags |= IORESOURCE_IRQ_LOWEDGE;
+
+       pnp_disable_dev(dev);
+       dev->res.port_resource[0] = sir;
+       dev->res.port_resource[1] = fir;
+       dev->res.irq_resource[0] = irq;
+       pnp_activate_dev(dev);
+
+       if (quirk_smc_fir_enabled(dev)) {
+               dev_err(&dev->dev, "responds at SIR 0x%lx, FIR 0x%lx\n",
+                       (unsigned long) pnp_port_start(dev, 0),
+                       (unsigned long) pnp_port_start(dev, 1));
+               return;
+       }
 
-       if (!quirk_smc_fir_enabled(dev))
-               dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n");
+       dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\" and "
+               "email [EMAIL PROTECTED]");
 }
 
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to