]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge branch 'pm-sleep'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 5 Aug 2014 20:49:45 +0000 (22:49 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 5 Aug 2014 20:49:45 +0000 (22:49 +0200)
* pm-sleep:
  PM / Hibernate: Touch Soft Lockup Watchdog in rtree_next_node
  PM / Hibernate: Remove the old memory-bitmap implementation
  PM / Hibernate: Iterate over set bits instead of PFNs in swsusp_free()
  PM / Hibernate: Implement position keeping in radix tree
  PM / Hibernate: Add memory_rtree_find_bit function
  PM / Hibernate: Create a Radix-Tree to store memory bitmap
  PM / sleep: fix kernel-doc warnings in drivers/base/power/main.c

253 files changed:
Documentation/input/event-codes.txt
Documentation/power/opp.txt
MAINTAINERS
Makefile
arch/arm/mach-exynos/Kconfig
arch/arm/mach-highbank/Kconfig
arch/arm/mach-imx/Kconfig
arch/arm/mach-omap2/Kconfig
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-zynq/Kconfig
arch/arm64/mm/init.c
arch/blackfin/configs/BF609-EZKIT_defconfig
arch/blackfin/kernel/vmlinux.lds.S
arch/blackfin/mach-bf533/boards/blackstamp.c
arch/blackfin/mach-bf537/boards/cm_bf537e.c
arch/blackfin/mach-bf537/boards/cm_bf537u.c
arch/blackfin/mach-bf537/boards/tcm_bf537.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf561/boards/acvilon.c
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf609/boards/ezkit.c
arch/blackfin/mach-bf609/include/mach/pm.h
arch/blackfin/mach-bf609/pm.c
arch/blackfin/mach-common/ints-priority.c
arch/ia64/Kconfig
arch/ia64/include/asm/acenv.h
arch/ia64/include/asm/acpi.h
arch/parisc/include/uapi/asm/signal.h
arch/parisc/mm/init.c
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/kvm_book3s_64.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/kernel/cputable.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv_rm_mmu.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_interrupts.S
arch/powerpc/kvm/book3s_rmhandlers.S
arch/powerpc/kvm/book3s_rtas.c
arch/powerpc/kvm/e500_mmu_host.c
arch/powerpc/lib/mem_64.S
arch/powerpc/lib/sstep.c
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/reconfig.c
arch/s390/include/asm/switch_to.h
arch/s390/kernel/head.S
arch/s390/kernel/ptrace.c
arch/s390/pci/pci.c
arch/sh/Makefile
arch/sparc/include/uapi/asm/unistd.h
arch/sparc/kernel/sys32.S
arch/sparc/kernel/systbls_32.S
arch/sparc/kernel/systbls_64.S
arch/x86/Kconfig
arch/x86/include/asm/acenv.h
arch/x86/include/asm/acpi.h
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/kprobes/core.c
arch/x86/kvm/x86.c
arch/xtensa/kernel/vectors.S
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/mm/init.c
block/blk-cgroup.c
block/blk-tag.c
block/compat_ioctl.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/acpi_extlog.c
drivers/acpi/acpi_processor.c
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/acapps.h
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/exfield.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/nsobject.c
drivers/acpi/acpica/utbuffer.c
drivers/acpi/acpica/utcopy.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utfileio.c [new file with mode: 0644]
drivers/acpi/acpica/utglobal.c
drivers/acpi/acpica/utinit.c
drivers/acpi/acpica/utprint.c [new file with mode: 0644]
drivers/acpi/apei/apei-internal.h
drivers/acpi/apei/ghes.c
drivers/acpi/blacklist.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/device_pm.c
drivers/acpi/internal.h
drivers/acpi/osl.c
drivers/acpi/pci_root.c
drivers/acpi/processor_core.c
drivers/acpi/processor_pdc.c [new file with mode: 0644]
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/video.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_ep93xx.c
drivers/block/drbd/drbd_nl.c
drivers/block/zram/zram_drv.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/freq_table.c
drivers/cpufreq/imx6q-cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/powernow-k6.c
drivers/cpuidle/Kconfig
drivers/cpuidle/Kconfig.arm
drivers/cpuidle/cpuidle.c
drivers/cpuidle/driver.c
drivers/cpuidle/governors/ladder.c
drivers/cpuidle/governors/menu.c
drivers/cpuidle/sysfs.c
drivers/devfreq/Kconfig
drivers/firewire/ohci.c
drivers/firmware/efi/cper.c
drivers/gpio/gpio-rcar.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_render_state.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_vm.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/trinity_dpm.c
drivers/hwmon/smsc47m192.c
drivers/ide/Kconfig
drivers/ide/ide-probe.c
drivers/input/input.c
drivers/input/keyboard/st-keyscan.c
drivers/input/misc/sirfsoc-onkey.c
drivers/input/mouse/synaptics.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/isdn/i4l/isdn_ppp.c
drivers/media/dvb-frontends/si2168.c
drivers/media/dvb-frontends/si2168_priv.h
drivers/media/dvb-frontends/tda10071.c
drivers/media/dvb-frontends/tda10071_priv.h
drivers/media/pci/saa7134/saa7134-empress.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/tuners/si2157.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/gspca/pac7302.c
drivers/media/usb/hdpvr/hdpvr-video.c
drivers/media/v4l2-core/v4l2-dv-timings.c
drivers/net/ethernet/mellanox/mlx4/en_cq.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sun/sunvnet.c
drivers/net/ppp/ppp_generic.c
drivers/net/usb/huawei_cdc_ncm.c
drivers/net/usb/qmi_wwan.c
drivers/net/wan/x25_asy.c
drivers/net/xen-netback/netback.c
drivers/parport/Kconfig
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/pci-acpi.c
drivers/pinctrl/pinctrl-st.c
drivers/pnp/pnpacpi/core.c
drivers/s390/char/raw3270.c
drivers/s390/crypto/ap_bus.c
drivers/staging/media/omap4iss/Kconfig
fs/coredump.c
fs/direct-io.c
fs/fuse/inode.c
fs/namei.c
fs/nfsd/nfs4xdr.c
fs/xattr.c
include/acpi/acpi_bus.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/actbl1.h
include/acpi/actbl2.h
include/acpi/actypes.h
include/acpi/ghes.h
include/acpi/platform/acenv.h
include/acpi/platform/aclinux.h
include/acpi/platform/aclinuxex.h
include/linux/acpi.h
include/linux/cpufreq.h
include/linux/libata.h
include/linux/pagemap.h
include/linux/pci-acpi.h
include/linux/pm_runtime.h
include/linux/sfi_acpi.h
include/net/netfilter/nf_tables.h
include/net/netns/nftables.h
include/uapi/linux/fuse.h
kernel/events/core.c
kernel/kprobes.c
kernel/power/Kconfig
kernel/power/main.c
kernel/sched/idle.c
kernel/trace/trace.c
kernel/trace/trace_clock.c
mm/hugetlb.c
mm/memory-failure.c
mm/memory.c
mm/migrate.c
mm/rmap.c
mm/shmem.c
mm/slab_common.c
mm/truncate.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/soft-interface.c
net/batman-adv/translation-table.c
net/batman-adv/types.h
net/core/dev.c
net/dns_resolver/dns_query.c
net/ipv4/af_inet.c
net/ipv4/gre_offload.c
net/ipv4/ip_options.c
net/ipv4/tcp_offload.c
net/ipv6/tcpv6_offload.c
net/netfilter/nf_tables_api.c
net/netfilter/nf_tables_core.c
net/sched/cls_u32.c
sound/firewire/bebob/bebob_maudio.c
tools/power/acpi/Makefile
tools/power/acpi/common/cmfsize.c
tools/power/acpi/common/getopt.c
tools/power/acpi/os_specific/service_layers/oslibcfs.c [new file with mode: 0644]
tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
tools/power/acpi/os_specific/service_layers/osunixxf.c [new file with mode: 0644]
tools/power/acpi/tools/acpidump/acpidump.h
tools/power/acpi/tools/acpidump/apdump.c
tools/power/acpi/tools/acpidump/apfiles.c
tools/power/acpi/tools/acpidump/apmain.c

index f1ea2c69648dcad46d061a78ac33036d3ac5c727..c587a966413e8597da3241f851db92f6e6df1d81 100644 (file)
@@ -281,6 +281,19 @@ gestures can normally be extracted from it.
 If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT
 device.
 
+INPUT_PROP_TOPBUTTONPAD:
+-----------------------
+Some laptops, most notably the Lenovo *40 series provide a trackstick
+device but do not have physical buttons associated with the trackstick
+device. Instead, the top area of the touchpad is marked to show
+visual/haptic areas for left, middle, right buttons intended to be used
+with the trackstick.
+
+If INPUT_PROP_TOPBUTTONPAD is set, userspace should emulate buttons
+accordingly. This property does not affect kernel behavior.
+The kernel does not provide button emulation for such devices but treats
+them as any other INPUT_PROP_BUTTONPAD device.
+
 Guidelines:
 ==========
 The guidelines below ensure proper single-touch and multi-finger functionality.
index a9adad828cdc450d480d6a5853bda056a6dfa413..c6279c2be47c20116dc56590b450f56a96a1ad5b 100644 (file)
@@ -51,9 +51,6 @@ Typical usage of the OPP library is as follows:
 SoC framework  -> modifies on required cases certain OPPs      -> OPP layer
                -> queries to search/retrieve information       ->
 
-Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
-to make the OPP layer available.
-
 OPP layer expects each domain to be represented by a unique device pointer. SoC
 framework registers a set of initial OPPs per device with the OPP layer. This
 list is expected to be an optimally small number typically around 5 per device.
index 61a8f486306b700749dce48b58ff63c856b3a5eb..c04b14898249d91f7c523cd31b4f2611b1b22fed 100644 (file)
@@ -6956,6 +6956,12 @@ L:       linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/pinctrl/pinctrl-at91.c
 
+PIN CONTROLLER - RENESAS
+M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+L:     linux-sh@vger.kernel.org
+S:     Maintained
+F:     drivers/pinctrl/sh-pfc/
+
 PIN CONTROLLER - SAMSUNG
 M:     Tomasz Figa <t.figa@samsung.com>
 M:     Thomas Abraham <thomas.abraham@linaro.org>
@@ -7026,8 +7032,10 @@ F:       include/linux/timer*
 F:     kernel/*timer*
 
 POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
+M:     Sebastian Reichel <sre@kernel.org>
 M:     Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
 M:     David Woodhouse <dwmw2@infradead.org>
+L:     linux-pm@vger.kernel.org
 T:     git git://git.infradead.org/battery-2.6.git
 S:     Maintained
 F:     include/linux/power_supply.h
@@ -8019,6 +8027,16 @@ F:       drivers/ata/
 F:     include/linux/ata.h
 F:     include/linux/libata.h
 
+SERIAL ATA AHCI PLATFORM devices support
+M:     Hans de Goede <hdegoede@redhat.com>
+M:     Tejun Heo <tj@kernel.org>
+L:     linux-ide@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+S:     Supported
+F:     drivers/ata/ahci_platform.c
+F:     drivers/ata/libahci_platform.c
+F:     include/linux/ahci_platform.h
+
 SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
 M:     Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
 L:     linux-scsi@vger.kernel.org
index 6b2774145d664289cca4b1a1a3799543d5f916c2..f6a7794e4db436c16246389642f86de3c9098699 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Shuffling Zombie Juror
 
 # *DOCUMENTATION*
@@ -688,6 +688,8 @@ KBUILD_CFLAGS       += -fomit-frame-pointer
 endif
 endif
 
+KBUILD_CFLAGS   += $(call cc-option, -fno-var-tracking-assignments)
+
 ifdef CONFIG_DEBUG_INFO
 KBUILD_CFLAGS  += -g
 KBUILD_AFLAGS  += -Wa,-gdwarf-2
index 8f9b66c4ac78804981692a8a27d06f49979fa6bc..f7889f6a13532c1ddf43200b917503429f3179ee 100644 (file)
@@ -100,7 +100,6 @@ config SOC_EXYNOS5440
        default y
        depends on ARCH_EXYNOS5
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-       select ARCH_HAS_OPP
        select HAVE_ARM_ARCH_TIMER
        select AUTO_ZRELADDR
        select MIGHT_HAVE_PCI
index a5960e2ac090682c411a2a336e5a5235dcc5f4e2..31aa866c33171aa107075e39d03551824a7fb51a 100644 (file)
@@ -2,7 +2,6 @@ config ARCH_HIGHBANK
        bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select ARCH_HAS_HOLES_MEMORYMODEL
-       select ARCH_HAS_OPP
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
        select ARM_ERRATA_764369 if SMP
index 4b5185748f744a47b7742d66a59bda80715d9b90..ab6bcfd2e220a82e9ebaf38709d91a30ac50d62d 100644 (file)
@@ -1,6 +1,5 @@
 menuconfig ARCH_MXC
        bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
-       select ARCH_HAS_OPP
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
        select CLKSRC_MMIO
index 1c1ed737f7ab763437c81a8223fd1a05fc2850a5..e7189dcc9309431291205b92c5328aed1ea71ffd 100644 (file)
@@ -15,7 +15,6 @@ config ARCH_OMAP3
        bool "TI OMAP3"
        depends on ARCH_MULTI_V7
        select ARCH_OMAP2PLUS
-       select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
        select OMAP_INTERCONNECT
        select PM_OPP if PM
index 798073057e51f8d44afa6e20bac7567533f2b636..3a6e3c20a86d898d91e2762fb88a39837d20910f 100644 (file)
@@ -85,7 +85,6 @@ config ARCH_R8A73A4
        select CPU_V7
        select SH_CLK_CPG
        select RENESAS_IRQC
-       select ARCH_HAS_OPP
        select SYS_SUPPORTS_SH_CMT
        select SYS_SUPPORTS_SH_TMU
 
@@ -263,7 +262,6 @@ config MACH_KOELSCH
 config MACH_KZM9G
        bool "KZM-A9-GT board"
        depends on ARCH_SH73A0
-       select ARCH_HAS_OPP
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
        select SND_SOC_AK4642 if SND_SIMPLE_CARD
index d8b9330f896a3edac20a11355d8b60b9a613f824..1af70329b88d069ef8c3278e450d4a46bf54b45c 100644 (file)
@@ -64,7 +64,6 @@ config ARCH_VEXPRESS_DCSCB
 
 config ARCH_VEXPRESS_SPC
        bool "Versatile Express Serial Power Controller (SPC)"
-       select ARCH_HAS_OPP
        select PM_OPP
        help
          The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
index 0c164f81e72d3b070236fd6545fff34383db4bdd..aaa5162c1509bd51342faeecf374fe72b25bdc60 100644 (file)
@@ -1,6 +1,5 @@
 config ARCH_ZYNQ
        bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
-       select ARCH_HAS_OPP
        select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
        select ARM_GIC
index f43db8a6926208f9b9419c3114d1c41c13514566..e90c5426fe14e5a1212706e3802aa32325c77d95 100644 (file)
@@ -60,6 +60,17 @@ static int __init early_initrd(char *p)
 early_param("initrd", early_initrd);
 #endif
 
+/*
+ * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
+ * currently assumes that for memory starting above 4G, 32-bit devices will
+ * use a DMA offset.
+ */
+static phys_addr_t max_zone_dma_phys(void)
+{
+       phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
+       return min(offset + (1ULL << 32), memblock_end_of_DRAM());
+}
+
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
        struct memblock_region *reg;
@@ -70,9 +81,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
        /* 4GB maximum for 32-bit only capable devices */
        if (IS_ENABLED(CONFIG_ZONE_DMA)) {
-               unsigned long max_dma_phys =
-                       (unsigned long)(dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1);
-               max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
+               max_dma = PFN_DOWN(max_zone_dma_phys());
                zone_size[ZONE_DMA] = max_dma - min;
        }
        zone_size[ZONE_NORMAL] = max - max_dma;
@@ -146,7 +155,7 @@ void __init arm64_memblock_init(void)
 
        /* 4GB maximum for 32-bit only capable devices */
        if (IS_ENABLED(CONFIG_ZONE_DMA))
-               dma_phys_limit = dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1;
+               dma_phys_limit = max_zone_dma_phys();
        dma_contiguous_reserve(dma_phys_limit);
 
        memblock_allow_resize();
index a7e9bfd84183d5b7c26924679f9bb33d88ac0118..fcec5ce71392d20712b15516c3786e43513b0d10 100644 (file)
@@ -102,7 +102,7 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_BLACKFIN_TWI=y
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 CONFIG_SPI=y
-CONFIG_SPI_BFIN_V3=y
+CONFIG_SPI_ADI_V3=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
index ba35864b2b74b50e3ad32527419a83ef6abb9629..c9eec84aa258628d1c9d70fc545420dde30c8bc1 100644 (file)
@@ -145,7 +145,7 @@ SECTIONS
 
        .text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data))
 #else
-       .init.data : AT(__data_lma + __data_len)
+       .init.data : AT(__data_lma + __data_len + 32)
        {
                __sinitdata = .;
                INIT_DATA
index 63b0e4fe760cd558d20a2f8359c1c975180b9c11..0ccf0cf4daaf92f8d38aa18962defd8a10707e7d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
index c65c6dbda3da9af86231d299b4502f0d3d72edb9..1e7290ef35258da56c5521ed23a1b637286b7342 100644 (file)
@@ -21,6 +21,7 @@
 #endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
index af58454b4bff3fdc4bffda53d5d252726fd4e4f8..c7495dc74690db99f52bfa30c94c62dd5faae63c 100644 (file)
@@ -21,6 +21,7 @@
 #endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
index a0211225748d23f0d0f14cdba4fd99a34aa8208f..6b988ad653d8d1e69a1721ddfe4b7208bf7cebb9 100644 (file)
@@ -21,6 +21,7 @@
 #endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
index 90138e6112c14b2f186640f22e61368a517fab94..1fe7ff286619f693c113faeac592ce3167d8de72 100644 (file)
@@ -2118,7 +2118,7 @@ static struct pinctrl_map __initdata bfin_pinmux_map[] = {
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-rotary",  "pinctrl-adi2.0", NULL, "rotary"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.0",  "pinctrl-adi2.0", NULL, "can0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.1",  "pinctrl-adi2.0", NULL, "can1"),
-       PIN_MAP_MUX_GROUP_DEFAULT("bf54x-lq043",  "pinctrl-adi2.0", NULL, "ppi0_24b"),
+       PIN_MAP_MUX_GROUP_DEFAULT("bf54x-lq043",  "pinctrl-adi2.0", "ppi0_24bgrp", "ppi0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.0",  "pinctrl-adi2.0", NULL, "sport0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.0",  "pinctrl-adi2.0", NULL, "sport0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-ac97.0",  "pinctrl-adi2.0", NULL, "sport0"),
@@ -2140,7 +2140,9 @@ static struct pinctrl_map __initdata bfin_pinmux_map[] = {
        PIN_MAP_MUX_GROUP_DEFAULT("pata-bf54x",  "pinctrl-adi2.0", NULL, "atapi_alter"),
 #endif
        PIN_MAP_MUX_GROUP_DEFAULT("bf5xx-nand.0",  "pinctrl-adi2.0", NULL, "nfc0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("bf54x-keys",  "pinctrl-adi2.0", NULL, "keys_4x4"),
+       PIN_MAP_MUX_GROUP_DEFAULT("bf54x-keys",  "pinctrl-adi2.0", "keys_4x4grp", "keys"),
+       PIN_MAP_MUX_GROUP("bf54x-keys", "4bit",  "pinctrl-adi2.0", "keys_4x4grp", "keys"),
+       PIN_MAP_MUX_GROUP("bf54x-keys", "8bit",  "pinctrl-adi2.0", "keys_8x8grp", "keys"),
 };
 
 static int __init ezkit_init(void)
index 430b16d5ccb1124f6fd896d4c8651050695d9053..6ab951534d790b6060aeea63cda8c1b158d90470 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/spi/flash.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/gpio.h>
 #include <linux/jiffies.h>
 #include <linux/i2c-pca-platform.h>
 #include <linux/delay.h>
index 9f777df4cacce9e77ada5ec46ff1698a72fbe419..e862f7823e68db1b5ea374a295982c23db2800c8 100644 (file)
@@ -18,6 +18,7 @@
 #endif
 #include <linux/ata_platform.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
index 88dee43e7abe8c4e34da9016b2333c539ef6b9a2..2de71e8c104b1e2233c7eba47c42ad28d2ab60c9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/spi/spi.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
index 1ba4600de69f72b37ca503f7aab752b9f4dcdb97..e2c0b024ce88f2593f4551b711b3821d8ae3879e 100644 (file)
@@ -698,8 +698,6 @@ int bf609_nor_flash_init(struct platform_device *pdev)
 {
 #define CONFIG_SMC_GCTL_VAL     0x00000010
 
-       if (!devm_pinctrl_get_select_default(&pdev->dev))
-               return -EBUSY;
        bfin_write32(SMC_GCTL, CONFIG_SMC_GCTL_VAL);
        bfin_write32(SMC_B0CTL, 0x01002011);
        bfin_write32(SMC_B0TIM, 0x08170977);
@@ -709,7 +707,6 @@ int bf609_nor_flash_init(struct platform_device *pdev)
 
 void bf609_nor_flash_exit(struct platform_device *pdev)
 {
-       devm_pinctrl_put(pdev->dev.pins->p);
        bfin_write32(SMC_GCTL, 0);
 }
 
@@ -2058,15 +2055,14 @@ static struct pinctrl_map __initdata bfin_pinmux_map[] = {
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-rotary",  "pinctrl-adi2.0", NULL, "rotary"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin_can.0",  "pinctrl-adi2.0", NULL, "can0"),
        PIN_MAP_MUX_GROUP_DEFAULT("physmap-flash.0",  "pinctrl-adi2.0", NULL, "smc0"),
-       PIN_MAP_MUX_GROUP_DEFAULT("bf609_nl8048.2",  "pinctrl-adi2.0", NULL, "ppi2_16b"),
-       PIN_MAP_MUX_GROUP_DEFAULT("bfin_display.0",  "pinctrl-adi2.0", NULL, "ppi0_16b"),
-#if IS_ENABLED(CONFIG_VIDEO_MT9M114)
-       PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0",  "pinctrl-adi2.0", NULL, "ppi0_8b"),
-#elif IS_ENABLED(CONFIG_VIDEO_VS6624)
-       PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0",  "pinctrl-adi2.0", NULL, "ppi0_16b"),
-#else
-       PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0",  "pinctrl-adi2.0", NULL, "ppi0_24b"),
-#endif
+       PIN_MAP_MUX_GROUP_DEFAULT("bf609_nl8048.2",  "pinctrl-adi2.0", "ppi2_16bgrp", "ppi2"),
+       PIN_MAP_MUX_GROUP("bfin_display.0", "8bit",  "pinctrl-adi2.0", "ppi2_8bgrp", "ppi2"),
+       PIN_MAP_MUX_GROUP_DEFAULT("bfin_display.0",  "pinctrl-adi2.0", "ppi2_16bgrp", "ppi2"),
+       PIN_MAP_MUX_GROUP("bfin_display.0", "16bit",  "pinctrl-adi2.0", "ppi2_16bgrp", "ppi2"),
+       PIN_MAP_MUX_GROUP("bfin_capture.0", "8bit",  "pinctrl-adi2.0", "ppi0_8bgrp", "ppi0"),
+       PIN_MAP_MUX_GROUP_DEFAULT("bfin_capture.0",  "pinctrl-adi2.0", "ppi0_16bgrp", "ppi0"),
+       PIN_MAP_MUX_GROUP("bfin_capture.0", "16bit",  "pinctrl-adi2.0", "ppi0_16bgrp", "ppi0"),
+       PIN_MAP_MUX_GROUP("bfin_capture.0", "24bit",  "pinctrl-adi2.0", "ppi0_24bgrp", "ppi0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.0",  "pinctrl-adi2.0", NULL, "sport0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-tdm.0",  "pinctrl-adi2.0", NULL, "sport0"),
        PIN_MAP_MUX_GROUP_DEFAULT("bfin-i2s.1",  "pinctrl-adi2.0", NULL, "sport1"),
index 3ca0fb965636ed3fad126ae021d9d87a6518ea8a..a1efd936dd30d2ec18e08c9d5b76bae6afabe99b 100644 (file)
@@ -10,6 +10,7 @@
 #define __MACH_BF609_PM_H__
 
 #include <linux/suspend.h>
+#include <linux/platform_device.h>
 
 extern int bfin609_pm_enter(suspend_state_t state);
 extern int bf609_pm_prepare(void);
@@ -19,6 +20,6 @@ void bf609_hibernate(void);
 void bfin_sec_raise_irq(unsigned int sid);
 void coreb_enable(void);
 
-int bf609_nor_flash_init(void);
-void bf609_nor_flash_exit(void);
+int bf609_nor_flash_init(struct platform_device *pdev);
+void bf609_nor_flash_exit(struct platform_device *pdev);
 #endif
index 0cdd6955c7be5a80a2cb7d406b3fefb1eac9a9a9..b1bfcf434d16cfc25e999222c5c972f3f110d519 100644 (file)
@@ -291,13 +291,13 @@ static struct bfin_cpu_pm_fns bf609_cpu_pm = {
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 static int smc_pm_syscore_suspend(void)
 {
-       bf609_nor_flash_exit();
+       bf609_nor_flash_exit(NULL);
        return 0;
 }
 
 static void smc_pm_syscore_resume(void)
 {
-       bf609_nor_flash_init();
+       bf609_nor_flash_init(NULL);
 }
 
 static struct syscore_ops smc_pm_syscore_ops = {
index 867b7cef204cb91f0ed15e9386ba7ea0b2089d96..1f94784eab6d79b7f63673e20e2039fb41a07edb 100644 (file)
@@ -1208,8 +1208,6 @@ int __init init_arch_irq(void)
 
        bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority);
 
-       bfin_sec_set_priority(CONFIG_SEC_IRQ_PRIORITY_LEVELS, sec_int_priority);
-
        /* Enable interrupts IVG7-15 */
        bfin_irq_flags |= IMASK_IVG15 |
            IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
index 2f3abcf8f6bc9b2b206652b52cf1318f93acb74a..44a6915ab13d474d53457e0d8c1a62838974b7ac 100644 (file)
@@ -10,6 +10,7 @@ config IA64
        select ARCH_MIGHT_HAVE_PC_SERIO
        select PCI if (!IA64_HP_SIM)
        select ACPI if (!IA64_HP_SIM)
+       select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
        select PM if (!IA64_HP_SIM)
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
index 3f9eaeec98734852e98830969ccf826d399dabde..35ff13afbf345df260ecc30045f91ca1a77fce42 100644 (file)
@@ -19,8 +19,6 @@
 
 /* Asm macros */
 
-#ifdef CONFIG_ACPI
-
 static inline int
 ia64_acpi_acquire_global_lock(unsigned int *lock)
 {
@@ -51,6 +49,4 @@ ia64_acpi_release_global_lock(unsigned int *lock)
 #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq)                            \
        ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock))
 
-#endif
-
 #endif /* _ASM_IA64_ACENV_H */
index 75dc59a793d61ce1f243526764056edd434330bf..a1d91ab4c5ef2010edb46e0a54ea0f016600581f 100644 (file)
@@ -40,6 +40,11 @@ extern int acpi_lapic;
 #define acpi_noirq 0   /* ACPI always enabled on IA64 */
 #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
 #define acpi_strict 1  /* no ACPI spec workarounds on IA64 */
+
+static inline bool acpi_has_cpu_in_madt(void)
+{
+       return !!acpi_lapic;
+}
 #endif
 #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
 static inline void disable_acpi(void) { }
index a2fa297196bc19f1de4f021ebec6e5338b237313..f5645d6a89f2c9c79e8e22cd9a7201df6dc389df 100644 (file)
@@ -69,8 +69,6 @@
 #define SA_NOMASK      SA_NODEFER
 #define SA_ONESHOT     SA_RESETHAND
 
-#define SA_RESTORER    0x04000000 /* obsolete -- ignored */
-
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
 
index ae085ad0fba03827df21874edfb6a6985c3338f8..0bef864264c0bb1e0d445c184ef79e51c9153caf 100644 (file)
@@ -728,7 +728,6 @@ static void __init pagetable_init(void)
 #endif
 
        empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
-       memset(empty_zero_page, 0, PAGE_SIZE);
 }
 
 static void __init gateway_init(void)
index bc2347774f0ad4ed111a5c98546fb763de6d8bbd..0fdd7eece6d91a3183a5857967ad910998d33c09 100644 (file)
@@ -447,6 +447,7 @@ extern const char *powerpc_base_platform;
            CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
            CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
 #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
+#define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
index fddb72b48ce9bd2a9a4e25460c2ff5cc4bc15ad5..d645428a65a411c187768bd296cc725e09fc2da6 100644 (file)
@@ -198,8 +198,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
        return rb;
 }
 
-static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
+static inline unsigned long __hpte_page_size(unsigned long h, unsigned long l,
+                                            bool is_base_size)
 {
+
        int size, a_psize;
        /* Look at the 8 bit LP value */
        unsigned int lp = (l >> LP_SHIFT) & ((1 << LP_BITS) - 1);
@@ -214,14 +216,27 @@ static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
                                continue;
 
                        a_psize = __hpte_actual_psize(lp, size);
-                       if (a_psize != -1)
+                       if (a_psize != -1) {
+                               if (is_base_size)
+                                       return 1ul << mmu_psize_defs[size].shift;
                                return 1ul << mmu_psize_defs[a_psize].shift;
+                       }
                }
 
        }
        return 0;
 }
 
+static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
+{
+       return __hpte_page_size(h, l, 0);
+}
+
+static inline unsigned long hpte_base_page_size(unsigned long h, unsigned long l)
+{
+       return __hpte_page_size(h, l, 1);
+}
+
 static inline unsigned long hpte_rpn(unsigned long ptel, unsigned long psize)
 {
        return ((ptel & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT;
index 807014dde821058429b41a5d825759d50d4d9ed7..c2b4dcf23d03768427fb5a42a134b86d02e8b0e8 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <asm/pgtable-ppc64.h>
 #include <asm/bug.h>
+#include <asm/processor.h>
 
 /*
  * Segment table
@@ -496,7 +497,7 @@ extern void slb_set_size(u16 size);
  */
 struct subpage_prot_table {
        unsigned long maxaddr;  /* only addresses < this are protected */
-       unsigned int **protptrs[2];
+       unsigned int **protptrs[(TASK_SIZE_USER64 >> 43)];
        unsigned int *low_prot[4];
 };
 
index 9ea266eae33e235cde422eaaf8c86e9fc9275236..7e4612528546b710cb13d7b9346d394d5cd4d99e 100644 (file)
@@ -277,6 +277,8 @@ n:
        .globl n;       \
 n:
 
+#define _GLOBAL_TOC(name) _GLOBAL(name)
+
 #define _KPROBE(n)     \
        .section ".kprobes.text","a";   \
        .globl  n;      \
index 965291b4c2fa15a9f6f50cd8ca8b1e3a3067db02..0c157642c2a140a5be7cf26d677f5fae2fe05816 100644 (file)
@@ -527,6 +527,26 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check_early    = __machine_check_early_realmode_p8,
                .platform               = "power8",
        },
+       {       /* Power8 DD1: Does not support doorbell IPIs */
+               .pvr_mask               = 0xffffff00,
+               .pvr_value              = 0x004d0100,
+               .cpu_name               = "POWER8 (raw)",
+               .cpu_features           = CPU_FTRS_POWER8_DD1,
+               .cpu_user_features      = COMMON_USER_POWER8,
+               .cpu_user_features2     = COMMON_USER2_POWER8,
+               .mmu_features           = MMU_FTRS_POWER8,
+               .icache_bsize           = 128,
+               .dcache_bsize           = 128,
+               .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_IBM,
+               .oprofile_cpu_type      = "ppc64/power8",
+               .oprofile_type          = PPC_OPROFILE_INVALID,
+               .cpu_setup              = __setup_cpu_power8,
+               .cpu_restore            = __restore_cpu_power8,
+               .flush_tlb              = __flush_tlb_power8,
+               .machine_check_early    = __machine_check_early_realmode_p8,
+               .platform               = "power8",
+       },
        {       /* Power8 */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x004d0000,
index 80561074078d01ca8d101f7997a55699e8589e3f..68468d695f12ab864281f19a3cfd872a6976fc8d 100644 (file)
@@ -1562,7 +1562,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
                                goto out;
                        }
                        if (!rma_setup && is_vrma_hpte(v)) {
-                               unsigned long psize = hpte_page_size(v, r);
+                               unsigned long psize = hpte_base_page_size(v, r);
                                unsigned long senc = slb_pgsize_encoding(psize);
                                unsigned long lpcr;
 
index 6e6224318c36aaf166e33e7c57c8a8e0dcd9544e..5a24d3c2b6b8ce9bb39f59f4c69733b00ca068f6 100644 (file)
@@ -814,13 +814,10 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
                        r = hpte[i+1];
 
                        /*
-                        * Check the HPTE again, including large page size
-                        * Since we don't currently allow any MPSS (mixed
-                        * page-size segment) page sizes, it is sufficient
-                        * to check against the actual page size.
+                        * Check the HPTE again, including base page size
                         */
                        if ((v & valid) && (v & mask) == val &&
-                           hpte_page_size(v, r) == (1ul << pshift))
+                           hpte_base_page_size(v, r) == (1ul << pshift))
                                /* Return with the HPTE still locked */
                                return (hash << 3) + (i >> 1);
 
index 868347ef09fd48bcf8bfd343becb49f6898887c5..558a67df8126434eb427c7ca24eebabb82676cac 100644 (file)
@@ -48,7 +48,7 @@
  *
  * LR = return address to continue at after eventually re-enabling MMU
  */
-_GLOBAL(kvmppc_hv_entry_trampoline)
+_GLOBAL_TOC(kvmppc_hv_entry_trampoline)
        mflr    r0
        std     r0, PPC_LR_STKOFF(r1)
        stdu    r1, -112(r1)
index e2c29e381dc7096d13af053526e0d98cf951d08e..d044b8b7c69dd6b675de969d30cc0345d104ba96 100644 (file)
 #include <asm/exception-64s.h>
 
 #if defined(CONFIG_PPC_BOOK3S_64)
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define FUNC(name)             name
+#else
 #define FUNC(name)             GLUE(.,name)
+#endif
 #define GET_SHADOW_VCPU(reg)    addi   reg, r13, PACA_SVCPU
 
 #elif defined(CONFIG_PPC_BOOK3S_32)
index 9eec675220e621e029eac8ecf2a5dabfff17df5a..16c4d88ba27df9ed3caba2e37e20d02a40407dbc 100644 (file)
 
 #if defined(CONFIG_PPC_BOOK3S_64)
 
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define FUNC(name)             name
+#else
 #define FUNC(name)             GLUE(.,name)
+#endif
 
 #elif defined(CONFIG_PPC_BOOK3S_32)
 
@@ -146,7 +150,7 @@ kvmppc_handler_skip_ins:
  * On entry, r4 contains the guest shadow MSR
  * MSR.EE has to be 0 when calling this function
  */
-_GLOBAL(kvmppc_entry_trampoline)
+_GLOBAL_TOC(kvmppc_entry_trampoline)
        mfmsr   r5
        LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
        toreal(r7)
index edb14ba992b34fa74f3e7cf11c1b9a8a1b01e921..ef27fbd5d9c54694beac4d1b400dc7d512db38da 100644 (file)
@@ -23,20 +23,20 @@ static void kvm_rtas_set_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
        u32 irq, server, priority;
        int rc;
 
-       if (args->nargs != 3 || args->nret != 1) {
+       if (be32_to_cpu(args->nargs) != 3 || be32_to_cpu(args->nret) != 1) {
                rc = -3;
                goto out;
        }
 
-       irq = args->args[0];
-       server = args->args[1];
-       priority = args->args[2];
+       irq = be32_to_cpu(args->args[0]);
+       server = be32_to_cpu(args->args[1]);
+       priority = be32_to_cpu(args->args[2]);
 
        rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority);
        if (rc)
                rc = -3;
 out:
-       args->rets[0] = rc;
+       args->rets[0] = cpu_to_be32(rc);
 }
 
 static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
@@ -44,12 +44,12 @@ static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
        u32 irq, server, priority;
        int rc;
 
-       if (args->nargs != 1 || args->nret != 3) {
+       if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 3) {
                rc = -3;
                goto out;
        }
 
-       irq = args->args[0];
+       irq = be32_to_cpu(args->args[0]);
 
        server = priority = 0;
        rc = kvmppc_xics_get_xive(vcpu->kvm, irq, &server, &priority);
@@ -58,10 +58,10 @@ static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
                goto out;
        }
 
-       args->rets[1] = server;
-       args->rets[2] = priority;
+       args->rets[1] = cpu_to_be32(server);
+       args->rets[2] = cpu_to_be32(priority);
 out:
-       args->rets[0] = rc;
+       args->rets[0] = cpu_to_be32(rc);
 }
 
 static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args)
@@ -69,18 +69,18 @@ static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args)
        u32 irq;
        int rc;
 
-       if (args->nargs != 1 || args->nret != 1) {
+       if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
                rc = -3;
                goto out;
        }
 
-       irq = args->args[0];
+       irq = be32_to_cpu(args->args[0]);
 
        rc = kvmppc_xics_int_off(vcpu->kvm, irq);
        if (rc)
                rc = -3;
 out:
-       args->rets[0] = rc;
+       args->rets[0] = cpu_to_be32(rc);
 }
 
 static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args)
@@ -88,18 +88,18 @@ static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args)
        u32 irq;
        int rc;
 
-       if (args->nargs != 1 || args->nret != 1) {
+       if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
                rc = -3;
                goto out;
        }
 
-       irq = args->args[0];
+       irq = be32_to_cpu(args->args[0]);
 
        rc = kvmppc_xics_int_on(vcpu->kvm, irq);
        if (rc)
                rc = -3;
 out:
-       args->rets[0] = rc;
+       args->rets[0] = cpu_to_be32(rc);
 }
 #endif /* CONFIG_KVM_XICS */
 
@@ -205,32 +205,6 @@ int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp)
        return rc;
 }
 
-static void kvmppc_rtas_swap_endian_in(struct rtas_args *args)
-{
-#ifdef __LITTLE_ENDIAN__
-       int i;
-
-       args->token = be32_to_cpu(args->token);
-       args->nargs = be32_to_cpu(args->nargs);
-       args->nret = be32_to_cpu(args->nret);
-       for (i = 0; i < args->nargs; i++)
-               args->args[i] = be32_to_cpu(args->args[i]);
-#endif
-}
-
-static void kvmppc_rtas_swap_endian_out(struct rtas_args *args)
-{
-#ifdef __LITTLE_ENDIAN__
-       int i;
-
-       for (i = 0; i < args->nret; i++)
-               args->args[i] = cpu_to_be32(args->args[i]);
-       args->token = cpu_to_be32(args->token);
-       args->nargs = cpu_to_be32(args->nargs);
-       args->nret = cpu_to_be32(args->nret);
-#endif
-}
-
 int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
 {
        struct rtas_token_definition *d;
@@ -249,8 +223,6 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
        if (rc)
                goto fail;
 
-       kvmppc_rtas_swap_endian_in(&args);
-
        /*
         * args->rets is a pointer into args->args. Now that we've
         * copied args we need to fix it up to point into our copy,
@@ -258,13 +230,13 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
         * value so we can restore it on the way out.
         */
        orig_rets = args.rets;
-       args.rets = &args.args[args.nargs];
+       args.rets = &args.args[be32_to_cpu(args.nargs)];
 
        mutex_lock(&vcpu->kvm->lock);
 
        rc = -ENOENT;
        list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) {
-               if (d->token == args.token) {
+               if (d->token == be32_to_cpu(args.token)) {
                        d->handler->handler(vcpu, &args);
                        rc = 0;
                        break;
@@ -275,7 +247,6 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
 
        if (rc == 0) {
                args.rets = orig_rets;
-               kvmppc_rtas_swap_endian_out(&args);
                rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args));
                if (rc)
                        goto fail;
index dd2cc03f406f9a0e1f844473ca92c5560eca6c67..86903d3f5a033d215b3857f979fcea2cb68a3de6 100644 (file)
@@ -473,7 +473,8 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
                if (printk_ratelimit())
                        pr_err("%s: pte not present: gfn %lx, pfn %lx\n",
                                __func__, (long)gfn, pfn);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
        kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg);
 
index 0738f96befbff76829e1119a5feefc915be39da8..43435c6892fb05d4ac2a732d30eef6e58b4bfaf8 100644 (file)
@@ -77,7 +77,7 @@ _GLOBAL(memset)
        stb     r4,0(r6)
        blr
 
-_GLOBAL(memmove)
+_GLOBAL_TOC(memmove)
        cmplw   0,r3,r4
        bgt     backwards_memcpy
        b       memcpy
index 412dd46dd0b7ea7136af14e8559e5d9b78d2c08a..5c09f365c84276161b75fd524fe270b2d43a1db2 100644 (file)
@@ -1198,7 +1198,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                        sh = regs->gpr[rb] & 0x3f;
                        ival = (signed int) regs->gpr[rd];
                        regs->gpr[ra] = ival >> (sh < 32 ? sh : 31);
-                       if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0))
+                       if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0))
                                regs->xer |= XER_CA;
                        else
                                regs->xer &= ~XER_CA;
@@ -1208,7 +1208,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                        sh = rb;
                        ival = (signed int) regs->gpr[rd];
                        regs->gpr[ra] = ival >> sh;
-                       if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+                       if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
                                regs->xer |= XER_CA;
                        else
                                regs->xer &= ~XER_CA;
@@ -1216,7 +1216,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 
 #ifdef __powerpc64__
                case 27:        /* sld */
-                       sh = regs->gpr[rd] & 0x7f;
+                       sh = regs->gpr[rb] & 0x7f;
                        if (sh < 64)
                                regs->gpr[ra] = regs->gpr[rd] << sh;
                        else
@@ -1235,7 +1235,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                        sh = regs->gpr[rb] & 0x7f;
                        ival = (signed long int) regs->gpr[rd];
                        regs->gpr[ra] = ival >> (sh < 64 ? sh : 63);
-                       if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0))
+                       if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0))
                                regs->xer |= XER_CA;
                        else
                                regs->xer &= ~XER_CA;
@@ -1246,7 +1246,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
                        sh = rb | ((instr & 2) << 4);
                        ival = (signed long int) regs->gpr[rd];
                        regs->gpr[ra] = ival >> sh;
-                       if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+                       if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
                                regs->xer |= XER_CA;
                        else
                                regs->xer &= ~XER_CA;
index 022b38e6a80be83c62900419c027562600b0e02a..2d0b4d68a40a076f970fd458ab09d06785a43ff2 100644 (file)
@@ -86,6 +86,7 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa,
        }
 
        of_node_set_flag(dn, OF_DYNAMIC);
+       of_node_init(dn);
 
        return dn;
 }
index 0435bb65d0aaf616d9cf4257b15e242d18d5d58c..1c0a60d988678ebf1f80f5ddc30beaa3f1f40094 100644 (file)
@@ -69,6 +69,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
 
        np->properties = proplist;
        of_node_set_flag(np, OF_DYNAMIC);
+       of_node_init(np);
 
        np->parent = derive_parent(path);
        if (IS_ERR(np->parent)) {
index df38c70cd59ef295328068e432fa55b04e03651f..18ea9e3f8142954926b8fea3afe79ce90193a4b3 100644 (file)
@@ -51,8 +51,8 @@ static inline int restore_fp_ctl(u32 *fpc)
                return 0;
 
        asm volatile(
-               "0:     lfpc    %1\n"
-               "       la      %0,0\n"
+               "       lfpc    %1\n"
+               "0:     la      %0,0\n"
                "1:\n"
                EX_TABLE(0b,1b)
                : "=d" (rc) : "Q" (*fpc), "0" (-EINVAL));
index 7ba7d6784510c257bbadc72d8f9cdf58151b8e5b..e88d35d749501e43b296e8794351f691368dcf5e 100644 (file)
@@ -437,11 +437,11 @@ ENTRY(startup_kdump)
 
 #if defined(CONFIG_64BIT)
 #if defined(CONFIG_MARCH_ZEC12)
-       .long 3, 0xc100efea, 0xf46ce800, 0x00400000
+       .long 3, 0xc100eff2, 0xf46ce800, 0x00400000
 #elif defined(CONFIG_MARCH_Z196)
-       .long 2, 0xc100efea, 0xf46c0000
+       .long 2, 0xc100eff2, 0xf46c0000
 #elif defined(CONFIG_MARCH_Z10)
-       .long 2, 0xc100efea, 0xf0680000
+       .long 2, 0xc100eff2, 0xf0680000
 #elif defined(CONFIG_MARCH_Z9_109)
        .long 1, 0xc100efc2
 #elif defined(CONFIG_MARCH_Z990)
index 2d716734b5b1b2b482e580aee483d07b014c301f..5dc7ad9e2fbf2d1b035194b30db18a82957c1358 100644 (file)
@@ -334,9 +334,14 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                        unsigned long mask = PSW_MASK_USER;
 
                        mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
-                       if ((data & ~mask) != PSW_USER_BITS)
+                       if ((data ^ PSW_USER_BITS) & ~mask)
+                               /* Invalid psw mask. */
+                               return -EINVAL;
+                       if ((data & PSW_MASK_ASC) == PSW_ASC_HOME)
+                               /* Invalid address-space-control bits */
                                return -EINVAL;
                        if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
+                               /* Invalid addressing mode bits */
                                return -EINVAL;
                }
                *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
@@ -672,9 +677,12 @@ static int __poke_user_compat(struct task_struct *child,
 
                        mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
                        /* Build a 64 bit psw mask from 31 bit mask. */
-                       if ((tmp & ~mask) != PSW32_USER_BITS)
+                       if ((tmp ^ PSW32_USER_BITS) & ~mask)
                                /* Invalid psw mask. */
                                return -EINVAL;
+                       if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
+                               /* Invalid address-space-control bits */
+                               return -EINVAL;
                        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
                                (regs->psw.mask & PSW_MASK_BA) |
                                (__u64)(tmp & mask) << 32;
index 9ddc51eeb8d690410aa6fbf98e1a36a6d544e4db..30de42730b2f20096890cf4022023a4f1b292884 100644 (file)
 static LIST_HEAD(zpci_list);
 static DEFINE_SPINLOCK(zpci_list_lock);
 
-static void zpci_enable_irq(struct irq_data *data);
-static void zpci_disable_irq(struct irq_data *data);
-
 static struct irq_chip zpci_irq_chip = {
        .name = "zPCI",
-       .irq_unmask = zpci_enable_irq,
-       .irq_mask = zpci_disable_irq,
+       .irq_unmask = unmask_msi_irq,
+       .irq_mask = mask_msi_irq,
 };
 
 static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
@@ -244,43 +241,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
        return rc;
 }
 
-static int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag)
-{
-       int offset, pos;
-       u32 mask_bits;
-
-       if (msi->msi_attrib.is_msix) {
-               offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-                       PCI_MSIX_ENTRY_VECTOR_CTRL;
-               msi->masked = readl(msi->mask_base + offset);
-               writel(flag, msi->mask_base + offset);
-       } else if (msi->msi_attrib.maskbit) {
-               pos = (long) msi->mask_base;
-               pci_read_config_dword(msi->dev, pos, &mask_bits);
-               mask_bits &= ~(mask);
-               mask_bits |= flag & mask;
-               pci_write_config_dword(msi->dev, pos, mask_bits);
-       } else
-               return 0;
-
-       msi->msi_attrib.maskbit = !!flag;
-       return 1;
-}
-
-static void zpci_enable_irq(struct irq_data *data)
-{
-       struct msi_desc *msi = irq_get_msi_desc(data->irq);
-
-       zpci_msi_set_mask_bits(msi, 1, 0);
-}
-
-static void zpci_disable_irq(struct irq_data *data)
-{
-       struct msi_desc *msi = irq_get_msi_desc(data->irq);
-
-       zpci_msi_set_mask_bits(msi, 1, 1);
-}
-
 void pcibios_fixup_bus(struct pci_bus *bus)
 {
 }
@@ -487,7 +447,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
 
        /* Release MSI interrupts */
        list_for_each_entry(msi, &pdev->msi_list, list) {
-               zpci_msi_set_mask_bits(msi, 1, 1);
+               if (msi->msi_attrib.is_msix)
+                       default_msix_mask_irq(msi, 1);
+               else
+                       default_msi_mask_irq(msi, 1, 1);
                irq_set_msi_desc(msi->irq, NULL);
                irq_free_desc(msi->irq);
                msi->msg.address_lo = 0;
index d4d16e4be07c246d5941c799e9f4cff5d091d702..bf5b3f5f496239740d0fc451e6c7806d2c2a59fc 100644 (file)
@@ -32,7 +32,8 @@ endif
 
 cflags-$(CONFIG_CPU_SH2)               := $(call cc-option,-m2,)
 cflags-$(CONFIG_CPU_SH2A)              += $(call cc-option,-m2a,) \
-                                          $(call cc-option,-m2a-nofpu,)
+                                          $(call cc-option,-m2a-nofpu,) \
+                                          $(call cc-option,-m4-nofpu,)
 cflags-$(CONFIG_CPU_SH3)               := $(call cc-option,-m3,)
 cflags-$(CONFIG_CPU_SH4)               := $(call cc-option,-m4,) \
        $(call cc-option,-mno-implicit-fp,-m4-nofpu)
index b73274fb961a27a9b54eb5fd1719650762fef305..42f2bca1d338c231c63c6f976b647336459b1435 100644 (file)
 #define __NR_finit_module      342
 #define __NR_sched_setattr     343
 #define __NR_sched_getattr     344
+#define __NR_renameat2         345
 
-#define NR_syscalls            345
+#define NR_syscalls            346
 
 /* Bitmask values returned from kern_features system call.  */
 #define KERN_FEATURE_MIXED_MODE_STACK  0x00000001
index d066eb18650c1598f898f7a4314bdd7ed5b606a7..f834224208ed8ca73d0b12f9d5ad320efd293ca8 100644 (file)
@@ -48,6 +48,7 @@ SIGN1(sys32_futex, compat_sys_futex, %o1)
 SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
 SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
 SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
+SIGN2(sys32_renameat2, sys_renameat2, %o0, %o2)
 
        .globl          sys32_mmap2
 sys32_mmap2:
index 151ace8766cc2d99d5be3552a4b2014eb74fdaa6..85fe9b1087cdb3eae326a46337f5484ca6d9a636 100644 (file)
@@ -86,3 +86,4 @@ sys_call_table:
 /*330*/        .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
 /*335*/        .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
+/*345*/        .long sys_renameat2
index 4bd4e2bb26cf4d35a8980f1a9040cdd88a645a4a..33ecba2826ea20b65693d90649a791db91fd4fcd 100644 (file)
@@ -87,6 +87,7 @@ sys_call_table32:
 /*330*/        .word compat_sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
        .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
+       .word sys32_renameat2
 
 #endif /* CONFIG_COMPAT */
 
@@ -165,3 +166,4 @@ sys_call_table:
 /*330*/        .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
        .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
 /*340*/        .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
+       .word sys_renameat2
index d24887b645dc41cd7e1b098e0d05522e2923cb87..70c43b5371bb57d5c3a3ec58f825b5abfa72f12b 100644 (file)
@@ -21,6 +21,7 @@ config X86_64
 ### Arch settings
 config X86
        def_bool y
+       select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
        select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
@@ -132,6 +133,7 @@ config X86
        select GENERIC_CPU_AUTOPROBE
        select HAVE_ARCH_AUDITSYSCALL
        select ARCH_SUPPORTS_ATOMIC_RMW
+       select ACPI_LEGACY_TABLES_LOOKUP if ACPI
 
 config INSTRUCTION_DECODER
        def_bool y
index 66873297e9f5764d89cf1e57544c65b7f2d86570..1b010a859b8b4816c7b28decea1f853eb0b2b5b3 100644 (file)
@@ -18,8 +18,6 @@
 
 #define ACPI_FLUSH_CPU_CACHE() wbinvd()
 
-#ifdef CONFIG_ACPI
-
 int __acpi_acquire_global_lock(unsigned int *lock);
 int __acpi_release_global_lock(unsigned int *lock);
 
@@ -44,6 +42,4 @@ int __acpi_release_global_lock(unsigned int *lock);
            : "=r"(n_hi), "=r"(n_lo)    \
            : "0"(n_hi), "1"(n_lo))
 
-#endif
-
 #endif /* _ASM_X86_ACENV_H */
index e06225eda63597e4f23ef01c8099fb1b5cf45c41..0ab4f9fd268764114e3f252b07895c4bcaf63f90 100644 (file)
@@ -121,6 +121,11 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf)
                buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
 }
 
+static inline bool acpi_has_cpu_in_madt(void)
+{
+       return !!acpi_lapic;
+}
+
 #else /* !CONFIG_ACPI */
 
 #define acpi_lapic 0
index a80029035bf2ae6acc5b4958df0dae905308d50b..f9e4fdd3b87736044840678a9fcf9afd6fc71b2f 100644 (file)
@@ -370,6 +370,17 @@ static void init_intel(struct cpuinfo_x86 *c)
         */
        detect_extended_topology(c);
 
+       if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) {
+               /*
+                * let's use the legacy cpuid vector 0x1 and 0x4 for topology
+                * detection.
+                */
+               c->x86_max_cores = intel_num_cpu_cores(c);
+#ifdef CONFIG_X86_32
+               detect_ht(c);
+#endif
+       }
+
        l2 = init_intel_cacheinfo(c);
        if (c->cpuid_level > 9) {
                unsigned eax = cpuid_eax(10);
@@ -438,17 +449,6 @@ static void init_intel(struct cpuinfo_x86 *c)
                set_cpu_cap(c, X86_FEATURE_P3);
 #endif
 
-       if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) {
-               /*
-                * let's use the legacy cpuid vector 0x1 and 0x4 for topology
-                * detection.
-                */
-               c->x86_max_cores = intel_num_cpu_cores(c);
-#ifdef CONFIG_X86_32
-               detect_ht(c);
-#endif
-       }
-
        /* Work around errata */
        srat_detect_node(c);
 
index a952e9c85b6fad81684c4bd39418bd5623a634ff..9c8f7394c612e7fa74d0ce356caa6d526dc02b0f 100644 (file)
@@ -730,6 +730,18 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c)
 #endif
        }
 
+#ifdef CONFIG_X86_HT
+       /*
+        * If cpu_llc_id is not yet set, this means cpuid_level < 4 which in
+        * turns means that the only possibility is SMT (as indicated in
+        * cpuid1). Since cpuid2 doesn't specify shared caches, and we know
+        * that SMT shares all caches, we can unconditionally set cpu_llc_id to
+        * c->phys_proc_id.
+        */
+       if (per_cpu(cpu_llc_id, cpu) == BAD_APICID)
+               per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+#endif
+
        c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
 
        return l2;
index bb92f38153b210a05fc16520e4b0bc44e828537d..9a79c8dbd8e87956374829d7a390b35e9330287d 100644 (file)
@@ -2451,6 +2451,12 @@ static __init int mcheck_init_device(void)
        for_each_online_cpu(i) {
                err = mce_device_create(i);
                if (err) {
+                       /*
+                        * Register notifier anyway (and do not unreg it) so
+                        * that we don't leave undeleted timers, see notifier
+                        * callback above.
+                        */
+                       __register_hotcpu_notifier(&mce_cpu_notifier);
                        cpu_notifier_register_done();
                        goto err_device_create;
                }
@@ -2471,10 +2477,6 @@ static __init int mcheck_init_device(void)
 err_register:
        unregister_syscore_ops(&mce_syscore_ops);
 
-       cpu_notifier_register_begin();
-       __unregister_hotcpu_notifier(&mce_cpu_notifier);
-       cpu_notifier_register_done();
-
 err_device_create:
        /*
         * We didn't keep track of which devices were created above, but
index 2bdfbff8a4f6165afb1e9931edcfb250c7113a34..2879ecdaac430c62710db3c90b326e6e25f60acf 100644 (file)
@@ -118,6 +118,9 @@ static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
                        continue;
                if (event->attr.config1 & ~er->valid_mask)
                        return -EINVAL;
+               /* Check if the extra msrs can be safely accessed*/
+               if (!er->extra_msr_access)
+                       return -ENXIO;
 
                reg->idx = er->idx;
                reg->config = event->attr.config1;
index 3b2f9bdd974be198d0622e306ddbba427add2d25..8ade93111e0379fd79e0b421d29256b6c9b1b206 100644 (file)
@@ -295,14 +295,16 @@ struct extra_reg {
        u64                     config_mask;
        u64                     valid_mask;
        int                     idx;  /* per_xxx->regs[] reg index */
+       bool                    extra_msr_access;
 };
 
 #define EVENT_EXTRA_REG(e, ms, m, vm, i) {     \
-       .event = (e),           \
-       .msr = (ms),            \
-       .config_mask = (m),     \
-       .valid_mask = (vm),     \
-       .idx = EXTRA_REG_##i,   \
+       .event = (e),                   \
+       .msr = (ms),                    \
+       .config_mask = (m),             \
+       .valid_mask = (vm),             \
+       .idx = EXTRA_REG_##i,           \
+       .extra_msr_access = true,       \
        }
 
 #define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx)     \
index 07846d738bdb06dd42b44c3294359bb16e07cd48..2502d0d9d246a1fe63c57070176b2bcc04cad3bb 100644 (file)
@@ -2182,6 +2182,41 @@ static void intel_snb_check_microcode(void)
        }
 }
 
+/*
+ * Under certain circumstances, access certain MSR may cause #GP.
+ * The function tests if the input MSR can be safely accessed.
+ */
+static bool check_msr(unsigned long msr, u64 mask)
+{
+       u64 val_old, val_new, val_tmp;
+
+       /*
+        * Read the current value, change it and read it back to see if it
+        * matches, this is needed to detect certain hardware emulators
+        * (qemu/kvm) that don't trap on the MSR access and always return 0s.
+        */
+       if (rdmsrl_safe(msr, &val_old))
+               return false;
+
+       /*
+        * Only change the bits which can be updated by wrmsrl.
+        */
+       val_tmp = val_old ^ mask;
+       if (wrmsrl_safe(msr, val_tmp) ||
+           rdmsrl_safe(msr, &val_new))
+               return false;
+
+       if (val_new != val_tmp)
+               return false;
+
+       /* Here it's sure that the MSR can be safely accessed.
+        * Restore the old value and return.
+        */
+       wrmsrl(msr, val_old);
+
+       return true;
+}
+
 static __init void intel_sandybridge_quirk(void)
 {
        x86_pmu.check_microcode = intel_snb_check_microcode;
@@ -2271,7 +2306,8 @@ __init int intel_pmu_init(void)
        union cpuid10_ebx ebx;
        struct event_constraint *c;
        unsigned int unused;
-       int version;
+       struct extra_reg *er;
+       int version, i;
 
        if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
                switch (boot_cpu_data.x86) {
@@ -2474,6 +2510,9 @@ __init int intel_pmu_init(void)
        case 62: /* IvyBridge EP */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
+               /* dTLB-load-misses on IVB is different than SNB */
+               hw_cache_event_ids[C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = 0x8108; /* DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK */
+
                memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
                       sizeof(hw_cache_extra_regs));
 
@@ -2574,6 +2613,34 @@ __init int intel_pmu_init(void)
                }
        }
 
+       /*
+        * Access LBR MSR may cause #GP under certain circumstances.
+        * E.g. KVM doesn't support LBR MSR
+        * Check all LBT MSR here.
+        * Disable LBR access if any LBR MSRs can not be accessed.
+        */
+       if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
+               x86_pmu.lbr_nr = 0;
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
+                     check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
+                       x86_pmu.lbr_nr = 0;
+       }
+
+       /*
+        * Access extra MSR may cause #GP under certain circumstances.
+        * E.g. KVM doesn't support offcore event
+        * Check all extra_regs here.
+        */
+       if (x86_pmu.extra_regs) {
+               for (er = x86_pmu.extra_regs; er->msr; er++) {
+                       er->extra_msr_access = check_msr(er->msr, 0x1ffUL);
+                       /* Disable LBR select mapping */
+                       if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
+                               x86_pmu.lbr_sel_map = NULL;
+               }
+       }
+
        /* Support full width counters using alternative MSR range */
        if (x86_pmu.intel_cap.full_width_write) {
                x86_pmu.max_period = x86_pmu.cntval_mask;
index 980970cb744db6793a0f355f092db0e4a17b6ec5..696ade311ded7d01103323d159cff621b46d4a89 100644 (file)
@@ -311,9 +311,11 @@ static int alloc_bts_buffer(int cpu)
        if (!x86_pmu.bts)
                return 0;
 
-       buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL, node);
-       if (unlikely(!buffer))
+       buffer = kzalloc_node(BTS_BUFFER_SIZE, GFP_KERNEL | __GFP_NOWARN, node);
+       if (unlikely(!buffer)) {
+               WARN_ONCE(1, "%s: BTS buffer allocation failure\n", __func__);
                return -ENOMEM;
+       }
 
        max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
        thresh = max / 16;
index 65bbbea38b9c9c0f7246a3c4fee4176dd529647b..ae6552a0701f25330bd0e7027e5767ac32cdfdcd 100644 (file)
@@ -550,16 +550,16 @@ static struct extra_reg snbep_uncore_cbox_extra_regs[] = {
        SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8),
-       SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xc),
-       SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xc),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8),
-       SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xc),
-       SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xc),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2),
@@ -1222,6 +1222,7 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = {
        SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,
                                  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),
        SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2),
+
        SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc),
        SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),
@@ -1245,7 +1246,7 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = {
        SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10),
        SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10),
-       SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10),
        SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18),
        SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18),
index dbaa23e78b369721d5082af26cc18fa698985d09..0d0c9d4ab6d5b0d9cc1009ae03aebff22c1e8585 100644 (file)
@@ -425,8 +425,8 @@ sysenter_do_call:
        cmpl $(NR_syscalls), %eax
        jae sysenter_badsys
        call *sys_call_table(,%eax,4)
-       movl %eax,PT_EAX(%esp)
 sysenter_after_call:
+       movl %eax,PT_EAX(%esp)
        LOCKDEP_SYS_EXIT
        DISABLE_INTERRUPTS(CLBR_ANY)
        TRACE_IRQS_OFF
@@ -502,6 +502,7 @@ ENTRY(system_call)
        jae syscall_badsys
 syscall_call:
        call *sys_call_table(,%eax,4)
+syscall_after_call:
        movl %eax,PT_EAX(%esp)          # store the return value
 syscall_exit:
        LOCKDEP_SYS_EXIT
@@ -675,12 +676,12 @@ syscall_fault:
 END(syscall_fault)
 
 syscall_badsys:
-       movl $-ENOSYS,PT_EAX(%esp)
-       jmp syscall_exit
+       movl $-ENOSYS,%eax
+       jmp syscall_after_call
 END(syscall_badsys)
 
 sysenter_badsys:
-       movl $-ENOSYS,PT_EAX(%esp)
+       movl $-ENOSYS,%eax
        jmp sysenter_after_call
 END(syscall_badsys)
        CFI_ENDPROC
index 7596df664901eed5a7aea5003ab83da49d34a615..67e6d19ef1be65e49a176a1c3bbd43cab654e7f5 100644 (file)
@@ -574,6 +574,9 @@ int kprobe_int3_handler(struct pt_regs *regs)
        struct kprobe *p;
        struct kprobe_ctlblk *kcb;
 
+       if (user_mode_vm(regs))
+               return 0;
+
        addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
        /*
         * We don't want to be preempted for the entire
index f6449334ec4514741f7f79481e419d30442d1ac2..ef432f891d30a69468a8093c2bd6f33ca1a7d54f 100644 (file)
@@ -5887,6 +5887,18 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win)
                        kvm_x86_ops->set_nmi(vcpu);
                }
        } else if (kvm_cpu_has_injectable_intr(vcpu)) {
+               /*
+                * Because interrupts can be injected asynchronously, we are
+                * calling check_nested_events again here to avoid a race condition.
+                * See https://lkml.org/lkml/2014/7/2/60 for discussion about this
+                * proposal and current concerns.  Perhaps we should be setting
+                * KVM_REQ_EVENT only on certain events and not unconditionally?
+                */
+               if (is_guest_mode(vcpu) && kvm_x86_ops->check_nested_events) {
+                       r = kvm_x86_ops->check_nested_events(vcpu, req_int_win);
+                       if (r != 0)
+                               return r;
+               }
                if (kvm_x86_ops->interrupt_allowed(vcpu)) {
                        kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu),
                                            false);
index f9e1ec346e359c7410482c5d8dfd5a9de88bfafc..8453e6e398951b0d1864b6e570c8d7d63e45d356 100644 (file)
@@ -376,38 +376,42 @@ _DoubleExceptionVector_WindowOverflow:
        beqz    a2, 1f          # if at start of vector, don't restore
 
        addi    a0, a0, -128
-       bbsi    a0, 8, 1f       # don't restore except for overflow 8 and 12
-       bbsi    a0, 7, 2f
+       bbsi.l  a0, 8, 1f       # don't restore except for overflow 8 and 12
+
+       /*
+        * This fixup handler is for the extremely unlikely case where the
+        * overflow handler's reference thru a0 gets a hardware TLB refill
+        * that bumps out the (distinct, aliasing) TLB entry that mapped its
+        * prior references thru a9/a13, and where our reference now thru
+        * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill).
+        */
+       movi    a2, window_overflow_restore_a0_fixup
+       s32i    a2, a3, EXC_TABLE_FIXUP
+       l32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       xsr     a3, excsave1
+
+       bbsi.l  a0, 7, 2f
 
        /*
         * Restore a0 as saved by _WindowOverflow8().
-        *
-        * FIXME:  we really need a fixup handler for this L32E,
-        * for the extremely unlikely case where the overflow handler's
-        * reference thru a0 gets a hardware TLB refill that bumps out
-        * the (distinct, aliasing) TLB entry that mapped its prior
-        * references thru a9, and where our reference now thru a9
-        * gets a 2nd-level miss exception (not hardware TLB refill).
         */
 
-       l32e    a2, a9, -16
-       wsr     a2, depc        # replace the saved a0
-       j       1f
+       l32e    a0, a9, -16
+       wsr     a0, depc        # replace the saved a0
+       j       3f
 
 2:
        /*
         * Restore a0 as saved by _WindowOverflow12().
-        *
-        * FIXME:  we really need a fixup handler for this L32E,
-        * for the extremely unlikely case where the overflow handler's
-        * reference thru a0 gets a hardware TLB refill that bumps out
-        * the (distinct, aliasing) TLB entry that mapped its prior
-        * references thru a13, and where our reference now thru a13
-        * gets a 2nd-level miss exception (not hardware TLB refill).
         */
 
-       l32e    a2, a13, -16
-       wsr     a2, depc        # replace the saved a0
+       l32e    a0, a13, -16
+       wsr     a0, depc        # replace the saved a0
+3:
+       xsr     a3, excsave1
+       movi    a0, 0
+       s32i    a0, a3, EXC_TABLE_FIXUP
+       s32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
 1:
        /*
         * Restore WindowBase while leaving all address registers restored.
@@ -449,6 +453,7 @@ _DoubleExceptionVector_WindowOverflow:
 
        s32i    a0, a2, PT_DEPC
 
+_DoubleExceptionVector_handle_exception:
        addx4   a0, a0, a3
        l32i    a0, a0, EXC_TABLE_FAST_USER
        xsr     a3, excsave1
@@ -464,10 +469,119 @@ _DoubleExceptionVector_WindowOverflow:
        rotw    -3
        j       1b
 
-       .end literal_prefix
 
 ENDPROC(_DoubleExceptionVector)
 
+/*
+ * Fixup handler for TLB miss in double exception handler for window owerflow.
+ * We get here with windowbase set to the window that was being spilled and
+ * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12
+ * (bit set) window.
+ *
+ * We do the following here:
+ * - go to the original window retaining a0 value;
+ * - set up exception stack to return back to appropriate a0 restore code
+ *   (we'll need to rotate window back and there's no place to save this
+ *    information, use different return address for that);
+ * - handle the exception;
+ * - go to the window that was being spilled;
+ * - set up window_overflow_restore_a0_fixup as a fixup routine;
+ * - reload a0;
+ * - restore the original window;
+ * - reset the default fixup routine;
+ * - return to user. By the time we get to this fixup handler all information
+ *   about the conditions of the original double exception that happened in
+ *   the window overflow handler is lost, so we just return to userspace to
+ *   retry overflow from start.
+ *
+ * a0: value of depc, original value in depc
+ * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
+ * a3: exctable, original value in excsave1
+ */
+
+ENTRY(window_overflow_restore_a0_fixup)
+
+       rsr     a0, ps
+       extui   a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
+       rsr     a2, windowbase
+       sub     a0, a2, a0
+       extui   a0, a0, 0, 3
+       l32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       xsr     a3, excsave1
+
+       _beqi   a0, 1, .Lhandle_1
+       _beqi   a0, 3, .Lhandle_3
+
+       .macro  overflow_fixup_handle_exception_pane n
+
+       rsr     a0, depc
+       rotw    -\n
+
+       xsr     a3, excsave1
+       wsr     a2, depc
+       l32i    a2, a3, EXC_TABLE_KSTK
+       s32i    a0, a2, PT_AREG0
+
+       movi    a0, .Lrestore_\n
+       s32i    a0, a2, PT_DEPC
+       rsr     a0, exccause
+       j       _DoubleExceptionVector_handle_exception
+
+       .endm
+
+       overflow_fixup_handle_exception_pane 2
+.Lhandle_1:
+       overflow_fixup_handle_exception_pane 1
+.Lhandle_3:
+       overflow_fixup_handle_exception_pane 3
+
+       .macro  overflow_fixup_restore_a0_pane n
+
+       rotw    \n
+       /* Need to preserve a0 value here to be able to handle exception
+        * that may occur on a0 reload from stack. It may occur because
+        * TLB miss handler may not be atomic and pointer to page table
+        * may be lost before we get here. There are no free registers,
+        * so we need to use EXC_TABLE_DOUBLE_SAVE area.
+        */
+       xsr     a3, excsave1
+       s32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       movi    a2, window_overflow_restore_a0_fixup
+       s32i    a2, a3, EXC_TABLE_FIXUP
+       l32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       xsr     a3, excsave1
+       bbsi.l  a0, 7, 1f
+       l32e    a0, a9, -16
+       j       2f
+1:
+       l32e    a0, a13, -16
+2:
+       rotw    -\n
+
+       .endm
+
+.Lrestore_2:
+       overflow_fixup_restore_a0_pane 2
+
+.Lset_default_fixup:
+       xsr     a3, excsave1
+       s32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       movi    a2, 0
+       s32i    a2, a3, EXC_TABLE_FIXUP
+       l32i    a2, a3, EXC_TABLE_DOUBLE_SAVE
+       xsr     a3, excsave1
+       rfe
+
+.Lrestore_1:
+       overflow_fixup_restore_a0_pane 1
+       j       .Lset_default_fixup
+.Lrestore_3:
+       overflow_fixup_restore_a0_pane 3
+       j       .Lset_default_fixup
+
+ENDPROC(window_overflow_restore_a0_fixup)
+
+       .end literal_prefix
 /*
  * Debug interrupt vector
  *
index ee32c0085dff4296fb9290e3706733db9402460d..d16db6df86f8e3d823ac2f189816d9889249323e 100644 (file)
@@ -269,13 +269,13 @@ SECTIONS
                  .UserExceptionVector.literal)
   SECTION_VECTOR (_DoubleExceptionVector_literal,
                  .DoubleExceptionVector.literal,
-                 DOUBLEEXC_VECTOR_VADDR - 16,
+                 DOUBLEEXC_VECTOR_VADDR - 40,
                  SIZEOF(.UserExceptionVector.text),
                  .UserExceptionVector.text)
   SECTION_VECTOR (_DoubleExceptionVector_text,
                  .DoubleExceptionVector.text,
                  DOUBLEEXC_VECTOR_VADDR,
-                 32,
+                 40,
                  .DoubleExceptionVector.literal)
 
   . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
index 4224256bb215f17c52d91662f186ecb250dee361..77ed20209ca57232dd79afa60fe91210515746bf 100644 (file)
@@ -191,7 +191,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
                return -EINVAL;
        }
 
-       if (it && start - it->start < bank_sz) {
+       if (it && start - it->start <= bank_sz) {
                if (start == it->start) {
                        if (end - it->start < bank_sz) {
                                it->start = end;
index b9f4cc494ecefbf2560483bdc4685bb98d59b5d3..28d227c5ca7781aed5bb15cf37d3b0f1dcaa8d79 100644 (file)
@@ -872,6 +872,13 @@ void blkcg_drain_queue(struct request_queue *q)
 {
        lockdep_assert_held(q->queue_lock);
 
+       /*
+        * @q could be exiting and already have destroyed all blkgs as
+        * indicated by NULL root_blkg.  If so, don't confuse policies.
+        */
+       if (!q->root_blkg)
+               return;
+
        blk_throtl_drain(q);
 }
 
index 3f33d86722688a4f50ac0064488540d1960447fb..a185b86741e5ff80dccbc5223eb570f764199d86 100644 (file)
@@ -27,18 +27,15 @@ struct request *blk_queue_find_tag(struct request_queue *q, int tag)
 EXPORT_SYMBOL(blk_queue_find_tag);
 
 /**
- * __blk_free_tags - release a given set of tag maintenance info
+ * blk_free_tags - release a given set of tag maintenance info
  * @bqt:       the tag map to free
  *
- * Tries to free the specified @bqt.  Returns true if it was
- * actually freed and false if there are still references using it
+ * Drop the reference count on @bqt and frees it when the last reference
+ * is dropped.
  */
-static int __blk_free_tags(struct blk_queue_tag *bqt)
+void blk_free_tags(struct blk_queue_tag *bqt)
 {
-       int retval;
-
-       retval = atomic_dec_and_test(&bqt->refcnt);
-       if (retval) {
+       if (atomic_dec_and_test(&bqt->refcnt)) {
                BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
                                                        bqt->max_depth);
 
@@ -50,9 +47,8 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)
 
                kfree(bqt);
        }
-
-       return retval;
 }
+EXPORT_SYMBOL(blk_free_tags);
 
 /**
  * __blk_queue_free_tags - release tag maintenance info
@@ -69,27 +65,12 @@ void __blk_queue_free_tags(struct request_queue *q)
        if (!bqt)
                return;
 
-       __blk_free_tags(bqt);
+       blk_free_tags(bqt);
 
        q->queue_tags = NULL;
        queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
 }
 
-/**
- * blk_free_tags - release a given set of tag maintenance info
- * @bqt:       the tag map to free
- *
- * For externally managed @bqt frees the map.  Callers of this
- * function must guarantee to have released all the queues that
- * might have been using this tag map.
- */
-void blk_free_tags(struct blk_queue_tag *bqt)
-{
-       if (unlikely(!__blk_free_tags(bqt)))
-               BUG();
-}
-EXPORT_SYMBOL(blk_free_tags);
-
 /**
  * blk_queue_free_tags - release tag maintenance info
  * @q:  the request queue for the device
index fbd5a67cb773886104cac49698ee589b8fbc9933..a0926a6094b28a7e4e67b3a88afc993719294405 100644 (file)
@@ -690,6 +690,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        case BLKROSET:
        case BLKDISCARD:
        case BLKSECDISCARD:
+       case BLKZEROOUT:
        /*
         * the ones below are implemented in blkdev_locked_ioctl,
         * but we call blkdev_ioctl, which gets the lock for us
index a34a22841002495713a74f960dea482ecee8dc11..3f5f745bbbea80327086e7391152b3a283733188 100644 (file)
@@ -42,6 +42,12 @@ menuconfig ACPI
 
 if ACPI
 
+config ACPI_LEGACY_TABLES_LOOKUP
+       bool
+
+config ARCH_MIGHT_HAVE_ACPI_PDC
+       bool
+
 config ACPI_SLEEP
        bool
        depends on SUSPEND || HIBERNATION
index ea55e0179f817c6331149315a6c7f3245e84de2d..505d4d79fe3e4ce74a631f487ce243e6ae7decb3 100644 (file)
@@ -36,6 +36,7 @@ acpi-y                                += scan.o
 acpi-y                         += resource.o
 acpi-y                         += acpi_processor.o
 acpi-y                         += processor_core.o
+acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
 acpi-y                         += ec.o
 acpi-$(CONFIG_ACPI_DOCK)       += dock.o
 acpi-y                         += pci_root.o pci_link.o pci_irq.o
index 185334114d71005e649f10fd04acfcd4b7bf14ef..340d09518f8e986a56bffd4dc61291fbcb6e0b87 100644 (file)
@@ -69,11 +69,11 @@ static u32 l1_percpu_entry;
 #define ELOG_ENTRY_ADDR(phyaddr) \
        (phyaddr - elog_base + (u8 *)elog_addr)
 
-static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
+static struct acpi_hest_generic_status *extlog_elog_entry_check(int cpu, int bank)
 {
        int idx;
        u64 data;
-       struct acpi_generic_status *estatus;
+       struct acpi_hest_generic_status *estatus;
 
        WARN_ON(cpu < 0);
        idx = ELOG_IDX(cpu, bank);
@@ -82,7 +82,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
                return NULL;
 
        data &= EXT_ELOG_ENTRY_MASK;
-       estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data);
+       estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data);
 
        /* if no valid data in elog entry, just return */
        if (estatus->block_status == 0)
@@ -92,7 +92,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
 }
 
 static void __print_extlog_rcd(const char *pfx,
-                              struct acpi_generic_status *estatus, int cpu)
+                              struct acpi_hest_generic_status *estatus, int cpu)
 {
        static atomic_t seqno;
        unsigned int curr_seqno;
@@ -111,7 +111,7 @@ static void __print_extlog_rcd(const char *pfx,
 }
 
 static int print_extlog_rcd(const char *pfx,
-                           struct acpi_generic_status *estatus, int cpu)
+                           struct acpi_hest_generic_status *estatus, int cpu)
 {
        /* Not more than 2 messages every 5 seconds */
        static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
@@ -137,7 +137,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
        struct mce *mce = (struct mce *)data;
        int     bank = mce->bank;
        int     cpu = mce->extcpu;
-       struct acpi_generic_status *estatus;
+       struct acpi_hest_generic_status *estatus;
        int rc;
 
        estatus = extlog_elog_entry_check(cpu, bank);
@@ -148,7 +148,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
        /* clear record status to enable BIOS to update it again */
        estatus->block_status = 0;
 
-       rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu);
+       rc = print_extlog_rcd(NULL, (struct acpi_hest_generic_status *)elog_buf, cpu);
 
        return NOTIFY_STOP;
 }
index 1c085742644faaef4f2da64bb1d7e857a7bd16f9..1fdf5e07a1c7cb0440594b12f8b78408c1c25bd4 100644 (file)
@@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
        pr->apic_id = apic_id;
 
        cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
-       if (!cpu0_initialized && !acpi_lapic) {
+       if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
                cpu0_initialized = 1;
                /* Handle UP system running SMP kernel, with no LAPIC in MADT */
                if ((cpu_index == -1) && (num_online_cpus() == 1))
index 8bb43f06e11fda07c6e71718fab7b2baa37a5a57..4be4cc94572d222a56960df60208fc7103d61b83 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for ACPICA Core interpreter
 #
 
-ccflags-y                      := -Os
+ccflags-y                      := -Os -DBUILDING_ACPICA
 ccflags-$(CONFIG_ACPI_DEBUG)   += -DACPI_DEBUG_OUTPUT
 
 # use acpi.o to put all files here into acpi.o modparam namespace
@@ -175,5 +175,5 @@ acpi-y +=           \
        utxferror.o     \
        utxfmutex.o
 
-acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o
+acpi-$(ACPI_FUTURE_USAGE) += utfileio.o utprint.o uttrack.o utcache.o
 
index 8698ffba6f392dd0e4c8b7db4b918ce9f4796464..3d2c88289da9ff88a0dde088ee5a3aba30362131 100644 (file)
 /* Macros for usage messages */
 
 #define ACPI_USAGE_HEADER(usage) \
-       printf ("Usage: %s\nOptions:\n", usage);
+       acpi_os_printf ("Usage: %s\nOptions:\n", usage);
+
+#define ACPI_USAGE_TEXT(description) \
+       acpi_os_printf (description);
 
 #define ACPI_OPTION(name, description) \
-       printf ("  %-18s%s\n", name, description);
+       acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY     "dsl"
 #define ACPI_TABLE_FILE_SUFFIX      ".dat"
@@ -102,7 +105,7 @@ extern char *acpi_gbl_optarg;
 /*
  * cmfsize - Common get file size function
  */
-u32 cm_get_file_size(FILE * file);
+u32 cm_get_file_size(ACPI_FILE file);
 
 #ifndef ACPI_DUMP_APP
 /*
index 68a91eb0fa483f24b55218770c4bed079873d3e6..1d026ff1683f381fffaae26cfa9262d9e208416d 100644 (file)
@@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename);
 acpi_status
 acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table);
 
-acpi_status
-acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table);
-
 /*
  * dbhistry - debugger HISTORY command
  */
index 115eedcade1e3d9ad652830936ac80c52ff42fec..ebf02cc10a430a9c52d99e3f245f20ce671ceab5 100644 (file)
@@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer);
  *
  ****************************************************************************/
 
-ACPI_GLOBAL(u8, acpi_gbl_db_output_flags);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT);
 
 #ifdef ACPI_DISASSEMBLER
 
@@ -362,6 +362,12 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 #ifdef ACPI_APPLICATION
 
 ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
+ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL);
+
+/* Print buffer */
+
+ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock);       /* For print buffer */
+ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]);
 
 #endif                         /* ACPI_APPLICATION */
 
index 1e256c5bda20675e73c1dbccd736cfc56606aebc..ed614f4b218273f8b000ebc017d699e0d09ef141 100644 (file)
@@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[];
 #ifdef ACPI_ASL_COMPILER
 
 #include <stdio.h>
-extern FILE *acpi_gbl_output_file;
 
 #define ACPI_MSG_REDIRECT_BEGIN \
        FILE                            *output_file = acpi_gbl_output_file; \
@@ -211,6 +210,8 @@ void acpi_ut_subsystem_shutdown(void);
 
 acpi_size acpi_ut_strlen(const char *string);
 
+char *acpi_ut_strchr(const char *string, int ch);
+
 char *acpi_ut_strcpy(char *dst_string, const char *src_string);
 
 char *acpi_ut_strncpy(char *dst_string,
@@ -257,7 +258,7 @@ extern const u8 _acpi_ctype[];
 #define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
 #define ACPI_IS_UPPER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
 #define ACPI_IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
-#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
+#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
 #define ACPI_IS_ALPHA(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
 
 #endif                         /* !ACPI_USE_SYSTEM_CLIBRARY */
@@ -352,6 +353,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);
 
 void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset);
 
+#ifdef ACPI_APPLICATION
+void
+acpi_ut_dump_buffer_to_file(ACPI_FILE file,
+                           u8 *buffer,
+                           u32 count, u32 display, u32 base_offset);
+#endif
+
 void acpi_ut_report_error(char *module_name, u32 line_number);
 
 void acpi_ut_report_info(char *module_name, u32 line_number);
@@ -393,6 +401,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
                              const char **method_names,
                              u8 method_count, u8 *out_values);
 
+/*
+ * utfileio - file operations
+ */
+#ifdef ACPI_APPLICATION
+acpi_status
+acpi_ut_read_table_from_file(char *filename, struct acpi_table_header **table);
+#endif
+
 /*
  * utids - device ID support
  */
@@ -743,4 +759,23 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);
 
 const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
 
+/*
+ * utprint - printf/vprintf output functions
+ */
+const char *acpi_ut_scan_number(const char *string, u64 *number_ptr);
+
+const char *acpi_ut_print_number(char *string, u64 number);
+
+int
+acpi_ut_vsnprintf(char *string,
+                 acpi_size size, const char *format, va_list args);
+
+int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...);
+
+#ifdef ACPI_APPLICATION
+int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args);
+
+int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...);
+#endif
+
 #endif                         /* _ACUTILS_H */
index 48f70013b488c7cdbb956b6ab316afe1c8396f03..e4ba4dec86af19ef447f3a4783c39015e558778f 100644 (file)
@@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
                                              acpi_gbl_global_event_handler_context);
        }
 
-       /*
-        * If edge-triggered, clear the GPE status bit now. Note that
-        * level-triggered events are cleared after the GPE is serviced.
-        */
-       if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
-           ACPI_GPE_EDGE_TRIGGERED) {
-               status = acpi_hw_clear_gpe(gpe_event_info);
-               if (ACPI_FAILURE(status)) {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "Unable to clear GPE %02X",
-                                       gpe_number));
-                       return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
-               }
-       }
-
        /*
         * Always disable the GPE so that it does not keep firing before
         * any asynchronous activity completes (either from the execution
@@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
                return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
        }
 
+       /*
+        * If edge-triggered, clear the GPE status bit now. Note that
+        * level-triggered events are cleared after the GPE is serviced.
+        */
+       if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+           ACPI_GPE_EDGE_TRIGGERED) {
+               status = acpi_hw_clear_gpe(gpe_event_info);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_EXCEPTION((AE_INFO, status,
+                                       "Unable to clear GPE %02X",
+                                       gpe_number));
+                       (void)acpi_hw_low_set_gpe(gpe_event_info,
+                                                 ACPI_GPE_CONDITIONAL_ENABLE);
+                       return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+               }
+       }
+
        /*
         * Dispatch the GPE to either an installed handler or the control
         * method associated with this GPE (_Lxx or _Exx). If a handler
index cb534faf536986da69a55fa3dc255e6de6a560cf..0cf159cc6e6d79085fa03ef15dcc91d9e53ec409 100644 (file)
@@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
 
        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
-       /* Ensure that we have a valid GPE number */
-
+       /*
+        * Ensure that we have a valid GPE number and that there is some way
+        * of handling the GPE (handler or a GPE method). In other words, we
+        * won't allow a valid GPE to be enabled if there is no way to handle it.
+        */
        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
        if (gpe_event_info) {
-               status = acpi_ev_add_gpe_reference(gpe_event_info);
+               if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
+                   ACPI_GPE_DISPATCH_NONE) {
+                       status = acpi_ev_add_gpe_reference(gpe_event_info);
+               } else {
+                       status = AE_NO_HANDLER;
+               }
        }
 
        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
@@ -177,6 +185,53 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_mark_gpe_for_wake
+ *
+ * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
+ *              gpe_number          - GPE level within the GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
+ *              sets the ACPI_GPE_CAN_WAKE flag.
+ *
+ * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
+ * there won't be any notify handlers installed for device wake notifications
+ * from the given GPE (one example is a button GPE in Linux). For these cases,
+ * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
+ * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
+ * setup implicit wake notification for it (since there's no handler method).
+ *
+ ******************************************************************************/
+acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
+{
+       struct acpi_gpe_event_info *gpe_event_info;
+       acpi_status status = AE_BAD_PARAMETER;
+       acpi_cpu_flags flags;
+
+       ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
+
+       flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+       /* Ensure that we have a valid GPE number */
+
+       gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+       if (gpe_event_info) {
+
+               /* Mark the GPE as a possible wake event */
+
+               gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
+               status = AE_OK;
+       }
+
+       acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_setup_gpe_for_wake
index 12878e1982f77d5f69fcad7d266f7ac922f2a12d..1ff42c07b42b116b54bb0bb2166967f7578ea147 100644 (file)
@@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_serial_access_bytes
+ * FUNCTION:    acpi_ex_get_serial_access_length
  *
  * PARAMETERS:  accessor_type   - The type of the protocol indicated by region
  *                                field access attributes
@@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
        case AML_FIELD_ATTRIB_BLOCK_CALL:
        default:
 
-               length = ACPI_GSBUS_BUFFER_SIZE;
+               length = ACPI_GSBUS_BUFFER_SIZE - 2;
                break;
        }
 
index e0fd9b4978cd6a22af964a3165d26cfd62ea032f..a4c34d2c556b24d14f4954d3afe516a39f9b10d9 100644 (file)
@@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
 
        acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
 
-       if (ACPI_FAILURE(status))
+       if (ACPI_FAILURE(status)) {
                goto exit;
+       }
 
        /* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
index fe54a8c73b8c8f1618c12badbe62d07ec73c7ea7..a42ee9d6970d727733cc260912352f56ba89cd22 100644 (file)
@@ -237,6 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
                    (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
                        node->object = node->object->common.next_object;
                }
+
+               /*
+                * Detach the object from any data objects (which are still held by
+                * the namespace node)
+                */
+               if (obj_desc->common.next_object &&
+                   ((obj_desc->common.next_object)->common.type ==
+                    ACPI_TYPE_LOCAL_DATA)) {
+                       obj_desc->common.next_object = NULL;
+               }
        }
 
        /* Reset the node type to untyped */
index 3c16997406535dc2e85445af0fd1b60cd0db2610..038ea887f56292c430bce8222697fde5cac243ee 100644 (file)
@@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
 
        acpi_ut_dump_buffer(buffer, count, display, 0);
 }
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_buffer_to_file
+ *
+ * PARAMETERS:  file                - File descriptor
+ *              buffer              - Buffer to dump
+ *              count               - Amount to dump, in bytes
+ *              display             - BYTE, WORD, DWORD, or QWORD display:
+ *                                      DB_BYTE_DISPLAY
+ *                                      DB_WORD_DISPLAY
+ *                                      DB_DWORD_DISPLAY
+ *                                      DB_QWORD_DISPLAY
+ *              base_offset         - Beginning buffer offset (display only)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii to a file.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_dump_buffer_to_file(ACPI_FILE file,
+                           u8 *buffer, u32 count, u32 display, u32 base_offset)
+{
+       u32 i = 0;
+       u32 j;
+       u32 temp32;
+       u8 buf_char;
+
+       if (!buffer) {
+               acpi_ut_file_printf(file,
+                                   "Null Buffer Pointer in DumpBuffer!\n");
+               return;
+       }
+
+       if ((count < 4) || (count & 0x01)) {
+               display = DB_BYTE_DISPLAY;
+       }
+
+       /* Nasty little dump buffer routine! */
+
+       while (i < count) {
+
+               /* Print current offset */
+
+               acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i));
+
+               /* Print 16 hex chars */
+
+               for (j = 0; j < 16;) {
+                       if (i + j >= count) {
+
+                               /* Dump fill spaces */
+
+                               acpi_ut_file_printf(file, "%*s",
+                                                   ((display * 2) + 1), " ");
+                               j += display;
+                               continue;
+                       }
+
+                       switch (display) {
+                       case DB_BYTE_DISPLAY:
+                       default:        /* Default is BYTE display */
+
+                               acpi_ut_file_printf(file, "%02X ",
+                                                   buffer[(acpi_size) i + j]);
+                               break;
+
+                       case DB_WORD_DISPLAY:
+
+                               ACPI_MOVE_16_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_ut_file_printf(file, "%04X ", temp32);
+                               break;
+
+                       case DB_DWORD_DISPLAY:
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_ut_file_printf(file, "%08X ", temp32);
+                               break;
+
+                       case DB_QWORD_DISPLAY:
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_ut_file_printf(file, "%08X", temp32);
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j +
+                                                          4]);
+                               acpi_ut_file_printf(file, "%08X ", temp32);
+                               break;
+                       }
+
+                       j += display;
+               }
+
+               /*
+                * Print the ASCII equivalent characters but watch out for the bad
+                * unprintable ones (printable chars are 0x20 through 0x7E)
+                */
+               acpi_ut_file_printf(file, " ");
+               for (j = 0; j < 16; j++) {
+                       if (i + j >= count) {
+                               acpi_ut_file_printf(file, "\n");
+                               return;
+                       }
+
+                       buf_char = buffer[(acpi_size) i + j];
+                       if (ACPI_IS_PRINT(buf_char)) {
+                               acpi_ut_file_printf(file, "%c", buf_char);
+                       } else {
+                               acpi_ut_file_printf(file, ".");
+                       }
+               }
+
+               /* Done with that line. */
+
+               acpi_ut_file_printf(file, "\n");
+               i += 16;
+       }
+
+       return;
+}
+#endif
index 270c16464dd948181f98755f8e1f13809c9acf13..ff601c0f7c7a0024048f2e2d10478c6a7104ad13 100644 (file)
@@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
                status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
        }
 
+       /* Delete the allocated object if copy failed */
+
+       if (ACPI_FAILURE(status)) {
+               acpi_ut_remove_reference(*dest_desc);
+       }
+
        return_ACPI_STATUS(status);
 }
index 21a20ac5b1e1aec4f8654b03caab01ba26466c8a..e516254c63b2260deeb1c3824292dd62f0472f1f 100644 (file)
@@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number,
 }
 
 #endif
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_log_error
+ *
+ * PARAMETERS:  format              - Printf format field
+ *              ...                 - Optional printf arguments
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message to the console, used by applications.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)
+{
+       va_list args;
+
+       va_start(args, format);
+       (void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args);
+       va_end(args);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_log_error)
+#endif
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
new file mode 100644 (file)
index 0000000..bdf9914
--- /dev/null
@@ -0,0 +1,332 @@
+/*******************************************************************************
+ *
+ * Module Name: utfileio - simple file I/O routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "actables.h"
+#include "acapps.h"
+
+#ifdef ACPI_ASL_COMPILER
+#include "aslcompiler.h"
+#endif
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("utfileio")
+
+#ifdef ACPI_APPLICATION
+/* Local prototypes */
+static acpi_status
+acpi_ut_check_text_mode_corruption(u8 *table,
+                                  u32 table_length, u32 file_length);
+
+static acpi_status
+acpi_ut_read_table(FILE * fp,
+                  struct acpi_table_header **table, u32 *table_length);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_check_text_mode_corruption
+ *
+ * PARAMETERS:  table           - Table buffer
+ *              table_length    - Length of table from the table header
+ *              file_length     - Length of the file that contains the table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check table for text mode file corruption where all linefeed
+ *              characters (LF) have been replaced by carriage return linefeed
+ *              pairs (CR/LF).
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length)
+{
+       u32 i;
+       u32 pairs = 0;
+
+       if (table_length != file_length) {
+               ACPI_WARNING((AE_INFO,
+                             "File length (0x%X) is not the same as the table length (0x%X)",
+                             file_length, table_length));
+       }
+
+       /* Scan entire table to determine if each LF has been prefixed with a CR */
+
+       for (i = 1; i < file_length; i++) {
+               if (table[i] == 0x0A) {
+                       if (table[i - 1] != 0x0D) {
+
+                               /* The LF does not have a preceding CR, table not corrupted */
+
+                               return (AE_OK);
+                       } else {
+                               /* Found a CR/LF pair */
+
+                               pairs++;
+                       }
+                       i++;
+               }
+       }
+
+       if (!pairs) {
+               return (AE_OK);
+       }
+
+       /*
+        * Entire table scanned, each CR is part of a CR/LF pair --
+        * meaning that the table was treated as a text file somewhere.
+        *
+        * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
+        * original table are left untouched by the text conversion process --
+        * meaning that we cannot simply replace CR/LF pairs with LFs.
+        */
+       acpi_os_printf("Table has been corrupted by text mode conversion\n");
+       acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs);
+       acpi_os_printf("Table cannot be repaired!\n");
+       return (AE_BAD_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_read_table
+ *
+ * PARAMETERS:  fp              - File that contains table
+ *              table           - Return value, buffer with table
+ *              table_length    - Return value, length of table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load the DSDT from the file pointer
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_read_table(FILE * fp,
+                  struct acpi_table_header **table, u32 *table_length)
+{
+       struct acpi_table_header table_header;
+       u32 actual;
+       acpi_status status;
+       u32 file_size;
+       u8 standard_header = TRUE;
+       s32 count;
+
+       /* Get the file size */
+
+       file_size = cm_get_file_size(fp);
+       if (file_size == ACPI_UINT32_MAX) {
+               return (AE_ERROR);
+       }
+
+       if (file_size < 4) {
+               return (AE_BAD_HEADER);
+       }
+
+       /* Read the signature */
+
+       fseek(fp, 0, SEEK_SET);
+
+       count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
+       if (count != sizeof(struct acpi_table_header)) {
+               acpi_os_printf("Could not read the table header\n");
+               return (AE_BAD_HEADER);
+       }
+
+       /* The RSDP table does not have standard ACPI header */
+
+       if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
+               *table_length = file_size;
+               standard_header = FALSE;
+       } else {
+
+#if 0
+               /* Validate the table header/length */
+
+               status = acpi_tb_validate_table_header(&table_header);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Table header is invalid!\n");
+                       return (status);
+               }
+#endif
+
+               /* File size must be at least as long as the Header-specified length */
+
+               if (table_header.length > file_size) {
+                       acpi_os_printf
+                           ("TableHeader length [0x%X] greater than the input file size [0x%X]\n",
+                            table_header.length, file_size);
+
+#ifdef ACPI_ASL_COMPILER
+                       status = fl_check_for_ascii(fp, NULL, FALSE);
+                       if (ACPI_SUCCESS(status)) {
+                               acpi_os_printf
+                                   ("File appears to be ASCII only, must be binary\n",
+                                    table_header.length, file_size);
+                       }
+#endif
+                       return (AE_BAD_HEADER);
+               }
+#ifdef ACPI_OBSOLETE_CODE
+               /* We only support a limited number of table types */
+
+               if (!ACPI_COMPARE_NAME
+                   ((char *)table_header.signature, ACPI_SIG_DSDT)
+                   && !ACPI_COMPARE_NAME((char *)table_header.signature,
+                                         ACPI_SIG_PSDT)
+                   && !ACPI_COMPARE_NAME((char *)table_header.signature,
+                                         ACPI_SIG_SSDT)) {
+                       acpi_os_printf
+                           ("Table signature [%4.4s] is invalid or not supported\n",
+                            (char *)table_header.signature);
+                       ACPI_DUMP_BUFFER(&table_header,
+                                        sizeof(struct acpi_table_header));
+                       return (AE_ERROR);
+               }
+#endif
+
+               *table_length = table_header.length;
+       }
+
+       /* Allocate a buffer for the table */
+
+       *table = acpi_os_allocate((size_t) file_size);
+       if (!*table) {
+               acpi_os_printf
+                   ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
+                    table_header.signature, *table_length);
+               return (AE_NO_MEMORY);
+       }
+
+       /* Get the rest of the table */
+
+       fseek(fp, 0, SEEK_SET);
+       actual = fread(*table, 1, (size_t) file_size, fp);
+       if (actual == file_size) {
+               if (standard_header) {
+
+                       /* Now validate the checksum */
+
+                       status = acpi_tb_verify_checksum((void *)*table,
+                                                        ACPI_CAST_PTR(struct
+                                                                      acpi_table_header,
+                                                                      *table)->
+                                                        length);
+
+                       if (status == AE_BAD_CHECKSUM) {
+                               status =
+                                   acpi_ut_check_text_mode_corruption((u8 *)
+                                                                      *table,
+                                                                      file_size,
+                                                                      (*table)->
+                                                                      length);
+                               return (status);
+                       }
+               }
+               return (AE_OK);
+       }
+
+       if (actual > 0) {
+               acpi_os_printf("Warning - reading table, asked for %X got %X\n",
+                              file_size, actual);
+               return (AE_OK);
+       }
+
+       acpi_os_printf("Error - could not read the table file\n");
+       acpi_os_free(*table);
+       *table = NULL;
+       *table_length = 0;
+       return (AE_ERROR);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_read_table_from_file
+ *
+ * PARAMETERS:  filename         - File where table is located
+ *              table            - Where a pointer to the table is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get an ACPI table from a file
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
+{
+       FILE *file;
+       u32 file_size;
+       u32 table_length;
+       acpi_status status = AE_ERROR;
+
+       /* Open the file, get current size */
+
+       file = fopen(filename, "rb");
+       if (!file) {
+               perror("Could not open input file");
+               return (status);
+       }
+
+       file_size = cm_get_file_size(file);
+       if (file_size == ACPI_UINT32_MAX) {
+               goto exit;
+       }
+
+       /* Get the entire file */
+
+       fprintf(stderr,
+               "Loading Acpi table from file %10s - Length %.8u (%06X)\n",
+               filename, file_size, file_size);
+
+       status = acpi_ut_read_table(file, table, &table_length);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not get table from the file\n");
+       }
+
+exit:
+       fclose(file);
+       return (status);
+}
+
+#endif
index d69be3cb3faebca6e981617b506a4dfdfcd18d7b..77ceac715f28bd40f1f3ad8f4ff8152f53fbf3f0 100644 (file)
@@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
 };
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_init_globals
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
- *              initialization should be initialized here. This allows for
- *              a warm restart.
- *
- ******************************************************************************/
-
-acpi_status acpi_ut_init_globals(void)
-{
-       acpi_status status;
-       u32 i;
-
-       ACPI_FUNCTION_TRACE(ut_init_globals);
-
-       /* Create all memory caches */
-
-       status = acpi_ut_create_caches();
-       if (ACPI_FAILURE(status)) {
-               return_ACPI_STATUS(status);
-       }
-
-       /* Address Range lists */
-
-       for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
-               acpi_gbl_address_range_list[i] = NULL;
-       }
-
-       /* Mutex locked flags */
-
-       for (i = 0; i < ACPI_NUM_MUTEX; i++) {
-               acpi_gbl_mutex_info[i].mutex = NULL;
-               acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
-               acpi_gbl_mutex_info[i].use_count = 0;
-       }
-
-       for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
-               acpi_gbl_owner_id_mask[i] = 0;
-       }
-
-       /* Last owner_ID is never valid */
-
-       acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
-
-       /* Event counters */
-
-       acpi_method_count = 0;
-       acpi_sci_count = 0;
-       acpi_gpe_count = 0;
-
-       for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
-               acpi_fixed_event_count[i] = 0;
-       }
-
-#if (!ACPI_REDUCED_HARDWARE)
-
-       /* GPE/SCI support */
-
-       acpi_gbl_all_gpes_initialized = FALSE;
-       acpi_gbl_gpe_xrupt_list_head = NULL;
-       acpi_gbl_gpe_fadt_blocks[0] = NULL;
-       acpi_gbl_gpe_fadt_blocks[1] = NULL;
-       acpi_current_gpe_count = 0;
-
-       acpi_gbl_global_event_handler = NULL;
-       acpi_gbl_sci_handler_list = NULL;
-
-#endif                         /* !ACPI_REDUCED_HARDWARE */
-
-       /* Global handlers */
-
-       acpi_gbl_global_notify[0].handler = NULL;
-       acpi_gbl_global_notify[1].handler = NULL;
-       acpi_gbl_exception_handler = NULL;
-       acpi_gbl_init_handler = NULL;
-       acpi_gbl_table_handler = NULL;
-       acpi_gbl_interface_handler = NULL;
-
-       /* Global Lock support */
-
-       acpi_gbl_global_lock_semaphore = NULL;
-       acpi_gbl_global_lock_mutex = NULL;
-       acpi_gbl_global_lock_acquired = FALSE;
-       acpi_gbl_global_lock_handle = 0;
-       acpi_gbl_global_lock_present = FALSE;
-
-       /* Miscellaneous variables */
-
-       acpi_gbl_DSDT = NULL;
-       acpi_gbl_cm_single_step = FALSE;
-       acpi_gbl_shutdown = FALSE;
-       acpi_gbl_ns_lookup_count = 0;
-       acpi_gbl_ps_find_count = 0;
-       acpi_gbl_acpi_hardware_present = TRUE;
-       acpi_gbl_last_owner_id_index = 0;
-       acpi_gbl_next_owner_id_offset = 0;
-       acpi_gbl_trace_dbg_level = 0;
-       acpi_gbl_trace_dbg_layer = 0;
-       acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
-       acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
-       acpi_gbl_osi_mutex = NULL;
-       acpi_gbl_reg_methods_executed = FALSE;
-
-       /* Hardware oriented */
-
-       acpi_gbl_events_initialized = FALSE;
-       acpi_gbl_system_awake_and_running = TRUE;
-
-       /* Namespace */
-
-       acpi_gbl_module_code_list = NULL;
-       acpi_gbl_root_node = NULL;
-       acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
-       acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
-       acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
-       acpi_gbl_root_node_struct.parent = NULL;
-       acpi_gbl_root_node_struct.child = NULL;
-       acpi_gbl_root_node_struct.peer = NULL;
-       acpi_gbl_root_node_struct.object = NULL;
-
-#ifdef ACPI_DISASSEMBLER
-       acpi_gbl_external_list = NULL;
-       acpi_gbl_num_external_methods = 0;
-       acpi_gbl_resolved_external_methods = 0;
-#endif
-
-#ifdef ACPI_DEBUG_OUTPUT
-       acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
-#endif
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-       acpi_gbl_display_final_mem_stats = FALSE;
-       acpi_gbl_disable_mem_tracking = FALSE;
-#endif
-
-       ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
-
-       return_ACPI_STATUS(AE_OK);
-}
-
 /* Public globals */
 
 ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
index 5f56fc49021ecf9f198baec7370e940441ecfc06..77120ec9ea860385cf5e3adddd530f83fc790a7f 100644 (file)
@@ -102,6 +102,151 @@ static void acpi_ut_free_gpe_lists(void)
 }
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_init_globals
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
+ *              initialization should be initialized here. This allows for
+ *              a warm restart.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_init_globals(void)
+{
+       acpi_status status;
+       u32 i;
+
+       ACPI_FUNCTION_TRACE(ut_init_globals);
+
+       /* Create all memory caches */
+
+       status = acpi_ut_create_caches();
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Address Range lists */
+
+       for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
+               acpi_gbl_address_range_list[i] = NULL;
+       }
+
+       /* Mutex locked flags */
+
+       for (i = 0; i < ACPI_NUM_MUTEX; i++) {
+               acpi_gbl_mutex_info[i].mutex = NULL;
+               acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+               acpi_gbl_mutex_info[i].use_count = 0;
+       }
+
+       for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
+               acpi_gbl_owner_id_mask[i] = 0;
+       }
+
+       /* Last owner_ID is never valid */
+
+       acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
+
+       /* Event counters */
+
+       acpi_method_count = 0;
+       acpi_sci_count = 0;
+       acpi_gpe_count = 0;
+
+       for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+               acpi_fixed_event_count[i] = 0;
+       }
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+       /* GPE/SCI support */
+
+       acpi_gbl_all_gpes_initialized = FALSE;
+       acpi_gbl_gpe_xrupt_list_head = NULL;
+       acpi_gbl_gpe_fadt_blocks[0] = NULL;
+       acpi_gbl_gpe_fadt_blocks[1] = NULL;
+       acpi_current_gpe_count = 0;
+
+       acpi_gbl_global_event_handler = NULL;
+       acpi_gbl_sci_handler_list = NULL;
+
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+       /* Global handlers */
+
+       acpi_gbl_global_notify[0].handler = NULL;
+       acpi_gbl_global_notify[1].handler = NULL;
+       acpi_gbl_exception_handler = NULL;
+       acpi_gbl_init_handler = NULL;
+       acpi_gbl_table_handler = NULL;
+       acpi_gbl_interface_handler = NULL;
+
+       /* Global Lock support */
+
+       acpi_gbl_global_lock_semaphore = NULL;
+       acpi_gbl_global_lock_mutex = NULL;
+       acpi_gbl_global_lock_acquired = FALSE;
+       acpi_gbl_global_lock_handle = 0;
+       acpi_gbl_global_lock_present = FALSE;
+
+       /* Miscellaneous variables */
+
+       acpi_gbl_DSDT = NULL;
+       acpi_gbl_cm_single_step = FALSE;
+       acpi_gbl_shutdown = FALSE;
+       acpi_gbl_ns_lookup_count = 0;
+       acpi_gbl_ps_find_count = 0;
+       acpi_gbl_acpi_hardware_present = TRUE;
+       acpi_gbl_last_owner_id_index = 0;
+       acpi_gbl_next_owner_id_offset = 0;
+       acpi_gbl_trace_dbg_level = 0;
+       acpi_gbl_trace_dbg_layer = 0;
+       acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
+       acpi_gbl_osi_mutex = NULL;
+       acpi_gbl_reg_methods_executed = FALSE;
+
+       /* Hardware oriented */
+
+       acpi_gbl_events_initialized = FALSE;
+       acpi_gbl_system_awake_and_running = TRUE;
+
+       /* Namespace */
+
+       acpi_gbl_module_code_list = NULL;
+       acpi_gbl_root_node = NULL;
+       acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
+       acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
+       acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
+       acpi_gbl_root_node_struct.parent = NULL;
+       acpi_gbl_root_node_struct.child = NULL;
+       acpi_gbl_root_node_struct.peer = NULL;
+       acpi_gbl_root_node_struct.object = NULL;
+
+#ifdef ACPI_DISASSEMBLER
+       acpi_gbl_external_list = NULL;
+       acpi_gbl_num_external_methods = 0;
+       acpi_gbl_resolved_external_methods = 0;
+#endif
+
+#ifdef ACPI_DEBUG_OUTPUT
+       acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
+#endif
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+       acpi_gbl_display_final_mem_stats = FALSE;
+       acpi_gbl_disable_mem_tracking = FALSE;
+#endif
+
+       ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
+
+       return_ACPI_STATUS(AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_ut_terminate
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c
new file mode 100644 (file)
index 0000000..1031164
--- /dev/null
@@ -0,0 +1,661 @@
+/******************************************************************************
+ *
+ * Module Name: utprint - Formatted printing routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utprint")
+
+#define ACPI_FORMAT_SIGN            0x01
+#define ACPI_FORMAT_SIGN_PLUS       0x02
+#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
+#define ACPI_FORMAT_ZERO            0x08
+#define ACPI_FORMAT_LEFT            0x10
+#define ACPI_FORMAT_UPPER           0x20
+#define ACPI_FORMAT_PREFIX          0x40
+/* Local prototypes */
+static acpi_size
+acpi_ut_bound_string_length(const char *string, acpi_size count);
+
+static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
+
+static char *acpi_ut_format_number(char *string,
+                                  char *end,
+                                  u64 number,
+                                  u8 base, s32 width, s32 precision, u8 type);
+
+static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
+
+/* Module globals */
+
+static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef";
+static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF";
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_bound_string_length
+ *
+ * PARAMETERS:  string              - String with boundary
+ *              count               - Boundary of the string
+ *
+ * RETURN:      Length of the string. Less than or equal to Count.
+ *
+ * DESCRIPTION: Calculate the length of a string with boundary.
+ *
+ ******************************************************************************/
+
+static acpi_size
+acpi_ut_bound_string_length(const char *string, acpi_size count)
+{
+       u32 length = 0;
+
+       while (*string && count) {
+               length++;
+               string++;
+               count--;
+       }
+
+       return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_bound_string_output
+ *
+ * PARAMETERS:  string              - String with boundary
+ *              end                 - Boundary of the string
+ *              c                   - Character to be output to the string
+ *
+ * RETURN:      Updated position for next valid character
+ *
+ * DESCRIPTION: Output a character into a string with boundary check.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
+{
+
+       if (string < end) {
+               *string = c;
+       }
+
+       ++string;
+       return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_put_number
+ *
+ * PARAMETERS:  string              - Buffer to hold reverse-ordered string
+ *              number              - Integer to be converted
+ *              base                - Base of the integer
+ *              upper               - Whether or not using upper cased digits
+ *
+ * RETURN:      Updated position for next valid character
+ *
+ * DESCRIPTION: Convert an integer into a string, note that, the string holds a
+ *              reversed ordered number without the trailing zero.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
+{
+       const char *digits;
+       u64 digit_index;
+       char *pos;
+
+       pos = string;
+       digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
+
+       if (number == 0) {
+               *(pos++) = '0';
+       } else {
+               while (number) {
+                       (void)acpi_ut_divide(number, base, &number,
+                                            &digit_index);
+                       *(pos++) = digits[digit_index];
+               }
+       }
+
+       /* *(Pos++) = '0'; */
+       return (pos);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_scan_number
+ *
+ * PARAMETERS:  string              - String buffer
+ *              number_ptr          - Where the number is returned
+ *
+ * RETURN:      Updated position for next valid character
+ *
+ * DESCRIPTION: Scan a string for a decimal integer.
+ *
+ ******************************************************************************/
+
+const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
+{
+       u64 number = 0;
+
+       while (ACPI_IS_DIGIT(*string)) {
+               number *= 10;
+               number += *(string++) - '0';
+       }
+
+       *number_ptr = number;
+       return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_print_number
+ *
+ * PARAMETERS:  string              - String buffer
+ *              number              - The number to be converted
+ *
+ * RETURN:      Updated position for next valid character
+ *
+ * DESCRIPTION: Print a decimal integer into a string.
+ *
+ ******************************************************************************/
+
+const char *acpi_ut_print_number(char *string, u64 number)
+{
+       char ascii_string[20];
+       const char *pos1;
+       char *pos2;
+
+       pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
+       pos2 = string;
+
+       while (pos1 != ascii_string) {
+               *(pos2++) = *(--pos1);
+       }
+
+       *pos2 = 0;
+       return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_format_number
+ *
+ * PARAMETERS:  string              - String buffer with boundary
+ *              end                 - Boundary of the string
+ *              number              - The number to be converted
+ *              base                - Base of the integer
+ *              width               - Field width
+ *              precision           - Precision of the integer
+ *              type                - Special printing flags
+ *
+ * RETURN:      Updated position for next valid character
+ *
+ * DESCRIPTION: Print an integer into a string with any base and any precision.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_format_number(char *string,
+                                  char *end,
+                                  u64 number,
+                                  u8 base, s32 width, s32 precision, u8 type)
+{
+       char sign;
+       char zero;
+       u8 need_prefix;
+       u8 upper;
+       s32 i;
+       char reversed_string[66];
+
+       /* Parameter validation */
+
+       if (base < 2 || base > 16) {
+               return (NULL);
+       }
+
+       if (type & ACPI_FORMAT_LEFT) {
+               type &= ~ACPI_FORMAT_ZERO;
+       }
+
+       need_prefix = ((type & ACPI_FORMAT_PREFIX)
+                      && base != 10) ? TRUE : FALSE;
+       upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
+       zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
+
+       /* Calculate size according to sign and prefix */
+
+       sign = '\0';
+       if (type & ACPI_FORMAT_SIGN) {
+               if ((s64) number < 0) {
+                       sign = '-';
+                       number = -(s64) number;
+                       width--;
+               } else if (type & ACPI_FORMAT_SIGN_PLUS) {
+                       sign = '+';
+                       width--;
+               } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
+                       sign = ' ';
+                       width--;
+               }
+       }
+       if (need_prefix) {
+               width--;
+               if (base == 16) {
+                       width--;
+               }
+       }
+
+       /* Generate full string in reverse order */
+
+       i = ACPI_PTR_DIFF(acpi_ut_put_number
+                         (reversed_string, number, base, upper),
+                         reversed_string);
+
+       /* Printing 100 using %2d gives "100", not "00" */
+
+       if (i > precision) {
+               precision = i;
+       }
+
+       width -= precision;
+
+       /* Output the string */
+
+       if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
+               while (--width >= 0) {
+                       string = acpi_ut_bound_string_output(string, end, ' ');
+               }
+       }
+       if (sign) {
+               string = acpi_ut_bound_string_output(string, end, sign);
+       }
+       if (need_prefix) {
+               string = acpi_ut_bound_string_output(string, end, '0');
+               if (base == 16) {
+                       string = acpi_ut_bound_string_output(string, end,
+                                                            upper ? 'X' : 'x');
+               }
+       }
+       if (!(type & ACPI_FORMAT_LEFT)) {
+               while (--width >= 0) {
+                       string = acpi_ut_bound_string_output(string, end, zero);
+               }
+       }
+
+       while (i <= --precision) {
+               string = acpi_ut_bound_string_output(string, end, '0');
+       }
+       while (--i >= 0) {
+               string = acpi_ut_bound_string_output(string, end,
+                                                    reversed_string[i]);
+       }
+       while (--width >= 0) {
+               string = acpi_ut_bound_string_output(string, end, ' ');
+       }
+
+       return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_vsnprintf
+ *
+ * PARAMETERS:  string              - String with boundary
+ *              size                - Boundary of the string
+ *              format              - Standard printf format
+ *              args                - Argument list
+ *
+ * RETURN:      Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a string using argument list pointer.
+ *
+ ******************************************************************************/
+
+int
+acpi_ut_vsnprintf(char *string,
+                 acpi_size size, const char *format, va_list args)
+{
+       u8 base = 10;
+       u8 type = 0;
+       s32 width = -1;
+       s32 precision = -1;
+       char qualifier = 0;
+       u64 number;
+       char *pos;
+       char *end;
+       char c;
+       const char *s;
+       const void *p;
+       s32 length;
+       int i;
+
+       pos = string;
+       end = string + size;
+
+       for (; *format; ++format) {
+               if (*format != '%') {
+                       pos = acpi_ut_bound_string_output(pos, end, *format);
+                       continue;
+               }
+
+               /* Process sign */
+
+               do {
+                       ++format;
+                       if (*format == '#') {
+                               type |= ACPI_FORMAT_PREFIX;
+                       } else if (*format == '0') {
+                               type |= ACPI_FORMAT_ZERO;
+                       } else if (*format == '+') {
+                               type |= ACPI_FORMAT_SIGN_PLUS;
+                       } else if (*format == ' ') {
+                               type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
+                       } else if (*format == '-') {
+                               type |= ACPI_FORMAT_LEFT;
+                       } else {
+                               break;
+                       }
+               } while (1);
+
+               /* Process width */
+
+               if (ACPI_IS_DIGIT(*format)) {
+                       format = acpi_ut_scan_number(format, &number);
+                       width = (s32) number;
+               } else if (*format == '*') {
+                       ++format;
+                       width = va_arg(args, int);
+                       if (width < 0) {
+                               width = -width;
+                               type |= ACPI_FORMAT_LEFT;
+                       }
+               }
+
+               /* Process precision */
+
+               if (*format == '.') {
+                       ++format;
+                       if (ACPI_IS_DIGIT(*format)) {
+                               format = acpi_ut_scan_number(format, &number);
+                               precision = (s32) number;
+                       } else if (*format == '*') {
+                               ++format;
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0) {
+                               precision = 0;
+                       }
+               }
+
+               /* Process qualifier */
+
+               if (*format == 'h' || *format == 'l' || *format == 'L') {
+                       qualifier = *format;
+                       ++format;
+
+                       if (qualifier == 'l' && *format == 'l') {
+                               qualifier = 'L';
+                               ++format;
+                       }
+               }
+
+               switch (*format) {
+               case '%':
+
+                       pos = acpi_ut_bound_string_output(pos, end, '%');
+                       continue;
+
+               case 'c':
+
+                       if (!(type & ACPI_FORMAT_LEFT)) {
+                               while (--width > 0) {
+                                       pos =
+                                           acpi_ut_bound_string_output(pos,
+                                                                       end,
+                                                                       ' ');
+                               }
+                       }
+
+                       c = (char)va_arg(args, int);
+                       pos = acpi_ut_bound_string_output(pos, end, c);
+
+                       while (--width > 0) {
+                               pos =
+                                   acpi_ut_bound_string_output(pos, end, ' ');
+                       }
+                       continue;
+
+               case 's':
+
+                       s = va_arg(args, char *);
+                       if (!s) {
+                               s = "<NULL>";
+                       }
+                       length = acpi_ut_bound_string_length(s, precision);
+                       if (!(type & ACPI_FORMAT_LEFT)) {
+                               while (length < width--) {
+                                       pos =
+                                           acpi_ut_bound_string_output(pos,
+                                                                       end,
+                                                                       ' ');
+                               }
+                       }
+                       for (i = 0; i < length; ++i) {
+                               pos = acpi_ut_bound_string_output(pos, end, *s);
+                               ++s;
+                       }
+                       while (length < width--) {
+                               pos =
+                                   acpi_ut_bound_string_output(pos, end, ' ');
+                       }
+                       continue;
+
+               case 'o':
+
+                       base = 8;
+                       break;
+
+               case 'X':
+
+                       type |= ACPI_FORMAT_UPPER;
+
+               case 'x':
+
+                       base = 16;
+                       break;
+
+               case 'd':
+               case 'i':
+
+                       type |= ACPI_FORMAT_SIGN;
+
+               case 'u':
+
+                       break;
+
+               case 'p':
+
+                       if (width == -1) {
+                               width = 2 * sizeof(void *);
+                               type |= ACPI_FORMAT_ZERO;
+                       }
+
+                       p = va_arg(args, void *);
+                       pos = acpi_ut_format_number(pos, end,
+                                                   ACPI_TO_INTEGER(p), 16,
+                                                   width, precision, type);
+                       continue;
+
+               default:
+
+                       pos = acpi_ut_bound_string_output(pos, end, '%');
+                       if (*format) {
+                               pos =
+                                   acpi_ut_bound_string_output(pos, end,
+                                                               *format);
+                       } else {
+                               --format;
+                       }
+                       continue;
+               }
+
+               if (qualifier == 'L') {
+                       number = va_arg(args, u64);
+                       if (type & ACPI_FORMAT_SIGN) {
+                               number = (s64) number;
+                       }
+               } else if (qualifier == 'l') {
+                       number = va_arg(args, unsigned long);
+                       if (type & ACPI_FORMAT_SIGN) {
+                               number = (s32) number;
+                       }
+               } else if (qualifier == 'h') {
+                       number = (u16)va_arg(args, int);
+                       if (type & ACPI_FORMAT_SIGN) {
+                               number = (s16) number;
+                       }
+               } else {
+                       number = va_arg(args, unsigned int);
+                       if (type & ACPI_FORMAT_SIGN) {
+                               number = (signed int)number;
+                       }
+               }
+
+               pos = acpi_ut_format_number(pos, end, number, base,
+                                           width, precision, type);
+       }
+
+       if (size > 0) {
+               if (pos < end) {
+                       *pos = '\0';
+               } else {
+                       end[-1] = '\0';
+               }
+       }
+
+       return (ACPI_PTR_DIFF(pos, string));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_snprintf
+ *
+ * PARAMETERS:  string              - String with boundary
+ *              size                - Boundary of the string
+ *              Format, ...         - Standard printf format
+ *
+ * RETURN:      Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a string.
+ *
+ ******************************************************************************/
+
+int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
+{
+       va_list args;
+       int length;
+
+       va_start(args, format);
+       length = acpi_ut_vsnprintf(string, size, format, args);
+       va_end(args);
+
+       return (length);
+}
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_file_vprintf
+ *
+ * PARAMETERS:  file                - File descriptor
+ *              format              - Standard printf format
+ *              args                - Argument list
+ *
+ * RETURN:      Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a file using argument list pointer.
+ *
+ ******************************************************************************/
+
+int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
+{
+       acpi_cpu_flags flags;
+       int length;
+
+       flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
+       length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
+                                  sizeof(acpi_gbl_print_buffer), format, args);
+
+       (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
+       acpi_os_release_lock(acpi_gbl_print_lock, flags);
+
+       return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_file_printf
+ *
+ * PARAMETERS:  file                - File descriptor
+ *              Format, ...         - Standard printf format
+ *
+ * RETURN:      Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a file.
+ *
+ ******************************************************************************/
+
+int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
+{
+       va_list args;
+       int length;
+
+       va_start(args, format);
+       length = acpi_ut_file_vprintf(file, format, args);
+       va_end(args);
+
+       return (length);
+}
+#endif
index e5bcd919d4e6922d9fc7b87d42d949adb07826cf..16129c78b4891f0d9d9e2b9035748ad643cabb6a 100644 (file)
@@ -121,11 +121,11 @@ struct dentry;
 struct dentry *apei_get_debugfs_dir(void);
 
 #define apei_estatus_for_each_section(estatus, section)                        \
-       for (section = (struct acpi_generic_data *)(estatus + 1);       \
+       for (section = (struct acpi_hest_generic_data *)(estatus + 1);  \
             (void *)section - (void *)estatus < estatus->data_length;  \
             section = (void *)(section+1) + section->error_data_length)
 
-static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)
 {
        if (estatus->raw_data_length)
                return estatus->raw_data_offset + \
@@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
 }
 
 void cper_estatus_print(const char *pfx,
-                       const struct acpi_generic_status *estatus);
-int cper_estatus_check_header(const struct acpi_generic_status *estatus);
-int cper_estatus_check(const struct acpi_generic_status *estatus);
+                       const struct acpi_hest_generic_status *estatus);
+int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus);
+int cper_estatus_check(const struct acpi_hest_generic_status *estatus);
 
 int apei_osc_setup(void);
 #endif
index dab7cb7349df7e62ee24f32493d8d5a8065ad3d9..7a38d1465b618e99a1bd9d20f2cbd7e0a0080f7f 100644 (file)
 #define GHES_ESTATUS_CACHE_LEN(estatus_len)                    \
        (sizeof(struct ghes_estatus_cache) + (estatus_len))
 #define GHES_ESTATUS_FROM_CACHE(estatus_cache)                 \
-       ((struct acpi_generic_status *)                         \
+       ((struct acpi_hest_generic_status *)                            \
         ((struct ghes_estatus_cache *)(estatus_cache) + 1))
 
 #define GHES_ESTATUS_NODE_LEN(estatus_len)                     \
        (sizeof(struct ghes_estatus_node) + (estatus_len))
 #define GHES_ESTATUS_FROM_NODE(estatus_node)                   \
-       ((struct acpi_generic_status *)                         \
+       ((struct acpi_hest_generic_status *)                            \
         ((struct ghes_estatus_node *)(estatus_node) + 1))
 
 bool ghes_disable;
@@ -408,7 +408,7 @@ static void ghes_clear_estatus(struct ghes *ghes)
        ghes->flags &= ~GHES_TO_CLEAR;
 }
 
-static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
+static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
 {
 #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
        unsigned long pfn;
@@ -441,10 +441,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
 }
 
 static void ghes_do_proc(struct ghes *ghes,
-                        const struct acpi_generic_status *estatus)
+                        const struct acpi_hest_generic_status *estatus)
 {
        int sev, sec_sev;
-       struct acpi_generic_data *gdata;
+       struct acpi_hest_generic_data *gdata;
 
        sev = ghes_severity(estatus->error_severity);
        apei_estatus_for_each_section(estatus, gdata) {
@@ -498,7 +498,7 @@ static void ghes_do_proc(struct ghes *ghes,
 
 static void __ghes_print_estatus(const char *pfx,
                                 const struct acpi_hest_generic *generic,
-                                const struct acpi_generic_status *estatus)
+                                const struct acpi_hest_generic_status *estatus)
 {
        static atomic_t seqno;
        unsigned int curr_seqno;
@@ -520,7 +520,7 @@ static void __ghes_print_estatus(const char *pfx,
 
 static int ghes_print_estatus(const char *pfx,
                              const struct acpi_hest_generic *generic,
-                             const struct acpi_generic_status *estatus)
+                             const struct acpi_hest_generic_status *estatus)
 {
        /* Not more than 2 messages every 5 seconds */
        static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
@@ -542,13 +542,13 @@ static int ghes_print_estatus(const char *pfx,
  * GHES error status reporting throttle, to report more kinds of
  * errors, instead of just most frequently occurred errors.
  */
-static int ghes_estatus_cached(struct acpi_generic_status *estatus)
+static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
 {
        u32 len;
        int i, cached = 0;
        unsigned long long now;
        struct ghes_estatus_cache *cache;
-       struct acpi_generic_status *cache_estatus;
+       struct acpi_hest_generic_status *cache_estatus;
 
        len = cper_estatus_len(estatus);
        rcu_read_lock();
@@ -573,12 +573,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus)
 
 static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
        struct acpi_hest_generic *generic,
-       struct acpi_generic_status *estatus)
+       struct acpi_hest_generic_status *estatus)
 {
        int alloced;
        u32 len, cache_len;
        struct ghes_estatus_cache *cache;
-       struct acpi_generic_status *cache_estatus;
+       struct acpi_hest_generic_status *cache_estatus;
 
        alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
        if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
@@ -621,7 +621,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
 
 static void ghes_estatus_cache_add(
        struct acpi_hest_generic *generic,
-       struct acpi_generic_status *estatus)
+       struct acpi_hest_generic_status *estatus)
 {
        int i, slot = -1, count;
        unsigned long long now, duration, period, max_period = 0;
@@ -753,7 +753,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
        struct llist_node *llnode, *next;
        struct ghes_estatus_node *estatus_node;
        struct acpi_hest_generic *generic;
-       struct acpi_generic_status *estatus;
+       struct acpi_hest_generic_status *estatus;
        u32 len, node_len;
 
        llnode = llist_del_all(&ghes_estatus_llist);
@@ -786,7 +786,7 @@ static void ghes_print_queued_estatus(void)
        struct llist_node *llnode;
        struct ghes_estatus_node *estatus_node;
        struct acpi_hest_generic *generic;
-       struct acpi_generic_status *estatus;
+       struct acpi_hest_generic_status *estatus;
        u32 len, node_len;
 
        llnode = llist_del_all(&ghes_estatus_llist);
@@ -845,7 +845,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
 #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
                u32 len, node_len;
                struct ghes_estatus_node *estatus_node;
-               struct acpi_generic_status *estatus;
+               struct acpi_hest_generic_status *estatus;
 #endif
                if (!(ghes->flags & GHES_TO_CLEAR))
                        continue;
@@ -925,7 +925,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
 
        rc = -EIO;
        if (generic->error_block_length <
-           sizeof(struct acpi_generic_status)) {
+           sizeof(struct acpi_hest_generic_status)) {
                pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
                           generic->error_block_length,
                           generic->header.source_id);
index 3d8413d02a975f0643275a247524a0c9d7569341..36eb42e3b0bb80688a52d4748d19d762d777aec9 100644 (file)
@@ -247,75 +247,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
        },
 
        /*
-        * The following machines have broken backlight support when reporting
-        * the Windows 2012 OSI, so disable it until their support is fixed.
+        * These machines will power on immediately after shutdown when
+        * reporting the Windows 2012 OSI.
         */
        {
        .callback = dmi_disable_osi_win8,
-       .ident = "ASUS Zenbook Prime UX31A",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "ThinkPad Edge E530",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "ThinkPad Edge E530",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "ThinkPad Edge E530",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "Acer Aspire V5-573G",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "Acer Aspire V5-572G",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "ThinkPad T431s",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
-       .ident = "ThinkPad T430",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_win8,
        .ident = "Dell Inspiron 7737",
        .matches = {
                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
index c5bc8cfe09fa6d2beba1c4ac9ea490314f3e08f7..8581f5b84f48b6d2b66fa4b1f7c120f6b0928bf6 100644 (file)
@@ -477,9 +477,6 @@ static int __init acpi_bus_init_irq(void)
        return 0;
 }
 
-u8 acpi_gbl_permanent_mmap;
-
-
 void __init acpi_early_init(void)
 {
        acpi_status status;
index db35594d4df7a072a76e0c2fb879c324efdcedb8..6d5d1832a5880e0badf4220d7fb7e89008d5f4cb 100644 (file)
@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
 static void acpi_button_notify(struct acpi_device *device, u32 event);
 
 #ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev);
 static int acpi_button_resume(struct device *dev);
 #else
+#define acpi_button_suspend NULL
 #define acpi_button_resume NULL
 #endif
-static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);
+static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
 
 static struct acpi_driver acpi_button_driver = {
        .name = "button",
@@ -102,6 +104,7 @@ struct acpi_button {
        struct input_dev *input;
        char phys[32];                  /* for input device */
        unsigned long pushed;
+       bool suspended;
 };
 
 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
                if (button->type == ACPI_BUTTON_TYPE_LID) {
                        acpi_lid_send_state(device);
                } else {
-                       int keycode = test_bit(KEY_SLEEP, input->keybit) ?
-                                               KEY_SLEEP : KEY_POWER;
+                       int keycode;
+
+                       pm_wakeup_event(&device->dev, 0);
+                       if (button->suspended)
+                               break;
 
+                       keycode = test_bit(KEY_SLEEP, input->keybit) ?
+                                               KEY_SLEEP : KEY_POWER;
                        input_report_key(input, keycode, 1);
                        input_sync(input);
                        input_report_key(input, keycode, 0);
                        input_sync(input);
 
-                       pm_wakeup_event(&device->dev, 0);
                        acpi_bus_generate_netlink_event(
                                        device->pnp.device_class,
                                        dev_name(&device->dev),
@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
 }
 
 #ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev)
+{
+       struct acpi_device *device = to_acpi_device(dev);
+       struct acpi_button *button = acpi_driver_data(device);
+
+       button->suspended = true;
+       return 0;
+}
+
 static int acpi_button_resume(struct device *dev)
 {
        struct acpi_device *device = to_acpi_device(dev);
        struct acpi_button *button = acpi_driver_data(device);
 
+       button->suspended = false;
        if (button->type == ACPI_BUTTON_TYPE_LID)
                return acpi_lid_send_state(device);
        return 0;
index 49a51277f81d17dad2d612cba4d3efe3f7b18bf2..67075f800e34cb69b3a28d852b9bc15b00ffa702 100644 (file)
@@ -367,29 +367,61 @@ EXPORT_SYMBOL(acpi_bus_power_manageable);
 #ifdef CONFIG_PM
 static DEFINE_MUTEX(acpi_pm_notifier_lock);
 
+static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
+{
+       struct acpi_device *adev;
+
+       if (val != ACPI_NOTIFY_DEVICE_WAKE)
+               return;
+
+       adev = acpi_bus_get_acpi_device(handle);
+       if (!adev)
+               return;
+
+       mutex_lock(&acpi_pm_notifier_lock);
+
+       if (adev->wakeup.flags.notifier_present) {
+               __pm_wakeup_event(adev->wakeup.ws, 0);
+               if (adev->wakeup.context.work.func)
+                       queue_pm_work(&adev->wakeup.context.work);
+       }
+
+       mutex_unlock(&acpi_pm_notifier_lock);
+
+       acpi_bus_put_acpi_device(adev);
+}
+
 /**
- * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
- * @adev: ACPI device to add the notifier for.
- * @context: Context information to pass to the notifier routine.
+ * acpi_add_pm_notifier - Register PM notify handler for given ACPI device.
+ * @adev: ACPI device to add the notify handler for.
+ * @dev: Device to generate a wakeup event for while handling the notification.
+ * @work_func: Work function to execute when handling the notification.
  *
  * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
  * PM wakeup events.  For example, wakeup events may be generated for bridges
  * if one of the devices below the bridge is signaling wakeup, even if the
  * bridge itself doesn't have a wakeup GPE associated with it.
  */
-acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
-                                acpi_notify_handler handler, void *context)
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
+                                void (*work_func)(struct work_struct *work))
 {
        acpi_status status = AE_ALREADY_EXISTS;
 
+       if (!dev && !work_func)
+               return AE_BAD_PARAMETER;
+
        mutex_lock(&acpi_pm_notifier_lock);
 
        if (adev->wakeup.flags.notifier_present)
                goto out;
 
-       status = acpi_install_notify_handler(adev->handle,
-                                            ACPI_SYSTEM_NOTIFY,
-                                            handler, context);
+       adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev));
+       adev->wakeup.context.dev = dev;
+       if (work_func)
+               INIT_WORK(&adev->wakeup.context.work, work_func);
+
+       status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY,
+                                            acpi_pm_notify_handler, NULL);
        if (ACPI_FAILURE(status))
                goto out;
 
@@ -404,8 +436,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
  * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
  * @adev: ACPI device to remove the notifier from.
  */
-acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
-                                   acpi_notify_handler handler)
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
 {
        acpi_status status = AE_BAD_PARAMETER;
 
@@ -416,10 +447,17 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 
        status = acpi_remove_notify_handler(adev->handle,
                                            ACPI_SYSTEM_NOTIFY,
-                                           handler);
+                                           acpi_pm_notify_handler);
        if (ACPI_FAILURE(status))
                goto out;
 
+       if (adev->wakeup.context.work.func) {
+               cancel_work_sync(&adev->wakeup.context.work);
+               adev->wakeup.context.work.func = NULL;
+       }
+       adev->wakeup.context.dev = NULL;
+       wakeup_source_unregister(adev->wakeup.ws);
+
        adev->wakeup.flags.notifier_present = false;
 
  out:
@@ -558,7 +596,6 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
  */
 int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
 {
-       acpi_handle handle = ACPI_HANDLE(dev);
        struct acpi_device *adev;
        int ret, d_min, d_max;
 
@@ -573,8 +610,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
                        d_max_in = ACPI_STATE_D3_HOT;
        }
 
-       if (!handle || acpi_bus_get_device(handle, &adev)) {
-               dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+       adev = ACPI_COMPANION(dev);
+       if (!adev) {
+               dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
                return -ENODEV;
        }
 
@@ -600,26 +638,25 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
 }
 EXPORT_SYMBOL(acpi_pm_device_sleep_state);
 
-#ifdef CONFIG_PM_RUNTIME
 /**
- * acpi_wakeup_device - Wakeup notification handler for ACPI devices.
- * @handle: ACPI handle of the device the notification is for.
- * @event: Type of the signaled event.
- * @context: Device corresponding to @handle.
+ * acpi_pm_notify_work_func - ACPI devices wakeup notification work function.
+ * @work: Work item to handle.
  */
-static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
+static void acpi_pm_notify_work_func(struct work_struct *work)
 {
-       struct device *dev = context;
+       struct device *dev;
 
-       if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) {
+       dev = container_of(work, struct acpi_device_wakeup_context, work)->dev;
+       if (dev) {
                pm_wakeup_event(dev, 0);
                pm_runtime_resume(dev);
        }
 }
 
 /**
- * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device.
- * @adev: ACPI device to enable/disable the remote wakeup for.
+ * acpi_device_wakeup - Enable/disable wakeup functionality for device.
+ * @adev: ACPI device to enable/disable wakeup functionality for.
+ * @target_state: State the system is transitioning into.
  * @enable: Whether to enable or disable the wakeup functionality.
  *
  * Enable/disable the GPE associated with @adev so that it can generate
@@ -629,7 +666,8 @@ static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
  * Callers must ensure that @adev is a valid ACPI device node before executing
  * this function.
  */
-int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
+static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state,
+                             bool enable)
 {
        struct acpi_device_wakeup *wakeup = &adev->wakeup;
 
@@ -637,7 +675,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
                acpi_status res;
                int error;
 
-               error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0);
+               error = acpi_enable_wakeup_device_power(adev, target_state);
                if (error)
                        return error;
 
@@ -653,6 +691,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
        return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
 /**
  * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
  * @dev: Device to enable/disable the platform to wake up.
@@ -661,41 +700,22 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
 int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
 {
        struct acpi_device *adev;
-       acpi_handle handle;
 
        if (!device_run_wake(phys_dev))
                return -EINVAL;
 
-       handle = ACPI_HANDLE(phys_dev);
-       if (!handle || acpi_bus_get_device(handle, &adev)) {
-               dev_dbg(phys_dev, "ACPI handle without context in %s!\n",
-                       __func__);
+       adev = ACPI_COMPANION(phys_dev);
+       if (!adev) {
+               dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
                return -ENODEV;
        }
 
-       return __acpi_device_run_wake(adev, enable);
+       return acpi_device_wakeup(adev, enable, ACPI_STATE_S0);
 }
 EXPORT_SYMBOL(acpi_pm_device_run_wake);
-#else
-static inline void acpi_wakeup_device(acpi_handle handle, u32 event,
-                                     void *context) {}
 #endif /* CONFIG_PM_RUNTIME */
 
 #ifdef CONFIG_PM_SLEEP
-/**
- * __acpi_device_sleep_wake - Enable or disable device to wake up the system.
- * @dev: Device to enable/desible to wake up the system.
- * @target_state: System state the device is supposed to wake up from.
- * @enable: Whether to enable or disable @dev to wake up the system.
- */
-int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state,
-                            bool enable)
-{
-       return enable ?
-               acpi_enable_wakeup_device_power(adev, target_state) :
-               acpi_disable_wakeup_device_power(adev);
-}
-
 /**
  * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
  * @dev: Device to enable/desible to wake up the system from sleep states.
@@ -703,21 +723,19 @@ int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state,
  */
 int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 {
-       acpi_handle handle;
        struct acpi_device *adev;
        int error;
 
        if (!device_can_wakeup(dev))
                return -EINVAL;
 
-       handle = ACPI_HANDLE(dev);
-       if (!handle || acpi_bus_get_device(handle, &adev)) {
-               dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+       adev = ACPI_COMPANION(dev);
+       if (!adev) {
+               dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
                return -ENODEV;
        }
 
-       error = __acpi_device_sleep_wake(adev, acpi_target_system_state(),
-                                        enable);
+       error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
        if (!error)
                dev_info(dev, "System wakeup %s by ACPI\n",
                                enable ? "enabled" : "disabled");
@@ -775,13 +793,13 @@ int acpi_dev_runtime_suspend(struct device *dev)
 
        remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) >
                                PM_QOS_FLAGS_NONE;
-       error = __acpi_device_run_wake(adev, remote_wakeup);
+       error = acpi_device_wakeup(adev, ACPI_STATE_S0, remote_wakeup);
        if (remote_wakeup && error)
                return -EAGAIN;
 
        error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
        if (error)
-               __acpi_device_run_wake(adev, false);
+               acpi_device_wakeup(adev, ACPI_STATE_S0, false);
 
        return error;
 }
@@ -804,7 +822,7 @@ int acpi_dev_runtime_resume(struct device *dev)
                return 0;
 
        error = acpi_dev_pm_full_power(adev);
-       __acpi_device_run_wake(adev, false);
+       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
        return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -860,13 +878,13 @@ int acpi_dev_suspend_late(struct device *dev)
 
        target_state = acpi_target_system_state();
        wakeup = device_may_wakeup(dev);
-       error = __acpi_device_sleep_wake(adev, target_state, wakeup);
+       error = acpi_device_wakeup(adev, target_state, wakeup);
        if (wakeup && error)
                return error;
 
        error = acpi_dev_pm_low_power(dev, adev, target_state);
        if (error)
-               __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+               acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false);
 
        return error;
 }
@@ -889,7 +907,7 @@ int acpi_dev_resume_early(struct device *dev)
                return 0;
 
        error = acpi_dev_pm_full_power(adev);
-       __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+       acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false);
        return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
@@ -1048,11 +1066,11 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
        if (dev->pm_domain)
                return -EEXIST;
 
-       acpi_add_pm_notifier(adev, acpi_wakeup_device, dev);
+       acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func);
        dev->pm_domain = &acpi_general_pm_domain;
        if (power_on) {
                acpi_dev_pm_full_power(adev);
-               __acpi_device_run_wake(adev, false);
+               acpi_device_wakeup(adev, ACPI_STATE_S0, false);
        }
        return 0;
 }
@@ -1076,7 +1094,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
 
        if (adev && dev->pm_domain == &acpi_general_pm_domain) {
                dev->pm_domain = NULL;
-               acpi_remove_pm_notifier(adev, acpi_wakeup_device);
+               acpi_remove_pm_notifier(adev);
                if (power_off) {
                        /*
                         * If the device's PM QoS resume latency limit or flags
@@ -1086,7 +1104,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
                         */
                        dev_pm_qos_hide_latency_limit(dev);
                        dev_pm_qos_hide_flags(dev);
-                       __acpi_device_run_wake(adev, false);
+                       acpi_device_wakeup(adev, ACPI_STATE_S0, false);
                        acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
                }
        }
index 7de5b603f272b204305899e0147fce9b7c4042a9..4c5cf77e7576ea10b9e11a07b7fc5a9adbb60214 100644 (file)
@@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
                             int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
-int acpi_bind_one(struct device *dev, struct acpi_device *adev);
-int acpi_unbind_one(struct device *dev);
 bool acpi_device_is_present(struct acpi_device *adev);
 bool acpi_device_is_battery(struct acpi_device *adev);
 
@@ -108,7 +106,12 @@ int acpi_power_transition(struct acpi_device *device, int state);
 int acpi_device_update_power(struct acpi_device *device, int *state_p);
 
 int acpi_wakeup_device_init(void);
+
+#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
 void acpi_early_processor_set_pdc(void);
+#else
+static inline void acpi_early_processor_set_pdc(void) {}
+#endif
 
 /* --------------------------------------------------------------------------
                                   Embedded Controller
index bad25b070fe0bfe8b0204cce2ddd5ce30f07ec91..3abe9b223ba717a644ecfd0a4edf401004f24807 100644 (file)
@@ -259,12 +259,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
                               "System description tables not found\n");
                        return 0;
                }
-       } else {
+       } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
                acpi_physical_address pa = 0;
 
                acpi_find_root_pointer(&pa);
                return pa;
        }
+
+       return 0;
 }
 
 /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
index d388f13d48b43634acaaddaf526f037051db78c0..e6ae603ed1a18594b2d4766371d748d5a0cfedc3 100644 (file)
@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
        if (no_aspm)
                pcie_no_aspm();
 
-       pci_acpi_add_bus_pm_notifier(device, root->bus);
+       pci_acpi_add_bus_pm_notifier(device);
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
 
index 71e2065639a6bcc74134a4447c803cbfac1c7841..00f48d13a51630df09afced52ac4c77abdec5240 100644 (file)
@@ -4,17 +4,11 @@
  *
  *     Alex Chiang <achiang@hp.com>
  *     - Unified x86/ia64 implementations
- *     Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- *     - Added _PDC for platforms with Intel CPUs
  */
 #include <linux/export.h>
-#include <linux/dmi.h>
-#include <linux/slab.h>
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
-#include "internal.h"
-
 #define _COMPONENT             ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_core");
 
@@ -208,195 +202,3 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
        return acpi_map_cpuid(apic_id, acpi_id);
 }
 EXPORT_SYMBOL_GPL(acpi_get_cpuid);
-
-static bool __init processor_physically_present(acpi_handle handle)
-{
-       int cpuid, type;
-       u32 acpi_id;
-       acpi_status status;
-       acpi_object_type acpi_type;
-       unsigned long long tmp;
-       union acpi_object object = { 0 };
-       struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
-
-       status = acpi_get_type(handle, &acpi_type);
-       if (ACPI_FAILURE(status))
-               return false;
-
-       switch (acpi_type) {
-       case ACPI_TYPE_PROCESSOR:
-               status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
-               if (ACPI_FAILURE(status))
-                       return false;
-               acpi_id = object.processor.proc_id;
-               break;
-       case ACPI_TYPE_DEVICE:
-               status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
-               if (ACPI_FAILURE(status))
-                       return false;
-               acpi_id = tmp;
-               break;
-       default:
-               return false;
-       }
-
-       type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
-       cpuid = acpi_get_cpuid(handle, type, acpi_id);
-
-       if (cpuid == -1)
-               return false;
-
-       return true;
-}
-
-static void acpi_set_pdc_bits(u32 *buf)
-{
-       buf[0] = ACPI_PDC_REVISION_ID;
-       buf[1] = 1;
-
-       /* Enable coordination with firmware's _TSD info */
-       buf[2] = ACPI_PDC_SMP_T_SWCOORD;
-
-       /* Twiddle arch-specific bits needed for _PDC */
-       arch_acpi_set_pdc_bits(buf);
-}
-
-static struct acpi_object_list *acpi_processor_alloc_pdc(void)
-{
-       struct acpi_object_list *obj_list;
-       union acpi_object *obj;
-       u32 *buf;
-
-       /* allocate and initialize pdc. It will be used later. */
-       obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
-       if (!obj_list) {
-               printk(KERN_ERR "Memory allocation error\n");
-               return NULL;
-       }
-
-       obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-       if (!obj) {
-               printk(KERN_ERR "Memory allocation error\n");
-               kfree(obj_list);
-               return NULL;
-       }
-
-       buf = kmalloc(12, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "Memory allocation error\n");
-               kfree(obj);
-               kfree(obj_list);
-               return NULL;
-       }
-
-       acpi_set_pdc_bits(buf);
-
-       obj->type = ACPI_TYPE_BUFFER;
-       obj->buffer.length = 12;
-       obj->buffer.pointer = (u8 *) buf;
-       obj_list->count = 1;
-       obj_list->pointer = obj;
-
-       return obj_list;
-}
-
-/*
- * _PDC is required for a BIOS-OS handshake for most of the newer
- * ACPI processor features.
- */
-static acpi_status
-acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
-{
-       acpi_status status = AE_OK;
-
-       if (boot_option_idle_override == IDLE_NOMWAIT) {
-               /*
-                * If mwait is disabled for CPU C-states, the C2C3_FFH access
-                * mode will be disabled in the parameter of _PDC object.
-                * Of course C1_FFH access mode will also be disabled.
-                */
-               union acpi_object *obj;
-               u32 *buffer = NULL;
-
-               obj = pdc_in->pointer;
-               buffer = (u32 *)(obj->buffer.pointer);
-               buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
-
-       }
-       status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
-
-       if (ACPI_FAILURE(status))
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                   "Could not evaluate _PDC, using legacy perf. control.\n"));
-
-       return status;
-}
-
-void acpi_processor_set_pdc(acpi_handle handle)
-{
-       struct acpi_object_list *obj_list;
-
-       if (arch_has_acpi_pdc() == false)
-               return;
-
-       obj_list = acpi_processor_alloc_pdc();
-       if (!obj_list)
-               return;
-
-       acpi_processor_eval_pdc(handle, obj_list);
-
-       kfree(obj_list->pointer->buffer.pointer);
-       kfree(obj_list->pointer);
-       kfree(obj_list);
-}
-
-static acpi_status __init
-early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       if (processor_physically_present(handle) == false)
-               return AE_OK;
-
-       acpi_processor_set_pdc(handle);
-       return AE_OK;
-}
-
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
-static int __init set_no_mwait(const struct dmi_system_id *id)
-{
-       pr_notice(PREFIX "%s detected - disabling mwait for CPU C-states\n",
-                 id->ident);
-       boot_option_idle_override = IDLE_NOMWAIT;
-       return 0;
-}
-
-static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
-       {
-       set_no_mwait, "Extensa 5220", {
-       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
-       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-       DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
-       DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
-       {},
-};
-
-static void __init processor_dmi_check(void)
-{
-       /*
-        * Check whether the system is DMI table. If yes, OSPM
-        * should not use mwait for CPU-states.
-        */
-       dmi_check_system(processor_idle_dmi_table);
-}
-#else
-static inline void processor_dmi_check(void) {}
-#endif
-
-void __init acpi_early_processor_set_pdc(void)
-{
-       processor_dmi_check();
-
-       acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           early_init_pdc, NULL, NULL, NULL);
-       acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
-}
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
new file mode 100644 (file)
index 0000000..e5dd808
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2005 Intel Corporation
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ *      Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *      - Added _PDC for platforms with Intel CPUs
+ */
+
+#define pr_fmt(fmt) "ACPI: " fmt
+
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#include "internal.h"
+
+#define _COMPONENT              ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME("processor_pdc");
+
+static bool __init processor_physically_present(acpi_handle handle)
+{
+       int cpuid, type;
+       u32 acpi_id;
+       acpi_status status;
+       acpi_object_type acpi_type;
+       unsigned long long tmp;
+       union acpi_object object = { 0 };
+       struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+
+       status = acpi_get_type(handle, &acpi_type);
+       if (ACPI_FAILURE(status))
+               return false;
+
+       switch (acpi_type) {
+       case ACPI_TYPE_PROCESSOR:
+               status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
+               if (ACPI_FAILURE(status))
+                       return false;
+               acpi_id = object.processor.proc_id;
+               break;
+       case ACPI_TYPE_DEVICE:
+               status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
+               if (ACPI_FAILURE(status))
+                       return false;
+               acpi_id = tmp;
+               break;
+       default:
+               return false;
+       }
+
+       type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+       cpuid = acpi_get_cpuid(handle, type, acpi_id);
+
+       if (cpuid == -1)
+               return false;
+
+       return true;
+}
+
+static void acpi_set_pdc_bits(u32 *buf)
+{
+       buf[0] = ACPI_PDC_REVISION_ID;
+       buf[1] = 1;
+
+       /* Enable coordination with firmware's _TSD info */
+       buf[2] = ACPI_PDC_SMP_T_SWCOORD;
+
+       /* Twiddle arch-specific bits needed for _PDC */
+       arch_acpi_set_pdc_bits(buf);
+}
+
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
+{
+       struct acpi_object_list *obj_list;
+       union acpi_object *obj;
+       u32 *buf;
+
+       /* allocate and initialize pdc. It will be used later. */
+       obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+       if (!obj_list)
+               goto out;
+
+       obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+       if (!obj) {
+               kfree(obj_list);
+               goto out;
+       }
+
+       buf = kmalloc(12, GFP_KERNEL);
+       if (!buf) {
+               kfree(obj);
+               kfree(obj_list);
+               goto out;
+       }
+
+       acpi_set_pdc_bits(buf);
+
+       obj->type = ACPI_TYPE_BUFFER;
+       obj->buffer.length = 12;
+       obj->buffer.pointer = (u8 *) buf;
+       obj_list->count = 1;
+       obj_list->pointer = obj;
+
+       return obj_list;
+out:
+       pr_err("Memory allocation error\n");
+       return NULL;
+}
+
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+static acpi_status
+acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
+{
+       acpi_status status = AE_OK;
+
+       if (boot_option_idle_override == IDLE_NOMWAIT) {
+               /*
+                * If mwait is disabled for CPU C-states, the C2C3_FFH access
+                * mode will be disabled in the parameter of _PDC object.
+                * Of course C1_FFH access mode will also be disabled.
+                */
+               union acpi_object *obj;
+               u32 *buffer = NULL;
+
+               obj = pdc_in->pointer;
+               buffer = (u32 *)(obj->buffer.pointer);
+               buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
+
+       }
+       status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
+
+       if (ACPI_FAILURE(status))
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                   "Could not evaluate _PDC, using legacy perf. control.\n"));
+
+       return status;
+}
+
+void acpi_processor_set_pdc(acpi_handle handle)
+{
+       struct acpi_object_list *obj_list;
+
+       if (arch_has_acpi_pdc() == false)
+               return;
+
+       obj_list = acpi_processor_alloc_pdc();
+       if (!obj_list)
+               return;
+
+       acpi_processor_eval_pdc(handle, obj_list);
+
+       kfree(obj_list->pointer->buffer.pointer);
+       kfree(obj_list->pointer);
+       kfree(obj_list);
+}
+
+static acpi_status __init
+early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       if (processor_physically_present(handle) == false)
+               return AE_OK;
+
+       acpi_processor_set_pdc(handle);
+       return AE_OK;
+}
+
+static int __init set_no_mwait(const struct dmi_system_id *id)
+{
+       pr_notice("%s detected - disabling mwait for CPU C-states\n",
+                 id->ident);
+       boot_option_idle_override = IDLE_NOMWAIT;
+       return 0;
+}
+
+static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
+       {
+       set_no_mwait, "Extensa 5220", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+       DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+       DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
+       {},
+};
+
+static void __init processor_dmi_check(void)
+{
+       /*
+        * Check whether the system is DMI table. If yes, OSPM
+        * should not use mwait for CPU-states.
+        */
+       dmi_check_system(processor_idle_dmi_table);
+}
+
+void __init acpi_early_processor_set_pdc(void)
+{
+       processor_dmi_check();
+
+       acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+                           ACPI_UINT32_MAX,
+                           early_init_pdc, NULL, NULL, NULL);
+       acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
+}
index f775fa0d850feee4996b7e90bd6158c379841e1b..5d592e17d760ebe940f3a64d9c6a30f5d8f158b8 100644 (file)
@@ -77,7 +77,9 @@ void acpi_initialize_hp_context(struct acpi_device *adev,
                                void (*uevent)(struct acpi_device *, u32))
 {
        acpi_lock_hp_context();
-       acpi_set_hp_context(adev, hp, notify, uevent, NULL);
+       hp->notify = notify;
+       hp->uevent = uevent;
+       acpi_set_hp_context(adev, hp);
        acpi_unlock_hp_context();
 }
 EXPORT_SYMBOL_GPL(acpi_initialize_hp_context);
@@ -1421,14 +1423,13 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
                        wakeup->sleep_state = sleep_state;
                }
        }
-       acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
 
  out:
        kfree(buffer.pointer);
        return err;
 }
 
-static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
+static void acpi_wakeup_gpe_init(struct acpi_device *device)
 {
        struct acpi_device_id button_device_ids[] = {
                {"PNP0C0C", 0},
@@ -1436,29 +1437,33 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
                {"PNP0C0E", 0},
                {"", 0},
        };
+       struct acpi_device_wakeup *wakeup = &device->wakeup;
        acpi_status status;
        acpi_event_status event_status;
 
-       device->wakeup.flags.notifier_present = 0;
+       wakeup->flags.notifier_present = 0;
 
        /* Power button, Lid switch always enable wakeup */
        if (!acpi_match_device_ids(device, button_device_ids)) {
-               device->wakeup.flags.run_wake = 1;
+               wakeup->flags.run_wake = 1;
                if (!acpi_match_device_ids(device, &button_device_ids[1])) {
                        /* Do not use Lid/sleep button for S5 wakeup */
-                       if (device->wakeup.sleep_state == ACPI_STATE_S5)
-                               device->wakeup.sleep_state = ACPI_STATE_S4;
+                       if (wakeup->sleep_state == ACPI_STATE_S5)
+                               wakeup->sleep_state = ACPI_STATE_S4;
                }
+               acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
                device_set_wakeup_capable(&device->dev, true);
                return;
        }
 
-       status = acpi_get_gpe_status(device->wakeup.gpe_device,
-                                       device->wakeup.gpe_number,
-                                               &event_status);
-       if (status == AE_OK)
-               device->wakeup.flags.run_wake =
-                               !!(event_status & ACPI_EVENT_FLAG_HANDLE);
+       acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
+                               wakeup->gpe_number);
+       status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
+                                    &event_status);
+       if (ACPI_FAILURE(status))
+               return;
+
+       wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE);
 }
 
 static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
@@ -1478,7 +1483,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 
        device->wakeup.flags.valid = 1;
        device->wakeup.prepare_count = 0;
-       acpi_bus_set_run_wake_flags(device);
+       acpi_wakeup_gpe_init(device);
        /* Call _PSW/_DSW object to disable its ability to wake the sleeping
         * system for the ACPI device with the _PRW object.
         * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
index b3e3cc73ba796edf49d856c203e441c5ab818420..54da4a3fe65e65d4b6334d93b82244f95c245b1f 100644 (file)
@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
 
 static void acpi_sleep_dmi_check(void)
 {
+       int year;
+
+       if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
+               acpi_nvs_nosave_s3();
+
        dmi_check_system(acpisleep_dmi_table);
 }
 
index 350d52a8f7811452142e87564e8ebd2b11cab2f0..18c0e6920eb41fdce3374c48d8946ed12f89fc76 100644 (file)
@@ -204,6 +204,8 @@ struct acpi_video_device {
        struct acpi_video_device_flags flags;
        struct acpi_video_device_cap cap;
        struct list_head entry;
+       struct delayed_work switch_brightness_work;
+       int switch_brightness_event;
        struct acpi_video_bus *video;
        struct acpi_device *dev;
        struct acpi_video_device_brightness *brightness;
@@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current(
                        unsigned long long *level, bool raw);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
-static int acpi_video_switch_brightness(struct acpi_video_device *device,
-                                        int event);
+static void acpi_video_switch_brightness(struct work_struct *work);
 
 static bool acpi_video_use_native_backlight(void)
 {
@@ -275,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd)
        int request_level = bd->props.brightness + 2;
        struct acpi_video_device *vd = bl_get_data(bd);
 
+       cancel_delayed_work(&vd->switch_brightness_work);
        return acpi_video_device_lcd_set_level(vd,
                                vd->brightness->levels[request_level]);
 }
@@ -459,6 +461,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),
                },
        },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ThinkPad X230",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+               },
+       },
        {
         .callback = video_set_use_native_backlight,
         .ident = "ThinkPad T430 and T430s",
@@ -469,10 +479,42 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
        },
        {
         .callback = video_set_use_native_backlight,
-        .ident = "ThinkPad X230",
+        .ident = "ThinkPad T430",
         .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ThinkPad T431s",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ThinkPad Edge E530",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ThinkPad Edge E530",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ThinkPad Edge E530",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
                },
        },
        {
@@ -571,6 +613,30 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"),
                },
        },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "Acer Aspire V5-572G",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "Acer Aspire V5-573G",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
+               },
+       },
+       {
+        .callback = video_set_use_native_backlight,
+        .ident = "ASUS Zenbook Prime UX31A",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
+               },
+       },
        {
        .callback = video_set_use_native_backlight,
        .ident = "HP ProBook 4340s",
@@ -1188,6 +1254,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
        data->device_id = device_id;
        data->video = video;
        data->dev = device;
+       INIT_DELAYED_WORK(&data->switch_brightness_work,
+                         acpi_video_switch_brightness);
 
        attribute = acpi_video_get_device_attr(video, device_id);
 
@@ -1410,15 +1478,18 @@ acpi_video_get_next_level(struct acpi_video_device *device,
        }
 }
 
-static int
-acpi_video_switch_brightness(struct acpi_video_device *device, int event)
+static void
+acpi_video_switch_brightness(struct work_struct *work)
 {
+       struct acpi_video_device *device = container_of(to_delayed_work(work),
+                            struct acpi_video_device, switch_brightness_work);
        unsigned long long level_current, level_next;
+       int event = device->switch_brightness_event;
        int result = -EINVAL;
 
        /* no warning message if acpi_backlight=vendor or a quirk is used */
        if (!acpi_video_verify_backlight_support())
-               return 0;
+               return;
 
        if (!device->brightness)
                goto out;
@@ -1440,8 +1511,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 out:
        if (result)
                printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
-
-       return result;
 }
 
 int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
@@ -1609,6 +1678,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
        return;
 }
 
+static void brightness_switch_event(struct acpi_video_device *video_device,
+                                   u32 event)
+{
+       if (!brightness_switch_enabled)
+               return;
+
+       video_device->switch_brightness_event = event;
+       schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10);
+}
+
 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
 {
        struct acpi_video_device *video_device = data;
@@ -1626,28 +1705,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
 
        switch (event) {
        case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:        /* Cycle brightness */
-               if (brightness_switch_enabled)
-                       acpi_video_switch_brightness(video_device, event);
+               brightness_switch_event(video_device, event);
                keycode = KEY_BRIGHTNESS_CYCLE;
                break;
        case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:  /* Increase brightness */
-               if (brightness_switch_enabled)
-                       acpi_video_switch_brightness(video_device, event);
+               brightness_switch_event(video_device, event);
                keycode = KEY_BRIGHTNESSUP;
                break;
        case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:  /* Decrease brightness */
-               if (brightness_switch_enabled)
-                       acpi_video_switch_brightness(video_device, event);
+               brightness_switch_event(video_device, event);
                keycode = KEY_BRIGHTNESSDOWN;
                break;
        case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
-               if (brightness_switch_enabled)
-                       acpi_video_switch_brightness(video_device, event);
+               brightness_switch_event(video_device, event);
                keycode = KEY_BRIGHTNESS_ZERO;
                break;
        case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:     /* display device off */
-               if (brightness_switch_enabled)
-                       acpi_video_switch_brightness(video_device, event);
+               brightness_switch_event(video_device, event);
                keycode = KEY_DISPLAY_OFF;
                break;
        default:
index dae5607e11153a7de89dc5cbec9ba85fda080ba9..4cd52a4541a96c44fe367bb274484f282287ab20 100644 (file)
@@ -456,6 +456,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 
        /* Promise */
        { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },   /* PDC42819 */
+       { PCI_VDEVICE(PROMISE, 0x3781), board_ahci },   /* FastTrak TX8660 ahci-mode */
 
        /* Asmedia */
        { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci },   /* ASM1060 */
index 18d97d5c7d90f216d76abd9033346a734ae8d9ed..677c0c1b03bd658322cad2faf5becd86ce1db3cd 100644 (file)
@@ -4787,6 +4787,10 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
  *     ata_qc_new - Request an available ATA command, for queueing
  *     @ap: target port
  *
+ *     Some ATA host controllers may implement a queue depth which is less
+ *     than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
+ *     the hardware limitation.
+ *
  *     LOCKING:
  *     None.
  */
@@ -4794,14 +4798,15 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc = NULL;
+       unsigned int max_queue = ap->host->n_tags;
        unsigned int i, tag;
 
        /* no command while frozen */
        if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
                return NULL;
 
-       for (i = 0; i < ATA_MAX_QUEUE; i++) {
-               tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+       for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
+               tag = tag < max_queue ? tag : 0;
 
                /* the last tag is reserved for internal command. */
                if (tag == ATA_TAG_INTERNAL)
@@ -6088,6 +6093,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
 {
        spin_lock_init(&host->lock);
        mutex_init(&host->eh_mutex);
+       host->n_tags = ATA_MAX_QUEUE - 1;
        host->dev = dev;
        host->ops = ops;
 }
@@ -6169,6 +6175,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 {
        int i, rc;
 
+       host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
+
        /* host must have been started */
        if (!(host->flags & ATA_HOST_STARTED)) {
                dev_err(host->dev, "BUG: trying to register unstarted host\n");
index 6760fc4e85b8c809e39655fd92adc83871e75fce..dad83df555c49d94534a544483e20aa0a9767635 100644 (file)
@@ -1811,7 +1811,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
        case ATA_DEV_ATA:
                if (err & ATA_ICRC)
                        qc->err_mask |= AC_ERR_ATA_BUS;
-               if (err & ATA_UNC)
+               if (err & (ATA_UNC | ATA_AMNF))
                        qc->err_mask |= AC_ERR_MEDIA;
                if (err & ATA_IDNF)
                        qc->err_mask |= AC_ERR_INVALID;
@@ -2556,11 +2556,12 @@ static void ata_eh_link_report(struct ata_link *link)
                }
 
                if (cmd->command != ATA_CMD_PACKET &&
-                   (res->feature & (ATA_ICRC | ATA_UNC | ATA_IDNF |
-                                    ATA_ABORTED)))
-                       ata_dev_err(qc->dev, "error: { %s%s%s%s}\n",
+                   (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF |
+                                    ATA_IDNF | ATA_ABORTED)))
+                       ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
                          res->feature & ATA_ICRC ? "ICRC " : "",
                          res->feature & ATA_UNC ? "UNC " : "",
+                         res->feature & ATA_AMNF ? "AMNF " : "",
                          res->feature & ATA_IDNF ? "IDNF " : "",
                          res->feature & ATA_ABORTED ? "ABRT " : "");
 #endif
index 6ad5c072ce348913d8c511574db503a37e798c9c..4d37c5415fc7fec23ba0120a917d706362709770 100644 (file)
@@ -915,7 +915,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
        struct ep93xx_pata_data *drv_data;
        struct ata_host *host;
        struct ata_port *ap;
-       unsigned int irq;
+       int irq;
        struct resource *mem_res;
        void __iomem *ide_base;
        int err;
index 1b35c45c92b75d7f01fd3fcda7a861ae099b4c7e..3f2e1673808053a4de70077735a67723f9955b64 100644 (file)
@@ -544,6 +544,12 @@ void conn_try_outdate_peer_async(struct drbd_connection *connection)
        struct task_struct *opa;
 
        kref_get(&connection->kref);
+       /* We may just have force_sig()'ed this thread
+        * to get it out of some blocking network function.
+        * Clear signals; otherwise kthread_run(), which internally uses
+        * wait_on_completion_killable(), will mistake our pending signal
+        * for a new fatal signal and fail. */
+       flush_signals(current);
        opa = kthread_run(_try_outdate_peer_async, connection, "drbd_async_h");
        if (IS_ERR(opa)) {
                drbd_err(connection, "out of mem, failed to invoke fence-peer helper\n");
index 089e72cd37bea051bf9f9758644fd8b79ea038cc..36e54be402df30b68c579e09c588193f5f015e00 100644 (file)
@@ -622,11 +622,18 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
        memset(&zram->stats, 0, sizeof(zram->stats));
 
        zram->disksize = 0;
-       if (reset_capacity) {
+       if (reset_capacity)
                set_capacity(zram->disk, 0);
-               revalidate_disk(zram->disk);
-       }
+
        up_write(&zram->init_lock);
+
+       /*
+        * Revalidate disk out of the init_lock to avoid lockdep splat.
+        * It's okay because disk's capacity is protected by init_lock
+        * so that revalidate_disk always sees up-to-date capacity.
+        */
+       if (reset_capacity)
+               revalidate_disk(zram->disk);
 }
 
 static ssize_t disksize_store(struct device *dev,
@@ -666,8 +673,15 @@ static ssize_t disksize_store(struct device *dev,
        zram->comp = comp;
        zram->disksize = disksize;
        set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
-       revalidate_disk(zram->disk);
        up_write(&zram->init_lock);
+
+       /*
+        * Revalidate disk out of the init_lock to avoid lockdep splat.
+        * It's okay because disk's capacity is protected by init_lock
+        * so that revalidate_disk always sees up-to-date capacity.
+        */
+       revalidate_disk(zram->disk);
+
        return len;
 
 out_destroy_comp:
index 6f024852c6fbdecc29845b199ded752e0afce468..d9fdeddcef96e6b29d5785cb2001e72b8f805248 100644 (file)
@@ -1076,10 +1076,20 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
        kfree(policy);
 }
 
-static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
+static int update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu,
+                            struct device *cpu_dev)
 {
+       int ret;
+
        if (WARN_ON(cpu == policy->cpu))
-               return;
+               return 0;
+
+       /* Move kobject to the new policy->cpu */
+       ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
+       if (ret) {
+               pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
+               return ret;
+       }
 
        down_write(&policy->rwsem);
 
@@ -1090,6 +1100,8 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
 
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
                        CPUFREQ_UPDATE_POLICY_CPU, policy);
+
+       return 0;
 }
 
 static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
@@ -1153,12 +1165,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
         * the creation of a brand new one. So we need to perform this update
         * by invoking update_policy_cpu().
         */
-       if (recover_policy && cpu != policy->cpu) {
-               update_policy_cpu(policy, cpu);
-               WARN_ON(kobject_move(&policy->kobj, &dev->kobj));
-       } else {
+       if (recover_policy && cpu != policy->cpu)
+               WARN_ON(update_policy_cpu(policy, cpu, dev));
+       else
                policy->cpu = cpu;
-       }
 
        cpumask_copy(policy->cpus, cpumask_of(cpu));
 
@@ -1309,38 +1319,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
        return __cpufreq_add_dev(dev, sif);
 }
 
-static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
-                                          unsigned int old_cpu)
-{
-       struct device *cpu_dev;
-       int ret;
-
-       /* first sibling now owns the new sysfs dir */
-       cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));
-
-       sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
-       ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
-       if (ret) {
-               pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
-
-               down_write(&policy->rwsem);
-               cpumask_set_cpu(old_cpu, policy->cpus);
-               up_write(&policy->rwsem);
-
-               ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
-                                       "cpufreq");
-
-               return -EINVAL;
-       }
-
-       return cpu_dev->id;
-}
-
 static int __cpufreq_remove_dev_prepare(struct device *dev,
                                        struct subsys_interface *sif)
 {
        unsigned int cpu = dev->id, cpus;
-       int new_cpu, ret;
+       int ret;
        unsigned long flags;
        struct cpufreq_policy *policy;
 
@@ -1380,14 +1363,23 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
        if (cpu != policy->cpu) {
                sysfs_remove_link(&dev->kobj, "cpufreq");
        } else if (cpus > 1) {
-               new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu);
-               if (new_cpu >= 0) {
-                       update_policy_cpu(policy, new_cpu);
+               /* Nominate new CPU */
+               int new_cpu = cpumask_any_but(policy->cpus, cpu);
+               struct device *cpu_dev = get_cpu_device(new_cpu);
 
-                       if (!cpufreq_suspended)
-                               pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
-                                        __func__, new_cpu, cpu);
+               sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
+               ret = update_policy_cpu(policy, new_cpu, cpu_dev);
+               if (ret) {
+                       if (sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
+                                             "cpufreq"))
+                               pr_err("%s: Failed to restore kobj link to cpu:%d\n",
+                                      __func__, cpu_dev->id);
+                       return ret;
                }
+
+               if (!cpufreq_suspended)
+                       pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
+                                __func__, new_cpu, cpu);
        } else if (cpufreq_driver->stop_cpu && cpufreq_driver->setpolicy) {
                cpufreq_driver->stop_cpu(policy);
        }
index 18d4091890920048f8ad0301bd784ee29cfca074..ad3f38fd3eb9feefa12212362e1312884974d745 100644 (file)
@@ -170,21 +170,24 @@ static void od_check_cpu(int cpu, unsigned int load)
                dbs_freq_increase(policy, policy->max);
        } else {
                /* Calculate the next frequency proportional to load */
-               unsigned int freq_next;
-               freq_next = load * policy->cpuinfo.max_freq / 100;
+               unsigned int freq_next, min_f, max_f;
+
+               min_f = policy->cpuinfo.min_freq;
+               max_f = policy->cpuinfo.max_freq;
+               freq_next = min_f + load * (max_f - min_f) / 100;
 
                /* No longer fully busy, reset rate_mult */
                dbs_info->rate_mult = 1;
 
                if (!od_tuners->powersave_bias) {
                        __cpufreq_driver_target(policy, freq_next,
-                                       CPUFREQ_RELATION_L);
+                                       CPUFREQ_RELATION_C);
                        return;
                }
 
                freq_next = od_ops.powersave_bias_target(policy, freq_next,
                                        CPUFREQ_RELATION_L);
-               __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
+               __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
        }
 }
 
index 1632981c4b25b7882008f25991c2071e94faf607..df14766a8e06b7b692807c08d1bf27d683a339eb 100644 (file)
@@ -117,7 +117,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
                .frequency = 0,
        };
        struct cpufreq_frequency_table *pos;
-       unsigned int freq, i = 0;
+       unsigned int freq, diff, i = 0;
 
        pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
                                        target_freq, relation, policy->cpu);
@@ -127,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
                suboptimal.frequency = ~0;
                break;
        case CPUFREQ_RELATION_L:
+       case CPUFREQ_RELATION_C:
                optimal.frequency = ~0;
                break;
        }
@@ -168,6 +169,15 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
                                }
                        }
                        break;
+               case CPUFREQ_RELATION_C:
+                       diff = abs(freq - target_freq);
+                       if (diff < optimal.frequency ||
+                           (diff == optimal.frequency &&
+                            freq > table[optimal.driver_data].frequency)) {
+                               optimal.frequency = diff;
+                               optimal.driver_data = i;
+                       }
+                       break;
                }
        }
        if (optimal.driver_data > i) {
index af366c21d4b4032e1471391e97ac800229d12733..c2d30765bf3d209618bc3b9049cff85f5d5c1745 100644 (file)
@@ -66,10 +66,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
 
        /* scaling up?  scale voltage before frequency */
        if (new_freq > old_freq) {
-               ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
-               if (ret) {
-                       dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
-                       return ret;
+               if (!IS_ERR(pu_reg)) {
+                       ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
+                       if (ret) {
+                               dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
+                               return ret;
+                       }
                }
                ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
                if (ret) {
@@ -121,10 +123,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
                        dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
                        ret = 0;
                }
-               ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
-               if (ret) {
-                       dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
-                       ret = 0;
+               if (!IS_ERR(pu_reg)) {
+                       ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
+                       if (ret) {
+                               dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
+                               ret = 0;
+                       }
                }
        }
 
@@ -182,9 +186,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
        }
 
        arm_reg = regulator_get(cpu_dev, "arm");
-       pu_reg = regulator_get(cpu_dev, "pu");
+       pu_reg = regulator_get_optional(cpu_dev, "pu");
        soc_reg = regulator_get(cpu_dev, "soc");
-       if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
+       if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) {
                dev_err(cpu_dev, "failed to get regulators\n");
                ret = -ENOENT;
                goto put_reg;
@@ -268,9 +272,11 @@ soc_opp_out:
        ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
        if (ret > 0)
                transition_latency += ret * 1000;
-       ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
-       if (ret > 0)
-               transition_latency += ret * 1000;
+       if (!IS_ERR(pu_reg)) {
+               ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
+               if (ret > 0)
+                       transition_latency += ret * 1000;
+       }
 
        /*
         * OPP is maintained in order of increasing frequency, and
@@ -327,7 +333,8 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev)
        cpufreq_unregister_driver(&imx6q_cpufreq_driver);
        dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
        regulator_put(arm_reg);
-       regulator_put(pu_reg);
+       if (!IS_ERR(pu_reg))
+               regulator_put(pu_reg);
        regulator_put(soc_reg);
        clk_put(arm_clk);
        clk_put(pll1_sys_clk);
index 86631cb6f7dee9316774517f6b9d75243bda103b..c5eac949760de99ab8345fa1933657278afe7092 100644 (file)
@@ -37,7 +37,6 @@
 #define BYT_TURBO_RATIOS       0x66c
 #define BYT_TURBO_VIDS         0x66d
 
-
 #define FRAC_BITS 8
 #define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
 #define fp_toint(X) ((X) >> FRAC_BITS)
@@ -50,7 +49,7 @@ static inline int32_t mul_fp(int32_t x, int32_t y)
 
 static inline int32_t div_fp(int32_t x, int32_t y)
 {
-       return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
+       return div_s64((int64_t)x << FRAC_BITS, y);
 }
 
 struct sample {
@@ -148,7 +147,7 @@ static struct perf_limits limits = {
 };
 
 static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
-                       int deadband, int integral) {
+                            int deadband, int integral) {
        pid->setpoint = setpoint;
        pid->deadband  = deadband;
        pid->integral  = int_tofp(integral);
@@ -167,7 +166,6 @@ static inline void pid_i_gain_set(struct _pid *pid, int percent)
 
 static inline void pid_d_gain_set(struct _pid *pid, int percent)
 {
-
        pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
 }
 
@@ -207,16 +205,13 @@ static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
        pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct);
        pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct);
 
-       pid_reset(&cpu->pid,
-               pid_params.setpoint,
-               100,
-               pid_params.deadband,
-               0);
+       pid_reset(&cpu->pid, pid_params.setpoint, 100, pid_params.deadband, 0);
 }
 
 static inline void intel_pstate_reset_all_pid(void)
 {
        unsigned int cpu;
+
        for_each_online_cpu(cpu) {
                if (all_cpu_data[cpu])
                        intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
@@ -230,13 +225,13 @@ static int pid_param_set(void *data, u64 val)
        intel_pstate_reset_all_pid();
        return 0;
 }
+
 static int pid_param_get(void *data, u64 *val)
 {
        *val = *(u32 *)data;
        return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get,
-                       pid_param_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get, pid_param_set, "%llu\n");
 
 struct pid_param {
        char *name;
@@ -253,9 +248,9 @@ static struct pid_param pid_files[] = {
        {NULL, NULL}
 };
 
-static struct dentry *debugfs_parent;
-static void intel_pstate_debug_expose_params(void)
+static void __init intel_pstate_debug_expose_params(void)
 {
+       struct dentry *debugfs_parent;
        int i = 0;
 
        debugfs_parent = debugfs_create_dir("pstate_snb", NULL);
@@ -263,8 +258,8 @@ static void intel_pstate_debug_expose_params(void)
                return;
        while (pid_files[i].name) {
                debugfs_create_file(pid_files[i].name, 0660,
-                               debugfs_parent, pid_files[i].value,
-                               &fops_pid_param);
+                                   debugfs_parent, pid_files[i].value,
+                                   &fops_pid_param);
                i++;
        }
 }
@@ -280,10 +275,11 @@ static void intel_pstate_debug_expose_params(void)
        }
 
 static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
-                               const char *buf, size_t count)
+                             const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
+
        ret = sscanf(buf, "%u", &input);
        if (ret != 1)
                return -EINVAL;
@@ -296,10 +292,11 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
 }
 
 static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
-                               const char *buf, size_t count)
+                                 const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
+
        ret = sscanf(buf, "%u", &input);
        if (ret != 1)
                return -EINVAL;
@@ -307,14 +304,16 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
        limits.max_sysfs_pct = clamp_t(int, input, 0 , 100);
        limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+
        return count;
 }
 
 static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
-                               const char *buf, size_t count)
+                                 const char *buf, size_t count)
 {
        unsigned int input;
        int ret;
+
        ret = sscanf(buf, "%u", &input);
        if (ret != 1)
                return -EINVAL;
@@ -342,17 +341,16 @@ static struct attribute *intel_pstate_attributes[] = {
 static struct attribute_group intel_pstate_attr_group = {
        .attrs = intel_pstate_attributes,
 };
-static struct kobject *intel_pstate_kobject;
 
-static void intel_pstate_sysfs_expose_params(void)
+static void __init intel_pstate_sysfs_expose_params(void)
 {
+       struct kobject *intel_pstate_kobject;
        int rc;
 
        intel_pstate_kobject = kobject_create_and_add("intel_pstate",
                                                &cpu_subsys.dev_root->kobj);
        BUG_ON(!intel_pstate_kobject);
-       rc = sysfs_create_group(intel_pstate_kobject,
-                               &intel_pstate_attr_group);
+       rc = sysfs_create_group(intel_pstate_kobject, &intel_pstate_attr_group);
        BUG_ON(rc);
 }
 
@@ -360,6 +358,7 @@ static void intel_pstate_sysfs_expose_params(void)
 static int byt_get_min_pstate(void)
 {
        u64 value;
+
        rdmsrl(BYT_RATIOS, value);
        return (value >> 8) & 0x7F;
 }
@@ -367,6 +366,7 @@ static int byt_get_min_pstate(void)
 static int byt_get_max_pstate(void)
 {
        u64 value;
+
        rdmsrl(BYT_RATIOS, value);
        return (value >> 16) & 0x7F;
 }
@@ -374,6 +374,7 @@ static int byt_get_max_pstate(void)
 static int byt_get_turbo_pstate(void)
 {
        u64 value;
+
        rdmsrl(BYT_TURBO_RATIOS, value);
        return value & 0x7F;
 }
@@ -407,7 +408,6 @@ static void byt_get_vid(struct cpudata *cpudata)
 {
        u64 value;
 
-
        rdmsrl(BYT_VIDS, value);
        cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
        cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
@@ -420,10 +420,10 @@ static void byt_get_vid(struct cpudata *cpudata)
        cpudata->vid.turbo = value & 0x7f;
 }
 
-
 static int core_get_min_pstate(void)
 {
        u64 value;
+
        rdmsrl(MSR_PLATFORM_INFO, value);
        return (value >> 40) & 0xFF;
 }
@@ -431,6 +431,7 @@ static int core_get_min_pstate(void)
 static int core_get_max_pstate(void)
 {
        u64 value;
+
        rdmsrl(MSR_PLATFORM_INFO, value);
        return (value >> 8) & 0xFF;
 }
@@ -439,9 +440,10 @@ static int core_get_turbo_pstate(void)
 {
        u64 value;
        int nont, ret;
+
        rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
        nont = core_get_max_pstate();
-       ret = ((value) & 255);
+       ret = (value) & 255;
        if (ret <= nont)
                ret = nont;
        return ret;
@@ -493,12 +495,12 @@ static struct cpu_defaults byt_params = {
        },
 };
 
-
 static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
 {
        int max_perf = cpu->pstate.turbo_pstate;
        int max_perf_adj;
        int min_perf;
+
        if (limits.no_turbo)
                max_perf = cpu->pstate.max_pstate;
 
@@ -507,8 +509,7 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
                        cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
 
        min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
-       *min = clamp_t(int, min_perf,
-                       cpu->pstate.min_pstate, max_perf);
+       *min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
 }
 
 static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
@@ -529,21 +530,6 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
        pstate_funcs.set(cpu, pstate);
 }
 
-static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
-{
-       int target;
-       target = cpu->pstate.current_pstate + steps;
-
-       intel_pstate_set_pstate(cpu, target);
-}
-
-static inline void intel_pstate_pstate_decrease(struct cpudata *cpu, int steps)
-{
-       int target;
-       target = cpu->pstate.current_pstate - steps;
-       intel_pstate_set_pstate(cpu, target);
-}
-
 static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 {
        cpu->pstate.min_pstate = pstate_funcs.get_min();
@@ -559,13 +545,9 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
 {
        struct sample *sample = &cpu->sample;
        int64_t core_pct;
-       int32_t rem;
 
        core_pct = int_tofp(sample->aperf) * int_tofp(100);
-       core_pct = div_u64_rem(core_pct, int_tofp(sample->mperf), &rem);
-
-       if ((rem << 1) >= int_tofp(sample->mperf))
-               core_pct += 1;
+       core_pct = div64_u64(core_pct, int_tofp(sample->mperf));
 
        sample->freq = fp_toint(
                mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
@@ -576,12 +558,12 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
 static inline void intel_pstate_sample(struct cpudata *cpu)
 {
        u64 aperf, mperf;
+       unsigned long flags;
 
+       local_irq_save(flags);
        rdmsrl(MSR_IA32_APERF, aperf);
        rdmsrl(MSR_IA32_MPERF, mperf);
-
-       aperf = aperf >> FRAC_BITS;
-       mperf = mperf >> FRAC_BITS;
+       local_irq_restore(flags);
 
        cpu->last_sample_time = cpu->sample.time;
        cpu->sample.time = ktime_get();
@@ -598,10 +580,9 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
 
 static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
 {
-       int sample_time, delay;
+       int delay;
 
-       sample_time = pid_params.sample_rate_ms;
-       delay = msecs_to_jiffies(sample_time);
+       delay = msecs_to_jiffies(pid_params.sample_rate_ms);
        mod_timer_pinned(&cpu->timer, jiffies + delay);
 }
 
@@ -616,12 +597,12 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
        current_pstate = int_tofp(cpu->pstate.current_pstate);
        core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
 
-       sample_time = (pid_params.sample_rate_ms  * USEC_PER_MSEC);
+       sample_time = pid_params.sample_rate_ms  * USEC_PER_MSEC;
        duration_us = (u32) ktime_us_delta(cpu->sample.time,
-                                       cpu->last_sample_time);
+                                          cpu->last_sample_time);
        if (duration_us > sample_time * 3) {
                sample_ratio = div_fp(int_tofp(sample_time),
-                               int_tofp(duration_us));
+                                     int_tofp(duration_us));
                core_busy = mul_fp(core_busy, sample_ratio);
        }
 
@@ -632,20 +613,15 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
 {
        int32_t busy_scaled;
        struct _pid *pid;
-       signed int ctl = 0;
-       int steps;
+       signed int ctl;
 
        pid = &cpu->pid;
        busy_scaled = intel_pstate_get_scaled_busy(cpu);
 
        ctl = pid_calc(pid, busy_scaled);
 
-       steps = abs(ctl);
-
-       if (ctl < 0)
-               intel_pstate_pstate_increase(cpu, steps);
-       else
-               intel_pstate_pstate_decrease(cpu, steps);
+       /* Negative values of ctl increase the pstate and vice versa */
+       intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
 }
 
 static void intel_pstate_timer_func(unsigned long __data)
@@ -705,8 +681,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
 
        init_timer_deferrable(&cpu->timer);
        cpu->timer.function = intel_pstate_timer_func;
-       cpu->timer.data =
-               (unsigned long)cpu;
+       cpu->timer.data = (unsigned long)cpu;
        cpu->timer.expires = jiffies + HZ/100;
        intel_pstate_busy_pid_reset(cpu);
        intel_pstate_sample(cpu);
@@ -751,7 +726,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
        limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100);
        limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
 
-       limits.max_policy_pct = policy->max * 100 / policy->cpuinfo.max_freq;
+       limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq;
        limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100);
        limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
@@ -763,8 +738,8 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
 {
        cpufreq_verify_within_cpu_limits(policy);
 
-       if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
-               (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
+       if (policy->policy != CPUFREQ_POLICY_POWERSAVE &&
+           policy->policy != CPUFREQ_POLICY_PERFORMANCE)
                return -EINVAL;
 
        return 0;
@@ -797,7 +772,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
 
        rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
        if (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ||
-               cpu->pstate.max_pstate == cpu->pstate.turbo_pstate) {
+           cpu->pstate.max_pstate == cpu->pstate.turbo_pstate) {
                limits.turbo_disabled = 1;
                limits.no_turbo = 1;
        }
@@ -839,8 +814,8 @@ static int intel_pstate_msrs_not_valid(void)
        rdmsrl(MSR_IA32_MPERF, mperf);
 
        if (!pstate_funcs.get_max() ||
-               !pstate_funcs.get_min() ||
-               !pstate_funcs.get_turbo())
+           !pstate_funcs.get_min() ||
+           !pstate_funcs.get_turbo())
                return -ENODEV;
 
        rdmsrl(MSR_IA32_APERF, tmp);
@@ -922,14 +897,14 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void)
        struct acpi_table_header hdr;
        struct hw_vendor_info *v_info;
 
-       if (acpi_disabled
-           || ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr)))
+       if (acpi_disabled ||
+           ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr)))
                return false;
 
        for (v_info = vendor_info; v_info->valid; v_info++) {
-               if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE)
-                   && !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE)
-                   && intel_pstate_no_acpi_pss())
+               if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE) &&
+                   !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
+                   intel_pstate_no_acpi_pss())
                        return true;
        }
 
index c8012bc869107206ad1fd7024ab86a76a406890e..f91027259c3ce7ab84da0db0feb8997c50824bf8 100644 (file)
@@ -55,6 +55,7 @@ static const struct {
        unsigned freq;
        unsigned mult;
 } usual_frequency_table[] = {
+       { 350000, 35 }, // 100   * 3.5
        { 400000, 40 }, // 100   * 4
        { 450000, 45 }, // 100   * 4.5
        { 475000, 50 }, //  95   * 5
index 1b96fb91d32cc1daf9aa3ba82e71168763dac9dc..32748c36c477099cf00344b3410dd8c2331b9404 100644 (file)
@@ -15,12 +15,7 @@ config CPU_IDLE
 if CPU_IDLE
 
 config CPU_IDLE_MULTIPLE_DRIVERS
-        bool "Support multiple cpuidle drivers"
-        default n
-        help
-         Allows the cpuidle framework to use different drivers for each CPU.
-         This is useful if you have a system with different CPU latencies and
-         states. If unsure say N.
+        bool
 
 config CPU_IDLE_GOV_LADDER
        bool "Ladder governor (for periodic timer tick)"
index b6d69e899f5de5380ff57e9ae7cf8ead0a9dd6e7..a186dec8e5df5ec1b0b7d935fbea3f65d180a1e3 100644 (file)
@@ -10,6 +10,7 @@ config ARM_ARMADA_370_XP_CPUIDLE
 config ARM_BIG_LITTLE_CPUIDLE
        bool "Support for ARM big.LITTLE processors"
        depends on ARCH_VEXPRESS_TC2_PM
+       depends on MCPM
        select ARM_CPU_SUSPEND
        select CPU_IDLE_MULTIPLE_DRIVERS
        help
index cb7019977c50febbcd21b9ad49f4a9bfe1ca6271..ee9df5e3f5eba2a5bb705e8be1898c2a370ccd21 100644 (file)
@@ -119,11 +119,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
        ktime_t time_start, time_end;
        s64 diff;
 
+       trace_cpu_idle_rcuidle(index, dev->cpu);
        time_start = ktime_get();
 
        entered_state = target_state->enter(dev, drv, index);
 
        time_end = ktime_get();
+       trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
        if (!cpuidle_state_is_coupled(dev, drv, entered_state))
                local_irq_enable();
index 9634f20e392611b32349aaa348aa3980f2344ecd..e431d11abf8d86deb79b200ef17eaa24a2c139ca 100644 (file)
@@ -182,10 +182,6 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
 static int poll_idle(struct cpuidle_device *dev,
                struct cpuidle_driver *drv, int index)
 {
-       ktime_t t1, t2;
-       s64 diff;
-
-       t1 = ktime_get();
        local_irq_enable();
        if (!current_set_polling_and_test()) {
                while (!need_resched())
@@ -193,13 +189,6 @@ static int poll_idle(struct cpuidle_device *dev,
        }
        current_clr_polling();
 
-       t2 = ktime_get();
-       diff = ktime_to_us(ktime_sub(t2, t1));
-       if (diff > INT_MAX)
-               diff = INT_MAX;
-
-       dev->last_residency = (int) diff;
-
        return index;
 }
 
index 9f08e8cce1af89c17b14bfed7358382b7ae3e542..044ee0df5871949b8c1e0c0c744b4db068d4ba57 100644 (file)
@@ -144,7 +144,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
 
        ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
 
-       for (i = 0; i < drv->state_count; i++) {
+       for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
                state = &drv->states[i];
                lstate = &ldev->states[i];
 
@@ -156,7 +156,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
 
                if (i < drv->state_count - 1)
                        lstate->threshold.promotion_time = state->exit_latency;
-               if (i > 0)
+               if (i > CPUIDLE_DRIVER_STATE_START)
                        lstate->threshold.demotion_time = state->exit_latency;
        }
 
index c4f80c15a48dde7be9e16898b09f008e5d0c28fd..c3732fa74f828b61172bd8a10e2953c8226b6689 100644 (file)
@@ -35,7 +35,6 @@
 #define RESOLUTION 1024
 #define DECAY 8
 #define MAX_INTERESTING 50000
-#define STDDEV_THRESH 400
 
 
 /*
index efe2f175168f608f6170d37d516a444cab6c0676..97c5903b4606cf0fa02aecec826cbed605796234 100644 (file)
@@ -445,7 +445,7 @@ static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
 
 #define define_one_driver_ro(_name, show)                       \
        static struct cpuidle_driver_attr attr_driver_##_name = \
-               __ATTR(_name, 0644, show, NULL)
+               __ATTR(_name, 0444, show, NULL)
 
 struct cpuidle_driver_kobj {
        struct cpuidle_driver *drv;
index 49e74c1fc63998d03367bba6f6e85f7c70731199..3dced0a9eae3038feae328815aee028e8ee86b36 100644 (file)
@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers"
 config ARM_EXYNOS4_BUS_DEVFREQ
        bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
        depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
-       select ARCH_HAS_OPP
        select DEVFREQ_GOV_SIMPLE_ONDEMAND
        select PM_OPP
        help
index 57985410f12f7ea9770818457e2d9550d815a3dd..a66a3217f1d92f939fa4f6f2b1ee7a7ee976488f 100644 (file)
@@ -336,10 +336,10 @@ static const struct {
                QUIRK_CYCLE_TIMER | QUIRK_IR_WAKE},
 
        {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, 0,
-               QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
+               QUIRK_CYCLE_TIMER /* FIXME: necessary? */ | QUIRK_NO_MSI},
 
        {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, PCI_ANY_ID,
-               0},
+               QUIRK_NO_MSI},
 
        {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
                QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
index 1491dd4f08f9f1526718835a3e4ef63c86d1e659..65f2f3fdde2417e5e923dba733aba14b5dadf3dc 100644 (file)
@@ -262,7 +262,7 @@ static const char *cper_pcie_port_type_strs[] = {
 };
 
 static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
-                           const struct acpi_generic_data *gdata)
+                           const struct acpi_hest_generic_data *gdata)
 {
        if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
                printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
@@ -298,7 +298,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
 }
 
 static void cper_estatus_print_section(
-       const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
+       const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
 {
        uuid_le *sec_type = (uuid_le *)gdata->section_type;
        __u16 severity;
@@ -344,9 +344,9 @@ err_section_too_small:
 }
 
 void cper_estatus_print(const char *pfx,
-                       const struct acpi_generic_status *estatus)
+                       const struct acpi_hest_generic_status *estatus)
 {
-       struct acpi_generic_data *gdata;
+       struct acpi_hest_generic_data *gdata;
        unsigned int data_len, gedata_len;
        int sec_no = 0;
        char newpfx[64];
@@ -359,7 +359,7 @@ void cper_estatus_print(const char *pfx,
                       "and requires no further action");
        printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
        data_len = estatus->data_length;
-       gdata = (struct acpi_generic_data *)(estatus + 1);
+       gdata = (struct acpi_hest_generic_data *)(estatus + 1);
        snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
        while (data_len >= sizeof(*gdata)) {
                gedata_len = gdata->error_data_length;
@@ -371,10 +371,10 @@ void cper_estatus_print(const char *pfx,
 }
 EXPORT_SYMBOL_GPL(cper_estatus_print);
 
-int cper_estatus_check_header(const struct acpi_generic_status *estatus)
+int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
 {
        if (estatus->data_length &&
-           estatus->data_length < sizeof(struct acpi_generic_data))
+           estatus->data_length < sizeof(struct acpi_hest_generic_data))
                return -EINVAL;
        if (estatus->raw_data_length &&
            estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
@@ -384,9 +384,9 @@ int cper_estatus_check_header(const struct acpi_generic_status *estatus)
 }
 EXPORT_SYMBOL_GPL(cper_estatus_check_header);
 
-int cper_estatus_check(const struct acpi_generic_status *estatus)
+int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
 {
-       struct acpi_generic_data *gdata;
+       struct acpi_hest_generic_data *gdata;
        unsigned int data_len, gedata_len;
        int rc;
 
@@ -394,7 +394,7 @@ int cper_estatus_check(const struct acpi_generic_status *estatus)
        if (rc)
                return rc;
        data_len = estatus->data_length;
-       gdata = (struct acpi_generic_data *)(estatus + 1);
+       gdata = (struct acpi_hest_generic_data *)(estatus + 1);
        while (data_len >= sizeof(*gdata)) {
                gedata_len = gdata->error_data_length;
                if (gedata_len > data_len - sizeof(*gdata))
index 0c9f803fc1acdb3fe9e6798ce506e1ec21a41680..b6ae89ea88119b2b1d35b522f64e07470d20a8dc 100644 (file)
@@ -284,6 +284,7 @@ static int gpio_rcar_irq_domain_map(struct irq_domain *h, unsigned int irq,
 
 static struct irq_domain_ops gpio_rcar_irq_domain_ops = {
        .map    = gpio_rcar_irq_domain_map,
+       .xlate  = irq_domain_xlate_twocell,
 };
 
 struct gpio_rcar_info {
index f36126383d260166a950ad20c72b69637246c550..d893e4da5dcef9cc0c30d873f6f3d6033a27a03d 100644 (file)
@@ -1616,22 +1616,6 @@ out:
        return ret;
 }
 
-void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv)
-{
-       struct i915_vma *vma;
-
-       /*
-        * Only the global gtt is relevant for gtt memory mappings, so restrict
-        * list traversal to objects bound into the global address space. Note
-        * that the active list should be empty, but better safe than sorry.
-        */
-       WARN_ON(!list_empty(&dev_priv->gtt.base.active_list));
-       list_for_each_entry(vma, &dev_priv->gtt.base.active_list, mm_list)
-               i915_gem_release_mmap(vma->obj);
-       list_for_each_entry(vma, &dev_priv->gtt.base.inactive_list, mm_list)
-               i915_gem_release_mmap(vma->obj);
-}
-
 /**
  * i915_gem_release_mmap - remove physical page mappings
  * @obj: obj in question
@@ -1657,6 +1641,15 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
        obj->fault_mappable = false;
 }
 
+void
+i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv)
+{
+       struct drm_i915_gem_object *obj;
+
+       list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
+               i915_gem_release_mmap(obj);
+}
+
 uint32_t
 i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
 {
index 3521f998a1788488b8c396860f6433ffacb81ae2..34894b57306401645a2184d48d99ed2966c8c9f1 100644 (file)
@@ -31,7 +31,7 @@
 struct i915_render_state {
        struct drm_i915_gem_object *obj;
        unsigned long ggtt_offset;
-       void *batch;
+       u32 *batch;
        u32 size;
        u32 len;
 };
@@ -80,7 +80,7 @@ free:
 
 static void render_state_free(struct i915_render_state *so)
 {
-       kunmap(so->batch);
+       kunmap(kmap_to_page(so->batch));
        i915_gem_object_ggtt_unpin(so->obj);
        drm_gem_object_unreference(&so->obj->base);
        kfree(so);
index 267f069765adedffb942d1352649502ac624a364..c05c84f3f091382729b5cfcfa867471faed06a83 100644 (file)
@@ -2845,7 +2845,7 @@ static int semaphore_passed(struct intel_engine_cs *ring)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
        struct intel_engine_cs *signaller;
-       u32 seqno, ctl;
+       u32 seqno;
 
        ring->hangcheck.deadlock++;
 
@@ -2857,15 +2857,12 @@ static int semaphore_passed(struct intel_engine_cs *ring)
        if (signaller->hangcheck.deadlock >= I915_NUM_RINGS)
                return -1;
 
-       /* cursory check for an unkickable deadlock */
-       ctl = I915_READ_CTL(signaller);
-       if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0)
-               return -1;
-
        if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno))
                return 1;
 
-       if (signaller->hangcheck.deadlock)
+       /* cursory check for an unkickable deadlock */
+       if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE &&
+           semaphore_passed(signaller) < 0)
                return -1;
 
        return 0;
index 0b2471107137a90af6677ece89a7351c9b97f599..c0ea66192fe03a8fe977ac0aea977a07204530c4 100644 (file)
@@ -2291,6 +2291,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
                                gb_tile_moden = 0;
                                break;
                        }
+                       rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
                        WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
                }
        } else if (num_pipe_configs == 8) {
@@ -7376,6 +7377,7 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)
                tmp = RREG32(IH_RB_CNTL);
                tmp |= IH_WPTR_OVERFLOW_CLEAR;
                WREG32(IH_RB_CNTL, tmp);
+               wptr &= ~RB_OVERFLOW;
        }
        return (wptr & rdev->ih.ptr_mask);
 }
index 250bac3935a43954c4fff467cdd7da694e1d57c3..15e4f28015e1e74fcc0a3e6189feee1274fa1794 100644 (file)
@@ -4756,6 +4756,7 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
                tmp = RREG32(IH_RB_CNTL);
                tmp |= IH_WPTR_OVERFLOW_CLEAR;
                WREG32(IH_RB_CNTL, tmp);
+               wptr &= ~RB_OVERFLOW;
        }
        return (wptr & rdev->ih.ptr_mask);
 }
index c66952d4b00cc5d706a13650fe2d82ef71389f1d..3c69f58e46efd94b02a440e15e8aad66f9241712 100644 (file)
@@ -3795,6 +3795,7 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev)
                tmp = RREG32(IH_RB_CNTL);
                tmp |= IH_WPTR_OVERFLOW_CLEAR;
                WREG32(IH_RB_CNTL, tmp);
+               wptr &= ~RB_OVERFLOW;
        }
        return (wptr & rdev->ih.ptr_mask);
 }
index b7204500a9a6970f863c09fe82aa495975b4092a..60c47f8291222369f7f6070953eea7bda1a25ce9 100644 (file)
@@ -449,6 +449,7 @@ struct radeon_bo_va {
 
        /* protected by vm mutex */
        struct list_head                vm_list;
+       struct list_head                vm_status;
 
        /* constant after initialization */
        struct radeon_vm                *vm;
@@ -867,6 +868,9 @@ struct radeon_vm {
        struct list_head                va;
        unsigned                        id;
 
+       /* BOs freed, but not yet updated in the PT */
+       struct list_head                freed;
+
        /* contains the page directory */
        struct radeon_bo                *page_directory;
        uint64_t                        pd_gpu_addr;
@@ -875,6 +879,8 @@ struct radeon_vm {
        /* array of page tables, one for each page directory entry */
        struct radeon_vm_pt             *page_tables;
 
+       struct radeon_bo_va             *ib_bo_va;
+
        struct mutex                    mutex;
        /* last fence for cs using this vm */
        struct radeon_fence             *fence;
@@ -2832,9 +2838,10 @@ void radeon_vm_fence(struct radeon_device *rdev,
 uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
 int radeon_vm_update_page_directory(struct radeon_device *rdev,
                                    struct radeon_vm *vm);
+int radeon_vm_clear_freed(struct radeon_device *rdev,
+                         struct radeon_vm *vm);
 int radeon_vm_bo_update(struct radeon_device *rdev,
-                       struct radeon_vm *vm,
-                       struct radeon_bo *bo,
+                       struct radeon_bo_va *bo_va,
                        struct ttm_mem_reg *mem);
 void radeon_vm_bo_invalidate(struct radeon_device *rdev,
                             struct radeon_bo *bo);
@@ -2847,8 +2854,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
                          struct radeon_bo_va *bo_va,
                          uint64_t offset,
                          uint32_t flags);
-int radeon_vm_bo_rmv(struct radeon_device *rdev,
-                    struct radeon_bo_va *bo_va);
+void radeon_vm_bo_rmv(struct radeon_device *rdev,
+                     struct radeon_bo_va *bo_va);
 
 /* audio */
 void r600_audio_update_hdmi(struct work_struct *work);
index 71a143461478a60f5d9bc8428a0276c38b78953b..ae763f60c8a0a23f551bffb5119770d94527931a 100644 (file)
@@ -461,13 +461,23 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
                                   struct radeon_vm *vm)
 {
        struct radeon_device *rdev = p->rdev;
+       struct radeon_bo_va *bo_va;
        int i, r;
 
        r = radeon_vm_update_page_directory(rdev, vm);
        if (r)
                return r;
 
-       r = radeon_vm_bo_update(rdev, vm, rdev->ring_tmp_bo.bo,
+       r = radeon_vm_clear_freed(rdev, vm);
+       if (r)
+               return r;
+
+       if (vm->ib_bo_va == NULL) {
+               DRM_ERROR("Tmp BO not in VM!\n");
+               return -EINVAL;
+       }
+
+       r = radeon_vm_bo_update(rdev, vm->ib_bo_va,
                                &rdev->ring_tmp_bo.bo->tbo.mem);
        if (r)
                return r;
@@ -480,7 +490,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
                        continue;
 
                bo = p->relocs[i].robj;
-               r = radeon_vm_bo_update(rdev, vm, bo, &bo->tbo.mem);
+               bo_va = radeon_vm_bo_find(vm, bo);
+               if (bo_va == NULL) {
+                       dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
+                       return -EINVAL;
+               }
+
+               r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem);
                if (r)
                        return r;
        }
index 03686fab842d3c2e0de237fa6fb027895a025a80..697add2cd4e34e89b6276659142f476ccf0c1e64 100644 (file)
@@ -1056,36 +1056,36 @@ static void radeon_check_arguments(struct radeon_device *rdev)
        if (!radeon_check_pot_argument(radeon_vm_size)) {
                dev_warn(rdev->dev, "VM size (%d) must be a power of 2\n",
                         radeon_vm_size);
-               radeon_vm_size = 4096;
+               radeon_vm_size = 4;
        }
 
-       if (radeon_vm_size < 4) {
-               dev_warn(rdev->dev, "VM size (%d) to small, min is 4MB\n",
+       if (radeon_vm_size < 1) {
+               dev_warn(rdev->dev, "VM size (%d) to small, min is 1GB\n",
                         radeon_vm_size);
-               radeon_vm_size = 4096;
+               radeon_vm_size = 4;
        }
 
        /*
         * Max GPUVM size for Cayman, SI and CI are 40 bits.
         */
-       if (radeon_vm_size > 1024*1024) {
-               dev_warn(rdev->dev, "VM size (%d) to large, max is 1TB\n",
+       if (radeon_vm_size > 1024) {
+               dev_warn(rdev->dev, "VM size (%d) too large, max is 1TB\n",
                         radeon_vm_size);
-               radeon_vm_size = 4096;
+               radeon_vm_size = 4;
        }
 
        /* defines number of bits in page table versus page directory,
         * a page is 4KB so we have 12 bits offset, minimum 9 bits in the
         * page table and the remaining bits are in the page directory */
        if (radeon_vm_block_size < 9) {
-               dev_warn(rdev->dev, "VM page table size (%d) to small\n",
+               dev_warn(rdev->dev, "VM page table size (%d) too small\n",
                         radeon_vm_block_size);
                radeon_vm_block_size = 9;
        }
 
        if (radeon_vm_block_size > 24 ||
-           radeon_vm_size < (1ull << radeon_vm_block_size)) {
-               dev_warn(rdev->dev, "VM page table size (%d) to large\n",
+           (radeon_vm_size * 1024) < (1ull << radeon_vm_block_size)) {
+               dev_warn(rdev->dev, "VM page table size (%d) too large\n",
                         radeon_vm_block_size);
                radeon_vm_block_size = 9;
        }
@@ -1238,7 +1238,7 @@ int radeon_device_init(struct radeon_device *rdev,
        /* Adjust VM size here.
         * Max GPUVM size for cayman+ is 40 bits.
         */
-       rdev->vm_manager.max_pfn = radeon_vm_size << 8;
+       rdev->vm_manager.max_pfn = radeon_vm_size << 18;
 
        /* Set asic functions */
        r = radeon_asic_init(rdev);
index cb1421369e3a2eaa111a8c6d5f3b1e248e72beec..e9e361084249c7deddd0dd680ced4d95a845d31d 100644 (file)
@@ -173,7 +173,7 @@ int radeon_dpm = -1;
 int radeon_aspm = -1;
 int radeon_runtime_pm = -1;
 int radeon_hard_reset = 0;
-int radeon_vm_size = 4096;
+int radeon_vm_size = 4;
 int radeon_vm_block_size = 9;
 int radeon_deep_color = 0;
 
@@ -243,7 +243,7 @@ module_param_named(runpm, radeon_runtime_pm, int, 0444);
 MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))");
 module_param_named(hard_reset, radeon_hard_reset, int, 0444);
 
-MODULE_PARM_DESC(vm_size, "VM address space size in megabytes (default 4GB)");
+MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 4GB)");
 module_param_named(vm_size, radeon_vm_size, int, 0444);
 
 MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default 9)");
index 35d931881b4b80bb5f6989580e993af8796e7041..d25ae6acfd5a05d3bc3ab9775cc3dc604f27554a 100644 (file)
@@ -579,7 +579,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
        /* new gpu have virtual address space support */
        if (rdev->family >= CHIP_CAYMAN) {
                struct radeon_fpriv *fpriv;
-               struct radeon_bo_va *bo_va;
+               struct radeon_vm *vm;
                int r;
 
                fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
@@ -587,7 +587,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
                        return -ENOMEM;
                }
 
-               r = radeon_vm_init(rdev, &fpriv->vm);
+               vm = &fpriv->vm;
+               r = radeon_vm_init(rdev, vm);
                if (r) {
                        kfree(fpriv);
                        return r;
@@ -596,22 +597,23 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
                if (rdev->accel_working) {
                        r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
                        if (r) {
-                               radeon_vm_fini(rdev, &fpriv->vm);
+                               radeon_vm_fini(rdev, vm);
                                kfree(fpriv);
                                return r;
                        }
 
                        /* map the ib pool buffer read only into
                         * virtual address space */
-                       bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
-                                                rdev->ring_tmp_bo.bo);
-                       r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
+                       vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
+                                                       rdev->ring_tmp_bo.bo);
+                       r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
+                                                 RADEON_VA_IB_OFFSET,
                                                  RADEON_VM_PAGE_READABLE |
                                                  RADEON_VM_PAGE_SNOOPED);
 
                        radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
                        if (r) {
-                               radeon_vm_fini(rdev, &fpriv->vm);
+                               radeon_vm_fini(rdev, vm);
                                kfree(fpriv);
                                return r;
                        }
@@ -640,21 +642,19 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
        /* new gpu have virtual address space support */
        if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
                struct radeon_fpriv *fpriv = file_priv->driver_priv;
-               struct radeon_bo_va *bo_va;
+               struct radeon_vm *vm = &fpriv->vm;
                int r;
 
                if (rdev->accel_working) {
                        r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
                        if (!r) {
-                               bo_va = radeon_vm_bo_find(&fpriv->vm,
-                                                         rdev->ring_tmp_bo.bo);
-                               if (bo_va)
-                                       radeon_vm_bo_rmv(rdev, bo_va);
+                               if (vm->ib_bo_va)
+                                       radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
                                radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
                        }
                }
 
-               radeon_vm_fini(rdev, &fpriv->vm);
+               radeon_vm_fini(rdev, vm);
                kfree(fpriv);
                file_priv->driver_priv = NULL;
        }
index eecff6bbd34145c6bf975ca0f2f19ff9af8534ba..725d3669014f8ef2bbd61f637d5e3e98de2772eb 100644 (file)
@@ -332,6 +332,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
        bo_va->ref_count = 1;
        INIT_LIST_HEAD(&bo_va->bo_list);
        INIT_LIST_HEAD(&bo_va->vm_list);
+       INIT_LIST_HEAD(&bo_va->vm_status);
 
        mutex_lock(&vm->mutex);
        list_add(&bo_va->vm_list, &vm->va);
@@ -468,6 +469,19 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
                head = &tmp->vm_list;
        }
 
+       if (bo_va->soffset) {
+               /* add a clone of the bo_va to clear the old address */
+               tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
+               if (!tmp) {
+                       mutex_unlock(&vm->mutex);
+                       return -ENOMEM;
+               }
+               tmp->soffset = bo_va->soffset;
+               tmp->eoffset = bo_va->eoffset;
+               tmp->vm = vm;
+               list_add(&tmp->vm_status, &vm->freed);
+       }
+
        bo_va->soffset = soffset;
        bo_va->eoffset = eoffset;
        bo_va->flags = flags;
@@ -823,25 +837,19 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
  * Object have to be reserved and mutex must be locked!
  */
 int radeon_vm_bo_update(struct radeon_device *rdev,
-                       struct radeon_vm *vm,
-                       struct radeon_bo *bo,
+                       struct radeon_bo_va *bo_va,
                        struct ttm_mem_reg *mem)
 {
+       struct radeon_vm *vm = bo_va->vm;
        struct radeon_ib ib;
-       struct radeon_bo_va *bo_va;
        unsigned nptes, ndw;
        uint64_t addr;
        int r;
 
-       bo_va = radeon_vm_bo_find(vm, bo);
-       if (bo_va == NULL) {
-               dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
-               return -EINVAL;
-       }
 
        if (!bo_va->soffset) {
                dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
-                       bo, vm);
+                       bo_va->bo, vm);
                return -EINVAL;
        }
 
@@ -868,7 +876,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
 
        trace_radeon_vm_bo_update(bo_va);
 
-       nptes = radeon_bo_ngpu_pages(bo);
+       nptes = (bo_va->eoffset - bo_va->soffset) / RADEON_GPU_PAGE_SIZE;
 
        /* padding, etc. */
        ndw = 64;
@@ -910,6 +918,34 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
        return 0;
 }
 
+/**
+ * radeon_vm_clear_freed - clear freed BOs in the PT
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ *
+ * Make sure all freed BOs are cleared in the PT.
+ * Returns 0 for success.
+ *
+ * PTs have to be reserved and mutex must be locked!
+ */
+int radeon_vm_clear_freed(struct radeon_device *rdev,
+                         struct radeon_vm *vm)
+{
+       struct radeon_bo_va *bo_va, *tmp;
+       int r;
+
+       list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
+               list_del(&bo_va->vm_status);
+               r = radeon_vm_bo_update(rdev, bo_va, NULL);
+               kfree(bo_va);
+               if (r)
+                       return r;
+       }
+       return 0;
+
+}
+
 /**
  * radeon_vm_bo_rmv - remove a bo to a specific vm
  *
@@ -917,27 +953,27 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
  * @bo_va: requested bo_va
  *
  * Remove @bo_va->bo from the requested vm (cayman+).
- * Remove @bo_va->bo from the list of bos associated with the bo_va->vm and
- * remove the ptes for @bo_va in the page table.
- * Returns 0 for success.
  *
  * Object have to be reserved!
  */
-int radeon_vm_bo_rmv(struct radeon_device *rdev,
-                    struct radeon_bo_va *bo_va)
+void radeon_vm_bo_rmv(struct radeon_device *rdev,
+                     struct radeon_bo_va *bo_va)
 {
-       int r = 0;
+       struct radeon_vm *vm = bo_va->vm;
 
-       mutex_lock(&bo_va->vm->mutex);
-       if (bo_va->soffset)
-               r = radeon_vm_bo_update(rdev, bo_va->vm, bo_va->bo, NULL);
+       list_del(&bo_va->bo_list);
 
+       mutex_lock(&vm->mutex);
        list_del(&bo_va->vm_list);
-       mutex_unlock(&bo_va->vm->mutex);
-       list_del(&bo_va->bo_list);
 
-       kfree(bo_va);
-       return r;
+       if (bo_va->soffset) {
+               bo_va->bo = NULL;
+               list_add(&bo_va->vm_status, &vm->freed);
+       } else {
+               kfree(bo_va);
+       }
+
+       mutex_unlock(&vm->mutex);
 }
 
 /**
@@ -975,11 +1011,13 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
        int r;
 
        vm->id = 0;
+       vm->ib_bo_va = NULL;
        vm->fence = NULL;
        vm->last_flush = NULL;
        vm->last_id_use = NULL;
        mutex_init(&vm->mutex);
        INIT_LIST_HEAD(&vm->va);
+       INIT_LIST_HEAD(&vm->freed);
 
        pd_size = radeon_vm_directory_size(rdev);
        pd_entries = radeon_vm_num_pdes(rdev);
@@ -1034,7 +1072,8 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
                        kfree(bo_va);
                }
        }
-
+       list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status)
+               kfree(bo_va);
 
        for (i = 0; i < radeon_vm_num_pdes(rdev); i++)
                radeon_bo_unref(&vm->page_tables[i].bo);
index eba0225259a457a3d494f39bfee13af0cdc865e6..9e854fd016dabac99c081896209ce9f732dc34f0 100644 (file)
@@ -6103,6 +6103,7 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
                tmp = RREG32(IH_RB_CNTL);
                tmp |= IH_WPTR_OVERFLOW_CLEAR;
                WREG32(IH_RB_CNTL, tmp);
+               wptr &= ~RB_OVERFLOW;
        }
        return (wptr & rdev->ih.ptr_mask);
 }
index 20da6ff183df9b6fb5b59554616a30f28aeeb96f..32e50be9c4ac1c41969fd9de2d1a6a3439a6ef27 100644 (file)
@@ -1874,15 +1874,16 @@ int trinity_dpm_init(struct radeon_device *rdev)
        for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
                pi->at[i] = TRINITY_AT_DFLT;
 
-       /* There are stability issues reported on latops with
-        * bapm installed when switching between AC and battery
-        * power.  At the same time, some desktop boards hang
-        * if it's not enabled and dpm is enabled.
+       /* There are stability issues reported on with
+        * bapm enabled when switching between AC and battery
+        * power.  At the same time, some MSI boards hang
+        * if it's not enabled and dpm is enabled.  Just enable
+        * it for MSI boards right now.
         */
-       if (rdev->flags & RADEON_IS_MOBILITY)
-               pi->enable_bapm = false;
-       else
+       if (rdev->pdev->subsystem_vendor == 0x1462)
                pi->enable_bapm = true;
+       else
+               pi->enable_bapm = false;
        pi->enable_nbps_policy = true;
        pi->enable_sclk_ds = true;
        pi->enable_gfx_power_gating = true;
index efee4c59239fcff8aa7b675c01cb5b9ac6bab5bd..34b9a601ad078c394513e67a5dccc345c6c02fef 100644 (file)
@@ -86,7 +86,7 @@ static inline u8 IN_TO_REG(unsigned long val, int n)
  */
 static inline s8 TEMP_TO_REG(int val)
 {
-       return clamp_val(SCALE(val, 1, 1000), -128000, 127000);
+       return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
 }
 
 static inline int TEMP_FROM_REG(s8 val)
@@ -384,6 +384,8 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
        err = kstrtoul(buf, 10, &val);
        if (err)
                return err;
+       if (val > 255)
+               return -EINVAL;
 
        data->vrm = val;
        return count;
index 8fb46aab2d87d5bf85ddc2a1b68ca38341bcb058..a04c49f2a0118a887e22c16b9716656af6e87723 100644 (file)
@@ -416,6 +416,7 @@ config BLK_DEV_CY82C693
 
 config BLK_DEV_CS5520
        tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
+       depends on X86_32 || COMPILE_TEST
        select BLK_DEV_IDEDMA_PCI
        help
          Include support for PIO tuning and virtual DMA on the Cyrix MediaGX
@@ -426,6 +427,7 @@ config BLK_DEV_CS5520
 
 config BLK_DEV_CS5530
        tristate "Cyrix/National Semiconductor CS5530 MediaGX chipset support"
+       depends on X86_32 || COMPILE_TEST
        select BLK_DEV_IDEDMA_PCI
        help
          Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
@@ -435,7 +437,7 @@ config BLK_DEV_CS5530
 
 config BLK_DEV_CS5535
        tristate "AMD CS5535 chipset support"
-       depends on X86 && !X86_64
+       depends on X86_32
        select BLK_DEV_IDEDMA_PCI
        help
          Include support for UDMA on the NSC/AMD CS5535 companion chipset.
@@ -486,6 +488,7 @@ config BLK_DEV_JMICRON
 
 config BLK_DEV_SC1200
        tristate "National SCx200 chipset support"
+       depends on X86_32 || COMPILE_TEST
        select BLK_DEV_IDEDMA_PCI
        help
          This driver adds support for the on-board IDE controller on the
index 2a744a91370e640d1fe3603409b80e776d8041de..a3d3b1733c49c667f7f1495d9dfef23623e28fa0 100644 (file)
@@ -853,8 +853,9 @@ static int init_irq (ide_hwif_t *hwif)
        if (irq_handler == NULL)
                irq_handler = ide_intr;
 
-       if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
-               goto out_up;
+       if (!host->get_lock)
+               if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
+                       goto out_up;
 
 #if !defined(__mc68000__)
        printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
@@ -1533,7 +1534,8 @@ static void ide_unregister(ide_hwif_t *hwif)
 
        ide_proc_unregister_port(hwif);
 
-       free_irq(hwif->irq, hwif);
+       if (!hwif->host->get_lock)
+               free_irq(hwif->irq, hwif);
 
        device_unregister(hwif->portdev);
        device_unregister(&hwif->gendev);
index 1c4c0db055509cc45df2e1865a5c0b6d86e25fc9..29ca0bb4f561e6af3960218d027bfd4ac6b300fa 100644 (file)
@@ -257,9 +257,10 @@ static int input_handle_abs_event(struct input_dev *dev,
 }
 
 static int input_get_disposition(struct input_dev *dev,
-                         unsigned int type, unsigned int code, int value)
+                         unsigned int type, unsigned int code, int *pval)
 {
        int disposition = INPUT_IGNORE_EVENT;
+       int value = *pval;
 
        switch (type) {
 
@@ -357,6 +358,7 @@ static int input_get_disposition(struct input_dev *dev,
                break;
        }
 
+       *pval = value;
        return disposition;
 }
 
@@ -365,7 +367,7 @@ static void input_handle_event(struct input_dev *dev,
 {
        int disposition;
 
-       disposition = input_get_disposition(dev, type, code, value);
+       disposition = input_get_disposition(dev, type, code, &value);
 
        if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
                dev->event(dev, type, code, value);
index 758b48731415a26bceff0fdb81ddc08cec0cc2c7..de7be4f03d9193884d248d506b6f75a306dbc17a 100644 (file)
@@ -215,6 +215,7 @@ static int keyscan_probe(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int keyscan_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -249,6 +250,7 @@ static int keyscan_resume(struct device *dev)
        mutex_unlock(&input->mutex);
        return retval;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume);
 
index e4104f9b2e6d7efb34e9e60812fdb154c90342f4..fed5102e1802075b6fd9318c2bd8aad044b317b0 100644 (file)
@@ -213,7 +213,7 @@ static struct platform_driver sirfsoc_pwrc_driver = {
 
 module_platform_driver(sirfsoc_pwrc_driver);
 
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>");
 MODULE_DESCRIPTION("CSR Prima2 PWRC Driver");
 MODULE_ALIAS("platform:sirfsoc-pwrc");
index ec772d962f06800fc92915fa27d51b25fca1e56f..ef9e0b8a9aa754b6b49e26b7b050c2a7bcf1f078 100644 (file)
@@ -132,7 +132,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
                1232, 5710, 1156, 4696
        },
        {
-               (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
+               (const char * const []){"LEN0034", "LEN0036", "LEN2002",
+                                       "LEN2004", NULL},
                1024, 5112, 2024, 4832
        },
        {
@@ -168,7 +169,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
        "LEN0049",
        "LEN2000",
        "LEN2001", /* Edge E431 */
-       "LEN2002",
+       "LEN2002", /* Edge E531 */
        "LEN2003",
        "LEN2004", /* L440 */
        "LEN2005",
index 381b20d4c5618d8fc7f5c3e616479d4663d9ae03..136b7b204f56c8d111812559384d6acd8e732514 100644 (file)
@@ -401,6 +401,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
                },
        },
+       {
+               /* Acer Aspire 5710 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
+               },
+       },
        {
                /* Gericom Bellagio */
                .matches = {
index 977d05cd9e2ea707c08c5eb6d3c9a4fd1a07adae..e73cf2c71f355993c564cee0a05b7cbd34e5f435 100644 (file)
@@ -1217,9 +1217,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
                         * a=(pi*r^2)/C.
                         */
                        int a = data[5];
-                       int x_res  = input_abs_get_res(input, ABS_X);
-                       int y_res  = input_abs_get_res(input, ABS_Y);
-                       width  = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
+                       int x_res = input_abs_get_res(input, ABS_MT_POSITION_X);
+                       int y_res = input_abs_get_res(input, ABS_MT_POSITION_Y);
+                       width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
                        height = width * y_res / x_res;
                }
 
@@ -1587,7 +1587,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev,
                input_abs_set_res(input_dev, ABS_X, features->x_resolution);
                input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
        } else {
-               if (features->touch_max <= 2) {
+               if (features->touch_max == 1) {
                        input_set_abs_params(input_dev, ABS_X, 0,
                                features->x_max, features->x_fuzz, 0);
                        input_set_abs_params(input_dev, ABS_Y, 0,
@@ -1815,14 +1815,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
        case MTTPC:
        case MTTPC_B:
        case TABLETPC2FG:
-               if (features->device_type == BTN_TOOL_FINGER) {
-                       unsigned int flags = INPUT_MT_DIRECT;
-
-                       if (wacom_wac->features.type == TABLETPC2FG)
-                               flags = 0;
-
-                       input_mt_init_slots(input_dev, features->touch_max, flags);
-               }
+               if (features->device_type == BTN_TOOL_FINGER && features->touch_max > 1)
+                       input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT);
                /* fall through */
 
        case TABLETPC:
@@ -1883,10 +1877,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                        __set_bit(BTN_RIGHT, input_dev->keybit);
 
                        if (features->touch_max) {
-                               /* touch interface */
-                               unsigned int flags = INPUT_MT_POINTER;
-
-                               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                                if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
                                        input_set_abs_params(input_dev,
                                                     ABS_MT_TOUCH_MAJOR,
@@ -1894,12 +1884,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                                        input_set_abs_params(input_dev,
                                                     ABS_MT_TOUCH_MINOR,
                                                     0, features->y_max, 0, 0);
-                               } else {
-                                       __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
-                                       __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
-                                       flags = 0;
                                }
-                               input_mt_init_slots(input_dev, features->touch_max, flags);
+                               input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
                        } else {
                                /* buttons/keys only interface */
                                __clear_bit(ABS_X, input_dev->absbit);
index 4e793a17361f7b2e02955e7e6e02ece9151f8063..2ce649520fe0d67021509b7e829cf1dbb9858e19 100644 (file)
@@ -359,9 +359,12 @@ static int titsc_parse_dt(struct platform_device *pdev,
         */
        err = of_property_read_u32(node, "ti,coordinate-readouts",
                        &ts_dev->coordinate_readouts);
-       if (err < 0)
+       if (err < 0) {
+               dev_warn(&pdev->dev, "please use 'ti,coordinate-readouts' instead\n");
                err = of_property_read_u32(node, "ti,coordiante-readouts",
                                &ts_dev->coordinate_readouts);
+       }
+
        if (err < 0)
                return err;
 
index a333b7f798d17de3f4f7bc2a610b7bceaa7c6307..62f0688d45a500530fd65014432be9fbfd5a7d69 100644 (file)
@@ -638,9 +638,15 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
                fprog.len = len;
                fprog.filter = code;
 
-               if (is->pass_filter)
+               if (is->pass_filter) {
                        sk_unattached_filter_destroy(is->pass_filter);
-               err = sk_unattached_filter_create(&is->pass_filter, &fprog);
+                       is->pass_filter = NULL;
+               }
+               if (fprog.filter != NULL)
+                       err = sk_unattached_filter_create(&is->pass_filter,
+                                                         &fprog);
+               else
+                       err = 0;
                kfree(code);
 
                return err;
@@ -657,9 +663,15 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
                fprog.len = len;
                fprog.filter = code;
 
-               if (is->active_filter)
+               if (is->active_filter) {
                        sk_unattached_filter_destroy(is->active_filter);
-               err = sk_unattached_filter_create(&is->active_filter, &fprog);
+                       is->active_filter = NULL;
+               }
+               if (fprog.filter != NULL)
+                       err = sk_unattached_filter_create(&is->active_filter,
+                                                         &fprog);
+               else
+                       err = 0;
                kfree(code);
 
                return err;
index 8637d2ed76238b1c76c95d6b6bf2f994f19a3562..2e3cdcfa0a675b2f8835fde25924d262f6ed6264 100644 (file)
@@ -60,7 +60,7 @@ static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
                                jiffies_to_msecs(jiffies) -
                                (jiffies_to_msecs(timeout) - TIMEOUT));
 
-               if (!(cmd->args[0] >> 7) & 0x01) {
+               if (!((cmd->args[0] >> 7) & 0x01)) {
                        ret = -ETIMEDOUT;
                        goto err_mutex_unlock;
                }
@@ -485,20 +485,6 @@ static int si2168_init(struct dvb_frontend *fe)
        if (ret)
                goto err;
 
-       cmd.args[0] = 0x05;
-       cmd.args[1] = 0x00;
-       cmd.args[2] = 0xaa;
-       cmd.args[3] = 0x4d;
-       cmd.args[4] = 0x56;
-       cmd.args[5] = 0x40;
-       cmd.args[6] = 0x00;
-       cmd.args[7] = 0x00;
-       cmd.wlen = 8;
-       cmd.rlen = 1;
-       ret = si2168_cmd_execute(s, &cmd);
-       if (ret)
-               goto err;
-
        /* cold state - try to download firmware */
        dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
                        KBUILD_MODNAME, si2168_ops.info.name);
index 2a343e896f4038d66f62ba255886a09add151b16..53f7f06ae3437aca8981f8d63f8e6538f7a77978 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/firmware.h>
 #include <linux/i2c-mux.h>
 
-#define SI2168_FIRMWARE "dvb-demod-si2168-01.fw"
+#define SI2168_FIRMWARE "dvb-demod-si2168-02.fw"
 
 /* state struct */
 struct si2168 {
index 522fe00f5eee167f6fa59a657aaad1b4dce55783..9619be5d48271827b28052c080f01fc5631224b7 100644 (file)
@@ -668,6 +668,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
        int ret, i;
        u8 mode, rolloff, pilot, inversion, div;
+       fe_modulation_t modulation;
 
        dev_dbg(&priv->i2c->dev,
                        "%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
@@ -702,10 +703,13 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
 
        switch (c->delivery_system) {
        case SYS_DVBS:
+               modulation = QPSK;
                rolloff = 0;
                pilot = 2;
                break;
        case SYS_DVBS2:
+               modulation = c->modulation;
+
                switch (c->rolloff) {
                case ROLLOFF_20:
                        rolloff = 2;
@@ -750,7 +754,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
 
        for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
                if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
-                       c->modulation == TDA10071_MODCOD[i].modulation &&
+                       modulation == TDA10071_MODCOD[i].modulation &&
                        c->fec_inner == TDA10071_MODCOD[i].fec) {
                        mode = TDA10071_MODCOD[i].val;
                        dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
@@ -834,10 +838,10 @@ static int tda10071_get_frontend(struct dvb_frontend *fe)
 
        switch ((buf[1] >> 0) & 0x01) {
        case 0:
-               c->inversion = INVERSION_OFF;
+               c->inversion = INVERSION_ON;
                break;
        case 1:
-               c->inversion = INVERSION_ON;
+               c->inversion = INVERSION_OFF;
                break;
        }
 
@@ -856,7 +860,7 @@ static int tda10071_get_frontend(struct dvb_frontend *fe)
        if (ret)
                goto error;
 
-       c->symbol_rate = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0);
+       c->symbol_rate = ((buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0)) * 1000;
 
        return ret;
 error:
index 4baf14bfb65a6d6ca4a485861492efcdc955f006..42048619273682089808eb1bffd1690704f7d13a 100644 (file)
@@ -55,6 +55,7 @@ static struct tda10071_modcod {
        { SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
        { SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
        /* 8PSK */
+       { SYS_DVBS2, PSK_8, FEC_AUTO, 0x00 },
        { SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
        { SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
        { SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
index e65c760e4e8bbc5df3da9d4fa970d003d6e0cc66..0006d6bf8c18a5015dea50cbd4e0386802b80bc6 100644 (file)
@@ -179,7 +179,7 @@ static const struct v4l2_file_operations ts_fops =
        .read     = vb2_fop_read,
        .poll     = vb2_fop_poll,
        .mmap     = vb2_fop_mmap,
-       .ioctl    = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops ts_ioctl_ops = {
index a7ed16497903ef171caf128697900aa9700b3915..1e4ec697fb1054c69becb4f4483f228508c2efe7 100644 (file)
@@ -269,6 +269,7 @@ err:
                list_del(&buf->list);
                vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
        }
+       spin_unlock_irqrestore(&common->irqlock, flags);
 
        return ret;
 }
index 5bb085b19bcbdad375ed9bbb52ab13851580127c..b431b58f39e3648d7d33ae6e049f1896ccd3fedc 100644 (file)
@@ -233,6 +233,7 @@ err:
                list_del(&buf->list);
                vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
        }
+       spin_unlock_irqrestore(&common->irqlock, flags);
 
        return ret;
 }
index 271a752cee5415a825fed6af3e2e125d1ebf343a..fa4cc7b880aa4774f4fdf6d7c6cf3ddbb010dbd8 100644 (file)
@@ -57,7 +57,7 @@ static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd)
                        jiffies_to_msecs(jiffies) -
                        (jiffies_to_msecs(timeout) - TIMEOUT));
 
-       if (!(buf[0] >> 7) & 0x01) {
+       if (!((buf[0] >> 7) & 0x01)) {
                ret = -ETIMEDOUT;
                goto err_mutex_unlock;
        } else {
index 021e4d35e4d7d5f65311c13bb70c33df07b40d3f..7b9b75f6077471aea8209f317bbd7a636f8e8b58 100644 (file)
@@ -704,15 +704,41 @@ static int af9035_read_config(struct dvb_usb_device *d)
                if (ret < 0)
                        goto err;
 
-               if (tmp == 0x00)
-                       dev_dbg(&d->udev->dev,
-                                       "%s: [%d]tuner not set, using default\n",
-                                       __func__, i);
-               else
+               dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
+                               __func__, i, tmp);
+
+               /* tuner sanity check */
+               if (state->chip_type == 0x9135) {
+                       if (state->chip_version == 0x02) {
+                               /* IT9135 BX (v2) */
+                               switch (tmp) {
+                               case AF9033_TUNER_IT9135_60:
+                               case AF9033_TUNER_IT9135_61:
+                               case AF9033_TUNER_IT9135_62:
+                                       state->af9033_config[i].tuner = tmp;
+                                       break;
+                               }
+                       } else {
+                               /* IT9135 AX (v1) */
+                               switch (tmp) {
+                               case AF9033_TUNER_IT9135_38:
+                               case AF9033_TUNER_IT9135_51:
+                               case AF9033_TUNER_IT9135_52:
+                                       state->af9033_config[i].tuner = tmp;
+                                       break;
+                               }
+                       }
+               } else {
+                       /* AF9035 */
                        state->af9033_config[i].tuner = tmp;
+               }
 
-               dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
-                               __func__, i, state->af9033_config[i].tuner);
+               if (state->af9033_config[i].tuner != tmp) {
+                       dev_info(&d->udev->dev,
+                                       "%s: [%d] overriding tuner from %02x to %02x\n",
+                                       KBUILD_MODNAME, i, tmp,
+                                       state->af9033_config[i].tuner);
+               }
 
                switch (state->af9033_config[i].tuner) {
                case AF9033_TUNER_TUA9001:
index 2fd1c5e31a0f2692a1d59dd88c72cbee74e61054..339adce7c7a50974ffe9c5a2a185ae26fe8956c6 100644 (file)
@@ -928,6 +928,7 @@ static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x093a, 0x2620)},
        {USB_DEVICE(0x093a, 0x2621)},
        {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
+       {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
        {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
        {USB_DEVICE(0x093a, 0x2625)},
        {USB_DEVICE(0x093a, 0x2626)},
index 0500c4175d5f095d3b27322f298aeb7130ab95e7..6bce01a674f9e12f9874636e962378f6965a4fad 100644 (file)
@@ -82,7 +82,7 @@ static void hdpvr_read_bulk_callback(struct urb *urb)
 }
 
 /*=========================================================================*/
-/* bufffer bits */
+/* buffer bits */
 
 /* function expects dev->io_mutex to be hold by caller */
 int hdpvr_cancel_queue(struct hdpvr_device *dev)
@@ -926,7 +926,7 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
        case V4L2_CID_MPEG_AUDIO_ENCODING:
                if (dev->flags & HDPVR_FLAG_AC3_CAP) {
                        opt->audio_codec = ctrl->val;
-                       return hdpvr_set_audio(dev, opt->audio_input,
+                       return hdpvr_set_audio(dev, opt->audio_input + 1,
                                              opt->audio_codec);
                }
                return 0;
@@ -1198,7 +1198,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
        v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
                V4L2_CID_MPEG_AUDIO_ENCODING,
                ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
-               0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
+               0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
        v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
                V4L2_CID_MPEG_VIDEO_ENCODING,
                V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
index 4ae54caadd0375b786bf50147c6499e892790263..ce1c9f5d9dee1040c43f798b5163c4821feabbfd 100644 (file)
@@ -610,10 +610,10 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
                aspect.denominator = 9;
        } else if (ratio == 34) {
                aspect.numerator = 4;
-               aspect.numerator = 3;
+               aspect.denominator = 3;
        } else if (ratio == 68) {
                aspect.numerator = 15;
-               aspect.numerator = 9;
+               aspect.denominator = 9;
        } else {
                aspect.numerator = hor_landscape + 99;
                aspect.denominator = 100;
index 14c00048bbec66bf85a3d3ef8127e8fa5f2363bf..82322b1c8411b80ff9d15f8c8022a3095f69c4d0 100644 (file)
@@ -129,14 +129,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
                                                  name);
                                }
 
-                               cq->irq_desc =
-                                       irq_to_desc(mlx4_eq_get_irq(mdev->dev,
-                                                                   cq->vector));
                        }
                } else {
                        cq->vector = (cq->ring + 1 + priv->port) %
                                mdev->dev->caps.num_comp_vectors;
                }
+
+               cq->irq_desc =
+                       irq_to_desc(mlx4_eq_get_irq(mdev->dev,
+                                                   cq->vector));
        } else {
                /* For TX we use the same irq per
                ring we assigned for the RX    */
index 06bdc31a828dce2163ca4a8cbd74d9a5cd5e65dd..61623e9af57424b1298c7db02641d78d6154b751 100644 (file)
@@ -4240,6 +4240,8 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
                RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
                break;
        case RTL_GIGA_MAC_VER_40:
+               RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
+               break;
        case RTL_GIGA_MAC_VER_41:
        case RTL_GIGA_MAC_VER_42:
        case RTL_GIGA_MAC_VER_43:
index 1c24a8f368bd86a25835053de21ee6f96df78adb..fd411d6e19a2f4e4d37675f1d27bd011584b8fa0 100644 (file)
@@ -1083,6 +1083,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac)
        return vp;
 }
 
+static void vnet_cleanup(void)
+{
+       struct vnet *vp;
+       struct net_device *dev;
+
+       mutex_lock(&vnet_list_mutex);
+       while (!list_empty(&vnet_list)) {
+               vp = list_first_entry(&vnet_list, struct vnet, list);
+               list_del(&vp->list);
+               dev = vp->dev;
+               /* vio_unregister_driver() should have cleaned up port_list */
+               BUG_ON(!list_empty(&vp->port_list));
+               unregister_netdev(dev);
+               free_netdev(dev);
+       }
+       mutex_unlock(&vnet_list_mutex);
+}
+
 static const char *local_mac_prop = "local-mac-address";
 
 static struct vnet *vnet_find_parent(struct mdesc_handle *hp,
@@ -1240,7 +1258,6 @@ static int vnet_port_remove(struct vio_dev *vdev)
 
                kfree(port);
 
-               unregister_netdev(vp->dev);
        }
        return 0;
 }
@@ -1268,6 +1285,7 @@ static int __init vnet_init(void)
 static void __exit vnet_exit(void)
 {
        vio_unregister_driver(&vnet_port_driver);
+       vnet_cleanup();
 }
 
 module_init(vnet_init);
index e2f20f807de81a5647623d95f868a635c7cba32a..d5b77ef3a2100c3ce42ad75f4e1c9fe981f046e9 100644 (file)
@@ -757,10 +757,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        };
 
                        ppp_lock(ppp);
-                       if (ppp->pass_filter)
+                       if (ppp->pass_filter) {
                                sk_unattached_filter_destroy(ppp->pass_filter);
-                       err = sk_unattached_filter_create(&ppp->pass_filter,
-                                                         &fprog);
+                               ppp->pass_filter = NULL;
+                       }
+                       if (fprog.filter != NULL)
+                               err = sk_unattached_filter_create(&ppp->pass_filter,
+                                                                 &fprog);
+                       else
+                               err = 0;
                        kfree(code);
                        ppp_unlock(ppp);
                }
@@ -778,10 +783,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        };
 
                        ppp_lock(ppp);
-                       if (ppp->active_filter)
+                       if (ppp->active_filter) {
                                sk_unattached_filter_destroy(ppp->active_filter);
-                       err = sk_unattached_filter_create(&ppp->active_filter,
-                                                         &fprog);
+                               ppp->active_filter = NULL;
+                       }
+                       if (fprog.filter != NULL)
+                               err = sk_unattached_filter_create(&ppp->active_filter,
+                                                                 &fprog);
+                       else
+                               err = 0;
                        kfree(code);
                        ppp_unlock(ppp);
                }
index 5d95a13dbe2aa5cb44f6f6ff9f8ab26b47d0c418..735f7dadb9a0740dea86ed58d55df1ae58edf9ef 100644 (file)
@@ -194,6 +194,9 @@ static const struct usb_device_id huawei_cdc_ncm_devs[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76),
          .driver_info = (unsigned long)&huawei_cdc_ncm_info,
        },
+       { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16),
+         .driver_info = (unsigned long)&huawei_cdc_ncm_info,
+       },
 
        /* Terminating entry */
        {
index c4638c67f6b9f8e2a28ae09d12e6fbe74bc735cb..22756db53dcacc3138fd000cad8dbda968948fb8 100644 (file)
@@ -667,6 +667,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
        {QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
        {QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
+       {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
        {QMI_FIXED_INTF(0x12d1, 0x140c, 1)},    /* Huawei E173 */
        {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)},    /* Huawei E1820 */
        {QMI_FIXED_INTF(0x16d8, 0x6003, 0)},    /* CMOTech 6003 */
@@ -757,6 +758,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x9054, 8)},    /* Sierra Wireless Modem */
        {QMI_FIXED_INTF(0x1199, 0x9055, 8)},    /* Netgear AirCard 341U */
        {QMI_FIXED_INTF(0x1199, 0x9056, 8)},    /* Sierra Wireless Modem */
+       {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
        {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
index 5895f19786919f6cfb36b97273a95bc1462d1c10..fa9fdfa128c1e6b732c74907fb43504c8ec2ad4c 100644 (file)
@@ -122,8 +122,12 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
 {
        struct x25_asy *sl = netdev_priv(dev);
        unsigned char *xbuff, *rbuff;
-       int len = 2 * newmtu;
+       int len;
 
+       if (newmtu > 65534)
+               return -EINVAL;
+
+       len = 2 * newmtu;
        xbuff = kmalloc(len + 4, GFP_ATOMIC);
        rbuff = kmalloc(len + 4, GFP_ATOMIC);
 
index 1844a47636b67c821f03fc8a565092ab59749426..c65b636bcab9dfb3bdf3528bd3d0fcd30f7a5812 100644 (file)
@@ -1030,14 +1030,21 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
 {
        struct gnttab_map_grant_ref *gop_map = *gopp_map;
        u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
+       /* This always points to the shinfo of the skb being checked, which
+        * could be either the first or the one on the frag_list
+        */
        struct skb_shared_info *shinfo = skb_shinfo(skb);
+       /* If this is non-NULL, we are currently checking the frag_list skb, and
+        * this points to the shinfo of the first one
+        */
+       struct skb_shared_info *first_shinfo = NULL;
        int nr_frags = shinfo->nr_frags;
+       const bool sharedslot = nr_frags &&
+                               frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
        int i, err;
-       struct sk_buff *first_skb = NULL;
 
        /* Check status of header. */
        err = (*gopp_copy)->status;
-       (*gopp_copy)++;
        if (unlikely(err)) {
                if (net_ratelimit())
                        netdev_dbg(queue->vif->dev,
@@ -1045,8 +1052,12 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
                                   (*gopp_copy)->status,
                                   pending_idx,
                                   (*gopp_copy)->source.u.ref);
-               xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
+               /* The first frag might still have this slot mapped */
+               if (!sharedslot)
+                       xenvif_idx_release(queue, pending_idx,
+                                          XEN_NETIF_RSP_ERROR);
        }
+       (*gopp_copy)++;
 
 check_frags:
        for (i = 0; i < nr_frags; i++, gop_map++) {
@@ -1062,8 +1073,19 @@ check_frags:
                                                pending_idx,
                                                gop_map->handle);
                        /* Had a previous error? Invalidate this fragment. */
-                       if (unlikely(err))
+                       if (unlikely(err)) {
                                xenvif_idx_unmap(queue, pending_idx);
+                               /* If the mapping of the first frag was OK, but
+                                * the header's copy failed, and they are
+                                * sharing a slot, send an error
+                                */
+                               if (i == 0 && sharedslot)
+                                       xenvif_idx_release(queue, pending_idx,
+                                                          XEN_NETIF_RSP_ERROR);
+                               else
+                                       xenvif_idx_release(queue, pending_idx,
+                                                          XEN_NETIF_RSP_OKAY);
+                       }
                        continue;
                }
 
@@ -1075,42 +1097,53 @@ check_frags:
                                   gop_map->status,
                                   pending_idx,
                                   gop_map->ref);
+
                xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
 
                /* Not the first error? Preceding frags already invalidated. */
                if (err)
                        continue;
-               /* First error: invalidate preceding fragments. */
+
+               /* First error: if the header haven't shared a slot with the
+                * first frag, release it as well.
+                */
+               if (!sharedslot)
+                       xenvif_idx_release(queue,
+                                          XENVIF_TX_CB(skb)->pending_idx,
+                                          XEN_NETIF_RSP_OKAY);
+
+               /* Invalidate preceding fragments of this skb. */
                for (j = 0; j < i; j++) {
                        pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
                        xenvif_idx_unmap(queue, pending_idx);
+                       xenvif_idx_release(queue, pending_idx,
+                                          XEN_NETIF_RSP_OKAY);
+               }
+
+               /* And if we found the error while checking the frag_list, unmap
+                * the first skb's frags
+                */
+               if (first_shinfo) {
+                       for (j = 0; j < first_shinfo->nr_frags; j++) {
+                               pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]);
+                               xenvif_idx_unmap(queue, pending_idx);
+                               xenvif_idx_release(queue, pending_idx,
+                                                  XEN_NETIF_RSP_OKAY);
+                       }
                }
 
                /* Remember the error: invalidate all subsequent fragments. */
                err = newerr;
        }
 
-       if (skb_has_frag_list(skb)) {
-               first_skb = skb;
-               skb = shinfo->frag_list;
-               shinfo = skb_shinfo(skb);
+       if (skb_has_frag_list(skb) && !first_shinfo) {
+               first_shinfo = skb_shinfo(skb);
+               shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
                nr_frags = shinfo->nr_frags;
 
                goto check_frags;
        }
 
-       /* There was a mapping error in the frag_list skb. We have to unmap
-        * the first skb's frags
-        */
-       if (first_skb && err) {
-               int j;
-               shinfo = skb_shinfo(first_skb);
-               for (j = 0; j < shinfo->nr_frags; j++) {
-                       pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
-                       xenvif_idx_unmap(queue, pending_idx);
-               }
-       }
-
        *gopp_map = gop_map;
        return err;
 }
@@ -1518,7 +1551,16 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
 
                /* Check the remap error code. */
                if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) {
+                       /* If there was an error, xenvif_tx_check_gop is
+                        * expected to release all the frags which were mapped,
+                        * so kfree_skb shouldn't do it again
+                        */
                        skb_shinfo(skb)->nr_frags = 0;
+                       if (skb_has_frag_list(skb)) {
+                               struct sk_buff *nskb =
+                                               skb_shinfo(skb)->frag_list;
+                               skb_shinfo(nskb)->nr_frags = 0;
+                       }
                        kfree_skb(skb);
                        continue;
                }
@@ -1822,8 +1864,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
                           tx_unmap_op.status);
                BUG();
        }
-
-       xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_OKAY);
 }
 
 static inline int rx_work_todo(struct xenvif_queue *queue)
index 2872ece81f358df7ff139c143e86d58031485b14..44333bd8f90886260e2219acad391dadaa9fd095 100644 (file)
@@ -5,6 +5,12 @@
 # Parport configuration.
 #
 
+config ARCH_MIGHT_HAVE_PC_PARPORT
+       bool
+       help
+         Select this config option from the architecture Kconfig if
+         the architecture might have PC parallel port hardware.
+
 menuconfig PARPORT
        tristate "Parallel port support"
        depends on HAS_IOMEM
@@ -31,12 +37,6 @@ menuconfig PARPORT
 
          If unsure, say Y.
 
-config ARCH_MIGHT_HAVE_PC_PARPORT
-       bool
-       help
-         Select this config option from the architecture Kconfig if
-         the architecture might have PC parallel port hardware.
-
 if PARPORT
 
 config PARPORT_PC
index 602d153c7055b0227416c2d960a1efe4688aa847..70741c8c46a0cae82069ea1eba5ffc8e98a3d834 100644 (file)
@@ -80,8 +80,9 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
                return NULL;
 
        context->refcount = 1;
-       acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL,
-                           acpiphp_post_dock_fixup);
+       context->hp.notify = acpiphp_hotplug_notify;
+       context->hp.fixup = acpiphp_post_dock_fixup;
+       acpi_set_hp_context(adev, &context->hp);
        return context;
 }
 
@@ -369,20 +370,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
        return AE_OK;
 }
 
-static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev)
-{
-       struct acpiphp_bridge *bridge = NULL;
-
-       acpi_lock_hp_context();
-       if (adev->hp) {
-               bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
-               if (bridge)
-                       get_bridge(bridge);
-       }
-       acpi_unlock_hp_context();
-       return bridge;
-}
-
 static void cleanup_bridge(struct acpiphp_bridge *bridge)
 {
        struct acpiphp_slot *slot;
@@ -753,9 +740,15 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
 
 void acpiphp_check_host_bridge(struct acpi_device *adev)
 {
-       struct acpiphp_bridge *bridge;
+       struct acpiphp_bridge *bridge = NULL;
 
-       bridge = acpiphp_dev_to_bridge(adev);
+       acpi_lock_hp_context();
+       if (adev->hp) {
+               bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
+               if (bridge)
+                       get_bridge(bridge);
+       }
+       acpi_unlock_hp_context();
        if (bridge) {
                pci_lock_rescan_remove();
 
@@ -884,7 +877,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
                        goto err;
 
                root_context->root_bridge = bridge;
-               acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL);
+               acpi_set_hp_context(adev, &root_context->hp);
        } else {
                struct acpiphp_context *context;
 
@@ -927,7 +920,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
        kfree(bridge);
 }
 
-void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
+static void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
 {
        if (pci_is_root_bus(bridge->pci_bus)) {
                struct acpiphp_root_context *root_context;
index ca4927ba84334a2b64b09b8b2e9eb60564024f65..37263b0ebfe32570f49a3df7bfc027ab6cd562e0 100644 (file)
 #include "pci.h"
 
 /**
- * pci_acpi_wake_bus - Wake-up notification handler for root buses.
- * @handle: ACPI handle of a device the notification is for.
- * @event: Type of the signaled event.
- * @context: PCI root bus to wake up devices on.
+ * pci_acpi_wake_bus - Root bus wakeup notification fork function.
+ * @work: Work item to handle.
  */
-static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context)
+static void pci_acpi_wake_bus(struct work_struct *work)
 {
-       struct pci_bus *pci_bus = context;
+       struct acpi_device *adev;
+       struct acpi_pci_root *root;
 
-       if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus)
-               pci_pme_wakeup_bus(pci_bus);
+       adev = container_of(work, struct acpi_device, wakeup.context.work);
+       root = acpi_driver_data(adev);
+       pci_pme_wakeup_bus(root->bus);
 }
 
 /**
- * pci_acpi_wake_dev - Wake-up notification handler for PCI devices.
+ * pci_acpi_wake_dev - PCI device wakeup notification work function.
  * @handle: ACPI handle of a device the notification is for.
- * @event: Type of the signaled event.
- * @context: PCI device object to wake up.
+ * @work: Work item to handle.
  */
-static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
+static void pci_acpi_wake_dev(struct work_struct *work)
 {
-       struct pci_dev *pci_dev = context;
+       struct acpi_device_wakeup_context *context;
+       struct pci_dev *pci_dev;
 
-       if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev)
-               return;
+       context = container_of(work, struct acpi_device_wakeup_context, work);
+       pci_dev = to_pci_dev(context->dev);
 
        if (pci_dev->pme_poll)
                pci_dev->pme_poll = false;
@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
 }
 
 /**
- * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus.
- * @dev: ACPI device to add the notifier for.
- * @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
- */
-acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
-                                        struct pci_bus *pci_bus)
-{
-       return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
-}
-
-/**
- * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier.
- * @dev: ACPI device to remove the notifier from.
+ * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus.
+ * @dev: PCI root bridge ACPI device.
  */
-acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
+acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev)
 {
-       return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus);
+       return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus);
 }
 
 /**
@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
 acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
                                     struct pci_dev *pci_dev)
 {
-       return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
-}
-
-/**
- * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier.
- * @dev: ACPI device to remove the notifier from.
- */
-acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
-{
-       return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev);
+       return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev);
 }
 
 phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
@@ -170,14 +150,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
 
 static bool acpi_pci_power_manageable(struct pci_dev *dev)
 {
-       acpi_handle handle = ACPI_HANDLE(&dev->dev);
-
-       return handle ? acpi_bus_power_manageable(handle) : false;
+       struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+       return adev ? acpi_device_power_manageable(adev) : false;
 }
 
 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-       acpi_handle handle = ACPI_HANDLE(&dev->dev);
+       struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
        static const u8 state_conv[] = {
                [PCI_D0] = ACPI_STATE_D0,
                [PCI_D1] = ACPI_STATE_D1,
@@ -188,7 +167,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        int error = -EINVAL;
 
        /* If the ACPI device has _EJ0, ignore the device */
-       if (!handle || acpi_has_method(handle, "_EJ0"))
+       if (!adev || acpi_has_method(adev->handle, "_EJ0"))
                return -ENODEV;
 
        switch (state) {
@@ -202,7 +181,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        case PCI_D1:
        case PCI_D2:
        case PCI_D3hot:
-               error = acpi_bus_set_power(handle, state_conv[state]);
+               error = acpi_device_set_power(adev, state_conv[state]);
        }
 
        if (!error)
@@ -214,9 +193,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 
 static bool acpi_pci_can_wakeup(struct pci_dev *dev)
 {
-       acpi_handle handle = ACPI_HANDLE(&dev->dev);
-
-       return handle ? acpi_bus_can_wakeup(handle) : false;
+       struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+       return adev ? acpi_device_can_wakeup(adev) : false;
 }
 
 static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
index 1bd6363bc95ef2b0d0bd2b58d733159941c78fa0..9f43916637ca251372fb57efc32bdd82dde4eef1 100644 (file)
@@ -1431,7 +1431,7 @@ static void st_gpio_irqmux_handler(unsigned irq, struct irq_desc *desc)
 
        status = readl(info->irqmux_base);
 
-       for_each_set_bit(n, &status, ST_GPIO_PINS_PER_BANK)
+       for_each_set_bit(n, &status, info->nbanks)
                __gpio_irq_handler(&info->banks[n]);
 
        chained_irq_exit(chip, desc);
index b81448b2c75da0c8c5d1803f3af64053f834e040..d2b780aade895e2baf44a7960f064025f7063dc6 100644 (file)
@@ -67,8 +67,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
 
        pnp_dbg(&dev->dev, "set resources\n");
 
-       handle = ACPI_HANDLE(&dev->dev);
-       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+       acpi_dev = ACPI_COMPANION(&dev->dev);
+       if (!acpi_dev) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return -ENODEV;
        }
@@ -76,6 +76,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
        if (WARN_ON_ONCE(acpi_dev != dev->data))
                dev->data = acpi_dev;
 
+       handle = acpi_dev->handle;
        if (acpi_has_method(handle, METHOD_NAME__SRS)) {
                struct acpi_buffer buffer;
 
@@ -93,8 +94,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
                }
                kfree(buffer.pointer);
        }
-       if (!ret && acpi_bus_power_manageable(handle))
-               ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
+       if (!ret && acpi_device_power_manageable(acpi_dev))
+               ret = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);
 
        return ret;
 }
@@ -102,23 +103,22 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
 static int pnpacpi_disable_resources(struct pnp_dev *dev)
 {
        struct acpi_device *acpi_dev;
-       acpi_handle handle;
        acpi_status status;
 
        dev_dbg(&dev->dev, "disable resources\n");
 
-       handle = ACPI_HANDLE(&dev->dev);
-       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+       acpi_dev = ACPI_COMPANION(&dev->dev);
+       if (!acpi_dev) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return 0;
        }
 
        /* acpi_unregister_gsi(pnp_irq(dev, 0)); */
-       if (acpi_bus_power_manageable(handle))
-               acpi_bus_set_power(handle, ACPI_STATE_D3_COLD);
+       if (acpi_device_power_manageable(acpi_dev))
+               acpi_device_set_power(acpi_dev, ACPI_STATE_D3_COLD);
 
-       /* continue even if acpi_bus_set_power() fails */
-       status = acpi_evaluate_object(handle, "_DIS", NULL, NULL);
+       /* continue even if acpi_device_set_power() fails */
+       status = acpi_evaluate_object(acpi_dev->handle, "_DIS", NULL, NULL);
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
                return -ENODEV;
 
@@ -128,26 +128,22 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
 #ifdef CONFIG_ACPI_SLEEP
 static bool pnpacpi_can_wakeup(struct pnp_dev *dev)
 {
-       struct acpi_device *acpi_dev;
-       acpi_handle handle;
+       struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
 
-       handle = ACPI_HANDLE(&dev->dev);
-       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+       if (!acpi_dev) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return false;
        }
 
-       return acpi_bus_can_wakeup(handle);
+       return acpi_bus_can_wakeup(acpi_dev->handle);
 }
 
 static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
 {
-       struct acpi_device *acpi_dev;
-       acpi_handle handle;
+       struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
        int error = 0;
 
-       handle = ACPI_HANDLE(&dev->dev);
-       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+       if (!acpi_dev) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return 0;
        }
@@ -159,7 +155,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
                        return error;
        }
 
-       if (acpi_bus_power_manageable(handle)) {
+       if (acpi_device_power_manageable(acpi_dev)) {
                int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL,
                                                        ACPI_STATE_D3_COLD);
                if (power_state < 0)
@@ -167,12 +163,12 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
                                        ACPI_STATE_D0 : ACPI_STATE_D3_COLD;
 
                /*
-                * acpi_bus_set_power() often fails (keyboard port can't be
+                * acpi_device_set_power() can fail (keyboard port can't be
                 * powered-down?), and in any case, our return value is ignored
                 * by pnp_bus_suspend().  Hence we don't revert the wakeup
                 * setting if the set_power fails.
                 */
-               error = acpi_bus_set_power(handle, power_state);
+               error = acpi_device_set_power(acpi_dev, power_state);
        }
 
        return error;
@@ -180,11 +176,10 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
 
 static int pnpacpi_resume(struct pnp_dev *dev)
 {
-       struct acpi_device *acpi_dev;
-       acpi_handle handle = ACPI_HANDLE(&dev->dev);
+       struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
        int error = 0;
 
-       if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+       if (!acpi_dev) {
                dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
                return -ENODEV;
        }
@@ -192,8 +187,8 @@ static int pnpacpi_resume(struct pnp_dev *dev)
        if (device_may_wakeup(&dev->dev))
                acpi_pm_device_sleep_wake(&dev->dev, false);
 
-       if (acpi_bus_power_manageable(handle))
-               error = acpi_bus_set_power(handle, ACPI_STATE_D0);
+       if (acpi_device_power_manageable(acpi_dev))
+               error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);
 
        return error;
 }
@@ -295,9 +290,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
                return error;
        }
 
+       error = acpi_bind_one(&dev->dev, device);
+
        num++;
 
-       return 0;
+       return error;
 }
 
 static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
@@ -313,41 +310,6 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
        return AE_OK;
 }
 
-static int __init acpi_pnp_match(struct device *dev, void *_pnp)
-{
-       struct acpi_device *acpi = to_acpi_device(dev);
-       struct pnp_dev *pnp = _pnp;
-
-       /* true means it matched */
-       return !acpi->physical_node_count
-           && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
-}
-
-static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev)
-{
-       dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev),
-                             acpi_pnp_match);
-       if (!dev)
-               return NULL;
-
-       put_device(dev);
-       return to_acpi_device(dev);
-}
-
-/* complete initialization of a PNPACPI device includes having
- * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
- */
-static bool acpi_pnp_bus_match(struct device *dev)
-{
-       return dev->bus == &pnp_bus_type;
-}
-
-static struct acpi_bus_type __initdata acpi_pnp_bus = {
-       .name        = "PNP",
-       .match       = acpi_pnp_bus_match,
-       .find_companion = acpi_pnp_find_companion,
-};
-
 int pnpacpi_disabled __initdata;
 static int __init pnpacpi_init(void)
 {
@@ -357,10 +319,8 @@ static int __init pnpacpi_init(void)
        }
        printk(KERN_INFO "pnp: PnP ACPI init\n");
        pnp_register_protocol(&pnpacpi_protocol);
-       register_acpi_bus_type(&acpi_pnp_bus);
        acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
        printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num);
-       unregister_acpi_bus_type(&acpi_pnp_bus);
        pnp_platform_devices = 1;
        return 0;
 }
index 15b3459f86562d2211dde73e507197bbea04b50e..220acb4cbee520c6cfed5c78fdf49fb776f6bf99 100644 (file)
@@ -633,7 +633,6 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
        } else
                raw3270_writesf_readpart(rp);
        memset(&rp->init_reset, 0, sizeof(rp->init_reset));
-       memset(&rp->init_data, 0, sizeof(rp->init_data));
 }
 
 static int
index 69ef4f8cfac8c14366c9803eec4ed6877accf786..4038437ff033f892d30c746056bbb16d12e40c5a 100644 (file)
@@ -901,10 +901,15 @@ static int ap_device_probe(struct device *dev)
        int rc;
 
        ap_dev->drv = ap_drv;
+
+       spin_lock_bh(&ap_device_list_lock);
+       list_add(&ap_dev->list, &ap_device_list);
+       spin_unlock_bh(&ap_device_list_lock);
+
        rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
-       if (!rc) {
+       if (rc) {
                spin_lock_bh(&ap_device_list_lock);
-               list_add(&ap_dev->list, &ap_device_list);
+               list_del_init(&ap_dev->list);
                spin_unlock_bh(&ap_device_list_lock);
        }
        return rc;
index 78b0fba7047e98d37ef4025690346bd93936d3fa..8afc6fee40c547ccca5f5c106e651c3fbfce9942 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_OMAP4
        bool "OMAP 4 Camera support"
-       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C && ARCH_OMAP4
+       depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4
        select VIDEOBUF2_DMA_CONTIG
        ---help---
          Driver for an OMAP 4 ISS controller.
index 0b2528fb640e77e4a38a351c51f8a01f12102c14..a93f7e6ea4cf935aea64e8266b221a2c53477628 100644 (file)
@@ -306,7 +306,7 @@ static int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
        if (unlikely(nr < 0))
                return nr;
 
-       tsk->flags = PF_DUMPCORE;
+       tsk->flags |= PF_DUMPCORE;
        if (atomic_read(&mm->mm_users) == nr + 1)
                goto done;
        /*
index 98040ba388ac1e2db62f96f253bc141758013b10..194d0d122cae566b8e82c1a1bd3188499a467796 100644 (file)
@@ -198,9 +198,8 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio)
  * L1 cache.
  */
 static inline struct page *dio_get_page(struct dio *dio,
-               struct dio_submit *sdio, size_t *from, size_t *to)
+                                       struct dio_submit *sdio)
 {
-       int n;
        if (dio_pages_present(sdio) == 0) {
                int ret;
 
@@ -209,10 +208,7 @@ static inline struct page *dio_get_page(struct dio *dio,
                        return ERR_PTR(ret);
                BUG_ON(dio_pages_present(sdio) == 0);
        }
-       n = sdio->head++;
-       *from = n ? 0 : sdio->from;
-       *to = (n == sdio->tail - 1) ? sdio->to : PAGE_SIZE;
-       return dio->pages[n];
+       return dio->pages[sdio->head];
 }
 
 /**
@@ -911,11 +907,15 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio,
        while (sdio->block_in_file < sdio->final_block_in_request) {
                struct page *page;
                size_t from, to;
-               page = dio_get_page(dio, sdio, &from, &to);
+
+               page = dio_get_page(dio, sdio);
                if (IS_ERR(page)) {
                        ret = PTR_ERR(page);
                        goto out;
                }
+               from = sdio->head ? 0 : sdio->from;
+               to = (sdio->head == sdio->tail - 1) ? sdio->to : PAGE_SIZE;
+               sdio->head++;
 
                while (from < to) {
                        unsigned this_chunk_bytes;      /* # of bytes mapped */
index 8474028d7848064912b34df229b893c39f6144e9..03246cd9d47a7b27d93ce0c2a122cae89d5fbd4f 100644 (file)
@@ -907,9 +907,6 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->writeback_cache = 1;
                        if (arg->time_gran && arg->time_gran <= 1000000000)
                                fc->sb->s_time_gran = arg->time_gran;
-                       else
-                               fc->sb->s_time_gran = 1000000000;
-
                } else {
                        ra_pages = fc->max_read / PAGE_CACHE_SIZE;
                        fc->no_lock = 1;
@@ -938,7 +935,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
                FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
                FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
                FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
-               FUSE_WRITEBACK_CACHE;
+               FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT;
        req->in.h.opcode = FUSE_INIT;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(*arg);
index 985c6f3684859e17439d62c7d319611305414437..9eb787e5c167fb601845590f0181d249bf515fb0 100644 (file)
@@ -2256,9 +2256,10 @@ done:
                goto out;
        }
        path->dentry = dentry;
-       path->mnt = mntget(nd->path.mnt);
+       path->mnt = nd->path.mnt;
        if (should_follow_link(dentry, nd->flags & LOOKUP_FOLLOW))
                return 1;
+       mntget(path->mnt);
        follow_mount(path);
        error = 0;
 out:
index b56b1cc0271853b566f83f4157eaa753fd8ad2e3..944275c8f56ddf79ec457f7ad5d916f6ad7c5982 100644 (file)
@@ -2879,6 +2879,7 @@ again:
                 * return the conflicting open:
                 */
                if (conf->len) {
+                       kfree(conf->data);
                        conf->len = 0;
                        conf->data = NULL;
                        goto again;
@@ -2891,6 +2892,7 @@ again:
        if (conf->len) {
                p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
                p = xdr_encode_opaque(p, conf->data, conf->len);
+               kfree(conf->data);
        }  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
                p = xdr_encode_hyper(p, (u64)0); /* clientid */
                *p++ = cpu_to_be32(0); /* length of owner name */
@@ -2907,7 +2909,7 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
                nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
        else if (nfserr == nfserr_denied)
                nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
-       kfree(lock->lk_denied.ld_owner.data);
+
        return nfserr;
 }
 
index 3377dff184042044547d42e9b123944a0ad7e96a..c69e6d43a0d2e863c3e2d6680731371e0d7ef284 100644 (file)
@@ -843,7 +843,7 @@ struct simple_xattr *simple_xattr_alloc(const void *value, size_t size)
 
        /* wrap around? */
        len = sizeof(*new_xattr) + size;
-       if (len <= sizeof(*new_xattr))
+       if (len < sizeof(*new_xattr))
                return NULL;
 
        new_xattr = kmalloc(len, GFP_KERNEL);
index b5714580801a54ac2c1c10ae2dcc2a0329042ed7..bcfd808b1098e81e410310e33582d814274188b8 100644 (file)
@@ -315,12 +315,19 @@ struct acpi_device_wakeup_flags {
        u8 notifier_present:1;  /* Wake-up notify handler has been installed */
 };
 
+struct acpi_device_wakeup_context {
+       struct work_struct work;
+       struct device *dev;
+};
+
 struct acpi_device_wakeup {
        acpi_handle gpe_device;
        u64 gpe_number;
        u64 sleep_state;
        struct list_head resources;
        struct acpi_device_wakeup_flags flags;
+       struct acpi_device_wakeup_context context;
+       struct wakeup_source *ws;
        int prepare_count;
 };
 
@@ -372,15 +379,9 @@ static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
 }
 
 static inline void acpi_set_hp_context(struct acpi_device *adev,
-                                      struct acpi_hotplug_context *hp,
-                                      int (*notify)(struct acpi_device *, u32),
-                                      void (*uevent)(struct acpi_device *, u32),
-                                      void (*fixup)(struct acpi_device *))
+                                      struct acpi_hotplug_context *hp)
 {
        hp->self = adev;
-       hp->notify = notify;
-       hp->uevent = uevent;
-       hp->fixup = fixup;
        adev->hp = hp;
 }
 
@@ -487,6 +488,8 @@ struct acpi_bus_type {
 };
 int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
+int acpi_bind_one(struct device *dev, struct acpi_device *adev);
+int acpi_unbind_one(struct device *dev);
 
 struct acpi_pci_root {
        struct acpi_device * device;
@@ -510,20 +513,18 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
 int acpi_disable_wakeup_device_power(struct acpi_device *dev);
 
 #ifdef CONFIG_PM
-acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
-                                acpi_notify_handler handler, void *context);
-acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
-                                   acpi_notify_handler handler);
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
+                                void (*work_func)(struct work_struct *work));
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
 #else
 static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
-                                              acpi_notify_handler handler,
-                                              void *context)
+                                              struct device *dev,
+                                              void (*work_func)(struct work_struct *work))
 {
        return AE_SUPPORT;
 }
-static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
-                                                 acpi_notify_handler handler)
+static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
 {
        return AE_SUPPORT;
 }
@@ -538,13 +539,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 #endif
 
 #ifdef CONFIG_PM_RUNTIME
-int __acpi_device_run_wake(struct acpi_device *, bool);
 int acpi_pm_device_run_wake(struct device *, bool);
 #else
-static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en)
-{
-       return -ENODEV;
-}
 static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
 {
        return -ENODEV;
@@ -552,14 +548,8 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
 int acpi_pm_device_sleep_wake(struct device *, bool);
 #else
-static inline int __acpi_device_sleep_wake(struct acpi_device *adev,
-                                          u32 target_state, bool enable)
-{
-       return -ENODEV;
-}
 static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 {
        return -ENODEV;
index f6f5f8af211245571f2c2bd38415afe7e988eb94..03b3e6d405ffdb7b538cab4d967040fedde4fbef 100644 (file)
@@ -399,4 +399,35 @@ char *acpi_os_get_next_filename(void *dir_handle);
 void acpi_os_close_directory(void *dir_handle);
 #endif
 
+/*
+ * File I/O and related support
+ */
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_open_file
+ACPI_FILE acpi_os_open_file(const char *path, u8 modes);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_file
+void acpi_os_close_file(ACPI_FILE file);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_read_file
+int
+acpi_os_read_file(ACPI_FILE file,
+                 void *buffer, acpi_size size, acpi_size count);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_write_file
+int
+acpi_os_write_file(ACPI_FILE file,
+                  void *buffer, acpi_size size, acpi_size count);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_file_offset
+long acpi_os_get_file_offset(ACPI_FILE file);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_set_file_offset
+acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from);
+#endif
+
 #endif                         /* __ACPIOSXF_H__ */
index 35b525c197114292423cbd76dd030e90a115e91d..c3f38bc459e1d155cfc6cdc5db7df5d92984c23c 100644 (file)
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20140424
+#define ACPI_CA_VERSION                 0x20140627
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
 #include <acpi/actbl.h>
 #include <acpi/acbuffer.h>
 
-extern u8 acpi_gbl_permanent_mmap;
-
 /*****************************************************************************
  *
  * Macros used for ACPICA globals and configuration
@@ -335,6 +333,23 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
 
 #endif                         /* ACPI_DEBUG_OUTPUT */
 
+/*
+ * Application prototypes
+ *
+ * All interfaces used by application will be configured
+ * out of the ACPICA build unless the ACPI_APPLICATION
+ * flag is defined.
+ */
+#ifdef ACPI_APPLICATION
+#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \
+       prototype;
+
+#else
+#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \
+       static ACPI_INLINE prototype {return;}
+
+#endif                         /* ACPI_APPLICATION */
+
 /*****************************************************************************
  *
  * ACPICA public interface prototypes
@@ -657,6 +672,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_finish_gpe(acpi_handle gpe_device,
                                                u32 gpe_number))
 
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+                               acpi_mark_gpe_for_wake(acpi_handle gpe_device,
+                                                      u32 gpe_number))
+
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_setup_gpe_for_wake(acpi_handle
                                                        parent_device,
@@ -861,21 +880,32 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6)
                                                     const char *module_name,
                                                     u32 component_id,
                                                     const char *format, ...))
+ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1)
+                               void ACPI_INTERNAL_VAR_XFACE
+                               acpi_log_error(const char *format, ...))
 
 /*
  * Divergences
  */
-acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type);
+ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap);
 
-acpi_status acpi_unload_table_id(acpi_owner_id id);
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+                           acpi_get_id(acpi_handle object,
+                                       acpi_owner_id * out_type))
 
-acpi_status
-acpi_get_table_with_size(acpi_string signature,
-              u32 instance, struct acpi_table_header **out_table,
-              acpi_size *tbl_size);
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_unload_table_id(acpi_owner_id id))
 
-acpi_status
-acpi_get_data_full(acpi_handle object, acpi_object_handler handler, void **data,
-                  void (*callback)(void *));
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+                           acpi_get_table_with_size(acpi_string signature,
+                                                    u32 instance,
+                                                    struct acpi_table_header
+                                                    **out_table,
+                                                    acpi_size *tbl_size))
+
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+                           acpi_get_data_full(acpi_handle object,
+                                              acpi_object_handler handler,
+                                              void **data,
+                                              void (*callback)(void *)))
 
 #endif                         /* __ACXFACE_H__ */
index 4ad7da8051802a835acc9bd9ab6c8c27516a57a8..9613e8e9796040473d8e28ddf654a815d44fbcfe 100644 (file)
@@ -604,7 +604,7 @@ struct acpi_hest_generic {
 
 /* Generic Error Status block */
 
-struct acpi_generic_status {
+struct acpi_hest_generic_status {
        u32 block_status;
        u32 raw_data_offset;
        u32 raw_data_length;
@@ -614,15 +614,15 @@ struct acpi_generic_status {
 
 /* Values for block_status flags above */
 
-#define ACPI_GEN_ERR_UC                        BIT(0)
-#define ACPI_GEN_ERR_CE                        BIT(1)
-#define ACPI_GEN_ERR_MULTI_UC          BIT(2)
-#define ACPI_GEN_ERR_MULTI_CE          BIT(3)
-#define ACPI_GEN_ERR_COUNT_SHIFT       (0xFF<<4) /* 8 bits, error count */
+#define ACPI_HEST_UNCORRECTABLE             (1)
+#define ACPI_HEST_CORRECTABLE               (1<<1)
+#define ACPI_HEST_MULTIPLE_UNCORRECTABLE    (1<<2)
+#define ACPI_HEST_MULTIPLE_CORRECTABLE      (1<<3)
+#define ACPI_HEST_ERROR_ENTRY_COUNT         (0xFF<<4)  /* 8 bits, error count */
 
 /* Generic Error Data entry */
 
-struct acpi_generic_data {
+struct acpi_hest_generic_data {
        u8 section_type[16];
        u32 error_severity;
        u16 revision;
index 860e5c883eb3cddc9b876a11437b97894d582fee..21314d37cb079415f0b900bb63cfc5d2e224d3bc 100644 (file)
@@ -516,7 +516,7 @@ struct acpi_dmar_andd {
        struct acpi_dmar_header header;
        u8 reserved[3];
        u8 device_number;
-       u8 object_name[];
+       char object_name[1];
 };
 
 /*******************************************************************************
index 19b26bb69a70b6025d305048b48fb7547a51ea2c..608a04019372e56f59aeab4a323abe216bfce875 100644 (file)
 typedef unsigned char u8;
 typedef unsigned char u8;
 typedef unsigned short u16;
+typedef short s16;
 typedef COMPILER_DEPENDENT_UINT64 u64;
 typedef COMPILER_DEPENDENT_INT64 s64;
 
@@ -1244,4 +1245,17 @@ struct acpi_memory_list {
 #define ACPI_OSI_WIN_7                  0x0B
 #define ACPI_OSI_WIN_8                  0x0C
 
+/* Definitions of file IO */
+
+#define ACPI_FILE_READING               0x01
+#define ACPI_FILE_WRITING               0x02
+#define ACPI_FILE_BINARY                0x04
+
+#define ACPI_FILE_BEGIN                 0x01
+#define ACPI_FILE_END                   0x02
+
+/* Definitions of getopt */
+
+#define ACPI_OPT_END                    -1
+
 #endif                         /* __ACTYPES_H__ */
index dfd60d0bfd2783ec8d93e53c9134c48d5b690bde..720446cb243e81f07a02a8763eea0994ce43e772 100644 (file)
@@ -14,7 +14,7 @@
 
 struct ghes {
        struct acpi_hest_generic *generic;
-       struct acpi_generic_status *estatus;
+       struct acpi_hest_generic_status *estatus;
        u64 buffer_paddr;
        unsigned long flags;
        union {
index e863dd5c4e0417411754910c334ee870d8bd8ad7..5f8cc1fa3278b071c2f733e8f62b44cd10fac2bb 100644 (file)
 #define ACPI_DBG_TRACK_ALLOCATIONS
 #endif
 
-/* acpi_names configuration. Single threaded with debugger output enabled. */
-
-#ifdef ACPI_NAMES_APP
-#define ACPI_DEBUGGER
-#define ACPI_APPLICATION
-#define ACPI_SINGLE_THREADED
-#endif
-
 /*
- * acpi_bin/acpi_dump/acpi_src/acpi_xtract/Example configuration. All single
- * threaded, with no debug output.
+ * acpi_bin/acpi_dump/acpi_help/acpi_names/acpi_src/acpi_xtract/Example configuration.
+ * All single threaded.
  */
 #if (defined ACPI_BIN_APP)      || \
        (defined ACPI_DUMP_APP)     || \
+       (defined ACPI_HELP_APP)     || \
+       (defined ACPI_NAMES_APP)    || \
        (defined ACPI_SRC_APP)      || \
        (defined ACPI_XTRACT_APP)   || \
        (defined ACPI_EXAMPLE_APP)
 #define ACPI_SINGLE_THREADED
 #endif
 
+/* acpi_help configuration. Error messages disabled. */
+
 #ifdef ACPI_HELP_APP
-#define ACPI_APPLICATION
-#define ACPI_SINGLE_THREADED
 #define ACPI_NO_ERROR_MESSAGES
 #endif
 
+/* acpi_names configuration. Debug output enabled. */
+
+#ifdef ACPI_NAMES_APP
+#define ACPI_DEBUG_OUTPUT
+#endif
+
+/* acpi_exec/acpi_names/Example configuration. Native RSDP used. */
+
+#if (defined ACPI_EXEC_APP)     || \
+       (defined ACPI_EXAMPLE_APP)  || \
+       (defined ACPI_NAMES_APP)
+#define ACPI_USE_NATIVE_RSDP_POINTER
+#endif
+
+/* acpi_dump configuration. Native mapping used if provied by OSPMs */
+
+#ifdef ACPI_DUMP_APP
+#define ACPI_USE_NATIVE_MEMORY_MAPPING
+#define USE_NATIVE_ALLOCATE_ZEROED
+#endif
+
+/* acpi_names/Example configuration. Hardware disabled */
+
+#if (defined ACPI_EXAMPLE_APP)  || \
+       (defined ACPI_NAMES_APP)
+#define ACPI_REDUCED_HARDWARE 1
+#endif
+
 /* Linkable ACPICA library */
 
 #ifdef ACPI_LIBRARY
 #elif defined(_AED_EFI)
 #include "acefi.h"
 
+#elif defined(_GNU_EFI)
+#include "acefi.h"
+
 #elif defined(__HAIKU__)
 #include "achaiku.h"
 
@@ -399,8 +424,12 @@ typedef char *va_list;
 #ifdef ACPI_APPLICATION
 #include <stdio.h>
 #define ACPI_FILE              FILE *
+#define ACPI_FILE_OUT          stdout
+#define ACPI_FILE_ERR          stderr
 #else
 #define ACPI_FILE              void *
+#define ACPI_FILE_OUT          NULL
+#define ACPI_FILE_ERR          NULL
 #endif                         /* ACPI_APPLICATION */
 #endif                         /* ACPI_FILE */
 
index cd1f052d55bb439175c5eb9624c38891b6cf3a0a..1ba7c190c2ccbfc22ca9f576a0f7faf9ef96d979 100644 (file)
 #ifndef __ACLINUX_H__
 #define __ACLINUX_H__
 
+#ifdef __KERNEL__
+
+/* ACPICA external files should not include ACPICA headers directly. */
+
+#if !defined(BUILDING_ACPICA) && !defined(_LINUX_ACPI_H)
+#error "Please don't include <acpi/acpi.h> directly, include <linux/acpi.h> instead."
+#endif
+
+#endif
+
 /* Common (in-kernel/user-space) ACPICA configuration */
 
 #define ACPI_USE_SYSTEM_CLIBRARY
@@ -70,7 +80,9 @@
 #ifdef EXPORT_ACPI_INTERFACES
 #include <linux/export.h>
 #endif
+#ifdef CONFIG_ACPI
 #include <asm/acenv.h>
+#endif
 
 #ifndef CONFIG_ACPI
 
index 191e741cfa0ed017bd0ec845152e814a15c0ba08..568d4b886712ddd8aae8ba244878d1ca38e30b65 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef ACPI_USE_NATIVE_DIVIDE
+
+#ifndef ACPI_DIV_64_BY_32
+#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \
+       do { \
+               u64 (__n) = ((u64) n_hi) << 32 | (n_lo); \
+               (r32) = do_div ((__n), (d32)); \
+               (q32) = (u32) (__n); \
+       } while (0)
+#endif
+
+#ifndef ACPI_SHIFT_RIGHT_64
+#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \
+       do { \
+               (n_lo) >>= 1; \
+               (n_lo) |= (((n_hi) & 1) << 31); \
+               (n_hi) >>= 1; \
+       } while (0)
+#endif
+
+#endif
+
 /*
  * Overrides for in-kernel ACPICA
  */
index 358c01b971db937c3f0da1ab4326d5fcab44d191..5320153c311ba1e5e5a4765f84d9f264351cc365 100644 (file)
 #include <linux/ioport.h>      /* for struct resource */
 #include <linux/device.h>
 
-#ifdef CONFIG_ACPI
-
 #ifndef _LINUX
 #define _LINUX
 #endif
+#include <acpi/acpi.h>
+
+#ifdef CONFIG_ACPI
 
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
 #include <linux/dynamic_debug.h>
 
-#include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_numa.h>
index 8f8ae95c6e279fed83180d319a26d725f628dbd2..7d1955afa62c7c319b4467bd98139f270ed004e4 100644 (file)
@@ -176,6 +176,7 @@ static inline void disable_cpufreq(void) { }
 
 #define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
 #define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
+#define CPUFREQ_RELATION_C 2  /* closest frequency to target */
 
 struct freq_attr {
        struct attribute attr;
index 5ab4e3a76721760e4d5a70f88de282a687858990..92abb497ab14bb50142652ead5dcf3f630556e3f 100644 (file)
@@ -593,6 +593,7 @@ struct ata_host {
        struct device           *dev;
        void __iomem * const    *iomap;
        unsigned int            n_ports;
+       unsigned int            n_tags;                 /* nr of NCQ tags */
        void                    *private_data;
        struct ata_port_operations *ops;
        unsigned long           flags;
index 0a97b583ee8d12ae696cd3d33a13ee17c62b518f..e1474ae18c8847cba4a2f17c396c6e7b59167fed 100644 (file)
@@ -398,6 +398,18 @@ static inline struct page *read_mapping_page(struct address_space *mapping,
        return read_cache_page(mapping, index, filler, data);
 }
 
+/*
+ * Get the offset in PAGE_SIZE.
+ * (TODO: hugepage should have ->index in PAGE_SIZE)
+ */
+static inline pgoff_t page_to_pgoff(struct page *page)
+{
+       if (unlikely(PageHeadHuge(page)))
+               return page->index << compound_order(page);
+       else
+               return page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+}
+
 /*
  * Return byte-offset into filesystem object for page.
  */
index 637a608ded0b0091503db1ac4aaa04cf7155823c..64dacb7288a6fc79e86ca536753f342a37252949 100644 (file)
 #include <linux/acpi.h>
 
 #ifdef CONFIG_ACPI
-extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
-                                                struct pci_bus *pci_bus);
-extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev);
+extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev);
+static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
+{
+       return acpi_remove_pm_notifier(dev);
+}
 extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
                                             struct pci_dev *pci_dev);
-extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev);
+static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
+{
+       return acpi_remove_pm_notifier(dev);
+}
 extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
 
 static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
index 43fd6716f66207bc824b94f1fdbfb44bc37d3534..367f49b9a1c93e5f48ede4b0b97d09ce4f73ce3e 100644 (file)
 #define RPM_AUTO               0x08    /* Use autosuspend_delay */
 
 #ifdef CONFIG_PM
+extern struct workqueue_struct *pm_wq;
+
+static inline bool queue_pm_work(struct work_struct *work)
+{
+       return queue_work(pm_wq, work);
+}
+
 extern int pm_generic_runtime_suspend(struct device *dev);
 extern int pm_generic_runtime_resume(struct device *dev);
 extern int pm_runtime_force_suspend(struct device *dev);
 extern int pm_runtime_force_resume(struct device *dev);
 #else
+static inline bool queue_pm_work(struct work_struct *work) { return false; }
+
 static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
 static inline int pm_runtime_force_suspend(struct device *dev) { return 0; }
@@ -37,8 +46,6 @@ static inline int pm_runtime_force_resume(struct device *dev) { return 0; }
 
 #ifdef CONFIG_PM_RUNTIME
 
-extern struct workqueue_struct *pm_wq;
-
 extern int __pm_runtime_idle(struct device *dev, int rpmflags);
 extern int __pm_runtime_suspend(struct device *dev, int rpmflags);
 extern int __pm_runtime_resume(struct device *dev, int rpmflags);
index 4723bbfa1c2643fe004d36b5b44367644ea524d9..a6e555cbe05c37a57ef70d2e31949c17a9d8b7dd 100644 (file)
@@ -63,8 +63,6 @@
 #include <linux/sfi.h>
 
 #ifdef CONFIG_SFI
-#include <acpi/acpi.h> /* FIXME: inclusion should be removed */
-
 extern int sfi_acpi_table_parse(char *signature, char *oem_id,
                                char *oem_table_id,
                                int (*handler)(struct acpi_table_header *));
@@ -78,7 +76,6 @@ static inline int __init acpi_sfi_table_parse(char *signature,
        return sfi_acpi_table_parse(signature, NULL, NULL, handler);
 }
 #else /* !CONFIG_SFI */
-
 static inline int sfi_acpi_table_parse(char *signature, char *oem_id,
                                char *oem_table_id,
                                int (*handler)(struct acpi_table_header *))
index 713b0b88bd5a4cb7e0820dc16bb60bfabe0cb945..c4d86198d3d6542088ed6db8d4daed2adf191806 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/nf_tables.h>
+#include <linux/u64_stats_sync.h>
 #include <net/netlink.h>
 
 #define NFT_JUMP_STACK_SIZE    16
@@ -528,8 +529,9 @@ enum nft_chain_type {
 };
 
 struct nft_stats {
-       u64 bytes;
-       u64 pkts;
+       u64                     bytes;
+       u64                     pkts;
+       struct u64_stats_sync   syncp;
 };
 
 #define NFT_HOOK_OPS_MAX               2
index 26a394cb91a8fde2bb5a3f8716d25e073e4b1862..eee608b12cc95f3267a00eed85467f94f761d298 100644 (file)
@@ -13,8 +13,8 @@ struct netns_nftables {
        struct nft_af_info      *inet;
        struct nft_af_info      *arp;
        struct nft_af_info      *bridge;
+       unsigned int            base_seq;
        u8                      gencursor;
-       u8                      genctr;
 };
 
 #endif
index 40b5ca8a1b1f3028e5e03c5b3372f98e39437422..25084a052a1eff964d19a9683d5d6470590e4c7e 100644 (file)
  *  - add FATTR_CTIME
  *  - add ctime and ctimensec to fuse_setattr_in
  *  - add FUSE_RENAME2 request
+ *  - add FUSE_NO_OPEN_SUPPORT flag
  */
 
 #ifndef _LINUX_FUSE_H
@@ -229,6 +230,7 @@ struct fuse_file_lock {
  * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
  * FUSE_ASYNC_DIO: asynchronous direct I/O submission
  * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
+ * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -247,6 +249,7 @@ struct fuse_file_lock {
 #define FUSE_READDIRPLUS_AUTO  (1 << 14)
 #define FUSE_ASYNC_DIO         (1 << 15)
 #define FUSE_WRITEBACK_CACHE   (1 << 16)
+#define FUSE_NO_OPEN_SUPPORT   (1 << 17)
 
 /**
  * CUSE INIT request/reply flags
index b0c95f0f06fd37ee40ac508427441d27ef3f824f..6b17ac1b0c2a33c479a352fde633f47731807950 100644 (file)
@@ -7458,7 +7458,19 @@ __perf_event_exit_task(struct perf_event *child_event,
                         struct perf_event_context *child_ctx,
                         struct task_struct *child)
 {
-       perf_remove_from_context(child_event, true);
+       /*
+        * Do not destroy the 'original' grouping; because of the context
+        * switch optimization the original events could've ended up in a
+        * random child task.
+        *
+        * If we were to destroy the original group, all group related
+        * operations would cease to function properly after this random
+        * child dies.
+        *
+        * Do destroy all inherited groups, we don't care about those
+        * and being thorough is better.
+        */
+       perf_remove_from_context(child_event, !!child_event->parent);
 
        /*
         * It can happen that the parent exits first, and has events
@@ -7474,7 +7486,7 @@ __perf_event_exit_task(struct perf_event *child_event,
 static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
 {
        struct perf_event *child_event, *next;
-       struct perf_event_context *child_ctx;
+       struct perf_event_context *child_ctx, *parent_ctx;
        unsigned long flags;
 
        if (likely(!child->perf_event_ctxp[ctxn])) {
@@ -7499,6 +7511,15 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
        raw_spin_lock(&child_ctx->lock);
        task_ctx_sched_out(child_ctx);
        child->perf_event_ctxp[ctxn] = NULL;
+
+       /*
+        * In order to avoid freeing: child_ctx->parent_ctx->task
+        * under perf_event_context::lock, grab another reference.
+        */
+       parent_ctx = child_ctx->parent_ctx;
+       if (parent_ctx)
+               get_ctx(parent_ctx);
+
        /*
         * If this context is a clone; unclone it so it can't get
         * swapped to another process while we're removing all
@@ -7508,6 +7529,13 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
        update_context_time(child_ctx);
        raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
 
+       /*
+        * Now that we no longer hold perf_event_context::lock, drop
+        * our extra child_ctx->parent_ctx reference.
+        */
+       if (parent_ctx)
+               put_ctx(parent_ctx);
+
        /*
         * Report the task dead after unscheduling the events so that we
         * won't get any samples after PERF_RECORD_EXIT. We can however still
index 3214289df5a7a8f6917718a9a00f418794efeab1..734e9a7d280bd22a046566cc40b1edf159f250bf 100644 (file)
@@ -2037,19 +2037,23 @@ static int __init populate_kprobe_blacklist(unsigned long *start,
 {
        unsigned long *iter;
        struct kprobe_blacklist_entry *ent;
-       unsigned long offset = 0, size = 0;
+       unsigned long entry, offset = 0, size = 0;
 
        for (iter = start; iter < end; iter++) {
-               if (!kallsyms_lookup_size_offset(*iter, &size, &offset)) {
-                       pr_err("Failed to find blacklist %p\n", (void *)*iter);
+               entry = arch_deref_entry_point((void *)*iter);
+
+               if (!kernel_text_address(entry) ||
+                   !kallsyms_lookup_size_offset(entry, &size, &offset)) {
+                       pr_err("Failed to find blacklist at %p\n",
+                               (void *)entry);
                        continue;
                }
 
                ent = kmalloc(sizeof(*ent), GFP_KERNEL);
                if (!ent)
                        return -ENOMEM;
-               ent->start_addr = *iter;
-               ent->end_addr = *iter + size;
+               ent->start_addr = entry;
+               ent->end_addr = entry + size;
                INIT_LIST_HEAD(&ent->list);
                list_add_tail(&ent->list, &kprobe_blacklist);
        }
index 9a83d780facd576f2d4e770c180b33b072aaac4a..e4e4121fa327d72e15f121697a493561ee6611b2 100644 (file)
@@ -253,9 +253,6 @@ config APM_EMULATION
          anything, try disabling/enabling this option (or disabling/enabling
          APM in your BIOS).
 
-config ARCH_HAS_OPP
-       bool
-
 config PM_OPP
        bool
        ---help---
index d57f66a367dcdab3d8f819bdda7170735a72212a..9a59d042ea84f67c40537f2bfbcf7593a05d8716 100644 (file)
@@ -616,7 +616,6 @@ static struct attribute_group attr_group = {
        .attrs = g,
 };
 
-#ifdef CONFIG_PM_RUNTIME
 struct workqueue_struct *pm_wq;
 EXPORT_SYMBOL_GPL(pm_wq);
 
@@ -626,9 +625,6 @@ static int __init pm_start_workqueue(void)
 
        return pm_wq ? 0 : -ENOMEM;
 }
-#else
-static inline int pm_start_workqueue(void) { return 0; }
-#endif
 
 static int __init pm_init(void)
 {
index cf009fb0bc25b1427683d614a3a40ad98ad0c958..658a58dc30f47de758687ec69159d03edfe481f9 100644 (file)
@@ -147,8 +147,6 @@ use_default:
            clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
                goto use_default;
 
-       trace_cpu_idle_rcuidle(next_state, dev->cpu);
-
        /*
         * Enter the idle state previously returned by the governor decision.
         * This function will block until an interrupt occurs and will take
@@ -156,8 +154,6 @@ use_default:
         */
        entered_state = cpuidle_enter(drv, dev, next_state);
 
-       trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
-
        if (broadcast)
                clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
 
index bda9621638ccca1a08e6ff24df9dc486464d256a..291397e66669d4d2f9f4090ce040b94f8e7187fe 100644 (file)
@@ -823,7 +823,7 @@ static struct {
        { trace_clock_local,    "local",        1 },
        { trace_clock_global,   "global",       1 },
        { trace_clock_counter,  "counter",      0 },
-       { trace_clock_jiffies,  "uptime",       1 },
+       { trace_clock_jiffies,  "uptime",       0 },
        { trace_clock,          "perf",         1 },
        ARCH_TRACE_CLOCKS
 };
index 26dc348332b798eeb43a77cf2d89357512d9e8c0..57b67b1f24d1a141f88163c385e62be25cd275cf 100644 (file)
@@ -59,13 +59,14 @@ u64 notrace trace_clock(void)
 
 /*
  * trace_jiffy_clock(): Simply use jiffies as a clock counter.
+ * Note that this use of jiffies_64 is not completely safe on
+ * 32-bit systems. But the window is tiny, and the effect if
+ * we are affected is that we will have an obviously bogus
+ * timestamp on a trace event - i.e. not life threatening.
  */
 u64 notrace trace_clock_jiffies(void)
 {
-       u64 jiffy = jiffies - INITIAL_JIFFIES;
-
-       /* Return nsecs */
-       return (u64)jiffies_to_usecs(jiffy) * 1000ULL;
+       return jiffies_64_to_clock_t(jiffies_64 - INITIAL_JIFFIES);
 }
 
 /*
index 2024bbd573d2a9ca8a08842cdf0b99d2062cbee1..9221c02ed9e2b8ab495e0b39482e2bcfa5ba9957 100644 (file)
@@ -2604,6 +2604,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
                } else {
                        if (cow)
                                huge_ptep_set_wrprotect(src, addr, src_pte);
+                       entry = huge_ptep_get(src_pte);
                        ptepage = pte_page(entry);
                        get_page(ptepage);
                        page_dup_rmap(ptepage);
index c6399e32893178b835457388371e8e4f85512361..7211a73ba14d16155c1514c078b1e3c9d25e0b22 100644 (file)
@@ -435,7 +435,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
        if (av == NULL) /* Not actually mapped anymore */
                return;
 
-       pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+       pgoff = page_to_pgoff(page);
        read_lock(&tasklist_lock);
        for_each_process (tsk) {
                struct anon_vma_chain *vmac;
@@ -469,7 +469,7 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill,
        mutex_lock(&mapping->i_mmap_mutex);
        read_lock(&tasklist_lock);
        for_each_process(tsk) {
-               pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+               pgoff_t pgoff = page_to_pgoff(page);
                struct task_struct *t = task_early_kill(tsk, force_early);
 
                if (!t)
index d67fd9fcf1f2e11d8b77c513113475df125ad99d..7e8d8205b6108fcf5b0a97aad3da36c9455b230f 100644 (file)
@@ -2882,7 +2882,8 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
         * if page by the offset is not ready to be mapped (cold cache or
         * something).
         */
-       if (vma->vm_ops->map_pages && fault_around_pages() > 1) {
+       if (vma->vm_ops->map_pages && !(flags & FAULT_FLAG_NONLINEAR) &&
+           fault_around_pages() > 1) {
                pte = pte_offset_map_lock(mm, pmd, address, &ptl);
                do_fault_around(vma, address, pte, pgoff, flags);
                if (!pte_same(*pte, orig_pte))
index 9e0beaa918454abbcd63e94ee6cefb5f108f751f..be6dbf995c0cea7128fa58124057d8891cfa7933 100644 (file)
@@ -988,9 +988,10 @@ out:
         * it.  Otherwise, putback_lru_page() will drop the reference grabbed
         * during isolation.
         */
-       if (rc != MIGRATEPAGE_SUCCESS && put_new_page)
+       if (rc != MIGRATEPAGE_SUCCESS && put_new_page) {
+               ClearPageSwapBacked(newpage);
                put_new_page(newpage, private);
-       else
+       else
                putback_lru_page(newpage);
 
        if (result) {
index b7e94ebbd09e88c3b356e36fe89ed72b89e14474..22a4a7699cdbeb51e86c22ebbd4b1118693042f9 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -517,11 +517,7 @@ void page_unlock_anon_vma_read(struct anon_vma *anon_vma)
 static inline unsigned long
 __vma_address(struct page *page, struct vm_area_struct *vma)
 {
-       pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
-
-       if (unlikely(is_vm_hugetlb_page(vma)))
-               pgoff = page->index << huge_page_order(page_hstate(page));
-
+       pgoff_t pgoff = page_to_pgoff(page);
        return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
 }
 
@@ -1639,7 +1635,7 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
 static int rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc)
 {
        struct anon_vma *anon_vma;
-       pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+       pgoff_t pgoff = page_to_pgoff(page);
        struct anon_vma_chain *avc;
        int ret = SWAP_AGAIN;
 
@@ -1680,7 +1676,7 @@ static int rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc)
 static int rmap_walk_file(struct page *page, struct rmap_walk_control *rwc)
 {
        struct address_space *mapping = page->mapping;
-       pgoff_t pgoff = page->index << compound_order(page);
+       pgoff_t pgoff = page_to_pgoff(page);
        struct vm_area_struct *vma;
        int ret = SWAP_AGAIN;
 
index 1140f49b6ded6f7a72d89d2e89f9fce0df1a940d..af68b15a8fc1f99ede5cf82a38aecfc6b3b6eda6 100644 (file)
@@ -85,7 +85,7 @@ static struct vfsmount *shm_mnt;
  * a time): we would prefer not to enlarge the shmem inode just for that.
  */
 struct shmem_falloc {
-       int     mode;           /* FALLOC_FL mode currently operating */
+       wait_queue_head_t *waitq; /* faults into hole wait for punch to end */
        pgoff_t start;          /* start of range currently being fallocated */
        pgoff_t next;           /* the next page offset to be fallocated */
        pgoff_t nr_falloced;    /* how many new pages have been fallocated */
@@ -468,23 +468,20 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                return;
 
        index = start;
-       for ( ; ; ) {
+       while (index < end) {
                cond_resched();
 
                pvec.nr = find_get_entries(mapping, index,
                                min(end - index, (pgoff_t)PAGEVEC_SIZE),
                                pvec.pages, indices);
                if (!pvec.nr) {
-                       if (index == start || unfalloc)
+                       /* If all gone or hole-punch or unfalloc, we're done */
+                       if (index == start || end != -1)
                                break;
+                       /* But if truncating, restart to make sure all gone */
                        index = start;
                        continue;
                }
-               if ((index == start || unfalloc) && indices[0] >= end) {
-                       pagevec_remove_exceptionals(&pvec);
-                       pagevec_release(&pvec);
-                       break;
-               }
                mem_cgroup_uncharge_start();
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
@@ -496,8 +493,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                        if (radix_tree_exceptional_entry(page)) {
                                if (unfalloc)
                                        continue;
-                               nr_swaps_freed += !shmem_free_swap(mapping,
-                                                               index, page);
+                               if (shmem_free_swap(mapping, index, page)) {
+                                       /* Swap was replaced by page: retry */
+                                       index--;
+                                       break;
+                               }
+                               nr_swaps_freed++;
                                continue;
                        }
 
@@ -506,6 +507,11 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                                if (page->mapping == mapping) {
                                        VM_BUG_ON_PAGE(PageWriteback(page), page);
                                        truncate_inode_page(mapping, page);
+                               } else {
+                                       /* Page was replaced by swap: retry */
+                                       unlock_page(page);
+                                       index--;
+                                       break;
                                }
                        }
                        unlock_page(page);
@@ -760,7 +766,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
                        spin_lock(&inode->i_lock);
                        shmem_falloc = inode->i_private;
                        if (shmem_falloc &&
-                           !shmem_falloc->mode &&
+                           !shmem_falloc->waitq &&
                            index >= shmem_falloc->start &&
                            index < shmem_falloc->next)
                                shmem_falloc->nr_unswapped++;
@@ -1248,38 +1254,58 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
         * Trinity finds that probing a hole which tmpfs is punching can
         * prevent the hole-punch from ever completing: which in turn
         * locks writers out with its hold on i_mutex.  So refrain from
-        * faulting pages into the hole while it's being punched, and
-        * wait on i_mutex to be released if vmf->flags permits.
+        * faulting pages into the hole while it's being punched.  Although
+        * shmem_undo_range() does remove the additions, it may be unable to
+        * keep up, as each new page needs its own unmap_mapping_range() call,
+        * and the i_mmap tree grows ever slower to scan if new vmas are added.
+        *
+        * It does not matter if we sometimes reach this check just before the
+        * hole-punch begins, so that one fault then races with the punch:
+        * we just need to make racing faults a rare case.
+        *
+        * The implementation below would be much simpler if we just used a
+        * standard mutex or completion: but we cannot take i_mutex in fault,
+        * and bloating every shmem inode for this unlikely case would be sad.
         */
        if (unlikely(inode->i_private)) {
                struct shmem_falloc *shmem_falloc;
 
                spin_lock(&inode->i_lock);
                shmem_falloc = inode->i_private;
-               if (!shmem_falloc ||
-                   shmem_falloc->mode != FALLOC_FL_PUNCH_HOLE ||
-                   vmf->pgoff < shmem_falloc->start ||
-                   vmf->pgoff >= shmem_falloc->next)
-                       shmem_falloc = NULL;
-               spin_unlock(&inode->i_lock);
-               /*
-                * i_lock has protected us from taking shmem_falloc seriously
-                * once return from shmem_fallocate() went back up that stack.
-                * i_lock does not serialize with i_mutex at all, but it does
-                * not matter if sometimes we wait unnecessarily, or sometimes
-                * miss out on waiting: we just need to make those cases rare.
-                */
-               if (shmem_falloc) {
+               if (shmem_falloc &&
+                   shmem_falloc->waitq &&
+                   vmf->pgoff >= shmem_falloc->start &&
+                   vmf->pgoff < shmem_falloc->next) {
+                       wait_queue_head_t *shmem_falloc_waitq;
+                       DEFINE_WAIT(shmem_fault_wait);
+
+                       ret = VM_FAULT_NOPAGE;
                        if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) &&
                           !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
+                               /* It's polite to up mmap_sem if we can */
                                up_read(&vma->vm_mm->mmap_sem);
-                               mutex_lock(&inode->i_mutex);
-                               mutex_unlock(&inode->i_mutex);
-                               return VM_FAULT_RETRY;
+                               ret = VM_FAULT_RETRY;
                        }
-                       /* cond_resched? Leave that to GUP or return to user */
-                       return VM_FAULT_NOPAGE;
+
+                       shmem_falloc_waitq = shmem_falloc->waitq;
+                       prepare_to_wait(shmem_falloc_waitq, &shmem_fault_wait,
+                                       TASK_UNINTERRUPTIBLE);
+                       spin_unlock(&inode->i_lock);
+                       schedule();
+
+                       /*
+                        * shmem_falloc_waitq points into the shmem_fallocate()
+                        * stack of the hole-punching task: shmem_falloc_waitq
+                        * is usually invalid by the time we reach here, but
+                        * finish_wait() does not dereference it in that case;
+                        * though i_lock needed lest racing with wake_up_all().
+                        */
+                       spin_lock(&inode->i_lock);
+                       finish_wait(shmem_falloc_waitq, &shmem_fault_wait);
+                       spin_unlock(&inode->i_lock);
+                       return ret;
                }
+               spin_unlock(&inode->i_lock);
        }
 
        error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret);
@@ -1774,13 +1800,13 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
 
        mutex_lock(&inode->i_mutex);
 
-       shmem_falloc.mode = mode & ~FALLOC_FL_KEEP_SIZE;
-
        if (mode & FALLOC_FL_PUNCH_HOLE) {
                struct address_space *mapping = file->f_mapping;
                loff_t unmap_start = round_up(offset, PAGE_SIZE);
                loff_t unmap_end = round_down(offset + len, PAGE_SIZE) - 1;
+               DECLARE_WAIT_QUEUE_HEAD_ONSTACK(shmem_falloc_waitq);
 
+               shmem_falloc.waitq = &shmem_falloc_waitq;
                shmem_falloc.start = unmap_start >> PAGE_SHIFT;
                shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT;
                spin_lock(&inode->i_lock);
@@ -1792,8 +1818,13 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
                                            1 + unmap_end - unmap_start, 0);
                shmem_truncate_range(inode, offset, offset + len - 1);
                /* No need to unmap again: hole-punching leaves COWed pages */
+
+               spin_lock(&inode->i_lock);
+               inode->i_private = NULL;
+               wake_up_all(&shmem_falloc_waitq);
+               spin_unlock(&inode->i_lock);
                error = 0;
-               goto undone;
+               goto out;
        }
 
        /* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */
@@ -1809,6 +1840,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
                goto out;
        }
 
+       shmem_falloc.waitq = NULL;
        shmem_falloc.start = start;
        shmem_falloc.next  = start;
        shmem_falloc.nr_falloced = 0;
index 735e01a0db6f8c3ffa28150e5faedf362dc5b874..d31c4bacc6a203b0bc555bd76c2a97e90e78fa6c 100644 (file)
@@ -55,7 +55,7 @@ static int kmem_cache_sanity_check(const char *name, size_t size)
                        continue;
                }
 
-#if !defined(CONFIG_SLUB) || !defined(CONFIG_SLUB_DEBUG_ON)
+#if !defined(CONFIG_SLUB)
                if (!strcmp(s->name, name)) {
                        pr_err("%s (%s): Cache name already exists.\n",
                               __func__, name);
index 6a78c814bebfb151b1e490424c731edc172ad430..eda2473071648cc47935dd9e21e9f57fd402a4dd 100644 (file)
@@ -355,14 +355,16 @@ void truncate_inode_pages_range(struct address_space *mapping,
        for ( ; ; ) {
                cond_resched();
                if (!pagevec_lookup_entries(&pvec, mapping, index,
-                       min(end - index, (pgoff_t)PAGEVEC_SIZE),
-                       indices)) {
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE), indices)) {
+                       /* If all gone from start onwards, we're done */
                        if (index == start)
                                break;
+                       /* Otherwise restart to make sure all gone */
                        index = start;
                        continue;
                }
                if (index == start && indices[0] >= end) {
+                       /* All gone out of hole to be punched, we're done */
                        pagevec_remove_exceptionals(&pvec);
                        pagevec_release(&pvec);
                        break;
@@ -373,8 +375,11 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
                        /* We rely upon deletion not changing page->index */
                        index = indices[i];
-                       if (index >= end)
+                       if (index >= end) {
+                               /* Restart punch to make sure all gone */
+                               index = start - 1;
                                break;
+                       }
 
                        if (radix_tree_exceptional_entry(page)) {
                                clear_exceptional_entry(mapping, index, page);
index 6f0d9ec3795059fdc5319574b65b24c08aaf2790..a957c8140721def2878b292c2e61e2dd37c36e5c 100644 (file)
@@ -800,11 +800,6 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
        bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
        bla_dst_own = &bat_priv->bla.claim_dest;
 
-       /* check if it is a claim packet in general */
-       if (memcmp(bla_dst->magic, bla_dst_own->magic,
-                  sizeof(bla_dst->magic)) != 0)
-               return 0;
-
        /* if announcement packet, use the source,
         * otherwise assume it is in the hw_src
         */
@@ -866,12 +861,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
                                    struct batadv_hard_iface *primary_if,
                                    struct sk_buff *skb)
 {
-       struct batadv_bla_claim_dst *bla_dst;
+       struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
        uint8_t *hw_src, *hw_dst;
-       struct vlan_ethhdr *vhdr;
+       struct vlan_hdr *vhdr, vhdr_buf;
        struct ethhdr *ethhdr;
        struct arphdr *arphdr;
        unsigned short vid;
+       int vlan_depth = 0;
        __be16 proto;
        int headlen;
        int ret;
@@ -882,9 +878,24 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        proto = ethhdr->h_proto;
        headlen = ETH_HLEN;
        if (vid & BATADV_VLAN_HAS_TAG) {
-               vhdr = vlan_eth_hdr(skb);
-               proto = vhdr->h_vlan_encapsulated_proto;
-               headlen += VLAN_HLEN;
+               /* Traverse the VLAN/Ethertypes.
+                *
+                * At this point it is known that the first protocol is a VLAN
+                * header, so start checking at the encapsulated protocol.
+                *
+                * The depth of the VLAN headers is recorded to drop BLA claim
+                * frames encapsulated into multiple VLAN headers (QinQ).
+                */
+               do {
+                       vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN,
+                                                 &vhdr_buf);
+                       if (!vhdr)
+                               return 0;
+
+                       proto = vhdr->h_vlan_encapsulated_proto;
+                       headlen += VLAN_HLEN;
+                       vlan_depth++;
+               } while (proto == htons(ETH_P_8021Q));
        }
 
        if (proto != htons(ETH_P_ARP))
@@ -914,6 +925,19 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
        hw_dst = hw_src + ETH_ALEN + 4;
        bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
+       bla_dst_own = &bat_priv->bla.claim_dest;
+
+       /* check if it is a claim frame in general */
+       if (memcmp(bla_dst->magic, bla_dst_own->magic,
+                  sizeof(bla_dst->magic)) != 0)
+               return 0;
+
+       /* check if there is a claim frame encapsulated deeper in (QinQ) and
+        * drop that, as this is not supported by BLA but should also not be
+        * sent via the mesh.
+        */
+       if (vlan_depth > 1)
+               return 1;
 
        /* check if it is a claim frame. */
        ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
index e7ee65dc20bf4f25a1a8d0134c66b0bfaef25bd3..cbd677f48c00541fc8ff9aed5b0943d3855b1810 100644 (file)
@@ -448,10 +448,15 @@ out:
  *  possibly free it
  * @softif_vlan: the vlan object to release
  */
-void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
+void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *vlan)
 {
-       if (atomic_dec_and_test(&softif_vlan->refcount))
-               kfree_rcu(softif_vlan, rcu);
+       if (atomic_dec_and_test(&vlan->refcount)) {
+               spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock);
+               hlist_del_rcu(&vlan->list);
+               spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock);
+
+               kfree_rcu(vlan, rcu);
+       }
 }
 
 /**
@@ -505,6 +510,7 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
        if (!vlan)
                return -ENOMEM;
 
+       vlan->bat_priv = bat_priv;
        vlan->vid = vid;
        atomic_set(&vlan->refcount, 1);
 
@@ -516,6 +522,10 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
                return err;
        }
 
+       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
+       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+
        /* add a new TT local entry. This one will be marked with the NOPURGE
         * flag
         */
@@ -523,10 +533,6 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
                            bat_priv->soft_iface->dev_addr, vid,
                            BATADV_NULL_IFINDEX, BATADV_NO_MARK);
 
-       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
-       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
-       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
-
        return 0;
 }
 
@@ -538,18 +544,13 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
 static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
                                       struct batadv_softif_vlan *vlan)
 {
-       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
-       hlist_del_rcu(&vlan->list);
-       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
-
-       batadv_sysfs_del_vlan(bat_priv, vlan);
-
        /* explicitly remove the associated TT local entry because it is marked
         * with the NOPURGE flag
         */
        batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr,
                               vlan->vid, "vlan interface destroyed", false);
 
+       batadv_sysfs_del_vlan(bat_priv, vlan);
        batadv_softif_vlan_free_ref(vlan);
 }
 
@@ -567,6 +568,8 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
                                    unsigned short vid)
 {
        struct batadv_priv *bat_priv = netdev_priv(dev);
+       struct batadv_softif_vlan *vlan;
+       int ret;
 
        /* only 802.1Q vlans are supported.
         * batman-adv does not know how to handle other types
@@ -576,7 +579,36 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
 
        vid |= BATADV_VLAN_HAS_TAG;
 
-       return batadv_softif_create_vlan(bat_priv, vid);
+       /* if a new vlan is getting created and it already exists, it means that
+        * it was not deleted yet. batadv_softif_vlan_get() increases the
+        * refcount in order to revive the object.
+        *
+        * if it does not exist then create it.
+        */
+       vlan = batadv_softif_vlan_get(bat_priv, vid);
+       if (!vlan)
+               return batadv_softif_create_vlan(bat_priv, vid);
+
+       /* recreate the sysfs object if it was already destroyed (and it should
+        * be since we received a kill_vid() for this vlan
+        */
+       if (!vlan->kobj) {
+               ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
+               if (ret) {
+                       batadv_softif_vlan_free_ref(vlan);
+                       return ret;
+               }
+       }
+
+       /* add a new TT local entry. This one will be marked with the NOPURGE
+        * flag. This must be added again, even if the vlan object already
+        * exists, because the entry was deleted by kill_vid()
+        */
+       batadv_tt_local_add(bat_priv->soft_iface,
+                           bat_priv->soft_iface->dev_addr, vid,
+                           BATADV_NULL_IFINDEX, BATADV_NO_MARK);
+
+       return 0;
 }
 
 /**
index d636bde72c9ace9cfbcead01353c955f17923155..5f59e7f899a0179a544764207468c6b4b336a237 100644 (file)
@@ -511,6 +511,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
        struct batadv_priv *bat_priv = netdev_priv(soft_iface);
        struct batadv_tt_local_entry *tt_local;
        struct batadv_tt_global_entry *tt_global = NULL;
+       struct batadv_softif_vlan *vlan;
        struct net_device *in_dev = NULL;
        struct hlist_head *head;
        struct batadv_tt_orig_list_entry *orig_entry;
@@ -572,6 +573,9 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
        if (!tt_local)
                goto out;
 
+       /* increase the refcounter of the related vlan */
+       vlan = batadv_softif_vlan_get(bat_priv, vid);
+
        batadv_dbg(BATADV_DBG_TT, bat_priv,
                   "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
                   addr, BATADV_PRINT_VID(vid),
@@ -604,6 +608,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
        if (unlikely(hash_added != 0)) {
                /* remove the reference for the hash */
                batadv_tt_local_entry_free_ref(tt_local);
+               batadv_softif_vlan_free_ref(vlan);
                goto out;
        }
 
@@ -1009,6 +1014,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
 {
        struct batadv_tt_local_entry *tt_local_entry;
        uint16_t flags, curr_flags = BATADV_NO_FLAGS;
+       struct batadv_softif_vlan *vlan;
 
        tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
        if (!tt_local_entry)
@@ -1039,6 +1045,11 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
        hlist_del_rcu(&tt_local_entry->common.hash_entry);
        batadv_tt_local_entry_free_ref(tt_local_entry);
 
+       /* decrease the reference held for this vlan */
+       vlan = batadv_softif_vlan_get(bat_priv, vid);
+       batadv_softif_vlan_free_ref(vlan);
+       batadv_softif_vlan_free_ref(vlan);
+
 out:
        if (tt_local_entry)
                batadv_tt_local_entry_free_ref(tt_local_entry);
@@ -1111,6 +1122,7 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
        spinlock_t *list_lock; /* protects write access to the hash lists */
        struct batadv_tt_common_entry *tt_common_entry;
        struct batadv_tt_local_entry *tt_local;
+       struct batadv_softif_vlan *vlan;
        struct hlist_node *node_tmp;
        struct hlist_head *head;
        uint32_t i;
@@ -1131,6 +1143,13 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
                        tt_local = container_of(tt_common_entry,
                                                struct batadv_tt_local_entry,
                                                common);
+
+                       /* decrease the reference held for this vlan */
+                       vlan = batadv_softif_vlan_get(bat_priv,
+                                                     tt_common_entry->vid);
+                       batadv_softif_vlan_free_ref(vlan);
+                       batadv_softif_vlan_free_ref(vlan);
+
                        batadv_tt_local_entry_free_ref(tt_local);
                }
                spin_unlock_bh(list_lock);
@@ -3139,6 +3158,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
        struct batadv_hashtable *hash = bat_priv->tt.local_hash;
        struct batadv_tt_common_entry *tt_common;
        struct batadv_tt_local_entry *tt_local;
+       struct batadv_softif_vlan *vlan;
        struct hlist_node *node_tmp;
        struct hlist_head *head;
        spinlock_t *list_lock; /* protects write access to the hash lists */
@@ -3167,6 +3187,12 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
                        tt_local = container_of(tt_common,
                                                struct batadv_tt_local_entry,
                                                common);
+
+                       /* decrease the reference held for this vlan */
+                       vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid);
+                       batadv_softif_vlan_free_ref(vlan);
+                       batadv_softif_vlan_free_ref(vlan);
+
                        batadv_tt_local_entry_free_ref(tt_local);
                }
                spin_unlock_bh(list_lock);
index 34891a56773f09ebcccab01fe3191b1a56651aed..8854c05622a9bae2b8f30b0cf91686e8c629a849 100644 (file)
@@ -687,6 +687,7 @@ struct batadv_priv_nc {
 
 /**
  * struct batadv_softif_vlan - per VLAN attributes set
+ * @bat_priv: pointer to the mesh object
  * @vid: VLAN identifier
  * @kobj: kobject for sysfs vlan subdirectory
  * @ap_isolation: AP isolation state
@@ -696,6 +697,7 @@ struct batadv_priv_nc {
  * @rcu: struct used for freeing in a RCU-safe manner
  */
 struct batadv_softif_vlan {
+       struct batadv_priv *bat_priv;
        unsigned short vid;
        struct kobject *kobj;
        atomic_t ap_isolation;          /* boolean */
index 7990984ca364093f77964d3ac1bbfcbc8f366595..367a586d0c8a851ad0b5ea57fab32dfe894d662c 100644 (file)
@@ -4096,6 +4096,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
        skb->vlan_tci = 0;
        skb->dev = napi->dev;
        skb->skb_iif = 0;
+       skb->encapsulation = 0;
+       skb_shinfo(skb)->gso_type = 0;
        skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
 
        napi->skb = skb;
index 9acec61f54334f146d87711f145f1992dbf2c360..dd8696a3dbec9b907cc9fa3744a8bf37e8efca93 100644 (file)
@@ -150,7 +150,7 @@ int dns_query(const char *type, const char *name, size_t namelen,
                goto put;
 
        memcpy(*_result, upayload->data, len);
-       *_result[len] = '\0';
+       (*_result)[len] = '\0';
 
        if (_expiry)
                *_expiry = rkey->expiry;
index d5e6836cf772d677271c46681ffa442baa9d0c99..d156b3c5f3631f169f179bfdd534b69ce5070b82 100644 (file)
@@ -1429,6 +1429,9 @@ static int inet_gro_complete(struct sk_buff *skb, int nhoff)
        int proto = iph->protocol;
        int err = -ENOSYS;
 
+       if (skb->encapsulation)
+               skb_set_inner_network_header(skb, nhoff);
+
        csum_replace2(&iph->check, iph->tot_len, newlen);
        iph->tot_len = newlen;
 
index eb92deb12666fb56b6a289c55b8205fc27117933..f0bdd47bbbcb5f420e9c3e406ca9dd1e83d0e554 100644 (file)
@@ -263,6 +263,9 @@ static int gre_gro_complete(struct sk_buff *skb, int nhoff)
        int err = -ENOENT;
        __be16 type;
 
+       skb->encapsulation = 1;
+       skb_shinfo(skb)->gso_type = SKB_GSO_GRE;
+
        type = greh->protocol;
        if (greh->flags & GRE_KEY)
                grehlen += GRE_HEADER_SECTION;
index 5e7aecea05cd2afbd3e3e13f417e26687517b468..ad382499bace4ce3852c2953bb262f2796d9a416 100644 (file)
@@ -288,6 +288,10 @@ int ip_options_compile(struct net *net,
                        optptr++;
                        continue;
                }
+               if (unlikely(l < 2)) {
+                       pp_ptr = optptr;
+                       goto error;
+               }
                optlen = optptr[1];
                if (optlen < 2 || optlen > l) {
                        pp_ptr = optptr;
index 4e86c59ec7f7f07fe06c6db20d17851da6f1563f..55046ecd083ea8afb964205eb8ea38e2bbe91708 100644 (file)
@@ -309,7 +309,7 @@ static int tcp4_gro_complete(struct sk_buff *skb, int thoff)
 
        th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr,
                                  iph->daddr, 0);
-       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+       skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
 
        return tcp_gro_complete(skb);
 }
index 8517d3cd1aed460bbfb1bfb0f515924f008b790d..01b0ff9a0c2c00d6734537254e2150edcbcb64d7 100644 (file)
@@ -73,7 +73,7 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff)
 
        th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,
                                  &iph->daddr, 0);
-       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+       skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
 
        return tcp_gro_complete(skb);
 }
index ab4566cfcbe497beea641dff934e24dc3341096b..8746ff9a83571d97b3991dced7ad3f968c15bdfa 100644 (file)
@@ -35,7 +35,7 @@ int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
 {
        INIT_LIST_HEAD(&afi->tables);
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
-       list_add_tail(&afi->list, &net->nft.af_info);
+       list_add_tail_rcu(&afi->list, &net->nft.af_info);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
        return 0;
 }
@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(nft_register_afinfo);
 void nft_unregister_afinfo(struct nft_af_info *afi)
 {
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
-       list_del(&afi->list);
+       list_del_rcu(&afi->list);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
 }
 EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
@@ -277,11 +277,14 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
        struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
 
-       list_for_each_entry(afi, &net->nft.af_info, list) {
+       rcu_read_lock();
+       cb->seq = net->nft.base_seq;
+
+       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
                if (family != NFPROTO_UNSPEC && family != afi->family)
                        continue;
 
-               list_for_each_entry(table, &afi->tables, list) {
+               list_for_each_entry_rcu(table, &afi->tables, list) {
                        if (idx < s_idx)
                                goto cont;
                        if (idx > s_idx)
@@ -294,11 +297,14 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
                                                      NLM_F_MULTI,
                                                      afi->family, table) < 0)
                                goto done;
+
+                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                        idx++;
                }
        }
 done:
+       rcu_read_unlock();
        cb->args[0] = idx;
        return skb->len;
 }
@@ -407,6 +413,9 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
        if (flags & ~NFT_TABLE_F_DORMANT)
                return -EINVAL;
 
+       if (flags == ctx->table->flags)
+               return 0;
+
        trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
                                sizeof(struct nft_trans_table));
        if (trans == NULL)
@@ -514,7 +523,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
                module_put(afi->owner);
                return err;
        }
-       list_add_tail(&table->list, &afi->tables);
+       list_add_tail_rcu(&table->list, &afi->tables);
        return 0;
 }
 
@@ -546,7 +555,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       list_del(&table->list);
+       list_del_rcu(&table->list);
        return 0;
 }
 
@@ -635,13 +644,20 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
 {
        struct nft_stats *cpu_stats, total;
        struct nlattr *nest;
+       unsigned int seq;
+       u64 pkts, bytes;
        int cpu;
 
        memset(&total, 0, sizeof(total));
        for_each_possible_cpu(cpu) {
                cpu_stats = per_cpu_ptr(stats, cpu);
-               total.pkts += cpu_stats->pkts;
-               total.bytes += cpu_stats->bytes;
+               do {
+                       seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
+                       pkts = cpu_stats->pkts;
+                       bytes = cpu_stats->bytes;
+               } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
+               total.pkts += pkts;
+               total.bytes += bytes;
        }
        nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
        if (nest == NULL)
@@ -761,12 +777,15 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
        struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
 
-       list_for_each_entry(afi, &net->nft.af_info, list) {
+       rcu_read_lock();
+       cb->seq = net->nft.base_seq;
+
+       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
                if (family != NFPROTO_UNSPEC && family != afi->family)
                        continue;
 
-               list_for_each_entry(table, &afi->tables, list) {
-                       list_for_each_entry(chain, &table->chains, list) {
+               list_for_each_entry_rcu(table, &afi->tables, list) {
+                       list_for_each_entry_rcu(chain, &table->chains, list) {
                                if (idx < s_idx)
                                        goto cont;
                                if (idx > s_idx)
@@ -778,17 +797,19 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
                                                              NLM_F_MULTI,
                                                              afi->family, table, chain) < 0)
                                        goto done;
+
+                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                                idx++;
                        }
                }
        }
 done:
+       rcu_read_unlock();
        cb->args[0] = idx;
        return skb->len;
 }
 
-
 static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
                              const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
@@ -861,7 +882,7 @@ static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
        if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
                return ERR_PTR(-EINVAL);
 
-       newstats = alloc_percpu(struct nft_stats);
+       newstats = netdev_alloc_pcpu_stats(struct nft_stats);
        if (newstats == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -1077,7 +1098,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
                        }
                        basechain->stats = stats;
                } else {
-                       stats = alloc_percpu(struct nft_stats);
+                       stats = netdev_alloc_pcpu_stats(struct nft_stats);
                        if (IS_ERR(stats)) {
                                module_put(type->owner);
                                kfree(basechain);
@@ -1130,7 +1151,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
                goto err2;
 
        table->use++;
-       list_add_tail(&chain->list, &table->chains);
+       list_add_tail_rcu(&chain->list, &table->chains);
        return 0;
 err2:
        if (!(table->flags & NFT_TABLE_F_DORMANT) &&
@@ -1180,7 +1201,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
                return err;
 
        table->use--;
-       list_del(&chain->list);
+       list_del_rcu(&chain->list);
        return 0;
 }
 
@@ -1199,9 +1220,9 @@ int nft_register_expr(struct nft_expr_type *type)
 {
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
        if (type->family == NFPROTO_UNSPEC)
-               list_add_tail(&type->list, &nf_tables_expressions);
+               list_add_tail_rcu(&type->list, &nf_tables_expressions);
        else
-               list_add(&type->list, &nf_tables_expressions);
+               list_add_rcu(&type->list, &nf_tables_expressions);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
        return 0;
 }
@@ -1216,7 +1237,7 @@ EXPORT_SYMBOL_GPL(nft_register_expr);
 void nft_unregister_expr(struct nft_expr_type *type)
 {
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
-       list_del(&type->list);
+       list_del_rcu(&type->list);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
 }
 EXPORT_SYMBOL_GPL(nft_unregister_expr);
@@ -1549,16 +1570,17 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
        unsigned int idx = 0, s_idx = cb->args[0];
        struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
-       u8 genctr = ACCESS_ONCE(net->nft.genctr);
-       u8 gencursor = ACCESS_ONCE(net->nft.gencursor);
 
-       list_for_each_entry(afi, &net->nft.af_info, list) {
+       rcu_read_lock();
+       cb->seq = net->nft.base_seq;
+
+       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
                if (family != NFPROTO_UNSPEC && family != afi->family)
                        continue;
 
-               list_for_each_entry(table, &afi->tables, list) {
-                       list_for_each_entry(chain, &table->chains, list) {
-                               list_for_each_entry(rule, &chain->rules, list) {
+               list_for_each_entry_rcu(table, &afi->tables, list) {
+                       list_for_each_entry_rcu(chain, &table->chains, list) {
+                               list_for_each_entry_rcu(rule, &chain->rules, list) {
                                        if (!nft_rule_is_active(net, rule))
                                                goto cont;
                                        if (idx < s_idx)
@@ -1572,6 +1594,8 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
                                                                      NLM_F_MULTI | NLM_F_APPEND,
                                                                      afi->family, table, chain, rule) < 0)
                                                goto done;
+
+                                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                                        idx++;
                                }
@@ -1579,9 +1603,7 @@ cont:
                }
        }
 done:
-       /* Invalidate this dump, a transition to the new generation happened */
-       if (gencursor != net->nft.gencursor || genctr != net->nft.genctr)
-               return -EBUSY;
+       rcu_read_unlock();
 
        cb->args[0] = idx;
        return skb->len;
@@ -1932,7 +1954,7 @@ static LIST_HEAD(nf_tables_set_ops);
 int nft_register_set(struct nft_set_ops *ops)
 {
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
-       list_add_tail(&ops->list, &nf_tables_set_ops);
+       list_add_tail_rcu(&ops->list, &nf_tables_set_ops);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
        return 0;
 }
@@ -1941,7 +1963,7 @@ EXPORT_SYMBOL_GPL(nft_register_set);
 void nft_unregister_set(struct nft_set_ops *ops)
 {
        nfnl_lock(NFNL_SUBSYS_NFTABLES);
-       list_del(&ops->list);
+       list_del_rcu(&ops->list);
        nfnl_unlock(NFNL_SUBSYS_NFTABLES);
 }
 EXPORT_SYMBOL_GPL(nft_unregister_set);
@@ -2234,7 +2256,10 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
        if (cb->args[1])
                return skb->len;
 
-       list_for_each_entry(set, &ctx->table->sets, list) {
+       rcu_read_lock();
+       cb->seq = ctx->net->nft.base_seq;
+
+       list_for_each_entry_rcu(set, &ctx->table->sets, list) {
                if (idx < s_idx)
                        goto cont;
                if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
@@ -2242,11 +2267,13 @@ static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
                        cb->args[0] = idx;
                        goto done;
                }
+               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                idx++;
        }
        cb->args[1] = 1;
 done:
+       rcu_read_unlock();
        return skb->len;
 }
 
@@ -2260,7 +2287,10 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
        if (cb->args[1])
                return skb->len;
 
-       list_for_each_entry(table, &ctx->afi->tables, list) {
+       rcu_read_lock();
+       cb->seq = ctx->net->nft.base_seq;
+
+       list_for_each_entry_rcu(table, &ctx->afi->tables, list) {
                if (cur_table) {
                        if (cur_table != table)
                                continue;
@@ -2269,7 +2299,7 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
                }
                ctx->table = table;
                idx = 0;
-               list_for_each_entry(set, &ctx->table->sets, list) {
+               list_for_each_entry_rcu(set, &ctx->table->sets, list) {
                        if (idx < s_idx)
                                goto cont;
                        if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
@@ -2278,12 +2308,14 @@ static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
                                cb->args[2] = (unsigned long) table;
                                goto done;
                        }
+                       nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                        idx++;
                }
        }
        cb->args[1] = 1;
 done:
+       rcu_read_unlock();
        return skb->len;
 }
 
@@ -2300,7 +2332,10 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
        if (cb->args[1])
                return skb->len;
 
-       list_for_each_entry(afi, &net->nft.af_info, list) {
+       rcu_read_lock();
+       cb->seq = net->nft.base_seq;
+
+       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
                if (cur_family) {
                        if (afi->family != cur_family)
                                continue;
@@ -2308,7 +2343,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
                        cur_family = 0;
                }
 
-               list_for_each_entry(table, &afi->tables, list) {
+               list_for_each_entry_rcu(table, &afi->tables, list) {
                        if (cur_table) {
                                if (cur_table != table)
                                        continue;
@@ -2319,7 +2354,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
                        ctx->table = table;
                        ctx->afi = afi;
                        idx = 0;
-                       list_for_each_entry(set, &ctx->table->sets, list) {
+                       list_for_each_entry_rcu(set, &ctx->table->sets, list) {
                                if (idx < s_idx)
                                        goto cont;
                                if (nf_tables_fill_set(skb, ctx, set,
@@ -2330,6 +2365,7 @@ static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
                                        cb->args[3] = afi->family;
                                        goto done;
                                }
+                               nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
                                idx++;
                        }
@@ -2339,6 +2375,7 @@ cont:
        }
        cb->args[1] = 1;
 done:
+       rcu_read_unlock();
        return skb->len;
 }
 
@@ -2597,7 +2634,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
        if (err < 0)
                goto err2;
 
-       list_add_tail(&set->list, &table->sets);
+       list_add_tail_rcu(&set->list, &table->sets);
        table->use++;
        return 0;
 
@@ -2617,7 +2654,7 @@ static void nft_set_destroy(struct nft_set *set)
 
 static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
 {
-       list_del(&set->list);
+       list_del_rcu(&set->list);
        nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
        nft_set_destroy(set);
 }
@@ -2652,7 +2689,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
        if (err < 0)
                return err;
 
-       list_del(&set->list);
+       list_del_rcu(&set->list);
        ctx.table->use--;
        return 0;
 }
@@ -2704,14 +2741,14 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
        }
 bind:
        binding->chain = ctx->chain;
-       list_add_tail(&binding->list, &set->bindings);
+       list_add_tail_rcu(&binding->list, &set->bindings);
        return 0;
 }
 
 void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
                          struct nft_set_binding *binding)
 {
-       list_del(&binding->list);
+       list_del_rcu(&binding->list);
 
        if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
            !(set->flags & NFT_SET_INACTIVE))
@@ -3346,7 +3383,7 @@ static int nf_tables_commit(struct sk_buff *skb)
        struct nft_set *set;
 
        /* Bump generation counter, invalidate any dump in progress */
-       net->nft.genctr++;
+       while (++net->nft.base_seq == 0);
 
        /* A new generation has just started */
        net->nft.gencursor = gencursor_next(net);
@@ -3491,12 +3528,12 @@ static int nf_tables_abort(struct sk_buff *skb)
                                }
                                nft_trans_destroy(trans);
                        } else {
-                               list_del(&trans->ctx.table->list);
+                               list_del_rcu(&trans->ctx.table->list);
                        }
                        break;
                case NFT_MSG_DELTABLE:
-                       list_add_tail(&trans->ctx.table->list,
-                                     &trans->ctx.afi->tables);
+                       list_add_tail_rcu(&trans->ctx.table->list,
+                                         &trans->ctx.afi->tables);
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_NEWCHAIN:
@@ -3507,7 +3544,7 @@ static int nf_tables_abort(struct sk_buff *skb)
                                nft_trans_destroy(trans);
                        } else {
                                trans->ctx.table->use--;
-                               list_del(&trans->ctx.chain->list);
+                               list_del_rcu(&trans->ctx.chain->list);
                                if (!(trans->ctx.table->flags & NFT_TABLE_F_DORMANT) &&
                                    trans->ctx.chain->flags & NFT_BASE_CHAIN) {
                                        nf_unregister_hooks(nft_base_chain(trans->ctx.chain)->ops,
@@ -3517,8 +3554,8 @@ static int nf_tables_abort(struct sk_buff *skb)
                        break;
                case NFT_MSG_DELCHAIN:
                        trans->ctx.table->use++;
-                       list_add_tail(&trans->ctx.chain->list,
-                                     &trans->ctx.table->chains);
+                       list_add_tail_rcu(&trans->ctx.chain->list,
+                                         &trans->ctx.table->chains);
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_NEWRULE:
@@ -3532,12 +3569,12 @@ static int nf_tables_abort(struct sk_buff *skb)
                        break;
                case NFT_MSG_NEWSET:
                        trans->ctx.table->use--;
-                       list_del(&nft_trans_set(trans)->list);
+                       list_del_rcu(&nft_trans_set(trans)->list);
                        break;
                case NFT_MSG_DELSET:
                        trans->ctx.table->use++;
-                       list_add_tail(&nft_trans_set(trans)->list,
-                                     &trans->ctx.table->sets);
+                       list_add_tail_rcu(&nft_trans_set(trans)->list,
+                                         &trans->ctx.table->sets);
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_NEWSETELEM:
@@ -3951,6 +3988,7 @@ static int nf_tables_init_net(struct net *net)
 {
        INIT_LIST_HEAD(&net->nft.af_info);
        INIT_LIST_HEAD(&net->nft.commit_list);
+       net->nft.base_seq = 1;
        return 0;
 }
 
index 345acfb1720b14f00aae0e5937ab07bfb90e9482..3b90eb2b2c55453e989c891a3f815be6e1da22d1 100644 (file)
@@ -109,7 +109,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
        struct nft_data data[NFT_REG_MAX + 1];
        unsigned int stackptr = 0;
        struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
-       struct nft_stats __percpu *stats;
+       struct nft_stats *stats;
        int rulenum;
        /*
         * Cache cursor to avoid problems in case that the cursor is updated
@@ -205,9 +205,11 @@ next_rule:
                nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY);
 
        rcu_read_lock_bh();
-       stats = rcu_dereference(nft_base_chain(basechain)->stats);
-       __this_cpu_inc(stats->pkts);
-       __this_cpu_add(stats->bytes, pkt->skb->len);
+       stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats));
+       u64_stats_update_begin(&stats->syncp);
+       stats->pkts++;
+       stats->bytes += pkt->skb->len;
+       u64_stats_update_end(&stats->syncp);
        rcu_read_unlock_bh();
 
        return nft_base_chain(basechain)->policy;
index c39b583ace3229d4bae6a7b3774593e5eebd7141..70c0be8d0121db461c1e21793a1b68d844f37e8b 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/errno.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
+#include <linux/bitmap.h>
 #include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
@@ -460,17 +461,25 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)
        return 0;
 }
 
+#define NR_U32_NODE (1<<12)
 static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle)
 {
        struct tc_u_knode *n;
-       unsigned int i = 0x7FF;
+       unsigned long i;
+       unsigned long *bitmap = kzalloc(BITS_TO_LONGS(NR_U32_NODE) * sizeof(unsigned long),
+                                       GFP_KERNEL);
+       if (!bitmap)
+               return handle | 0xFFF;
 
        for (n = ht->ht[TC_U32_HASH(handle)]; n; n = n->next)
-               if (i < TC_U32_NODE(n->handle))
-                       i = TC_U32_NODE(n->handle);
-       i++;
+               set_bit(TC_U32_NODE(n->handle), bitmap);
 
-       return handle | (i > 0xFFF ? 0xFFF : i);
+       i = find_next_zero_bit(bitmap, NR_U32_NODE, 0x800);
+       if (i >= NR_U32_NODE)
+               i = find_next_zero_bit(bitmap, NR_U32_NODE, 1);
+
+       kfree(bitmap);
+       return handle | (i >= NR_U32_NODE ? 0xFFF : i);
 }
 
 static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
index 6af50eb80ea7517680dbb7b18981eb9906fde5ae..70faa3a325264a68511a2edca0efa225ebe40942 100644 (file)
@@ -379,11 +379,11 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
        struct special_params *params = bebob->maudio_special_quirk;
        int err, id;
 
-       mutex_lock(&bebob->mutex);
-
        id = uval->value.enumerated.item[0];
        if (id >= ARRAY_SIZE(special_clk_labels))
-               return 0;
+               return -EINVAL;
+
+       mutex_lock(&bebob->mutex);
 
        err = avc_maudio_set_special_clk(bebob, id,
                                         params->dig_in_fmt,
@@ -391,7 +391,10 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
                                         params->clk_lock);
        mutex_unlock(&bebob->mutex);
 
-       return err >= 0;
+       if (err >= 0)
+               err = 1;
+
+       return err;
 }
 static struct snd_kcontrol_new special_clk_ctl = {
        .name   = "Clock Source",
@@ -434,8 +437,8 @@ static struct snd_kcontrol_new special_sync_ctl = {
        .get    = special_sync_ctl_get,
 };
 
-/* Digital interface control for special firmware */
-static char *const special_dig_iface_labels[] = {
+/* Digital input interface control for special firmware */
+static char *const special_dig_in_iface_labels[] = {
        "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical"
 };
 static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
@@ -443,13 +446,13 @@ static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
 {
        einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        einf->count = 1;
-       einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels);
+       einf->value.enumerated.items = ARRAY_SIZE(special_dig_in_iface_labels);
 
        if (einf->value.enumerated.item >= einf->value.enumerated.items)
                einf->value.enumerated.item = einf->value.enumerated.items - 1;
 
        strcpy(einf->value.enumerated.name,
-              special_dig_iface_labels[einf->value.enumerated.item]);
+              special_dig_in_iface_labels[einf->value.enumerated.item]);
 
        return 0;
 }
@@ -491,26 +494,36 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
        unsigned int id, dig_in_fmt, dig_in_iface;
        int err;
 
-       mutex_lock(&bebob->mutex);
-
        id = uval->value.enumerated.item[0];
+       if (id >= ARRAY_SIZE(special_dig_in_iface_labels))
+               return -EINVAL;
 
        /* decode user value */
        dig_in_fmt = (id >> 1) & 0x01;
        dig_in_iface = id & 0x01;
 
+       mutex_lock(&bebob->mutex);
+
        err = avc_maudio_set_special_clk(bebob,
                                         params->clk_src,
                                         dig_in_fmt,
                                         params->dig_out_fmt,
                                         params->clk_lock);
-       if ((err < 0) || (params->dig_in_fmt > 0)) /* ADAT */
+       if (err < 0)
+               goto end;
+
+       /* For ADAT, optical interface is only available. */
+       if (params->dig_in_fmt > 0) {
+               err = 1;
                goto end;
+       }
 
+       /* For S/PDIF, optical/coaxial interfaces are selectable. */
        err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
        if (err < 0)
                dev_err(&bebob->unit->device,
                        "fail to set digital input interface: %d\n", err);
+       err = 1;
 end:
        special_stream_formation_set(bebob);
        mutex_unlock(&bebob->mutex);
@@ -525,18 +538,22 @@ static struct snd_kcontrol_new special_dig_in_iface_ctl = {
        .put    = special_dig_in_iface_ctl_set
 };
 
+/* Digital output interface control for special firmware */
+static char *const special_dig_out_iface_labels[] = {
+       "S/PDIF Optical and Coaxial", "ADAT Optical"
+};
 static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl,
                                          struct snd_ctl_elem_info *einf)
 {
        einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        einf->count = 1;
-       einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels) - 1;
+       einf->value.enumerated.items = ARRAY_SIZE(special_dig_out_iface_labels);
 
        if (einf->value.enumerated.item >= einf->value.enumerated.items)
                einf->value.enumerated.item = einf->value.enumerated.items - 1;
 
        strcpy(einf->value.enumerated.name,
-              special_dig_iface_labels[einf->value.enumerated.item + 1]);
+              special_dig_out_iface_labels[einf->value.enumerated.item]);
 
        return 0;
 }
@@ -558,16 +575,20 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
        unsigned int id;
        int err;
 
-       mutex_lock(&bebob->mutex);
-
        id = uval->value.enumerated.item[0];
+       if (id >= ARRAY_SIZE(special_dig_out_iface_labels))
+               return -EINVAL;
+
+       mutex_lock(&bebob->mutex);
 
        err = avc_maudio_set_special_clk(bebob,
                                         params->clk_src,
                                         params->dig_in_fmt,
                                         id, params->clk_lock);
-       if (err >= 0)
+       if (err >= 0) {
                special_stream_formation_set(bebob);
+               err = 1;
+       }
 
        mutex_unlock(&bebob->mutex);
        return err;
index e5a3c4be2a10d696c31aebc733234964197affad..3d1537b93c645968410463b75c2721ca4d7c1949 100644 (file)
@@ -108,13 +108,18 @@ DUMP_OBJS = \
        apmain.o\
        osunixdir.o\
        osunixmap.o\
+       osunixxf.o\
        tbprint.o\
        tbxfroot.o\
        utbuffer.o\
+       utdebug.o\
        utexcep.o\
+       utglobal.o\
        utmath.o\
+       utprint.o\
        utstring.o\
        utxferror.o\
+       oslibcfs.o\
        oslinuxtbl.o\
        cmfsize.o\
        getopt.o
index 5140e5edae1fb0d48fd9eb9a0adf6d63f421b0f6..f4b953354ff7e28fa11e86b9b260754ad78c7e99 100644 (file)
@@ -58,44 +58,46 @@ ACPI_MODULE_NAME("cmfsize")
  * RETURN:      File Size. On error, -1 (ACPI_UINT32_MAX)
  *
  * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
- *              Does not disturb the current file pointer. Uses perror for
- *              error messages.
+ *              Does not disturb the current file pointer.
  *
  ******************************************************************************/
-u32 cm_get_file_size(FILE * file)
+u32 cm_get_file_size(ACPI_FILE file)
 {
        long file_size;
        long current_offset;
+       acpi_status status;
 
        /* Save the current file pointer, seek to EOF to obtain file size */
 
-       current_offset = ftell(file);
+       current_offset = acpi_os_get_file_offset(file);
        if (current_offset < 0) {
                goto offset_error;
        }
 
-       if (fseek(file, 0, SEEK_END)) {
+       status = acpi_os_set_file_offset(file, 0, ACPI_FILE_END);
+       if (ACPI_FAILURE(status)) {
                goto seek_error;
        }
 
-       file_size = ftell(file);
+       file_size = acpi_os_get_file_offset(file);
        if (file_size < 0) {
                goto offset_error;
        }
 
        /* Restore original file pointer */
 
-       if (fseek(file, current_offset, SEEK_SET)) {
+       status = acpi_os_set_file_offset(file, current_offset, ACPI_FILE_BEGIN);
+       if (ACPI_FAILURE(status)) {
                goto seek_error;
        }
 
        return ((u32)file_size);
 
 offset_error:
-       perror("Could not get file offset");
+       acpi_log_error("Could not get file offset");
        return (ACPI_UINT32_MAX);
 
 seek_error:
-       perror("Could not seek file");
+       acpi_log_error("Could not set file offset");
        return (ACPI_UINT32_MAX);
 }
index a302f52e4fd354d08aa2502ba181ae2fff566d5d..2f0f34a36db4440660c51366fa4f2bcf2aa6343d 100644 (file)
  *    "f|"      - Option has required single-char sub-options
  */
 
-#include <stdio.h>
-#include <string.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acapps.h"
 
 #define ACPI_OPTION_ERROR(msg, badchar) \
-       if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
+       if (acpi_gbl_opterr) {acpi_log_error ("%s%c\n", msg, badchar);}
 
 int acpi_gbl_opterr = 1;
 int acpi_gbl_optind = 1;
@@ -113,7 +111,7 @@ int acpi_getopt_argument(int argc, char **argv)
  * PARAMETERS:  argc, argv          - from main
  *              opts                - options info list
  *
- * RETURN:      Option character or EOF
+ * RETURN:      Option character or ACPI_OPT_END
  *
  * DESCRIPTION: Get the next option
  *
@@ -128,10 +126,10 @@ int acpi_getopt(int argc, char **argv, char *opts)
                if (acpi_gbl_optind >= argc ||
                    argv[acpi_gbl_optind][0] != '-' ||
                    argv[acpi_gbl_optind][1] == '\0') {
-                       return (EOF);
-               } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
+                       return (ACPI_OPT_END);
+               } else if (ACPI_STRCMP(argv[acpi_gbl_optind], "--") == 0) {
                        acpi_gbl_optind++;
-                       return (EOF);
+                       return (ACPI_OPT_END);
                }
        }
 
@@ -142,7 +140,7 @@ int acpi_getopt(int argc, char **argv, char *opts)
        /* Make sure that the option is legal */
 
        if (current_char == ':' ||
-           (opts_ptr = strchr(opts, current_char)) == NULL) {
+           (opts_ptr = ACPI_STRCHR(opts, current_char)) == NULL) {
                ACPI_OPTION_ERROR("Illegal option: -", current_char);
 
                if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
new file mode 100644 (file)
index 0000000..c13ff9c
--- /dev/null
@@ -0,0 +1,214 @@
+/******************************************************************************
+ *
+ * Module Name: oslibcfs - C library OSL for file I/O
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define _COMPONENT          ACPI_OS_SERVICES
+ACPI_MODULE_NAME("oslibcfs")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_open_file
+ *
+ * PARAMETERS:  path                - File path
+ *              modes               - File operation type
+ *
+ * RETURN:      File descriptor.
+ *
+ * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
+ *              (ACPI_FILE_WRITING).
+ *
+ ******************************************************************************/
+ACPI_FILE acpi_os_open_file(const char *path, u8 modes)
+{
+       ACPI_FILE file;
+       u32 i = 0;
+       char modes_str[4];
+
+       if (modes & ACPI_FILE_READING) {
+               modes_str[i++] = 'r';
+       }
+       if (modes & ACPI_FILE_WRITING) {
+               modes_str[i++] = 'w';
+       }
+       if (modes & ACPI_FILE_BINARY) {
+               modes_str[i++] = 'b';
+       }
+
+       modes_str[i++] = '\0';
+
+       file = fopen(path, modes_str);
+       if (!file) {
+               perror("Could not open file");
+       }
+
+       return (file);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_close_file
+ *
+ * PARAMETERS:  file                - An open file descriptor
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Close a file opened via acpi_os_open_file.
+ *
+ ******************************************************************************/
+
+void acpi_os_close_file(ACPI_FILE file)
+{
+       fclose(file);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_file
+ *
+ * PARAMETERS:  file                - An open file descriptor
+ *              buffer              - Data buffer
+ *              size                - Data block size
+ *              count               - Number of data blocks
+ *
+ * RETURN:      Number of bytes actually read.
+ *
+ * DESCRIPTION: Read from a file.
+ *
+ ******************************************************************************/
+
+int
+acpi_os_read_file(ACPI_FILE file, void *buffer, acpi_size size, acpi_size count)
+{
+       int length;
+
+       length = fread(buffer, size, count, file);
+       if (length < 0) {
+               perror("Error reading file");
+       }
+
+       return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_file
+ *
+ * PARAMETERS:  file                - An open file descriptor
+ *              buffer              - Data buffer
+ *              size                - Data block size
+ *              count               - Number of data blocks
+ *
+ * RETURN:      Number of bytes actually written.
+ *
+ * DESCRIPTION: Write to a file.
+ *
+ ******************************************************************************/
+
+int
+acpi_os_write_file(ACPI_FILE file,
+                  void *buffer, acpi_size size, acpi_size count)
+{
+       int length;
+
+       length = fwrite(buffer, size, count, file);
+       if (length < 0) {
+               perror("Error writing file");
+       }
+
+       return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_file_offset
+ *
+ * PARAMETERS:  file                - An open file descriptor
+ *
+ * RETURN:      Current file pointer position.
+ *
+ * DESCRIPTION: Get current file offset.
+ *
+ ******************************************************************************/
+
+long acpi_os_get_file_offset(ACPI_FILE file)
+{
+       long offset;
+
+       offset = ftell(file);
+       return (offset);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_os_set_file_offset
+ *
+ * PARAMETERS:  file                - An open file descriptor
+ *              offset              - New file offset
+ *              from                - From begin/end of file
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Set current file offset.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from)
+{
+       int ret = 0;
+
+       if (from == ACPI_FILE_BEGIN) {
+               ret = fseek(file, offset, SEEK_SET);
+       }
+       if (from == ACPI_FILE_END) {
+               ret = fseek(file, offset, SEEK_END);
+       }
+
+       if (ret < 0) {
+               return (AE_ERROR);
+       } else {
+               return (AE_OK);
+       }
+}
index 28c52008e854ad8fe8b58372867f654cc5df2ea5..0dc2485dedf5e5f68c2c409ef7ee5fa6facc8d48 100644 (file)
@@ -77,6 +77,9 @@ osl_map_table(acpi_size address,
 
 static void osl_unmap_table(struct acpi_table_header *table);
 
+static acpi_physical_address
+osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword);
+
 static acpi_physical_address osl_find_rsdp_via_efi(void);
 
 static acpi_status osl_load_rsdp(void);
@@ -415,6 +418,38 @@ acpi_os_get_table_by_index(u32 index,
        return (status);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:    osl_find_rsdp_via_efi_by_keyword
+ *
+ * PARAMETERS:  keyword         - Character string indicating ACPI GUID version
+ *                                in the EFI table
+ *
+ * RETURN:      RSDP address if found
+ *
+ * DESCRIPTION: Find RSDP address via EFI using keyword indicating the ACPI
+ *              GUID version.
+ *
+ *****************************************************************************/
+
+static acpi_physical_address
+osl_find_rsdp_via_efi_by_keyword(FILE * file, const char *keyword)
+{
+       char buffer[80];
+       unsigned long long address = 0;
+       char format[32];
+
+       snprintf(format, 32, "%s=%s", keyword, "%llx");
+       fseek(file, 0, SEEK_SET);
+       while (fgets(buffer, 80, file)) {
+               if (sscanf(buffer, format, &address) == 1) {
+                       break;
+               }
+       }
+
+       return ((acpi_physical_address) (address));
+}
+
 /******************************************************************************
  *
  * FUNCTION:    osl_find_rsdp_via_efi
@@ -430,20 +465,19 @@ acpi_os_get_table_by_index(u32 index,
 static acpi_physical_address osl_find_rsdp_via_efi(void)
 {
        FILE *file;
-       char buffer[80];
-       unsigned long address = 0;
+       acpi_physical_address address = 0;
 
        file = fopen(EFI_SYSTAB, "r");
        if (file) {
-               while (fgets(buffer, 80, file)) {
-                       if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) {
-                               break;
-                       }
+               address = osl_find_rsdp_via_efi_by_keyword(file, "ACPI20");
+               if (!address) {
+                       address =
+                           osl_find_rsdp_via_efi_by_keyword(file, "ACPI");
                }
                fclose(file);
        }
 
-       return ((acpi_physical_address) (address));
+       return (address);
 }
 
 /******************************************************************************
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c
new file mode 100644 (file)
index 0000000..60b58cd
--- /dev/null
@@ -0,0 +1,1311 @@
+/******************************************************************************
+ *
+ * Module Name: osunixxf - UNIX OSL interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * These interfaces are required in order to compile the ASL compiler and the
+ * various ACPICA tools under Linux or other Unix-like system.
+ */
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "amlcode.h"
+#include "acparser.h"
+#include "acdebug.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <errno.h>
+
+#define _COMPONENT          ACPI_OS_SERVICES
+ACPI_MODULE_NAME("osunixxf")
+
+u8 acpi_gbl_debug_timeout = FALSE;
+
+/* Upcalls to acpi_exec */
+
+void
+ae_table_override(struct acpi_table_header *existing_table,
+                 struct acpi_table_header **new_table);
+
+typedef void *(*PTHREAD_CALLBACK) (void *);
+
+/* Buffer used by acpi_os_vprintf */
+
+#define ACPI_VPRINTF_BUFFER_SIZE    512
+#define _ASCII_NEWLINE              '\n'
+
+/* Terminal support for acpi_exec only */
+
+#ifdef ACPI_EXEC_APP
+#include <termios.h>
+
+struct termios original_term_attributes;
+int term_attributes_were_set = 0;
+
+acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read);
+
+static void os_enter_line_edit_mode(void);
+
+static void os_exit_line_edit_mode(void);
+
+/******************************************************************************
+ *
+ * FUNCTION:    os_enter_line_edit_mode, os_exit_line_edit_mode
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
+ *
+ * Interactive line-editing support for the AML debugger. Used with the
+ * common/acgetline module.
+ *
+ * readline() is not used because of non-portability. It is not available
+ * on all systems, and if it is, often the package must be manually installed.
+ *
+ * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
+ * editing that we need in acpi_os_get_line.
+ *
+ * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
+ * calls will also work:
+ *     For os_enter_line_edit_mode: system ("stty cbreak -echo")
+ *     For os_exit_line_edit_mode: system ("stty cooked echo")
+ *
+ *****************************************************************************/
+
+static void os_enter_line_edit_mode(void)
+{
+       struct termios local_term_attributes;
+
+       /* Get and keep the original attributes */
+
+       if (tcgetattr(STDIN_FILENO, &original_term_attributes)) {
+               fprintf(stderr, "Could not get terminal attributes!\n");
+               return;
+       }
+
+       /* Set the new attributes to enable raw character input */
+
+       memcpy(&local_term_attributes, &original_term_attributes,
+              sizeof(struct termios));
+
+       local_term_attributes.c_lflag &= ~(ICANON | ECHO);
+       local_term_attributes.c_cc[VMIN] = 1;
+       local_term_attributes.c_cc[VTIME] = 0;
+
+       if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) {
+               fprintf(stderr, "Could not set terminal attributes!\n");
+               return;
+       }
+
+       term_attributes_were_set = 1;
+}
+
+static void os_exit_line_edit_mode(void)
+{
+
+       if (!term_attributes_were_set) {
+               return;
+       }
+
+       /* Set terminal attributes back to the original values */
+
+       if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) {
+               fprintf(stderr, "Could not restore terminal attributes!\n");
+       }
+}
+
+#else
+
+/* These functions are not needed for other ACPICA utilities */
+
+#define os_enter_line_edit_mode()
+#define os_exit_line_edit_mode()
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_initialize, acpi_os_terminate
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize and terminate this module.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_initialize(void)
+{
+       acpi_status status;
+
+       acpi_gbl_output_file = stdout;
+
+       os_enter_line_edit_mode();
+
+       status = acpi_os_create_lock(&acpi_gbl_print_lock);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       return (AE_OK);
+}
+
+acpi_status acpi_os_terminate(void)
+{
+
+       os_exit_line_edit_mode();
+       return (AE_OK);
+}
+
+#ifndef ACPI_USE_NATIVE_RSDP_POINTER
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_root_pointer
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      RSDP physical address
+ *
+ * DESCRIPTION: Gets the ACPI root pointer (RSDP)
+ *
+ *****************************************************************************/
+
+acpi_physical_address acpi_os_get_root_pointer(void)
+{
+
+       return (0);
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_predefined_override
+ *
+ * PARAMETERS:  init_val            - Initial value of the predefined object
+ *              new_val             - The new value for the object
+ *
+ * RETURN:      Status, pointer to value. Null pointer returned if not
+ *              overriding.
+ *
+ * DESCRIPTION: Allow the OS to override predefined names
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_predefined_override(const struct acpi_predefined_names * init_val,
+                           acpi_string * new_val)
+{
+
+       if (!init_val || !new_val) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       *new_val = NULL;
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_table_override
+ *
+ * PARAMETERS:  existing_table      - Header of current table (probably
+ *                                    firmware)
+ *              new_table           - Where an entire new table is returned.
+ *
+ * RETURN:      Status, pointer to new table. Null pointer returned if no
+ *              table is available to override
+ *
+ * DESCRIPTION: Return a different version of a table if one is available
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_table_override(struct acpi_table_header * existing_table,
+                      struct acpi_table_header ** new_table)
+{
+
+       if (!existing_table || !new_table) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       *new_table = NULL;
+
+#ifdef ACPI_EXEC_APP
+
+       ae_table_override(existing_table, new_table);
+       return (AE_OK);
+#else
+
+       return (AE_NO_ACPI_TABLES);
+#endif
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_physical_table_override
+ *
+ * PARAMETERS:  existing_table      - Header of current table (probably firmware)
+ *              new_address         - Where new table address is returned
+ *                                    (Physical address)
+ *              new_table_length    - Where new table length is returned
+ *
+ * RETURN:      Status, address/length of new table. Null pointer returned
+ *              if no table is available to override.
+ *
+ * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_physical_table_override(struct acpi_table_header * existing_table,
+                               acpi_physical_address * new_address,
+                               u32 *new_table_length)
+{
+
+       return (AE_SUPPORT);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_redirect_output
+ *
+ * PARAMETERS:  destination         - An open file handle/pointer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf
+ *
+ *****************************************************************************/
+
+void acpi_os_redirect_output(void *destination)
+{
+
+       acpi_gbl_output_file = destination;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_printf
+ *
+ * PARAMETERS:  fmt, ...            - Standard printf format
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf
+ *              (performance), changes should be tracked in both functions.
+ *
+ *****************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
+{
+       va_list args;
+       u8 flags;
+
+       flags = acpi_gbl_db_output_flags;
+       if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
+
+               /* Output is directable to either a file (if open) or the console */
+
+               if (acpi_gbl_debug_file) {
+
+                       /* Output file is open, send the output there */
+
+                       va_start(args, fmt);
+                       vfprintf(acpi_gbl_debug_file, fmt, args);
+                       va_end(args);
+               } else {
+                       /* No redirection, send output to console (once only!) */
+
+                       flags |= ACPI_DB_CONSOLE_OUTPUT;
+               }
+       }
+
+       if (flags & ACPI_DB_CONSOLE_OUTPUT) {
+               va_start(args, fmt);
+               vfprintf(acpi_gbl_output_file, fmt, args);
+               va_end(args);
+       }
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_vprintf
+ *
+ * PARAMETERS:  fmt                 - Standard printf format
+ *              args                - Argument list
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Formatted output with argument list pointer. Note: very
+ *              similar to acpi_os_printf, changes should be tracked in both
+ *              functions.
+ *
+ *****************************************************************************/
+
+void acpi_os_vprintf(const char *fmt, va_list args)
+{
+       u8 flags;
+       char buffer[ACPI_VPRINTF_BUFFER_SIZE];
+
+       /*
+        * We build the output string in a local buffer because we may be
+        * outputting the buffer twice. Using vfprintf is problematic because
+        * some implementations modify the args pointer/structure during
+        * execution. Thus, we use the local buffer for portability.
+        *
+        * Note: Since this module is intended for use by the various ACPICA
+        * utilities/applications, we can safely declare the buffer on the stack.
+        * Also, This function is used for relatively small error messages only.
+        */
+       vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args);
+
+       flags = acpi_gbl_db_output_flags;
+       if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
+
+               /* Output is directable to either a file (if open) or the console */
+
+               if (acpi_gbl_debug_file) {
+
+                       /* Output file is open, send the output there */
+
+                       fputs(buffer, acpi_gbl_debug_file);
+               } else {
+                       /* No redirection, send output to console (once only!) */
+
+                       flags |= ACPI_DB_CONSOLE_OUTPUT;
+               }
+       }
+
+       if (flags & ACPI_DB_CONSOLE_OUTPUT) {
+               fputs(buffer, acpi_gbl_output_file);
+       }
+}
+
+#ifndef ACPI_EXEC_APP
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_line
+ *
+ * PARAMETERS:  buffer              - Where to return the command line
+ *              buffer_length       - Maximum length of Buffer
+ *              bytes_read          - Where the actual byte count is returned
+ *
+ * RETURN:      Status and actual bytes read
+ *
+ * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
+ *              acpi_exec utility, we use the acgetline module instead to
+ *              provide line-editing and history support.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
+{
+       int input_char;
+       u32 end_of_line;
+
+       /* Standard acpi_os_get_line for all utilities except acpi_exec */
+
+       for (end_of_line = 0;; end_of_line++) {
+               if (end_of_line >= buffer_length) {
+                       return (AE_BUFFER_OVERFLOW);
+               }
+
+               if ((input_char = getchar()) == EOF) {
+                       return (AE_ERROR);
+               }
+
+               if (!input_char || input_char == _ASCII_NEWLINE) {
+                       break;
+               }
+
+               buffer[end_of_line] = (char)input_char;
+       }
+
+       /* Null terminate the buffer */
+
+       buffer[end_of_line] = 0;
+
+       /* Return the number of bytes in the string */
+
+       if (bytes_read) {
+               *bytes_read = end_of_line;
+       }
+
+       return (AE_OK);
+}
+#endif
+
+#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_map_memory
+ *
+ * PARAMETERS:  where               - Physical address of memory to be mapped
+ *              length              - How much memory to map
+ *
+ * RETURN:      Pointer to mapped memory. Null on error.
+ *
+ * DESCRIPTION: Map physical memory into caller's address space
+ *
+ *****************************************************************************/
+
+void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
+{
+
+       return (ACPI_TO_POINTER((acpi_size) where));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_unmap_memory
+ *
+ * PARAMETERS:  where               - Logical address of memory to be unmapped
+ *              length              - How much memory to unmap
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete a previously created mapping. Where and Length must
+ *              correspond to a previous mapping exactly.
+ *
+ *****************************************************************************/
+
+void acpi_os_unmap_memory(void *where, acpi_size length)
+{
+
+       return;
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_allocate
+ *
+ * PARAMETERS:  size                - Amount to allocate, in bytes
+ *
+ * RETURN:      Pointer to the new allocation. Null on error.
+ *
+ * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
+ *
+ *****************************************************************************/
+
+void *acpi_os_allocate(acpi_size size)
+{
+       void *mem;
+
+       mem = (void *)malloc((size_t) size);
+       return (mem);
+}
+
+#ifdef USE_NATIVE_ALLOCATE_ZEROED
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_allocate_zeroed
+ *
+ * PARAMETERS:  size                - Amount to allocate, in bytes
+ *
+ * RETURN:      Pointer to the new allocation. Null on error.
+ *
+ * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
+ *
+ *****************************************************************************/
+
+void *acpi_os_allocate_zeroed(acpi_size size)
+{
+       void *mem;
+
+       mem = (void *)calloc(1, (size_t) size);
+       return (mem);
+}
+#endif
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_free
+ *
+ * PARAMETERS:  mem                 - Pointer to previously allocated memory
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free memory allocated via acpi_os_allocate
+ *
+ *****************************************************************************/
+
+void acpi_os_free(void *mem)
+{
+
+       free(mem);
+}
+
+#ifdef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION:    Semaphore stub functions
+ *
+ * DESCRIPTION: Stub functions used for single-thread applications that do
+ *              not require semaphore synchronization. Full implementations
+ *              of these functions appear after the stubs.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_create_semaphore(u32 max_units,
+                        u32 initial_units, acpi_handle * out_handle)
+{
+       *out_handle = (acpi_handle) 1;
+       return (AE_OK);
+}
+
+acpi_status acpi_os_delete_semaphore(acpi_handle handle)
+{
+       return (AE_OK);
+}
+
+acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
+{
+       return (AE_OK);
+}
+
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+{
+       return (AE_OK);
+}
+
+#else
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_create_semaphore
+ *
+ * PARAMETERS:  initial_units       - Units to be assigned to the new semaphore
+ *              out_handle          - Where a handle will be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create an OS semaphore
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_create_semaphore(u32 max_units,
+                        u32 initial_units, acpi_handle * out_handle)
+{
+       sem_t *sem;
+
+       if (!out_handle) {
+               return (AE_BAD_PARAMETER);
+       }
+#ifdef __APPLE__
+       {
+               char *semaphore_name = tmpnam(NULL);
+
+               sem =
+                   sem_open(semaphore_name, O_EXCL | O_CREAT, 0755,
+                            initial_units);
+               if (!sem) {
+                       return (AE_NO_MEMORY);
+               }
+               sem_unlink(semaphore_name);     /* This just deletes the name */
+       }
+
+#else
+       sem = acpi_os_allocate(sizeof(sem_t));
+       if (!sem) {
+               return (AE_NO_MEMORY);
+       }
+
+       if (sem_init(sem, 0, initial_units) == -1) {
+               acpi_os_free(sem);
+               return (AE_BAD_PARAMETER);
+       }
+#endif
+
+       *out_handle = (acpi_handle) sem;
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_delete_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete an OS semaphore
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_delete_semaphore(acpi_handle handle)
+{
+       sem_t *sem = (sem_t *) handle;
+
+       if (!sem) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       if (sem_destroy(sem) == -1) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_wait_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *              units               - How many units to wait for
+ *              msec_timeout        - How long to wait (milliseconds)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Wait for units
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout)
+{
+       acpi_status status = AE_OK;
+       sem_t *sem = (sem_t *) handle;
+#ifndef ACPI_USE_ALTERNATE_TIMEOUT
+       struct timespec time;
+       int ret_val;
+#endif
+
+       if (!sem) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       switch (msec_timeout) {
+               /*
+                * No Wait:
+                * --------
+                * A zero timeout value indicates that we shouldn't wait - just
+                * acquire the semaphore if available otherwise return AE_TIME
+                * (a.k.a. 'would block').
+                */
+       case 0:
+
+               if (sem_trywait(sem) == -1) {
+                       status = (AE_TIME);
+               }
+               break;
+
+               /* Wait Indefinitely */
+
+       case ACPI_WAIT_FOREVER:
+
+               if (sem_wait(sem)) {
+                       status = (AE_TIME);
+               }
+               break;
+
+               /* Wait with msec_timeout */
+
+       default:
+
+#ifdef ACPI_USE_ALTERNATE_TIMEOUT
+               /*
+                * Alternate timeout mechanism for environments where
+                * sem_timedwait is not available or does not work properly.
+                */
+               while (msec_timeout) {
+                       if (sem_trywait(sem) == 0) {
+
+                               /* Got the semaphore */
+                               return (AE_OK);
+                       }
+
+                       if (msec_timeout >= 10) {
+                               msec_timeout -= 10;
+                               usleep(10 * ACPI_USEC_PER_MSEC);        /* ten milliseconds */
+                       } else {
+                               msec_timeout--;
+                               usleep(ACPI_USEC_PER_MSEC);     /* one millisecond */
+                       }
+               }
+               status = (AE_TIME);
+#else
+               /*
+                * The interface to sem_timedwait is an absolute time, so we need to
+                * get the current time, then add in the millisecond Timeout value.
+                */
+               if (clock_gettime(CLOCK_REALTIME, &time) == -1) {
+                       perror("clock_gettime");
+                       return (AE_TIME);
+               }
+
+               time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC);
+               time.tv_nsec +=
+                   ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
+
+               /* Handle nanosecond overflow (field must be less than one second) */
+
+               if (time.tv_nsec >= ACPI_NSEC_PER_SEC) {
+                       time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC);
+                       time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC);
+               }
+
+               while (((ret_val = sem_timedwait(sem, &time)) == -1)
+                      && (errno == EINTR)) {
+                       continue;
+               }
+
+               if (ret_val != 0) {
+                       if (errno != ETIMEDOUT) {
+                               perror("sem_timedwait");
+                       }
+                       status = (AE_TIME);
+               }
+#endif
+               break;
+       }
+
+       return (status);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_signal_semaphore
+ *
+ * PARAMETERS:  handle              - Handle returned by acpi_os_create_semaphore
+ *              units               - Number of units to send
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Send units
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
+{
+       sem_t *sem = (sem_t *) handle;
+
+       if (!sem) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       if (sem_post(sem) == -1) {
+               return (AE_LIMIT);
+       }
+
+       return (AE_OK);
+}
+
+#endif                         /* ACPI_SINGLE_THREADED */
+
+/******************************************************************************
+ *
+ * FUNCTION:    Spinlock interfaces
+ *
+ * DESCRIPTION: Map these interfaces to semaphore interfaces
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_create_lock(acpi_spinlock * out_handle)
+{
+
+       return (acpi_os_create_semaphore(1, 1, out_handle));
+}
+
+void acpi_os_delete_lock(acpi_spinlock handle)
+{
+       acpi_os_delete_semaphore(handle);
+}
+
+acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)
+{
+       acpi_os_wait_semaphore(handle, 1, 0xFFFF);
+       return (0);
+}
+
+void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags)
+{
+       acpi_os_signal_semaphore(handle, 1);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_install_interrupt_handler
+ *
+ * PARAMETERS:  interrupt_number    - Level handler should respond to.
+ *              isr                 - Address of the ACPI interrupt handler
+ *              except_ptr          - Where status is returned
+ *
+ * RETURN:      Handle to the newly installed handler.
+ *
+ * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
+ *              OS-independent handler.
+ *
+ *****************************************************************************/
+
+u32
+acpi_os_install_interrupt_handler(u32 interrupt_number,
+                                 acpi_osd_handler service_routine,
+                                 void *context)
+{
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_remove_interrupt_handler
+ *
+ * PARAMETERS:  handle              - Returned when handler was installed
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Uninstalls an interrupt handler.
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_remove_interrupt_handler(u32 interrupt_number,
+                                acpi_osd_handler service_routine)
+{
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_stall
+ *
+ * PARAMETERS:  microseconds        - Time to sleep
+ *
+ * RETURN:      Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at microsecond granularity
+ *
+ *****************************************************************************/
+
+void acpi_os_stall(u32 microseconds)
+{
+
+       if (microseconds) {
+               usleep(microseconds);
+       }
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_sleep
+ *
+ * PARAMETERS:  milliseconds        - Time to sleep
+ *
+ * RETURN:      Blocks until sleep is completed.
+ *
+ * DESCRIPTION: Sleep at millisecond granularity
+ *
+ *****************************************************************************/
+
+void acpi_os_sleep(u64 milliseconds)
+{
+
+       /* Sleep for whole seconds */
+
+       sleep(milliseconds / ACPI_MSEC_PER_SEC);
+
+       /*
+        * Sleep for remaining microseconds.
+        * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
+        */
+       usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_timer
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Current time in 100 nanosecond units
+ *
+ * DESCRIPTION: Get the current system time
+ *
+ *****************************************************************************/
+
+u64 acpi_os_get_timer(void)
+{
+       struct timeval time;
+
+       /* This timer has sufficient resolution for user-space application code */
+
+       gettimeofday(&time, NULL);
+
+       /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
+
+       return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) +
+               ((u64)time.tv_usec * ACPI_100NSEC_PER_USEC));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_pci_configuration
+ *
+ * PARAMETERS:  pci_id              - Seg/Bus/Dev
+ *              pci_register        - Device Register
+ *              value               - Buffer where value is placed
+ *              width               - Number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read data from PCI configuration space
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
+                              u32 pci_register, u64 *value, u32 width)
+{
+
+       *value = 0;
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_pci_configuration
+ *
+ * PARAMETERS:  pci_id              - Seg/Bus/Dev
+ *              pci_register        - Device Register
+ *              value               - Value to be written
+ *              width               - Number of bits
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Write data to PCI configuration space
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id,
+                               u32 pci_register, u64 value, u32 width)
+{
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_port
+ *
+ * PARAMETERS:  address             - Address of I/O port/register to read
+ *              value               - Where value is placed
+ *              width               - Number of bits
+ *
+ * RETURN:      Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+
+       switch (width) {
+       case 8:
+
+               *value = 0xFF;
+               break;
+
+       case 16:
+
+               *value = 0xFFFF;
+               break;
+
+       case 32:
+
+               *value = 0xFFFFFFFF;
+               break;
+
+       default:
+
+               return (AE_BAD_PARAMETER);
+       }
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_port
+ *
+ * PARAMETERS:  address             - Address of I/O port/register to write
+ *              value               - Value to write
+ *              width               - Number of bits
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to an I/O port or register
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width)
+{
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_read_memory
+ *
+ * PARAMETERS:  address             - Physical Memory Address to read
+ *              value               - Where value is placed
+ *              width               - Number of bits (8,16,32, or 64)
+ *
+ * RETURN:      Value read from physical memory address. Always returned
+ *              as a 64-bit integer, regardless of the read width.
+ *
+ * DESCRIPTION: Read data from a physical memory address
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width)
+{
+
+       switch (width) {
+       case 8:
+       case 16:
+       case 32:
+       case 64:
+
+               *value = 0;
+               break;
+
+       default:
+
+               return (AE_BAD_PARAMETER);
+       }
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_write_memory
+ *
+ * PARAMETERS:  address             - Physical Memory Address to write
+ *              value               - Value to write
+ *              width               - Number of bits (8,16,32, or 64)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to a physical memory address
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width)
+{
+
+       return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_readable
+ *
+ * PARAMETERS:  pointer             - Area to be verified
+ *              length              - Size of area
+ *
+ * RETURN:      TRUE if readable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for reading
+ *
+ *****************************************************************************/
+
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+
+       return (TRUE);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_writable
+ *
+ * PARAMETERS:  pointer             - Area to be verified
+ *              length              - Size of area
+ *
+ * RETURN:      TRUE if writable for entire length
+ *
+ * DESCRIPTION: Verify that a pointer is valid for writing
+ *
+ *****************************************************************************/
+
+u8 acpi_os_writable(void *pointer, acpi_size length)
+{
+
+       return (TRUE);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_signal
+ *
+ * PARAMETERS:  function            - ACPI A signal function code
+ *              info                - Pointer to function-dependent structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Miscellaneous functions. Example implementation only.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_os_signal(u32 function, void *info)
+{
+
+       switch (function) {
+       case ACPI_SIGNAL_FATAL:
+
+               break;
+
+       case ACPI_SIGNAL_BREAKPOINT:
+
+               break;
+
+       default:
+
+               break;
+       }
+
+       return (AE_OK);
+}
+
+/* Optional multi-thread support */
+
+#ifndef ACPI_SINGLE_THREADED
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_get_thread_id
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Id of the running thread
+ *
+ * DESCRIPTION: Get the ID of the current (running) thread
+ *
+ *****************************************************************************/
+
+acpi_thread_id acpi_os_get_thread_id(void)
+{
+       pthread_t thread;
+
+       thread = pthread_self();
+       return (ACPI_CAST_PTHREAD_T(thread));
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_execute
+ *
+ * PARAMETERS:  type                - Type of execution
+ *              function            - Address of the function to execute
+ *              context             - Passed as a parameter to the function
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Execute a new thread
+ *
+ *****************************************************************************/
+
+acpi_status
+acpi_os_execute(acpi_execute_type type,
+               acpi_osd_exec_callback function, void *context)
+{
+       pthread_t thread;
+       int ret;
+
+       ret =
+           pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context);
+       if (ret) {
+               acpi_os_printf("Create thread failed");
+       }
+       return (0);
+}
+
+#else                          /* ACPI_SINGLE_THREADED */
+acpi_thread_id acpi_os_get_thread_id(void)
+{
+       return (1);
+}
+
+acpi_status
+acpi_os_execute(acpi_execute_type type,
+               acpi_osd_exec_callback function, void *context)
+{
+
+       function(context);
+
+       return (AE_OK);
+}
+
+#endif                         /* ACPI_SINGLE_THREADED */
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_os_wait_events_complete
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Wait for all asynchronous events to complete. This
+ *              implementation does nothing.
+ *
+ *****************************************************************************/
+
+void acpi_os_wait_events_complete(void)
+{
+       return;
+}
index 46f519597fe5eb4a8e2f8674f2bcaef29f31eb0c..a2d37d610639afaf4fc1f23e6742ae74001f6bdd 100644 (file)
@@ -47,7 +47,6 @@
 #ifdef _DECLARE_GLOBALS
 #define EXTERN
 #define INIT_GLOBAL(a,b)        a=b
-#define DEFINE_ACPI_GLOBALS     1
 #else
 #define EXTERN                  extern
 #define INIT_GLOBAL(a,b)        a
@@ -69,7 +68,7 @@ EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE);
 EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE);
 EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE);
 EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE);
-EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL);
+EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL);
 EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
 EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
 
index 3cac123783663083849b8589d893b3059075552c..53cee781e24e646f98a041ff1906b1fb13158a3a 100644 (file)
@@ -69,17 +69,16 @@ u8 ap_is_valid_header(struct acpi_table_header *table)
                /* Make sure signature is all ASCII and a valid ACPI name */
 
                if (!acpi_ut_valid_acpi_name(table->signature)) {
-                       fprintf(stderr,
-                               "Table signature (0x%8.8X) is invalid\n",
-                               *(u32 *)table->signature);
+                       acpi_log_error("Table signature (0x%8.8X) is invalid\n",
+                                      *(u32 *)table->signature);
                        return (FALSE);
                }
 
                /* Check for minimum table length */
 
                if (table->length < sizeof(struct acpi_table_header)) {
-                       fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
-                               table->length);
+                       acpi_log_error("Table length (0x%8.8X) is invalid\n",
+                                      table->length);
                        return (FALSE);
                }
        }
@@ -116,8 +115,8 @@ u8 ap_is_valid_checksum(struct acpi_table_header *table)
        }
 
        if (ACPI_FAILURE(status)) {
-               fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
-                       table->signature);
+               acpi_log_error("%4.4s: Warning: wrong checksum in table\n",
+                              table->signature);
        }
 
        return (AE_OK);
@@ -196,12 +195,13 @@ ap_dump_table_buffer(struct acpi_table_header *table,
         * Note: simplest to just always emit a 64-bit address. acpi_xtract
         * utility can handle this.
         */
-       printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature,
-              ACPI_FORMAT_UINT64(address));
+       acpi_ut_file_printf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
+                           table->signature, ACPI_FORMAT_UINT64(address));
 
-       acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length,
-                           DB_BYTE_DISPLAY, 0);
-       printf("\n");
+       acpi_ut_dump_buffer_to_file(gbl_output_file,
+                                   ACPI_CAST_PTR(u8, table), table_length,
+                                   DB_BYTE_DISPLAY, 0);
+       acpi_ut_file_printf(gbl_output_file, "\n");
        return (0);
 }
 
@@ -239,20 +239,20 @@ int ap_dump_all_tables(void)
                        if (status == AE_LIMIT) {
                                return (0);
                        } else if (i == 0) {
-                               fprintf(stderr,
-                                       "Could not get ACPI tables, %s\n",
-                                       acpi_format_exception(status));
+                               acpi_log_error
+                                   ("Could not get ACPI tables, %s\n",
+                                    acpi_format_exception(status));
                                return (-1);
                        } else {
-                               fprintf(stderr,
-                                       "Could not get ACPI table at index %u, %s\n",
-                                       i, acpi_format_exception(status));
+                               acpi_log_error
+                                   ("Could not get ACPI table at index %u, %s\n",
+                                    i, acpi_format_exception(status));
                                continue;
                        }
                }
 
                table_status = ap_dump_table_buffer(table, instance, address);
-               free(table);
+               ACPI_FREE(table);
 
                if (table_status) {
                        break;
@@ -288,22 +288,22 @@ int ap_dump_table_by_address(char *ascii_address)
 
        status = acpi_ut_strtoul64(ascii_address, 0, &long_address);
        if (ACPI_FAILURE(status)) {
-               fprintf(stderr, "%s: Could not convert to a physical address\n",
-                       ascii_address);
+               acpi_log_error("%s: Could not convert to a physical address\n",
+                              ascii_address);
                return (-1);
        }
 
        address = (acpi_physical_address) long_address;
        status = acpi_os_get_table_by_address(address, &table);
        if (ACPI_FAILURE(status)) {
-               fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
-                       ACPI_FORMAT_UINT64(address),
-                       acpi_format_exception(status));
+               acpi_log_error("Could not get table at 0x%8.8X%8.8X, %s\n",
+                              ACPI_FORMAT_UINT64(address),
+                              acpi_format_exception(status));
                return (-1);
        }
 
        table_status = ap_dump_table_buffer(table, 0, address);
-       free(table);
+       ACPI_FREE(table);
        return (table_status);
 }
 
@@ -329,24 +329,24 @@ int ap_dump_table_by_name(char *signature)
        acpi_status status;
        int table_status;
 
-       if (strlen(signature) != ACPI_NAME_SIZE) {
-               fprintf(stderr,
-                       "Invalid table signature [%s]: must be exactly 4 characters\n",
-                       signature);
+       if (ACPI_STRLEN(signature) != ACPI_NAME_SIZE) {
+               acpi_log_error
+                   ("Invalid table signature [%s]: must be exactly 4 characters\n",
+                    signature);
                return (-1);
        }
 
        /* Table signatures are expected to be uppercase */
 
-       strcpy(local_signature, signature);
+       ACPI_STRCPY(local_signature, signature);
        acpi_ut_strupr(local_signature);
 
        /* To be friendly, handle tables whose signatures do not match the name */
 
        if (ACPI_COMPARE_NAME(local_signature, "FADT")) {
-               strcpy(local_signature, ACPI_SIG_FADT);
+               ACPI_STRCPY(local_signature, ACPI_SIG_FADT);
        } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) {
-               strcpy(local_signature, ACPI_SIG_MADT);
+               ACPI_STRCPY(local_signature, ACPI_SIG_MADT);
        }
 
        /* Dump all instances of this signature (to handle multiple SSDTs) */
@@ -362,14 +362,14 @@ int ap_dump_table_by_name(char *signature)
                                return (0);
                        }
 
-                       fprintf(stderr,
-                               "Could not get ACPI table with signature [%s], %s\n",
-                               local_signature, acpi_format_exception(status));
+                       acpi_log_error
+                           ("Could not get ACPI table with signature [%s], %s\n",
+                            local_signature, acpi_format_exception(status));
                        return (-1);
                }
 
                table_status = ap_dump_table_buffer(table, instance, address);
-               free(table);
+               ACPI_FREE(table);
 
                if (table_status) {
                        break;
@@ -409,43 +409,21 @@ int ap_dump_table_from_file(char *pathname)
        /* File must be at least as long as the table length */
 
        if (table->length > file_size) {
-               fprintf(stderr,
-                       "Table length (0x%X) is too large for input file (0x%X) %s\n",
-                       table->length, file_size, pathname);
+               acpi_log_error
+                   ("Table length (0x%X) is too large for input file (0x%X) %s\n",
+                    table->length, file_size, pathname);
                goto exit;
        }
 
        if (gbl_verbose_mode) {
-               fprintf(stderr,
-                       "Input file:  %s contains table [%4.4s], 0x%X (%u) bytes\n",
-                       pathname, table->signature, file_size, file_size);
+               acpi_log_error
+                   ("Input file:  %s contains table [%4.4s], 0x%X (%u) bytes\n",
+                    pathname, table->signature, file_size, file_size);
        }
 
        table_status = ap_dump_table_buffer(table, 0, 0);
 
 exit:
-       free(table);
+       ACPI_FREE(table);
        return (table_status);
 }
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_os* print functions
- *
- * DESCRIPTION: Used for linkage with ACPICA modules
- *
- ******************************************************************************/
-
-void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
-{
-       va_list args;
-
-       va_start(args, fmt);
-       vfprintf(stdout, fmt, args);
-       va_end(args);
-}
-
-void acpi_os_vprintf(const char *fmt, va_list args)
-{
-       vfprintf(stdout, fmt, args);
-}
index 4488accc010b1d4b1b0ebd57ce9a168578491519..d470046a6d81ae9e89b0da80173cb4a277bcfce2 100644 (file)
 #include "acpidump.h"
 #include "acapps.h"
 
+/* Local prototypes */
+
+static int ap_is_existing_file(char *pathname);
+
+static int ap_is_existing_file(char *pathname)
+{
+#ifndef _GNU_EFI
+       struct stat stat_info;
+
+       if (!stat(pathname, &stat_info)) {
+               acpi_log_error("Target path already exists, overwrite? [y|n] ");
+
+               if (getchar() != 'y') {
+                       return (-1);
+               }
+       }
+#endif
+
+       return 0;
+}
+
 /******************************************************************************
  *
  * FUNCTION:    ap_open_output_file
 
 int ap_open_output_file(char *pathname)
 {
-       struct stat stat_info;
-       FILE *file;
+       ACPI_FILE file;
 
        /* If file exists, prompt for overwrite */
 
-       if (!stat(pathname, &stat_info)) {
-               fprintf(stderr,
-                       "Target path already exists, overwrite? [y|n] ");
-
-               if (getchar() != 'y') {
-                       return (-1);
-               }
+       if (ap_is_existing_file(pathname) != 0) {
+               return (-1);
        }
 
        /* Point stdout to the file */
 
-       file = freopen(pathname, "w", stdout);
+       file = acpi_os_open_file(pathname, ACPI_FILE_WRITING);
        if (!file) {
-               perror("Could not open output file");
+               acpi_log_error("Could not open output file: %s\n", pathname);
                return (-1);
        }
 
@@ -106,7 +121,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
 {
        char filename[ACPI_NAME_SIZE + 16];
        char instance_str[16];
-       FILE *file;
+       ACPI_FILE file;
        size_t actual;
        u32 table_length;
 
@@ -130,35 +145,37 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
        /* Handle multiple SSDts - create different filenames for each */
 
        if (instance > 0) {
-               sprintf(instance_str, "%u", instance);
-               strcat(filename, instance_str);
+               acpi_ut_snprintf(instance_str, sizeof(instance_str), "%u",
+                                instance);
+               ACPI_STRCAT(filename, instance_str);
        }
 
-       strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+       ACPI_STRCAT(filename, ACPI_TABLE_FILE_SUFFIX);
 
        if (gbl_verbose_mode) {
-               fprintf(stderr,
-                       "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
-                       table->signature, filename, table->length,
-                       table->length);
+               acpi_log_error
+                   ("Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
+                    table->signature, filename, table->length, table->length);
        }
 
        /* Open the file and dump the entire table in binary mode */
 
-       file = fopen(filename, "wb");
+       file = acpi_os_open_file(filename,
+                                ACPI_FILE_WRITING | ACPI_FILE_BINARY);
        if (!file) {
-               perror("Could not open output file");
+               acpi_log_error("Could not open output file: %s\n", filename);
                return (-1);
        }
 
-       actual = fwrite(table, 1, table_length, file);
+       actual = acpi_os_write_file(file, table, 1, table_length);
        if (actual != table_length) {
-               perror("Error writing binary output file");
-               fclose(file);
+               acpi_log_error("Error writing binary output file: %s\n",
+                              filename);
+               acpi_os_close_file(file);
                return (-1);
        }
 
-       fclose(file);
+       acpi_os_close_file(file);
        return (0);
 }
 
@@ -179,15 +196,16 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
                                                 u32 *out_file_size)
 {
        struct acpi_table_header *buffer = NULL;
-       FILE *file;
+       ACPI_FILE file;
        u32 file_size;
        size_t actual;
 
        /* Must use binary mode */
 
-       file = fopen(pathname, "rb");
+       file =
+           acpi_os_open_file(pathname, ACPI_FILE_READING | ACPI_FILE_BINARY);
        if (!file) {
-               perror("Could not open input file");
+               acpi_log_error("Could not open input file: %s\n", pathname);
                return (NULL);
        }
 
@@ -195,27 +213,25 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
 
        file_size = cm_get_file_size(file);
        if (file_size == ACPI_UINT32_MAX) {
-               fprintf(stderr,
-                       "Could not get input file size: %s\n", pathname);
+               acpi_log_error("Could not get input file size: %s\n", pathname);
                goto cleanup;
        }
 
        /* Allocate a buffer for the entire file */
 
-       buffer = calloc(1, file_size);
+       buffer = ACPI_ALLOCATE_ZEROED(file_size);
        if (!buffer) {
-               fprintf(stderr,
-                       "Could not allocate file buffer of size: %u\n",
-                       file_size);
+               acpi_log_error("Could not allocate file buffer of size: %u\n",
+                              file_size);
                goto cleanup;
        }
 
        /* Read the entire file */
 
-       actual = fread(buffer, 1, file_size, file);
+       actual = acpi_os_read_file(file, buffer, 1, file_size);
        if (actual != file_size) {
-               fprintf(stderr, "Could not read input file: %s\n", pathname);
-               free(buffer);
+               acpi_log_error("Could not read input file: %s\n", pathname);
+               ACPI_FREE(buffer);
                buffer = NULL;
                goto cleanup;
        }
@@ -223,6 +239,6 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
        *out_file_size = file_size;
 
 cleanup:
-       fclose(file);
+       acpi_os_close_file(file);
        return (buffer);
 }
index 51e8d638db18d06b38cdbca6c9285a2fb9ebd194..853b4da22c3e12ef509e26db30651cb6e12de5cd 100644 (file)
@@ -72,7 +72,7 @@ static void ap_display_usage(void);
 
 static int ap_do_options(int argc, char **argv);
 
-static void ap_insert_action(char *argument, u32 to_be_done);
+static int ap_insert_action(char *argument, u32 to_be_done);
 
 /* Table for deferred actions from command line options */
 
@@ -104,7 +104,7 @@ static void ap_display_usage(void)
        ACPI_OPTION("-v", "Display version information");
        ACPI_OPTION("-z", "Verbose mode");
 
-       printf("\nTable Options:\n");
+       ACPI_USAGE_TEXT("\nTable Options:\n");
 
        ACPI_OPTION("-a <Address>", "Get table via a physical address");
        ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file");
@@ -112,9 +112,9 @@ static void ap_display_usage(void)
        ACPI_OPTION("-x", "Do not use but dump XSDT");
        ACPI_OPTION("-x -x", "Do not use or dump XSDT");
 
-       printf("\n"
-              "Invocation without parameters dumps all available tables\n"
-              "Multiple mixed instances of -a, -f, and -n are supported\n\n");
+       ACPI_USAGE_TEXT("\n"
+                       "Invocation without parameters dumps all available tables\n"
+                       "Multiple mixed instances of -a, -f, and -n are supported\n\n");
 }
 
 /******************************************************************************
@@ -124,13 +124,13 @@ static void ap_display_usage(void)
  * PARAMETERS:  argument            - Pointer to the argument for this action
  *              to_be_done          - What to do to process this action
  *
- * RETURN:      None. Exits program if action table becomes full.
+ * RETURN:      Status
  *
  * DESCRIPTION: Add an action item to the action table
  *
  ******************************************************************************/
 
-static void ap_insert_action(char *argument, u32 to_be_done)
+static int ap_insert_action(char *argument, u32 to_be_done)
 {
 
        /* Insert action and check for table overflow */
@@ -140,10 +140,12 @@ static void ap_insert_action(char *argument, u32 to_be_done)
 
        current_action++;
        if (current_action > AP_MAX_ACTIONS) {
-               fprintf(stderr, "Too many table options (max %u)\n",
-                       AP_MAX_ACTIONS);
-               exit(-1);
+               acpi_log_error("Too many table options (max %u)\n",
+                              AP_MAX_ACTIONS);
+               return (-1);
        }
+
+       return (0);
 }
 
 /******************************************************************************
@@ -166,7 +168,8 @@ static int ap_do_options(int argc, char **argv)
 
        /* Command line options */
 
-       while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF)
+       while ((j =
+               acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END)
                switch (j) {
                        /*
                         * Global options
@@ -185,12 +188,12 @@ static int ap_do_options(int argc, char **argv)
                case '?':
 
                        ap_display_usage();
-                       exit(0);
+                       return (1);
 
                case 'o':       /* Redirect output to a single file */
 
                        if (ap_open_output_file(acpi_gbl_optarg)) {
-                               exit(-1);
+                               return (-1);
                        }
                        continue;
 
@@ -200,10 +203,10 @@ static int ap_do_options(int argc, char **argv)
                            acpi_ut_strtoul64(acpi_gbl_optarg, 0,
                                              &gbl_rsdp_base);
                        if (ACPI_FAILURE(status)) {
-                               fprintf(stderr,
-                                       "%s: Could not convert to a physical address\n",
-                                       acpi_gbl_optarg);
-                               exit(-1);
+                               acpi_log_error
+                                   ("%s: Could not convert to a physical address\n",
+                                    acpi_gbl_optarg);
+                               return (-1);
                        }
                        continue;
 
@@ -223,13 +226,13 @@ static int ap_do_options(int argc, char **argv)
 
                case 'v':       /* Revision/version */
 
-                       printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
-                       exit(0);
+                       acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
+                       return (1);
 
                case 'z':       /* Verbose mode */
 
                        gbl_verbose_mode = TRUE;
-                       fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
+                       acpi_log_error(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
                        continue;
 
                        /*
@@ -237,32 +240,40 @@ static int ap_do_options(int argc, char **argv)
                         */
                case 'a':       /* Get table by physical address */
 
-                       ap_insert_action(acpi_gbl_optarg,
-                                        AP_DUMP_TABLE_BY_ADDRESS);
+                       if (ap_insert_action
+                           (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) {
+                               return (-1);
+                       }
                        break;
 
                case 'f':       /* Get table from a file */
 
-                       ap_insert_action(acpi_gbl_optarg,
-                                        AP_DUMP_TABLE_BY_FILE);
+                       if (ap_insert_action
+                           (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) {
+                               return (-1);
+                       }
                        break;
 
                case 'n':       /* Get table by input name (signature) */
 
-                       ap_insert_action(acpi_gbl_optarg,
-                                        AP_DUMP_TABLE_BY_NAME);
+                       if (ap_insert_action
+                           (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) {
+                               return (-1);
+                       }
                        break;
 
                default:
 
                        ap_display_usage();
-                       exit(-1);
+                       return (-1);
                }
 
        /* If there are no actions, this means "get/dump all tables" */
 
        if (current_action == 0) {
-               ap_insert_action(NULL, AP_DUMP_ALL_TABLES);
+               if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) {
+                       return (-1);
+               }
        }
 
        return (0);
@@ -280,7 +291,11 @@ static int ap_do_options(int argc, char **argv)
  *
  ******************************************************************************/
 
+#ifndef _GNU_EFI
 int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
+#else
+int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
+#endif
 {
        int status = 0;
        struct ap_dump_action *action;
@@ -288,11 +303,17 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
        u32 i;
 
        ACPI_DEBUG_INITIALIZE();        /* For debug version only */
+       acpi_os_initialize();
+       gbl_output_file = ACPI_FILE_OUT;
 
        /* Process command line options */
 
-       if (ap_do_options(argc, argv)) {
-               return (-1);
+       status = ap_do_options(argc, argv);
+       if (status > 0) {
+               return (0);
+       }
+       if (status < 0) {
+               return (status);
        }
 
        /* Get/dump ACPI table(s) as requested */
@@ -322,9 +343,8 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
 
                default:
 
-                       fprintf(stderr,
-                               "Internal error, invalid action: 0x%X\n",
-                               action->to_be_done);
+                       acpi_log_error("Internal error, invalid action: 0x%X\n",
+                                      action->to_be_done);
                        return (-1);
                }
 
@@ -333,18 +353,18 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[])
                }
        }
 
-       if (gbl_output_file) {
+       if (gbl_output_filename) {
                if (gbl_verbose_mode) {
 
                        /* Summary for the output file */
 
                        file_size = cm_get_file_size(gbl_output_file);
-                       fprintf(stderr,
-                               "Output file %s contains 0x%X (%u) bytes\n\n",
-                               gbl_output_filename, file_size, file_size);
+                       acpi_log_error
+                           ("Output file %s contains 0x%X (%u) bytes\n\n",
+                            gbl_output_filename, file_size, file_size);
                }
 
-               fclose(gbl_output_file);
+               acpi_os_close_file(gbl_output_file);
        }
 
        return (status);