]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'pm/linux-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 00:43:41 +0000 (11:43 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 00:43:44 +0000 (11:43 +1100)
23 files changed:
1  2 
Documentation/kernel-parameters.txt
arch/arm/mach-mediatek/mediatek.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-sunxi/sunxi.c
arch/arm64/include/asm/acpi.h
arch/arm64/include/asm/irq.h
arch/arm64/kernel/acpi.c
drivers/acpi/nfit.c
drivers/acpi/osl.c
drivers/base/power/clock_ops.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
drivers/irqchip/irq-gic.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h
include/linux/acpi.h
include/linux/fwnode.h

index 046832ef14ce136d4192e6cf7b39fb54de75c522,a491aaecc8bb569bf88aa51f4eb238b358ddcd51..c76200afb7bb6575402427786decd10ce072dc7d
@@@ -167,7 -167,8 +167,8 @@@ bytes respectively. Such letter suffixe
  
        acpi=           [HW,ACPI,X86,ARM64]
                        Advanced Configuration and Power Interface
-                       Format: { force | off | strict | noirq | rsdt }
+                       Format: { force | off | strict | noirq | rsdt |
+                                 copy_dsdt }
                        force -- enable ACPI if default was off
                        off -- disable ACPI if default was on
                        noirq -- do not use ACPI for IRQ routing
                        you are really sure that your UEFI does sane gc and
                        fulfills the spec otherwise your board may brick.
  
 +      efi_fake_mem=   nn[KMG]@ss[KMG]:aa[,nn[KMG]@ss[KMG]:aa,..] [EFI; X86]
 +                      Add arbitrary attribute to specific memory range by
 +                      updating original EFI memory map.
 +                      Region of memory which aa attribute is added to is
 +                      from ss to ss+nn.
 +                      If efi_fake_mem=2G@4G:0x10000,2G@0x10a0000000:0x10000
 +                      is specified, EFI_MEMORY_MORE_RELIABLE(0x10000)
 +                      attribute is added to range 0x100000000-0x180000000 and
 +                      0x10a0000000-0x1120000000.
 +
 +                      Using this parameter you can do debugging of EFI memmap
 +                      related feature. For example, you can do debugging of
 +                      Address Range Mirroring feature even if your box
 +                      doesn't support it.
 +
        eisa_irq_edge=  [PARISC,HW]
                        See header of drivers/parisc/eisa.c.
  
                hwp_only
                        Only load intel_pstate on systems which support
                        hardware P state control (HWP) if available.
+               no_acpi
+                       Don't use ACPI processor performance control objects
+                       _PSS and _PPC specified limits.
  
        intremap=       [X86-64, Intel-IOMMU]
                        on      enable Interrupt Remapping (default)
                        cache-to-cache transfer latencies.
  
        rcutree.rcu_fanout_leaf= [KNL]
 -                      Increase the number of CPUs assigned to each
 -                      leaf rcu_node structure.  Useful for very large
 -                      systems.
 +                      Change the number of CPUs assigned to each
 +                      leaf rcu_node structure.  Useful for very
 +                      large systems, which will choose the value 64,
 +                      and for NUMA systems with large remote-access
 +                      latencies, which will choose a value aligned
 +                      with the appropriate hardware boundaries.
  
        rcutree.jiffies_till_sched_qs= [KNL]
                        Set required age in jiffies for a
index 19dc738c1abc5ab340d640c59a0ecccaa2f88aa5,a9549005097e035271ca34fae7a6a71caffdf956..d019a080a559a467acd503c94c0f70ec7c0050af
   */
  #include <linux/init.h>
  #include <asm/mach/arch.h>
-       clocksource_of_init();
 +#include <linux/of.h>
 +#include <linux/clk-provider.h>
 +#include <linux/clocksource.h>
 +
 +
 +#define GPT6_CON_MT65xx 0x10008060
 +#define GPT_ENABLE      0x31
 +
 +static void __init mediatek_timer_init(void)
 +{
 +      void __iomem *gpt_base;
 +
 +      if (of_machine_is_compatible("mediatek,mt6589") ||
 +          of_machine_is_compatible("mediatek,mt8135") ||
 +          of_machine_is_compatible("mediatek,mt8127")) {
 +              /* turn on GPT6 which ungates arch timer clocks */
 +              gpt_base = ioremap(GPT6_CON_MT65xx, 0x04);
 +
 +              /* enable clock and set to free-run */
 +              writel(GPT_ENABLE, gpt_base);
 +              iounmap(gpt_base);
 +      }
 +
 +      of_clk_init(NULL);
++      clocksource_probe();
 +};
  
  static const char * const mediatek_board_dt_compat[] = {
        "mediatek,mt6589",
@@@ -53,5 -27,4 +53,5 @@@
  
  DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
        .dt_compat      = mediatek_board_dt_compat,
 +      .init_time      = mediatek_timer_init,
  MACHINE_END
index 05c17eb2f2d9374122bdecffcd163931f2ab251c,bef41837bf7fd7090eccf768c2881662ac42025a..b18ebbefae09577e20b19e53167aca5ef11b8d86
@@@ -183,8 -183,7 +183,8 @@@ static struct device_node * __init omap
                                  of_get_property(np, "ti,timer-secure", NULL)))
                        continue;
  
 -              of_add_property(np, &device_disabled);
 +              if (!of_device_is_compatible(np, "ti,omap-counter32k"))
 +                      of_add_property(np, &device_disabled);
                return np;
        }
  
@@@ -395,6 -394,7 +395,6 @@@ static int __init __maybe_unused omap2_
        int ret;
        struct device_node *np = NULL;
        struct omap_hwmod *oh;
 -      void __iomem *vbase;
        const char *oh_name = "counter_32k";
  
        /*
  
        omap_hwmod_setup_one(oh_name);
  
 -      if (np) {
 -              vbase = of_iomap(np, 0);
 -              of_node_put(np);
 -      } else {
 -              vbase = omap_hwmod_get_mpu_rt_va(oh);
 -      }
 -
 -      if (!vbase) {
 -              pr_warn("%s: failed to get counter_32k resource\n", __func__);
 -              return -ENXIO;
 -      }
 -
        ret = omap_hwmod_enable(oh);
        if (ret) {
                pr_warn("%s: failed to enable counter_32k module (%d)\n",
                return ret;
        }
  
 -      ret = omap_init_clocksource_32k(vbase);
 -      if (ret) {
 -              pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
 -                                                      __func__, ret);
 -              omap_hwmod_idle(oh);
 -      }
 +      if (!of_have_populated_dt()) {
 +              void __iomem *vbase;
 +
 +              vbase = omap_hwmod_get_mpu_rt_va(oh);
  
 +              ret = omap_init_clocksource_32k(vbase);
 +              if (ret) {
 +                      pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
 +                                      __func__, ret);
 +                      omap_hwmod_idle(oh);
 +              }
 +      }
        return ret;
  }
  
@@@ -469,64 -476,7 +469,64 @@@ static void __init omap2_gptimer_clocks
                        clocksource_gpt.name, clksrc.rate);
  }
  
 -#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
 +static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src,
 +              const char *clkev_prop, int clksrc_nr, const char *clksrc_src,
 +              const char *clksrc_prop, bool gptimer)
 +{
 +      omap_clk_init();
 +      omap_dmtimer_init();
 +      omap2_gp_clockevent_init(clkev_nr, clkev_src, clkev_prop);
 +
 +      /* Enable the use of clocksource="gp_timer" kernel parameter */
 +      if (use_gptimer_clksrc || gptimer)
 +              omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src,
 +                                              clksrc_prop);
 +      else
 +              omap2_sync32k_clocksource_init();
 +}
 +
 +void __init omap_init_time(void)
 +{
 +      __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
 +                      2, "timer_sys_ck", NULL, false);
 +
 +      if (of_have_populated_dt())
-               clocksource_of_init();
++              clocksource_probe();
 +}
 +
 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
 +void __init omap3_secure_sync32k_timer_init(void)
 +{
 +      __omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure",
 +                      2, "timer_sys_ck", NULL, false);
 +}
 +#endif /* CONFIG_ARCH_OMAP3 */
 +
 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
 +void __init omap3_gptimer_timer_init(void)
 +{
 +      __omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
 +                      1, "timer_sys_ck", "ti,timer-alwon", true);
 +}
 +#endif
 +
 +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) ||                \
 +      defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
 +static void __init omap4_sync32k_timer_init(void)
 +{
 +      __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
 +                      2, "sys_clkin_ck", NULL, false);
 +}
 +
 +void __init omap4_local_timer_init(void)
 +{
 +      omap4_sync32k_timer_init();
-       clocksource_of_init();
++      clocksource_probe();
 +}
 +#endif
 +
 +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
 +
  /*
   * The realtime counter also called master counter, is a free-running
   * counter, which is related to real time. It produces the count used
   */
  static void __init realtime_counter_init(void)
  {
 +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
        void __iomem *base;
        static struct clk *sys_clk;
        unsigned long rate;
@@@ -637,15 -586,84 +637,15 @@@ sysclk1_based
        set_cntfreq();
  
        iounmap(base);
 -}
 -#else
 -static inline void __init realtime_counter_init(void)
 -{}
  #endif
 -
 -#define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \
 -                             clksrc_nr, clksrc_src, clksrc_prop)      \
 -void __init omap##name##_gptimer_timer_init(void)                     \
 -{                                                                     \
 -      omap_clk_init();                                        \
 -      omap_dmtimer_init();                                            \
 -      omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);    \
 -      omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src,         \
 -                                      clksrc_prop);                   \
  }
  
 -#define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop,        \
 -                              clksrc_nr, clksrc_src, clksrc_prop)     \
 -void __init omap##name##_sync32k_timer_init(void)             \
 -{                                                                     \
 -      omap_clk_init();                                        \
 -      omap_dmtimer_init();                                            \
 -      omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);    \
 -      /* Enable the use of clocksource="gp_timer" kernel parameter */ \
 -      if (use_gptimer_clksrc)                                         \
 -              omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \
 -                                              clksrc_prop);           \
 -      else                                                            \
 -              omap2_sync32k_clocksource_init();                       \
 -}
 -
 -#ifdef CONFIG_ARCH_OMAP2
 -OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon",
 -                      2, "timer_sys_ck", NULL);
 -#endif /* CONFIG_ARCH_OMAP2 */
 -
 -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
 -OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
 -                      2, "timer_sys_ck", NULL);
 -OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
 -                      2, "timer_sys_ck", NULL);
 -#endif /* CONFIG_ARCH_OMAP3 */
 -
 -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
 -      defined(CONFIG_SOC_AM43XX)
 -OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL,
 -                     1, "timer_sys_ck", "ti,timer-alwon");
 -#endif
 -
 -#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
 -      defined(CONFIG_SOC_DRA7XX)
 -static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
 -                             2, "sys_clkin_ck", NULL);
 -#endif
 -
 -#ifdef CONFIG_ARCH_OMAP4
 -#ifdef CONFIG_HAVE_ARM_TWD
 -void __init omap4_local_timer_init(void)
 -{
 -      omap4_sync32k_timer_init();
 -      clocksource_probe();
 -}
 -#else
 -void __init omap4_local_timer_init(void)
 -{
 -      omap4_sync32k_timer_init();
 -}
 -#endif /* CONFIG_HAVE_ARM_TWD */
 -#endif /* CONFIG_ARCH_OMAP4 */
 -
 -#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
  void __init omap5_realtime_timer_init(void)
  {
        omap4_sync32k_timer_init();
        realtime_counter_init();
  
-       clocksource_of_init();
+       clocksource_probe();
  }
  #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
  
index 8583a9ca86bd6f70220c4055fb9da8b916a7233a,223c9e99380d89fa7658a46ba67534d9c3c47776..c2be98f38e73b2006ea664b7089dc427a2575d8e
@@@ -26,11 -26,10 +26,11 @@@ static const char * const sunxi_board_d
        "allwinner,sun4i-a10",
        "allwinner,sun5i-a10s",
        "allwinner,sun5i-a13",
 +      "allwinner,sun5i-r8",
        NULL,
  };
  
 -DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
 +DT_MACHINE_START(SUNXI_DT, "Allwinner sun4i/sun5i Families")
        .dt_compat      = sunxi_board_dt_compat,
        .init_late      = sunxi_dt_cpufreq_init,
  MACHINE_END
@@@ -47,7 -46,7 +47,7 @@@ static void __init sun6i_timer_init(voi
        of_clk_init(NULL);
        if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
                sun6i_reset_init();
-       clocksource_of_init();
+       clocksource_probe();
  }
  
  DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
index 5f8a38dee2744d6655bb6eceb3cabf6917c80ad4,6894205797a3df0b5e233a464ea2199f7376032b..caafd63b8092d8102401112d811b1055f4cc3524
@@@ -12,7 -12,6 +12,6 @@@
  #ifndef _ASM_ACPI_H
  #define _ASM_ACPI_H
  
- #include <linux/irqchip/arm-gic-acpi.h>
  #include <linux/mm.h>
  #include <linux/psci.h>
  
@@@ -92,9 -91,4 +91,9 @@@ static inline const char *acpi_get_enab
  {
        return acpi_psci_present() ? "psci" : NULL;
  }
 +
 +#ifdef        CONFIG_ACPI_APEI
 +pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
 +#endif
 +
  #endif /*_ASM_ACPI_H*/
index 09169296c3cc4c235d10a0b040c68938eb4a4c80,94c53674a31d24f45b6b392d90ac840c6bde7589..23eb450b820ba03ce83b737f308fcd3d6b33f9a8
@@@ -1,23 -1,11 +1,10 @@@
  #ifndef __ASM_IRQ_H
  #define __ASM_IRQ_H
  
- #include <linux/irqchip/arm-gic-acpi.h>
  #include <asm-generic/irq.h>
  
  struct pt_regs;
  
 -extern void migrate_irqs(void);
  extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
  
- static inline void acpi_irq_init(void)
- {
-       /*
-        * Hardcode ACPI IRQ chip initialization to GICv2 for now.
-        * Proper irqchip infrastructure will be implemented along with
-        * incoming  GICv2m|GICv3|ITS bits.
-        */
-       acpi_gic_init();
- }
- #define acpi_irq_init acpi_irq_init
  #endif
diff --combined arch/arm64/kernel/acpi.c
index 137d537ddceb8001f15d9daa18c95631b561a085,d6463bba2360561e59acb1f0fa5dbac926f37dfa..d1ce8e2f98b99bcb1fba0bae25c08e8f851c4f4b
  #include <asm/cpu_ops.h>
  #include <asm/smp_plat.h>
  
 +#ifdef CONFIG_ACPI_APEI
 +# include <linux/efi.h>
 +# include <asm/pgtable.h>
 +#endif
 +
  int acpi_noirq = 1;           /* skip ACPI IRQ initialization */
  int acpi_disabled = 1;
  EXPORT_SYMBOL(acpi_disabled);
@@@ -210,52 -205,3 +210,27 @@@ void __init acpi_boot_table_init(void
                        disable_acpi();
        }
  }
- void __init acpi_gic_init(void)
- {
-       struct acpi_table_header *table;
-       acpi_status status;
-       acpi_size tbl_size;
-       int err;
-       if (acpi_disabled)
-               return;
-       status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
-       if (ACPI_FAILURE(status)) {
-               const char *msg = acpi_format_exception(status);
-               pr_err("Failed to get MADT table, %s\n", msg);
-               return;
-       }
-       err = gic_v2_acpi_init(table);
-       if (err)
-               pr_err("Failed to initialize GIC IRQ controller");
-       early_acpi_os_unmap_memory((char *)table, tbl_size);
- }
 +
 +#ifdef CONFIG_ACPI_APEI
 +pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
 +{
 +      /*
 +       * According to "Table 8 Map: EFI memory types to AArch64 memory
 +       * types" of UEFI 2.5 section 2.3.6.1, each EFI memory type is
 +       * mapped to a corresponding MAIR attribute encoding.
 +       * The EFI memory attribute advises all possible capabilities
 +       * of a memory region. We use the most efficient capability.
 +       */
 +
 +      u64 attr;
 +
 +      attr = efi_mem_attributes(addr);
 +      if (attr & EFI_MEMORY_WB)
 +              return PAGE_KERNEL;
 +      if (attr & EFI_MEMORY_WT)
 +              return __pgprot(PROT_NORMAL_WT);
 +      if (attr & EFI_MEMORY_WC)
 +              return __pgprot(PROT_NORMAL_NC);
 +      return __pgprot(PROT_DEVICE_nGnRnE);
 +}
 +#endif
diff --combined drivers/acpi/nfit.c
index a14ee291d1a70cf0dc053e351435de16ba00e472,bc18aa213bb1c9ce23d07cc60b54f505d7d14c81..6e26761a27dae90d0671b1edf38b2e8533d56df3
@@@ -27,7 -27,7 +27,7 @@@
   * For readq() and writeq() on 32-bit builds, the hi-lo, lo-hi order is
   * irrelevant.
   */
 -#include <asm-generic/io-64-nonatomic-hi-lo.h>
 +#include <linux/io-64-nonatomic-hi-lo.h>
  
  static bool force_enable_dimms;
  module_param(force_enable_dimms, bool, S_IRUGO|S_IWUSR);
@@@ -706,7 -706,7 +706,7 @@@ static ssize_t flags_show(struct devic
                flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
                flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
                flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-               flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+               flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
                flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
  }
  static DEVICE_ATTR_RO(flags);
@@@ -815,7 -815,7 +815,7 @@@ static int acpi_nfit_register_dimms(str
                        flags |= NDD_ALIASING;
  
                mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-               if (mem_flags & ACPI_NFIT_MEM_ARMED)
+               if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
                        flags |= NDD_UNARMED;
  
                rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
                  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
                  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
                  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
-                 mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+                 mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
  
        }
  
diff --combined drivers/acpi/osl.c
index 7d0848190b75e758c1243893bed084c1075672fd,3935745ac78bf83e2299172fef06f342a038b65a..32d684af0ec7c8a36781e5b7e712c7dd0e65b241
@@@ -43,7 -43,7 +43,7 @@@
  
  #include <asm/io.h>
  #include <asm/uaccess.h>
 -#include <asm-generic/io-64-nonatomic-lo-hi.h>
 +#include <linux/io-64-nonatomic-lo-hi.h>
  
  #include "internal.h"
  
@@@ -66,8 -66,6 +66,6 @@@ struct acpi_os_dpc 
  /* stuff for debugger support */
  int acpi_in_debugger;
  EXPORT_SYMBOL(acpi_in_debugger);
- extern char line_buf[80];
  #endif                                /*ENABLE_DEBUGGER */
  
  static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
@@@ -81,6 -79,7 +79,7 @@@ static struct workqueue_struct *kacpid_
  static struct workqueue_struct *kacpi_notify_wq;
  static struct workqueue_struct *kacpi_hotplug_wq;
  static bool acpi_os_initialized;
+ unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
  
  /*
   * This list of permanent mappings is for memory that may be accessed from
@@@ -856,17 -855,19 +855,19 @@@ acpi_os_install_interrupt_handler(u32 g
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
        }
+       acpi_sci_irq = irq;
  
        return AE_OK;
  }
  
- acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+ acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
  {
-       if (irq != acpi_gbl_FADT.sci_interrupt)
+       if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
                return AE_BAD_PARAMETER;
  
-       free_irq(irq, acpi_irq);
+       free_irq(acpi_sci_irq, acpi_irq);
        acpi_irq_handler = NULL;
+       acpi_sci_irq = INVALID_ACPI_IRQ;
  
        return AE_OK;
  }
@@@ -1180,8 -1181,8 +1181,8 @@@ void acpi_os_wait_events_complete(void
         * Make sure the GPE handler or the fixed event handler is not used
         * on another CPU after removal.
         */
-       if (acpi_irq_handler)
-               synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
+       if (acpi_sci_irq_valid())
+               synchronize_hardirq(acpi_sci_irq);
        flush_workqueue(kacpid_wq);
        flush_workqueue(kacpi_notify_wq);
  }
@@@ -1345,15 -1346,13 +1346,13 @@@ acpi_status acpi_os_signal_semaphore(ac
        return AE_OK;
  }
  
- #ifdef ACPI_FUTURE_USAGE
- u32 acpi_os_get_line(char *buffer)
+ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
  {
  #ifdef ENABLE_DEBUGGER
        if (acpi_in_debugger) {
                u32 chars;
  
-               kdb_read(buffer, sizeof(line_buf));
+               kdb_read(buffer, buffer_length);
  
                /* remove the CR kdb includes */
                chars = strlen(buffer) - 1;
        }
  #endif
  
-       return 0;
+       return AE_OK;
  }
- #endif                                /*  ACPI_FUTURE_USAGE  */
  
  acpi_status acpi_os_signal(u32 function, void *info)
  {
index 6ce76934057fcc15831a85400754c551294b35d9,fd0973b922a7508629b5d33348ccc7535989ca78..60ee5591ee8f0d58d8229bad412d0f5882064e6a
@@@ -17,7 -17,7 +17,7 @@@
  #include <linux/err.h>
  #include <linux/pm_runtime.h>
  
- #ifdef CONFIG_PM
+ #ifdef CONFIG_PM_CLK
  
  enum pce_status {
        PCE_STATUS_NONE = 0,
@@@ -93,7 -93,7 +93,7 @@@ static int __pm_clk_add(struct device *
                        return -ENOMEM;
                }
        } else {
 -              if (IS_ERR(clk) || !__clk_get(clk)) {
 +              if (IS_ERR(clk)) {
                        kfree(ce);
                        return -ENOENT;
                }
@@@ -127,9 -127,7 +127,9 @@@ int pm_clk_add(struct device *dev, cons
   * @clk: Clock pointer
   *
   * Add the clock to the list of clocks used for the power management of @dev.
 - * It will increment refcount on clock pointer, use clk_put() on it when done.
 + * The power-management code will take control of the clock reference, so
 + * callers should not call clk_put() on @clk after this function sucessfully
 + * returned.
   */
  int pm_clk_add_clk(struct device *dev, struct clk *clk)
  {
@@@ -406,7 -404,7 +406,7 @@@ int pm_clk_runtime_resume(struct devic
        return pm_generic_runtime_resume(dev);
  }
  
- #else /* !CONFIG_PM */
+ #else /* !CONFIG_PM_CLK */
  
  /**
   * enable_clock - Enable a device clock.
@@@ -486,7 -484,7 +486,7 @@@ static int pm_clk_notify(struct notifie
        return 0;
  }
  
- #endif /* !CONFIG_PM */
+ #endif /* !CONFIG_PM_CLK */
  
  /**
   * pm_clk_add_notifier - Add bus type notifier for power management clocks.
index 8a06b8e7ca43189586a4c4e700f74e2b82c492cb,1a9c5dc1e5f9c54de7fc77834de21719ea4258fb..71cfdf7c97086273b1cc8ae1235ecf919abcfda1
@@@ -2,6 -2,14 +2,14 @@@ menu "Clock Source drivers
  
  config CLKSRC_OF
        bool
+       select CLKSRC_PROBE
+ config CLKSRC_ACPI
+       bool
+       select CLKSRC_PROBE
+ config CLKSRC_PROBE
+       bool
  
  config CLKSRC_I8253
        bool
@@@ -115,14 -123,6 +123,14 @@@ config CLKSRC_PISTACHI
        bool
        select CLKSRC_OF
  
 +config CLKSRC_TI_32K
 +      bool "Texas Instruments 32.768 Hz Clocksource" if COMPILE_TEST
 +      depends on GENERIC_SCHED_CLOCK
 +      select CLKSRC_OF if OF
 +      help
 +        This option enables support for Texas Instruments 32.768 Hz clocksource
 +        available on many OMAP-like platforms.
 +
  config CLKSRC_STM32
        bool "Clocksource for STM32 SoCs" if !ARCH_STM32
        depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
  config ARM_ARCH_TIMER
        bool
        select CLKSRC_OF if OF
+       select CLKSRC_ACPI if ACPI
  
  config ARM_ARCH_TIMER_EVTSTREAM
        bool "Support for ARM architected timer event stream generation"
@@@ -287,10 -288,6 +296,10 @@@ config CLKSRC_MIPS_GI
        depends on MIPS_GIC
        select CLKSRC_OF
  
 +config CLKSRC_TANGO_XTAL
 +      bool
 +      select CLKSRC_OF
 +
  config CLKSRC_PXA
        def_bool y if ARCH_PXA || ARCH_SA1100
        select CLKSRC_OF if OF
index 063d78607c993d726639c8cd858029278c62bf5b,51856d50bccc33ac49793e7eff9bffc25ef19e80..56bd16e77ae37147da0fa4e977adffcb9bc1a4c6
@@@ -1,4 -1,4 +1,4 @@@
- obj-$(CONFIG_CLKSRC_OF)       += clksrc-of.o
+ obj-$(CONFIG_CLKSRC_PROBE)    += clksrc-probe.o
  obj-$(CONFIG_ATMEL_PIT)               += timer-atmel-pit.o
  obj-$(CONFIG_ATMEL_ST)                += timer-atmel-st.o
  obj-$(CONFIG_ATMEL_TCB_CLKSRC)        += tcb_clksrc.o
@@@ -45,7 -45,6 +45,7 @@@ obj-$(CONFIG_VF_PIT_TIMER)    += vf_pit_ti
  obj-$(CONFIG_CLKSRC_QCOM)     += qcom-timer.o
  obj-$(CONFIG_MTK_TIMER)               += mtk_timer.o
  obj-$(CONFIG_CLKSRC_PISTACHIO)        += time-pistachio.o
 +obj-$(CONFIG_CLKSRC_TI_32K)   += timer-ti-32k.o
  
  obj-$(CONFIG_ARM_ARCH_TIMER)          += arm_arch_timer.o
  obj-$(CONFIG_ARM_GLOBAL_TIMER)                += arm_global_timer.o
@@@ -57,11 -56,9 +57,11 @@@ obj-$(CONFIG_ARCH_KEYSTONE)         += timer-k
  obj-$(CONFIG_ARCH_INTEGRATOR_AP)      += timer-integrator-ap.o
  obj-$(CONFIG_CLKSRC_VERSATILE)                += versatile.o
  obj-$(CONFIG_CLKSRC_MIPS_GIC)         += mips-gic-timer.o
 +obj-$(CONFIG_CLKSRC_TANGO_XTAL)               += tango_xtal.o
  obj-$(CONFIG_CLKSRC_IMX_GPT)          += timer-imx-gpt.o
  obj-$(CONFIG_ASM9260_TIMER)           += asm9260_timer.o
  obj-$(CONFIG_H8300)                   += h8300_timer8.o
  obj-$(CONFIG_H8300_TMR16)             += h8300_timer16.o
  obj-$(CONFIG_H8300_TPU)                       += h8300_tpu.o
  obj-$(CONFIG_CLKSRC_ST_LPC)           += clksrc_st_lpc.o
 +obj-$(CONFIG_X86_NUMACHIP)            += numachip.o
index c737f7359974b1afe98650b05c2e67c27351d184,642fd49793b0a9284a83eddb3275ff627ca46763..1582c1c016b098b7d40cccbaf52f7d715a0586d2
@@@ -199,16 -199,6 +199,16 @@@ config ARM_SA1100_CPUFRE
  config ARM_SA1110_CPUFREQ
        bool
  
 +config ARM_SCPI_CPUFREQ
 +        tristate "SCPI based CPUfreq driver"
 +      depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL
 +        help
 +        This adds the CPUfreq driver support for ARM big.LITTLE platforms
 +        using SCPI protocol for CPU power management.
 +
 +        This driver uses SCPI Message Protocol driver to interact with the
 +        firmware providing the CPU DVFS functionality.
 +
  config ARM_SPEAR_CPUFREQ
        bool "SPEAr CPUFreq support"
        depends on PLAT_SPEAR
@@@ -237,3 -227,20 +237,20 @@@ config ARM_PXA2xx_CPUFRE
          This add the CPUFreq driver support for Intel PXA2xx SOCs.
  
          If in doubt, say N.
+ config ACPI_CPPC_CPUFREQ
+       tristate "CPUFreq driver based on the ACPI CPPC spec"
+       depends on ACPI
+       select ACPI_CPPC_LIB
+       default n
+       help
+         This adds a CPUFreq driver which uses CPPC methods
+         as described in the ACPIv5.1 spec. CPPC stands for
+         Collaborative Processor Performance Controls. It
+         is based on an abstract continuous scale of CPU
+         performance values which allows the remote power
+         processor to flexibly optimize for power and
+         performance. CPPC relies on power management firmware
+         support for its operation.
+         If in doubt, say N.
diff --combined drivers/cpufreq/Makefile
index ccfaa4c68a9a236998015e2fe2af3700759e6f3b,d11309c487d0ef1be2de721a137e888159fe418f..c0af1a1281c89134269445f9330d4d449c37135e
@@@ -1,6 -1,5 +1,5 @@@
  # CPUfreq core
  obj-$(CONFIG_CPU_FREQ)                        += cpufreq.o freq_table.o
- obj-$(CONFIG_PM_OPP)                  += cpufreq_opp.o
  
  # CPUfreq stats
  obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
@@@ -72,11 -71,12 +71,13 @@@ obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)  += s3
  obj-$(CONFIG_ARM_S5PV210_CPUFREQ)     += s5pv210-cpufreq.o
  obj-$(CONFIG_ARM_SA1100_CPUFREQ)      += sa1100-cpufreq.o
  obj-$(CONFIG_ARM_SA1110_CPUFREQ)      += sa1110-cpufreq.o
 +obj-$(CONFIG_ARM_SCPI_CPUFREQ)                += scpi-cpufreq.o
  obj-$(CONFIG_ARM_SPEAR_CPUFREQ)               += spear-cpufreq.o
  obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)     += tegra20-cpufreq.o
  obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)    += tegra124-cpufreq.o
  obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)        += vexpress-spc-cpufreq.o
+ obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
  
  ##################################################################################
  # PowerPC platform drivers
index bbcac3af2a7ab84804fa862fe6a31869ca35aca3,69a83626f1aed1ef78bbd6c25a2ffe3208d69274..16a7b68167444bba93e24d3d59769f0a08d55440
@@@ -304,6 -304,7 +304,6 @@@ void acpi_gpiochip_request_interrupts(s
        if (ACPI_FAILURE(status))
                return;
  
 -      INIT_LIST_HEAD(&acpi_gpio->events);
        acpi_walk_resources(handle, "_AEI",
                            acpi_gpiochip_request_interrupt, acpi_gpio);
  }
@@@ -388,6 -389,8 +388,8 @@@ struct acpi_gpio_lookup 
        struct acpi_gpio_info info;
        int index;
        int pin_index;
+       bool active_low;
+       struct acpi_device *adev;
        struct gpio_desc *desc;
        int n;
  };
@@@ -424,6 -427,65 +426,65 @@@ static int acpi_find_gpio(struct acpi_r
        return 1;
  }
  
+ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup,
+                                    struct acpi_gpio_info *info)
+ {
+       struct list_head res_list;
+       int ret;
+       INIT_LIST_HEAD(&res_list);
+       ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio,
+                                    lookup);
+       if (ret < 0)
+               return ret;
+       acpi_dev_free_resource_list(&res_list);
+       if (!lookup->desc)
+               return -ENOENT;
+       if (info) {
+               *info = lookup->info;
+               if (lookup->active_low)
+                       info->active_low = lookup->active_low;
+       }
+       return 0;
+ }
+ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
+                                    const char *propname, int index,
+                                    struct acpi_gpio_lookup *lookup)
+ {
+       struct acpi_reference_args args;
+       int ret;
+       memset(&args, 0, sizeof(args));
+       ret = acpi_node_get_property_reference(fwnode, propname, index, &args);
+       if (ret) {
+               struct acpi_device *adev = to_acpi_device_node(fwnode);
+               if (!adev)
+                       return ret;
+               if (!acpi_get_driver_gpio_data(adev, propname, index, &args))
+                       return ret;
+       }
+       /*
+        * The property was found and resolved, so need to lookup the GPIO based
+        * on returned args.
+        */
+       lookup->adev = args.adev;
+       if (args.nargs >= 2) {
+               lookup->index = args.args[0];
+               lookup->pin_index = args.args[1];
+               /* 3rd argument, if present is used to specify active_low. */
+               if (args.nargs >= 3)
+                       lookup->active_low = !!args.args[2];
+       }
+       return 0;
+ }
  /**
   * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
   * @adev: pointer to a ACPI device to get GPIO from
@@@ -451,8 -513,6 +512,6 @@@ struct gpio_desc *acpi_get_gpiod_by_ind
                                          struct acpi_gpio_info *info)
  {
        struct acpi_gpio_lookup lookup;
-       struct list_head resource_list;
-       bool active_low = false;
        int ret;
  
        if (!adev)
        lookup.index = index;
  
        if (propname) {
-               struct acpi_reference_args args;
                dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
  
-               memset(&args, 0, sizeof(args));
-               ret = acpi_dev_get_property_reference(adev, propname,
-                                                     index, &args);
-               if (ret) {
-                       bool found = acpi_get_driver_gpio_data(adev, propname,
-                                                              index, &args);
-                       if (!found)
-                               return ERR_PTR(ret);
-               }
+               ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev),
+                                               propname, index, &lookup);
+               if (ret)
+                       return ERR_PTR(ret);
  
-               /*
-                * The property was found and resolved so need to
-                * lookup the GPIO based on returned args instead.
-                */
-               adev = args.adev;
-               if (args.nargs >= 2) {
-                       lookup.index = args.args[0];
-                       lookup.pin_index = args.args[1];
-                       /*
-                        * 3rd argument, if present is used to
-                        * specify active_low.
-                        */
-                       if (args.nargs >= 3)
-                               active_low = !!args.args[2];
-               }
-               dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
-                       dev_name(&adev->dev), args.nargs,
-                       args.args[0], args.args[1], args.args[2]);
+               dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n",
+                       dev_name(&lookup.adev->dev), lookup.index,
+                       lookup.pin_index, lookup.active_low);
        } else {
                dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
+               lookup.adev = adev;
        }
  
-       INIT_LIST_HEAD(&resource_list);
-       ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
-                                    &lookup);
-       if (ret < 0)
-               return ERR_PTR(ret);
+       ret = acpi_gpio_resource_lookup(&lookup, info);
+       return ret ? ERR_PTR(ret) : lookup.desc;
+ }
+ /**
+  * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
+  * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
+  * @propname: Property name of the GPIO
+  * @index: index of GpioIo/GpioInt resource (starting from %0)
+  * @info: info pointer to fill in (optional)
+  *
+  * If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it.
+  * Otherwise (ie. it is a data-only non-device object), use the property-based
+  * GPIO lookup to get to the GPIO resource with the relevant information and use
+  * that to obtain the GPIO descriptor to return.
+  */
+ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+                                     const char *propname, int index,
+                                     struct acpi_gpio_info *info)
+ {
+       struct acpi_gpio_lookup lookup;
+       struct acpi_device *adev;
+       int ret;
  
-       acpi_dev_free_resource_list(&resource_list);
+       adev = to_acpi_device_node(fwnode);
+       if (adev)
+               return acpi_get_gpiod_by_index(adev, propname, index, info);
  
-       if (lookup.desc && info) {
-               *info = lookup.info;
-               if (active_low)
-                       info->active_low = active_low;
-       }
+       if (!is_acpi_data_node(fwnode))
+               return ERR_PTR(-ENODEV);
+       if (!propname)
+               return ERR_PTR(-EINVAL);
+       memset(&lookup, 0, sizeof(lookup));
+       lookup.index = index;
+       ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);
+       if (ret)
+               return ERR_PTR(ret);
  
-       return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
+       ret = acpi_gpio_resource_lookup(&lookup, info);
+       return ret ? ERR_PTR(ret) : lookup.desc;
  }
  
  /**
@@@ -602,25 -668,6 +667,25 @@@ acpi_gpio_adr_space_handler(u32 functio
                                break;
                        }
                }
 +
 +              /*
 +               * The same GPIO can be shared between operation region and
 +               * event but only if the access here is ACPI_READ. In that
 +               * case we "borrow" the event GPIO instead.
 +               */
 +              if (!found && agpio->sharable == ACPI_SHARED &&
 +                   function == ACPI_READ) {
 +                      struct acpi_gpio_event *event;
 +
 +                      list_for_each_entry(event, &achip->events, node) {
 +                              if (event->pin == pin) {
 +                                      desc = event->desc;
 +                                      found = true;
 +                                      break;
 +                              }
 +                      }
 +              }
 +
                if (!found) {
                        desc = gpiochip_request_own_desc(chip, pin,
                                                         "ACPI:OpRegion");
@@@ -737,7 -784,6 +802,7 @@@ void acpi_gpiochip_add(struct gpio_chi
        }
  
        acpi_gpio->chip = chip;
 +      INIT_LIST_HEAD(&acpi_gpio->events);
  
        status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
        if (ACPI_FAILURE(status)) {
diff --combined drivers/gpio/gpiolib.c
index 6798355c61c6f763c6d30cc5ec623d0afd873827,c52a70f3d0a8c0e2c97aa2d4fe9400d5d2ddfa1c..a18f00fc1bb87544cc59182e6f4a5515464a2f29
@@@ -15,7 -15,6 +15,7 @@@
  #include <linux/acpi.h>
  #include <linux/gpio/driver.h>
  #include <linux/gpio/machine.h>
 +#include <linux/pinctrl/consumer.h>
  
  #include "gpiolib.h"
  
@@@ -48,6 -47,8 +48,6 @@@
   */
  DEFINE_SPINLOCK(gpio_lock);
  
 -#define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio)
 -
  static DEFINE_MUTEX(gpio_lookup_lock);
  static LIST_HEAD(gpio_lookup_list);
  LIST_HEAD(gpio_chips);
@@@ -217,68 -218,6 +217,68 @@@ static int gpiochip_add_to_list(struct 
        return err;
  }
  
 +/**
 + * Convert a GPIO name to its descriptor
 + */
 +static struct gpio_desc *gpio_name_to_desc(const char * const name)
 +{
 +      struct gpio_chip *chip;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&gpio_lock, flags);
 +
 +      list_for_each_entry(chip, &gpio_chips, list) {
 +              int i;
 +
 +              for (i = 0; i != chip->ngpio; ++i) {
 +                      struct gpio_desc *gpio = &chip->desc[i];
 +
 +                      if (!gpio->name)
 +                              continue;
 +
 +                      if (!strcmp(gpio->name, name)) {
 +                              spin_unlock_irqrestore(&gpio_lock, flags);
 +                              return gpio;
 +                      }
 +              }
 +      }
 +
 +      spin_unlock_irqrestore(&gpio_lock, flags);
 +
 +      return NULL;
 +}
 +
 +/*
 + * Takes the names from gc->names and checks if they are all unique. If they
 + * are, they are assigned to their gpio descriptors.
 + *
 + * Returns -EEXIST if one of the names is already used for a different GPIO.
 + */
 +static int gpiochip_set_desc_names(struct gpio_chip *gc)
 +{
 +      int i;
 +
 +      if (!gc->names)
 +              return 0;
 +
 +      /* First check all names if they are unique */
 +      for (i = 0; i != gc->ngpio; ++i) {
 +              struct gpio_desc *gpio;
 +
 +              gpio = gpio_name_to_desc(gc->names[i]);
 +              if (gpio)
 +                      dev_warn(gc->dev, "Detected name collision for "
 +                               "GPIO name '%s'\n",
 +                               gc->names[i]);
 +      }
 +
 +      /* Then add all names to the GPIO descriptors */
 +      for (i = 0; i != gc->ngpio; ++i)
 +              gc->desc[i].name = gc->names[i];
 +
 +      return 0;
 +}
 +
  /**
   * gpiochip_add() - register a gpio_chip
   * @chip: the chip to register, with chip->base initialized
@@@ -351,10 -290,6 +351,10 @@@ int gpiochip_add(struct gpio_chip *chip
        if (!chip->owner && chip->dev && chip->dev->driver)
                chip->owner = chip->dev->driver->owner;
  
 +      status = gpiochip_set_desc_names(chip);
 +      if (status)
 +              goto err_remove_from_list;
 +
        status = of_gpiochip_add(chip);
        if (status)
                goto err_remove_chip;
@@@ -375,7 -310,6 +375,7 @@@ err_remove_chip
        acpi_gpiochip_remove(chip);
        gpiochip_free_hogs(chip);
        of_gpiochip_remove(chip);
 +err_remove_from_list:
        spin_lock_irqsave(&gpio_lock, flags);
        list_del(&chip->list);
        spin_unlock_irqrestore(&gpio_lock, flags);
@@@ -746,28 -680,6 +746,28 @@@ static void gpiochip_irqchip_remove(str
  
  #endif /* CONFIG_GPIOLIB_IRQCHIP */
  
 +/**
 + * gpiochip_generic_request() - request the gpio function for a pin
 + * @chip: the gpiochip owning the GPIO
 + * @offset: the offset of the GPIO to request for GPIO function
 + */
 +int gpiochip_generic_request(struct gpio_chip *chip, unsigned offset)
 +{
 +      return pinctrl_request_gpio(chip->base + offset);
 +}
 +EXPORT_SYMBOL_GPL(gpiochip_generic_request);
 +
 +/**
 + * gpiochip_generic_free() - free the gpio function from a pin
 + * @chip: the gpiochip to request the gpio function for
 + * @offset: the offset of the GPIO to free from GPIO function
 + */
 +void gpiochip_generic_free(struct gpio_chip *chip, unsigned offset)
 +{
 +      pinctrl_free_gpio(chip->base + offset);
 +}
 +EXPORT_SYMBOL_GPL(gpiochip_generic_free);
 +
  #ifdef CONFIG_PINCTRL
  
  /**
@@@ -927,14 -839,6 +927,14 @@@ static int __gpiod_request(struct gpio_
                spin_lock_irqsave(&gpio_lock, flags);
        }
  done:
 +      if (status < 0) {
 +              /* Clear flags that might have been set by the caller before
 +               * requesting the GPIO.
 +               */
 +              clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
 +              clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
 +              clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
 +      }
        spin_unlock_irqrestore(&gpio_lock, flags);
        return status;
  }
@@@ -1024,7 -928,7 +1024,7 @@@ const char *gpiochip_is_requested(struc
  {
        struct gpio_desc *desc;
  
 -      if (!GPIO_OFFSET_VALID(chip, offset))
 +      if (offset >= chip->ngpio)
                return NULL;
  
        desc = &chip->desc[offset];
@@@ -1831,13 -1735,6 +1831,13 @@@ static struct gpio_desc *of_find_gpio(s
        if (of_flags & OF_GPIO_ACTIVE_LOW)
                *flags |= GPIO_ACTIVE_LOW;
  
 +      if (of_flags & OF_GPIO_SINGLE_ENDED) {
 +              if (of_flags & OF_GPIO_ACTIVE_LOW)
 +                      *flags |= GPIO_OPEN_DRAIN;
 +              else
 +                      *flags |= GPIO_OPEN_SOURCE;
 +      }
 +
        return desc;
  }
  
@@@ -2056,28 -1953,13 +2056,28 @@@ struct gpio_desc *__must_check gpiod_ge
  }
  EXPORT_SYMBOL_GPL(gpiod_get_optional);
  
 +/**
 + * gpiod_parse_flags - helper function to parse GPIO lookup flags
 + * @desc:     gpio to be setup
 + * @lflags:   gpio_lookup_flags - returned from of_find_gpio() or
 + *            of_get_gpio_hog()
 + *
 + * Set the GPIO descriptor flags based on the given GPIO lookup flags.
 + */
 +static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
 +{
 +      if (lflags & GPIO_ACTIVE_LOW)
 +              set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 +      if (lflags & GPIO_OPEN_DRAIN)
 +              set_bit(FLAG_OPEN_DRAIN, &desc->flags);
 +      if (lflags & GPIO_OPEN_SOURCE)
 +              set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 +}
  
  /**
   * gpiod_configure_flags - helper function to configure a given GPIO
   * @desc:     gpio whose value will be assigned
   * @con_id:   function within the GPIO consumer
 - * @lflags:   gpio_lookup_flags - returned from of_find_gpio() or
 - *            of_get_gpio_hog()
   * @dflags:   gpiod_flags - optional GPIO initialization flags
   *
   * Return 0 on success, -ENOENT if no GPIO has been assigned to the
   * occurred while trying to acquire the GPIO.
   */
  static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 -              unsigned long lflags, enum gpiod_flags dflags)
 +                               enum gpiod_flags dflags)
  {
        int status;
  
 -      if (lflags & GPIO_ACTIVE_LOW)
 -              set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 -      if (lflags & GPIO_OPEN_DRAIN)
 -              set_bit(FLAG_OPEN_DRAIN, &desc->flags);
 -      if (lflags & GPIO_OPEN_SOURCE)
 -              set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 -
        /* No particular flag request, return here... */
        if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
                pr_debug("no flags found for %s\n", con_id);
@@@ -2155,13 -2044,11 +2155,13 @@@ struct gpio_desc *__must_check gpiod_ge
                return desc;
        }
  
 +      gpiod_parse_flags(desc, lookupflags);
 +
        status = gpiod_request(desc, con_id);
        if (status < 0)
                return ERR_PTR(status);
  
 -      status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
 +      status = gpiod_configure_flags(desc, con_id, flags);
        if (status < 0) {
                dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
                gpiod_put(desc);
@@@ -2191,7 -2078,6 +2191,7 @@@ struct gpio_desc *fwnode_get_named_gpio
  {
        struct gpio_desc *desc = ERR_PTR(-ENODEV);
        bool active_low = false;
 +      bool single_ended = false;
        int ret;
  
        if (!fwnode)
  
                desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, 0,
                                                &flags);
 -              if (!IS_ERR(desc))
 +              if (!IS_ERR(desc)) {
                        active_low = flags & OF_GPIO_ACTIVE_LOW;
 +                      single_ended = flags & OF_GPIO_SINGLE_ENDED;
 +              }
        } else if (is_acpi_node(fwnode)) {
                struct acpi_gpio_info info;
  
-               desc = acpi_get_gpiod_by_index(to_acpi_node(fwnode), propname, 0,
-                                              &info);
+               desc = acpi_node_get_gpiod(fwnode, propname, 0, &info);
                if (!IS_ERR(desc))
                        active_low = info.active_low;
        }
        if (IS_ERR(desc))
                return desc;
  
 +      if (active_low)
 +              set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 +
 +      if (single_ended) {
 +              if (active_low)
 +                      set_bit(FLAG_OPEN_DRAIN, &desc->flags);
 +              else
 +                      set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 +      }
 +
        ret = gpiod_request(desc, NULL);
        if (ret)
                return ERR_PTR(ret);
  
 -      /* Only value flag can be set from both DT and ACPI is active_low */
 -      if (active_low)
 -              set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 -
        return desc;
  }
  EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
@@@ -2284,8 -2161,6 +2283,8 @@@ int gpiod_hog(struct gpio_desc *desc, c
        chip = gpiod_to_chip(desc);
        hwnum = gpio_chip_hwgpio(desc);
  
 +      gpiod_parse_flags(desc, lflags);
 +
        local_desc = gpiochip_request_own_desc(chip, hwnum, name);
        if (IS_ERR(local_desc)) {
                pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
                return PTR_ERR(local_desc);
        }
  
 -      status = gpiod_configure_flags(desc, name, lflags, dflags);
 +      status = gpiod_configure_flags(desc, name, dflags);
        if (status < 0) {
                pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
                       name, chip->label, hwnum);
@@@ -2433,19 -2308,14 +2432,19 @@@ static void gpiolib_dbg_show(struct seq
        int                     is_irq;
  
        for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
 -              if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
 +              if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) {
 +                      if (gdesc->name) {
 +                              seq_printf(s, " gpio-%-3d (%-20.20s)\n",
 +                                         gpio, gdesc->name);
 +                      }
                        continue;
 +              }
  
                gpiod_get_direction(gdesc);
                is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
                is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags);
 -              seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s",
 -                      gpio, gdesc->label,
 +              seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s",
 +                      gpio, gdesc->name ? gdesc->name : "", gdesc->label,
                        is_out ? "out" : "in ",
                        chip->get
                                ? (chip->get(chip, i) ? "hi" : "lo")
diff --combined drivers/gpio/gpiolib.h
index 78e634d1c719b10846e4399de1c766f644d2f31c,e69c7157cdad16986735c69219703526f0793857..98ab08c0aa2d2d13344b6af003e6696129193907
@@@ -42,6 -42,9 +42,9 @@@ void acpi_gpiochip_free_interrupts(stru
  struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
                                          const char *propname, int index,
                                          struct acpi_gpio_info *info);
+ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+                                     const char *propname, int index,
+                                     struct acpi_gpio_info *info);
  
  int acpi_gpio_count(struct device *dev, const char *con_id);
  #else
@@@ -60,7 -63,12 +63,12 @@@ acpi_get_gpiod_by_index(struct acpi_dev
  {
        return ERR_PTR(-ENOSYS);
  }
+ static inline struct gpio_desc *
+ acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
+                   int index, struct acpi_gpio_info *info)
+ {
+       return ERR_PTR(-ENXIO);
+ }
  static inline int acpi_gpio_count(struct device *dev, const char *con_id)
  {
        return -ENODEV;
@@@ -89,10 -97,7 +97,10 @@@ struct gpio_desc 
  #define FLAG_USED_AS_IRQ 9    /* GPIO is connected to an IRQ */
  #define FLAG_IS_HOGGED        11      /* GPIO is hogged */
  
 +      /* Connection label */
        const char              *label;
 +      /* Name of the GPIO */
 +      const char              *name;
  };
  
  int gpiod_request(struct gpio_desc *desc, const char *label);
index 1d0e76855106cf946627dcc5c5aaa728a38c6bc8,d4add30d1d4650c507da403aca880f6157ef6681..515c823c1c95cee63b46c18bed35bb70260ae9a9
@@@ -41,7 -41,6 +41,6 @@@
  #include <linux/irqchip.h>
  #include <linux/irqchip/chained_irq.h>
  #include <linux/irqchip/arm-gic.h>
- #include <linux/irqchip/arm-gic-acpi.h>
  
  #include <asm/cputype.h>
  #include <asm/irq.h>
  
  #include "irq-gic-common.h"
  
 +#ifdef CONFIG_ARM64
 +#include <asm/cpufeature.h>
 +
 +static void gic_check_cpu_features(void)
 +{
 +      WARN_TAINT_ONCE(cpus_have_cap(ARM64_HAS_SYSREG_GIC_CPUIF),
 +                      TAINT_CPU_OUT_OF_SPEC,
 +                      "GICv3 system registers enabled, broken firmware!\n");
 +}
 +#else
 +#define gic_check_cpu_features()      do { } while(0)
 +#endif
 +
  union gic_base {
        void __iomem *common_base;
        void __percpu * __iomem *percpu_base;
@@@ -916,39 -902,28 +915,39 @@@ static void gic_irq_domain_unmap(struc
  {
  }
  
 -static int gic_irq_domain_xlate(struct irq_domain *d,
 -                              struct device_node *controller,
 -                              const u32 *intspec, unsigned int intsize,
 -                              unsigned long *out_hwirq, unsigned int *out_type)
 +static int gic_irq_domain_translate(struct irq_domain *d,
 +                                  struct irq_fwspec *fwspec,
 +                                  unsigned long *hwirq,
 +                                  unsigned int *type)
  {
 -      unsigned long ret = 0;
 +      if (is_of_node(fwspec->fwnode)) {
 +              if (fwspec->param_count < 3)
 +                      return -EINVAL;
  
 -      if (d->of_node != controller)
 -              return -EINVAL;
 -      if (intsize < 3)
 -              return -EINVAL;
 +              /* Get the interrupt number and add 16 to skip over SGIs */
 +              *hwirq = fwspec->param[1] + 16;
  
 -      /* Get the interrupt number and add 16 to skip over SGIs */
 -      *out_hwirq = intspec[1] + 16;
 +              /*
 +               * For SPIs, we need to add 16 more to get the GIC irq
 +               * ID number
 +               */
 +              if (!fwspec->param[0])
 +                      *hwirq += 16;
  
 -      /* For SPIs, we need to add 16 more to get the GIC irq ID number */
 -      if (!intspec[0])
 -              *out_hwirq += 16;
 +              *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
 +              return 0;
 +      }
  
 -      *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
 +      if (fwspec->fwnode->type == FWNODE_IRQCHIP) {
 +              if(fwspec->param_count != 2)
 +                      return -EINVAL;
  
 -      return ret;
 +              *hwirq = fwspec->param[0];
 +              *type = fwspec->param[1];
 +              return 0;
 +      }
 +
 +      return -EINVAL;
  }
  
  #ifdef CONFIG_SMP
@@@ -976,9 -951,10 +975,9 @@@ static int gic_irq_domain_alloc(struct 
        int i, ret;
        irq_hw_number_t hwirq;
        unsigned int type = IRQ_TYPE_NONE;
 -      struct of_phandle_args *irq_data = arg;
 +      struct irq_fwspec *fwspec = arg;
  
 -      ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args,
 -                                 irq_data->args_count, &hwirq, &type);
 +      ret = gic_irq_domain_translate(domain, fwspec, &hwirq, &type);
        if (ret)
                return ret;
  
  }
  
  static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = {
 -      .xlate = gic_irq_domain_xlate,
 +      .translate = gic_irq_domain_translate,
        .alloc = gic_irq_domain_alloc,
        .free = irq_domain_free_irqs_top,
  };
  static const struct irq_domain_ops gic_irq_domain_ops = {
        .map = gic_irq_domain_map,
        .unmap = gic_irq_domain_unmap,
 -      .xlate = gic_irq_domain_xlate,
  };
  
  static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
                           void __iomem *dist_base, void __iomem *cpu_base,
 -                         u32 percpu_offset, struct device_node *node)
 +                         u32 percpu_offset, struct fwnode_handle *handle)
  {
        irq_hw_number_t hwirq_base;
        struct gic_chip_data *gic;
  
        BUG_ON(gic_nr >= MAX_GIC_NR);
  
 +      gic_check_cpu_features();
 +
        gic = &gic_data[gic_nr];
  #ifdef CONFIG_GIC_NON_BANKED
        if (percpu_offset) { /* Frankein-GIC without banked registers... */
                gic_irqs = 1020;
        gic->gic_irqs = gic_irqs;
  
 -      if (node) {             /* DT case */
 -              gic->domain = irq_domain_add_linear(node, gic_irqs,
 -                                                  &gic_irq_domain_hierarchy_ops,
 -                                                  gic);
 -      } else {                /* Non-DT case */
 +      if (handle) {           /* DT/ACPI */
 +              gic->domain = irq_domain_create_linear(handle, gic_irqs,
 +                                                     &gic_irq_domain_hierarchy_ops,
 +                                                     gic);
 +      } else {                /* Legacy support */
                /*
                 * For primary GICs, skip over SGIs.
                 * For secondary GICs, skip over PPIs, too.
                        irq_base = irq_start;
                }
  
 -              gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
 +              gic->domain = irq_domain_add_legacy(NULL, gic_irqs, irq_base,
                                        hwirq_base, &gic_irq_domain_ops, gic);
        }
  
        gic_pm_init(gic);
  }
  
 -void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 -                         void __iomem *dist_base, void __iomem *cpu_base,
 -                         u32 percpu_offset, struct device_node *node)
 +void __init gic_init(unsigned int gic_nr, int irq_start,
 +                   void __iomem *dist_base, void __iomem *cpu_base)
  {
        /*
         * Non-DT/ACPI systems won't run a hypervisor, so let's not
         * bother with these...
         */
        static_key_slow_dec(&supports_deactivate);
 -      __gic_init_bases(gic_nr, irq_start, dist_base, cpu_base,
 -                       percpu_offset, node);
 +      __gic_init_bases(gic_nr, irq_start, dist_base, cpu_base, 0, NULL);
  }
  
  #ifdef CONFIG_OF
@@@ -1190,8 -1167,7 +1189,8 @@@ gic_of_init(struct device_node *node, s
        if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
                percpu_offset = 0;
  
 -      __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
 +      __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset,
 +                       &node->fwnode);
        if (!gic_cnt)
                gic_init_physaddr(node);
  
@@@ -1214,12 -1190,11 +1213,12 @@@ IRQCHIP_DECLARE(cortex_a9_gic, "arm,cor
  IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
  IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
  IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 +IRQCHIP_DECLARE(pl390, "arm,pl390", gic_of_init);
  
  #endif
  
  #ifdef CONFIG_ACPI
- static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
+ static phys_addr_t cpu_phy_base __initdata;
  
  static int __init
  gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
        return 0;
  }
  
- static int __init
gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-                               const unsigned long end)
+ /* The things you have to do to just *count* something... */
static int __init acpi_dummy_func(struct acpi_subtable_header *header,
+                                 const unsigned long end)
  {
-       struct acpi_madt_generic_distributor *dist;
+       return 0;
+ }
  
-       dist = (struct acpi_madt_generic_distributor *)header;
+ static bool __init acpi_gic_redist_is_present(void)
+ {
+       return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                    acpi_dummy_func, 0) > 0;
+ }
  
-       if (BAD_MADT_ENTRY(dist, end))
-               return -EINVAL;
+ static bool __init gic_validate_dist(struct acpi_subtable_header *header,
+                                    struct acpi_probe_entry *ape)
+ {
+       struct acpi_madt_generic_distributor *dist;
+       dist = (struct acpi_madt_generic_distributor *)header;
  
-       dist_phy_base = dist->base_address;
-       return 0;
+       return (dist->version == ape->driver_data &&
+               (dist->version != ACPI_MADT_GIC_VERSION_NONE ||
+                !acpi_gic_redist_is_present()));
  }
  
- int __init
- gic_v2_acpi_init(struct acpi_table_header *table)
+ #define ACPI_GICV2_DIST_MEM_SIZE      (SZ_4K)
+ #define ACPI_GIC_CPU_IF_MEM_SIZE      (SZ_8K)
+ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
+                                  const unsigned long end)
  {
+       struct acpi_madt_generic_distributor *dist;
        void __iomem *cpu_base, *dist_base;
 +      struct fwnode_handle *domain_handle;
        int count;
  
        /* Collect CPU base addresses */
-       count = acpi_parse_entries(ACPI_SIG_MADT,
-                                  sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_cpu, table,
-                                  ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+       count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+                                     gic_acpi_parse_madt_cpu, 0);
        if (count <= 0) {
                pr_err("No valid GICC entries exist\n");
                return -EINVAL;
        }
  
-       /*
-        * Find distributor base address. We expect one distributor entry since
-        * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-        */
-       count = acpi_parse_entries(ACPI_SIG_MADT,
-                                  sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_distributor, table,
-                                  ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-       if (count <= 0) {
-               pr_err("No valid GICD entries exist\n");
-               return -EINVAL;
-       } else if (count > 1) {
-               pr_err("More than one GICD entry detected\n");
-               return -EINVAL;
-       }
        cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
        if (!cpu_base) {
                pr_err("Unable to map GICC registers\n");
                return -ENOMEM;
        }
  
-       dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
+       dist = (struct acpi_madt_generic_distributor *)header;
+       dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
        if (!dist_base) {
                pr_err("Unable to map GICD registers\n");
                iounmap(cpu_base);
                static_key_slow_dec(&supports_deactivate);
  
        /*
 -       * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
 -       * as default IRQ domain to allow for GSI registration and GSI to IRQ
 -       * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
 +       * Initialize GIC instance zero (no multi-GIC support).
         */
 -      __gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
 -      irq_set_default_host(gic_data[0].domain);
 +      domain_handle = irq_domain_alloc_fwnode(dist_base);
 +      if (!domain_handle) {
 +              pr_err("Unable to allocate domain handle\n");
 +              iounmap(cpu_base);
 +              iounmap(dist_base);
 +              return -ENOMEM;
 +      }
 +
 +      __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
  
 -      acpi_irq_model = ACPI_IRQ_MODEL_GIC;
 +      acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
        return 0;
  }
+ IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+                    gic_validate_dist, ACPI_MADT_GIC_VERSION_V2,
+                    gic_v2_acpi_init);
+ IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+                    gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE,
+                    gic_v2_acpi_init);
  #endif
diff --combined drivers/pci/pci-driver.c
index 61122fa0879b0314f9802e49b337907e0a294d86,306124bba61e2a1dbf3e116e33b8768db192bc25..4446fcb5effd347d87fb6314473297acc4558769
@@@ -172,7 -172,7 +172,7 @@@ static ssize_t store_remove_id(struct d
        __u32 vendor, device, subvendor = PCI_ANY_ID,
                subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
        int fields = 0;
 -      int retval = -ENODEV;
 +      size_t retval = -ENODEV;
  
        fields = sscanf(buf, "%x %x %x %x %x %x",
                        &vendor, &device, &subvendor, &subdevice,
                    !((id->class ^ class) & class_mask)) {
                        list_del(&dynid->node);
                        kfree(dynid);
 -                      retval = 0;
 +                      retval = count;
                        break;
                }
        }
        spin_unlock(&pdrv->dynids.lock);
  
 -      if (retval)
 -              return retval;
 -      return count;
 +      return retval;
  }
  static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
  
@@@ -682,10 -684,16 +682,16 @@@ static int pci_pm_prepare(struct devic
        return pci_dev_keep_suspended(to_pci_dev(dev));
  }
  
+ static void pci_pm_complete(struct device *dev)
+ {
+       pci_dev_complete_resume(to_pci_dev(dev));
+       pm_complete_with_resume_check(dev);
+ }
  
  #else /* !CONFIG_PM_SLEEP */
  
  #define pci_pm_prepare        NULL
+ #define pci_pm_complete       NULL
  
  #endif /* !CONFIG_PM_SLEEP */
  
@@@ -1216,6 -1224,7 +1222,7 @@@ static int pci_pm_runtime_idle(struct d
  
  static const struct dev_pm_ops pci_dev_pm_ops = {
        .prepare = pci_pm_prepare,
+       .complete = pci_pm_complete,
        .suspend = pci_pm_suspend,
        .resume = pci_pm_resume,
        .freeze = pci_pm_freeze,
diff --combined drivers/pci/pci.c
index 2b28a4e77ea40308c1d10310a6947798b96db998,78693fc5dbe9e680952687d4a0f04d08e7fb0ca6..314db8c1047a30228f68072f820d7f40babc2ad0
@@@ -27,7 -27,6 +27,7 @@@
  #include <linux/pci_hotplug.h>
  #include <asm-generic/pci-bridge.h>
  #include <asm/setup.h>
 +#include <linux/aer.h>
  #include "pci.h"
  
  const char *pci_power_names[] = {
@@@ -458,30 -457,6 +458,30 @@@ struct resource *pci_find_parent_resour
  }
  EXPORT_SYMBOL(pci_find_parent_resource);
  
 +/**
 + * pci_find_pcie_root_port - return PCIe Root Port
 + * @dev: PCI device to query
 + *
 + * Traverse up the parent chain and return the PCIe Root Port PCI Device
 + * for a given PCI Device.
 + */
 +struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev)
 +{
 +      struct pci_dev *bridge, *highest_pcie_bridge = NULL;
 +
 +      bridge = pci_upstream_bridge(dev);
 +      while (bridge && pci_is_pcie(bridge)) {
 +              highest_pcie_bridge = bridge;
 +              bridge = pci_upstream_bridge(bridge);
 +      }
 +
 +      if (pci_pcie_type(highest_pcie_bridge) != PCI_EXP_TYPE_ROOT_PORT)
 +              return NULL;
 +
 +      return highest_pcie_bridge;
 +}
 +EXPORT_SYMBOL(pci_find_pcie_root_port);
 +
  /**
   * pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos
   * @dev: the PCI device to operate on
@@@ -509,7 -484,7 +509,7 @@@ int pci_wait_for_pending(struct pci_de
  }
  
  /**
 - * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
 + * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
   * @dev: PCI device to have its BARs restored
   *
   * Restore the BAR values for a given device, so as to make it
@@@ -519,10 -494,6 +519,10 @@@ static void pci_restore_bars(struct pci
  {
        int i;
  
 +      /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
 +      if (dev->is_virtfn)
 +              return;
 +
        for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
                pci_update_resource(dev, i);
  }
@@@ -1128,8 -1099,6 +1128,8 @@@ void pci_restore_state(struct pci_dev *
        pci_restore_ats_state(dev);
        pci_restore_vc_state(dev);
  
 +      pci_cleanup_aer_error_status_regs(dev);
 +
        pci_restore_config_space(dev);
  
        pci_restore_pcix_state(dev);
@@@ -1741,15 -1710,7 +1741,7 @@@ static void pci_pme_list_scan(struct wo
        mutex_unlock(&pci_pme_list_mutex);
  }
  
- /**
-  * pci_pme_active - enable or disable PCI device's PME# function
-  * @dev: PCI device to handle.
-  * @enable: 'true' to enable PME# generation; 'false' to disable it.
-  *
-  * The caller must verify that the device is capable of generating PME# before
-  * calling this function with @enable equal to 'true'.
-  */
- void pci_pme_active(struct pci_dev *dev, bool enable)
+ static void __pci_pme_active(struct pci_dev *dev, bool enable)
  {
        u16 pmcsr;
  
                pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
  
        pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
+ }
+ /**
+  * pci_pme_active - enable or disable PCI device's PME# function
+  * @dev: PCI device to handle.
+  * @enable: 'true' to enable PME# generation; 'false' to disable it.
+  *
+  * The caller must verify that the device is capable of generating PME# before
+  * calling this function with @enable equal to 'true'.
+  */
+ void pci_pme_active(struct pci_dev *dev, bool enable)
+ {
+       __pci_pme_active(dev, enable);
  
        /*
         * PCI (as opposed to PCIe) PME requires that the device have
@@@ -2063,17 -2037,60 +2068,60 @@@ EXPORT_SYMBOL_GPL(pci_dev_run_wake)
   * reconfigured due to wakeup settings difference between system and runtime
   * suspend and the current power state of it is suitable for the upcoming
   * (system) transition.
+  *
+  * If the device is not configured for system wakeup, disable PME for it before
+  * returning 'true' to prevent it from waking up the system unnecessarily.
   */
  bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
  {
        struct device *dev = &pci_dev->dev;
  
        if (!pm_runtime_suspended(dev)
-           || (device_can_wakeup(dev) && !device_may_wakeup(dev))
+           || pci_target_state(pci_dev) != pci_dev->current_state
            || platform_pci_need_resume(pci_dev))
                return false;
  
-       return pci_target_state(pci_dev) == pci_dev->current_state;
+       /*
+        * At this point the device is good to go unless it's been configured
+        * to generate PME at the runtime suspend time, but it is not supposed
+        * to wake up the system.  In that case, simply disable PME for it
+        * (it will have to be re-enabled on exit from system resume).
+        *
+        * If the device's power state is D3cold and the platform check above
+        * hasn't triggered, the device's configuration is suitable and we don't
+        * need to manipulate it at all.
+        */
+       spin_lock_irq(&dev->power.lock);
+       if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold &&
+           !device_may_wakeup(dev))
+               __pci_pme_active(pci_dev, false);
+       spin_unlock_irq(&dev->power.lock);
+       return true;
+ }
+ /**
+  * pci_dev_complete_resume - Finalize resume from system sleep for a device.
+  * @pci_dev: Device to handle.
+  *
+  * If the device is runtime suspended and wakeup-capable, enable PME for it as
+  * it might have been disabled during the prepare phase of system suspend if
+  * the device was not configured for system wakeup.
+  */
+ void pci_dev_complete_resume(struct pci_dev *pci_dev)
+ {
+       struct device *dev = &pci_dev->dev;
+       if (!pci_dev_run_wake(pci_dev))
+               return;
+       spin_lock_irq(&dev->power.lock);
+       if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold)
+               __pci_pme_active(pci_dev, true);
+       spin_unlock_irq(&dev->power.lock);
  }
  
  void pci_config_pm_runtime_get(struct pci_dev *pdev)
@@@ -2179,198 -2196,6 +2227,198 @@@ void pci_pm_init(struct pci_dev *dev
        }
  }
  
 +static unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop)
 +{
 +      unsigned long flags = IORESOURCE_PCI_FIXED;
 +
 +      switch (prop) {
 +      case PCI_EA_P_MEM:
 +      case PCI_EA_P_VF_MEM:
 +              flags |= IORESOURCE_MEM;
 +              break;
 +      case PCI_EA_P_MEM_PREFETCH:
 +      case PCI_EA_P_VF_MEM_PREFETCH:
 +              flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 +              break;
 +      case PCI_EA_P_IO:
 +              flags |= IORESOURCE_IO;
 +              break;
 +      default:
 +              return 0;
 +      }
 +
 +      return flags;
 +}
 +
 +static struct resource *pci_ea_get_resource(struct pci_dev *dev, u8 bei,
 +                                          u8 prop)
 +{
 +      if (bei <= PCI_EA_BEI_BAR5 && prop <= PCI_EA_P_IO)
 +              return &dev->resource[bei];
 +#ifdef CONFIG_PCI_IOV
 +      else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5 &&
 +               (prop == PCI_EA_P_VF_MEM || prop == PCI_EA_P_VF_MEM_PREFETCH))
 +              return &dev->resource[PCI_IOV_RESOURCES +
 +                                    bei - PCI_EA_BEI_VF_BAR0];
 +#endif
 +      else if (bei == PCI_EA_BEI_ROM)
 +              return &dev->resource[PCI_ROM_RESOURCE];
 +      else
 +              return NULL;
 +}
 +
 +/* Read an Enhanced Allocation (EA) entry */
 +static int pci_ea_read(struct pci_dev *dev, int offset)
 +{
 +      struct resource *res;
 +      int ent_size, ent_offset = offset;
 +      resource_size_t start, end;
 +      unsigned long flags;
 +      u32 dw0, bei, base, max_offset;
 +      u8 prop;
 +      bool support_64 = (sizeof(resource_size_t) >= 8);
 +
 +      pci_read_config_dword(dev, ent_offset, &dw0);
 +      ent_offset += 4;
 +
 +      /* Entry size field indicates DWORDs after 1st */
 +      ent_size = ((dw0 & PCI_EA_ES) + 1) << 2;
 +
 +      if (!(dw0 & PCI_EA_ENABLE)) /* Entry not enabled */
 +              goto out;
 +
 +      bei = (dw0 & PCI_EA_BEI) >> 4;
 +      prop = (dw0 & PCI_EA_PP) >> 8;
 +
 +      /*
 +       * If the Property is in the reserved range, try the Secondary
 +       * Property instead.
 +       */
 +      if (prop > PCI_EA_P_BRIDGE_IO && prop < PCI_EA_P_MEM_RESERVED)
 +              prop = (dw0 & PCI_EA_SP) >> 16;
 +      if (prop > PCI_EA_P_BRIDGE_IO)
 +              goto out;
 +
 +      res = pci_ea_get_resource(dev, bei, prop);
 +      if (!res) {
 +              dev_err(&dev->dev, "Unsupported EA entry BEI: %u\n", bei);
 +              goto out;
 +      }
 +
 +      flags = pci_ea_flags(dev, prop);
 +      if (!flags) {
 +              dev_err(&dev->dev, "Unsupported EA properties: %#x\n", prop);
 +              goto out;
 +      }
 +
 +      /* Read Base */
 +      pci_read_config_dword(dev, ent_offset, &base);
 +      start = (base & PCI_EA_FIELD_MASK);
 +      ent_offset += 4;
 +
 +      /* Read MaxOffset */
 +      pci_read_config_dword(dev, ent_offset, &max_offset);
 +      ent_offset += 4;
 +
 +      /* Read Base MSBs (if 64-bit entry) */
 +      if (base & PCI_EA_IS_64) {
 +              u32 base_upper;
 +
 +              pci_read_config_dword(dev, ent_offset, &base_upper);
 +              ent_offset += 4;
 +
 +              flags |= IORESOURCE_MEM_64;
 +
 +              /* entry starts above 32-bit boundary, can't use */
 +              if (!support_64 && base_upper)
 +                      goto out;
 +
 +              if (support_64)
 +                      start |= ((u64)base_upper << 32);
 +      }
 +
 +      end = start + (max_offset | 0x03);
 +
 +      /* Read MaxOffset MSBs (if 64-bit entry) */
 +      if (max_offset & PCI_EA_IS_64) {
 +              u32 max_offset_upper;
 +
 +              pci_read_config_dword(dev, ent_offset, &max_offset_upper);
 +              ent_offset += 4;
 +
 +              flags |= IORESOURCE_MEM_64;
 +
 +              /* entry too big, can't use */
 +              if (!support_64 && max_offset_upper)
 +                      goto out;
 +
 +              if (support_64)
 +                      end += ((u64)max_offset_upper << 32);
 +      }
 +
 +      if (end < start) {
 +              dev_err(&dev->dev, "EA Entry crosses address boundary\n");
 +              goto out;
 +      }
 +
 +      if (ent_size != ent_offset - offset) {
 +              dev_err(&dev->dev,
 +                      "EA Entry Size (%d) does not match length read (%d)\n",
 +                      ent_size, ent_offset - offset);
 +              goto out;
 +      }
 +
 +      res->name = pci_name(dev);
 +      res->start = start;
 +      res->end = end;
 +      res->flags = flags;
 +
 +      if (bei <= PCI_EA_BEI_BAR5)
 +              dev_printk(KERN_DEBUG, &dev->dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
 +                         bei, res, prop);
 +      else if (bei == PCI_EA_BEI_ROM)
 +              dev_printk(KERN_DEBUG, &dev->dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
 +                         res, prop);
 +      else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5)
 +              dev_printk(KERN_DEBUG, &dev->dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
 +                         bei - PCI_EA_BEI_VF_BAR0, res, prop);
 +      else
 +              dev_printk(KERN_DEBUG, &dev->dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
 +                         bei, res, prop);
 +
 +out:
 +      return offset + ent_size;
 +}
 +
 +/* Enhanced Allocation Initalization */
 +void pci_ea_init(struct pci_dev *dev)
 +{
 +      int ea;
 +      u8 num_ent;
 +      int offset;
 +      int i;
 +
 +      /* find PCI EA capability in list */
 +      ea = pci_find_capability(dev, PCI_CAP_ID_EA);
 +      if (!ea)
 +              return;
 +
 +      /* determine the number of entries */
 +      pci_bus_read_config_byte(dev->bus, dev->devfn, ea + PCI_EA_NUM_ENT,
 +                                      &num_ent);
 +      num_ent &= PCI_EA_NUM_ENT_MASK;
 +
 +      offset = ea + PCI_EA_FIRST_ENT;
 +
 +      /* Skip DWORD 2 for type 1 functions */
 +      if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
 +              offset += 4;
 +
 +      /* parse each EA entry */
 +      for (i = 0; i < num_ent; ++i)
 +              offset = pci_ea_read(dev, offset);
 +}
 +
  static void pci_add_saved_cap(struct pci_dev *pci_dev,
        struct pci_cap_saved_state *new_cap)
  {
diff --combined drivers/pci/pci.h
index a1607331693ece030bbb3a8f08064f0f2887807e,037e787a3ad582c62121175a6b17339ed546d83b..fd2f03fa53f33a34977fc8713fd8cf6759cad2d5
@@@ -75,10 -75,10 +75,11 @@@ void pci_disable_enabled_device(struct 
  int pci_finish_runtime_suspend(struct pci_dev *dev);
  int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
  bool pci_dev_keep_suspended(struct pci_dev *dev);
+ void pci_dev_complete_resume(struct pci_dev *pci_dev);
  void pci_config_pm_runtime_get(struct pci_dev *dev);
  void pci_config_pm_runtime_put(struct pci_dev *dev);
  void pci_pm_init(struct pci_dev *dev);
 +void pci_ea_init(struct pci_dev *dev);
  void pci_allocate_cap_save_buffers(struct pci_dev *dev);
  void pci_free_cap_save_buffers(struct pci_dev *dev);
  
diff --combined include/linux/acpi.h
index 55af199f8aaf73fef834d242442c5cffc6a089c9,82f56bb0214c5be2321b679402a743c4f70b97e3..ebfac2fe0c813bea9d98d01e8dc4f244e1bd97d4
@@@ -49,7 -49,7 +49,7 @@@ static inline acpi_handle acpi_device_h
        return adev ? adev->handle : NULL;
  }
  
- #define ACPI_COMPANION(dev)           to_acpi_node((dev)->fwnode)
+ #define ACPI_COMPANION(dev)           to_acpi_device_node((dev)->fwnode)
  #define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \
        acpi_fwnode_handle(adev) : NULL)
  #define ACPI_HANDLE(dev)              acpi_device_handle(ACPI_COMPANION(dev))
@@@ -69,7 -69,7 +69,7 @@@
  
  static inline bool has_acpi_companion(struct device *dev)
  {
-       return is_acpi_node(dev->fwnode);
+       return is_acpi_device_node(dev->fwnode);
  }
  
  static inline void acpi_preset_companion(struct device *dev,
@@@ -131,6 -131,12 +131,12 @@@ static inline void acpi_initrd_override
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
                ((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
  
+ struct acpi_subtable_proc {
+       int id;
+       acpi_tbl_entry_handler handler;
+       int count;
+ };
  char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
  void __acpi_unmap_table(char *map, unsigned long size);
  int early_acpi_boot_init(void);
@@@ -146,9 -152,16 +152,16 @@@ int __init acpi_parse_entries(char *id
                              struct acpi_table_header *table_header,
                              int entry_id, unsigned int max_entries);
  int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-                                   int entry_id,
-                                   acpi_tbl_entry_handler handler,
-                                   unsigned int max_entries);
+                             int entry_id,
+                             acpi_tbl_entry_handler handler,
+                             unsigned int max_entries);
+ int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+                             int entry_id,
+                             acpi_tbl_entry_handler handler,
+                             unsigned int max_entries);
+ int __init acpi_table_parse_entries_array(char *id, unsigned long table_size,
+                             struct acpi_subtable_proc *proc, int proc_num,
+                             unsigned int max_entries);
  int acpi_table_parse_madt(enum acpi_madt_type id,
                          acpi_tbl_entry_handler handler,
                          unsigned int max_entries);
@@@ -193,6 -206,12 +206,12 @@@ int acpi_ioapic_registered(acpi_handle 
  void acpi_irq_stats_init(void);
  extern u32 acpi_irq_handled;
  extern u32 acpi_irq_not_handled;
+ extern unsigned int acpi_sci_irq;
+ #define INVALID_ACPI_IRQ      ((unsigned)-1)
+ static inline bool acpi_sci_irq_valid(void)
+ {
+       return acpi_sci_irq != INVALID_ACPI_IRQ;
+ }
  
  extern int sbf_port;
  extern unsigned long acpi_realmode_flags;
@@@ -201,9 -220,6 +220,9 @@@ int acpi_register_gsi (struct device *d
  int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
  int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
  
 +void acpi_set_irq_model(enum acpi_irq_model_id model,
 +                      struct fwnode_handle *fwnode);
 +
  #ifdef CONFIG_X86_IO_APIC
  extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
  #else
@@@ -465,7 -481,22 +484,22 @@@ static inline bool is_acpi_node(struct 
        return false;
  }
  
- static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode)
+ static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
+ {
+       return false;
+ }
+ static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
+ {
+       return NULL;
+ }
+ static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
+ {
+       return false;
+ }
+ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
  {
        return NULL;
  }
@@@ -480,11 -511,6 +514,11 @@@ static inline bool has_acpi_companion(s
        return false;
  }
  
 +static inline void acpi_preset_companion(struct device *dev,
 +                                       struct acpi_device *parent, u64 addr)
 +{
 +}
 +
  static inline const char *acpi_dev_name(struct acpi_device *adev)
  {
        return NULL;
@@@ -752,22 -778,76 +786,76 @@@ struct acpi_reference_args 
  #ifdef CONFIG_ACPI
  int acpi_dev_get_property(struct acpi_device *adev, const char *name,
                          acpi_object_type type, const union acpi_object **obj);
- int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
-                               acpi_object_type type,
-                               const union acpi_object **obj);
- int acpi_dev_get_property_reference(struct acpi_device *adev,
-                                   const char *name, size_t index,
-                                   struct acpi_reference_args *args);
- int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
-                     void **valptr);
+ int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+                                    const char *name, size_t index,
+                                    struct acpi_reference_args *args);
+ int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
+                      void **valptr);
  int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
                              enum dev_prop_type proptype, void *val);
+ int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname,
+                       enum dev_prop_type proptype, void *val, size_t nval);
  int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
                       enum dev_prop_type proptype, void *val, size_t nval);
  
- struct acpi_device *acpi_get_next_child(struct device *dev,
-                                       struct acpi_device *child);
+ struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+                                           struct fwnode_handle *subnode);
+ struct acpi_probe_entry;
+ typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
+                                                struct acpi_probe_entry *);
+ #define ACPI_TABLE_ID_LEN     5
+ /**
+  * struct acpi_probe_entry - boot-time probing entry
+  * @id:                       ACPI table name
+  * @type:             Optional subtable type to match
+  *                    (if @id contains subtables)
+  * @subtable_valid:   Optional callback to check the validity of
+  *                    the subtable
+  * @probe_table:      Callback to the driver being probed when table
+  *                    match is successful
+  * @probe_subtbl:     Callback to the driver being probed when table and
+  *                    subtable match (and optional callback is successful)
+  * @driver_data:      Sideband data provided back to the driver
+  */
+ struct acpi_probe_entry {
+       __u8 id[ACPI_TABLE_ID_LEN];
+       __u8 type;
+       acpi_probe_entry_validate_subtbl subtable_valid;
+       union {
+               acpi_tbl_table_handler probe_table;
+               acpi_tbl_entry_handler probe_subtbl;
+       };
+       kernel_ulong_t driver_data;
+ };
+ #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn)    \
+       static const struct acpi_probe_entry __acpi_probe_##name        \
+               __used __section(__##table##_acpi_probe_table)          \
+                = {                                                    \
+                       .id = table_id,                                 \
+                       .type = subtable,                               \
+                       .subtable_valid = valid,                        \
+                       .probe_table = (acpi_tbl_table_handler)fn,      \
+                       .driver_data = data,                            \
+                  }
+ #define ACPI_PROBE_TABLE(name)                __##name##_acpi_probe_table
+ #define ACPI_PROBE_TABLE_END(name)    __##name##_acpi_probe_table_end
+ int __acpi_probe_device_table(struct acpi_probe_entry *start, int nr);
+ #define acpi_probe_device_table(t)                                    \
+       ({                                                              \
+               extern struct acpi_probe_entry ACPI_PROBE_TABLE(t),     \
+                                              ACPI_PROBE_TABLE_END(t); \
+               __acpi_probe_device_table(&ACPI_PROBE_TABLE(t),         \
+                                         (&ACPI_PROBE_TABLE_END(t) -   \
+                                          &ACPI_PROBE_TABLE(t)));      \
+       })
  #else
  static inline int acpi_dev_get_property(struct acpi_device *adev,
                                        const char *name, acpi_object_type type,
  {
        return -ENXIO;
  }
- static inline int acpi_dev_get_property_array(struct acpi_device *adev,
                                            const char *name,
-                                             acpi_object_type type,
-                                             const union acpi_object **obj)
static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+                               const char *name, const char *cells_name,
+                               size_t index, struct acpi_reference_args *args)
  {
        return -ENXIO;
  }
- static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
-                               const char *name, const char *cells_name,
-                               size_t index, struct acpi_reference_args *args)
+ static inline int acpi_node_prop_get(struct fwnode_handle *fwnode,
+                                    const char *propname,
+                                    void **valptr)
  {
        return -ENXIO;
  }
@@@ -804,6 -885,14 +893,14 @@@ static inline int acpi_dev_prop_read_si
        return -ENXIO;
  }
  
+ static inline int acpi_node_prop_read(struct fwnode_handle *fwnode,
+                                     const char *propname,
+                                     enum dev_prop_type proptype,
+                                     void *val, size_t nval)
+ {
+       return -ENXIO;
+ }
  static inline int acpi_dev_prop_read(struct acpi_device *adev,
                                     const char *propname,
                                     enum dev_prop_type proptype,
        return -ENXIO;
  }
  
- static inline struct acpi_device *acpi_get_next_child(struct device *dev,
-                                                     struct acpi_device *child)
+ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+                                               struct fwnode_handle *subnode)
  {
        return NULL;
  }
  
+ #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \
+       static const void * __acpi_table_##name[]                       \
+               __attribute__((unused))                                 \
+                = { (void *) table_id,                                 \
+                    (void *) subtable,                                 \
+                    (void *) valid,                                    \
+                    (void *) fn,                                       \
+                    (void *) data }
+ #define acpi_probe_device_table(t)    ({ int __r = 0; __r;})
  #endif
  
  #endif        /*_LINUX_ACPI_H*/
diff --combined include/linux/fwnode.h
index 37ec668546ab21897393bcebc1ba548796db7994,b08d6ba5c1e6c9a5e7e31d7ed966bffa20e517a1..8516717427906948a215c56fad35ab462a8cbfda
@@@ -16,8 -16,8 +16,9 @@@ enum fwnode_type 
        FWNODE_INVALID = 0,
        FWNODE_OF,
        FWNODE_ACPI,
+       FWNODE_ACPI_DATA,
        FWNODE_PDATA,
 +      FWNODE_IRQCHIP,
  };
  
  struct fwnode_handle {