Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 May 2010 16:45:38 +0000 (09:45 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 May 2010 16:45:38 +0000 (09:45 -0700)
* 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (22 commits)
  ACPI: fix early DSDT dmi check warnings on ia64
  ACPICA: Update version to 20100428.
  ACPICA: Update/clarify some parameter names associated with acpi_handle
  ACPICA: Rename acpi_ex_system_do_suspend->acpi_ex_system_do_sleep
  ACPICA: Prevent possible allocation overrun during object copy
  ACPICA: Split large file, evgpeblk
  ACPICA: Add GPE support for dynamically loaded ACPI tables
  ACPICA: Clarify/rename some root table descriptor fields
  ACPICA: Update version to 20100331.
  ACPICA: Minimize the differences between linux GPE code and ACPICA code base
  ACPI: add boot option acpi=copy_dsdt to fix corrupt DSDT
  ACPICA: Update DSDT copy/detection.
  ACPICA: Add subsystem option to force copy of DSDT to local memory
  ACPICA: Add detection of corrupted/replaced DSDT
  ACPICA: Add write support for DataTable operation regions
  ACPICA: Fix for acpi_reallocate_root_table for incorrect root table copy
  ACPICA: Update comments/headers, no functional change
  ACPICA: Update version to 20100304
  ACPICA: Fix for possible fault in acpi_ex_release_mutex
  ACPICA: Standardize integer output for ACPICA warnings/errors
  ...

1  2 
Documentation/kernel-parameters.txt
arch/x86/kernel/acpi/boot.c
drivers/acpi/bus.c

index b9b0d7989f4e88ca1829f288dd7f9897fdaa4e1c,93f113a1b326d2ea06851bde0245194cf54f1ba2..b12bacd252fc92b2c737fdcc1ecb4c9390161e95
@@@ -99,7 -99,6 +99,7 @@@ parameter is applicable
        SWSUSP  Software suspend (hibernation) is enabled.
        SUSPEND System suspend states are enabled.
        FTRACE  Function tracing enabled.
 +      TPM     TPM drivers are enabled.
        TS      Appropriate touchscreen support is enabled.
        UMS     USB Mass Storage support is enabled.
        USB     USB support is enabled.
@@@ -152,6 -151,7 +152,7 @@@ and is between 256 and 4096 characters
                        strict -- Be less tolerant of platforms that are not
                                strictly ACPI specification compliant.
                        rsdt -- prefer RSDT over (default) XSDT
+                       copy_dsdt -- copy DSDT to memory
  
                        See also Documentation/power/pm.txt, pci=noacpi
  
                                    they are unmapped. Otherwise they are
                                    flushed before they will be reused, which
                                    is a lot of faster
 +                      off       - do not initialize any AMD IOMMU found in
 +                                  the system
  
        amijoy.map=     [HW,JOY] Amiga joystick support
                        Map of devices attached to JOY0DAT and JOY1DAT
                        as early as possible in order to facilitate early
                        boot debugging.
  
 -      ftrace_dump_on_oops
 +      ftrace_dump_on_oops[=orig_cpu]
                        [FTRACE] will dump the trace buffers on oops.
 +                      If no parameter is passed, ftrace will dump
 +                      buffers of all CPUs, but if you pass orig_cpu, it will
 +                      dump only the buffer of the CPU that triggered the
 +                      oops.
  
        ftrace_filter=[function-list]
                        [FTRACE] Limit the functions traced by the function
  
        libata.force=   [LIBATA] Force configurations.  The format is comma
                        separated list of "[ID:]VAL" where ID is
 -                      PORT[:DEVICE].  PORT and DEVICE are decimal numbers
 +                      PORT[.DEVICE].  PORT and DEVICE are decimal numbers
                        matching port, link or device.  Basically, it matches
                        the ATA ID string printed on console by libata.  If
                        the whole ID part is omitted, the last PORT and DEVICE
  
        tp720=          [HW,PS2]
  
 +      tpm_suspend_pcr=[HW,TPM]
 +                      Format: integer pcr id
 +                      Specify that at suspend time, the tpm driver
 +                      should extend the specified pcr with zeros,
 +                      as a workaround for some chips which fail to
 +                      flush the last written pcr on TPM_SaveState.
 +                      This will guarantee that all the other pcrs
 +                      are saved.
 +
        trace_buf_size=nn[KMG]
                        [FTRACE] will set tracing buffer size.
  
index 9a5ed58f09dcdcc0a80e5e14ab9b09bb062d44a3,b9629384263c30741d9dfcd4dc3568038773cc63..488be461a3805104746e5a38a819f2691bb97c09
@@@ -93,53 -93,6 +93,53 @@@ static u64 acpi_lapic_addr __initdata 
  enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
  
  
 +/*
 + * ISA irqs by default are the first 16 gsis but can be
 + * any gsi as specified by an interrupt source override.
 + */
 +static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
 +      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 +};
 +
 +static unsigned int gsi_to_irq(unsigned int gsi)
 +{
 +      unsigned int irq = gsi + NR_IRQS_LEGACY;
 +      unsigned int i;
 +
 +      for (i = 0; i < NR_IRQS_LEGACY; i++) {
 +              if (isa_irq_to_gsi[i] == gsi) {
 +                      return i;
 +              }
 +      }
 +
 +      /* Provide an identity mapping of gsi == irq
 +       * except on truly weird platforms that have
 +       * non isa irqs in the first 16 gsis.
 +       */
 +      if (gsi >= NR_IRQS_LEGACY)
 +              irq = gsi;
 +      else
 +              irq = gsi_end + 1 + gsi;
 +
 +      return irq;
 +}
 +
 +static u32 irq_to_gsi(int irq)
 +{
 +      unsigned int gsi;
 +
 +      if (irq < NR_IRQS_LEGACY)
 +              gsi = isa_irq_to_gsi[irq];
 +      else if (irq <= gsi_end)
 +              gsi = irq;
 +      else if (irq <= (gsi_end + NR_IRQS_LEGACY))
 +              gsi = irq - gsi_end;
 +      else
 +              gsi = 0xffffffff;
 +
 +      return gsi;
 +}
 +
  /*
   * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
   * to map the target physical address. The problem is that set_fixmap()
@@@ -360,7 -313,7 +360,7 @@@ acpi_parse_ioapic(struct acpi_subtable_
  /*
   * Parse Interrupt Source Override for the ACPI SCI
   */
 -static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
 +static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
  {
        if (trigger == 0)       /* compatible SCI trigger is level */
                trigger = 3;
         * If GSI is < 16, this will update its flags,
         * else it will create a new mp_irqs[] entry.
         */
 -      mp_override_legacy_irq(gsi, polarity, trigger, gsi);
 +      mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
  
        /*
         * stash over-ride to indicate we've been here
@@@ -404,10 -357,9 +404,10 @@@ acpi_parse_int_src_ovr(struct acpi_subt
        acpi_table_print_madt_entry(header);
  
        if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
 -              acpi_sci_ioapic_setup(intsrc->global_irq,
 +              acpi_sci_ioapic_setup(intsrc->source_irq,
                                      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
 -                                    (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
 +                                    (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
 +                                    intsrc->global_irq);
                return 0;
        }
  
@@@ -496,7 -448,7 +496,7 @@@ void __init acpi_pic_sci_set_trigger(un
  
  int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
  {
 -      *irq = gsi;
 +      *irq = gsi_to_irq(gsi);
  
  #ifdef CONFIG_X86_IO_APIC
        if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
        return 0;
  }
  
 +int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 +{
 +      if (isa_irq >= 16)
 +              return -1;
 +      *gsi = irq_to_gsi(isa_irq);
 +      return 0;
 +}
 +
  /*
   * success: return IRQ number (>=0)
   * failure: return < 0
@@@ -538,7 -482,7 +538,7 @@@ int acpi_register_gsi(struct device *de
                plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
        }
  #endif
 -      irq = plat_gsi;
 +      irq = gsi_to_irq(plat_gsi);
  
        return irq;
  }
@@@ -923,6 -867,29 +923,6 @@@ static int __init acpi_parse_madt_lapic
  extern int es7000_plat;
  #endif
  
 -int __init acpi_probe_gsi(void)
 -{
 -      int idx;
 -      int gsi;
 -      int max_gsi = 0;
 -
 -      if (acpi_disabled)
 -              return 0;
 -
 -      if (!acpi_ioapic)
 -              return 0;
 -
 -      max_gsi = 0;
 -      for (idx = 0; idx < nr_ioapics; idx++) {
 -              gsi = mp_gsi_routing[idx].gsi_end;
 -
 -              if (gsi > max_gsi)
 -                      max_gsi = gsi;
 -      }
 -
 -      return max_gsi + 1;
 -}
 -
  static void assign_to_mp_irq(struct mpc_intsrc *m,
                                    struct mpc_intsrc *mp_irq)
  {
@@@ -980,13 -947,13 +980,13 @@@ void __init mp_override_legacy_irq(u8 b
        mp_irq.dstirq = pin;    /* INTIN# */
  
        save_mp_irq(&mp_irq);
 +
 +      isa_irq_to_gsi[bus_irq] = gsi;
  }
  
  void __init mp_config_acpi_legacy_irqs(void)
  {
        int i;
 -      int ioapic;
 -      unsigned int dstapic;
        struct mpc_intsrc mp_irq;
  
  #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
                return;
  #endif
  
 -      /*
 -       * Locate the IOAPIC that manages the ISA IRQs (0-15).
 -       */
 -      ioapic = mp_find_ioapic(0);
 -      if (ioapic < 0)
 -              return;
 -      dstapic = mp_ioapics[ioapic].apicid;
 -
        /*
         * Use the default configuration for the IRQs 0-15.  Unless
         * overridden by (MADT) interrupt source override entries.
         */
        for (i = 0; i < 16; i++) {
 +              int ioapic, pin;
 +              unsigned int dstapic;
                int idx;
 +              u32 gsi;
 +
 +              /* Locate the gsi that irq i maps to. */
 +              if (acpi_isa_irq_to_gsi(i, &gsi))
 +                      continue;
 +
 +              /*
 +               * Locate the IOAPIC that manages the ISA IRQ.
 +               */
 +              ioapic = mp_find_ioapic(gsi);
 +              if (ioapic < 0)
 +                      continue;
 +              pin = mp_find_ioapic_pin(ioapic, gsi);
 +              dstapic = mp_ioapics[ioapic].apicid;
  
                for (idx = 0; idx < mp_irq_entries; idx++) {
                        struct mpc_intsrc *irq = mp_irqs + idx;
                                break;
  
                        /* Do we already have a mapping for this IOAPIC pin */
 -                      if (irq->dstapic == dstapic && irq->dstirq == i)
 +                      if (irq->dstapic == dstapic && irq->dstirq == pin)
                                break;
                }
  
                mp_irq.dstapic = dstapic;
                mp_irq.irqtype = mp_INT;
                mp_irq.srcbusirq = i; /* Identity mapped */
 -              mp_irq.dstirq = i;
 +              mp_irq.dstirq = pin;
  
                save_mp_irq(&mp_irq);
        }
@@@ -1117,6 -1076,11 +1117,6 @@@ int mp_register_gsi(struct device *dev
  
        ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
  
 -#ifdef CONFIG_X86_32
 -      if (ioapic_renumber_irq)
 -              gsi = ioapic_renumber_irq(ioapic, gsi);
 -#endif
 -
        if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
                printk(KERN_ERR "Invalid reference to IOAPIC pin "
                       "%d-%d\n", mp_ioapics[ioapic].apicid,
        set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
                             trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
                             polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 -      io_apic_set_pci_routing(dev, gsi, &irq_attr);
 +      io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
  
        return gsi;
  }
@@@ -1190,8 -1154,7 +1190,8 @@@ static int __init acpi_parse_madt_ioapi
         * pretend we got one so we can set the SCI flags.
         */
        if (!acpi_sci_override_gsi)
 -              acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
 +              acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
 +                                    acpi_gbl_FADT.sci_interrupt);
  
        /* Fill in identity legacy mappings where no override */
        mp_config_acpi_legacy_irqs();
@@@ -1613,6 -1576,10 +1613,10 @@@ static int __init parse_acpi(char *arg
        /* "acpi=noirq" disables ACPI interrupt routing */
        else if (strcmp(arg, "noirq") == 0) {
                acpi_noirq_set();
+       }
+       /* "acpi=copy_dsdt" copys DSDT */
+       else if (strcmp(arg, "copy_dsdt") == 0) {
+               acpi_gbl_copy_dsdt_locally = 1;
        } else {
                /* Core will printk when we return error. */
                return -EINVAL;
diff --combined drivers/acpi/bus.c
index 743576bf1bd79e5e7b8c6fc10bafb674d88c8803,e1bfe71642457a133ec20fa7f053855a95dac5cf..9042a85796685ee66dda133e55f4617016e01d00
@@@ -69,6 -69,44 +69,44 @@@ static struct dmi_system_id __cpuinitda
  };
  
  
+ #ifdef CONFIG_X86
+ static int set_copy_dsdt(const struct dmi_system_id *id)
+ {
+       printk(KERN_NOTICE "%s detected - "
+               "force copy of DSDT to local memory\n", id->ident);
+       acpi_gbl_copy_dsdt_locally = 1;
+       return 0;
+ }
+ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
+       /*
+        * Insyde BIOS on some TOSHIBA machines corrupt the DSDT.
+        * https://bugzilla.kernel.org/show_bug.cgi?id=14679
+        */
+       {
+        .callback = set_copy_dsdt,
+        .ident = "TOSHIBA Satellite A505",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"),
+               },
+       },
+       {
+        .callback = set_copy_dsdt,
+        .ident = "TOSHIBA Satellite L505D",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"),
+               },
+       },
+       {}
+ };
+ #else
+ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
+       {}
+ };
+ #endif
  /* --------------------------------------------------------------------------
                                  Device Management
     -------------------------------------------------------------------------- */
@@@ -527,7 -565,7 +565,7 @@@ int acpi_bus_generate_proc_event4(cons
        if (!event_is_open)
                return 0;
  
 -      event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
 +      event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
        if (!event)
                return -ENOMEM;
  
@@@ -813,6 -851,12 +851,12 @@@ void __init acpi_early_init(void
  
        acpi_gbl_permanent_mmap = 1;
  
+       /*
+        * If the machine falls into the DMI check table,
+        * DSDT will be copied to memory
+        */
+       dmi_check_system(dsdt_dmi_table);
        status = acpi_reallocate_root_table();
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR PREFIX