Merge branches 'pm-cpufreq' and 'pm-cpuidle'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sun, 1 Nov 2015 23:54:10 +0000 (00:54 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sun, 1 Nov 2015 23:54:10 +0000 (00:54 +0100)
* pm-cpufreq:
  cpufreq: postfix policy directory with the first CPU in related_cpus
  cpufreq: create cpu/cpufreq/policyX directories
  cpufreq: remove cpufreq_sysfs_{create|remove}_file()
  cpufreq: create cpu/cpufreq at boot time
  cpufreq: Use cpumask_copy instead of cpumask_or to copy a mask
  cpufreq: ondemand: Drop unnecessary locks from update_sampling_rate()
  cpufreq: intel_pstate: Fix intel_pstate powersave min_perf_pct value
  cpufreq: intel_pstate: Avoid calculation for max/min
  Documentation: kernel_parameters for Intel P state driver
  cpufreq: intel_pstate: Use ACPI perf configuration
  cpufreq: intel-pstate: Use separate max pstate for scaling
  cpufreq: intel_pstate: get P1 from TAR when available
  cpufreq: Drop redundant check for inactive policies
  cpufreq : powernv: Report Pmax throttling if capped below nominal frequency
  cpufreq: imx: update the clock switch flow to support imx6ul
  cpufreq: tegra20: remove superfluous CONFIG_PM ifdefs
  cpufreq: conservative: remove 'enable' field
  cpufreq: integrator: Fix module autoload for OF platform driver

* pm-cpuidle:
  cpuidle: mvebu: disable the bind/unbind attributes and use builtin_platform_driver
  cpuidle: mvebu: clean up multiple platform drivers

500 files changed:
.mailmap
Documentation/ABI/testing/sysfs-power
Documentation/arm/OMAP/README [new file with mode: 0644]
Documentation/kernel-parameters.txt
MAINTAINERS
Makefile
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/armada-385-db-ap.dts
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/meson.dtsi
arch/arm/boot/dts/omap3-evm-37xx.dts
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
arch/arm/kernel/time.c
arch/arm/kvm/Kconfig
arch/arm/kvm/arm.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-rockchip/rockchip.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-spear/spear13xx.c
arch/arm/mach-sunxi/sunxi.c
arch/arm/mach-u300/core.c
arch/arm/mach-ux500/timer.c
arch/arm/mach-zynq/common.c
arch/arm/net/bpf_jit_32.c
arch/arm/plat-orion/common.c
arch/arm64/Makefile
arch/arm64/include/asm/acpi.h
arch/arm64/include/asm/irq.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/include/uapi/asm/signal.h
arch/arm64/kernel/acpi.c
arch/arm64/kernel/time.c
arch/ia64/include/asm/pci.h
arch/ia64/pci/pci.c
arch/microblaze/kernel/setup.c
arch/mips/pistachio/time.c
arch/mips/ralink/clk.c
arch/nios2/kernel/time.c
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/cache.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/rtas.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/mm/hash_native_64.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/smp.c
arch/powerpc/platforms/ps3/os-area.c
arch/sh/include/asm/page.h
arch/sparc/crypto/aes_glue.c
arch/sparc/crypto/camellia_glue.c
arch/sparc/crypto/des_glue.c
arch/um/Makefile
arch/um/kernel/trap.c
arch/um/os-Linux/helper.c
arch/x86/boot/compressed/eboot.c
arch/x86/crypto/camellia_aesni_avx_glue.c
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/string_64.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/process.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/emulate.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/pci/acpi.c
arch/x86/um/ldt.c
arch/xtensa/kernel/time.c
block/blk-core.c
block/blk-mq-tag.c
block/blk-mq.c
block/blk-sysfs.c
crypto/ahash.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_pad.c
drivers/acpi/acpi_pnp.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/acinterp.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acopcode.h
drivers/acpi/acpica/acparser.h
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/amlcode.h
drivers/acpi/acpica/dbcmds.c [new file with mode: 0644]
drivers/acpi/acpica/dbconvert.c [new file with mode: 0644]
drivers/acpi/acpica/dbdisply.c [new file with mode: 0644]
drivers/acpi/acpica/dbexec.c [new file with mode: 0644]
drivers/acpi/acpica/dbfileio.c [new file with mode: 0644]
drivers/acpi/acpica/dbhistry.c [new file with mode: 0644]
drivers/acpi/acpica/dbinput.c [new file with mode: 0644]
drivers/acpi/acpica/dbmethod.c [new file with mode: 0644]
drivers/acpi/acpica/dbnames.c [new file with mode: 0644]
drivers/acpi/acpica/dbobject.c [new file with mode: 0644]
drivers/acpi/acpica/dbstats.c [new file with mode: 0644]
drivers/acpi/acpica/dbtest.c [new file with mode: 0644]
drivers/acpi/acpica/dbutils.c [new file with mode: 0644]
drivers/acpi/acpica/dbxface.c [new file with mode: 0644]
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/exconvrt.c
drivers/acpi/acpica/exresolv.c
drivers/acpi/acpica/exresop.c
drivers/acpi/acpica/exstore.c
drivers/acpi/acpica/exstoren.c
drivers/acpi/acpica/nsdump.c
drivers/acpi/acpica/nspredef.c
drivers/acpi/acpica/pstree.c
drivers/acpi/acpica/psutils.c
drivers/acpi/acpica/rsdump.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/utdecode.c
drivers/acpi/acpica/utfileio.c
drivers/acpi/acpica/utinit.c
drivers/acpi/acpica/utmutex.c
drivers/acpi/acpica/utxface.c
drivers/acpi/cppc_acpi.c [new file with mode: 0644]
drivers/acpi/device_pm.c
drivers/acpi/device_sysfs.c
drivers/acpi/ec.c
drivers/acpi/glue.c
drivers/acpi/internal.h
drivers/acpi/nfit.c
drivers/acpi/nfit.h
drivers/acpi/osl.c
drivers/acpi/pci_root.c
drivers/acpi/proc.c
drivers/acpi/processor_driver.c
drivers/acpi/property.c
drivers/acpi/resource.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/tables.c
drivers/acpi/video_detect.c
drivers/base/dma-contiguous.c
drivers/base/power/domain_governor.c
drivers/base/power/generic_ops.c
drivers/base/power/wakeup.c
drivers/base/property.c
drivers/block/nbd.c
drivers/block/nvme-core.c
drivers/block/rbd.c
drivers/block/xen-blkfront.c
drivers/bus/arm-ccn.c
drivers/clk/mvebu/clk-cpu.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/arm_arch_timer.c
drivers/clocksource/clksrc-of.c [deleted file]
drivers/clocksource/clksrc-probe.c [new file with mode: 0644]
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/cppc_cpufreq.c [new file with mode: 0644]
drivers/cpuidle/cpuidle-mvebu-v7.c
drivers/dma/acpi-dma.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/ci_dpm.c
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/cz_dpm.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/kv_dpm.c
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/i915/i915_gem_shrinker.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c
drivers/gpu/drm/qxl/qxl_display.c
drivers/gpu/drm/qxl/qxl_fb.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/si_dpm.c
drivers/gpu/drm/virtio/virtgpu_debugfs.c
drivers/gpu/drm/virtio/virtgpu_fence.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/i2c-core.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/twl4030-madc.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/usnic/usnic.h
drivers/infiniband/hw/usnic/usnic_abi.h
drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h
drivers/infiniband/hw/usnic/usnic_common_util.h
drivers/infiniband/hw/usnic/usnic_debugfs.c
drivers/infiniband/hw/usnic/usnic_debugfs.h
drivers/infiniband/hw/usnic/usnic_fwd.c
drivers/infiniband/hw/usnic/usnic_fwd.h
drivers/infiniband/hw/usnic/usnic_ib.h
drivers/infiniband/hw/usnic/usnic_ib_main.c
drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c
drivers/infiniband/hw/usnic/usnic_ib_sysfs.h
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/usnic/usnic_log.h
drivers/infiniband/hw/usnic/usnic_transport.c
drivers/infiniband/hw/usnic/usnic_transport.h
drivers/infiniband/hw/usnic/usnic_uiom.c
drivers/infiniband/hw/usnic/usnic_uiom.h
drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
drivers/infiniband/hw/usnic/usnic_vnic.c
drivers/infiniband/hw/usnic/usnic_vnic.h
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/mouse/cyapa_gen6.c
drivers/input/serio/i8042.c
drivers/input/touchscreen/ads7846.c
drivers/iommu/Kconfig
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/arm-smmu-v3.c
drivers/iommu/intel-iommu.c
drivers/iommu/io-pgtable-arm.c
drivers/irqchip/irq-gic.c
drivers/irqchip/irqchip.c
drivers/md/dm-cache-metadata.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-thin.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/persistent-data/dm-btree.c
drivers/media/dvb-frontends/horus3a.h
drivers/media/dvb-frontends/lnbh25.h
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/dvb-frontends/si2168.c
drivers/media/pci/netup_unidvb/netup_unidvb_spi.c
drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
drivers/media/rc/ir-hix5hd2.c
drivers/media/tuners/si2157.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.h
drivers/media/v4l2-core/Kconfig
drivers/memory/Kconfig
drivers/memory/omap-gpmc.c
drivers/mfd/intel-lpss.h
drivers/mfd/max77843.c
drivers/misc/cxl/api.c
drivers/misc/cxl/context.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/file.c
drivers/misc/cxl/irq.c
drivers/misc/cxl/native.c
drivers/misc/cxl/pci.c
drivers/mmc/card/mmc_test.c
drivers/mmc/core/mmc.c
drivers/net/can/sja1000/peak_pci.c
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40evf/i40e_adminq.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
drivers/net/ethernet/mellanox/mlx5/core/port.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/item.h
drivers/net/ethernet/mellanox/mlxsw/pci.c
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/via/via-rhine.c
drivers/net/geneve.c
drivers/net/phy/Kconfig
drivers/net/ppp/pppoe.c
drivers/net/usb/Kconfig
drivers/net/usb/asix_common.c
drivers/net/usb/asix_devices.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/xen-netback/xenbus.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/perf/arm_pmu.c
drivers/pinctrl/freescale/pinctrl-imx25.c
drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
drivers/pinctrl/uniphier/pinctrl-ph1-sld8.c
drivers/pnp/pnpacpi/core.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/thermal/samsung/exynos_tmu.c
drivers/tty/serial/8250/8250_dma.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/video/console/fbcon.c
fs/btrfs/backref.c
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/btrfs/volumes.h
fs/cifs/file.c
fs/dax.c
fs/ext4/Kconfig
fs/ext4/readpage.c
fs/fs-writeback.c
fs/mpage.c
fs/nfsd/blocklayout.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ramfs/file-nommu.c
include/acpi/acexcep.h
include/acpi/acpi_bus.h
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/acpi/actbl1.h
include/acpi/cppc_acpi.h [new file with mode: 0644]
include/acpi/platform/acenv.h
include/acpi/platform/aclinux.h
include/acpi/platform/aclinuxex.h
include/acpi/processor.h
include/asm-generic/vmlinux.lds.h
include/drm/drm_dp_mst_helper.h
include/linux/acpi.h
include/linux/acpi_irq.h [deleted file]
include/linux/backing-dev-defs.h
include/linux/backing-dev.h
include/linux/clocksource.h
include/linux/cma.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/dma-contiguous.h
include/linux/fwnode.h
include/linux/ioport.h
include/linux/irqchip.h
include/linux/irqchip/arm-gic-acpi.h [deleted file]
include/linux/memcontrol.h
include/linux/pci-acpi.h
include/linux/pm.h
include/linux/property.h
include/linux/suspend.h
include/net/af_unix.h
include/net/inet_timewait_sock.h
include/net/sock.h
include/sound/soc.h
include/sound/wm8904.h
include/uapi/asm-generic/signal.h
include/uapi/linux/openvswitch.h
include/uapi/linux/rtnetlink.h
kernel/irq/msi.c
kernel/irq/pm.c
kernel/kmod.c
kernel/power/hibernate.c
kernel/power/main.c
kernel/power/suspend.c
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/fair.c
kernel/sched/idle.c
kernel/time/timekeeping.c
kernel/trace/trace_stack.c
kernel/workqueue.c
lib/Kconfig
lib/Kconfig.debug
lib/fault-inject.c
mm/backing-dev.c
mm/cma.c
mm/filemap.c
mm/huge_memory.c
mm/memcontrol.c
mm/memory.c
mm/page-writeback.c
mm/readahead.c
mm/vmstat.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/ceph/osd_client.c
net/core/ethtool.c
net/core/filter.c
net/dsa/dsa.c
net/ipv4/arp.c
net/ipv4/inet_connection_sock.c
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/ipv6/xfrm6_policy.c
net/mac80211/debugfs.c
net/mac80211/status.c
net/mac80211/tx.c
net/netlink/af_netlink.c
net/openvswitch/actions.c
net/openvswitch/conntrack.c
net/openvswitch/conntrack.h
net/openvswitch/flow.h
net/openvswitch/flow_netlink.c
net/openvswitch/flow_table.c
net/openvswitch/vport.c
net/sched/act_mirred.c
net/sched/sch_hhf.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/verbs.c
net/switchdev/switchdev.c
net/tipc/msg.h
net/tipc/node.c
net/unix/af_unix.c
scripts/package/builddeb
security/keys/gc.c
security/keys/request_key.c
sound/hda/ext/hdac_ext_bus.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_conexant.c
sound/soc/codecs/rt298.c
sound/soc/codecs/wm8962.c
sound/soc/soc-ops.c
tools/power/acpi/tools/acpidump/apfiles.c
tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c
virt/kvm/arm/arch_timer.c
virt/kvm/arm/vgic.c

index 4b31af54ccd5864359c0810f9733f3026181a631..b1e9a97653dc64853775a97db377a8f269cc8d95 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -59,6 +59,7 @@ James Bottomley <jejb@mulgrave.(none)>
 James Bottomley <jejb@titanic.il.steeleye.com>
 James E Wilson <wilson@specifix.com>
 James Ketrenos <jketreno@io.(none)>
+<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
 Jean Tourrilhes <jt@hpl.hp.com>
 Jeff Garzik <jgarzik@pretzel.yyz.us>
 Jens Axboe <axboe@suse.de>
index f4551816329e17ae8020a256211b499776c19e4b..50b368d490b599f29809e55bbdd0a29535163fa4 100644 (file)
@@ -256,3 +256,15 @@ Description:
                Writing a "1" enables this printing while writing a "0"
                disables it.  The default value is "0".  Reading from this file
                will display the current value.
+
+What:          /sys/power/pm_wakeup_irq
+Date:          April 2015
+Contact:       Alexandra Yates <alexandra.yates@linux.intel.org>
+Description:
+               The /sys/power/pm_wakeup_irq file reports to user space the IRQ
+               number of the first wakeup interrupt (that is, the first
+               interrupt from an IRQ line armed for system wakeup) seen by the
+               kernel during the most recent system suspend/resume cycle.
+
+               This output is useful for system wakeup diagnostics of spurious
+               wakeup interrupts.
diff --git a/Documentation/arm/OMAP/README b/Documentation/arm/OMAP/README
new file mode 100644 (file)
index 0000000..75645c4
--- /dev/null
@@ -0,0 +1,7 @@
+This file contains documentation for running mainline
+kernel on omaps.
+
+KERNEL         NEW DEPENDENCIES
+v4.3+          Update is needed for custom .config files to make sure
+               CONFIG_REGULATOR_PBIAS is enabled for MMC1 to work
+               properly.
index 9b75e2a760de47ec86e0a83672751534bc54e284..a491aaecc8bb569bf88aa51f4eb238b358ddcd51 100644 (file)
@@ -167,7 +167,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
        acpi=           [HW,ACPI,X86,ARM64]
                        Advanced Configuration and Power Interface
-                       Format: { force | off | strict | noirq | rsdt }
+                       Format: { force | off | strict | noirq | rsdt |
+                                 copy_dsdt }
                        force -- enable ACPI if default was off
                        off -- disable ACPI if default was on
                        noirq -- do not use ACPI for IRQ routing
index 5f467845ef725f42cca522e9f02bf93292c42d4a..9de185da5f5b0dfe1be0730b8248b3aff44e0c84 100644 (file)
@@ -894,11 +894,12 @@ M:        Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
-ARM/Allwinner A1X SoC support
+ARM/Allwinner sunXi SoC support
 M:     Maxime Ripard <maxime.ripard@free-electrons.com>
+M:     Chen-Yu Tsai <wens@csie.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-N:     sun[x4567]i
+N:     sun[x456789]i
 
 ARM/Allwinner SoC Clock Support
 M:     Emilio López <emilio@elopez.com.ar>
@@ -3591,6 +3592,13 @@ F:       drivers/gpu/drm/i915/
 F:     include/drm/i915*
 F:     include/uapi/drm/i915*
 
+DRM DRIVERS FOR ATMEL HLCDC
+M:     Boris Brezillon <boris.brezillon@free-electrons.com>
+L:     dri-devel@lists.freedesktop.org
+S:     Supported
+F:     drivers/gpu/drm/atmel-hlcdc/
+F:     Documentation/devicetree/bindings/drm/atmel/
+
 DRM DRIVERS FOR EXYNOS
 M:     Inki Dae <inki.dae@samsung.com>
 M:     Joonyoung Shim <jy0922.shim@samsung.com>
@@ -3619,6 +3627,14 @@ S:       Maintained
 F:     drivers/gpu/drm/imx/
 F:     Documentation/devicetree/bindings/drm/imx/
 
+DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
+M:     Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
+L:     dri-devel@lists.freedesktop.org
+T:     git git://github.com/patjak/drm-gma500
+S:     Maintained
+F:     drivers/gpu/drm/gma500
+F:     include/drm/gma500*
+
 DRM DRIVERS FOR NVIDIA TEGRA
 M:     Thierry Reding <thierry.reding@gmail.com>
 M:     Terje Bergström <tbergstrom@nvidia.com>
@@ -6778,7 +6794,6 @@ F:        drivers/scsi/megaraid/
 
 MELLANOX ETHERNET DRIVER (mlx4_en)
 M:     Amir Vadai <amirv@mellanox.com>
-M:     Ido Shamay <idos@mellanox.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.mellanox.com
@@ -9101,6 +9116,15 @@ S: Supported
 F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
 F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
 
+SYNOPSYS DESIGNWARE I2C DRIVER
+M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+M:     Jarkko Nikula <jarkko.nikula@linux.intel.com>
+M:     Mika Westerberg <mika.westerberg@linux.intel.com>
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+F:     drivers/i2c/busses/i2c-designware-*
+F:     include/linux/platform_data/i2c-designware.h
+
 SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
 M:     Seungwon Jeon <tgih.jun@samsung.com>
 M:     Jaehoon Chung <jh80.chung@samsung.com>
@@ -11651,6 +11675,7 @@ F:      drivers/tty/serial/zs.*
 ZSMALLOC COMPRESSED SLAB MEMORY ALLOCATOR
 M:     Minchan Kim <minchan@kernel.org>
 M:     Nitin Gupta <ngupta@vflare.org>
+R:     Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     mm/zsmalloc.c
index 416660d05739d5a5fe05dcb10b463f883b8c04f2..431067a41fcfe5df67e3799ad0a6c7880030d41d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc7
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index 568adf5efde059f8c9a5ee56d182ea8def05788e..d55e3ea89fda51ba1d6b45f69eeaa8849dad9487 100644 (file)
                                /* SMPS9 unused */
 
                                ldo1_reg: ldo1 {
-                                       /* VDD_SD  */
+                                       /* VDD_SD / VDDSHV8  */
                                        regulator-name = "ldo1";
                                        regulator-min-microvolt = <1800000>;
                                        regulator-max-microvolt = <3300000>;
                                        regulator-boot-on;
+                                       regulator-always-on;
                                };
 
                                ldo2_reg: ldo2 {
index 89f5a95954ed9020c070491cae36cc7b2556eccf..4047621b137e6b107f875dc2f7c82292752bf448 100644 (file)
@@ -46,7 +46,7 @@
 
 / {
        model = "Marvell Armada 385 Access Point Development Board";
-       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada380";
 
        chosen {
                stdout-path = "serial1:115200n8";
index 63a48490e2f9653ff83f7f6202fd993d101b6ec9..d4dbd28d348c0b74ae4b23b5886b1dfb29dc3aa6 100644 (file)
                };
 
                usb_phy2: phy@a2f400 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xa2f400 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 14>;
                };
 
                usb_phy0: phy@b74000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb74000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 12>;
                };
 
                usb_phy1: phy@b78000 {
-                       compatible = "marvell,berlin2-usb-phy";
+                       compatible = "marvell,berlin2cd-usb-phy";
                        reg = <0xb78000 0x128>;
                        #phy-cells = <0>;
                        resets = <&chip_rst 0x104 13>;
index 8f4d76c5e11c5821ef7e504f21aa87c6103c92de..1b95da79293c58a173ce833d2e72e995a7761cb0 100644 (file)
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
index 7d5b386b5ae6aeb32aed5baf55a2d50ddf374b39..8f40c7e549bd5ef48d77c4ee5c9dacaaae65d820 100644 (file)
        };
 };
 
+&pmu_system_controller {
+       assigned-clocks = <&pmu_system_controller 0>;
+       assigned-clock-parents = <&clock CLK_FIN_PLL>;
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&max77802 MAX77802_CLK_32K_AP>;
index b738ce0f9d9bc31f5369b1c97284cf1ec7ff9bb7..6e444bb873f92ee28dd5cebec93d5947f3b8ea15 100644 (file)
                                status = "disabled";
                        };
 
-                       uart2: serial@30870000 {
+                       uart2: serial@30890000 {
                                compatible = "fsl,imx7d-uart",
                                             "fsl,imx6q-uart";
-                               reg = <0x30870000 0x10000>;
+                               reg = <0x30890000 0x10000>;
                                interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_UART2_ROOT_CLK>,
                                        <&clks IMX7D_UART2_ROOT_CLK>;
index 91146c318798ff3422f5fecb87ec0d8f0c97df45..5b0430041ec6d1980cb47ba253ce410bcebd05d0 100644 (file)
@@ -12,7 +12,7 @@
 
 / {
        model = "LogicPD Zoom DM3730 Torpedo Development Kit";
-       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap36xx";
+       compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3";
 
        gpio_keys {
                compatible = "gpio-keys";
index 548441384d2a39488d7daffef79ed6c707576a86..8c77c87660cdf2d72e1df3f00d2c76a8e447293c 100644 (file)
@@ -67,7 +67,7 @@
 
        timer@c1109940 {
                compatible = "amlogic,meson6-timer";
-               reg = <0xc1109940 0x14>;
+               reg = <0xc1109940 0x18>;
                interrupts = <0 10 1>;
        };
 
                wdt: watchdog@c1109900 {
                        compatible = "amlogic,meson6-wdt";
                        reg = <0xc1109900 0x8>;
+                       interrupts = <0 0 1>;
                };
 
                uart_AO: serial@c81004c0 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81004c0 0x14>;
+                       reg = <0xc81004c0 0x18>;
                        interrupts = <0 90 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_A: serial@c81084c0 {
+               uart_A: serial@c11084c0 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81084c0 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc11084c0 0x18>;
+                       interrupts = <0 26 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_B: serial@c81084dc {
+               uart_B: serial@c11084dc {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc81084dc 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc11084dc 0x18>;
+                       interrupts = <0 75 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
 
-               uart_C: serial@c8108700 {
+               uart_C: serial@c1108700 {
                        compatible = "amlogic,meson-uart";
-                       reg = <0xc8108700 0x14>;
-                       interrupts = <0 90 1>;
+                       reg = <0xc1108700 0x18>;
+                       interrupts = <0 93 1>;
                        clocks = <&clk81>;
                        status = "disabled";
                };
index 16e8ce350ddaae4f4bedc3d86f9d0418e4852f87..bb339d1648e071c4c456a3f627de68f805e1aa9b 100644 (file)
@@ -13,7 +13,7 @@
 
 / {
        model = "TI OMAP37XX EVM (TMDSEVM3730)";
-       compatible = "ti,omap3-evm-37xx", "ti,omap36xx";
+       compatible = "ti,omap3-evm-37xx", "ti,omap3630", "ti,omap3";
 
        memory {
                device_type = "memory";
index 810cda743b6d56ae19118260367f986dcee690af..9c2387b34d0c73c6942c4051d7f6ce72ee2a0aec 100644 (file)
@@ -56,7 +56,7 @@
                                        /* VMMCI level-shifter enable */
                                        default_hrefv60_cfg2 {
                                                pins = "GPIO169_D22";
-                                               ste,config = <&gpio_out_lo>;
+                                               ste,config = <&gpio_out_hi>;
                                        };
                                        /* VMMCI level-shifter voltage select */
                                        default_hrefv60_cfg3 {
index 9d4f86e9c50ada156a5ae785399799b23d67efba..d845bd1448b5459f9a6e4ab52c538c541b8832ef 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 246>;
+               */
        };
 
        apbmisc@70000800 {
index 1e204a6de12c3a4156821a289a2f7064bd346574..819e2ae2cabe28b09952807ca2f0249c1aa82b7f 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 251>;
+               */
        };
 
        apbdma: dma@0,60020000 {
index e058709e6d98c0db886bf4549366722605380985..969b828505ae4404846ff169ce17ad7ffd178ec2 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 224>;
+               */
        };
 
        apbmisc@70000800 {
index fe04fb5e155f4c7dd39509b8877d95eb7a6f8021..c6938ad1b543fb93cf22d297dda5b2d18795afe8 100644 (file)
                gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
+               /*
                gpio-ranges = <&pinmux 0 0 248>;
+               */
        };
 
        apbmisc@70000800 {
index 33963acd7e8f9227eaca31a60c240a37d9f6e754..f80f772d99fb5750ca4cb484a49bbea18b8ba61a 100644 (file)
@@ -85,7 +85,7 @@
 };
 
 &ethsc {
-       interrupts = <0 50 4>;
+       interrupts = <0 52 4>;
 };
 
 &serial0 {
index a66e37e211a9a8cbfabf85d9213f6b73db417085..97b22fa7cb3a62d5d6fd4a36935d4a32715fe6cf 100644 (file)
@@ -120,6 +120,6 @@ void __init time_init(void)
 #ifdef CONFIG_COMMON_CLK
                of_clk_init(NULL);
 #endif
-               clocksource_of_init();
+               clocksource_probe();
        }
 }
index 210eccadb69a9770ba1b51beb077bb071f565261..356970f3b25e3d2f54b691c8c8b1bb9baca1d7b1 100644 (file)
@@ -21,6 +21,7 @@ config KVM
        depends on MMU && OF
        select PREEMPT_NOTIFIERS
        select ANON_INODES
+       select ARM_GIC
        select HAVE_KVM_CPU_RELAX_INTERCEPT
        select HAVE_KVM_ARCH_TLB_FLUSH_ALL
        select KVM_MMIO
index dc017adfddc8b83698fa8486e2b9b6dbc1e189a0..78b286994577183b8d9ef415ae3ba5f6a41113c4 100644 (file)
@@ -1080,7 +1080,7 @@ static int init_hyp_mode(void)
         */
        err = kvm_timer_hyp_init();
        if (err)
-               goto out_free_mappings;
+               goto out_free_context;
 
 #ifndef CONFIG_HOTPLUG_CPU
        free_boot_hyp_pgd();
index 4a87e86dec45d1546153ca0ebb7310bbd5f82d93..7c21760f590ffd0d4cd47fcafcbcaffe64a85952 100644 (file)
@@ -200,15 +200,15 @@ no_clk:
                args.args_count = 0;
                child_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(child_domain))
-                       goto next_pd;
+                       continue;
 
                if (of_parse_phandle_with_args(np, "power-domains",
                                         "#power-domain-cells", 0, &args) != 0)
-                       goto next_pd;
+                       continue;
 
                parent_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(parent_domain))
-                       goto next_pd;
+                       continue;
 
                if (pm_genpd_add_subdomain(parent_domain, child_domain))
                        pr_warn("%s failed to add subdomain: %s\n",
@@ -216,8 +216,6 @@ no_clk:
                else
                        pr_info("%s has as child subdomain: %s.\n",
                                parent_domain->name, child_domain->name);
-next_pd:
-               of_node_put(np);
        }
 
        return 0;
index b3a0dff67e3fc48bb34b13567778d0f178298834..33d1460a56391c397ef305d8ed8275fa94b15720 100644 (file)
@@ -49,6 +49,7 @@ config SOC_OMAP5
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config SOC_AM33XX
        bool "TI AM33XX"
@@ -78,6 +79,7 @@ config SOC_DRA7XX
        select OMAP_INTERCONNECT
        select OMAP_INTERCONNECT_BARRIER
        select PM_OPP if PM
+       select ZONE_DMA if ARM_LPAE
 
 config ARCH_OMAP2PLUS
        bool
index 6133eaac685df545ec5a6665db0ae72051d8c2fa..fb219a30c10c60ff56f8b6c0ae754a861f886dc0 100644 (file)
@@ -106,6 +106,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
 MACHINE_END
 
 static const char *const omap36xx_boards_compat[] __initconst = {
+       "ti,omap3630",
        "ti,omap36xx",
        NULL,
 };
@@ -243,6 +244,9 @@ static const char *const omap5_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = omap5_map_io,
@@ -288,6 +292,9 @@ static const char *const dra74x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
        .map_io         = dra7xx_map_io,
@@ -308,6 +315,9 @@ static const char *const dra72x_boards_compat[] __initconst = {
 };
 
 DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE)
+       .dma_zone_size  = SZ_2G,
+#endif
        .reserve        = omap_reserve,
        .map_io         = dra7xx_map_io,
        .init_early     = dra7xx_init_early,
index ea56397599c21b1f0c7d806ccfe9b1f4fb062f52..1dfe34654c43a353a34ac2cb9b941ff9f951b275 100644 (file)
@@ -559,7 +559,14 @@ static void pdata_quirks_check(struct pdata_init *quirks)
 
 void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
 {
-       omap_sdrc_init(NULL, NULL);
+       /*
+        * We still need this for omap2420 and omap3 PM to work, others are
+        * using drivers/misc/sram.c already.
+        */
+       if (of_machine_is_compatible("ti,omap2420") ||
+           of_machine_is_compatible("ti,omap3"))
+               omap_sdrc_init(NULL, NULL);
+
        pdata_quirks_check(auxdata_quirks);
        of_platform_populate(NULL, omap_dt_match_table,
                             omap_auxdata_lookup, NULL);
index a55655127ef23e7b3a325fdd43c4d9ff729719fd..bef41837bf7fd7090eccf768c2881662ac42025a 100644 (file)
@@ -647,7 +647,7 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
 void __init omap4_local_timer_init(void)
 {
        omap4_sync32k_timer_init();
-       clocksource_of_init();
+       clocksource_probe();
 }
 #else
 void __init omap4_local_timer_init(void)
@@ -663,7 +663,7 @@ void __init omap5_realtime_timer_init(void)
        omap4_sync32k_timer_init();
        realtime_counter_init();
 
-       clocksource_of_init();
+       clocksource_probe();
 }
 #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
 
index 06005d3f2ba33523d1ee4f9e96499290a9908572..20ce2d386f172c849459e94d1bb88601f1fdd0e7 100644 (file)
 #define PECR_IS(n)     ((1 << ((n) * 2)) << 29)
 
 extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
-#ifdef CONFIG_PM
-
-#define ISRAM_START    0x5c000000
-#define ISRAM_SIZE     SZ_256K
 
 /*
  * NAND NFC: DFI bus arbitration subset
@@ -54,6 +50,11 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
 #define NDCR_ND_ARB_EN         (1 << 12)
 #define NDCR_ND_ARB_CNTL       (1 << 19)
 
+#ifdef CONFIG_PM
+
+#define ISRAM_START    0x5c000000
+#define ISRAM_SIZE     SZ_256K
+
 static void __iomem *sram;
 static unsigned long wakeup_src;
 
index b6cf3b449428960d28590f5cdad6e331d2239080..251c7b9c5f9b6c15ffdab39475d6b7764e9c2fc0 100644 (file)
@@ -67,7 +67,7 @@ static void __init rockchip_timer_init(void)
        }
 
        of_clk_init(NULL);
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 static void __init rockchip_dt_init(void)
index 6bfa6407a27c0baed01a04c17f223b0e6087c5cf..1e572a903f8e470e8864738be0464b3a48b63940 100644 (file)
@@ -97,7 +97,7 @@ static u32 __init r8a7779_read_mode_pins(void)
 static void __init r8a7779_init_time(void)
 {
        r8a7779_clocks_init(r8a7779_read_mode_pins());
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 static const char *const r8a7779_compat_dt[] __initconst = {
index aa3339258d9c0232a4092a01e9abf2b3243098f6..9eccde3c7b137151e3fcff5c882cb6bd62870195 100644 (file)
@@ -128,7 +128,7 @@ void __init rcar_gen2_timer_init(void)
 #endif /* CONFIG_ARM_ARCH_TIMER */
 
        rcar_gen2_clocks_init(mode);
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 struct memory_reserve_config {
index b7afce6795f436e9259e84d34f01fa246173eedf..ca2f6a82a4141e7d448779901e2fc1a151d118b8 100644 (file)
@@ -124,5 +124,5 @@ void __init spear13xx_timer_init(void)
        clk_put(pclk);
 
        spear_setup_of_timer();
-       clocksource_of_init();
+       clocksource_probe();
 }
index 65bab2876343aff24707105f0432c90faaf90e60..223c9e99380d89fa7658a46ba67534d9c3c47776 100644 (file)
@@ -46,7 +46,7 @@ static void __init sun6i_timer_init(void)
        of_clk_init(NULL);
        if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
                sun6i_reset_init();
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
index 35670b15f28182299a94373cfd8fdae54c2f7e2f..546338bbacf8670b30b483c1c69737bc5813a723 100644 (file)
@@ -408,7 +408,7 @@ static const char * u300_board_compat[] = {
 DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
        .map_io         = u300_map_io,
        .init_irq       = u300_init_irq_dt,
-       .init_time      = clocksource_of_init,
+       .init_time      = clocksource_probe,
        .init_machine   = u300_init_machine_dt,
        .restart        = u300_restart,
        .dt_compat      = u300_board_compat,
index ff28d8ad1ed7347dec1928ca0d2bb1ac118d7c47..8d2d233f8e6cfaa248801c69033b511d7adef5af 100644 (file)
@@ -44,5 +44,5 @@ void __init ux500_timer_init(void)
 
 dt_fail:
        clksrc_dbx500_prcmu_init(prcmu_timer_base);
-       clocksource_of_init();
+       clocksource_probe();
 }
index 5a6e4e20ca0a98ae07d39d6b764d2f799fc1448d..6f39d03cc27eac777a243abcb5a08ea4c35e8d7c 100644 (file)
@@ -154,7 +154,7 @@ static void __init zynq_timer_init(void)
 
        zynq_clock_init();
        of_clk_init(NULL);
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 static struct map_desc zynq_cortex_a9_scu_map __initdata = {
index 876060bcceeb3ea989e24fe18b42910f3cce4058..b8efb8cd1f73ee1cb7de196ae88d9173203c4d2a 100644 (file)
@@ -614,6 +614,7 @@ load_common:
                case BPF_LD | BPF_B | BPF_IND:
                        load_order = 0;
 load_ind:
+                       update_on_xread(ctx);
                        OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
                        goto load_common;
                case BPF_LDX | BPF_IMM:
index 2235081a04eeac818f58b44923aa565026c0b746..8861c367d06114651920b05420e53ebde3099712 100644 (file)
@@ -495,7 +495,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
 
        d->netdev = &orion_ge00.dev;
        for (i = 0; i < d->nr_chips; i++)
-               d->chip[i].host_dev = &orion_ge00_shared.dev;
+               d->chip[i].host_dev = &orion_ge_mvmdio.dev;
        orion_switch_device.dev.platform_data = d;
 
        platform_device_register(&orion_switch_device);
index f9914d7c1bb00b5c4cbe7a19c0f62c8eca54cf81..d10b5d483022f5374fa16c7783b7fb62014c3acb 100644 (file)
@@ -42,7 +42,7 @@ endif
 CHECKFLAGS     += -D__aarch64__
 
 ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
-CFLAGS_MODULE  += -mcmodel=large
+KBUILD_CFLAGS_MODULE   += -mcmodel=large
 endif
 
 # Default value
index 208cec08a74fa09973473adca3c69dfbcdb6111c..6894205797a3df0b5e233a464ea2199f7376032b 100644 (file)
@@ -12,7 +12,6 @@
 #ifndef _ASM_ACPI_H
 #define _ASM_ACPI_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
 #include <linux/mm.h>
 #include <linux/psci.h>
 
index bbb251b14746cb7005d1be35d50fdfb453464870..94c53674a31d24f45b6b392d90ac840c6bde7589 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef __ASM_IRQ_H
 #define __ASM_IRQ_H
 
-#include <linux/irqchip/arm-gic-acpi.h>
-
 #include <asm-generic/irq.h>
 
 struct pt_regs;
@@ -10,15 +8,4 @@ struct pt_regs;
 extern void migrate_irqs(void);
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
-static inline void acpi_irq_init(void)
-{
-       /*
-        * Hardcode ACPI IRQ chip initialization to GICv2 for now.
-        * Proper irqchip infrastructure will be implemented along with
-        * incoming  GICv2m|GICv3|ITS bits.
-        */
-       acpi_gic_init();
-}
-#define acpi_irq_init acpi_irq_init
-
 #endif
index 3bc498c250dc08b04f81abdde71e83f886454147..41e58fe3c041e9adcade0f113064ea42e87045ba 100644 (file)
@@ -44,7 +44,7 @@
 #define __ARM_NR_compat_cacheflush     (__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE+5)
 
-#define __NR_compat_syscalls           388
+#define __NR_compat_syscalls           390
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
index cef934a90f17ecec303a1dcd12133a962f27b9d1..5b925b761a2a8857a62720110076e062edd4d7f3 100644 (file)
@@ -797,3 +797,12 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
 __SYSCALL(__NR_bpf, sys_bpf)
 #define __NR_execveat 387
 __SYSCALL(__NR_execveat, compat_sys_execveat)
+#define __NR_userfaultfd 388
+__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
+#define __NR_membarrier 389
+__SYSCALL(__NR_membarrier, sys_membarrier)
+
+/*
+ * Please add new compat syscalls above this comment and update
+ * __NR_compat_syscalls in asm/unistd.h.
+ */
index 8d1e7236431b428490cfb95cb6bfbeba24143854..991bf5db2ca19aa19b617e4752d6fd65280b164b 100644 (file)
@@ -19,6 +19,9 @@
 /* Required for AArch32 compatibility. */
 #define SA_RESTORER    0x04000000
 
+#define MINSIGSTKSZ 5120
+#define SIGSTKSZ    16384
+
 #include <asm-generic/signal.h>
 
 #endif
index 19de7537e7d32f407f3f75d5f295ab5f3c7c4291..d6463bba2360561e59acb1f0fa5dbac926f37dfa 100644 (file)
@@ -205,28 +205,3 @@ void __init acpi_boot_table_init(void)
                        disable_acpi();
        }
 }
-
-void __init acpi_gic_init(void)
-{
-       struct acpi_table_header *table;
-       acpi_status status;
-       acpi_size tbl_size;
-       int err;
-
-       if (acpi_disabled)
-               return;
-
-       status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size);
-       if (ACPI_FAILURE(status)) {
-               const char *msg = acpi_format_exception(status);
-
-               pr_err("Failed to get MADT table, %s\n", msg);
-               return;
-       }
-
-       err = gic_v2_acpi_init(table);
-       if (err)
-               pr_err("Failed to initialize GIC IRQ controller");
-
-       early_acpi_os_unmap_memory((char *)table, tbl_size);
-}
index 149151fb42bb1579127100f24a0f91a2124c92e1..13339b6ffc1a07839103fca328f1eccd6d185c12 100644 (file)
@@ -67,16 +67,10 @@ void __init time_init(void)
        u32 arch_timer_rate;
 
        of_clk_init(NULL);
-       clocksource_of_init();
+       clocksource_probe();
 
        tick_setup_hrtimer_broadcast();
 
-       /*
-        * Since ACPI or FDT will only one be available in the system,
-        * we can use acpi_generic_timer_init() here safely
-        */
-       acpi_generic_timer_init();
-
        arch_timer_rate = arch_timer_get_rate();
        if (!arch_timer_rate)
                panic("Unable to initialise architected timer.\n");
index 36d2c1e3928bc744eb2d66eeb18aa7291969eab5..07039d168f37bfd14048e9e4a73d50bc4d20f35d 100644 (file)
@@ -64,11 +64,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 #define pci_legacy_read platform_pci_legacy_read
 #define pci_legacy_write platform_pci_legacy_write
 
-struct iospace_resource {
-       struct list_head list;
-       struct resource res;
-};
-
 struct pci_controller {
        struct acpi_device *companion;
        void *iommu;
index 7cc3be9fa7c65a0dd700dfd30c04cc7be822922d..8f6ac2f8ae4c8cebea5cd85d79b11251d7b09979 100644 (file)
@@ -115,33 +115,13 @@ struct pci_ops pci_root_ops = {
        .write = pci_write,
 };
 
-/* Called by ACPI when it finds a new root bus.  */
-
-static struct pci_controller *alloc_pci_controller(int seg)
-{
-       struct pci_controller *controller;
-
-       controller = kzalloc(sizeof(*controller), GFP_KERNEL);
-       if (!controller)
-               return NULL;
-
-       controller->segment = seg;
-       return controller;
-}
-
 struct pci_root_info {
-       struct acpi_device *bridge;
-       struct pci_controller *controller;
-       struct list_head resources;
-       struct resource *res;
-       resource_size_t *res_offset;
-       unsigned int res_num;
+       struct acpi_pci_root_info common;
+       struct pci_controller controller;
        struct list_head io_resources;
-       char *name;
 };
 
-static unsigned int
-new_space (u64 phys_base, int sparse)
+static unsigned int new_space(u64 phys_base, int sparse)
 {
        u64 mmio_base;
        int i;
@@ -168,39 +148,36 @@ new_space (u64 phys_base, int sparse)
        return i;
 }
 
-static u64 add_io_space(struct pci_root_info *info,
-                       struct acpi_resource_address64 *addr)
+static int add_io_space(struct device *dev, struct pci_root_info *info,
+                       struct resource_entry *entry)
 {
-       struct iospace_resource *iospace;
-       struct resource *resource;
+       struct resource_entry *iospace;
+       struct resource *resource, *res = entry->res;
        char *name;
        unsigned long base, min, max, base_port;
        unsigned int sparse = 0, space_nr, len;
 
-       len = strlen(info->name) + 32;
-       iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+       len = strlen(info->common.name) + 32;
+       iospace = resource_list_create_entry(NULL, len);
        if (!iospace) {
-               dev_err(&info->bridge->dev,
-                               "PCI: No memory for %s I/O port space\n",
-                               info->name);
-               goto out;
+               dev_err(dev, "PCI: No memory for %s I/O port space\n",
+                       info->common.name);
+               return -ENOMEM;
        }
 
-       name = (char *)(iospace + 1);
-
-       min = addr->address.minimum;
-       max = min + addr->address.address_length - 1;
-       if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
+       if (res->flags & IORESOURCE_IO_SPARSE)
                sparse = 1;
-
-       space_nr = new_space(addr->address.translation_offset, sparse);
+       space_nr = new_space(entry->offset, sparse);
        if (space_nr == ~0)
                goto free_resource;
 
+       name = (char *)(iospace + 1);
+       min = res->start - entry->offset;
+       max = res->end - entry->offset;
        base = __pa(io_space[space_nr].mmio_base);
        base_port = IO_SPACE_BASE(space_nr);
-       snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
-               base_port + min, base_port + max);
+       snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->common.name,
+                base_port + min, base_port + max);
 
        /*
         * The SDM guarantees the legacy 0-64K space is sparse, but if the
@@ -210,270 +187,125 @@ static u64 add_io_space(struct pci_root_info *info,
        if (space_nr == 0)
                sparse = 1;
 
-       resource = &iospace->res;
+       resource = iospace->res;
        resource->name  = name;
        resource->flags = IORESOURCE_MEM;
        resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
        resource->end   = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
        if (insert_resource(&iomem_resource, resource)) {
-               dev_err(&info->bridge->dev,
-                               "can't allocate host bridge io space resource  %pR\n",
-                               resource);
+               dev_err(dev,
+                       "can't allocate host bridge io space resource  %pR\n",
+                       resource);
                goto free_resource;
        }
 
-       list_add_tail(&iospace->list, &info->io_resources);
-       return base_port;
+       entry->offset = base_port;
+       res->start = min + base_port;
+       res->end = max + base_port;
+       resource_list_add_tail(iospace, &info->io_resources);
 
-free_resource:
-       kfree(iospace);
-out:
-       return ~0;
-}
-
-static acpi_status resource_to_window(struct acpi_resource *resource,
-                                     struct acpi_resource_address64 *addr)
-{
-       acpi_status status;
+       return 0;
 
-       /*
-        * We're only interested in _CRS descriptors that are
-        *      - address space descriptors for memory or I/O space
-        *      - non-zero size
-        */
-       status = acpi_resource_to_address64(resource, addr);
-       if (ACPI_SUCCESS(status) &&
-           (addr->resource_type == ACPI_MEMORY_RANGE ||
-            addr->resource_type == ACPI_IO_RANGE) &&
-           addr->address.address_length)
-               return AE_OK;
-
-       return AE_ERROR;
+free_resource:
+       resource_list_free_entry(iospace);
+       return -ENOSPC;
 }
 
-static acpi_status count_window(struct acpi_resource *resource, void *data)
+/*
+ * An IO port or MMIO resource assigned to a PCI host bridge may be
+ * consumed by the host bridge itself or available to its child
+ * bus/devices. The ACPI specification defines a bit (Producer/Consumer)
+ * to tell whether the resource is consumed by the host bridge itself,
+ * but firmware hasn't used that bit consistently, so we can't rely on it.
+ *
+ * On x86 and IA64 platforms, all IO port and MMIO resources are assumed
+ * to be available to child bus/devices except one special case:
+ *     IO port [0xCF8-0xCFF] is consumed by the host bridge itself
+ *     to access PCI configuration space.
+ *
+ * So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
+ */
+static bool resource_is_pcicfg_ioport(struct resource *res)
 {
-       unsigned int *windows = (unsigned int *) data;
-       struct acpi_resource_address64 addr;
-       acpi_status status;
-
-       status = resource_to_window(resource, &addr);
-       if (ACPI_SUCCESS(status))
-               (*windows)++;
-
-       return AE_OK;
+       return (res->flags & IORESOURCE_IO) &&
+               res->start == 0xCF8 && res->end == 0xCFF;
 }
 
-static acpi_status add_window(struct acpi_resource *res, void *data)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
 {
-       struct pci_root_info *info = data;
-       struct resource *resource;
-       struct acpi_resource_address64 addr;
-       acpi_status status;
-       unsigned long flags, offset = 0;
-       struct resource *root;
-
-       /* Return AE_OK for non-window resources to keep scanning for more */
-       status = resource_to_window(res, &addr);
-       if (!ACPI_SUCCESS(status))
-               return AE_OK;
-
-       if (addr.resource_type == ACPI_MEMORY_RANGE) {
-               flags = IORESOURCE_MEM;
-               root = &iomem_resource;
-               offset = addr.address.translation_offset;
-       } else if (addr.resource_type == ACPI_IO_RANGE) {
-               flags = IORESOURCE_IO;
-               root = &ioport_resource;
-               offset = add_io_space(info, &addr);
-               if (offset == ~0)
-                       return AE_OK;
-       } else
-               return AE_OK;
-
-       resource = &info->res[info->res_num];
-       resource->name = info->name;
-       resource->flags = flags;
-       resource->start = addr.address.minimum + offset;
-       resource->end = resource->start + addr.address.address_length - 1;
-       info->res_offset[info->res_num] = offset;
-
-       if (insert_resource(root, resource)) {
-               dev_err(&info->bridge->dev,
-                       "can't allocate host bridge window %pR\n",
-                       resource);
-       } else {
-               if (offset)
-                       dev_info(&info->bridge->dev, "host bridge window %pR "
-                                "(PCI address [%#llx-%#llx])\n",
-                                resource,
-                                resource->start - offset,
-                                resource->end - offset);
-               else
-                       dev_info(&info->bridge->dev,
-                                "host bridge window %pR\n", resource);
+       struct device *dev = &ci->bridge->dev;
+       struct pci_root_info *info;
+       struct resource *res;
+       struct resource_entry *entry, *tmp;
+       int status;
+
+       status = acpi_pci_probe_root_resources(ci);
+       if (status > 0) {
+               info = container_of(ci, struct pci_root_info, common);
+               resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+                       res = entry->res;
+                       if (res->flags & IORESOURCE_MEM) {
+                               /*
+                                * HP's firmware has a hack to work around a
+                                * Windows bug. Ignore these tiny memory ranges.
+                                */
+                               if (resource_size(res) <= 16) {
+                                       resource_list_del(entry);
+                                       insert_resource(&iomem_resource,
+                                                       entry->res);
+                                       resource_list_add_tail(entry,
+                                                       &info->io_resources);
+                               }
+                       } else if (res->flags & IORESOURCE_IO) {
+                               if (resource_is_pcicfg_ioport(entry->res))
+                                       resource_list_destroy_entry(entry);
+                               else if (add_io_space(dev, info, entry))
+                                       resource_list_destroy_entry(entry);
+                       }
+               }
        }
-       /* HP's firmware has a hack to work around a Windows bug.
-        * Ignore these tiny memory ranges */
-       if (!((resource->flags & IORESOURCE_MEM) &&
-             (resource->end - resource->start < 16)))
-               pci_add_resource_offset(&info->resources, resource,
-                                       info->res_offset[info->res_num]);
-
-       info->res_num++;
-       return AE_OK;
-}
 
-static void free_pci_root_info_res(struct pci_root_info *info)
-{
-       struct iospace_resource *iospace, *tmp;
-
-       list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
-               kfree(iospace);
-
-       kfree(info->name);
-       kfree(info->res);
-       info->res = NULL;
-       kfree(info->res_offset);
-       info->res_offset = NULL;
-       info->res_num = 0;
-       kfree(info->controller);
-       info->controller = NULL;
+       return status;
 }
 
-static void __release_pci_root_info(struct pci_root_info *info)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
 {
-       int i;
-       struct resource *res;
-       struct iospace_resource *iospace;
+       struct pci_root_info *info;
+       struct resource_entry *entry, *tmp;
 
-       list_for_each_entry(iospace, &info->io_resources, list)
-               release_resource(&iospace->res);
-
-       for (i = 0; i < info->res_num; i++) {
-               res = &info->res[i];
-
-               if (!res->parent)
-                       continue;
-
-               if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
-                       continue;
-
-               release_resource(res);
+       info = container_of(ci, struct pci_root_info, common);
+       resource_list_for_each_entry_safe(entry, tmp, &info->io_resources) {
+               release_resource(entry->res);
+               resource_list_destroy_entry(entry);
        }
-
-       free_pci_root_info_res(info);
        kfree(info);
 }
 
-static void release_pci_root_info(struct pci_host_bridge *bridge)
-{
-       struct pci_root_info *info = bridge->release_data;
-
-       __release_pci_root_info(info);
-}
-
-static int
-probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
-               int busnum, int domain)
-{
-       char *name;
-
-       name = kmalloc(16, GFP_KERNEL);
-       if (!name)
-               return -ENOMEM;
-
-       sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
-       info->bridge = device;
-       info->name = name;
-
-       acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
-                       &info->res_num);
-       if (info->res_num) {
-               info->res =
-                       kzalloc_node(sizeof(*info->res) * info->res_num,
-                                    GFP_KERNEL, info->controller->node);
-               if (!info->res) {
-                       kfree(name);
-                       return -ENOMEM;
-               }
-
-               info->res_offset =
-                       kzalloc_node(sizeof(*info->res_offset) * info->res_num,
-                                       GFP_KERNEL, info->controller->node);
-               if (!info->res_offset) {
-                       kfree(name);
-                       kfree(info->res);
-                       info->res = NULL;
-                       return -ENOMEM;
-               }
-
-               info->res_num = 0;
-               acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-                       add_window, info);
-       } else
-               kfree(name);
-
-       return 0;
-}
+static struct acpi_pci_root_ops pci_acpi_root_ops = {
+       .pci_ops = &pci_root_ops,
+       .release_info = pci_acpi_root_release_info,
+       .prepare_resources = pci_acpi_root_prepare_resources,
+};
 
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
        struct acpi_device *device = root->device;
-       int domain = root->segment;
-       int bus = root->secondary.start;
-       struct pci_controller *controller;
-       struct pci_root_info *info = NULL;
-       int busnum = root->secondary.start;
-       struct pci_bus *pbus;
-       int ret;
-
-       controller = alloc_pci_controller(domain);
-       if (!controller)
-               return NULL;
-
-       controller->companion = device;
-       controller->node = acpi_get_node(device->handle);
+       struct pci_root_info *info;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
                dev_err(&device->dev,
-                               "pci_bus %04x:%02x: ignored (out of memory)\n",
-                               domain, busnum);
-               kfree(controller);
+                       "pci_bus %04x:%02x: ignored (out of memory)\n",
+                       root->segment, (int)root->secondary.start);
                return NULL;
        }
 
-       info->controller = controller;
+       info->controller.segment = root->segment;
+       info->controller.companion = device;
+       info->controller.node = acpi_get_node(device->handle);
        INIT_LIST_HEAD(&info->io_resources);
-       INIT_LIST_HEAD(&info->resources);
-
-       ret = probe_pci_root_info(info, device, busnum, domain);
-       if (ret) {
-               kfree(info->controller);
-               kfree(info);
-               return NULL;
-       }
-       /* insert busn resource at first */
-       pci_add_resource(&info->resources, &root->secondary);
-       /*
-        * See arch/x86/pci/acpi.c.
-        * The desired pci bus might already be scanned in a quirk. We
-        * should handle the case here, but it appears that IA64 hasn't
-        * such quirk. So we just ignore the case now.
-        */
-       pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
-                                  &info->resources);
-       if (!pbus) {
-               pci_free_resource_list(&info->resources);
-               __release_pci_root_info(info);
-               return NULL;
-       }
-
-       pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
-                       release_pci_root_info, info);
-       pci_scan_child_bus(pbus);
-       return pbus;
+       return acpi_pci_root_create(root, &pci_acpi_root_ops,
+                                   &info->common, &info->controller);
 }
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
index ab5b488e1fde666bc24b3dd3d78f6f4950829282..89a2a93949274b16b3508b314d0cbdf6db5946e6 100644 (file)
@@ -194,7 +194,7 @@ void __init time_init(void)
 {
        of_clk_init(NULL);
        setup_cpuinfo_clk();
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 #ifdef CONFIG_DEBUG_FS
index 8a377346f0cabbf5ce91199ca039ec013b16dda1..1022201b2bebddf5453cda975ab6820bd432e41c 100644 (file)
@@ -39,7 +39,7 @@ void __init plat_time_init(void)
        struct clk *clk;
 
        of_clk_init(NULL);
-       clocksource_of_init();
+       clocksource_probe();
 
        np = of_get_cpu_node(0, NULL);
        if (!np) {
index feb5a9bf98b4bc316a8e568635613e02fd262b68..25c4a61779f1f3a015b9eb7d76bdfc63e3a7dab4 100644 (file)
@@ -75,5 +75,5 @@ void __init plat_time_init(void)
        pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
        mips_hpt_frequency = clk_get_rate(clk) / 2;
        clk_put(clk);
-       clocksource_of_init();
+       clocksource_probe();
 }
index bbc3f9157f9c4fec3418e8a92c20f204924e0c5b..e835dda2bfe2d5342f0b87f763476ebd9ae81875 100644 (file)
@@ -324,7 +324,7 @@ void __init time_init(void)
        if (count < 2)
                panic("%d timer is found, it needs 2 timers in system\n", count);
 
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 CLOCKSOURCE_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
index 6bc0ee4b1070a83de003d1c74ec64f818bd3dacb..2c041b535a64ed58d3be2aa79916f94308190b92 100644 (file)
@@ -111,7 +111,7 @@ CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
index 7991f37e5fe2a174fd3284a4fb1b5e72d2ab267a..36871a4bfa54293b2e70851ea1aa4c1a379dd1dd 100644 (file)
@@ -114,7 +114,7 @@ CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
 CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH=y
 CONFIG_SCSI_DH_RDAC=m
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
index 0dc42c5082b74a1d4fee5709e21100ee0ec8a2df..5f8229e24fe6523a73ef2335a5f480e5f3983911 100644 (file)
@@ -3,7 +3,6 @@
 
 #ifdef __KERNEL__
 
-#include <asm/reg.h>
 
 /* bytes per L1 cache line */
 #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
@@ -40,12 +39,6 @@ struct ppc64_caches {
 };
 
 extern struct ppc64_caches ppc64_caches;
-
-static inline void logmpp(u64 x)
-{
-       asm volatile(PPC_LOGMPP(R1) : : "r" (x));
-}
-
 #endif /* __powerpc64__ && ! __ASSEMBLY__ */
 
 #if defined(__ASSEMBLY__)
index 827a38d7a9dbe32adfcaf7937c276f6cfce222a4..887c259556dff8e6a2f534ec38355d77a90fbeda 100644 (file)
@@ -297,8 +297,6 @@ struct kvmppc_vcore {
        u32 arch_compat;
        ulong pcr;
        ulong dpdes;            /* doorbell state (POWER8) */
-       void *mpp_buffer; /* Micro Partition Prefetch buffer */
-       bool mpp_buffer_is_valid;
        ulong conferring_threads;
 };
 
index cab6753f1be56e3f1810be80d50cf94524eaa04b..3f191f573d4f1f487b5e417ddd55eaed8d49951d 100644 (file)
@@ -61,8 +61,13 @@ struct machdep_calls {
                                               unsigned long addr,
                                               unsigned char *hpte_slot_array,
                                               int psize, int ssize, int local);
-       /* special for kexec, to be called in real mode, linear mapping is
-        * destroyed as well */
+       /*
+        * Special for kexec.
+        * To be called in real mode with interrupts disabled. No locks are
+        * taken as such, concurrent access on pre POWER5 hardware could result
+        * in a deadlock.
+        * The linear mapping is destroyed as well.
+        */
        void            (*hpte_clear_all)(void);
 
        void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
index 790f5d1d9a4624d6f17bdde78706be7240d29ad2..7ab04fc59e2462917501a7f6a1b8727be3685163 100644 (file)
 #define PPC_INST_ISEL                  0x7c00001e
 #define PPC_INST_ISEL_MASK             0xfc00003e
 #define PPC_INST_LDARX                 0x7c0000a8
-#define PPC_INST_LOGMPP                        0x7c0007e4
 #define PPC_INST_LSWI                  0x7c0004aa
 #define PPC_INST_LSWX                  0x7c00042a
 #define PPC_INST_LWARX                 0x7c000028
 #define __PPC_EH(eh)   0
 #endif
 
-/* POWER8 Micro Partition Prefetch (MPP) parameters */
-/* Address mask is common for LOGMPP instruction and MPPR SPR */
-#define PPC_MPPE_ADDRESS_MASK 0xffffffffc000ULL
-
-/* Bits 60 and 61 of MPP SPR should be set to one of the following */
-/* Aborting the fetch is indeed setting 00 in the table size bits */
-#define PPC_MPPR_FETCH_ABORT (0x0ULL << 60)
-#define PPC_MPPR_FETCH_WHOLE_TABLE (0x2ULL << 60)
-
-/* Bits 54 and 55 of register for LOGMPP instruction should be set to: */
-#define PPC_LOGMPP_LOG_L2 (0x02ULL << 54)
-#define PPC_LOGMPP_LOG_L2L3 (0x01ULL << 54)
-#define PPC_LOGMPP_LOG_ABORT (0x03ULL << 54)
-
 /* Deal with instructions that older assemblers aren't aware of */
 #define        PPC_DCBAL(a, b)         stringify_in_c(.long PPC_INST_DCBAL | \
                                        __PPC_RA(a) | __PPC_RB(b))
 #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \
                                        ___PPC_RT(t) | ___PPC_RA(a) | \
                                        ___PPC_RB(b) | __PPC_EH(eh))
-#define PPC_LOGMPP(b)          stringify_in_c(.long PPC_INST_LOGMPP | \
-                                       __PPC_RB(b))
 #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \
                                        ___PPC_RT(t) | ___PPC_RA(a) | \
                                        ___PPC_RB(b) | __PPC_EH(eh))
index aa1cc5f015eeee564e2c1c83f295acb7d0c523d8..a908ada8e0a5353f5fce19af6ad3e59779ce2e0e 100644 (file)
 #define   CTRL_TE      0x00c00000      /* thread enable */
 #define   CTRL_RUNLATCH        0x1
 #define SPRN_DAWR      0xB4
-#define SPRN_MPPR      0xB8    /* Micro Partition Prefetch Register */
 #define SPRN_RPR       0xBA    /* Relative Priority Register */
 #define SPRN_CIABR     0xBB
 #define   CIABR_PRIV           0x3
index 84bf934cf74874eab39926b292c6fa7534829d24..5a753fae8265ae8fc2f9e2e99152c0192fd62b9d 100644 (file)
@@ -1043,6 +1043,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
+       if (!rtas.entry)
+               return -EINVAL;
+
        if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
                return -EFAULT;
 
index 2280497868886990678c19c01f5cf1c22b25f7a5..9c26c5a96ea2bc0ea9d2286f4995b2d629be9003 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <asm/reg.h>
 #include <asm/cputable.h>
-#include <asm/cache.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/uaccess.h>
 
 static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
 
-#if defined(CONFIG_PPC_64K_PAGES)
-#define MPP_BUFFER_ORDER       0
-#elif defined(CONFIG_PPC_4K_PAGES)
-#define MPP_BUFFER_ORDER       3
-#endif
-
 static int dynamic_mt_modes = 6;
 module_param(dynamic_mt_modes, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(dynamic_mt_modes, "Set of allowed dynamic micro-threading modes: 0 (= none), 2, 4, or 6 (= 2 or 4)");
@@ -1455,13 +1448,6 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core)
        vcore->kvm = kvm;
        INIT_LIST_HEAD(&vcore->preempt_list);
 
-       vcore->mpp_buffer_is_valid = false;
-
-       if (cpu_has_feature(CPU_FTR_ARCH_207S))
-               vcore->mpp_buffer = (void *)__get_free_pages(
-                       GFP_KERNEL|__GFP_ZERO,
-                       MPP_BUFFER_ORDER);
-
        return vcore;
 }
 
@@ -1894,33 +1880,6 @@ static int on_primary_thread(void)
        return 1;
 }
 
-static void kvmppc_start_saving_l2_cache(struct kvmppc_vcore *vc)
-{
-       phys_addr_t phy_addr, mpp_addr;
-
-       phy_addr = (phys_addr_t)virt_to_phys(vc->mpp_buffer);
-       mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK;
-
-       mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_ABORT);
-       logmpp(mpp_addr | PPC_LOGMPP_LOG_L2);
-
-       vc->mpp_buffer_is_valid = true;
-}
-
-static void kvmppc_start_restoring_l2_cache(const struct kvmppc_vcore *vc)
-{
-       phys_addr_t phy_addr, mpp_addr;
-
-       phy_addr = virt_to_phys(vc->mpp_buffer);
-       mpp_addr = phy_addr & PPC_MPPE_ADDRESS_MASK;
-
-       /* We must abort any in-progress save operations to ensure
-        * the table is valid so that prefetch engine knows when to
-        * stop prefetching. */
-       logmpp(mpp_addr | PPC_LOGMPP_LOG_ABORT);
-       mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_WHOLE_TABLE);
-}
-
 /*
  * A list of virtual cores for each physical CPU.
  * These are vcores that could run but their runner VCPU tasks are
@@ -2471,14 +2430,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 
        srcu_idx = srcu_read_lock(&vc->kvm->srcu);
 
-       if (vc->mpp_buffer_is_valid)
-               kvmppc_start_restoring_l2_cache(vc);
-
        __kvmppc_vcore_entry();
 
-       if (vc->mpp_buffer)
-               kvmppc_start_saving_l2_cache(vc);
-
        srcu_read_unlock(&vc->kvm->srcu, srcu_idx);
 
        spin_lock(&vc->lock);
@@ -3073,14 +3026,8 @@ static void kvmppc_free_vcores(struct kvm *kvm)
 {
        long int i;
 
-       for (i = 0; i < KVM_MAX_VCORES; ++i) {
-               if (kvm->arch.vcores[i] && kvm->arch.vcores[i]->mpp_buffer) {
-                       struct kvmppc_vcore *vc = kvm->arch.vcores[i];
-                       free_pages((unsigned long)vc->mpp_buffer,
-                                  MPP_BUFFER_ORDER);
-               }
+       for (i = 0; i < KVM_MAX_VCORES; ++i)
                kfree(kvm->arch.vcores[i]);
-       }
        kvm->arch.online_vcores = 0;
 }
 
index 13befa35d8a8ecdd31611aadb42c6be206ba743e..c8822af10a587389999473171db475eb5462714b 100644 (file)
@@ -582,13 +582,21 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
  * be when they isi), and we are the only one left.  We rely on our kernel
  * mapping being 0xC0's and the hardware ignoring those two real bits.
  *
+ * This must be called with interrupts disabled.
+ *
+ * Taking the native_tlbie_lock is unsafe here due to the possibility of
+ * lockdep being on. On pre POWER5 hardware, not taking the lock could
+ * cause deadlock. POWER5 and newer not taking the lock is fine. This only
+ * gets called during boot before secondary CPUs have come up and during
+ * crashdump and all bets are off anyway.
+ *
  * TODO: add batching support when enabled.  remember, no dynamic memory here,
  * athough there is the control page available...
  */
 static void native_hpte_clear(void)
 {
        unsigned long vpn = 0;
-       unsigned long slot, slots, flags;
+       unsigned long slot, slots;
        struct hash_pte *hptep = htab_address;
        unsigned long hpte_v;
        unsigned long pteg_count;
@@ -596,13 +604,6 @@ static void native_hpte_clear(void)
 
        pteg_count = htab_hash_mask + 1;
 
-       local_irq_save(flags);
-
-       /* we take the tlbie lock and hold it.  Some hardware will
-        * deadlock if we try to tlbie from two processors at once.
-        */
-       raw_spin_lock(&native_tlbie_lock);
-
        slots = pteg_count * HPTES_PER_GROUP;
 
        for (slot = 0; slot < slots; slot++, hptep++) {
@@ -614,8 +615,8 @@ static void native_hpte_clear(void)
                hpte_v = be64_to_cpu(hptep->v);
 
                /*
-                * Call __tlbie() here rather than tlbie() since we
-                * already hold the native_tlbie_lock.
+                * Call __tlbie() here rather than tlbie() since we can't take the
+                * native_tlbie_lock.
                 */
                if (hpte_v & HPTE_V_VALID) {
                        hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn);
@@ -625,8 +626,6 @@ static void native_hpte_clear(void)
        }
 
        asm volatile("eieio; tlbsync; ptesync":::"memory");
-       raw_spin_unlock(&native_tlbie_lock);
-       local_irq_restore(flags);
 }
 
 /*
index 230f3a7cdea45f8d160797fe55eb7b154c9c9dba..4296d55e88f30afa7cb91fd54d06e6b2a532d577 100644 (file)
@@ -487,9 +487,12 @@ int opal_machine_check(struct pt_regs *regs)
         *    PRD component would have already got notified about this
         *    error through other channels.
         *
-        * In any case, let us just fall through. We anyway heading
-        * down to panic path.
+        * If hardware marked this as an unrecoverable MCE, we are
+        * going to panic anyway. Even if it didn't, it's not safe to
+        * continue at this point, so we should explicitly panic.
         */
+
+       panic("PowerNV Unrecovered Machine Check");
        return 0;
 }
 
index 8f70ba681a78b91e6755e3e123c3dc784857e3c6..ca264833ee64d5c7a55035c66c21454d7b4d0b14 100644 (file)
@@ -171,7 +171,26 @@ static void pnv_smp_cpu_kill_self(void)
         * so clear LPCR:PECE1. We keep PECE2 enabled.
         */
        mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
+
+       /*
+        * Hard-disable interrupts, and then clear irq_happened flags
+        * that we can safely ignore while off-line, since they
+        * are for things for which we do no processing when off-line
+        * (or in the case of HMI, all the processing we need to do
+        * is done in lower-level real-mode code).
+        */
+       hard_irq_disable();
+       local_paca->irq_happened &= ~(PACA_IRQ_DEC | PACA_IRQ_HMI);
+
        while (!generic_check_cpu_restart(cpu)) {
+               /*
+                * Clear IPI flag, since we don't handle IPIs while
+                * offline, except for those when changing micro-threading
+                * mode, which are handled explicitly below, and those
+                * for coming online, which are handled via
+                * generic_check_cpu_restart() calls.
+                */
+               kvmppc_set_host_ipi(cpu, 0);
 
                ppc64_runlatch_off();
 
@@ -196,20 +215,20 @@ static void pnv_smp_cpu_kill_self(void)
                 * having finished executing in a KVM guest, then srr1
                 * contains 0.
                 */
-               if ((srr1 & wmask) == SRR1_WAKEEE) {
+               if (((srr1 & wmask) == SRR1_WAKEEE) ||
+                   (local_paca->irq_happened & PACA_IRQ_EE)) {
                        icp_native_flush_interrupt();
-                       local_paca->irq_happened &= PACA_IRQ_HARD_DIS;
-                       smp_mb();
                } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
                        unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
                        asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
-                       kvmppc_set_host_ipi(cpu, 0);
                }
+               local_paca->irq_happened &= ~(PACA_IRQ_EE | PACA_IRQ_DBELL);
+               smp_mb();
 
                if (cpu_core_split_required())
                        continue;
 
-               if (!generic_check_cpu_restart(cpu))
+               if (srr1 && !generic_check_cpu_restart(cpu))
                        DBG("CPU%d Unexpected exit while offline !\n", cpu);
        }
        mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
index 09787139834ddd8bd01fbce0448ca34297a1cd5c..3db53e8aff9279cfe761ac9f43926559e347eaf4 100644 (file)
@@ -194,11 +194,6 @@ static const struct os_area_db_id os_area_db_id_rtc_diff = {
        .key = OS_AREA_DB_KEY_RTC_DIFF
 };
 
-static const struct os_area_db_id os_area_db_id_video_mode = {
-       .owner = OS_AREA_DB_OWNER_LINUX,
-       .key = OS_AREA_DB_KEY_VIDEO_MODE
-};
-
 #define SECONDS_FROM_1970_TO_2000 946684800LL
 
 /**
index fe20d14ae051a5892350185d55ce1adfc352e538..ceb5201a30ed36899010715143b8679cd4a819fb 100644 (file)
@@ -59,6 +59,7 @@ pages_do_alias(unsigned long addr1, unsigned long addr2)
 
 #define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, void *from);
+#define copy_user_page(to, from, vaddr, pg)  __copy_user(to, from, PAGE_SIZE)
 
 struct page;
 struct vm_area_struct;
index 2e48eb8813ffa2fccf6df34ad5cee3bcf1857f94..c90930de76ba8670041598ba0d6461ef439c9539 100644 (file)
@@ -433,6 +433,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = AES_MIN_KEY_SIZE,
                        .max_keysize    = AES_MAX_KEY_SIZE,
+                       .ivsize         = AES_BLOCK_SIZE,
                        .setkey         = aes_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
@@ -452,6 +453,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = AES_MIN_KEY_SIZE,
                        .max_keysize    = AES_MAX_KEY_SIZE,
+                       .ivsize         = AES_BLOCK_SIZE,
                        .setkey         = aes_set_key,
                        .encrypt        = ctr_crypt,
                        .decrypt        = ctr_crypt,
index 6bf2479a12fbe2a9c82b4275e40ac9e85ac191ed..561a84d93cf682a400a7555862f065f1fb04c84c 100644 (file)
@@ -274,6 +274,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = CAMELLIA_MIN_KEY_SIZE,
                        .max_keysize    = CAMELLIA_MAX_KEY_SIZE,
+                       .ivsize         = CAMELLIA_BLOCK_SIZE,
                        .setkey         = camellia_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
index dd6a34fa6e19d2e36f5d30de6256655dc0ee2e0c..61af794aa2d31d5df27d0a318ac8b8f9d605637b 100644 (file)
@@ -429,6 +429,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = DES_KEY_SIZE,
                        .max_keysize    = DES_KEY_SIZE,
+                       .ivsize         = DES_BLOCK_SIZE,
                        .setkey         = des_set_key,
                        .encrypt        = cbc_encrypt,
                        .decrypt        = cbc_decrypt,
@@ -485,6 +486,7 @@ static struct crypto_alg algs[] = { {
                .blkcipher = {
                        .min_keysize    = DES3_EDE_KEY_SIZE,
                        .max_keysize    = DES3_EDE_KEY_SIZE,
+                       .ivsize         = DES3_EDE_BLOCK_SIZE,
                        .setkey         = des3_ede_set_key,
                        .encrypt        = cbc3_encrypt,
                        .decrypt        = cbc3_decrypt,
index 098ab3333e7cdd5e4cdce7f20b28c7678ed2a852..e3abe6f3156d3fbacca4003c072954619c7e1bb1 100644 (file)
@@ -70,8 +70,8 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE)
 
 USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
                $(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
-               -D_FILE_OFFSET_BITS=64 -idirafter include \
-               -D__KERNEL__ -D__UM_HOST__
+               -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
+               -idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__
 
 #This will adjust *FLAGS accordingly to the platform.
 include $(ARCH_DIR)/Makefile-os-$(OS)
index d8a9fce6ee2e5b10a63405654c3958c7361951fe..98783dd0fa2ea697a50cb65afb661aa7f7bf0322 100644 (file)
@@ -220,7 +220,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
                show_regs(container_of(regs, struct pt_regs, regs));
                panic("Segfault with no mm");
        }
-       else if (!is_user && address < TASK_SIZE) {
+       else if (!is_user && address > PAGE_SIZE && address < TASK_SIZE) {
                show_regs(container_of(regs, struct pt_regs, regs));
                panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
                       address, ip);
index e3ee4a51ef63a3ec7e7314aa7f00d59ec93ce37e..3f02d42328127bc6c41b786fd9b10145256cd57f 100644 (file)
@@ -96,7 +96,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
                               "ret = %d\n", -n);
                        ret = n;
                }
-               CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
+               CATCH_EINTR(waitpid(pid, NULL, __WALL));
        }
 
 out_free2:
@@ -129,7 +129,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
                return err;
        }
        if (stack_out == NULL) {
-               CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
+               CATCH_EINTR(pid = waitpid(pid, &status, __WALL));
                if (pid < 0) {
                        err = -errno;
                        printk(UM_KERN_ERR "run_helper_thread - wait failed, "
@@ -148,7 +148,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
 int helper_wait(int pid)
 {
        int ret, status;
-       int wflags = __WCLONE;
+       int wflags = __WALL;
 
        CATCH_EINTR(ret = waitpid(pid, &status, wflags));
        if (ret < 0) {
index ee1b6d346b983ad196a003dcb47c7a1de439eb3b..db51c1f27446157001cedc87bdd38b551e2f1844 100644 (file)
@@ -667,6 +667,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                bool conout_found = false;
                void *dummy = NULL;
                u32 h = handles[i];
+               u32 current_fb_base;
 
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop32);
@@ -678,7 +679,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                if (status == EFI_SUCCESS)
                        conout_found = true;
 
-               status = __gop_query32(gop32, &info, &size, &fb_base);
+               status = __gop_query32(gop32, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
@@ -692,6 +693,7 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto,
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
+                       fb_base = current_fb_base;
 
                        /*
                         * Once we've found a GOP supporting ConOut,
@@ -770,6 +772,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                bool conout_found = false;
                void *dummy = NULL;
                u64 h = handles[i];
+               u32 current_fb_base;
 
                status = efi_call_early(handle_protocol, h,
                                        proto, (void **)&gop64);
@@ -781,7 +784,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                if (status == EFI_SUCCESS)
                        conout_found = true;
 
-               status = __gop_query64(gop64, &info, &size, &fb_base);
+               status = __gop_query64(gop64, &info, &size, &current_fb_base);
                if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
                        /*
                         * Systems that use the UEFI Console Splitter may
@@ -795,6 +798,7 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto,
                        pixel_format = info->pixel_format;
                        pixel_info = info->pixel_information;
                        pixels_per_scan_line = info->pixels_per_scan_line;
+                       fb_base = current_fb_base;
 
                        /*
                         * Once we've found a GOP supporting ConOut,
index 80a0e4389c9ad3f5e6e1f6d8bc5292e391801ff2..bacaa13acac544e037571bd292e91f5239256edc 100644 (file)
@@ -554,6 +554,11 @@ static int __init camellia_aesni_init(void)
 {
        const char *feature_name;
 
+       if (!cpu_has_avx || !cpu_has_aes || !cpu_has_osxsave) {
+               pr_info("AVX or AES-NI instructions are not detected.\n");
+               return -ENODEV;
+       }
+
        if (!cpu_has_xfeatures(XSTATE_SSE | XSTATE_YMM, &feature_name)) {
                pr_info("CPU feature '%s' is not supported.\n", feature_name);
                return -ENODEV;
index 2beee03820889b6c6b436e884a4e83e023d76f9a..3a36ee704c307414b305e1cac21ec9aba4de5872 100644 (file)
@@ -1226,10 +1226,8 @@ void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 
 int kvm_is_in_guest(void);
 
-int __x86_set_memory_region(struct kvm *kvm,
-                           const struct kvm_userspace_memory_region *mem);
-int x86_set_memory_region(struct kvm *kvm,
-                         const struct kvm_userspace_memory_region *mem);
+int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size);
+int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size);
 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
 bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
 
index e4661196994e86b189da7f6c2e84841d3dcdcb9b..ff8b9a17dc4b2d354971fb52b60b69e6fbb0e903 100644 (file)
@@ -27,12 +27,11 @@ static __always_inline void *__inline_memcpy(void *to, const void *from, size_t
    function. */
 
 #define __HAVE_ARCH_MEMCPY 1
+extern void *memcpy(void *to, const void *from, size_t len);
 extern void *__memcpy(void *to, const void *from, size_t len);
 
 #ifndef CONFIG_KMEMCHECK
-#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
-extern void *memcpy(void *to, const void *from, size_t len);
-#else
+#if (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || __GNUC__ < 4
 #define memcpy(dst, src, len)                                  \
 ({                                                             \
        size_t __len = (len);                                   \
index ded848c20e05a115a3556b95cd4a8d6b30c0bdbe..e75907601a41c349e05c8dfe63047dc460ccdf30 100644 (file)
@@ -976,6 +976,8 @@ static int __init acpi_parse_madt_lapic_entries(void)
 {
        int count;
        int x2count = 0;
+       int ret;
+       struct acpi_subtable_proc madt_proc[2];
 
        if (!cpu_has_apic)
                return -ENODEV;
@@ -999,10 +1001,22 @@ static int __init acpi_parse_madt_lapic_entries(void)
                                      acpi_parse_sapic, MAX_LOCAL_APIC);
 
        if (!count) {
-               x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
-                                       acpi_parse_x2apic, MAX_LOCAL_APIC);
-               count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
-                                       acpi_parse_lapic, MAX_LOCAL_APIC);
+               memset(madt_proc, 0, sizeof(madt_proc));
+               madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+               madt_proc[0].handler = acpi_parse_lapic;
+               madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+               madt_proc[1].handler = acpi_parse_x2apic;
+               ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+                               sizeof(struct acpi_table_madt),
+                               madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+               if (ret < 0) {
+                       printk(KERN_ERR PREFIX
+                                       "Error parsing LAPIC/X2APIC entries\n");
+                       return ret;
+               }
+
+               x2count = madt_proc[0].count;
+               count = madt_proc[1].count;
        }
        if (!count && !x2count) {
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
index 5c60bb16262203ab63720ee349384180e9e7d8fb..bb6bfc01cb82dd6ffbe4aa49e92020b2600584d6 100644 (file)
@@ -2907,6 +2907,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
        struct irq_data *irq_data;
        struct mp_chip_data *data;
        struct irq_alloc_info *info = arg;
+       unsigned long flags;
 
        if (!info || nr_irqs > 1)
                return -EINVAL;
@@ -2939,11 +2940,14 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
 
        cfg = irqd_cfg(irq_data);
        add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
+
+       local_irq_save(flags);
        if (info->ioapic_entry)
                mp_setup_entry(cfg, data, info->ioapic_entry);
        mp_register_handler(virq, data->trigger);
        if (virq < nr_legacy_irqs())
                legacy_pic->mask(virq);
+       local_irq_restore(flags);
 
        apic_printk(APIC_VERBOSE, KERN_DEBUG
                    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n",
index 39e585a554b71d2a469c8b8c3ba487be7edc87a7..e28db181e4fcb04d19c02e7709e20fabb06f8c29 100644 (file)
@@ -550,14 +550,14 @@ unsigned long get_wchan(struct task_struct *p)
        if (sp < bottom || sp > top)
                return 0;
 
-       fp = READ_ONCE(*(unsigned long *)sp);
+       fp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
        do {
                if (fp < bottom || fp > top)
                        return 0;
-               ip = READ_ONCE(*(unsigned long *)(fp + sizeof(unsigned long)));
+               ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long)));
                if (!in_sched_functions(ip))
                        return ip;
-               fp = READ_ONCE(*(unsigned long *)fp);
+               fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
        } while (count++ < 16 && p->state != TASK_RUNNING);
        return 0;
 }
index fdb7f2a2d3286013a7ea41d392e48596c90fc672..a3cccbfc5f777e3483cad7da4a5a587bdd56c09c 100644 (file)
@@ -1173,6 +1173,14 @@ void __init setup_arch(char **cmdline_p)
        clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
                        swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
                        KERNEL_PGD_PTRS);
+
+       /*
+        * sync back low identity map too.  It is used for example
+        * in the 32-bit EFI stub.
+        */
+       clone_pgd_range(initial_page_table,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
 #endif
 
        tboot_probe();
index e0c198e5f920202bf25fa36e34922d4b0d29d82c..892ee2e5ecbce417df506715f7b28d28c403ef91 100644 (file)
@@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
  */
 #define UDELAY_10MS_DEFAULT 10000
 
-static unsigned int init_udelay = UDELAY_10MS_DEFAULT;
+static unsigned int init_udelay = INT_MAX;
 
 static int __init cpu_init_udelay(char *str)
 {
@@ -522,13 +522,16 @@ early_param("cpu_init_udelay", cpu_init_udelay);
 static void __init smp_quirk_init_udelay(void)
 {
        /* if cmdline changed it from default, leave it alone */
-       if (init_udelay != UDELAY_10MS_DEFAULT)
+       if (init_udelay != INT_MAX)
                return;
 
        /* if modern processor, use no delay */
        if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
            ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF)))
                init_udelay = 0;
+
+       /* else, use legacy delay */
+       init_udelay = UDELAY_10MS_DEFAULT;
 }
 
 /*
@@ -657,7 +660,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
-               if (init_udelay)
+               if (init_udelay == 0)
+                       udelay(10);
+               else
                        udelay(300);
 
                pr_debug("Startup point 1\n");
@@ -668,7 +673,9 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
-               if (init_udelay)
+               if (init_udelay == 0)
+                       udelay(10);
+               else
                        udelay(200);
 
                if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
index b372a7557c16c7d8391fffafdf0b1c74b49c4822..9da95b9daf8deb83af606ae0fffb73f7fab74ff2 100644 (file)
@@ -2418,7 +2418,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
        u64 val, cr0, cr4;
        u32 base3;
        u16 selector;
-       int i;
+       int i, r;
 
        for (i = 0; i < 16; i++)
                *reg_write(ctxt, i) = GET_SMSTATE(u64, smbase, 0x7ff8 - i * 8);
@@ -2460,13 +2460,17 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
        dt.address =                GET_SMSTATE(u64, smbase, 0x7e68);
        ctxt->ops->set_gdt(ctxt, &dt);
 
+       r = rsm_enter_protected_mode(ctxt, cr0, cr4);
+       if (r != X86EMUL_CONTINUE)
+               return r;
+
        for (i = 0; i < 6; i++) {
-               int r = rsm_load_seg_64(ctxt, smbase, i);
+               r = rsm_load_seg_64(ctxt, smbase, i);
                if (r != X86EMUL_CONTINUE)
                        return r;
        }
 
-       return rsm_enter_protected_mode(ctxt, cr0, cr4);
+       return X86EMUL_CONTINUE;
 }
 
 static int em_rsm(struct x86_emulate_ctxt *ctxt)
index 06ef4908ba61d2e25ead615953a2f42c923a9219..6a8bc64566abde57f8914f103a6b5d9d49ed8ae8 100644 (file)
@@ -4105,17 +4105,13 @@ static void seg_setup(int seg)
 static int alloc_apic_access_page(struct kvm *kvm)
 {
        struct page *page;
-       struct kvm_userspace_memory_region kvm_userspace_mem;
        int r = 0;
 
        mutex_lock(&kvm->slots_lock);
        if (kvm->arch.apic_access_page_done)
                goto out;
-       kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
-       kvm_userspace_mem.flags = 0;
-       kvm_userspace_mem.guest_phys_addr = APIC_DEFAULT_PHYS_BASE;
-       kvm_userspace_mem.memory_size = PAGE_SIZE;
-       r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
+       r = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
+                                   APIC_DEFAULT_PHYS_BASE, PAGE_SIZE);
        if (r)
                goto out;
 
@@ -4140,17 +4136,12 @@ static int alloc_identity_pagetable(struct kvm *kvm)
 {
        /* Called with kvm->slots_lock held. */
 
-       struct kvm_userspace_memory_region kvm_userspace_mem;
        int r = 0;
 
        BUG_ON(kvm->arch.ept_identity_pagetable_done);
 
-       kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
-       kvm_userspace_mem.flags = 0;
-       kvm_userspace_mem.guest_phys_addr =
-               kvm->arch.ept_identity_map_addr;
-       kvm_userspace_mem.memory_size = PAGE_SIZE;
-       r = __x86_set_memory_region(kvm, &kvm_userspace_mem);
+       r = __x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT,
+                                   kvm->arch.ept_identity_map_addr, PAGE_SIZE);
 
        return r;
 }
@@ -4949,14 +4940,9 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
 {
        int ret;
-       struct kvm_userspace_memory_region tss_mem = {
-               .slot = TSS_PRIVATE_MEMSLOT,
-               .guest_phys_addr = addr,
-               .memory_size = PAGE_SIZE * 3,
-               .flags = 0,
-       };
 
-       ret = x86_set_memory_region(kvm, &tss_mem);
+       ret = x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, addr,
+                                   PAGE_SIZE * 3);
        if (ret)
                return ret;
        kvm->arch.tss_addr = addr;
index 92511d4b72364a978db0b38628b9449907ee1832..9a9a198303219b6430159af03d4d1e1d898ec6f7 100644 (file)
@@ -6453,6 +6453,12 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu)
        return 1;
 }
 
+static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu)
+{
+       return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
+               !vcpu->arch.apf.halted);
+}
+
 static int vcpu_run(struct kvm_vcpu *vcpu)
 {
        int r;
@@ -6461,8 +6467,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
        vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
 
        for (;;) {
-               if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
-                   !vcpu->arch.apf.halted)
+               if (kvm_vcpu_running(vcpu))
                        r = vcpu_enter_guest(vcpu);
                else
                        r = vcpu_block(kvm, vcpu);
@@ -7474,34 +7479,66 @@ void kvm_arch_sync_events(struct kvm *kvm)
        kvm_free_pit(kvm);
 }
 
-int __x86_set_memory_region(struct kvm *kvm,
-                           const struct kvm_userspace_memory_region *mem)
+int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
 {
        int i, r;
+       unsigned long hva;
+       struct kvm_memslots *slots = kvm_memslots(kvm);
+       struct kvm_memory_slot *slot, old;
 
        /* Called with kvm->slots_lock held.  */
-       BUG_ON(mem->slot >= KVM_MEM_SLOTS_NUM);
+       if (WARN_ON(id >= KVM_MEM_SLOTS_NUM))
+               return -EINVAL;
+
+       slot = id_to_memslot(slots, id);
+       if (size) {
+               if (WARN_ON(slot->npages))
+                       return -EEXIST;
+
+               /*
+                * MAP_SHARED to prevent internal slot pages from being moved
+                * by fork()/COW.
+                */
+               hva = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE,
+                             MAP_SHARED | MAP_ANONYMOUS, 0);
+               if (IS_ERR((void *)hva))
+                       return PTR_ERR((void *)hva);
+       } else {
+               if (!slot->npages)
+                       return 0;
 
+               hva = 0;
+       }
+
+       old = *slot;
        for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
-               struct kvm_userspace_memory_region m = *mem;
+               struct kvm_userspace_memory_region m;
 
-               m.slot |= i << 16;
+               m.slot = id | (i << 16);
+               m.flags = 0;
+               m.guest_phys_addr = gpa;
+               m.userspace_addr = hva;
+               m.memory_size = size;
                r = __kvm_set_memory_region(kvm, &m);
                if (r < 0)
                        return r;
        }
 
+       if (!size) {
+               r = vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE);
+               WARN_ON(r < 0);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(__x86_set_memory_region);
 
-int x86_set_memory_region(struct kvm *kvm,
-                         const struct kvm_userspace_memory_region *mem)
+int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
 {
        int r;
 
        mutex_lock(&kvm->slots_lock);
-       r = __x86_set_memory_region(kvm, mem);
+       r = __x86_set_memory_region(kvm, id, gpa, size);
        mutex_unlock(&kvm->slots_lock);
 
        return r;
@@ -7516,16 +7553,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
                 * unless the the memory map has changed due to process exit
                 * or fd copying.
                 */
-               struct kvm_userspace_memory_region mem;
-               memset(&mem, 0, sizeof(mem));
-               mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
-
-               mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
-
-               mem.slot = TSS_PRIVATE_MEMSLOT;
-               x86_set_memory_region(kvm, &mem);
+               x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, 0, 0);
+               x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, 0, 0);
+               x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, 0, 0);
        }
        kvm_iommu_unmap_guest(kvm);
        kfree(kvm->arch.vpic);
@@ -7628,27 +7658,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                                const struct kvm_userspace_memory_region *mem,
                                enum kvm_mr_change change)
 {
-       /*
-        * Only private memory slots need to be mapped here since
-        * KVM_SET_MEMORY_REGION ioctl is no longer supported.
-        */
-       if ((memslot->id >= KVM_USER_MEM_SLOTS) && (change == KVM_MR_CREATE)) {
-               unsigned long userspace_addr;
-
-               /*
-                * MAP_SHARED to prevent internal slot pages from being moved
-                * by fork()/COW.
-                */
-               userspace_addr = vm_mmap(NULL, 0, memslot->npages * PAGE_SIZE,
-                                        PROT_READ | PROT_WRITE,
-                                        MAP_SHARED | MAP_ANONYMOUS, 0);
-
-               if (IS_ERR((void *)userspace_addr))
-                       return PTR_ERR((void *)userspace_addr);
-
-               memslot->userspace_addr = userspace_addr;
-       }
-
        return 0;
 }
 
@@ -7710,17 +7719,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 {
        int nr_mmu_pages = 0;
 
-       if (change == KVM_MR_DELETE && old->id >= KVM_USER_MEM_SLOTS) {
-               int ret;
-
-               ret = vm_munmap(old->userspace_addr,
-                               old->npages * PAGE_SIZE);
-               if (ret < 0)
-                       printk(KERN_WARNING
-                              "kvm_vm_ioctl_set_memory_region: "
-                              "failed to munmap memory\n");
-       }
-
        if (!kvm->arch.n_requested_mmu_pages)
                nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
 
@@ -7769,19 +7767,36 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
        kvm_mmu_invalidate_zap_all_pages(kvm);
 }
 
+static inline bool kvm_vcpu_has_events(struct kvm_vcpu *vcpu)
+{
+       if (!list_empty_careful(&vcpu->async_pf.done))
+               return true;
+
+       if (kvm_apic_has_events(vcpu))
+               return true;
+
+       if (vcpu->arch.pv.pv_unhalted)
+               return true;
+
+       if (atomic_read(&vcpu->arch.nmi_queued))
+               return true;
+
+       if (test_bit(KVM_REQ_SMI, &vcpu->requests))
+               return true;
+
+       if (kvm_arch_interrupt_allowed(vcpu) &&
+           kvm_cpu_has_interrupt(vcpu))
+               return true;
+
+       return false;
+}
+
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
 {
        if (is_guest_mode(vcpu) && kvm_x86_ops->check_nested_events)
                kvm_x86_ops->check_nested_events(vcpu, false);
 
-       return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
-               !vcpu->arch.apf.halted)
-               || !list_empty_careful(&vcpu->async_pf.done)
-               || kvm_apic_has_events(vcpu)
-               || vcpu->arch.pv.pv_unhalted
-               || atomic_read(&vcpu->arch.nmi_queued) ||
-               (kvm_arch_interrupt_allowed(vcpu) &&
-                kvm_cpu_has_interrupt(vcpu));
+       return kvm_vcpu_running(vcpu) || kvm_vcpu_has_events(vcpu);
 }
 
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
index ff9911707160ac7691e119aad62f32d7f61c143a..3cd69832d7f4c6f3743bbb3a190c39672c89461d 100644 (file)
@@ -4,16 +4,15 @@
 #include <linux/irq.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/pci-acpi.h>
 #include <asm/numa.h>
 #include <asm/pci_x86.h>
 
 struct pci_root_info {
-       struct acpi_device *bridge;
-       char name[16];
+       struct acpi_pci_root_info common;
        struct pci_sysdata sd;
 #ifdef CONFIG_PCI_MMCONFIG
        bool mcfg_added;
-       u16 segment;
        u8 start_bus;
        u8 end_bus;
 #endif
@@ -178,15 +177,18 @@ static int check_segment(u16 seg, struct device *dev, char *estr)
        return 0;
 }
 
-static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
-                         u8 end, phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
 {
-       int result;
-       struct device *dev = &info->bridge->dev;
+       int result, seg;
+       struct pci_root_info *info;
+       struct acpi_pci_root *root = ci->root;
+       struct device *dev = &ci->bridge->dev;
 
-       info->start_bus = start;
-       info->end_bus = end;
+       info = container_of(ci, struct pci_root_info, common);
+       info->start_bus = (u8)root->secondary.start;
+       info->end_bus = (u8)root->secondary.end;
        info->mcfg_added = false;
+       seg = info->sd.domain;
 
        /* return success if MMCFG is not in use */
        if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
@@ -195,7 +197,8 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
        if (!(pci_probe & PCI_PROBE_MMCONF))
                return check_segment(seg, dev, "MMCONFIG is disabled,");
 
-       result = pci_mmconfig_insert(dev, seg, start, end, addr);
+       result = pci_mmconfig_insert(dev, seg, info->start_bus, info->end_bus,
+                                    root->mcfg_addr);
        if (result == 0) {
                /* enable MMCFG if it hasn't been enabled yet */
                if (raw_pci_ext_ops == NULL)
@@ -208,134 +211,55 @@ static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
        return 0;
 }
 
-static void teardown_mcfg_map(struct pci_root_info *info)
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
 {
+       struct pci_root_info *info;
+
+       info = container_of(ci, struct pci_root_info, common);
        if (info->mcfg_added) {
-               pci_mmconfig_delete(info->segment, info->start_bus,
-                                   info->end_bus);
+               pci_mmconfig_delete(info->sd.domain,
+                                   info->start_bus, info->end_bus);
                info->mcfg_added = false;
        }
 }
 #else
-static int setup_mcfg_map(struct pci_root_info *info,
-                                   u16 seg, u8 start, u8 end,
-                                   phys_addr_t addr)
+static int setup_mcfg_map(struct acpi_pci_root_info *ci)
 {
        return 0;
 }
-static void teardown_mcfg_map(struct pci_root_info *info)
+
+static void teardown_mcfg_map(struct acpi_pci_root_info *ci)
 {
 }
 #endif
 
-static void validate_resources(struct device *dev, struct list_head *crs_res,
-                              unsigned long type)
+static int pci_acpi_root_get_node(struct acpi_pci_root *root)
 {
-       LIST_HEAD(list);
-       struct resource *res1, *res2, *root = NULL;
-       struct resource_entry *tmp, *entry, *entry2;
-
-       BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
-       root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
-
-       list_splice_init(crs_res, &list);
-       resource_list_for_each_entry_safe(entry, tmp, &list) {
-               bool free = false;
-               resource_size_t end;
-
-               res1 = entry->res;
-               if (!(res1->flags & type))
-                       goto next;
-
-               /* Exclude non-addressable range or non-addressable portion */
-               end = min(res1->end, root->end);
-               if (end <= res1->start) {
-                       dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
-                                res1);
-                       free = true;
-                       goto next;
-               } else if (res1->end != end) {
-                       dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
-                                res1, (unsigned long long)end + 1,
-                                (unsigned long long)res1->end);
-                       res1->end = end;
-               }
-
-               resource_list_for_each_entry(entry2, crs_res) {
-                       res2 = entry2->res;
-                       if (!(res2->flags & type))
-                               continue;
-
-                       /*
-                        * I don't like throwing away windows because then
-                        * our resources no longer match the ACPI _CRS, but
-                        * the kernel resource tree doesn't allow overlaps.
-                        */
-                       if (resource_overlaps(res1, res2)) {
-                               res2->start = min(res1->start, res2->start);
-                               res2->end = max(res1->end, res2->end);
-                               dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
-                                        res2, res1);
-                               free = true;
-                               goto next;
-                       }
-               }
+       int busnum = root->secondary.start;
+       struct acpi_device *device = root->device;
+       int node = acpi_get_node(device->handle);
 
-next:
-               resource_list_del(entry);
-               if (free)
-                       resource_list_free_entry(entry);
-               else
-                       resource_list_add_tail(entry, crs_res);
+       if (node == NUMA_NO_NODE) {
+               node = x86_pci_root_bus_node(busnum);
+               if (node != 0 && node != NUMA_NO_NODE)
+                       dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
+                               node);
        }
+       if (node != NUMA_NO_NODE && !node_online(node))
+               node = NUMA_NO_NODE;
+
+       return node;
 }
 
-static void add_resources(struct pci_root_info *info,
-                         struct list_head *resources,
-                         struct list_head *crs_res)
+static int pci_acpi_root_init_info(struct acpi_pci_root_info *ci)
 {
-       struct resource_entry *entry, *tmp;
-       struct resource *res, *conflict, *root = NULL;
-
-       validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM);
-       validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO);
-
-       resource_list_for_each_entry_safe(entry, tmp, crs_res) {
-               res = entry->res;
-               if (res->flags & IORESOURCE_MEM)
-                       root = &iomem_resource;
-               else if (res->flags & IORESOURCE_IO)
-                       root = &ioport_resource;
-               else
-                       BUG_ON(res);
-
-               conflict = insert_resource_conflict(root, res);
-               if (conflict) {
-                       dev_info(&info->bridge->dev,
-                                "ignoring host bridge window %pR (conflicts with %s %pR)\n",
-                                res, conflict->name, conflict);
-                       resource_list_destroy_entry(entry);
-               }
-       }
-
-       list_splice_tail(crs_res, resources);
+       return setup_mcfg_map(ci);
 }
 
-static void release_pci_root_info(struct pci_host_bridge *bridge)
+static void pci_acpi_root_release_info(struct acpi_pci_root_info *ci)
 {
-       struct resource *res;
-       struct resource_entry *entry;
-       struct pci_root_info *info = bridge->release_data;
-
-       resource_list_for_each_entry(entry, &bridge->windows) {
-               res = entry->res;
-               if (res->parent &&
-                   (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
-                       release_resource(res);
-       }
-
-       teardown_mcfg_map(info);
-       kfree(info);
+       teardown_mcfg_map(ci);
+       kfree(container_of(ci, struct pci_root_info, common));
 }
 
 /*
@@ -358,50 +282,47 @@ static bool resource_is_pcicfg_ioport(struct resource *res)
                res->start == 0xCF8 && res->end == 0xCFF;
 }
 
-static void probe_pci_root_info(struct pci_root_info *info,
-                               struct acpi_device *device,
-                               int busnum, int domain,
-                               struct list_head *list)
+static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
 {
-       int ret;
+       struct acpi_device *device = ci->bridge;
+       int busnum = ci->root->secondary.start;
        struct resource_entry *entry, *tmp;
+       int status;
 
-       sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
-       info->bridge = device;
-       ret = acpi_dev_get_resources(device, list,
-                                    acpi_dev_filter_resource_type_cb,
-                                    (void *)(IORESOURCE_IO | IORESOURCE_MEM));
-       if (ret < 0)
-               dev_warn(&device->dev,
-                        "failed to parse _CRS method, error code %d\n", ret);
-       else if (ret == 0)
-               dev_dbg(&device->dev,
-                       "no IO and memory resources present in _CRS\n");
-       else
-               resource_list_for_each_entry_safe(entry, tmp, list) {
-                       if ((entry->res->flags & IORESOURCE_DISABLED) ||
-                           resource_is_pcicfg_ioport(entry->res))
+       status = acpi_pci_probe_root_resources(ci);
+       if (pci_use_crs) {
+               resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
+                       if (resource_is_pcicfg_ioport(entry->res))
                                resource_list_destroy_entry(entry);
-                       else
-                               entry->res->name = info->name;
-               }
+               return status;
+       }
+
+       resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
+               dev_printk(KERN_DEBUG, &device->dev,
+                          "host bridge window %pR (ignored)\n", entry->res);
+               resource_list_destroy_entry(entry);
+       }
+       x86_pci_root_bus_resources(busnum, &ci->resources);
+
+       return 0;
 }
 
+static struct acpi_pci_root_ops acpi_pci_root_ops = {
+       .pci_ops = &pci_root_ops,
+       .init_info = pci_acpi_root_init_info,
+       .release_info = pci_acpi_root_release_info,
+       .prepare_resources = pci_acpi_root_prepare_resources,
+};
+
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
-       struct acpi_device *device = root->device;
-       struct pci_root_info *info;
        int domain = root->segment;
        int busnum = root->secondary.start;
-       struct resource_entry *res_entry;
-       LIST_HEAD(crs_res);
-       LIST_HEAD(resources);
+       int node = pci_acpi_root_get_node(root);
        struct pci_bus *bus;
-       struct pci_sysdata *sd;
-       int node;
 
        if (pci_ignore_seg)
-               domain = 0;
+               root->segment = domain = 0;
 
        if (domain && !pci_domains_supported) {
                printk(KERN_WARNING "pci_bus %04x:%02x: "
@@ -410,71 +331,33 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
                return NULL;
        }
 
-       node = acpi_get_node(device->handle);
-       if (node == NUMA_NO_NODE) {
-               node = x86_pci_root_bus_node(busnum);
-               if (node != 0 && node != NUMA_NO_NODE)
-                       dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
-                               node);
-       }
-
-       if (node != NUMA_NO_NODE && !node_online(node))
-               node = NUMA_NO_NODE;
-
-       info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
-       if (!info) {
-               printk(KERN_WARNING "pci_bus %04x:%02x: "
-                      "ignored (out of memory)\n", domain, busnum);
-               return NULL;
-       }
-
-       sd = &info->sd;
-       sd->domain = domain;
-       sd->node = node;
-       sd->companion = device;
-
        bus = pci_find_bus(domain, busnum);
        if (bus) {
                /*
                 * If the desired bus has been scanned already, replace
                 * its bus->sysdata.
                 */
-               memcpy(bus->sysdata, sd, sizeof(*sd));
-               kfree(info);
-       } else {
-               /* insert busn res at first */
-               pci_add_resource(&resources,  &root->secondary);
+               struct pci_sysdata sd = {
+                       .domain = domain,
+                       .node = node,
+                       .companion = root->device
+               };
 
-               /*
-                * _CRS with no apertures is normal, so only fall back to
-                * defaults or native bridge info if we're ignoring _CRS.
-                */
-               probe_pci_root_info(info, device, busnum, domain, &crs_res);
-               if (pci_use_crs) {
-                       add_resources(info, &resources, &crs_res);
-               } else {
-                       resource_list_for_each_entry(res_entry, &crs_res)
-                               dev_printk(KERN_DEBUG, &device->dev,
-                                          "host bridge window %pR (ignored)\n",
-                                          res_entry->res);
-                       resource_list_free(&crs_res);
-                       x86_pci_root_bus_resources(busnum, &resources);
-               }
-
-               if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
-                                   (u8)root->secondary.end, root->mcfg_addr))
-                       bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
-                                                 sd, &resources);
-
-               if (bus) {
-                       pci_scan_child_bus(bus);
-                       pci_set_host_bridge_release(
-                               to_pci_host_bridge(bus->bridge),
-                               release_pci_root_info, info);
-               } else {
-                       resource_list_free(&resources);
-                       teardown_mcfg_map(info);
-                       kfree(info);
+               memcpy(bus->sysdata, &sd, sizeof(sd));
+       } else {
+               struct pci_root_info *info;
+
+               info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
+               if (!info)
+                       dev_err(&root->device->dev,
+                               "pci_bus %04x:%02x: ignored (out of memory)\n",
+                               domain, busnum);
+               else {
+                       info->sd.domain = domain;
+                       info->sd.node = node;
+                       info->sd.companion = root->device;
+                       bus = acpi_pci_root_create(root, &acpi_pci_root_ops,
+                                                  &info->common, &info->sd);
                }
        }
 
@@ -487,9 +370,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
                        pcie_bus_configure_settings(child);
        }
 
-       if (bus && node != NUMA_NO_NODE)
-               dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
-
        return bus;
 }
 
index 9701a4fd7bf2ea83d640ddeefebd5e4d5de27598..836a1eb5df436bdad88fe3b4ae59b512f9573b19 100644 (file)
 #include <skas.h>
 #include <sysdep/tls.h>
 
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
+static inline int modify_ldt (int func, void *ptr, unsigned long bytecount)
+{
+       return syscall(__NR_modify_ldt, func, ptr, bytecount);
+}
 
 static long write_ldt_entry(struct mm_id *mm_idp, int func,
                     struct user_desc *desc, void **addr, int done)
index b97767dbc7c8e71d15d5d845f2388508ffc5b0ed..b9ad9feadc2d1a01da539d69fa735ebb61f607f2 100644 (file)
@@ -148,7 +148,7 @@ void __init time_init(void)
        local_timer_setup(0);
        setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction);
        sched_clock_register(ccount_sched_clock_read, 32, ccount_freq);
-       clocksource_of_init();
+       clocksource_probe();
 }
 
 /*
index 2eb722d48773cb8a8de49d58b934eed830755da7..18e92a6645e24741b786bc35f14b9d06f1355569 100644 (file)
@@ -576,7 +576,7 @@ void blk_cleanup_queue(struct request_queue *q)
                q->queue_lock = &q->__queue_lock;
        spin_unlock_irq(lock);
 
-       bdi_destroy(&q->backing_dev_info);
+       bdi_unregister(&q->backing_dev_info);
 
        /* @q is and will stay empty, shutdown and put */
        blk_put_queue(q);
index ed96474d75cb62fb261526736727c67ea2238d46..ec2d11915142a8f9b7a49e839e41a2f54a55aa09 100644 (file)
@@ -641,6 +641,7 @@ void blk_mq_free_tags(struct blk_mq_tags *tags)
 {
        bt_free(&tags->bitmap_tags);
        bt_free(&tags->breserved_tags);
+       free_cpumask_var(tags->cpumask);
        kfree(tags);
 }
 
index 7785ae96267a197926c700f74bcd6524892a8c01..85f014327342efc775c31833a52f531b69a66329 100644 (file)
@@ -2296,10 +2296,8 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set)
        int i;
 
        for (i = 0; i < set->nr_hw_queues; i++) {
-               if (set->tags[i]) {
+               if (set->tags[i])
                        blk_mq_free_rq_map(set, set->tags[i], i);
-                       free_cpumask_var(set->tags[i]->cpumask);
-               }
        }
 
        kfree(set->tags);
index 3e44a9da2a13579cacaee3d5e03bb3868f34d02a..07b42f5ad797b7b5e6367d5c70051d3b34fca55c 100644 (file)
@@ -540,6 +540,7 @@ static void blk_release_queue(struct kobject *kobj)
        struct request_queue *q =
                container_of(kobj, struct request_queue, kobj);
 
+       bdi_exit(&q->backing_dev_info);
        blkcg_exit_queue(q);
 
        if (q->elevator) {
index 8acb886032ae7a604fe0e965eb5d3ce07dd4845b..9c1dc8d6106a89a0f853271c1dfc49cd301ec983 100644 (file)
@@ -544,7 +544,8 @@ static int ahash_prepare_alg(struct ahash_alg *alg)
        struct crypto_alg *base = &alg->halg.base;
 
        if (alg->halg.digestsize > PAGE_SIZE / 8 ||
-           alg->halg.statesize > PAGE_SIZE / 8)
+           alg->halg.statesize > PAGE_SIZE / 8 ||
+           alg->halg.statesize == 0)
                return -EINVAL;
 
        base->cra_type = &crypto_ahash_type;
index 5d1015c26ff4cf9bb20adc92da1cb0f3921c3a14..25dbb76c02ccb0fd1d9b56d9956acb115d2e8419 100644 (file)
@@ -57,6 +57,15 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
        bool
 
+config ACPI_DEBUGGER
+       bool "In-kernel debugger (EXPERIMENTAL)"
+       select ACPI_DEBUG
+       help
+         Enable in-kernel debugging facilities: statistics, internal
+         object dump, single step control method execution.
+         This is still under development, currently enabling this only
+         results in the compilation of the ACPICA debugger files.
+
 config ACPI_SLEEP
        bool
        depends on SUSPEND || HIBERNATION
@@ -197,11 +206,25 @@ config ACPI_PROCESSOR_IDLE
        bool
        select CPU_IDLE
 
+config ACPI_CPPC_LIB
+       bool
+       depends on ACPI_PROCESSOR
+       depends on !ACPI_CPU_FREQ_PSS
+       select MAILBOX
+       select PCC
+       help
+         If this option is enabled, this file implements common functionality
+         to parse CPPC tables as described in the ACPI 5.1+ spec. The
+         routines implemented are meant to be used by other
+         drivers to control CPU performance using CPPC semantics.
+         If your platform does not support CPPC in firmware,
+         leave this option disabled.
+
 config ACPI_PROCESSOR
        tristate "Processor"
-       depends on X86 || IA64
-       select ACPI_PROCESSOR_IDLE
-       select ACPI_CPU_FREQ_PSS
+       depends on X86 || IA64 || ARM64
+       select ACPI_PROCESSOR_IDLE if X86 || IA64
+       select ACPI_CPU_FREQ_PSS if X86 || IA64
        default y
        help
          This driver adds support for the ACPI Processor package. It is required
index b5e7cd8a9c71ed22c8f7e21b3b41c0d8eecdfc9d..675eaf3371789618cdfb21ead69e121844dc006e 100644 (file)
@@ -78,6 +78,7 @@ obj-$(CONFIG_ACPI_HED)                += hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)  += ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)                += bgrt.o
+obj-$(CONFIG_ACPI_CPPC_LIB)    += cppc_acpi.o
 
 # processor has its own "processor." module_param namespace
 processor-y                    := processor_driver.o
index f51bd0d0bc17ceced34eab34463c8f048430de91..f9e0d09f7c66cf6bebfdaab992b3b1780b563766 100644 (file)
@@ -664,7 +664,7 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM_SLEEP
                .prepare = acpi_subsys_prepare,
-               .complete = acpi_subsys_complete,
+               .complete = pm_complete_with_resume_check,
                .suspend = acpi_subsys_suspend,
                .suspend_late = acpi_lpss_suspend_late,
                .resume_early = acpi_lpss_resume_early,
index ae307ff36acb9ed76a7a4d360c7c1ad7f99353fa..8ea8211b2d589c6618d5037e40d653a3771edc55 100644 (file)
@@ -148,8 +148,6 @@ static int power_saving_thread(void *data)
        while (!kthread_should_stop()) {
                unsigned long expire_time;
 
-               try_to_freeze();
-
                /* round robin to cpus */
                expire_time = last_jiffies + round_robin_time * HZ;
                if (time_before(expire_time, jiffies)) {
index c58940b231d69df0c135bd5f821dbef64ef5755c..48fc3ad13a4bbcfe5fc12a5db772855b5add0780 100644 (file)
@@ -316,7 +316,7 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
        {""},
 };
 
-static bool matching_id(char *idstr, char *list_id)
+static bool matching_id(const char *idstr, const char *list_id)
 {
        int i;
 
@@ -333,7 +333,7 @@ static bool matching_id(char *idstr, char *list_id)
        return true;
 }
 
-static bool acpi_pnp_match(char *idstr, const struct acpi_device_id **matchid)
+static bool acpi_pnp_match(const char *idstr, const struct acpi_device_id **matchid)
 {
        const struct acpi_device_id *devid;
 
index 985b8a83184e1e366ad39c3b326a1619b0b97bcb..6979186dbd4b45bd19b60b51d4fd76c76abd683f 100644 (file)
@@ -164,6 +164,24 @@ static int acpi_processor_errata(void)
    -------------------------------------------------------------------------- */
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
+int __weak acpi_map_cpu(acpi_handle handle,
+               phys_cpuid_t physid, int *pcpu)
+{
+       return -ENODEV;
+}
+
+int __weak acpi_unmap_cpu(int cpu)
+{
+       return -ENODEV;
+}
+
+int __weak arch_register_cpu(int cpu)
+{
+       return -ENODEV;
+}
+
+void __weak arch_unregister_cpu(int cpu) {}
+
 static int acpi_processor_hotadd_init(struct acpi_processor *pr)
 {
        unsigned long long sta;
index fedcc16b56cc5771ce2e6bddadb0705c84122b81..885936f7954287dcc15ef3048a1546137b25c61e 100644 (file)
@@ -123,7 +123,6 @@ acpi-y +=           \
        rsaddr.o        \
        rscalc.o        \
        rscreate.o      \
-       rsdump.o        \
        rsdumpinfo.o    \
        rsinfo.o        \
        rsio.o          \
@@ -178,7 +177,24 @@ acpi-y +=          \
        utxferror.o     \
        utxfmutex.o
 
+acpi-$(CONFIG_ACPI_DEBUGGER) +=        \
+       dbcmds.o                \
+       dbconvert.o             \
+       dbdisply.o              \
+       dbexec.o                \
+       dbhistry.o              \
+       dbinput.o               \
+       dbmethod.o              \
+       dbnames.o               \
+       dbobject.o              \
+       dbstats.o               \
+       dbutils.o               \
+       dbxface.o               \
+       rsdump.o                \
+
 acpi-$(ACPI_FUTURE_USAGE) +=   \
+       dbfileio.o              \
+       dbtest.o                \
        utcache.o               \
        utfileio.o              \
        utprint.o               \
index e9f0833e818d17c641a75adaa01c1f6fd4dcd4f3..e4cc48fbf4eef49bdcbac4a879e0739a0faac25f 100644 (file)
@@ -88,7 +88,7 @@
        acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY     "dsl"
-#define ACPI_TABLE_FILE_SUFFIX      ".dat"
+#define FILE_SUFFIX_BINARY_TABLE    ".dat"     /* Needs the dot */
 
 /*
  * getopt
index eb2e926d8218f04c6bedab32f8dfc5d5febfce90..c928ba494c4000ff71a54bcd4ea022082ee7ccc6 100644 (file)
 #ifndef __ACDEBUG_H__
 #define __ACDEBUG_H__
 
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include "acdisasm.h"
+#endif
+
 #define ACPI_DEBUG_BUFFER_SIZE  0x4000 /* 16K buffer for return objects */
 
 struct acpi_db_command_info {
index 09f37b51680871d8a34dc3a33563872652d4f0d6..faa97604d878e01a41707494435ed16d7f9b81fc 100644 (file)
@@ -61,6 +61,7 @@ ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
 ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
+ACPI_INIT_GLOBAL(u32, acpi_gbl_fadt_index, ACPI_INVALID_TABLE_INDEX);
 
 #if (!ACPI_REDUCED_HARDWARE)
 ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS);
@@ -324,9 +325,9 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 
 #ifdef ACPI_DEBUGGER
 
-ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support);
@@ -336,6 +337,8 @@ ACPI_GLOBAL(char *, acpi_gbl_db_filename);
 ACPI_GLOBAL(u32, acpi_gbl_db_debug_level);
 ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level);
 ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node);
+ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop);
+ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated);
 
 ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]);
 ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
@@ -357,6 +360,9 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
+
 #endif                         /* ACPI_DEBUGGER */
 
 /*****************************************************************************
index e820ed8f173f01b19322b426b66df6620aec8ce0..e9e936e78154c5eeed8134d1c04d317fd535a3f6 100644 (file)
@@ -397,12 +397,10 @@ void
 acpi_ex_dump_operands(union acpi_operand_object **operands,
                      const char *opcode_name, u32 num_opcodes);
 
-#ifdef ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
 void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*
  * exnames - AML namestring support
index 6f708267ad8cbf0d172704772a8b62d85783c3b1..e1dd784d851599e12a8adbf831d3f560f3c0dc94 100644 (file)
@@ -83,10 +83,8 @@ union acpi_parse_object;
 #define ACPI_MTX_EVENTS                 3      /* Data for ACPI events */
 #define ACPI_MTX_CACHES                 4      /* Internal caches, general purposes */
 #define ACPI_MTX_MEMORY                 5      /* Debug memory tracking lists */
-#define ACPI_MTX_DEBUG_CMD_COMPLETE     6      /* AML debugger */
-#define ACPI_MTX_DEBUG_CMD_READY        7      /* AML debugger */
 
-#define ACPI_MAX_MUTEX                  7
+#define ACPI_MAX_MUTEX                  5
 #define ACPI_NUM_MUTEX                  ACPI_MAX_MUTEX+1
 
 /* Lock structure for reader/writer interfaces */
@@ -111,6 +109,14 @@ struct acpi_rw_lock {
 
 #define ACPI_MUTEX_NOT_ACQUIRED         (acpi_thread_id) 0
 
+/* This Thread ID means an invalid thread ID */
+
+#ifdef ACPI_OS_INVALID_THREAD_ID
+#define ACPI_INVALID_THREAD_ID          ACPI_OS_INVALID_THREAD_ID
+#else
+#define ACPI_INVALID_THREAD_ID          ((acpi_thread_id) 0xFFFFFFFF)
+#endif
+
 /* Table for the global mutexes */
 
 struct acpi_mutex_info {
@@ -287,13 +293,17 @@ acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state);
 #define ACPI_BTYPE_BUFFER_FIELD         0x00002000
 #define ACPI_BTYPE_DDB_HANDLE           0x00004000
 #define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_REFERENCE_OBJECT     0x00010000     /* From Index(), ref_of(), etc (type6_opcodes) */
 #define ACPI_BTYPE_RESOURCE             0x00020000
+#define ACPI_BTYPE_NAMED_REFERENCE      0x00040000     /* Generic unresolved Name or Namepath */
 
 #define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
 
 #define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+
+       /* Used by Copy, de_ref_of, Store, Printf, Fprintf */
+
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE)
 #define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
 #define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF     /* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
@@ -848,7 +858,7 @@ struct acpi_parse_state {
 #define ACPI_PARSEOP_PARAMLIST          0x02
 #define ACPI_PARSEOP_EMPTY_TERMLIST     0x04
 #define ACPI_PARSEOP_PREDEF_CHECKED     0x08
-#define ACPI_PARSEOP_SPECIAL            0x10
+#define ACPI_PARSEOP_CLOSING_PAREN      0x10
 #define ACPI_PARSEOP_COMPOUND           0x20
 #define ACPI_PARSEOP_ASSIGNMENT         0x40
 
index ea0d9076d4087a697499b728ed766c9ddb484837..5d261c942a0d129150ab76c05e82af9b1ab43a2e 100644 (file)
@@ -193,9 +193,7 @@ acpi_ns_convert_to_resource(union acpi_operand_object *original_object,
 /*
  * nsdump - Namespace dump/print utilities
  */
-#ifdef ACPI_FUTURE_USAGE
 void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level);
 
@@ -208,7 +206,6 @@ acpi_status
 acpi_ns_dump_one_object(acpi_handle obj_handle,
                        u32 level, void *context, void **return_value);
 
-#ifdef ACPI_FUTURE_USAGE
 void
 acpi_ns_dump_objects(acpi_object_type type,
                     u8 display_type,
@@ -220,7 +217,6 @@ acpi_ns_dump_object_paths(acpi_object_type type,
                          u8 display_type,
                          u32 max_depth,
                          acpi_owner_id owner_id, acpi_handle start_handle);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*
  * nseval - Namespace evaluation functions
index fd85ad05a24ac716ec33214e8ec79fdc7d6f9014..f9acf92fa0bc2121b6a50a99874979d63e0fe37b 100644 (file)
 #define ARGI_ARG4                       ARG_NONE
 #define ARGI_ARG5                       ARG_NONE
 #define ARGI_ARG6                       ARG_NONE
-#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_BANK_FIELD_OP              ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
-#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_STORE_TARGET)
 #define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
 #define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
index 6021ccfb0b1c8cad1e80bd350355a2698f085320..8fc8c7cea87963ceb40c8a3184290ebe23b0d331 100644 (file)
@@ -194,10 +194,8 @@ union acpi_parse_object *acpi_ps_find(union acpi_parse_object *scope,
 
 union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn);
 
-#ifdef ACPI_FUTURE_USAGE
 union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
                                                union acpi_parse_object *op);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*
  * pswalk - parse tree walk routines
@@ -235,9 +233,7 @@ void acpi_ps_free_op(union acpi_parse_object *op);
 
 u8 acpi_ps_is_leading_char(u32 c);
 
-#ifdef ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object *op);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 void acpi_ps_set_name(union acpi_parse_object *op, u32 name);
 
index f7731f260c318606e32455b7175a01ea157d8267..591ea95319e25ca7e5630970dd080ab1eab85e5e 100644 (file)
@@ -85,7 +85,7 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index);
+void acpi_tb_parse_fadt(void);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -138,8 +138,6 @@ acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
  */
 acpi_status acpi_tb_initialize_facs(void);
 
-u8 acpi_tb_tables_loaded(void);
-
 void
 acpi_tb_print_table_header(acpi_physical_address address,
                           struct acpi_table_header *header);
index fb2aa5066f3fa8c980cc9184a6965bda3091fac8..8b8fef6cc32df7dac1d77191172550b5bf7b3d2c 100644 (file)
@@ -635,9 +635,7 @@ void
 acpi_ut_free_and_track(void *address,
                       u32 component, const char *module, u32 line);
 
-#ifdef ACPI_FUTURE_USAGE
 void acpi_ut_dump_allocation_info(void);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 void acpi_ut_dump_allocations(u32 component, const char *module);
 
index be9fd009cb28fa8e9d74c1826f3641cc2ebddabb..883f20cfa69809674d04db7070118bda7d2400d5 100644 (file)
 #define ARGI_TARGETREF              0x0F       /* Target, subject to implicit conversion */
 #define ARGI_FIXED_TARGET           0x10       /* Target, no implicit conversion */
 #define ARGI_SIMPLE_TARGET          0x11       /* Name, Local, Arg -- no implicit conversion */
+#define ARGI_STORE_TARGET           0x12       /* Target for store is TARGETREF + package objects */
 
 /* Multiple/complex types */
 
-#define ARGI_DATAOBJECT             0x12       /* Buffer, String, package or reference to a node - Used only by size_of operator */
-#define ARGI_COMPLEXOBJ             0x13       /* Buffer, String, or package (Used by INDEX op only) */
-#define ARGI_REF_OR_STRING          0x14       /* Reference or String (Used by DEREFOF op only) */
-#define ARGI_REGION_OR_BUFFER       0x15       /* Used by LOAD op only */
-#define ARGI_DATAREFOBJ             0x16
+#define ARGI_DATAOBJECT             0x13       /* Buffer, String, package or reference to a node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ             0x14       /* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_REF_OR_STRING          0x15       /* Reference or String (Used by DEREFOF op only) */
+#define ARGI_REGION_OR_BUFFER       0x16       /* Used by LOAD op only */
+#define ARGI_DATAREFOBJ             0x17
 
 /* Note: types above can expand to 0x1F maximum */
 
diff --git a/drivers/acpi/acpica/dbcmds.c b/drivers/acpi/acpica/dbcmds.c
new file mode 100644 (file)
index 0000000..30414b3
--- /dev/null
@@ -0,0 +1,1187 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acevents.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acresrc.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbcmds")
+
+/* Local prototypes */
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+                             acpi_rsdesc_size aml1_buffer_length,
+                             u8 *aml2_buffer,
+                             acpi_rsdesc_size aml2_buffer_length);
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context);
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+                        u32 nesting_level, void *context, void **return_value);
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state);
+
+static char *acpi_db_trace_method_name = NULL;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_node
+ *
+ * PARAMETERS:  in_string           - String to convert
+ *
+ * RETURN:      Pointer to a NS node
+ *
+ * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
+ *              alphanumeric strings.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
+{
+       struct acpi_namespace_node *node;
+       acpi_size address;
+
+       if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
+
+               /* Numeric argument, convert */
+
+               address = strtoul(in_string, NULL, 16);
+               node = ACPI_TO_POINTER(address);
+               if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
+                       acpi_os_printf("Address %p is invalid", node);
+                       return (NULL);
+               }
+
+               /* Make sure pointer is valid NS node */
+
+               if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+                       acpi_os_printf
+                           ("Address %p is not a valid namespace node [%s]\n",
+                            node, acpi_ut_get_descriptor_name(node));
+                       return (NULL);
+               }
+       } else {
+               /*
+                * Alpha argument: The parameter is a name string that must be
+                * resolved to a Namespace object.
+                */
+               node = acpi_db_local_ns_lookup(in_string);
+               if (!node) {
+                       acpi_os_printf
+                           ("Could not find [%s] in namespace, defaulting to root node\n",
+                            in_string);
+                       node = acpi_gbl_root_node;
+               }
+       }
+
+       return (node);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_sleep
+ *
+ * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
+ *                                    invoke all possible sleep states.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simulate sleep/wake sequences
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_sleep(char *object_arg)
+{
+       u8 sleep_state;
+       u32 i;
+
+       ACPI_FUNCTION_TRACE(acpi_db_sleep);
+
+       /* Null input (no arguments) means to invoke all sleep states */
+
+       if (!object_arg) {
+               acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
+                              ACPI_S_STATES_MAX);
+
+               for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
+                       acpi_db_do_one_sleep_state((u8)i);
+               }
+
+               return_ACPI_STATUS(AE_OK);
+       }
+
+       /* Convert argument to binary and invoke the sleep state */
+
+       sleep_state = (u8)strtoul(object_arg, NULL, 0);
+       acpi_db_do_one_sleep_state(sleep_state);
+       return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_do_one_sleep_state
+ *
+ * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate a sleep/wake sequence
+ *
+ ******************************************************************************/
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state)
+{
+       acpi_status status;
+       u8 sleep_type_a;
+       u8 sleep_type_b;
+
+       /* Validate parameter */
+
+       if (sleep_state > ACPI_S_STATES_MAX) {
+               acpi_os_printf("Sleep state %d out of range (%d max)\n",
+                              sleep_state, ACPI_S_STATES_MAX);
+               return;
+       }
+
+       acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
+                      sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
+
+       /* Get the values for the sleep type registers (for display only) */
+
+       status =
+           acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not evaluate [%s] method, %s\n",
+                              acpi_gbl_sleep_state_names[sleep_state],
+                              acpi_format_exception(status));
+               return;
+       }
+
+       acpi_os_printf
+           ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
+            sleep_state, sleep_type_a, sleep_type_b);
+
+       /* Invoke the various sleep/wake interfaces */
+
+       acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
+                      sleep_state);
+       status = acpi_enter_sleep_state_prep(sleep_state);
+       if (ACPI_FAILURE(status)) {
+               goto error_exit;
+       }
+
+       acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
+       status = acpi_enter_sleep_state(sleep_state);
+       if (ACPI_FAILURE(status)) {
+               goto error_exit;
+       }
+
+       acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
+                      sleep_state);
+       status = acpi_leave_sleep_state_prep(sleep_state);
+       if (ACPI_FAILURE(status)) {
+               goto error_exit;
+       }
+
+       acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
+                      sleep_state);
+       status = acpi_leave_sleep_state(sleep_state);
+       if (ACPI_FAILURE(status)) {
+               goto error_exit;
+       }
+
+       return;
+
+error_exit:
+       ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
+                       sleep_state));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_locks
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_locks(void)
+{
+       u32 i;
+
+       for (i = 0; i < ACPI_MAX_MUTEX; i++) {
+               acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
+                              acpi_gbl_mutex_info[i].thread_id ==
+                              ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_table_info
+ *
+ * PARAMETERS:  table_arg           - Name of table to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about loaded tables. Current
+ *              implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_table_info(char *table_arg)
+{
+       u32 i;
+       struct acpi_table_desc *table_desc;
+       acpi_status status;
+
+       /* Header */
+
+       acpi_os_printf("Idx ID  Status Type                    "
+                      "TableHeader (Sig, Address, Length, Misc)\n");
+
+       /* Walk the entire root table list */
+
+       for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
+               table_desc = &acpi_gbl_root_table_list.tables[i];
+
+               /* Index and Table ID */
+
+               acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
+
+               /* Decode the table flags */
+
+               if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
+                       acpi_os_printf("NotLoaded ");
+               } else {
+                       acpi_os_printf(" Loaded ");
+               }
+
+               switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+               case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+                       acpi_os_printf("External/virtual ");
+                       break;
+
+               case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+                       acpi_os_printf("Internal/physical ");
+                       break;
+
+               case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+
+                       acpi_os_printf("Internal/virtual ");
+                       break;
+
+               default:
+
+                       acpi_os_printf("INVALID TYPE    ");
+                       break;
+               }
+
+               /* Make sure that the table is mapped */
+
+               status = acpi_tb_validate_table(table_desc);
+               if (ACPI_FAILURE(status)) {
+                       return;
+               }
+
+               /* Dump the table header */
+
+               if (table_desc->pointer) {
+                       acpi_tb_print_table_header(table_desc->address,
+                                                  table_desc->pointer);
+               } else {
+                       /* If the pointer is null, the table has been unloaded */
+
+                       ACPI_INFO((AE_INFO, "%4.4s - Table has been unloaded",
+                                  table_desc->signature.ascii));
+               }
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_unload_acpi_table
+ *
+ * PARAMETERS:  object_name         - Namespace pathname for an object that
+ *                                    is owned by the table to be unloaded
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ *              by the table.
+ *
+ ******************************************************************************/
+
+void acpi_db_unload_acpi_table(char *object_name)
+{
+       struct acpi_namespace_node *node;
+       acpi_status status;
+
+       /* Translate name to an Named object */
+
+       node = acpi_db_convert_to_node(object_name);
+       if (!node) {
+               return;
+       }
+
+       status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
+       if (ACPI_SUCCESS(status)) {
+               acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
+                              object_name, node);
+       } else {
+               acpi_os_printf("%s, while unloading parent table of [%s]\n",
+                              acpi_format_exception(status), object_name);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_send_notify
+ *
+ * PARAMETERS:  name                - Name of ACPI object where to send notify
+ *              value               - Value of the notify to send.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
+ *              named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void acpi_db_send_notify(char *name, u32 value)
+{
+       struct acpi_namespace_node *node;
+       acpi_status status;
+
+       /* Translate name to an Named object */
+
+       node = acpi_db_convert_to_node(name);
+       if (!node) {
+               return;
+       }
+
+       /* Dispatch the notify if legal */
+
+       if (acpi_ev_is_notify_object(node)) {
+               status = acpi_ev_queue_notify_request(node, value);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not queue notify\n");
+               }
+       } else {
+               acpi_os_printf("Named object [%4.4s] Type %s, "
+                              "must be Device/Thermal/Processor type\n",
+                              acpi_ut_get_node_name(node),
+                              acpi_ut_get_type_name(node->type));
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_interfaces
+ *
+ * PARAMETERS:  action_arg          - Null, "install", or "remove"
+ *              interface_name_arg  - Name for install/remove options
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display or modify the global _OSI interface list
+ *
+ ******************************************************************************/
+
+void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
+{
+       struct acpi_interface_info *next_interface;
+       char *sub_string;
+       acpi_status status;
+
+       /* If no arguments, just display current interface list */
+
+       if (!action_arg) {
+               (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
+                                           ACPI_WAIT_FOREVER);
+
+               next_interface = acpi_gbl_supported_interfaces;
+               while (next_interface) {
+                       if (!(next_interface->flags & ACPI_OSI_INVALID)) {
+                               acpi_os_printf("%s\n", next_interface->name);
+                       }
+
+                       next_interface = next_interface->next;
+               }
+
+               acpi_os_release_mutex(acpi_gbl_osi_mutex);
+               return;
+       }
+
+       /* If action_arg exists, so must interface_name_arg */
+
+       if (!interface_name_arg) {
+               acpi_os_printf("Missing Interface Name argument\n");
+               return;
+       }
+
+       /* Uppercase the action for match below */
+
+       acpi_ut_strupr(action_arg);
+
+       /* install - install an interface */
+
+       sub_string = strstr("INSTALL", action_arg);
+       if (sub_string) {
+               status = acpi_install_interface(interface_name_arg);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("%s, while installing \"%s\"\n",
+                                      acpi_format_exception(status),
+                                      interface_name_arg);
+               }
+               return;
+       }
+
+       /* remove - remove an interface */
+
+       sub_string = strstr("REMOVE", action_arg);
+       if (sub_string) {
+               status = acpi_remove_interface(interface_name_arg);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("%s, while removing \"%s\"\n",
+                                      acpi_format_exception(status),
+                                      interface_name_arg);
+               }
+               return;
+       }
+
+       /* Invalid action_arg */
+
+       acpi_os_printf("Invalid action argument: %s\n", action_arg);
+       return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_template
+ *
+ * PARAMETERS:  buffer_arg          - Buffer name or address
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump a buffer that contains a resource template
+ *
+ ******************************************************************************/
+
+void acpi_db_display_template(char *buffer_arg)
+{
+       struct acpi_namespace_node *node;
+       acpi_status status;
+       struct acpi_buffer return_buffer;
+
+       /* Translate buffer_arg to an Named object */
+
+       node = acpi_db_convert_to_node(buffer_arg);
+       if (!node || (node == acpi_gbl_root_node)) {
+               acpi_os_printf("Invalid argument: %s\n", buffer_arg);
+               return;
+       }
+
+       /* We must have a buffer object */
+
+       if (node->type != ACPI_TYPE_BUFFER) {
+               acpi_os_printf
+                   ("Not a Buffer object, cannot be a template: %s\n",
+                    buffer_arg);
+               return;
+       }
+
+       return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+       return_buffer.pointer = acpi_gbl_db_buffer;
+
+       /* Attempt to convert the raw buffer to a resource list */
+
+       status = acpi_rs_create_resource_list(node->object, &return_buffer);
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf
+                   ("Could not convert Buffer to a resource list: %s, %s\n",
+                    buffer_arg, acpi_format_exception(status));
+               goto dump_buffer;
+       }
+
+       /* Now we can dump the resource list */
+
+       acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+                                                return_buffer.pointer));
+
+dump_buffer:
+       acpi_os_printf("\nRaw data buffer:\n");
+       acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
+                                 node->object->buffer.length,
+                                 DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+       return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_compare_aml_resources
+ *
+ * PARAMETERS:  aml1_buffer         - Contains first resource list
+ *              aml1_buffer_length  - Length of first resource list
+ *              aml2_buffer         - Contains second resource list
+ *              aml2_buffer_length  - Length of second resource list
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
+ *              order to isolate a miscompare to an individual resource)
+ *
+ ******************************************************************************/
+
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+                             acpi_rsdesc_size aml1_buffer_length,
+                             u8 *aml2_buffer,
+                             acpi_rsdesc_size aml2_buffer_length)
+{
+       u8 *aml1;
+       u8 *aml2;
+       u8 *aml1_end;
+       u8 *aml2_end;
+       acpi_rsdesc_size aml1_length;
+       acpi_rsdesc_size aml2_length;
+       acpi_rsdesc_size offset = 0;
+       u8 resource_type;
+       u32 count = 0;
+       u32 i;
+
+       /* Compare overall buffer sizes (may be different due to size rounding) */
+
+       if (aml1_buffer_length != aml2_buffer_length) {
+               acpi_os_printf("**** Buffer length mismatch in converted "
+                              "AML: Original %X, New %X ****\n",
+                              aml1_buffer_length, aml2_buffer_length);
+       }
+
+       aml1 = aml1_buffer;
+       aml2 = aml2_buffer;
+       aml1_end = aml1_buffer + aml1_buffer_length;
+       aml2_end = aml2_buffer + aml2_buffer_length;
+
+       /* Walk the descriptor lists, comparing each descriptor */
+
+       while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
+
+               /* Get the lengths of each descriptor */
+
+               aml1_length = acpi_ut_get_descriptor_length(aml1);
+               aml2_length = acpi_ut_get_descriptor_length(aml2);
+               resource_type = acpi_ut_get_resource_type(aml1);
+
+               /* Check for descriptor length match */
+
+               if (aml1_length != aml2_length) {
+                       acpi_os_printf
+                           ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
+                            "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
+                            resource_type, offset, aml1_length, aml2_length);
+               }
+
+               /* Check for descriptor byte match */
+
+               else if (memcmp(aml1, aml2, aml1_length)) {
+                       acpi_os_printf
+                           ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
+                            "Offset %8.8X ****\n", count, resource_type,
+                            offset);
+
+                       for (i = 0; i < aml1_length; i++) {
+                               if (aml1[i] != aml2[i]) {
+                                       acpi_os_printf
+                                           ("Mismatch at byte offset %.2X: is %2.2X, "
+                                            "should be %2.2X\n", i, aml2[i],
+                                            aml1[i]);
+                               }
+                       }
+               }
+
+               /* Exit on end_tag descriptor */
+
+               if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
+                       return;
+               }
+
+               /* Point to next descriptor in each buffer */
+
+               count++;
+               offset += aml1_length;
+               aml1 += aml1_length;
+               aml2 += aml2_length;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_test_resource_conversion
+ *
+ * PARAMETERS:  node                - Parent device node
+ *              name                - resource method name (_CRS)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Compare the original AML with a conversion of the AML to
+ *              internal resource list, then back to AML.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
+{
+       acpi_status status;
+       struct acpi_buffer return_buffer;
+       struct acpi_buffer resource_buffer;
+       struct acpi_buffer new_aml;
+       union acpi_object *original_aml;
+
+       acpi_os_printf("Resource Conversion Comparison:\n");
+
+       new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+       /* Get the original _CRS AML resource template */
+
+       status = acpi_evaluate_object(node, name, NULL, &return_buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not obtain %s: %s\n",
+                              name, acpi_format_exception(status));
+               return (status);
+       }
+
+       /* Get the AML resource template, converted to internal resource structs */
+
+       status = acpi_get_current_resources(node, &resource_buffer);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+                              acpi_format_exception(status));
+               goto exit1;
+       }
+
+       /* Convert internal resource list to external AML resource template */
+
+       status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
+                              acpi_format_exception(status));
+               goto exit2;
+       }
+
+       /* Compare original AML to the newly created AML resource list */
+
+       original_aml = return_buffer.pointer;
+
+       acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
+                                     (acpi_rsdesc_size) original_aml->buffer.
+                                     length, new_aml.pointer,
+                                     (acpi_rsdesc_size) new_aml.length);
+
+       /* Cleanup and exit */
+
+       ACPI_FREE(new_aml.pointer);
+exit2:
+       ACPI_FREE(resource_buffer.pointer);
+exit1:
+       ACPI_FREE(return_buffer.pointer);
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_resource_callback
+ *
+ * PARAMETERS:  acpi_walk_resource_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
+ *              acpi_walk_resource_buffer.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context)
+{
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_device_resources
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+                        u32 nesting_level, void *context, void **return_value)
+{
+       struct acpi_namespace_node *node;
+       struct acpi_namespace_node *prt_node = NULL;
+       struct acpi_namespace_node *crs_node = NULL;
+       struct acpi_namespace_node *prs_node = NULL;
+       struct acpi_namespace_node *aei_node = NULL;
+       char *parent_path;
+       struct acpi_buffer return_buffer;
+       acpi_status status;
+
+       node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+       parent_path = acpi_ns_get_external_pathname(node);
+       if (!parent_path) {
+               return (AE_NO_MEMORY);
+       }
+
+       /* Get handles to the resource methods for this device */
+
+       (void)acpi_get_handle(node, METHOD_NAME__PRT,
+                             ACPI_CAST_PTR(acpi_handle, &prt_node));
+       (void)acpi_get_handle(node, METHOD_NAME__CRS,
+                             ACPI_CAST_PTR(acpi_handle, &crs_node));
+       (void)acpi_get_handle(node, METHOD_NAME__PRS,
+                             ACPI_CAST_PTR(acpi_handle, &prs_node));
+       (void)acpi_get_handle(node, METHOD_NAME__AEI,
+                             ACPI_CAST_PTR(acpi_handle, &aei_node));
+
+       if (!prt_node && !crs_node && !prs_node && !aei_node) {
+               goto cleanup;   /* Nothing to do */
+       }
+
+       acpi_os_printf("\nDevice: %s\n", parent_path);
+
+       /* Prepare for a return object of arbitrary size */
+
+       return_buffer.pointer = acpi_gbl_db_buffer;
+       return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+       /* _PRT */
+
+       if (prt_node) {
+               acpi_os_printf("Evaluating _PRT\n");
+
+               status =
+                   acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not evaluate _PRT: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_crs;
+               }
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status = acpi_get_irq_routing_table(node, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("GetIrqRoutingTable failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_crs;
+               }
+
+               acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
+       }
+
+       /* _CRS */
+
+get_crs:
+       if (crs_node) {
+               acpi_os_printf("Evaluating _CRS\n");
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status =
+                   acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not evaluate _CRS: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_prs;
+               }
+
+               /* This code exercises the acpi_walk_resources interface */
+
+               status = acpi_walk_resources(node, METHOD_NAME__CRS,
+                                            acpi_db_resource_callback, NULL);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiWalkResources failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_prs;
+               }
+
+               /* Get the _CRS resource list (test ALLOCATE buffer) */
+
+               return_buffer.pointer = NULL;
+               return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+               status = acpi_get_current_resources(node, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_prs;
+               }
+
+               /* This code exercises the acpi_walk_resource_buffer interface */
+
+               status = acpi_walk_resource_buffer(&return_buffer,
+                                                  acpi_db_resource_callback,
+                                                  NULL);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto end_crs;
+               }
+
+               /* Dump the _CRS resource list */
+
+               acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+                                                        return_buffer.
+                                                        pointer));
+
+               /*
+                * Perform comparison of original AML to newly created AML. This
+                * tests both the AML->Resource conversion and the Resource->AML
+                * conversion.
+                */
+               (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
+
+               /* Execute _SRS with the resource list */
+
+               acpi_os_printf("Evaluating _SRS\n");
+
+               status = acpi_set_current_resources(node, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto end_crs;
+               }
+
+end_crs:
+               ACPI_FREE(return_buffer.pointer);
+       }
+
+       /* _PRS */
+
+get_prs:
+       if (prs_node) {
+               acpi_os_printf("Evaluating _PRS\n");
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status =
+                   acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not evaluate _PRS: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_aei;
+               }
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status = acpi_get_possible_resources(node, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto get_aei;
+               }
+
+               acpi_rs_dump_resource_list(ACPI_CAST_PTR
+                                          (struct acpi_resource,
+                                           acpi_gbl_db_buffer));
+       }
+
+       /* _AEI */
+
+get_aei:
+       if (aei_node) {
+               acpi_os_printf("Evaluating _AEI\n");
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status =
+                   acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not evaluate _AEI: %s\n",
+                                      acpi_format_exception(status));
+                       goto cleanup;
+               }
+
+               return_buffer.pointer = acpi_gbl_db_buffer;
+               return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+               status = acpi_get_event_resources(node, &return_buffer);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiGetEventResources failed: %s\n",
+                                      acpi_format_exception(status));
+                       goto cleanup;
+               }
+
+               acpi_rs_dump_resource_list(ACPI_CAST_PTR
+                                          (struct acpi_resource,
+                                           acpi_gbl_db_buffer));
+       }
+
+cleanup:
+       ACPI_FREE(parent_path);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_resources
+ *
+ * PARAMETERS:  object_arg          - String object name or object pointer.
+ *                                    NULL or "*" means "display resources for
+ *                                    all devices"
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the resource objects associated with a device.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_resources(char *object_arg)
+{
+       struct acpi_namespace_node *node;
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+       /* Asterisk means "display resources for all devices" */
+
+       if (!object_arg || (!strcmp(object_arg, "*"))) {
+               (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                         ACPI_UINT32_MAX,
+                                         acpi_db_device_resources, NULL, NULL,
+                                         NULL);
+       } else {
+               /* Convert string to object pointer */
+
+               node = acpi_db_convert_to_node(object_arg);
+               if (node) {
+                       if (node->type != ACPI_TYPE_DEVICE) {
+                               acpi_os_printf
+                                   ("%4.4s: Name is not a device object (%s)\n",
+                                    node->name.ascii,
+                                    acpi_ut_get_type_name(node->type));
+                       } else {
+                               (void)acpi_db_device_resources(node, 0, NULL,
+                                                              NULL);
+                       }
+               }
+       }
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_gpe
+ *
+ * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
+ *              block_arg           - GPE block number, ascii string
+ *                                    0 or 1 for FADT GPE blocks
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate firing of a GPE
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
+{
+       u32 block_number = 0;
+       u32 gpe_number;
+       struct acpi_gpe_event_info *gpe_event_info;
+
+       gpe_number = strtoul(gpe_arg, NULL, 0);
+
+       /*
+        * If no block arg, or block arg == 0 or 1, use the FADT-defined
+        * GPE blocks.
+        */
+       if (block_arg) {
+               block_number = strtoul(block_arg, NULL, 0);
+               if (block_number == 1) {
+                       block_number = 0;
+               }
+       }
+
+       gpe_event_info =
+           acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
+                                      gpe_number);
+       if (!gpe_event_info) {
+               acpi_os_printf("Invalid GPE\n");
+               return;
+       }
+
+       (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_sci
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_sci(void)
+{
+       acpi_ev_sci_dispatch();
+}
+
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_trace
+ *
+ * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
+ *                                    DISABLE to disable tracer
+ *              method_arg          - Method to trace
+ *              once_arg            - Whether trace once
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Control method tracing facility
+ *
+ ******************************************************************************/
+
+void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
+{
+       u32 debug_level = 0;
+       u32 debug_layer = 0;
+       u32 flags = 0;
+
+       if (enable_arg) {
+               acpi_ut_strupr(enable_arg);
+       }
+
+       if (once_arg) {
+               acpi_ut_strupr(once_arg);
+       }
+
+       if (method_arg) {
+               if (acpi_db_trace_method_name) {
+                       ACPI_FREE(acpi_db_trace_method_name);
+                       acpi_db_trace_method_name = NULL;
+               }
+
+               acpi_db_trace_method_name =
+                   ACPI_ALLOCATE(strlen(method_arg) + 1);
+               if (!acpi_db_trace_method_name) {
+                       acpi_os_printf("Failed to allocate method name (%s)\n",
+                                      method_arg);
+                       return;
+               }
+
+               strcpy(acpi_db_trace_method_name, method_arg);
+       }
+
+       if (!strcmp(enable_arg, "ENABLE") ||
+           !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
+               if (!strcmp(enable_arg, "ENABLE")) {
+
+                       /* Inherit current console settings */
+
+                       debug_level = acpi_gbl_db_console_debug_level;
+                       debug_layer = acpi_dbg_layer;
+               } else {
+                       /* Restrict console output to trace points only */
+
+                       debug_level = ACPI_LV_TRACE_POINT;
+                       debug_layer = ACPI_EXECUTER;
+               }
+
+               flags = ACPI_TRACE_ENABLED;
+
+               if (!strcmp(enable_arg, "OPCODE")) {
+                       flags |= ACPI_TRACE_OPCODE;
+               }
+
+               if (once_arg && !strcmp(once_arg, "ONCE")) {
+                       flags |= ACPI_TRACE_ONESHOT;
+               }
+       }
+
+       (void)acpi_debug_trace(acpi_db_trace_method_name,
+                              debug_level, debug_layer, flags);
+}
diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c
new file mode 100644 (file)
index 0000000..a71632c
--- /dev/null
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ *
+ * Module Name: dbconvert - debugger miscellaneous conversion routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbconvert")
+
+#define DB_DEFAULT_PKG_ELEMENTS     33
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_hex_char_to_value
+ *
+ * PARAMETERS:  hex_char            - Ascii Hex digit, 0-9|a-f|A-F
+ *              return_value        - Where the converted value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
+ *
+ ******************************************************************************/
+acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value)
+{
+       u8 value;
+
+       /* Digit must be ascii [0-9a-fA-F] */
+
+       if (!isxdigit(hex_char)) {
+               return (AE_BAD_HEX_CONSTANT);
+       }
+
+       if (hex_char <= 0x39) {
+               value = (u8)(hex_char - 0x30);
+       } else {
+               value = (u8)(toupper(hex_char) - 0x37);
+       }
+
+       *return_value = value;
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_hex_byte_to_binary
+ *
+ * PARAMETERS:  hex_byte            - Double hex digit (0x00 - 0xFF) in format:
+ *                                    hi_byte then lo_byte.
+ *              return_value        - Where the converted value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_db_hex_byte_to_binary(char *hex_byte, u8 *return_value)
+{
+       u8 local0;
+       u8 local1;
+       acpi_status status;
+
+       /* High byte */
+
+       status = acpi_db_hex_char_to_value(hex_byte[0], &local0);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       /* Low byte */
+
+       status = acpi_db_hex_char_to_value(hex_byte[1], &local1);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       *return_value = (u8)((local0 << 4) | local1);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_buffer
+ *
+ * PARAMETERS:  string              - Input string to be converted
+ *              object              - Where the buffer object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a string to a buffer object. String is treated a list
+ *              of buffer elements, each separated by a space or comma.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_convert_to_buffer(char *string, union acpi_object *object)
+{
+       u32 i;
+       u32 j;
+       u32 length;
+       u8 *buffer;
+       acpi_status status;
+
+       /* Generate the final buffer length */
+
+       for (i = 0, length = 0; string[i];) {
+               i += 2;
+               length++;
+
+               while (string[i] && ((string[i] == ',') || (string[i] == ' '))) {
+                       i++;
+               }
+       }
+
+       buffer = ACPI_ALLOCATE(length);
+       if (!buffer) {
+               return (AE_NO_MEMORY);
+       }
+
+       /* Convert the command line bytes to the buffer */
+
+       for (i = 0, j = 0; string[i];) {
+               status = acpi_db_hex_byte_to_binary(&string[i], &buffer[j]);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_FREE(buffer);
+                       return (status);
+               }
+
+               j++;
+               i += 2;
+               while (string[i] && ((string[i] == ',') || (string[i] == ' '))) {
+                       i++;
+               }
+       }
+
+       object->type = ACPI_TYPE_BUFFER;
+       object->buffer.pointer = buffer;
+       object->buffer.length = length;
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_package
+ *
+ * PARAMETERS:  string              - Input string to be converted
+ *              object              - Where the package object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a string to a package object. Handles nested packages
+ *              via recursion with acpi_db_convert_to_object.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_convert_to_package(char *string, union acpi_object * object)
+{
+       char *this;
+       char *next;
+       u32 i;
+       acpi_object_type type;
+       union acpi_object *elements;
+       acpi_status status;
+
+       elements =
+           ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
+                                sizeof(union acpi_object));
+
+       this = string;
+       for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
+               this = acpi_db_get_next_token(this, &next, &type);
+               if (!this) {
+                       break;
+               }
+
+               /* Recursive call to convert each package element */
+
+               status = acpi_db_convert_to_object(type, this, &elements[i]);
+               if (ACPI_FAILURE(status)) {
+                       acpi_db_delete_objects(i + 1, elements);
+                       ACPI_FREE(elements);
+                       return (status);
+               }
+
+               this = next;
+       }
+
+       object->type = ACPI_TYPE_PACKAGE;
+       object->package.count = i;
+       object->package.elements = elements;
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_object
+ *
+ * PARAMETERS:  type                - Object type as determined by parser
+ *              string              - Input string to be converted
+ *              object              - Where the new object is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Convert a typed and tokenized string to an union acpi_object. Typing:
+ *              1) String objects were surrounded by quotes.
+ *              2) Buffer objects were surrounded by parentheses.
+ *              3) Package objects were surrounded by brackets "[]".
+ *              4) All standalone tokens are treated as integers.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_convert_to_object(acpi_object_type type,
+                         char *string, union acpi_object * object)
+{
+       acpi_status status = AE_OK;
+
+       switch (type) {
+       case ACPI_TYPE_STRING:
+
+               object->type = ACPI_TYPE_STRING;
+               object->string.pointer = string;
+               object->string.length = (u32)strlen(string);
+               break;
+
+       case ACPI_TYPE_BUFFER:
+
+               status = acpi_db_convert_to_buffer(string, object);
+               break;
+
+       case ACPI_TYPE_PACKAGE:
+
+               status = acpi_db_convert_to_package(string, object);
+               break;
+
+       default:
+
+               object->type = ACPI_TYPE_INTEGER;
+               status = acpi_ut_strtoul64(string, 16, &object->integer.value);
+               break;
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_encode_pld_buffer
+ *
+ * PARAMETERS:  pld_info            - _PLD buffer struct (Using local struct)
+ *
+ * RETURN:      Encode _PLD buffer suitable for return value from _PLD
+ *
+ * DESCRIPTION: Bit-packs a _PLD buffer struct. Used to test the _PLD macros
+ *
+ ******************************************************************************/
+
+u8 *acpi_db_encode_pld_buffer(struct acpi_pld_info *pld_info)
+{
+       u32 *buffer;
+       u32 dword;
+
+       buffer = ACPI_ALLOCATE_ZEROED(ACPI_PLD_BUFFER_SIZE);
+       if (!buffer) {
+               return (NULL);
+       }
+
+       /* First 32 bits */
+
+       dword = 0;
+       ACPI_PLD_SET_REVISION(&dword, pld_info->revision);
+       ACPI_PLD_SET_IGNORE_COLOR(&dword, pld_info->ignore_color);
+       ACPI_PLD_SET_RED(&dword, pld_info->red);
+       ACPI_PLD_SET_GREEN(&dword, pld_info->green);
+       ACPI_PLD_SET_BLUE(&dword, pld_info->blue);
+       ACPI_MOVE_32_TO_32(&buffer[0], &dword);
+
+       /* Second 32 bits */
+
+       dword = 0;
+       ACPI_PLD_SET_WIDTH(&dword, pld_info->width);
+       ACPI_PLD_SET_HEIGHT(&dword, pld_info->height);
+       ACPI_MOVE_32_TO_32(&buffer[1], &dword);
+
+       /* Third 32 bits */
+
+       dword = 0;
+       ACPI_PLD_SET_USER_VISIBLE(&dword, pld_info->user_visible);
+       ACPI_PLD_SET_DOCK(&dword, pld_info->dock);
+       ACPI_PLD_SET_LID(&dword, pld_info->lid);
+       ACPI_PLD_SET_PANEL(&dword, pld_info->panel);
+       ACPI_PLD_SET_VERTICAL(&dword, pld_info->vertical_position);
+       ACPI_PLD_SET_HORIZONTAL(&dword, pld_info->horizontal_position);
+       ACPI_PLD_SET_SHAPE(&dword, pld_info->shape);
+       ACPI_PLD_SET_ORIENTATION(&dword, pld_info->group_orientation);
+       ACPI_PLD_SET_TOKEN(&dword, pld_info->group_token);
+       ACPI_PLD_SET_POSITION(&dword, pld_info->group_position);
+       ACPI_PLD_SET_BAY(&dword, pld_info->bay);
+       ACPI_MOVE_32_TO_32(&buffer[2], &dword);
+
+       /* Fourth 32 bits */
+
+       dword = 0;
+       ACPI_PLD_SET_EJECTABLE(&dword, pld_info->ejectable);
+       ACPI_PLD_SET_OSPM_EJECT(&dword, pld_info->ospm_eject_required);
+       ACPI_PLD_SET_CABINET(&dword, pld_info->cabinet_number);
+       ACPI_PLD_SET_CARD_CAGE(&dword, pld_info->card_cage_number);
+       ACPI_PLD_SET_REFERENCE(&dword, pld_info->reference);
+       ACPI_PLD_SET_ROTATION(&dword, pld_info->rotation);
+       ACPI_PLD_SET_ORDER(&dword, pld_info->order);
+       ACPI_MOVE_32_TO_32(&buffer[3], &dword);
+
+       if (pld_info->revision >= 2) {
+
+               /* Fifth 32 bits */
+
+               dword = 0;
+               ACPI_PLD_SET_VERT_OFFSET(&dword, pld_info->vertical_offset);
+               ACPI_PLD_SET_HORIZ_OFFSET(&dword, pld_info->horizontal_offset);
+               ACPI_MOVE_32_TO_32(&buffer[4], &dword);
+       }
+
+       return (ACPI_CAST_PTR(u8, buffer));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_pld_buffer
+ *
+ * PARAMETERS:  obj_desc            - Object returned from _PLD method
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Dumps formatted contents of a _PLD return buffer.
+ *
+ ******************************************************************************/
+
+#define ACPI_PLD_OUTPUT     "%20s : %-6X\n"
+
+void acpi_db_dump_pld_buffer(union acpi_object *obj_desc)
+{
+       union acpi_object *buffer_desc;
+       struct acpi_pld_info *pld_info;
+       u8 *new_buffer;
+       acpi_status status;
+
+       /* Object must be of type Package with at least one Buffer element */
+
+       if (obj_desc->type != ACPI_TYPE_PACKAGE) {
+               return;
+       }
+
+       buffer_desc = &obj_desc->package.elements[0];
+       if (buffer_desc->type != ACPI_TYPE_BUFFER) {
+               return;
+       }
+
+       /* Convert _PLD buffer to local _PLD struct */
+
+       status = acpi_decode_pld_buffer(buffer_desc->buffer.pointer,
+                                       buffer_desc->buffer.length, &pld_info);
+       if (ACPI_FAILURE(status)) {
+               return;
+       }
+
+       /* Encode local _PLD struct back to a _PLD buffer */
+
+       new_buffer = acpi_db_encode_pld_buffer(pld_info);
+       if (!new_buffer) {
+               return;
+       }
+
+       /* The two bit-packed buffers should match */
+
+       if (memcmp(new_buffer, buffer_desc->buffer.pointer,
+                  buffer_desc->buffer.length)) {
+               acpi_os_printf
+                   ("Converted _PLD buffer does not compare. New:\n");
+
+               acpi_ut_dump_buffer(new_buffer,
+                                   buffer_desc->buffer.length, DB_BYTE_DISPLAY,
+                                   0);
+       }
+
+       /* First 32-bit dword */
+
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Revision", pld_info->revision);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_IgnoreColor",
+                      pld_info->ignore_color);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Red", pld_info->red);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Green", pld_info->green);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Blue", pld_info->blue);
+
+       /* Second 32-bit dword */
+
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Width", pld_info->width);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Height", pld_info->height);
+
+       /* Third 32-bit dword */
+
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_UserVisible",
+                      pld_info->user_visible);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Dock", pld_info->dock);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Lid", pld_info->lid);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Panel", pld_info->panel);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalPosition",
+                      pld_info->vertical_position);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalPosition",
+                      pld_info->horizontal_position);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Shape", pld_info->shape);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupOrientation",
+                      pld_info->group_orientation);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupToken",
+                      pld_info->group_token);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_GroupPosition",
+                      pld_info->group_position);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Bay", pld_info->bay);
+
+       /* Fourth 32-bit dword */
+
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Ejectable", pld_info->ejectable);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_EjectRequired",
+                      pld_info->ospm_eject_required);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CabinetNumber",
+                      pld_info->cabinet_number);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_CardCageNumber",
+                      pld_info->card_cage_number);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Reference", pld_info->reference);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Rotation", pld_info->rotation);
+       acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_Order", pld_info->order);
+
+       /* Fifth 32-bit dword */
+
+       if (buffer_desc->buffer.length > 16) {
+               acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_VerticalOffset",
+                              pld_info->vertical_offset);
+               acpi_os_printf(ACPI_PLD_OUTPUT, "PLD_HorizontalOffset",
+                              pld_info->horizontal_offset);
+       }
+
+       ACPI_FREE(pld_info);
+       ACPI_FREE(new_buffer);
+}
diff --git a/drivers/acpi/acpica/dbdisply.c b/drivers/acpi/acpica/dbdisply.c
new file mode 100644 (file)
index 0000000..672977e
--- /dev/null
@@ -0,0 +1,1108 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisply - debug display commands
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbdisply")
+
+/* Local prototypes */
+static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op);
+
+static void *acpi_db_get_pointer(void *target);
+
+static acpi_status
+acpi_db_display_non_root_handlers(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value);
+
+/*
+ * System handler information.
+ * Used for Handlers command, in acpi_db_display_handlers.
+ */
+#define ACPI_PREDEFINED_PREFIX          "%25s (%.2X) : "
+#define ACPI_HANDLER_NAME_STRING               "%30s : "
+#define ACPI_HANDLER_PRESENT_STRING                    "%-9s (%p)\n"
+#define ACPI_HANDLER_PRESENT_STRING2                   "%-9s (%p)"
+#define ACPI_HANDLER_NOT_PRESENT_STRING                "%-9s\n"
+
+/* All predefined Address Space IDs */
+
+static acpi_adr_space_type acpi_gbl_space_id_list[] = {
+       ACPI_ADR_SPACE_SYSTEM_MEMORY,
+       ACPI_ADR_SPACE_SYSTEM_IO,
+       ACPI_ADR_SPACE_PCI_CONFIG,
+       ACPI_ADR_SPACE_EC,
+       ACPI_ADR_SPACE_SMBUS,
+       ACPI_ADR_SPACE_CMOS,
+       ACPI_ADR_SPACE_PCI_BAR_TARGET,
+       ACPI_ADR_SPACE_IPMI,
+       ACPI_ADR_SPACE_GPIO,
+       ACPI_ADR_SPACE_GSBUS,
+       ACPI_ADR_SPACE_DATA_TABLE,
+       ACPI_ADR_SPACE_FIXED_HARDWARE
+};
+
+/* Global handler information */
+
+typedef struct acpi_handler_info {
+       void *handler;
+       char *name;
+
+} acpi_handler_info;
+
+static struct acpi_handler_info acpi_gbl_handler_list[] = {
+       {&acpi_gbl_global_notify[0].handler, "System Notifications"},
+       {&acpi_gbl_global_notify[1].handler, "Device Notifications"},
+       {&acpi_gbl_table_handler, "ACPI Table Events"},
+       {&acpi_gbl_exception_handler, "Control Method Exceptions"},
+       {&acpi_gbl_interface_handler, "OSI Invocations"}
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_pointer
+ *
+ * PARAMETERS:  target          - Pointer to string to be converted
+ *
+ * RETURN:      Converted pointer
+ *
+ * DESCRIPTION: Convert an ascii pointer value to a real value
+ *
+ ******************************************************************************/
+
+static void *acpi_db_get_pointer(void *target)
+{
+       void *obj_ptr;
+       acpi_size address;
+
+       address = strtoul(target, NULL, 16);
+       obj_ptr = ACPI_TO_POINTER(address);
+       return (obj_ptr);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_parser_descriptor
+ *
+ * PARAMETERS:  op              - A parser Op descriptor
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted parser object
+ *
+ ******************************************************************************/
+
+static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op)
+{
+       const struct acpi_opcode_info *info;
+
+       info = acpi_ps_get_opcode_info(op->common.aml_opcode);
+
+       acpi_os_printf("Parser Op Descriptor:\n");
+       acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode);
+
+       ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name",
+                                              info->name));
+
+       acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg);
+       acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent);
+       acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_and_display_object
+ *
+ * PARAMETERS:  target          - String with object to be displayed. Names
+ *                                and hex pointers are supported.
+ *              output_type     - Byte, Word, Dword, or Qword (B|W|D|Q)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display a formatted ACPI object
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_and_display_object(char *target, char *output_type)
+{
+       void *obj_ptr;
+       struct acpi_namespace_node *node;
+       union acpi_operand_object *obj_desc;
+       u32 display = DB_BYTE_DISPLAY;
+       char buffer[80];
+       struct acpi_buffer ret_buf;
+       acpi_status status;
+       u32 size;
+
+       if (!target) {
+               return;
+       }
+
+       /* Decode the output type */
+
+       if (output_type) {
+               acpi_ut_strupr(output_type);
+               if (output_type[0] == 'W') {
+                       display = DB_WORD_DISPLAY;
+               } else if (output_type[0] == 'D') {
+                       display = DB_DWORD_DISPLAY;
+               } else if (output_type[0] == 'Q') {
+                       display = DB_QWORD_DISPLAY;
+               }
+       }
+
+       ret_buf.length = sizeof(buffer);
+       ret_buf.pointer = buffer;
+
+       /* Differentiate between a number and a name */
+
+       if ((target[0] >= 0x30) && (target[0] <= 0x39)) {
+               obj_ptr = acpi_db_get_pointer(target);
+               if (!acpi_os_readable(obj_ptr, 16)) {
+                       acpi_os_printf
+                           ("Address %p is invalid in this address space\n",
+                            obj_ptr);
+                       return;
+               }
+
+               /* Decode the object type */
+
+               switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) {
+               case ACPI_DESC_TYPE_NAMED:
+
+                       /* This is a namespace Node */
+
+                       if (!acpi_os_readable
+                           (obj_ptr, sizeof(struct acpi_namespace_node))) {
+                               acpi_os_printf
+                                   ("Cannot read entire Named object at address %p\n",
+                                    obj_ptr);
+                               return;
+                       }
+
+                       node = obj_ptr;
+                       goto dump_node;
+
+               case ACPI_DESC_TYPE_OPERAND:
+
+                       /* This is a ACPI OPERAND OBJECT */
+
+                       if (!acpi_os_readable
+                           (obj_ptr, sizeof(union acpi_operand_object))) {
+                               acpi_os_printf
+                                   ("Cannot read entire ACPI object at address %p\n",
+                                    obj_ptr);
+                               return;
+                       }
+
+                       acpi_ut_debug_dump_buffer(obj_ptr,
+                                                 sizeof(union
+                                                        acpi_operand_object),
+                                                 display, ACPI_UINT32_MAX);
+                       acpi_ex_dump_object_descriptor(obj_ptr, 1);
+                       break;
+
+               case ACPI_DESC_TYPE_PARSER:
+
+                       /* This is a Parser Op object */
+
+                       if (!acpi_os_readable
+                           (obj_ptr, sizeof(union acpi_parse_object))) {
+                               acpi_os_printf
+                                   ("Cannot read entire Parser object at address %p\n",
+                                    obj_ptr);
+                               return;
+                       }
+
+                       acpi_ut_debug_dump_buffer(obj_ptr,
+                                                 sizeof(union
+                                                        acpi_parse_object),
+                                                 display, ACPI_UINT32_MAX);
+                       acpi_db_dump_parser_descriptor((union acpi_parse_object
+                                                       *)obj_ptr);
+                       break;
+
+               default:
+
+                       /* Is not a recognizeable object */
+
+                       acpi_os_printf
+                           ("Not a known ACPI internal object, descriptor type %2.2X\n",
+                            ACPI_GET_DESCRIPTOR_TYPE(obj_ptr));
+
+                       size = 16;
+                       if (acpi_os_readable(obj_ptr, 64)) {
+                               size = 64;
+                       }
+
+                       /* Just dump some memory */
+
+                       acpi_ut_debug_dump_buffer(obj_ptr, size, display,
+                                                 ACPI_UINT32_MAX);
+                       break;
+               }
+
+               return;
+       }
+
+       /* The parameter is a name string that must be resolved to a Named obj */
+
+       node = acpi_db_local_ns_lookup(target);
+       if (!node) {
+               return;
+       }
+
+dump_node:
+       /* Now dump the NS node */
+
+       status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not convert name to pathname\n");
+       }
+
+       else {
+               acpi_os_printf("Object (%p) Pathname: %s\n",
+                              node, (char *)ret_buf.pointer);
+       }
+
+       if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
+               acpi_os_printf("Invalid Named object at address %p\n", node);
+               return;
+       }
+
+       acpi_ut_debug_dump_buffer((void *)node,
+                                 sizeof(struct acpi_namespace_node), display,
+                                 ACPI_UINT32_MAX);
+       acpi_ex_dump_namespace_node(node, 1);
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (obj_desc) {
+               acpi_os_printf("\nAttached Object (%p):\n", obj_desc);
+               if (!acpi_os_readable
+                   (obj_desc, sizeof(union acpi_operand_object))) {
+                       acpi_os_printf
+                           ("Invalid internal ACPI Object at address %p\n",
+                            obj_desc);
+                       return;
+               }
+
+               acpi_ut_debug_dump_buffer((void *)obj_desc,
+                                         sizeof(union acpi_operand_object),
+                                         display, ACPI_UINT32_MAX);
+               acpi_ex_dump_object_descriptor(obj_desc, 1);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_method_info
+ *
+ * PARAMETERS:  start_op        - Root of the control method parse tree
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about the current method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_method_info(union acpi_parse_object *start_op)
+{
+       struct acpi_walk_state *walk_state;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node;
+       union acpi_parse_object *root_op;
+       union acpi_parse_object *op;
+       const struct acpi_opcode_info *op_info;
+       u32 num_ops = 0;
+       u32 num_operands = 0;
+       u32 num_operators = 0;
+       u32 num_remaining_ops = 0;
+       u32 num_remaining_operands = 0;
+       u32 num_remaining_operators = 0;
+       u8 count_remaining = FALSE;
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       obj_desc = walk_state->method_desc;
+       node = walk_state->method_node;
+
+       acpi_os_printf("Currently executing control method is [%4.4s]\n",
+                      acpi_ut_get_node_name(node));
+       acpi_os_printf("%X Arguments, SyncLevel = %X\n",
+                      (u32)obj_desc->method.param_count,
+                      (u32)obj_desc->method.sync_level);
+
+       root_op = start_op;
+       while (root_op->common.parent) {
+               root_op = root_op->common.parent;
+       }
+
+       op = root_op;
+
+       while (op) {
+               if (op == start_op) {
+                       count_remaining = TRUE;
+               }
+
+               num_ops++;
+               if (count_remaining) {
+                       num_remaining_ops++;
+               }
+
+               /* Decode the opcode */
+
+               op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
+               switch (op_info->class) {
+               case AML_CLASS_ARGUMENT:
+
+                       if (count_remaining) {
+                               num_remaining_operands++;
+                       }
+
+                       num_operands++;
+                       break;
+
+               case AML_CLASS_UNKNOWN:
+
+                       /* Bad opcode or ASCII character */
+
+                       continue;
+
+               default:
+
+                       if (count_remaining) {
+                               num_remaining_operators++;
+                       }
+
+                       num_operators++;
+                       break;
+               }
+
+               op = acpi_ps_get_depth_next(start_op, op);
+       }
+
+       acpi_os_printf
+           ("Method contains:       %X AML Opcodes - %X Operators, %X Operands\n",
+            num_ops, num_operators, num_operands);
+
+       acpi_os_printf
+           ("Remaining to execute:  %X AML Opcodes - %X Operators, %X Operands\n",
+            num_remaining_ops, num_remaining_operators,
+            num_remaining_operands);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_locals
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_locals(void)
+{
+       struct acpi_walk_state *walk_state;
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       acpi_db_decode_locals(walk_state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_arguments
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_display_arguments(void)
+{
+       struct acpi_walk_state *walk_state;
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       acpi_db_decode_arguments(walk_state);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_results
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current contents of a method result stack
+ *
+ ******************************************************************************/
+
+void acpi_db_display_results(void)
+{
+       u32 i;
+       struct acpi_walk_state *walk_state;
+       union acpi_operand_object *obj_desc;
+       u32 result_count = 0;
+       struct acpi_namespace_node *node;
+       union acpi_generic_state *frame;
+       u32 index;              /* Index onto current frame */
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       obj_desc = walk_state->method_desc;
+       node = walk_state->method_node;
+
+       if (walk_state->results) {
+               result_count = walk_state->result_count;
+       }
+
+       acpi_os_printf("Method [%4.4s] has %X stacked result objects\n",
+                      acpi_ut_get_node_name(node), result_count);
+
+       /* From the top element of result stack */
+
+       frame = walk_state->results;
+       index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
+
+       for (i = 0; i < result_count; i++) {
+               obj_desc = frame->results.obj_desc[index];
+               acpi_os_printf("Result%u: ", i);
+               acpi_db_display_internal_object(obj_desc, walk_state);
+
+               if (index == 0) {
+                       frame = frame->results.next;
+                       index = ACPI_RESULTS_FRAME_OBJ_NUM;
+               }
+
+               index--;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_calling_tree
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display current calling tree of nested control methods
+ *
+ ******************************************************************************/
+
+void acpi_db_display_calling_tree(void)
+{
+       struct acpi_walk_state *walk_state;
+       struct acpi_namespace_node *node;
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       node = walk_state->method_node;
+       acpi_os_printf("Current Control Method Call Tree\n");
+
+       while (walk_state) {
+               node = walk_state->method_node;
+               acpi_os_printf("  [%4.4s]\n", acpi_ut_get_node_name(node));
+
+               walk_state = walk_state->next;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_object_type
+ *
+ * PARAMETERS:  name            - User entered NS node handle or name
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display type of an arbitrary NS node
+ *
+ ******************************************************************************/
+
+void acpi_db_display_object_type(char *name)
+{
+       struct acpi_namespace_node *node;
+       struct acpi_device_info *info;
+       acpi_status status;
+       u32 i;
+
+       node = acpi_db_convert_to_node(name);
+       if (!node) {
+               return;
+       }
+
+       status = acpi_get_object_info(ACPI_CAST_PTR(acpi_handle, node), &info);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not get object info, %s\n",
+                              acpi_format_exception(status));
+               return;
+       }
+
+       if (info->valid & ACPI_VALID_ADR) {
+               acpi_os_printf("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n",
+                              ACPI_FORMAT_UINT64(info->address),
+                              info->current_status, info->flags);
+       }
+       if (info->valid & ACPI_VALID_SXDS) {
+               acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
+                              info->highest_dstates[0],
+                              info->highest_dstates[1],
+                              info->highest_dstates[2],
+                              info->highest_dstates[3]);
+       }
+       if (info->valid & ACPI_VALID_SXWS) {
+               acpi_os_printf
+                   ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
+                    info->lowest_dstates[0], info->lowest_dstates[1],
+                    info->lowest_dstates[2], info->lowest_dstates[3],
+                    info->lowest_dstates[4]);
+       }
+
+       if (info->valid & ACPI_VALID_HID) {
+               acpi_os_printf("HID: %s\n", info->hardware_id.string);
+       }
+
+       if (info->valid & ACPI_VALID_UID) {
+               acpi_os_printf("UID: %s\n", info->unique_id.string);
+       }
+
+       if (info->valid & ACPI_VALID_SUB) {
+               acpi_os_printf("SUB: %s\n", info->subsystem_id.string);
+       }
+
+       if (info->valid & ACPI_VALID_CID) {
+               for (i = 0; i < info->compatible_id_list.count; i++) {
+                       acpi_os_printf("CID %u: %s\n", i,
+                                      info->compatible_id_list.ids[i].string);
+               }
+       }
+
+       ACPI_FREE(info);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_result_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ * Note: Curently only displays the result object if we are single stepping.
+ * However, this output may be useful in other contexts and could be enabled
+ * to do so if needed.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_result_object(union acpi_operand_object *obj_desc,
+                             struct acpi_walk_state *walk_state)
+{
+
+       /* Only display if single stepping */
+
+       if (!acpi_gbl_cm_single_step) {
+               return;
+       }
+
+       acpi_os_printf("ResultObj: ");
+       acpi_db_display_internal_object(obj_desc, walk_state);
+       acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_argument_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
+                               struct acpi_walk_state *walk_state)
+{
+
+       if (!acpi_gbl_cm_single_step) {
+               return;
+       }
+
+       acpi_os_printf("ArgObj:  ");
+       acpi_db_display_internal_object(obj_desc, walk_state);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_gpes
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the current GPE structures
+ *
+ ******************************************************************************/
+
+void acpi_db_display_gpes(void)
+{
+       struct acpi_gpe_block_info *gpe_block;
+       struct acpi_gpe_xrupt_info *gpe_xrupt_info;
+       struct acpi_gpe_event_info *gpe_event_info;
+       struct acpi_gpe_register_info *gpe_register_info;
+       char *gpe_type;
+       struct acpi_gpe_notify_info *notify;
+       u32 gpe_index;
+       u32 block = 0;
+       u32 i;
+       u32 j;
+       u32 count;
+       char buffer[80];
+       struct acpi_buffer ret_buf;
+       acpi_status status;
+
+       ret_buf.length = sizeof(buffer);
+       ret_buf.pointer = buffer;
+
+       block = 0;
+
+       /* Walk the GPE lists */
+
+       gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
+       while (gpe_xrupt_info) {
+               gpe_block = gpe_xrupt_info->gpe_block_list_head;
+               while (gpe_block) {
+                       status = acpi_get_name(gpe_block->node,
+                                              ACPI_FULL_PATHNAME_NO_TRAILING,
+                                              &ret_buf);
+                       if (ACPI_FAILURE(status)) {
+                               acpi_os_printf
+                                   ("Could not convert name to pathname\n");
+                       }
+
+                       if (gpe_block->node == acpi_gbl_fadt_gpe_device) {
+                               gpe_type = "FADT-defined GPE block";
+                       } else {
+                               gpe_type = "GPE Block Device";
+                       }
+
+                       acpi_os_printf
+                           ("\nBlock %u - Info %p  DeviceNode %p [%s] - %s\n",
+                            block, gpe_block, gpe_block->node, buffer,
+                            gpe_type);
+
+                       acpi_os_printf("    Registers:    %u (%u GPEs)\n",
+                                      gpe_block->register_count,
+                                      gpe_block->gpe_count);
+
+                       acpi_os_printf
+                           ("    GPE range:    0x%X to 0x%X on interrupt %u\n",
+                            gpe_block->block_base_number,
+                            gpe_block->block_base_number +
+                            (gpe_block->gpe_count - 1),
+                            gpe_xrupt_info->interrupt_number);
+
+                       acpi_os_printf
+                           ("    RegisterInfo: %p  Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+                            gpe_block->register_info,
+                            ACPI_FORMAT_UINT64(gpe_block->register_info->
+                                               status_address.address),
+                            ACPI_FORMAT_UINT64(gpe_block->register_info->
+                                               enable_address.address));
+
+                       acpi_os_printf("  EventInfo:    %p\n",
+                                      gpe_block->event_info);
+
+                       /* Examine each GPE Register within the block */
+
+                       for (i = 0; i < gpe_block->register_count; i++) {
+                               gpe_register_info =
+                                   &gpe_block->register_info[i];
+
+                               acpi_os_printf("    Reg %u: (GPE %.2X-%.2X)  "
+                                              "RunEnable %2.2X WakeEnable %2.2X"
+                                              " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+                                              i,
+                                              gpe_register_info->
+                                              base_gpe_number,
+                                              gpe_register_info->
+                                              base_gpe_number +
+                                              (ACPI_GPE_REGISTER_WIDTH - 1),
+                                              gpe_register_info->
+                                              enable_for_run,
+                                              gpe_register_info->
+                                              enable_for_wake,
+                                              ACPI_FORMAT_UINT64
+                                              (gpe_register_info->
+                                               status_address.address),
+                                              ACPI_FORMAT_UINT64
+                                              (gpe_register_info->
+                                               enable_address.address));
+
+                               /* Now look at the individual GPEs in this byte register */
+
+                               for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+                                       gpe_index =
+                                           (i * ACPI_GPE_REGISTER_WIDTH) + j;
+                                       gpe_event_info =
+                                           &gpe_block->event_info[gpe_index];
+
+                                       if (ACPI_GPE_DISPATCH_TYPE
+                                           (gpe_event_info->flags) ==
+                                           ACPI_GPE_DISPATCH_NONE) {
+
+                                               /* This GPE is not used (no method or handler), ignore it */
+
+                                               continue;
+                                       }
+
+                                       acpi_os_printf
+                                           ("        GPE %.2X: %p  RunRefs %2.2X Flags %2.2X (",
+                                            gpe_block->block_base_number +
+                                            gpe_index, gpe_event_info,
+                                            gpe_event_info->runtime_count,
+                                            gpe_event_info->flags);
+
+                                       /* Decode the flags byte */
+
+                                       if (gpe_event_info->
+                                           flags & ACPI_GPE_LEVEL_TRIGGERED) {
+                                               acpi_os_printf("Level, ");
+                                       } else {
+                                               acpi_os_printf("Edge, ");
+                                       }
+
+                                       if (gpe_event_info->
+                                           flags & ACPI_GPE_CAN_WAKE) {
+                                               acpi_os_printf("CanWake, ");
+                                       } else {
+                                               acpi_os_printf("RunOnly, ");
+                                       }
+
+                                       switch (ACPI_GPE_DISPATCH_TYPE
+                                               (gpe_event_info->flags)) {
+                                       case ACPI_GPE_DISPATCH_NONE:
+
+                                               acpi_os_printf("NotUsed");
+                                               break;
+
+                                       case ACPI_GPE_DISPATCH_METHOD:
+
+                                               acpi_os_printf("Method");
+                                               break;
+
+                                       case ACPI_GPE_DISPATCH_HANDLER:
+
+                                               acpi_os_printf("Handler");
+                                               break;
+
+                                       case ACPI_GPE_DISPATCH_NOTIFY:
+
+                                               count = 0;
+                                               notify =
+                                                   gpe_event_info->dispatch.
+                                                   notify_list;
+                                               while (notify) {
+                                                       count++;
+                                                       notify = notify->next;
+                                               }
+
+                                               acpi_os_printf
+                                                   ("Implicit Notify on %u devices",
+                                                    count);
+                                               break;
+
+                                       case ACPI_GPE_DISPATCH_RAW_HANDLER:
+
+                                               acpi_os_printf("RawHandler");
+                                               break;
+
+                                       default:
+
+                                               acpi_os_printf("UNKNOWN: %X",
+                                                              ACPI_GPE_DISPATCH_TYPE
+                                                              (gpe_event_info->
+                                                               flags));
+                                               break;
+                                       }
+
+                                       acpi_os_printf(")\n");
+                               }
+                       }
+
+                       block++;
+                       gpe_block = gpe_block->next;
+               }
+
+               gpe_xrupt_info = gpe_xrupt_info->next;
+       }
+}
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_handlers
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the currently installed global handlers
+ *
+ ******************************************************************************/
+
+void acpi_db_display_handlers(void)
+{
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *handler_obj;
+       acpi_adr_space_type space_id;
+       u32 i;
+
+       /* Operation region handlers */
+
+       acpi_os_printf("\nOperation Region Handlers at the namespace root:\n");
+
+       obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
+       if (obj_desc) {
+               for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) {
+                       space_id = acpi_gbl_space_id_list[i];
+                       handler_obj = obj_desc->device.handler;
+
+                       acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+                                      acpi_ut_get_region_name((u8)space_id),
+                                      space_id);
+
+                       while (handler_obj) {
+                               if (acpi_gbl_space_id_list[i] ==
+                                   handler_obj->address_space.space_id) {
+                                       acpi_os_printf
+                                           (ACPI_HANDLER_PRESENT_STRING,
+                                            (handler_obj->address_space.
+                                             handler_flags &
+                                             ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+                                            ? "Default" : "User",
+                                            handler_obj->address_space.
+                                            handler);
+
+                                       goto found_handler;
+                               }
+
+                               handler_obj = handler_obj->address_space.next;
+                       }
+
+                       /* There is no handler for this space_id */
+
+                       acpi_os_printf("None\n");
+
+found_handler:         ;
+               }
+
+               /* Find all handlers for user-defined space_IDs */
+
+               handler_obj = obj_desc->device.handler;
+               while (handler_obj) {
+                       if (handler_obj->address_space.space_id >=
+                           ACPI_USER_REGION_BEGIN) {
+                               acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+                                              "User-defined ID",
+                                              handler_obj->address_space.
+                                              space_id);
+                               acpi_os_printf(ACPI_HANDLER_PRESENT_STRING,
+                                              (handler_obj->address_space.
+                                               handler_flags &
+                                               ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
+                                              ? "Default" : "User",
+                                              handler_obj->address_space.
+                                              handler);
+                       }
+
+                       handler_obj = handler_obj->address_space.next;
+               }
+       }
+#if (!ACPI_REDUCED_HARDWARE)
+
+       /* Fixed event handlers */
+
+       acpi_os_printf("\nFixed Event Handlers:\n");
+
+       for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+               acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+                              acpi_ut_get_event_name(i), i);
+               if (acpi_gbl_fixed_event_handlers[i].handler) {
+                       acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
+                                      acpi_gbl_fixed_event_handlers[i].
+                                      handler);
+               } else {
+                       acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+               }
+       }
+
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+       /* Miscellaneous global handlers */
+
+       acpi_os_printf("\nMiscellaneous Global Handlers:\n");
+
+       for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) {
+               acpi_os_printf(ACPI_HANDLER_NAME_STRING,
+                              acpi_gbl_handler_list[i].name);
+
+               if (acpi_gbl_handler_list[i].handler) {
+                       acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User",
+                                      acpi_gbl_handler_list[i].handler);
+               } else {
+                       acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+               }
+       }
+
+       /* Other handlers that are installed throughout the namespace */
+
+       acpi_os_printf("\nOperation Region Handlers for specific devices:\n");
+
+       (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX,
+                                 acpi_db_display_non_root_handlers, NULL, NULL,
+                                 NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_non_root_handlers
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display information about all handlers installed for a
+ *              device object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_display_non_root_handlers(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value)
+{
+       struct acpi_namespace_node *node =
+           ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *handler_obj;
+       char *pathname;
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (!obj_desc) {
+               return (AE_OK);
+       }
+
+       pathname = acpi_ns_get_external_pathname(node);
+       if (!pathname) {
+               return (AE_OK);
+       }
+
+       /* Display all handlers associated with this device */
+
+       handler_obj = obj_desc->device.handler;
+       while (handler_obj) {
+               acpi_os_printf(ACPI_PREDEFINED_PREFIX,
+                              acpi_ut_get_region_name((u8)handler_obj->
+                                                      address_space.space_id),
+                              handler_obj->address_space.space_id);
+
+               acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2,
+                              (handler_obj->address_space.handler_flags &
+                               ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default"
+                              : "User", handler_obj->address_space.handler);
+
+               acpi_os_printf(" Device Name: %s (%p)\n", pathname, node);
+
+               handler_obj = handler_obj->address_space.next;
+       }
+
+       ACPI_FREE(pathname);
+       return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c
new file mode 100644 (file)
index 0000000..d713e2d
--- /dev/null
@@ -0,0 +1,764 @@
+/*******************************************************************************
+ *
+ * Module Name: dbexec - debugger control method execution
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbexec")
+
+static struct acpi_db_method_info acpi_gbl_db_method_info;
+
+/* Local prototypes */
+
+static acpi_status
+acpi_db_execute_method(struct acpi_db_method_info *info,
+                      struct acpi_buffer *return_obj);
+
+static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info);
+
+static u32 acpi_db_get_outstanding_allocations(void);
+
+static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context);
+
+static acpi_status
+acpi_db_execution_walk(acpi_handle obj_handle,
+                      u32 nesting_level, void *context, void **return_value);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_delete_objects
+ *
+ * PARAMETERS:  count               - Count of objects in the list
+ *              objects             - Array of ACPI_OBJECTs to be deleted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
+ *              packages via recursion.
+ *
+ ******************************************************************************/
+
+void acpi_db_delete_objects(u32 count, union acpi_object *objects)
+{
+       u32 i;
+
+       for (i = 0; i < count; i++) {
+               switch (objects[i].type) {
+               case ACPI_TYPE_BUFFER:
+
+                       ACPI_FREE(objects[i].buffer.pointer);
+                       break;
+
+               case ACPI_TYPE_PACKAGE:
+
+                       /* Recursive call to delete package elements */
+
+                       acpi_db_delete_objects(objects[i].package.count,
+                                              objects[i].package.elements);
+
+                       /* Free the elements array */
+
+                       ACPI_FREE(objects[i].package.elements);
+                       break;
+
+               default:
+
+                       break;
+               }
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_method
+ *
+ * PARAMETERS:  info            - Valid info segment
+ *              return_obj      - Where to put return object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_execute_method(struct acpi_db_method_info *info,
+                      struct acpi_buffer *return_obj)
+{
+       acpi_status status;
+       struct acpi_object_list param_objects;
+       union acpi_object params[ACPI_DEBUGGER_MAX_ARGS + 1];
+       u32 i;
+
+       ACPI_FUNCTION_TRACE(db_execute_method);
+
+       if (acpi_gbl_db_output_to_file && !acpi_dbg_level) {
+               acpi_os_printf("Warning: debug output is not enabled!\n");
+       }
+
+       param_objects.count = 0;
+       param_objects.pointer = NULL;
+
+       /* Pass through any command-line arguments */
+
+       if (info->args && info->args[0]) {
+
+               /* Get arguments passed on the command line */
+
+               for (i = 0; (info->args[i] && *(info->args[i])); i++) {
+
+                       /* Convert input string (token) to an actual union acpi_object */
+
+                       status = acpi_db_convert_to_object(info->types[i],
+                                                          info->args[i],
+                                                          &params[i]);
+                       if (ACPI_FAILURE(status)) {
+                               ACPI_EXCEPTION((AE_INFO, status,
+                                               "While parsing method arguments"));
+                               goto cleanup;
+                       }
+               }
+
+               param_objects.count = i;
+               param_objects.pointer = params;
+       }
+
+       /* Prepare for a return object of arbitrary size */
+
+       return_obj->pointer = acpi_gbl_db_buffer;
+       return_obj->length = ACPI_DEBUG_BUFFER_SIZE;
+
+       /* Do the actual method execution */
+
+       acpi_gbl_method_executing = TRUE;
+       status = acpi_evaluate_object(NULL, info->pathname,
+                                     &param_objects, return_obj);
+
+       acpi_gbl_cm_single_step = FALSE;
+       acpi_gbl_method_executing = FALSE;
+
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "while executing %s from debugger",
+                               info->pathname));
+
+               if (status == AE_BUFFER_OVERFLOW) {
+                       ACPI_ERROR((AE_INFO,
+                                   "Possible overflow of internal debugger "
+                                   "buffer (size 0x%X needed 0x%X)",
+                                   ACPI_DEBUG_BUFFER_SIZE,
+                                   (u32)return_obj->length));
+               }
+       }
+
+cleanup:
+       acpi_db_delete_objects(param_objects.count, params);
+       return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_setup
+ *
+ * PARAMETERS:  info            - Valid method info
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Setup info segment prior to method execution
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_NAME(db_execute_setup);
+
+       /* Catenate the current scope to the supplied name */
+
+       info->pathname[0] = 0;
+       if ((info->name[0] != '\\') && (info->name[0] != '/')) {
+               if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname),
+                                       acpi_gbl_db_scope_buf)) {
+                       status = AE_BUFFER_OVERFLOW;
+                       goto error_exit;
+               }
+       }
+
+       if (acpi_ut_safe_strcat(info->pathname, sizeof(info->pathname),
+                               info->name)) {
+               status = AE_BUFFER_OVERFLOW;
+               goto error_exit;
+       }
+
+       acpi_db_prep_namestring(info->pathname);
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf("Evaluating %s\n", info->pathname);
+
+       if (info->flags & EX_SINGLE_STEP) {
+               acpi_gbl_cm_single_step = TRUE;
+               acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+       }
+
+       else {
+               /* No single step, allow redirection to a file */
+
+               acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       }
+
+       return (AE_OK);
+
+error_exit:
+
+       ACPI_EXCEPTION((AE_INFO, status, "During setup for method execution"));
+       return (status);
+}
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+u32 acpi_db_get_cache_info(struct acpi_memory_list *cache)
+{
+
+       return (cache->total_allocated - cache->total_freed -
+               cache->current_depth);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_outstanding_allocations
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Current global allocation count minus cache entries
+ *
+ * DESCRIPTION: Determine the current number of "outstanding" allocations --
+ *              those allocations that have not been freed and also are not
+ *              in one of the various object caches.
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_get_outstanding_allocations(void)
+{
+       u32 outstanding = 0;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+       outstanding += acpi_db_get_cache_info(acpi_gbl_state_cache);
+       outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_cache);
+       outstanding += acpi_db_get_cache_info(acpi_gbl_ps_node_ext_cache);
+       outstanding += acpi_db_get_cache_info(acpi_gbl_operand_cache);
+#endif
+
+       return (outstanding);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execution_walk
+ *
+ * PARAMETERS:  WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ *              scope.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_execution_walk(acpi_handle obj_handle,
+                      u32 nesting_level, void *context, void **return_value)
+{
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+       struct acpi_buffer return_obj;
+       acpi_status status;
+
+       obj_desc = acpi_ns_get_attached_object(node);
+       if (obj_desc->method.param_count) {
+               return (AE_OK);
+       }
+
+       return_obj.pointer = NULL;
+       return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+       acpi_ns_print_node_pathname(node, "Evaluating");
+
+       /* Do the actual method execution */
+
+       acpi_os_printf("\n");
+       acpi_gbl_method_executing = TRUE;
+
+       status = acpi_evaluate_object(node, NULL, NULL, &return_obj);
+
+       acpi_os_printf("Evaluation of [%4.4s] returned %s\n",
+                      acpi_ut_get_node_name(node),
+                      acpi_format_exception(status));
+
+       acpi_gbl_method_executing = FALSE;
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute
+ *
+ * PARAMETERS:  name                - Name of method to execute
+ *              args                - Parameters to the method
+ *              Types               -
+ *              flags               - single step/no single step
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ *              scope.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags)
+{
+       acpi_status status;
+       struct acpi_buffer return_obj;
+       char *name_string;
+
+#ifdef ACPI_DEBUG_OUTPUT
+       u32 previous_allocations;
+       u32 allocations;
+#endif
+
+       /*
+        * Allow one execution to be performed by debugger or single step
+        * execution will be dead locked by the interpreter mutexes.
+        */
+       if (acpi_gbl_method_executing) {
+               acpi_os_printf("Only one debugger execution is allowed.\n");
+               return;
+       }
+#ifdef ACPI_DEBUG_OUTPUT
+       /* Memory allocation tracking */
+
+       previous_allocations = acpi_db_get_outstanding_allocations();
+#endif
+
+       if (*name == '*') {
+               (void)acpi_walk_namespace(ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
+                                         ACPI_UINT32_MAX,
+                                         acpi_db_execution_walk, NULL, NULL,
+                                         NULL);
+               return;
+       } else {
+               name_string = ACPI_ALLOCATE(strlen(name) + 1);
+               if (!name_string) {
+                       return;
+               }
+
+               memset(&acpi_gbl_db_method_info, 0,
+                      sizeof(struct acpi_db_method_info));
+
+               strcpy(name_string, name);
+               acpi_ut_strupr(name_string);
+               acpi_gbl_db_method_info.name = name_string;
+               acpi_gbl_db_method_info.args = args;
+               acpi_gbl_db_method_info.types = types;
+               acpi_gbl_db_method_info.flags = flags;
+
+               return_obj.pointer = NULL;
+               return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+               status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_FREE(name_string);
+                       return;
+               }
+
+               /* Get the NS node, determines existence also */
+
+               status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
+                                        &acpi_gbl_db_method_info.method);
+               if (ACPI_SUCCESS(status)) {
+                       status =
+                           acpi_db_execute_method(&acpi_gbl_db_method_info,
+                                                  &return_obj);
+               }
+               ACPI_FREE(name_string);
+       }
+
+       /*
+        * Allow any handlers in separate threads to complete.
+        * (Such as Notify handlers invoked from AML executed above).
+        */
+       acpi_os_sleep((u64)10);
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+       /* Memory allocation tracking */
+
+       allocations =
+           acpi_db_get_outstanding_allocations() - previous_allocations;
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+
+       if (allocations > 0) {
+               acpi_os_printf
+                   ("0x%X Outstanding allocations after evaluation of %s\n",
+                    allocations, acpi_gbl_db_method_info.pathname);
+       }
+#endif
+
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Evaluation of %s failed with status %s\n",
+                              acpi_gbl_db_method_info.pathname,
+                              acpi_format_exception(status));
+       } else {
+               /* Display a return object, if any */
+
+               if (return_obj.length) {
+                       acpi_os_printf("Evaluation of %s returned object %p, "
+                                      "external buffer length %X\n",
+                                      acpi_gbl_db_method_info.pathname,
+                                      return_obj.pointer,
+                                      (u32)return_obj.length);
+
+                       acpi_db_dump_external_object(return_obj.pointer, 1);
+
+                       /* Dump a _PLD buffer if present */
+
+                       if (ACPI_COMPARE_NAME
+                           ((ACPI_CAST_PTR
+                             (struct acpi_namespace_node,
+                              acpi_gbl_db_method_info.method)->name.ascii),
+                            METHOD_NAME__PLD)) {
+                               acpi_db_dump_pld_buffer(return_obj.pointer);
+                       }
+               } else {
+                       acpi_os_printf
+                           ("No object was returned from evaluation of %s\n",
+                            acpi_gbl_db_method_info.pathname);
+               }
+       }
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_method_thread
+ *
+ * PARAMETERS:  context             - Execution info segment
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context)
+{
+       acpi_status status;
+       struct acpi_db_method_info *info = context;
+       struct acpi_db_method_info local_info;
+       u32 i;
+       u8 allow;
+       struct acpi_buffer return_obj;
+
+       /*
+        * acpi_gbl_db_method_info.Arguments will be passed as method arguments.
+        * Prevent acpi_gbl_db_method_info from being modified by multiple threads
+        * concurrently.
+        *
+        * Note: The arguments we are passing are used by the ASL test suite
+        * (aslts). Do not change them without updating the tests.
+        */
+       (void)acpi_os_wait_semaphore(info->info_gate, 1, ACPI_WAIT_FOREVER);
+
+       if (info->init_args) {
+               acpi_db_uint32_to_hex_string(info->num_created,
+                                            info->index_of_thread_str);
+               acpi_db_uint32_to_hex_string((u32)acpi_os_get_thread_id(),
+                                            info->id_of_thread_str);
+       }
+
+       if (info->threads && (info->num_created < info->num_threads)) {
+               info->threads[info->num_created++] = acpi_os_get_thread_id();
+       }
+
+       local_info = *info;
+       local_info.args = local_info.arguments;
+       local_info.arguments[0] = local_info.num_threads_str;
+       local_info.arguments[1] = local_info.id_of_thread_str;
+       local_info.arguments[2] = local_info.index_of_thread_str;
+       local_info.arguments[3] = NULL;
+
+       local_info.types = local_info.arg_types;
+
+       (void)acpi_os_signal_semaphore(info->info_gate, 1);
+
+       for (i = 0; i < info->num_loops; i++) {
+               status = acpi_db_execute_method(&local_info, &return_obj);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("%s During evaluation of %s at iteration %X\n",
+                            acpi_format_exception(status), info->pathname, i);
+                       if (status == AE_ABORT_METHOD) {
+                               break;
+                       }
+               }
+#if 0
+               if ((i % 100) == 0) {
+                       acpi_os_printf("%u loops, Thread 0x%x\n",
+                                      i, acpi_os_get_thread_id());
+               }
+
+               if (return_obj.length) {
+                       acpi_os_printf
+                           ("Evaluation of %s returned object %p Buflen %X\n",
+                            info->pathname, return_obj.pointer,
+                            (u32)return_obj.length);
+                       acpi_db_dump_external_object(return_obj.pointer, 1);
+               }
+#endif
+       }
+
+       /* Signal our completion */
+
+       allow = 0;
+       (void)acpi_os_wait_semaphore(info->thread_complete_gate,
+                                    1, ACPI_WAIT_FOREVER);
+       info->num_completed++;
+
+       if (info->num_completed == info->num_threads) {
+
+               /* Do signal for main thread once only */
+               allow = 1;
+       }
+
+       (void)acpi_os_signal_semaphore(info->thread_complete_gate, 1);
+
+       if (allow) {
+               status = acpi_os_signal_semaphore(info->main_thread_gate, 1);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("Could not signal debugger thread sync semaphore, %s\n",
+                            acpi_format_exception(status));
+               }
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_create_execution_threads
+ *
+ * PARAMETERS:  num_threads_arg         - Number of threads to create
+ *              num_loops_arg           - Loop count for the thread(s)
+ *              method_name_arg         - Control method to execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Create threads to execute method(s)
+ *
+ ******************************************************************************/
+
+void
+acpi_db_create_execution_threads(char *num_threads_arg,
+                                char *num_loops_arg, char *method_name_arg)
+{
+       acpi_status status;
+       u32 num_threads;
+       u32 num_loops;
+       u32 i;
+       u32 size;
+       acpi_mutex main_thread_gate;
+       acpi_mutex thread_complete_gate;
+       acpi_mutex info_gate;
+
+       /* Get the arguments */
+
+       num_threads = strtoul(num_threads_arg, NULL, 0);
+       num_loops = strtoul(num_loops_arg, NULL, 0);
+
+       if (!num_threads || !num_loops) {
+               acpi_os_printf("Bad argument: Threads %X, Loops %X\n",
+                              num_threads, num_loops);
+               return;
+       }
+
+       /*
+        * Create the semaphore for synchronization of
+        * the created threads with the main thread.
+        */
+       status = acpi_os_create_semaphore(1, 0, &main_thread_gate);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not create semaphore for "
+                              "synchronization with the main thread, %s\n",
+                              acpi_format_exception(status));
+               return;
+       }
+
+       /*
+        * Create the semaphore for synchronization
+        * between the created threads.
+        */
+       status = acpi_os_create_semaphore(1, 1, &thread_complete_gate);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not create semaphore for "
+                              "synchronization between the created threads, %s\n",
+                              acpi_format_exception(status));
+
+               (void)acpi_os_delete_semaphore(main_thread_gate);
+               return;
+       }
+
+       status = acpi_os_create_semaphore(1, 1, &info_gate);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not create semaphore for "
+                              "synchronization of AcpiGbl_DbMethodInfo, %s\n",
+                              acpi_format_exception(status));
+
+               (void)acpi_os_delete_semaphore(thread_complete_gate);
+               (void)acpi_os_delete_semaphore(main_thread_gate);
+               return;
+       }
+
+       memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info));
+
+       /* Array to store IDs of threads */
+
+       acpi_gbl_db_method_info.num_threads = num_threads;
+       size = sizeof(acpi_thread_id) * acpi_gbl_db_method_info.num_threads;
+
+       acpi_gbl_db_method_info.threads = acpi_os_allocate(size);
+       if (acpi_gbl_db_method_info.threads == NULL) {
+               acpi_os_printf("No memory for thread IDs array\n");
+               (void)acpi_os_delete_semaphore(main_thread_gate);
+               (void)acpi_os_delete_semaphore(thread_complete_gate);
+               (void)acpi_os_delete_semaphore(info_gate);
+               return;
+       }
+       memset(acpi_gbl_db_method_info.threads, 0, size);
+
+       /* Setup the context to be passed to each thread */
+
+       acpi_gbl_db_method_info.name = method_name_arg;
+       acpi_gbl_db_method_info.flags = 0;
+       acpi_gbl_db_method_info.num_loops = num_loops;
+       acpi_gbl_db_method_info.main_thread_gate = main_thread_gate;
+       acpi_gbl_db_method_info.thread_complete_gate = thread_complete_gate;
+       acpi_gbl_db_method_info.info_gate = info_gate;
+
+       /* Init arguments to be passed to method */
+
+       acpi_gbl_db_method_info.init_args = 1;
+       acpi_gbl_db_method_info.args = acpi_gbl_db_method_info.arguments;
+       acpi_gbl_db_method_info.arguments[0] =
+           acpi_gbl_db_method_info.num_threads_str;
+       acpi_gbl_db_method_info.arguments[1] =
+           acpi_gbl_db_method_info.id_of_thread_str;
+       acpi_gbl_db_method_info.arguments[2] =
+           acpi_gbl_db_method_info.index_of_thread_str;
+       acpi_gbl_db_method_info.arguments[3] = NULL;
+
+       acpi_gbl_db_method_info.types = acpi_gbl_db_method_info.arg_types;
+       acpi_gbl_db_method_info.arg_types[0] = ACPI_TYPE_INTEGER;
+       acpi_gbl_db_method_info.arg_types[1] = ACPI_TYPE_INTEGER;
+       acpi_gbl_db_method_info.arg_types[2] = ACPI_TYPE_INTEGER;
+
+       acpi_db_uint32_to_hex_string(num_threads,
+                                    acpi_gbl_db_method_info.num_threads_str);
+
+       status = acpi_db_execute_setup(&acpi_gbl_db_method_info);
+       if (ACPI_FAILURE(status)) {
+               goto cleanup_and_exit;
+       }
+
+       /* Get the NS node, determines existence also */
+
+       status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname,
+                                &acpi_gbl_db_method_info.method);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("%s Could not get handle for %s\n",
+                              acpi_format_exception(status),
+                              acpi_gbl_db_method_info.pathname);
+               goto cleanup_and_exit;
+       }
+
+       /* Create the threads */
+
+       acpi_os_printf("Creating %X threads to execute %X times each\n",
+                      num_threads, num_loops);
+
+       for (i = 0; i < (num_threads); i++) {
+               status =
+                   acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD,
+                                   acpi_db_method_thread,
+                                   &acpi_gbl_db_method_info);
+               if (ACPI_FAILURE(status)) {
+                       break;
+               }
+       }
+
+       /* Wait for all threads to complete */
+
+       (void)acpi_os_wait_semaphore(main_thread_gate, 1, ACPI_WAIT_FOREVER);
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf("All threads (%X) have completed\n", num_threads);
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+cleanup_and_exit:
+
+       /* Cleanup and exit */
+
+       (void)acpi_os_delete_semaphore(main_thread_gate);
+       (void)acpi_os_delete_semaphore(thread_complete_gate);
+       (void)acpi_os_delete_semaphore(info_gate);
+
+       acpi_os_free(acpi_gbl_db_method_info.threads);
+       acpi_gbl_db_method_info.threads = NULL;
+}
diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c
new file mode 100644 (file)
index 0000000..d0e6b20
--- /dev/null
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ *
+ * Module Name: dbfileio - Debugger file I/O commands. These can't usually
+ *              be used when running the debugger in Ring 0 (Kernel mode)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbfileio")
+
+#ifdef ACPI_DEBUGGER
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_close_debug_file
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: If open, close the current debug output file
+ *
+ ******************************************************************************/
+void acpi_db_close_debug_file(void)
+{
+
+#ifdef ACPI_APPLICATION
+
+       if (acpi_gbl_debug_file) {
+               fclose(acpi_gbl_debug_file);
+               acpi_gbl_debug_file = NULL;
+               acpi_gbl_db_output_to_file = FALSE;
+               acpi_os_printf("Debug output file %s closed\n",
+                              acpi_gbl_db_debug_filename);
+       }
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_open_debug_file
+ *
+ * PARAMETERS:  name                - Filename to open
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Open a file where debug output will be directed.
+ *
+ ******************************************************************************/
+
+void acpi_db_open_debug_file(char *name)
+{
+
+#ifdef ACPI_APPLICATION
+
+       acpi_db_close_debug_file();
+       acpi_gbl_debug_file = fopen(name, "w+");
+       if (!acpi_gbl_debug_file) {
+               acpi_os_printf("Could not open debug file %s\n", name);
+               return;
+       }
+
+       acpi_os_printf("Debug output file %s opened\n", name);
+       strncpy(acpi_gbl_db_debug_filename, name,
+               sizeof(acpi_gbl_db_debug_filename));
+       acpi_gbl_db_output_to_file = TRUE;
+
+#endif
+}
+#endif
+
+#ifdef ACPI_APPLICATION
+#include "acapps.h"
+
+/*******************************************************************************
+ *
+ * FUNCTION:    ae_local_load_table
+ *
+ * PARAMETERS:  table           - pointer to a buffer containing the entire
+ *                                table to be loaded
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ *              buffer. The buffer must contain an entire ACPI Table including
+ *              a valid header. The header fields will be verified, and if it
+ *              is determined that the table is invalid, the call will fail.
+ *
+ ******************************************************************************/
+
+static acpi_status ae_local_load_table(struct acpi_table_header *table)
+{
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE(ae_local_load_table);
+
+#if 0
+/*    struct acpi_table_desc          table_info; */
+
+       if (!table) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       table_info.pointer = table;
+       status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Install the new table into the local data structures */
+
+       status = acpi_tb_init_table_descriptor(&table_info);
+       if (ACPI_FAILURE(status)) {
+               if (status == AE_ALREADY_EXISTS) {
+
+                       /* Table already exists, no error */
+
+                       status = AE_OK;
+               }
+
+               /* Free table allocated by acpi_tb_get_table */
+
+               acpi_tb_delete_single_table(&table_info);
+               return_ACPI_STATUS(status);
+       }
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+       status =
+           acpi_ns_load_table(table_info.installed_desc, acpi_gbl_root_node);
+       if (ACPI_FAILURE(status)) {
+
+               /* Uninstall table and free the buffer */
+
+               acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_DSDT);
+               return_ACPI_STATUS(status);
+       }
+#endif
+#endif
+
+       return_ACPI_STATUS(status);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_table_from_file
+ *
+ * PARAMETERS:  filename        - File where table is located
+ *              return_table    - Where a pointer to the table is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load an ACPI table from a file
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_get_table_from_file(char *filename,
+                           struct acpi_table_header **return_table,
+                           u8 must_be_aml_file)
+{
+#ifdef ACPI_APPLICATION
+       acpi_status status;
+       struct acpi_table_header *table;
+       u8 is_aml_table = TRUE;
+
+       status = acpi_ut_read_table_from_file(filename, &table);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       if (must_be_aml_file) {
+               is_aml_table = acpi_ut_is_aml_table(table);
+               if (!is_aml_table) {
+                       ACPI_EXCEPTION((AE_INFO, AE_OK,
+                                       "Input for -e is not an AML table: "
+                                       "\"%4.4s\" (must be DSDT/SSDT)",
+                                       table->signature));
+                       return (AE_TYPE);
+               }
+       }
+
+       if (is_aml_table) {
+
+               /* Attempt to recognize and install the table */
+
+               status = ae_local_load_table(table);
+               if (ACPI_FAILURE(status)) {
+                       if (status == AE_ALREADY_EXISTS) {
+                               acpi_os_printf
+                                   ("Table %4.4s is already installed\n",
+                                    table->signature);
+                       } else {
+                               acpi_os_printf("Could not install table, %s\n",
+                                              acpi_format_exception(status));
+                       }
+
+                       return (status);
+               }
+
+               acpi_tb_print_table_header(0, table);
+
+               fprintf(stderr,
+                       "Acpi table [%4.4s] successfully installed and loaded\n",
+                       table->signature);
+       }
+
+       acpi_gbl_acpi_hardware_present = FALSE;
+       if (return_table) {
+               *return_table = table;
+       }
+
+#endif                         /* ACPI_APPLICATION */
+       return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c
new file mode 100644 (file)
index 0000000..9c66a9e
--- /dev/null
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ * Module Name: dbhistry - debugger HISTORY command
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbhistry")
+
+#define HI_NO_HISTORY       0
+#define HI_RECORD_HISTORY   1
+#define HISTORY_SIZE        40
+typedef struct history_info {
+       char *command;
+       u32 cmd_num;
+
+} HISTORY_INFO;
+
+static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE];
+static u16 acpi_gbl_lo_history = 0;
+static u16 acpi_gbl_num_history = 0;
+static u16 acpi_gbl_next_history_index = 0;
+u32 acpi_gbl_next_cmd_num = 1;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_add_to_history
+ *
+ * PARAMETERS:  command_line    - Command to add
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add a command line to the history buffer.
+ *
+ ******************************************************************************/
+
+void acpi_db_add_to_history(char *command_line)
+{
+       u16 cmd_len;
+       u16 buffer_len;
+
+       /* Put command into the next available slot */
+
+       cmd_len = (u16)strlen(command_line);
+       if (!cmd_len) {
+               return;
+       }
+
+       if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command !=
+           NULL) {
+               buffer_len =
+                   (u16)
+                   strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index].
+                          command);
+
+               if (cmd_len > buffer_len) {
+                       acpi_os_free(acpi_gbl_history_buffer
+                                    [acpi_gbl_next_history_index].command);
+                       acpi_gbl_history_buffer[acpi_gbl_next_history_index].
+                           command = acpi_os_allocate(cmd_len + 1);
+               }
+       } else {
+               acpi_gbl_history_buffer[acpi_gbl_next_history_index].command =
+                   acpi_os_allocate(cmd_len + 1);
+       }
+
+       strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command,
+              command_line);
+
+       acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num =
+           acpi_gbl_next_cmd_num;
+
+       /* Adjust indexes */
+
+       if ((acpi_gbl_num_history == HISTORY_SIZE) &&
+           (acpi_gbl_next_history_index == acpi_gbl_lo_history)) {
+               acpi_gbl_lo_history++;
+               if (acpi_gbl_lo_history >= HISTORY_SIZE) {
+                       acpi_gbl_lo_history = 0;
+               }
+       }
+
+       acpi_gbl_next_history_index++;
+       if (acpi_gbl_next_history_index >= HISTORY_SIZE) {
+               acpi_gbl_next_history_index = 0;
+       }
+
+       acpi_gbl_next_cmd_num++;
+       if (acpi_gbl_num_history < HISTORY_SIZE) {
+               acpi_gbl_num_history++;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_history
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the contents of the history buffer
+ *
+ ******************************************************************************/
+
+void acpi_db_display_history(void)
+{
+       u32 i;
+       u16 history_index;
+
+       history_index = acpi_gbl_lo_history;
+
+       /* Dump entire history buffer */
+
+       for (i = 0; i < acpi_gbl_num_history; i++) {
+               if (acpi_gbl_history_buffer[history_index].command) {
+                       acpi_os_printf("%3ld %s\n",
+                                      acpi_gbl_history_buffer[history_index].
+                                      cmd_num,
+                                      acpi_gbl_history_buffer[history_index].
+                                      command);
+               }
+
+               history_index++;
+               if (history_index >= HISTORY_SIZE) {
+                       history_index = 0;
+               }
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_from_history
+ *
+ * PARAMETERS:  command_num_arg         - String containing the number of the
+ *                                        command to be retrieved
+ *
+ * RETURN:      Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_from_history(char *command_num_arg)
+{
+       u32 cmd_num;
+
+       if (command_num_arg == NULL) {
+               cmd_num = acpi_gbl_next_cmd_num - 1;
+       }
+
+       else {
+               cmd_num = strtoul(command_num_arg, NULL, 0);
+       }
+
+       return (acpi_db_get_history_by_index(cmd_num));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_history_by_index
+ *
+ * PARAMETERS:  cmd_num             - Index of the desired history entry.
+ *                                    Values are 0...(acpi_gbl_next_cmd_num - 1)
+ *
+ * RETURN:      Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_history_by_index(u32 cmd_num)
+{
+       u32 i;
+       u16 history_index;
+
+       /* Search history buffer */
+
+       history_index = acpi_gbl_lo_history;
+       for (i = 0; i < acpi_gbl_num_history; i++) {
+               if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) {
+
+                       /* Found the command, return it */
+
+                       return (acpi_gbl_history_buffer[history_index].command);
+               }
+
+               /* History buffer is circular */
+
+               history_index++;
+               if (history_index >= HISTORY_SIZE) {
+                       history_index = 0;
+               }
+       }
+
+       acpi_os_printf("Invalid history number: %u\n", history_index);
+       return (NULL);
+}
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
new file mode 100644 (file)
index 0000000..0480254
--- /dev/null
@@ -0,0 +1,1267 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbinput")
+
+/* Local prototypes */
+static u32 acpi_db_get_line(char *input_buffer);
+
+static u32 acpi_db_match_command(char *user_command);
+
+static void acpi_db_single_thread(void);
+
+static void acpi_db_display_command_info(char *command, u8 display_all);
+
+static void acpi_db_display_help(char *command);
+
+static u8
+acpi_db_match_command_help(char *command,
+                          const struct acpi_db_command_help *help);
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+enum acpi_ex_debugger_commands {
+       CMD_NOT_FOUND = 0,
+       CMD_NULL,
+       CMD_ALLOCATIONS,
+       CMD_ARGS,
+       CMD_ARGUMENTS,
+       CMD_BREAKPOINT,
+       CMD_BUSINFO,
+       CMD_CALL,
+       CMD_DEBUG,
+       CMD_DISASSEMBLE,
+       CMD_DISASM,
+       CMD_DUMP,
+       CMD_EVALUATE,
+       CMD_EXECUTE,
+       CMD_EXIT,
+       CMD_FIND,
+       CMD_GO,
+       CMD_HANDLERS,
+       CMD_HELP,
+       CMD_HELP2,
+       CMD_HISTORY,
+       CMD_HISTORY_EXE,
+       CMD_HISTORY_LAST,
+       CMD_INFORMATION,
+       CMD_INTEGRITY,
+       CMD_INTO,
+       CMD_LEVEL,
+       CMD_LIST,
+       CMD_LOCALS,
+       CMD_LOCKS,
+       CMD_METHODS,
+       CMD_NAMESPACE,
+       CMD_NOTIFY,
+       CMD_OBJECTS,
+       CMD_OSI,
+       CMD_OWNER,
+       CMD_PATHS,
+       CMD_PREDEFINED,
+       CMD_PREFIX,
+       CMD_QUIT,
+       CMD_REFERENCES,
+       CMD_RESOURCES,
+       CMD_RESULTS,
+       CMD_SET,
+       CMD_STATS,
+       CMD_STOP,
+       CMD_TABLES,
+       CMD_TEMPLATE,
+       CMD_TRACE,
+       CMD_TREE,
+       CMD_TYPE,
+#ifdef ACPI_APPLICATION
+       CMD_ENABLEACPI,
+       CMD_EVENT,
+       CMD_GPE,
+       CMD_GPES,
+       CMD_SCI,
+       CMD_SLEEP,
+
+       CMD_CLOSE,
+       CMD_LOAD,
+       CMD_OPEN,
+       CMD_UNLOAD,
+
+       CMD_TERMINATE,
+       CMD_THREADS,
+
+       CMD_TEST,
+#endif
+};
+
+#define CMD_FIRST_VALID     2
+
+/* Second parameter is the required argument count */
+
+static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
+       {"<NOT FOUND>", 0},
+       {"<NULL>", 0},
+       {"ALLOCATIONS", 0},
+       {"ARGS", 0},
+       {"ARGUMENTS", 0},
+       {"BREAKPOINT", 1},
+       {"BUSINFO", 0},
+       {"CALL", 0},
+       {"DEBUG", 1},
+       {"DISASSEMBLE", 1},
+       {"DISASM", 1},
+       {"DUMP", 1},
+       {"EVALUATE", 1},
+       {"EXECUTE", 1},
+       {"EXIT", 0},
+       {"FIND", 1},
+       {"GO", 0},
+       {"HANDLERS", 0},
+       {"HELP", 0},
+       {"?", 0},
+       {"HISTORY", 0},
+       {"!", 1},
+       {"!!", 0},
+       {"INFORMATION", 0},
+       {"INTEGRITY", 0},
+       {"INTO", 0},
+       {"LEVEL", 0},
+       {"LIST", 0},
+       {"LOCALS", 0},
+       {"LOCKS", 0},
+       {"METHODS", 0},
+       {"NAMESPACE", 0},
+       {"NOTIFY", 2},
+       {"OBJECTS", 0},
+       {"OSI", 0},
+       {"OWNER", 1},
+       {"PATHS", 0},
+       {"PREDEFINED", 0},
+       {"PREFIX", 0},
+       {"QUIT", 0},
+       {"REFERENCES", 1},
+       {"RESOURCES", 0},
+       {"RESULTS", 0},
+       {"SET", 3},
+       {"STATS", 1},
+       {"STOP", 0},
+       {"TABLES", 0},
+       {"TEMPLATE", 1},
+       {"TRACE", 1},
+       {"TREE", 0},
+       {"TYPE", 1},
+#ifdef ACPI_APPLICATION
+       {"ENABLEACPI", 0},
+       {"EVENT", 1},
+       {"GPE", 1},
+       {"GPES", 0},
+       {"SCI", 0},
+       {"SLEEP", 0},
+
+       {"CLOSE", 0},
+       {"LOAD", 1},
+       {"OPEN", 1},
+       {"UNLOAD", 1},
+
+       {"TERMINATE", 0},
+       {"THREADS", 3},
+
+       {"TEST", 1},
+#endif
+       {NULL, 0}
+};
+
+/*
+ * Help for all debugger commands. First argument is the number of lines
+ * of help to output for the command.
+ */
+static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
+       {0, "\nGeneral-Purpose Commands:", "\n"},
+       {1, "  Allocations", "Display list of current memory allocations\n"},
+       {2, "  Dump <Address>|<Namepath>", "\n"},
+       {0, "       [Byte|Word|Dword|Qword]",
+        "Display ACPI objects or memory\n"},
+       {1, "  Handlers", "Info about global handlers\n"},
+       {1, "  Help [Command]", "This help screen or individual command\n"},
+       {1, "  History", "Display command history buffer\n"},
+       {1, "  Level <DebugLevel>] [console]",
+        "Get/Set debug level for file or console\n"},
+       {1, "  Locks", "Current status of internal mutexes\n"},
+       {1, "  Osi [Install|Remove <name>]",
+        "Display or modify global _OSI list\n"},
+       {1, "  Quit or Exit", "Exit this command\n"},
+       {8, "  Stats <SubCommand>",
+        "Display namespace and memory statistics\n"},
+       {1, "     Allocations", "Display list of current memory allocations\n"},
+       {1, "     Memory", "Dump internal memory lists\n"},
+       {1, "     Misc", "Namespace search and mutex stats\n"},
+       {1, "     Objects", "Summary of namespace objects\n"},
+       {1, "     Sizes", "Sizes for each of the internal objects\n"},
+       {1, "     Stack", "Display CPU stack usage\n"},
+       {1, "     Tables", "Info about current ACPI table(s)\n"},
+       {1, "  Tables", "Display info about loaded ACPI tables\n"},
+       {1, "  ! <CommandNumber>", "Execute command from history buffer\n"},
+       {1, "  !!", "Execute last command again\n"},
+
+       {0, "\nNamespace Access Commands:", "\n"},
+       {1, "  Businfo", "Display system bus info\n"},
+       {1, "  Disassemble <Method>", "Disassemble a control method\n"},
+       {1, "  Find <AcpiName> (? is wildcard)",
+        "Find ACPI name(s) with wildcards\n"},
+       {1, "  Integrity", "Validate namespace integrity\n"},
+       {1, "  Methods", "Display list of loaded control methods\n"},
+       {1, "  Namespace [Object] [Depth]",
+        "Display loaded namespace tree/subtree\n"},
+       {1, "  Notify <Object> <Value>", "Send a notification on Object\n"},
+       {1, "  Objects [ObjectType]",
+        "Display summary of all objects or just given type\n"},
+       {1, "  Owner <OwnerId> [Depth]",
+        "Display loaded namespace by object owner\n"},
+       {1, "  Paths", "Display full pathnames of namespace objects\n"},
+       {1, "  Predefined", "Check all predefined names\n"},
+       {1, "  Prefix [<Namepath>]", "Set or Get current execution prefix\n"},
+       {1, "  References <Addr>", "Find all references to object at addr\n"},
+       {1, "  Resources [DeviceName]",
+        "Display Device resources (no arg = all devices)\n"},
+       {1, "  Set N <NamedObject> <Value>", "Set value for named integer\n"},
+       {1, "  Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
+       {1, "  Type <Object>", "Display object type\n"},
+
+       {0, "\nControl Method Execution Commands:", "\n"},
+       {1, "  Arguments (or Args)", "Display method arguments\n"},
+       {1, "  Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"},
+       {1, "  Call", "Run to next control method invocation\n"},
+       {1, "  Debug <Namepath> [Arguments]", "Single Step a control method\n"},
+       {6, "  Evaluate", "Synonym for Execute\n"},
+       {5, "  Execute <Namepath> [Arguments]", "Execute control method\n"},
+       {1, "     Hex Integer", "Integer method argument\n"},
+       {1, "     \"Ascii String\"", "String method argument\n"},
+       {1, "     (Hex Byte List)", "Buffer method argument\n"},
+       {1, "     [Package Element List]", "Package method argument\n"},
+       {1, "  Go", "Allow method to run to completion\n"},
+       {1, "  Information", "Display info about the current method\n"},
+       {1, "  Into", "Step into (not over) a method call\n"},
+       {1, "  List [# of Aml Opcodes]", "Display method ASL statements\n"},
+       {1, "  Locals", "Display method local variables\n"},
+       {1, "  Results", "Display method result stack\n"},
+       {1, "  Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"},
+       {1, "  Stop", "Terminate control method\n"},
+       {5, "  Trace <State> [<Namepath>] [Once]",
+        "Trace control method execution\n"},
+       {1, "     Enable", "Enable all messages\n"},
+       {1, "     Disable", "Disable tracing\n"},
+       {1, "     Method", "Enable method execution messages\n"},
+       {1, "     Opcode", "Enable opcode execution messages\n"},
+       {1, "  Tree", "Display control method calling tree\n"},
+       {1, "  <Enter>", "Single step next AML opcode (over calls)\n"},
+
+#ifdef ACPI_APPLICATION
+       {0, "\nHardware Simulation Commands:", "\n"},
+       {1, "  EnableAcpi", "Enable ACPI (hardware) mode\n"},
+       {1, "  Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
+       {1, "  Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"},
+       {1, "  Gpes", "Display info on all GPE devices\n"},
+       {1, "  Sci", "Generate an SCI\n"},
+       {1, "  Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
+
+       {0, "\nFile I/O Commands:", "\n"},
+       {1, "  Close", "Close debug output file\n"},
+       {1, "  Load <Input Filename>", "Load ACPI table from a file\n"},
+       {1, "  Open <Output Filename>", "Open a file for debug output\n"},
+       {1, "  Unload <Namepath>",
+        "Unload an ACPI table via namespace object\n"},
+
+       {0, "\nUser Space Commands:", "\n"},
+       {1, "  Terminate", "Delete namespace and all internal objects\n"},
+       {1, "  Thread <Threads><Loops><NamePath>",
+        "Spawn threads to execute method(s)\n"},
+
+       {0, "\nDebug Test Commands:", "\n"},
+       {3, "  Test <TestName>", "Invoke a debug test\n"},
+       {1, "     Objects", "Read/write/compare all namespace data objects\n"},
+       {1, "     Predefined",
+        "Execute all ACPI predefined names (_STA, etc.)\n"},
+#endif
+       {0, NULL, NULL}
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_command_help
+ *
+ * PARAMETERS:  command             - Command string to match
+ *              help                - Help table entry to attempt match
+ *
+ * RETURN:      TRUE if command matched, FALSE otherwise
+ *
+ * DESCRIPTION: Attempt to match a command in the help table in order to
+ *              print help information for a single command.
+ *
+ ******************************************************************************/
+
+static u8
+acpi_db_match_command_help(char *command,
+                          const struct acpi_db_command_help *help)
+{
+       char *invocation = help->invocation;
+       u32 line_count;
+
+       /* Valid commands in the help table begin with a couple of spaces */
+
+       if (*invocation != ' ') {
+               return (FALSE);
+       }
+
+       while (*invocation == ' ') {
+               invocation++;
+       }
+
+       /* Match command name (full command or substring) */
+
+       while ((*command) && (*invocation) && (*invocation != ' ')) {
+               if (tolower((int)*command) != tolower((int)*invocation)) {
+                       return (FALSE);
+               }
+
+               invocation++;
+               command++;
+       }
+
+       /* Print the appropriate number of help lines */
+
+       line_count = help->line_count;
+       while (line_count) {
+               acpi_os_printf("%-38s : %s", help->invocation,
+                              help->description);
+               help++;
+               line_count--;
+       }
+
+       return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_command_info
+ *
+ * PARAMETERS:  command             - Command string to match
+ *              display_all         - Display all matching commands, or just
+ *                                    the first one (substring match)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display help information for a Debugger command.
+ *
+ ******************************************************************************/
+
+static void acpi_db_display_command_info(char *command, u8 display_all)
+{
+       const struct acpi_db_command_help *next;
+       u8 matched;
+
+       next = acpi_gbl_db_command_help;
+       while (next->invocation) {
+               matched = acpi_db_match_command_help(command, next);
+               if (!display_all && matched) {
+                       return;
+               }
+
+               next++;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_help
+ *
+ * PARAMETERS:  command             - Optional command string to display help.
+ *                                    if not specified, all debugger command
+ *                                    help strings are displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display help for a single debugger command, or all of them.
+ *
+ ******************************************************************************/
+
+static void acpi_db_display_help(char *command)
+{
+       const struct acpi_db_command_help *next = acpi_gbl_db_command_help;
+
+       if (!command) {
+
+               /* No argument to help, display help for all commands */
+
+               while (next->invocation) {
+                       acpi_os_printf("%-38s%s", next->invocation,
+                                      next->description);
+                       next++;
+               }
+       } else {
+               /* Display help for all commands that match the subtring */
+
+               acpi_db_display_command_info(command, TRUE);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_next_token
+ *
+ * PARAMETERS:  string          - Command buffer
+ *              next            - Return value, end of next token
+ *
+ * RETURN:      Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing. Get the next token on the command line
+ *
+ ******************************************************************************/
+
+char *acpi_db_get_next_token(char *string,
+                            char **next, acpi_object_type * return_type)
+{
+       char *start;
+       u32 depth;
+       acpi_object_type type = ACPI_TYPE_INTEGER;
+
+       /* At end of buffer? */
+
+       if (!string || !(*string)) {
+               return (NULL);
+       }
+
+       /* Remove any spaces at the beginning */
+
+       if (*string == ' ') {
+               while (*string && (*string == ' ')) {
+                       string++;
+               }
+
+               if (!(*string)) {
+                       return (NULL);
+               }
+       }
+
+       switch (*string) {
+       case '"':
+
+               /* This is a quoted string, scan until closing quote */
+
+               string++;
+               start = string;
+               type = ACPI_TYPE_STRING;
+
+               /* Find end of string */
+
+               while (*string && (*string != '"')) {
+                       string++;
+               }
+               break;
+
+       case '(':
+
+               /* This is the start of a buffer, scan until closing paren */
+
+               string++;
+               start = string;
+               type = ACPI_TYPE_BUFFER;
+
+               /* Find end of buffer */
+
+               while (*string && (*string != ')')) {
+                       string++;
+               }
+               break;
+
+       case '[':
+
+               /* This is the start of a package, scan until closing bracket */
+
+               string++;
+               depth = 1;
+               start = string;
+               type = ACPI_TYPE_PACKAGE;
+
+               /* Find end of package (closing bracket) */
+
+               while (*string) {
+
+                       /* Handle String package elements */
+
+                       if (*string == '"') {
+                               /* Find end of string */
+
+                               string++;
+                               while (*string && (*string != '"')) {
+                                       string++;
+                               }
+                               if (!(*string)) {
+                                       break;
+                               }
+                       } else if (*string == '[') {
+                               depth++;        /* A nested package declaration */
+                       } else if (*string == ']') {
+                               depth--;
+                               if (depth == 0) {       /* Found final package closing bracket */
+                                       break;
+                               }
+                       }
+
+                       string++;
+               }
+               break;
+
+       default:
+
+               start = string;
+
+               /* Find end of token */
+
+               while (*string && (*string != ' ')) {
+                       string++;
+               }
+               break;
+       }
+
+       if (!(*string)) {
+               *next = NULL;
+       } else {
+               *string = 0;
+               *next = string + 1;
+       }
+
+       *return_type = type;
+       return (start);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_line
+ *
+ * PARAMETERS:  input_buffer        - Command line buffer
+ *
+ * RETURN:      Count of arguments to the command
+ *
+ * DESCRIPTION: Get the next command line from the user. Gets entire line
+ *              up to the next newline
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_get_line(char *input_buffer)
+{
+       u32 i;
+       u32 count;
+       char *next;
+       char *this;
+
+       if (acpi_ut_safe_strcpy
+           (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf),
+            input_buffer)) {
+               acpi_os_printf
+                   ("Buffer overflow while parsing input line (max %u characters)\n",
+                    sizeof(acpi_gbl_db_parsed_buf));
+               return (0);
+       }
+
+       this = acpi_gbl_db_parsed_buf;
+       for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) {
+               acpi_gbl_db_args[i] = acpi_db_get_next_token(this, &next,
+                                                            &acpi_gbl_db_arg_types
+                                                            [i]);
+               if (!acpi_gbl_db_args[i]) {
+                       break;
+               }
+
+               this = next;
+       }
+
+       /* Uppercase the actual command */
+
+       if (acpi_gbl_db_args[0]) {
+               acpi_ut_strupr(acpi_gbl_db_args[0]);
+       }
+
+       count = i;
+       if (count) {
+               count--;        /* Number of args only */
+       }
+
+       return (count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_command
+ *
+ * PARAMETERS:  user_command            - User command line
+ *
+ * RETURN:      Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+static u32 acpi_db_match_command(char *user_command)
+{
+       u32 i;
+
+       if (!user_command || user_command[0] == 0) {
+               return (CMD_NULL);
+       }
+
+       for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) {
+               if (strstr(acpi_gbl_db_commands[i].name, user_command) ==
+                   acpi_gbl_db_commands[i].name) {
+                       return (i);
+               }
+       }
+
+       /* Command not recognized */
+
+       return (CMD_NOT_FOUND);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_command_dispatch
+ *
+ * PARAMETERS:  input_buffer        - Command line buffer
+ *              walk_state          - Current walk
+ *              op                  - Current (executing) parse op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Command dispatcher.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_command_dispatch(char *input_buffer,
+                        struct acpi_walk_state * walk_state,
+                        union acpi_parse_object * op)
+{
+       u32 temp;
+       u32 command_index;
+       u32 param_count;
+       char *command_line;
+       acpi_status status = AE_CTRL_TRUE;
+
+       /* If acpi_terminate has been called, terminate this thread */
+
+       if (acpi_gbl_db_terminate_loop) {
+               return (AE_CTRL_TERMINATE);
+       }
+
+       /* Find command and add to the history buffer */
+
+       param_count = acpi_db_get_line(input_buffer);
+       command_index = acpi_db_match_command(acpi_gbl_db_args[0]);
+       temp = 0;
+
+       /*
+        * We don't want to add the !! command to the history buffer. It
+        * would cause an infinite loop because it would always be the
+        * previous command.
+        */
+       if (command_index != CMD_HISTORY_LAST) {
+               acpi_db_add_to_history(input_buffer);
+       }
+
+       /* Verify that we have the minimum number of params */
+
+       if (param_count < acpi_gbl_db_commands[command_index].min_args) {
+               acpi_os_printf
+                   ("%u parameters entered, [%s] requires %u parameters\n",
+                    param_count, acpi_gbl_db_commands[command_index].name,
+                    acpi_gbl_db_commands[command_index].min_args);
+
+               acpi_db_display_command_info(acpi_gbl_db_commands
+                                            [command_index].name, FALSE);
+               return (AE_CTRL_TRUE);
+       }
+
+       /* Decode and dispatch the command */
+
+       switch (command_index) {
+       case CMD_NULL:
+
+               if (op) {
+                       return (AE_OK);
+               }
+               break;
+
+       case CMD_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+               acpi_ut_dump_allocations((u32)-1, NULL);
+#endif
+               break;
+
+       case CMD_ARGS:
+       case CMD_ARGUMENTS:
+
+               acpi_db_display_arguments();
+               break;
+
+       case CMD_BREAKPOINT:
+
+               acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state,
+                                             op);
+               break;
+
+       case CMD_BUSINFO:
+
+               acpi_db_get_bus_info();
+               break;
+
+       case CMD_CALL:
+
+               acpi_db_set_method_call_breakpoint(op);
+               status = AE_OK;
+               break;
+
+       case CMD_DEBUG:
+
+               acpi_db_execute(acpi_gbl_db_args[1],
+                               &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
+                               EX_SINGLE_STEP);
+               break;
+
+       case CMD_DISASSEMBLE:
+       case CMD_DISASM:
+
+               (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_DUMP:
+
+               acpi_db_decode_and_display_object(acpi_gbl_db_args[1],
+                                                 acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_EVALUATE:
+       case CMD_EXECUTE:
+
+               acpi_db_execute(acpi_gbl_db_args[1],
+                               &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
+                               EX_NO_SINGLE_STEP);
+               break;
+
+       case CMD_FIND:
+
+               status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_GO:
+
+               acpi_gbl_cm_single_step = FALSE;
+               return (AE_OK);
+
+       case CMD_HANDLERS:
+
+               acpi_db_display_handlers();
+               break;
+
+       case CMD_HELP:
+       case CMD_HELP2:
+
+               acpi_db_display_help(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_HISTORY:
+
+               acpi_db_display_history();
+               break;
+
+       case CMD_HISTORY_EXE:   /* ! command */
+
+               command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]);
+               if (!command_line) {
+                       return (AE_CTRL_TRUE);
+               }
+
+               status = acpi_db_command_dispatch(command_line, walk_state, op);
+               return (status);
+
+       case CMD_HISTORY_LAST:  /* !! command */
+
+               command_line = acpi_db_get_from_history(NULL);
+               if (!command_line) {
+                       return (AE_CTRL_TRUE);
+               }
+
+               status = acpi_db_command_dispatch(command_line, walk_state, op);
+               return (status);
+
+       case CMD_INFORMATION:
+
+               acpi_db_display_method_info(op);
+               break;
+
+       case CMD_INTEGRITY:
+
+               acpi_db_check_integrity();
+               break;
+
+       case CMD_INTO:
+
+               if (op) {
+                       acpi_gbl_cm_single_step = TRUE;
+                       return (AE_OK);
+               }
+               break;
+
+       case CMD_LEVEL:
+
+               if (param_count == 0) {
+                       acpi_os_printf
+                           ("Current debug level for file output is:    %8.8lX\n",
+                            acpi_gbl_db_debug_level);
+                       acpi_os_printf
+                           ("Current debug level for console output is: %8.8lX\n",
+                            acpi_gbl_db_console_debug_level);
+               } else if (param_count == 2) {
+                       temp = acpi_gbl_db_console_debug_level;
+                       acpi_gbl_db_console_debug_level =
+                           strtoul(acpi_gbl_db_args[1], NULL, 16);
+                       acpi_os_printf
+                           ("Debug Level for console output was %8.8lX, now %8.8lX\n",
+                            temp, acpi_gbl_db_console_debug_level);
+               } else {
+                       temp = acpi_gbl_db_debug_level;
+                       acpi_gbl_db_debug_level =
+                           strtoul(acpi_gbl_db_args[1], NULL, 16);
+                       acpi_os_printf
+                           ("Debug Level for file output was %8.8lX, now %8.8lX\n",
+                            temp, acpi_gbl_db_debug_level);
+               }
+               break;
+
+       case CMD_LIST:
+
+               acpi_db_disassemble_aml(acpi_gbl_db_args[1], op);
+               break;
+
+       case CMD_LOCKS:
+
+               acpi_db_display_locks();
+               break;
+
+       case CMD_LOCALS:
+
+               acpi_db_display_locals();
+               break;
+
+       case CMD_METHODS:
+
+               status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_NAMESPACE:
+
+               acpi_db_dump_namespace(acpi_gbl_db_args[1],
+                                      acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_NOTIFY:
+
+               temp = strtoul(acpi_gbl_db_args[2], NULL, 0);
+               acpi_db_send_notify(acpi_gbl_db_args[1], temp);
+               break;
+
+       case CMD_OBJECTS:
+
+               acpi_ut_strupr(acpi_gbl_db_args[1]);
+               status =
+                   acpi_db_display_objects(acpi_gbl_db_args[1],
+                                           acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_OSI:
+
+               acpi_db_display_interfaces(acpi_gbl_db_args[1],
+                                          acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_OWNER:
+
+               acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1],
+                                               acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_PATHS:
+
+               acpi_db_dump_namespace_paths();
+               break;
+
+       case CMD_PREFIX:
+
+               acpi_db_set_scope(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_REFERENCES:
+
+               acpi_db_find_references(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_RESOURCES:
+
+               acpi_db_display_resources(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_RESULTS:
+
+               acpi_db_display_results();
+               break;
+
+       case CMD_SET:
+
+               acpi_db_set_method_data(acpi_gbl_db_args[1],
+                                       acpi_gbl_db_args[2],
+                                       acpi_gbl_db_args[3]);
+               break;
+
+       case CMD_STATS:
+
+               status = acpi_db_display_statistics(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_STOP:
+
+               return (AE_NOT_IMPLEMENTED);
+
+       case CMD_TABLES:
+
+               acpi_db_display_table_info(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_TEMPLATE:
+
+               acpi_db_display_template(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_TRACE:
+
+               acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2],
+                             acpi_gbl_db_args[3]);
+               break;
+
+       case CMD_TREE:
+
+               acpi_db_display_calling_tree();
+               break;
+
+       case CMD_TYPE:
+
+               acpi_db_display_object_type(acpi_gbl_db_args[1]);
+               break;
+
+#ifdef ACPI_APPLICATION
+
+               /* Hardware simulation commands. */
+
+       case CMD_ENABLEACPI:
+#if (!ACPI_REDUCED_HARDWARE)
+
+               status = acpi_enable();
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("AcpiEnable failed (Status=%X)\n",
+                                      status);
+                       return (status);
+               }
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+               break;
+
+       case CMD_EVENT:
+
+               acpi_os_printf("Event command not implemented\n");
+               break;
+
+       case CMD_GPE:
+
+               acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
+               break;
+
+       case CMD_GPES:
+
+               acpi_db_display_gpes();
+               break;
+
+       case CMD_SCI:
+
+               acpi_db_generate_sci();
+               break;
+
+       case CMD_SLEEP:
+
+               status = acpi_db_sleep(acpi_gbl_db_args[1]);
+               break;
+
+               /* File I/O commands. */
+
+       case CMD_CLOSE:
+
+               acpi_db_close_debug_file();
+               break;
+
+       case CMD_LOAD:
+
+               status =
+                   acpi_db_get_table_from_file(acpi_gbl_db_args[1], NULL,
+                                               FALSE);
+               break;
+
+       case CMD_OPEN:
+
+               acpi_db_open_debug_file(acpi_gbl_db_args[1]);
+               break;
+
+               /* User space commands. */
+
+       case CMD_TERMINATE:
+
+               acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+               acpi_ut_subsystem_shutdown();
+
+               /*
+                * TBD: [Restructure] Need some way to re-initialize without
+                * re-creating the semaphores!
+                */
+
+               acpi_gbl_db_terminate_loop = TRUE;
+               /*  acpi_initialize (NULL); */
+               break;
+
+       case CMD_THREADS:
+
+               acpi_db_create_execution_threads(acpi_gbl_db_args[1],
+                                                acpi_gbl_db_args[2],
+                                                acpi_gbl_db_args[3]);
+               break;
+
+               /* Debug test commands. */
+
+       case CMD_PREDEFINED:
+
+               acpi_db_check_predefined_names();
+               break;
+
+       case CMD_TEST:
+
+               acpi_db_execute_test(acpi_gbl_db_args[1]);
+               break;
+
+       case CMD_UNLOAD:
+
+               acpi_db_unload_acpi_table(acpi_gbl_db_args[1]);
+               break;
+#endif
+
+       case CMD_EXIT:
+       case CMD_QUIT:
+
+               if (op) {
+                       acpi_os_printf("Method execution terminated\n");
+                       return (AE_CTRL_TERMINATE);
+               }
+
+               if (!acpi_gbl_db_output_to_file) {
+                       acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+               }
+#ifdef ACPI_APPLICATION
+               acpi_db_close_debug_file();
+#endif
+               acpi_gbl_db_terminate_loop = TRUE;
+               return (AE_CTRL_TERMINATE);
+
+       case CMD_NOT_FOUND:
+       default:
+
+               acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]);
+               return (AE_CTRL_TRUE);
+       }
+
+       if (ACPI_SUCCESS(status)) {
+               status = AE_CTRL_TRUE;
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_thread
+ *
+ * PARAMETERS:  context         - Not used
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context)
+{
+       acpi_status status = AE_OK;
+       acpi_status Mstatus;
+
+       while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
+               acpi_gbl_method_executing = FALSE;
+               acpi_gbl_step_to_next_call = FALSE;
+
+               Mstatus = acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+                                               ACPI_WAIT_FOREVER);
+               if (ACPI_FAILURE(Mstatus)) {
+                       return;
+               }
+
+               status =
+                   acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
+
+               acpi_os_release_mutex(acpi_gbl_db_command_complete);
+       }
+       acpi_gbl_db_threads_terminated = TRUE;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_single_thread
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void acpi_db_single_thread(void)
+{
+
+       acpi_gbl_method_executing = FALSE;
+       acpi_gbl_step_to_next_call = FALSE;
+
+       (void)acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_user_commands
+ *
+ * PARAMETERS:  prompt              - User prompt (depends on mode)
+ *              op                  - Current executing parse op
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger. Commands are
+ *              matched and dispatched here.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
+{
+       acpi_status status = AE_OK;
+
+       acpi_os_printf("\n");
+
+       /* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+       while (!acpi_gbl_db_terminate_loop) {
+
+               /* Force output to console until a command is entered */
+
+               acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+               /* Different prompt if method is executing */
+
+               if (!acpi_gbl_method_executing) {
+                       acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+               } else {
+                       acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+               }
+
+               /* Get the user input line */
+
+               status = acpi_os_get_line(acpi_gbl_db_line_buf,
+                                         ACPI_DB_LINE_BUFFER_SIZE, NULL);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_EXCEPTION((AE_INFO, status,
+                                       "While parsing command line"));
+                       return (status);
+               }
+
+               /* Check for single or multithreaded debug */
+
+               if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+                       /*
+                        * Signal the debug thread that we have a command to execute,
+                        * and wait for the command to complete.
+                        */
+                       acpi_os_release_mutex(acpi_gbl_db_command_ready);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+
+                       status =
+                           acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
+                                                 ACPI_WAIT_FOREVER);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+               } else {
+                       /* Just call to the command line interpreter */
+
+                       acpi_db_single_thread();
+               }
+       }
+
+       return (status);
+}
diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c
new file mode 100644 (file)
index 0000000..01e5a71
--- /dev/null
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ *
+ * Module Name: dbmethod - Debug commands for control methods
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdispat.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "acparser.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbmethod")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_breakpoint
+ *
+ * PARAMETERS:  location            - AML offset of breakpoint
+ *              walk_state          - Current walk info
+ *              op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+void
+acpi_db_set_method_breakpoint(char *location,
+                             struct acpi_walk_state *walk_state,
+                             union acpi_parse_object *op)
+{
+       u32 address;
+       u32 aml_offset;
+
+       if (!op) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       /* Get and verify the breakpoint address */
+
+       address = strtoul(location, NULL, 16);
+       aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
+                                       walk_state->parser_state.aml_start);
+       if (address <= aml_offset) {
+               acpi_os_printf("Breakpoint %X is beyond current address %X\n",
+                              address, aml_offset);
+       }
+
+       /* Save breakpoint in current walk */
+
+       walk_state->user_breakpoint = address;
+       acpi_os_printf("Breakpoint set at AML offset %X\n", address);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_call_breakpoint
+ *
+ * PARAMETERS:  op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ *              AML offset
+ *
+ ******************************************************************************/
+
+void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op)
+{
+
+       if (!op) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       acpi_gbl_step_to_next_call = TRUE;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_method_data
+ *
+ * PARAMETERS:  type_arg        - L for local, A for argument
+ *              index_arg       - which one
+ *              value_arg       - Value to set.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set a local or argument for the running control method.
+ *              NOTE: only object supported is Number.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg)
+{
+       char type;
+       u32 index;
+       u32 value;
+       struct acpi_walk_state *walk_state;
+       union acpi_operand_object *obj_desc;
+       acpi_status status;
+       struct acpi_namespace_node *node;
+
+       /* Validate type_arg */
+
+       acpi_ut_strupr(type_arg);
+       type = type_arg[0];
+       if ((type != 'L') && (type != 'A') && (type != 'N')) {
+               acpi_os_printf("Invalid SET operand: %s\n", type_arg);
+               return;
+       }
+
+       value = strtoul(value_arg, NULL, 16);
+
+       if (type == 'N') {
+               node = acpi_db_convert_to_node(index_arg);
+               if (!node) {
+                       return;
+               }
+
+               if (node->type != ACPI_TYPE_INTEGER) {
+                       acpi_os_printf("Can only set Integer nodes\n");
+                       return;
+               }
+               obj_desc = node->object;
+               obj_desc->integer.value = value;
+               return;
+       }
+
+       /* Get the index and value */
+
+       index = strtoul(index_arg, NULL, 16);
+
+       walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list);
+       if (!walk_state) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       /* Create and initialize the new object */
+
+       obj_desc = acpi_ut_create_integer_object((u64)value);
+       if (!obj_desc) {
+               acpi_os_printf("Could not create an internal object\n");
+               return;
+       }
+
+       /* Store the new object into the target */
+
+       switch (type) {
+       case 'A':
+
+               /* Set a method argument */
+
+               if (index > ACPI_METHOD_MAX_ARG) {
+                       acpi_os_printf("Arg%u - Invalid argument name\n",
+                                      index);
+                       goto cleanup;
+               }
+
+               status = acpi_ds_store_object_to_local(ACPI_REFCLASS_ARG,
+                                                      index, obj_desc,
+                                                      walk_state);
+               if (ACPI_FAILURE(status)) {
+                       goto cleanup;
+               }
+
+               obj_desc = walk_state->arguments[index].object;
+
+               acpi_os_printf("Arg%u: ", index);
+               acpi_db_display_internal_object(obj_desc, walk_state);
+               break;
+
+       case 'L':
+
+               /* Set a method local */
+
+               if (index > ACPI_METHOD_MAX_LOCAL) {
+                       acpi_os_printf
+                           ("Local%u - Invalid local variable name\n", index);
+                       goto cleanup;
+               }
+
+               status = acpi_ds_store_object_to_local(ACPI_REFCLASS_LOCAL,
+                                                      index, obj_desc,
+                                                      walk_state);
+               if (ACPI_FAILURE(status)) {
+                       goto cleanup;
+               }
+
+               obj_desc = walk_state->local_variables[index].object;
+
+               acpi_os_printf("Local%u: ", index);
+               acpi_db_display_internal_object(obj_desc, walk_state);
+               break;
+
+       default:
+
+               break;
+       }
+
+cleanup:
+       acpi_ut_remove_reference(obj_desc);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_disassemble_aml
+ *
+ * PARAMETERS:  statements          - Number of statements to disassemble
+ *              op                  - Current Op (from parse walk)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ *              of statements specified.
+ *
+ ******************************************************************************/
+
+void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op)
+{
+       u32 num_statements = 8;
+
+       if (!op) {
+               acpi_os_printf("There is no method currently executing\n");
+               return;
+       }
+
+       if (statements) {
+               num_statements = strtoul(statements, NULL, 0);
+       }
+#ifdef ACPI_DISASSEMBLER
+       acpi_dm_disassemble(NULL, op, num_statements);
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_disassemble_method
+ *
+ * PARAMETERS:  name            - Name of control method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ *              of statements specified.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_disassemble_method(char *name)
+{
+       acpi_status status;
+       union acpi_parse_object *op;
+       struct acpi_walk_state *walk_state;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *method;
+
+       method = acpi_db_convert_to_node(name);
+       if (!method) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       if (method->type != ACPI_TYPE_METHOD) {
+               ACPI_ERROR((AE_INFO, "%s (%s): Object must be a control method",
+                           name, acpi_ut_get_type_name(method->type)));
+               return (AE_BAD_PARAMETER);
+       }
+
+       obj_desc = method->object;
+
+       op = acpi_ps_create_scope_op(obj_desc->method.aml_start);
+       if (!op) {
+               return (AE_NO_MEMORY);
+       }
+
+       /* Create and initialize a new walk state */
+
+       walk_state = acpi_ds_create_walk_state(0, op, NULL, NULL);
+       if (!walk_state) {
+               return (AE_NO_MEMORY);
+       }
+
+       status = acpi_ds_init_aml_walk(walk_state, op, NULL,
+                                      obj_desc->method.aml_start,
+                                      obj_desc->method.aml_length, NULL,
+                                      ACPI_IMODE_LOAD_PASS1);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
+       walk_state->owner_id = obj_desc->method.owner_id;
+
+       /* Push start scope on scope stack and make it current */
+
+       status = acpi_ds_scope_stack_push(method, method->type, walk_state);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       /* Parse the entire method AML including deferred operators */
+
+       walk_state->parse_flags &= ~ACPI_PARSE_DELETE_TREE;
+       walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE;
+
+       status = acpi_ps_parse_aml(walk_state);
+
+#ifdef ACPI_DISASSEMBLER
+       (void)acpi_dm_parse_deferred_ops(op);
+
+       /* Now we can disassemble the method */
+
+       acpi_gbl_dm_opt_verbose = FALSE;
+       acpi_dm_disassemble(NULL, op, 0);
+       acpi_gbl_dm_opt_verbose = TRUE;
+#endif
+
+       acpi_ps_delete_parse_tree(op);
+
+       /* Method cleanup */
+
+       acpi_ns_delete_namespace_subtree(method);
+       acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
+       acpi_ut_release_owner_id(&obj_desc->method.owner_id);
+       return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c
new file mode 100644 (file)
index 0000000..04ff1eb
--- /dev/null
@@ -0,0 +1,947 @@
+/*******************************************************************************
+ *
+ * Module Name: dbnames - Debugger commands for the acpi namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acnamesp.h"
+#include "acdebug.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbnames")
+
+/* Local prototypes */
+static acpi_status
+acpi_db_walk_and_match_name(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_object_counts(acpi_handle obj_handle,
+                              u32 nesting_level,
+                              void *context, void **return_value);
+
+static acpi_status
+acpi_db_integrity_walk(acpi_handle obj_handle,
+                      u32 nesting_level, void *context, void **return_value);
+
+static acpi_status
+acpi_db_walk_for_references(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value);
+
+static acpi_status
+acpi_db_bus_walk(acpi_handle obj_handle,
+                u32 nesting_level, void *context, void **return_value);
+
+/*
+ * Arguments for the Objects command
+ * These object types map directly to the ACPI_TYPES
+ */
+static struct acpi_db_argument_info acpi_db_object_types[] = {
+       {"ANY"},
+       {"INTEGERS"},
+       {"STRINGS"},
+       {"BUFFERS"},
+       {"PACKAGES"},
+       {"FIELDS"},
+       {"DEVICES"},
+       {"EVENTS"},
+       {"METHODS"},
+       {"MUTEXES"},
+       {"REGIONS"},
+       {"POWERRESOURCES"},
+       {"PROCESSORS"},
+       {"THERMALZONES"},
+       {"BUFFERFIELDS"},
+       {"DDBHANDLES"},
+       {"DEBUG"},
+       {"REGIONFIELDS"},
+       {"BANKFIELDS"},
+       {"INDEXFIELDS"},
+       {"REFERENCES"},
+       {"ALIASES"},
+       {"METHODALIASES"},
+       {"NOTIFY"},
+       {"ADDRESSHANDLER"},
+       {"RESOURCE"},
+       {"RESOURCEFIELD"},
+       {"SCOPES"},
+       {NULL}                  /* Must be null terminated */
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_scope
+ *
+ * PARAMETERS:  name                - New scope path
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Set the "current scope" as maintained by this utility.
+ *              The scope is used as a prefix to ACPI paths.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_scope(char *name)
+{
+       acpi_status status;
+       struct acpi_namespace_node *node;
+
+       if (!name || name[0] == 0) {
+               acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
+               return;
+       }
+
+       acpi_db_prep_namestring(name);
+
+       if (ACPI_IS_ROOT_PREFIX(name[0])) {
+
+               /* Validate new scope from the root */
+
+               status = acpi_ns_get_node(acpi_gbl_root_node, name,
+                                         ACPI_NS_NO_UPSEARCH, &node);
+               if (ACPI_FAILURE(status)) {
+                       goto error_exit;
+               }
+
+               acpi_gbl_db_scope_buf[0] = 0;
+       } else {
+               /* Validate new scope relative to old scope */
+
+               status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
+                                         ACPI_NS_NO_UPSEARCH, &node);
+               if (ACPI_FAILURE(status)) {
+                       goto error_exit;
+               }
+       }
+
+       /* Build the final pathname */
+
+       if (acpi_ut_safe_strcat
+           (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
+               status = AE_BUFFER_OVERFLOW;
+               goto error_exit;
+       }
+
+       if (acpi_ut_safe_strcat
+           (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
+               status = AE_BUFFER_OVERFLOW;
+               goto error_exit;
+       }
+
+       acpi_gbl_db_scope_node = node;
+       acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
+       return;
+
+error_exit:
+
+       acpi_os_printf("Could not attach scope: %s, %s\n",
+                      name, acpi_format_exception(status));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace
+ *
+ * PARAMETERS:  start_arg       - Node to begin namespace dump
+ *              depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
+ *              with type and other information.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
+{
+       acpi_handle subtree_entry = acpi_gbl_root_node;
+       u32 max_depth = ACPI_UINT32_MAX;
+
+       /* No argument given, just start at the root and dump entire namespace */
+
+       if (start_arg) {
+               subtree_entry = acpi_db_convert_to_node(start_arg);
+               if (!subtree_entry) {
+                       return;
+               }
+
+               /* Now we can check for the depth argument */
+
+               if (depth_arg) {
+                       max_depth = strtoul(depth_arg, NULL, 0);
+               }
+       }
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
+                      ((struct acpi_namespace_node *)subtree_entry)->name.
+                      ascii, subtree_entry);
+
+       /* Display the subtree */
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
+                            ACPI_OWNER_ID_MAX, subtree_entry);
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace_paths
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump entire namespace with full object pathnames and object
+ *              type information. Alternative to "namespace" command.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace_paths(void)
+{
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf("ACPI Namespace (from root):\n");
+
+       /* Display the entire namespace */
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
+                                 ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
+                                 acpi_gbl_root_node);
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_namespace_by_owner
+ *
+ * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
+ *              depth_arg       - Maximum tree depth to be dumped
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
+{
+       acpi_handle subtree_entry = acpi_gbl_root_node;
+       u32 max_depth = ACPI_UINT32_MAX;
+       acpi_owner_id owner_id;
+
+       owner_id = (acpi_owner_id) strtoul(owner_arg, NULL, 0);
+
+       /* Now we can check for the depth argument */
+
+       if (depth_arg) {
+               max_depth = strtoul(depth_arg, NULL, 0);
+       }
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
+
+       /* Display the subtree */
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+       acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
+                            owner_id, subtree_entry);
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_and_match_name
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
+ *              are supported -- '?' matches any character.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_and_match_name(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value)
+{
+       acpi_status status;
+       char *requested_name = (char *)context;
+       u32 i;
+       struct acpi_buffer buffer;
+       struct acpi_walk_info info;
+
+       /* Check for a name match */
+
+       for (i = 0; i < 4; i++) {
+
+               /* Wildcard support */
+
+               if ((requested_name[i] != '?') &&
+                   (requested_name[i] != ((struct acpi_namespace_node *)
+                                          obj_handle)->name.ascii[i])) {
+
+                       /* No match, just exit */
+
+                       return (AE_OK);
+               }
+       }
+
+       /* Get the full pathname to this object */
+
+       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could Not get pathname for object %p\n",
+                              obj_handle);
+       } else {
+               info.owner_id = ACPI_OWNER_ID_MAX;
+               info.debug_level = ACPI_UINT32_MAX;
+               info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+               acpi_os_printf("%32s", (char *)buffer.pointer);
+               (void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
+                                             NULL);
+               ACPI_FREE(buffer.pointer);
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_find_name_in_namespace
+ *
+ * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
+ *                                wildcards are supported.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search the namespace for a given name (with wildcards)
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_find_name_in_namespace(char *name_arg)
+{
+       char acpi_name[5] = "____";
+       char *acpi_name_ptr = acpi_name;
+
+       if (strlen(name_arg) > ACPI_NAME_SIZE) {
+               acpi_os_printf("Name must be no longer than 4 characters\n");
+               return (AE_OK);
+       }
+
+       /* Pad out name with underscores as necessary to create a 4-char name */
+
+       acpi_ut_strupr(name_arg);
+       while (*name_arg) {
+               *acpi_name_ptr = *name_arg;
+               acpi_name_ptr++;
+               name_arg++;
+       }
+
+       /* Walk the namespace from the root */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
+                                 NULL, acpi_name, NULL);
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_predefined_names
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Detect and display predefined ACPI names (names that start with
+ *              an underscore)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value)
+{
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+       u32 *count = (u32 *)context;
+       const union acpi_predefined_info *predefined;
+       const union acpi_predefined_info *package = NULL;
+       char *pathname;
+       char string_buffer[48];
+
+       predefined = acpi_ut_match_predefined_method(node->name.ascii);
+       if (!predefined) {
+               return (AE_OK);
+       }
+
+       pathname = acpi_ns_get_external_pathname(node);
+       if (!pathname) {
+               return (AE_OK);
+       }
+
+       /* If method returns a package, the info is in the next table entry */
+
+       if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
+               package = predefined + 1;
+       }
+
+       acpi_ut_get_expected_return_types(string_buffer,
+                                         predefined->info.expected_btypes);
+
+       acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
+                      METHOD_GET_ARG_COUNT(predefined->info.argument_list),
+                      string_buffer);
+
+       if (package) {
+               acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
+                              package->ret_info.type,
+                              package->ret_info.object_type1,
+                              package->ret_info.count1);
+       }
+
+       acpi_os_printf("\n");
+
+       /* Check that the declared argument count matches the ACPI spec */
+
+       acpi_ns_check_acpi_compliance(pathname, node, predefined);
+
+       ACPI_FREE(pathname);
+       (*count)++;
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_check_predefined_names
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Validate all predefined names in the namespace
+ *
+ ******************************************************************************/
+
+void acpi_db_check_predefined_names(void)
+{
+       u32 count = 0;
+
+       /* Search all nodes in namespace */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX,
+                                 acpi_db_walk_for_predefined_names, NULL,
+                                 (void *)&count, NULL);
+
+       acpi_os_printf("Found %u predefined names in the namespace\n", count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_object_counts
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_object_counts(acpi_handle obj_handle,
+                              u32 nesting_level,
+                              void *context, void **return_value)
+{
+       struct acpi_object_info *info = (struct acpi_object_info *)context;
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+
+       if (node->type > ACPI_TYPE_NS_NODE_MAX) {
+               acpi_os_printf("[%4.4s]: Unknown object type %X\n",
+                              node->name.ascii, node->type);
+       } else {
+               info->types[node->type]++;
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_specific_objects
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
+                                 u32 nesting_level,
+                                 void *context, void **return_value)
+{
+       struct acpi_walk_info *info = (struct acpi_walk_info *)context;
+       struct acpi_buffer buffer;
+       acpi_status status;
+
+       info->count++;
+
+       /* Get and display the full pathname to this object */
+
+       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could Not get pathname for object %p\n",
+                              obj_handle);
+               return (AE_OK);
+       }
+
+       acpi_os_printf("%32s", (char *)buffer.pointer);
+       ACPI_FREE(buffer.pointer);
+
+       /* Dump short info about the object */
+
+       (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_objects
+ *
+ * PARAMETERS:  obj_type_arg        - Type of object to display
+ *              display_count_arg   - Max depth to display
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display objects in the namespace of the requested type
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
+{
+       struct acpi_walk_info info;
+       acpi_object_type type;
+       struct acpi_object_info *object_info;
+       u32 i;
+       u32 total_objects = 0;
+
+       /* No argument means display summary/count of all object types */
+
+       if (!obj_type_arg) {
+               object_info =
+                   ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
+
+               /* Walk the namespace from the root */
+
+               (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                         ACPI_UINT32_MAX,
+                                         acpi_db_walk_for_object_counts, NULL,
+                                         (void *)object_info, NULL);
+
+               acpi_os_printf("\nSummary of namespace objects:\n\n");
+
+               for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
+                       acpi_os_printf("%8u %s\n", object_info->types[i],
+                                      acpi_ut_get_type_name(i));
+
+                       total_objects += object_info->types[i];
+               }
+
+               acpi_os_printf("\n%8u Total namespace objects\n\n",
+                              total_objects);
+
+               ACPI_FREE(object_info);
+               return (AE_OK);
+       }
+
+       /* Get the object type */
+
+       type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
+       if (type == ACPI_TYPE_NOT_FOUND) {
+               acpi_os_printf("Invalid or unsupported argument\n");
+               return (AE_OK);
+       }
+
+       acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
+       acpi_os_printf
+           ("Objects of type [%s] defined in the current ACPI Namespace:\n",
+            acpi_ut_get_type_name(type));
+
+       acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+
+       info.count = 0;
+       info.owner_id = ACPI_OWNER_ID_MAX;
+       info.debug_level = ACPI_UINT32_MAX;
+       info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+       /* Walk the namespace from the root */
+
+       (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+                                 acpi_db_walk_for_specific_objects, NULL,
+                                 (void *)&info, NULL);
+
+       acpi_os_printf
+           ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
+            info.count, acpi_ut_get_type_name(type));
+
+       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_integrity_walk
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Examine one NS node for valid values.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_integrity_walk(acpi_handle obj_handle,
+                      u32 nesting_level, void *context, void **return_value)
+{
+       struct acpi_integrity_info *info =
+           (struct acpi_integrity_info *)context;
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+       union acpi_operand_object *object;
+       u8 alias = TRUE;
+
+       info->nodes++;
+
+       /* Verify the NS node, and dereference aliases */
+
+       while (alias) {
+               if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+                       acpi_os_printf
+                           ("Invalid Descriptor Type for Node %p [%s] - "
+                            "is %2.2X should be %2.2X\n", node,
+                            acpi_ut_get_descriptor_name(node),
+                            ACPI_GET_DESCRIPTOR_TYPE(node),
+                            ACPI_DESC_TYPE_NAMED);
+                       return (AE_OK);
+               }
+
+               if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
+                   (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
+                       node = (struct acpi_namespace_node *)node->object;
+               } else {
+                       alias = FALSE;
+               }
+       }
+
+       if (node->type > ACPI_TYPE_LOCAL_MAX) {
+               acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
+                              node, node->type);
+               return (AE_OK);
+       }
+
+       if (!acpi_ut_valid_acpi_name(node->name.ascii)) {
+               acpi_os_printf("Invalid AcpiName for Node %p\n", node);
+               return (AE_OK);
+       }
+
+       object = acpi_ns_get_attached_object(node);
+       if (object) {
+               info->objects++;
+               if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
+                       acpi_os_printf
+                           ("Invalid Descriptor Type for Object %p [%s]\n",
+                            object, acpi_ut_get_descriptor_name(object));
+               }
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_check_integrity
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check entire namespace for data structure integrity
+ *
+ ******************************************************************************/
+
+void acpi_db_check_integrity(void)
+{
+       struct acpi_integrity_info info = { 0, 0 };
+
+       /* Search all nodes in namespace */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
+                                 (void *)&info, NULL);
+
+       acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
+                      info.nodes, info.objects);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_walk_for_references
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check if this namespace object refers to the target object
+ *              that is passed in as the context value.
+ *
+ * Note: Currently doesn't check subobjects within the Node's object
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_walk_for_references(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value)
+{
+       union acpi_operand_object *obj_desc =
+           (union acpi_operand_object *)context;
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+
+       /* Check for match against the namespace node itself */
+
+       if (node == (void *)obj_desc) {
+               acpi_os_printf("Object is a Node [%4.4s]\n",
+                              acpi_ut_get_node_name(node));
+       }
+
+       /* Check for match against the object attached to the node */
+
+       if (acpi_ns_get_attached_object(node) == obj_desc) {
+               acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
+                              node, acpi_ut_get_node_name(node));
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_find_references
+ *
+ * PARAMETERS:  object_arg      - String with hex value of the object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Search namespace for all references to the input object
+ *
+ ******************************************************************************/
+
+void acpi_db_find_references(char *object_arg)
+{
+       union acpi_operand_object *obj_desc;
+       acpi_size address;
+
+       /* Convert string to object pointer */
+
+       address = strtoul(object_arg, NULL, 16);
+       obj_desc = ACPI_TO_POINTER(address);
+
+       /* Search all nodes in namespace */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX, acpi_db_walk_for_references,
+                                 NULL, (void *)obj_desc, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_bus_walk
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display info about device objects that have a corresponding
+ *              _PRT method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_bus_walk(acpi_handle obj_handle,
+                u32 nesting_level, void *context, void **return_value)
+{
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+       acpi_status status;
+       struct acpi_buffer buffer;
+       struct acpi_namespace_node *temp_node;
+       struct acpi_device_info *info;
+       u32 i;
+
+       if ((node->type != ACPI_TYPE_DEVICE) &&
+           (node->type != ACPI_TYPE_PROCESSOR)) {
+               return (AE_OK);
+       }
+
+       /* Exit if there is no _PRT under this device */
+
+       status = acpi_get_handle(node, METHOD_NAME__PRT,
+                                ACPI_CAST_PTR(acpi_handle, &temp_node));
+       if (ACPI_FAILURE(status)) {
+               return (AE_OK);
+       }
+
+       /* Get the full path to this device object */
+
+       buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+       status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could Not get pathname for object %p\n",
+                              obj_handle);
+               return (AE_OK);
+       }
+
+       status = acpi_get_object_info(obj_handle, &info);
+       if (ACPI_FAILURE(status)) {
+               return (AE_OK);
+       }
+
+       /* Display the full path */
+
+       acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
+       ACPI_FREE(buffer.pointer);
+
+       if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
+               acpi_os_printf(" - Is PCI Root Bridge");
+       }
+       acpi_os_printf("\n");
+
+       /* _PRT info */
+
+       acpi_os_printf("_PRT: %p\n", temp_node);
+
+       /* Dump _ADR, _HID, _UID, _CID */
+
+       if (info->valid & ACPI_VALID_ADR) {
+               acpi_os_printf("_ADR: %8.8X%8.8X\n",
+                              ACPI_FORMAT_UINT64(info->address));
+       } else {
+               acpi_os_printf("_ADR: <Not Present>\n");
+       }
+
+       if (info->valid & ACPI_VALID_HID) {
+               acpi_os_printf("_HID: %s\n", info->hardware_id.string);
+       } else {
+               acpi_os_printf("_HID: <Not Present>\n");
+       }
+
+       if (info->valid & ACPI_VALID_UID) {
+               acpi_os_printf("_UID: %s\n", info->unique_id.string);
+       } else {
+               acpi_os_printf("_UID: <Not Present>\n");
+       }
+
+       if (info->valid & ACPI_VALID_CID) {
+               for (i = 0; i < info->compatible_id_list.count; i++) {
+                       acpi_os_printf("_CID: %s\n",
+                                      info->compatible_id_list.ids[i].string);
+               }
+       } else {
+               acpi_os_printf("_CID: <Not Present>\n");
+       }
+
+       ACPI_FREE(info);
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_get_bus_info
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display info about system busses.
+ *
+ ******************************************************************************/
+
+void acpi_db_get_bus_info(void)
+{
+       /* Search all nodes in namespace */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
+                                 NULL);
+}
diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c
new file mode 100644 (file)
index 0000000..116f6db
--- /dev/null
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ *
+ * Module Name: dbobject - ACPI object decode and display
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acnamesp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbobject")
+
+/* Local prototypes */
+static void acpi_db_decode_node(struct acpi_namespace_node *node);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_method_info
+ *
+ * PARAMETERS:  status          - Method execution status
+ *              walk_state      - Current state of the parse tree walk
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ *              Dumps the method execution stack, and the method locals/args,
+ *              and disassembles the AML opcode that failed.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_dump_method_info(acpi_status status, struct acpi_walk_state *walk_state)
+{
+       struct acpi_thread_state *thread;
+
+       /* Ignore control codes, they are not errors */
+
+       if ((status & AE_CODE_MASK) == AE_CODE_CONTROL) {
+               return;
+       }
+
+       /* We may be executing a deferred opcode */
+
+       if (walk_state->deferred_node) {
+               acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+               return;
+       }
+
+       /*
+        * If there is no Thread, we are not actually executing a method.
+        * This can happen when the iASL compiler calls the interpreter
+        * to perform constant folding.
+        */
+       thread = walk_state->thread;
+       if (!thread) {
+               return;
+       }
+
+       /* Display the method locals and arguments */
+
+       acpi_os_printf("\n");
+       acpi_db_decode_locals(walk_state);
+       acpi_os_printf("\n");
+       acpi_db_decode_arguments(walk_state);
+       acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_internal_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
+{
+       u32 i;
+
+       if (!obj_desc) {
+               acpi_os_printf(" Uninitialized");
+               return;
+       }
+
+       if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+               acpi_os_printf(" %p [%s]", obj_desc,
+                              acpi_ut_get_descriptor_name(obj_desc));
+               return;
+       }
+
+       acpi_os_printf(" %s", acpi_ut_get_object_type_name(obj_desc));
+
+       switch (obj_desc->common.type) {
+       case ACPI_TYPE_INTEGER:
+
+               acpi_os_printf(" %8.8X%8.8X",
+                              ACPI_FORMAT_UINT64(obj_desc->integer.value));
+               break;
+
+       case ACPI_TYPE_STRING:
+
+               acpi_os_printf("(%u) \"%.24s",
+                              obj_desc->string.length,
+                              obj_desc->string.pointer);
+
+               if (obj_desc->string.length > 24) {
+                       acpi_os_printf("...");
+               } else {
+                       acpi_os_printf("\"");
+               }
+               break;
+
+       case ACPI_TYPE_BUFFER:
+
+               acpi_os_printf("(%u)", obj_desc->buffer.length);
+               for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) {
+                       acpi_os_printf(" %2.2X", obj_desc->buffer.pointer[i]);
+               }
+               break;
+
+       default:
+
+               acpi_os_printf(" %p", obj_desc);
+               break;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_node
+ *
+ * PARAMETERS:  node        - Object to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of a namespace node
+ *
+ ******************************************************************************/
+
+static void acpi_db_decode_node(struct acpi_namespace_node *node)
+{
+
+       acpi_os_printf("<Node>          Name %4.4s",
+                      acpi_ut_get_node_name(node));
+
+       if (node->flags & ANOBJ_METHOD_ARG) {
+               acpi_os_printf(" [Method Arg]");
+       }
+       if (node->flags & ANOBJ_METHOD_LOCAL) {
+               acpi_os_printf(" [Method Local]");
+       }
+
+       switch (node->type) {
+
+               /* These types have no attached object */
+
+       case ACPI_TYPE_DEVICE:
+
+               acpi_os_printf(" Device");
+               break;
+
+       case ACPI_TYPE_THERMAL:
+
+               acpi_os_printf(" Thermal Zone");
+               break;
+
+       default:
+
+               acpi_db_decode_internal_object(acpi_ns_get_attached_object
+                                              (node));
+               break;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_internal_object
+ *
+ * PARAMETERS:  obj_desc        - Object to be displayed
+ *              walk_state      - Current walk state
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Short display of an internal object
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_internal_object(union acpi_operand_object *obj_desc,
+                               struct acpi_walk_state *walk_state)
+{
+       u8 type;
+
+       acpi_os_printf("%p ", obj_desc);
+
+       if (!obj_desc) {
+               acpi_os_printf("<Null Object>\n");
+               return;
+       }
+
+       /* Decode the object type */
+
+       switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
+       case ACPI_DESC_TYPE_PARSER:
+
+               acpi_os_printf("<Parser> ");
+               break;
+
+       case ACPI_DESC_TYPE_NAMED:
+
+               acpi_db_decode_node((struct acpi_namespace_node *)obj_desc);
+               break;
+
+       case ACPI_DESC_TYPE_OPERAND:
+
+               type = obj_desc->common.type;
+               if (type > ACPI_TYPE_LOCAL_MAX) {
+                       acpi_os_printf(" Type %X [Invalid Type]", (u32)type);
+                       return;
+               }
+
+               /* Decode the ACPI object type */
+
+               switch (obj_desc->common.type) {
+               case ACPI_TYPE_LOCAL_REFERENCE:
+
+                       acpi_os_printf("[%s] ",
+                                      acpi_ut_get_reference_name(obj_desc));
+
+                       /* Decode the refererence */
+
+                       switch (obj_desc->reference.class) {
+                       case ACPI_REFCLASS_LOCAL:
+
+                               acpi_os_printf("%X ",
+                                              obj_desc->reference.value);
+                               if (walk_state) {
+                                       obj_desc = walk_state->local_variables
+                                           [obj_desc->reference.value].object;
+                                       acpi_os_printf("%p", obj_desc);
+                                       acpi_db_decode_internal_object
+                                           (obj_desc);
+                               }
+                               break;
+
+                       case ACPI_REFCLASS_ARG:
+
+                               acpi_os_printf("%X ",
+                                              obj_desc->reference.value);
+                               if (walk_state) {
+                                       obj_desc = walk_state->arguments
+                                           [obj_desc->reference.value].object;
+                                       acpi_os_printf("%p", obj_desc);
+                                       acpi_db_decode_internal_object
+                                           (obj_desc);
+                               }
+                               break;
+
+                       case ACPI_REFCLASS_INDEX:
+
+                               switch (obj_desc->reference.target_type) {
+                               case ACPI_TYPE_BUFFER_FIELD:
+
+                                       acpi_os_printf("%p",
+                                                      obj_desc->reference.
+                                                      object);
+                                       acpi_db_decode_internal_object
+                                           (obj_desc->reference.object);
+                                       break;
+
+                               case ACPI_TYPE_PACKAGE:
+
+                                       acpi_os_printf("%p",
+                                                      obj_desc->reference.
+                                                      where);
+                                       if (!obj_desc->reference.where) {
+                                               acpi_os_printf
+                                                   (" Uninitialized WHERE pointer");
+                                       } else {
+                                               acpi_db_decode_internal_object(*
+                                                                              (obj_desc->
+                                                                               reference.
+                                                                               where));
+                                       }
+                                       break;
+
+                               default:
+
+                                       acpi_os_printf
+                                           ("Unknown index target type");
+                                       break;
+                               }
+                               break;
+
+                       case ACPI_REFCLASS_REFOF:
+
+                               if (!obj_desc->reference.object) {
+                                       acpi_os_printf
+                                           ("Uninitialized reference subobject pointer");
+                                       break;
+                               }
+
+                               /* Reference can be to a Node or an Operand object */
+
+                               switch (ACPI_GET_DESCRIPTOR_TYPE
+                                       (obj_desc->reference.object)) {
+                               case ACPI_DESC_TYPE_NAMED:
+
+                                       acpi_db_decode_node(obj_desc->reference.
+                                                           object);
+                                       break;
+
+                               case ACPI_DESC_TYPE_OPERAND:
+
+                                       acpi_db_decode_internal_object
+                                           (obj_desc->reference.object);
+                                       break;
+
+                               default:
+                                       break;
+                               }
+                               break;
+
+                       case ACPI_REFCLASS_NAME:
+
+                               acpi_db_decode_node(obj_desc->reference.node);
+                               break;
+
+                       case ACPI_REFCLASS_DEBUG:
+                       case ACPI_REFCLASS_TABLE:
+
+                               acpi_os_printf("\n");
+                               break;
+
+                       default:        /* Unknown reference class */
+
+                               acpi_os_printf("%2.2X\n",
+                                              obj_desc->reference.class);
+                               break;
+                       }
+                       break;
+
+               default:
+
+                       acpi_os_printf("<Obj>          ");
+                       acpi_db_decode_internal_object(obj_desc);
+                       break;
+               }
+               break;
+
+       default:
+
+               acpi_os_printf("<Not a valid ACPI Object Descriptor> [%s]",
+                              acpi_ut_get_descriptor_name(obj_desc));
+               break;
+       }
+
+       acpi_os_printf("\n");
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_locals
+ *
+ * PARAMETERS:  walk_state      - State for current method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_locals(struct acpi_walk_state *walk_state)
+{
+       u32 i;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node;
+       u8 display_locals = FALSE;
+
+       obj_desc = walk_state->method_desc;
+       node = walk_state->method_node;
+
+       if (!node) {
+               acpi_os_printf
+                   ("No method node (Executing subtree for buffer or opregion)\n");
+               return;
+       }
+
+       if (node->type != ACPI_TYPE_METHOD) {
+               acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+               return;
+       }
+
+       /* Are any locals actually set? */
+
+       for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
+               obj_desc = walk_state->local_variables[i].object;
+               if (obj_desc) {
+                       display_locals = TRUE;
+                       break;
+               }
+       }
+
+       /* If any are set, only display the ones that are set */
+
+       if (display_locals) {
+               acpi_os_printf
+                   ("\nInitialized Local Variables for method [%4.4s]:\n",
+                    acpi_ut_get_node_name(node));
+
+               for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
+                       obj_desc = walk_state->local_variables[i].object;
+                       if (obj_desc) {
+                               acpi_os_printf("  Local%X: ", i);
+                               acpi_db_display_internal_object(obj_desc,
+                                                               walk_state);
+                       }
+               }
+       } else {
+               acpi_os_printf
+                   ("No Local Variables are initialized for method [%4.4s]\n",
+                    acpi_ut_get_node_name(node));
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_decode_arguments
+ *
+ * PARAMETERS:  walk_state      - State for current method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void acpi_db_decode_arguments(struct acpi_walk_state *walk_state)
+{
+       u32 i;
+       union acpi_operand_object *obj_desc;
+       struct acpi_namespace_node *node;
+       u8 display_args = FALSE;
+
+       node = walk_state->method_node;
+       obj_desc = walk_state->method_desc;
+
+       if (!node) {
+               acpi_os_printf
+                   ("No method node (Executing subtree for buffer or opregion)\n");
+               return;
+       }
+
+       if (node->type != ACPI_TYPE_METHOD) {
+               acpi_os_printf("Executing subtree for Buffer/Package/Region\n");
+               return;
+       }
+
+       /* Are any arguments actually set? */
+
+       for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
+               obj_desc = walk_state->arguments[i].object;
+               if (obj_desc) {
+                       display_args = TRUE;
+                       break;
+               }
+       }
+
+       /* If any are set, only display the ones that are set */
+
+       if (display_args) {
+               acpi_os_printf("Initialized Arguments for Method [%4.4s]:  "
+                              "(%X arguments defined for method invocation)\n",
+                              acpi_ut_get_node_name(node),
+                              obj_desc->method.param_count);
+
+               for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
+                       obj_desc = walk_state->arguments[i].object;
+                       if (obj_desc) {
+                               acpi_os_printf("  Arg%u:   ", i);
+                               acpi_db_display_internal_object(obj_desc,
+                                                               walk_state);
+                       }
+               }
+       } else {
+               acpi_os_printf
+                   ("No Arguments are initialized for method [%4.4s]\n",
+                    acpi_ut_get_node_name(node));
+       }
+}
diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c
new file mode 100644 (file)
index 0000000..4ba0a20
--- /dev/null
@@ -0,0 +1,546 @@
+/*******************************************************************************
+ *
+ * Module Name: dbstats - Generation and display of ACPI table statistics
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbstats")
+
+/* Local prototypes */
+static void acpi_db_count_namespace_objects(void);
+
+static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
+
+static acpi_status
+acpi_db_classify_one_object(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value);
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+static void acpi_db_list_info(struct acpi_memory_list *list);
+#endif
+
+/*
+ * Statistics subcommands
+ */
+static struct acpi_db_argument_info acpi_db_stat_types[] = {
+       {"ALLOCATIONS"},
+       {"OBJECTS"},
+       {"MEMORY"},
+       {"MISC"},
+       {"TABLES"},
+       {"SIZES"},
+       {"STACK"},
+       {NULL}                  /* Must be null terminated */
+};
+
+#define CMD_STAT_ALLOCATIONS     0
+#define CMD_STAT_OBJECTS         1
+#define CMD_STAT_MEMORY          2
+#define CMD_STAT_MISC            3
+#define CMD_STAT_TABLES          4
+#define CMD_STAT_SIZES           5
+#define CMD_STAT_STACK           6
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_list_info
+ *
+ * PARAMETERS:  list            - Memory list/cache to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about the input memory list or cache.
+ *
+ ******************************************************************************/
+
+static void acpi_db_list_info(struct acpi_memory_list *list)
+{
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+       u32 outstanding;
+#endif
+
+       acpi_os_printf("\n%s\n", list->list_name);
+
+       /* max_depth > 0 indicates a cache object */
+
+       if (list->max_depth > 0) {
+               acpi_os_printf
+                   ("    Cache: [Depth    MaxD Avail  Size]                "
+                    "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
+                    list->max_depth, list->max_depth - list->current_depth,
+                    (list->current_depth * list->object_size));
+       }
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+       if (list->max_depth > 0) {
+               acpi_os_printf
+                   ("    Cache: [Requests Hits Misses ObjSize]             "
+                    "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
+                    list->requests - list->hits, list->object_size);
+       }
+
+       outstanding = acpi_db_get_cache_info(list);
+
+       if (list->object_size) {
+               acpi_os_printf
+                   ("    Mem:   [Alloc    Free Max    CurSize Outstanding] "
+                    "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
+                    list->total_freed, list->max_occupied,
+                    outstanding * list->object_size, outstanding);
+       } else {
+               acpi_os_printf
+                   ("    Mem:   [Alloc Free Max CurSize Outstanding Total] "
+                    "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
+                    list->total_allocated, list->total_freed,
+                    list->max_occupied, list->current_total_size, outstanding,
+                    list->total_size);
+       }
+#endif
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_enumerate_object
+ *
+ * PARAMETERS:  obj_desc            - Object to be counted
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add this object to the global counts, by object type.
+ *              Limited recursion handles subobjects and packages, and this
+ *              is probably acceptable within the AML debugger only.
+ *
+ ******************************************************************************/
+
+static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
+{
+       u32 i;
+
+       if (!obj_desc) {
+               return;
+       }
+
+       /* Enumerate this object first */
+
+       acpi_gbl_num_objects++;
+
+       if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
+               acpi_gbl_obj_type_count_misc++;
+       } else {
+               acpi_gbl_obj_type_count[obj_desc->common.type]++;
+       }
+
+       /* Count the sub-objects */
+
+       switch (obj_desc->common.type) {
+       case ACPI_TYPE_PACKAGE:
+
+               for (i = 0; i < obj_desc->package.count; i++) {
+                       acpi_db_enumerate_object(obj_desc->package.elements[i]);
+               }
+               break;
+
+       case ACPI_TYPE_DEVICE:
+
+               acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
+               acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
+               acpi_db_enumerate_object(obj_desc->device.handler);
+               break;
+
+       case ACPI_TYPE_BUFFER_FIELD:
+
+               if (acpi_ns_get_secondary_object(obj_desc)) {
+                       acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
+               }
+               break;
+
+       case ACPI_TYPE_REGION:
+
+               acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
+               acpi_db_enumerate_object(obj_desc->region.handler);
+               break;
+
+       case ACPI_TYPE_POWER:
+
+               acpi_db_enumerate_object(obj_desc->power_resource.
+                                        notify_list[0]);
+               acpi_db_enumerate_object(obj_desc->power_resource.
+                                        notify_list[1]);
+               break;
+
+       case ACPI_TYPE_PROCESSOR:
+
+               acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
+               acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
+               acpi_db_enumerate_object(obj_desc->processor.handler);
+               break;
+
+       case ACPI_TYPE_THERMAL:
+
+               acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
+               acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
+               acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
+               break;
+
+       default:
+
+               break;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_classify_one_object
+ *
+ * PARAMETERS:  Callback for walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
+ *              the parent namespace node.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_classify_one_object(acpi_handle obj_handle,
+                           u32 nesting_level,
+                           void *context, void **return_value)
+{
+       struct acpi_namespace_node *node;
+       union acpi_operand_object *obj_desc;
+       u32 type;
+
+       acpi_gbl_num_nodes++;
+
+       node = (struct acpi_namespace_node *)obj_handle;
+       obj_desc = acpi_ns_get_attached_object(node);
+
+       acpi_db_enumerate_object(obj_desc);
+
+       type = node->type;
+       if (type > ACPI_TYPE_NS_NODE_MAX) {
+               acpi_gbl_node_type_count_misc++;
+       } else {
+               acpi_gbl_node_type_count[type]++;
+       }
+
+       return (AE_OK);
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+       /* TBD: These need to be counted during the initial parsing phase */
+
+       if (acpi_ps_is_named_op(op->opcode)) {
+               num_nodes++;
+       }
+
+       if (is_method) {
+               num_method_elements++;
+       }
+
+       num_grammar_elements++;
+       op = acpi_ps_get_depth_next(root, op);
+
+       size_of_parse_tree = (num_grammar_elements - num_method_elements) *
+           (u32)sizeof(union acpi_parse_object);
+       size_of_method_trees =
+           num_method_elements * (u32)sizeof(union acpi_parse_object);
+       size_of_node_entries =
+           num_nodes * (u32)sizeof(struct acpi_namespace_node);
+       size_of_acpi_objects =
+           num_nodes * (u32)sizeof(union acpi_operand_object);
+#endif
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_count_namespace_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Count and classify the entire namespace, including all
+ *              namespace nodes and attached objects.
+ *
+ ******************************************************************************/
+
+static void acpi_db_count_namespace_objects(void)
+{
+       u32 i;
+
+       acpi_gbl_num_nodes = 0;
+       acpi_gbl_num_objects = 0;
+
+       acpi_gbl_obj_type_count_misc = 0;
+       for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
+               acpi_gbl_obj_type_count[i] = 0;
+               acpi_gbl_node_type_count[i] = 0;
+       }
+
+       (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                    ACPI_UINT32_MAX, FALSE,
+                                    acpi_db_classify_one_object, NULL, NULL,
+                                    NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_statistics
+ *
+ * PARAMETERS:  type_arg        - Subcommand
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display various statistics
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_display_statistics(char *type_arg)
+{
+       u32 i;
+       u32 temp;
+
+       acpi_ut_strupr(type_arg);
+       temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
+       if (temp == ACPI_TYPE_NOT_FOUND) {
+               acpi_os_printf("Invalid or unsupported argument\n");
+               return (AE_OK);
+       }
+
+       switch (temp) {
+       case CMD_STAT_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+               acpi_ut_dump_allocation_info();
+#endif
+               break;
+
+       case CMD_STAT_TABLES:
+
+               acpi_os_printf("ACPI Table Information (not implemented):\n\n");
+               break;
+
+       case CMD_STAT_OBJECTS:
+
+               acpi_db_count_namespace_objects();
+
+               acpi_os_printf
+                   ("\nObjects defined in the current namespace:\n\n");
+
+               acpi_os_printf("%16.16s %10.10s %10.10s\n",
+                              "ACPI_TYPE", "NODES", "OBJECTS");
+
+               for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
+                       acpi_os_printf("%16.16s % 10ld% 10ld\n",
+                                      acpi_ut_get_type_name(i),
+                                      acpi_gbl_node_type_count[i],
+                                      acpi_gbl_obj_type_count[i]);
+               }
+               acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+                              acpi_gbl_node_type_count_misc,
+                              acpi_gbl_obj_type_count_misc);
+
+               acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:",
+                              acpi_gbl_num_nodes, acpi_gbl_num_objects);
+               break;
+
+       case CMD_STAT_MEMORY:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+               acpi_os_printf
+                   ("\n----Object Statistics (all in hex)---------\n");
+
+               acpi_db_list_info(acpi_gbl_global_list);
+               acpi_db_list_info(acpi_gbl_ns_node_list);
+#endif
+
+#ifdef ACPI_USE_LOCAL_CACHE
+               acpi_os_printf
+                   ("\n----Cache Statistics (all in hex)---------\n");
+               acpi_db_list_info(acpi_gbl_operand_cache);
+               acpi_db_list_info(acpi_gbl_ps_node_cache);
+               acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
+               acpi_db_list_info(acpi_gbl_state_cache);
+#endif
+
+               break;
+
+       case CMD_STAT_MISC:
+
+               acpi_os_printf("\nMiscellaneous Statistics:\n\n");
+               acpi_os_printf("Calls to AcpiPsFind:.. ........% 7ld\n",
+                              acpi_gbl_ps_find_count);
+               acpi_os_printf("Calls to AcpiNsLookup:..........% 7ld\n",
+                              acpi_gbl_ns_lookup_count);
+
+               acpi_os_printf("\n");
+
+               acpi_os_printf("Mutex usage:\n\n");
+               for (i = 0; i < ACPI_NUM_MUTEX; i++) {
+                       acpi_os_printf("%-28s:     % 7ld\n",
+                                      acpi_ut_get_mutex_name(i),
+                                      acpi_gbl_mutex_info[i].use_count);
+               }
+               break;
+
+       case CMD_STAT_SIZES:
+
+               acpi_os_printf("\nInternal object sizes:\n\n");
+
+               acpi_os_printf("Common         %3d\n",
+                              sizeof(struct acpi_object_common));
+               acpi_os_printf("Number         %3d\n",
+                              sizeof(struct acpi_object_integer));
+               acpi_os_printf("String         %3d\n",
+                              sizeof(struct acpi_object_string));
+               acpi_os_printf("Buffer         %3d\n",
+                              sizeof(struct acpi_object_buffer));
+               acpi_os_printf("Package        %3d\n",
+                              sizeof(struct acpi_object_package));
+               acpi_os_printf("BufferField    %3d\n",
+                              sizeof(struct acpi_object_buffer_field));
+               acpi_os_printf("Device         %3d\n",
+                              sizeof(struct acpi_object_device));
+               acpi_os_printf("Event          %3d\n",
+                              sizeof(struct acpi_object_event));
+               acpi_os_printf("Method         %3d\n",
+                              sizeof(struct acpi_object_method));
+               acpi_os_printf("Mutex          %3d\n",
+                              sizeof(struct acpi_object_mutex));
+               acpi_os_printf("Region         %3d\n",
+                              sizeof(struct acpi_object_region));
+               acpi_os_printf("PowerResource  %3d\n",
+                              sizeof(struct acpi_object_power_resource));
+               acpi_os_printf("Processor      %3d\n",
+                              sizeof(struct acpi_object_processor));
+               acpi_os_printf("ThermalZone    %3d\n",
+                              sizeof(struct acpi_object_thermal_zone));
+               acpi_os_printf("RegionField    %3d\n",
+                              sizeof(struct acpi_object_region_field));
+               acpi_os_printf("BankField      %3d\n",
+                              sizeof(struct acpi_object_bank_field));
+               acpi_os_printf("IndexField     %3d\n",
+                              sizeof(struct acpi_object_index_field));
+               acpi_os_printf("Reference      %3d\n",
+                              sizeof(struct acpi_object_reference));
+               acpi_os_printf("Notify         %3d\n",
+                              sizeof(struct acpi_object_notify_handler));
+               acpi_os_printf("AddressSpace   %3d\n",
+                              sizeof(struct acpi_object_addr_handler));
+               acpi_os_printf("Extra          %3d\n",
+                              sizeof(struct acpi_object_extra));
+               acpi_os_printf("Data           %3d\n",
+                              sizeof(struct acpi_object_data));
+
+               acpi_os_printf("\n");
+
+               acpi_os_printf("ParseObject    %3d\n",
+                              sizeof(struct acpi_parse_obj_common));
+               acpi_os_printf("ParseObjectNamed %3d\n",
+                              sizeof(struct acpi_parse_obj_named));
+               acpi_os_printf("ParseObjectAsl %3d\n",
+                              sizeof(struct acpi_parse_obj_asl));
+               acpi_os_printf("OperandObject  %3d\n",
+                              sizeof(union acpi_operand_object));
+               acpi_os_printf("NamespaceNode  %3d\n",
+                              sizeof(struct acpi_namespace_node));
+               acpi_os_printf("AcpiObject     %3d\n",
+                              sizeof(union acpi_object));
+
+               acpi_os_printf("\n");
+
+               acpi_os_printf("Generic State  %3d\n",
+                              sizeof(union acpi_generic_state));
+               acpi_os_printf("Common State   %3d\n",
+                              sizeof(struct acpi_common_state));
+               acpi_os_printf("Control State  %3d\n",
+                              sizeof(struct acpi_control_state));
+               acpi_os_printf("Update State   %3d\n",
+                              sizeof(struct acpi_update_state));
+               acpi_os_printf("Scope State    %3d\n",
+                              sizeof(struct acpi_scope_state));
+               acpi_os_printf("Parse Scope    %3d\n",
+                              sizeof(struct acpi_pscope_state));
+               acpi_os_printf("Package State  %3d\n",
+                              sizeof(struct acpi_pkg_state));
+               acpi_os_printf("Thread State   %3d\n",
+                              sizeof(struct acpi_thread_state));
+               acpi_os_printf("Result Values  %3d\n",
+                              sizeof(struct acpi_result_values));
+               acpi_os_printf("Notify Info    %3d\n",
+                              sizeof(struct acpi_notify_info));
+               break;
+
+       case CMD_STAT_STACK:
+#if defined(ACPI_DEBUG_OUTPUT)
+
+               temp =
+                   (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
+                                      acpi_gbl_lowest_stack_pointer);
+
+               acpi_os_printf("\nSubsystem Stack Usage:\n\n");
+               acpi_os_printf("Entry Stack Pointer        %p\n",
+                              acpi_gbl_entry_stack_pointer);
+               acpi_os_printf("Lowest Stack Pointer       %p\n",
+                              acpi_gbl_lowest_stack_pointer);
+               acpi_os_printf("Stack Use                  %X (%u)\n", temp,
+                              temp);
+               acpi_os_printf("Deepest Procedure Nesting  %u\n",
+                              acpi_gbl_deepest_nesting);
+#endif
+               break;
+
+       default:
+
+               break;
+       }
+
+       acpi_os_printf("\n");
+       return (AE_OK);
+}
diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c
new file mode 100644 (file)
index 0000000..10ea8bf
--- /dev/null
@@ -0,0 +1,1057 @@
+/*******************************************************************************
+ *
+ * Module Name: dbtest - Various debug-related tests
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acdebug.h"
+#include "acnamesp.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbtest")
+
+/* Local prototypes */
+static void acpi_db_test_all_objects(void);
+
+static acpi_status
+acpi_db_test_one_object(acpi_handle obj_handle,
+                       u32 nesting_level, void *context, void **return_value);
+
+static acpi_status
+acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
+
+static acpi_status
+acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
+
+static acpi_status
+acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
+
+static acpi_status
+acpi_db_read_from_object(struct acpi_namespace_node *node,
+                        acpi_object_type expected_type,
+                        union acpi_object **value);
+
+static acpi_status
+acpi_db_write_to_object(struct acpi_namespace_node *node,
+                       union acpi_object *value);
+
+static void acpi_db_evaluate_all_predefined_names(char *count_arg);
+
+static acpi_status
+acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
+                                    u32 nesting_level,
+                                    void *context, void **return_value);
+
+/*
+ * Test subcommands
+ */
+static struct acpi_db_argument_info acpi_db_test_types[] = {
+       {"OBJECTS"},
+       {"PREDEFINED"},
+       {NULL}                  /* Must be null terminated */
+};
+
+#define CMD_TEST_OBJECTS        0
+#define CMD_TEST_PREDEFINED     1
+
+#define BUFFER_FILL_VALUE       0xFF
+
+/*
+ * Support for the special debugger read/write control methods.
+ * These methods are installed into the current namespace and are
+ * used to read and write the various namespace objects. The point
+ * is to force the AML interpreter do all of the work.
+ */
+#define ACPI_DB_READ_METHOD     "\\_T98"
+#define ACPI_DB_WRITE_METHOD    "\\_T99"
+
+static acpi_handle read_handle = NULL;
+static acpi_handle write_handle = NULL;
+
+/* ASL Definitions of the debugger read/write control methods */
+
+#if 0
+definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+       method(_T98, 1, not_serialized) {       /* Read */
+               return (de_ref_of(arg0))
+       }
+}
+
+definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
+{
+       method(_T99, 2, not_serialized) {       /* Write */
+               store(arg1, arg0)
+       }
+}
+#endif
+
+static unsigned char read_method_code[] = {
+       0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
+       0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
+       0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
+       0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
+       0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
+       0x39, 0x38, 0x01, 0xA4, 0x83, 0x68      /* 00000028    "98...h"   */
+};
+
+static unsigned char write_method_code[] = {
+       0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000    "SSDT...." */
+       0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008    "..Intel." */
+       0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010    "DEBUG..." */
+       0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018    "....INTL" */
+       0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020    "... .._T" */
+       0x39, 0x39, 0x02, 0x70, 0x69, 0x68      /* 00000028    "99.pih"   */
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_execute_test
+ *
+ * PARAMETERS:  type_arg        - Subcommand
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Execute various debug tests.
+ *
+ * Note: Code is prepared for future expansion of the TEST command.
+ *
+ ******************************************************************************/
+
+void acpi_db_execute_test(char *type_arg)
+{
+       u32 temp;
+
+       acpi_ut_strupr(type_arg);
+       temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
+       if (temp == ACPI_TYPE_NOT_FOUND) {
+               acpi_os_printf("Invalid or unsupported argument\n");
+               return;
+       }
+
+       switch (temp) {
+       case CMD_TEST_OBJECTS:
+
+               acpi_db_test_all_objects();
+               break;
+
+       case CMD_TEST_PREDEFINED:
+
+               acpi_db_evaluate_all_predefined_names(NULL);
+               break;
+
+       default:
+               break;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_all_objects
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
+ *              namespace by reading/writing/comparing all data objects such
+ *              as integers, strings, buffers, fields, buffer fields, etc.
+ *
+ ******************************************************************************/
+
+static void acpi_db_test_all_objects(void)
+{
+       acpi_status status;
+
+       /* Install the debugger read-object control method if necessary */
+
+       if (!read_handle) {
+               status = acpi_install_method(read_method_code);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("%s, Could not install debugger read method\n",
+                            acpi_format_exception(status));
+                       return;
+               }
+
+               status =
+                   acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("Could not obtain handle for debug method %s\n",
+                            ACPI_DB_READ_METHOD);
+                       return;
+               }
+       }
+
+       /* Install the debugger write-object control method if necessary */
+
+       if (!write_handle) {
+               status = acpi_install_method(write_method_code);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("%s, Could not install debugger write method\n",
+                            acpi_format_exception(status));
+                       return;
+               }
+
+               status =
+                   acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf
+                           ("Could not obtain handle for debug method %s\n",
+                            ACPI_DB_WRITE_METHOD);
+                       return;
+               }
+       }
+
+       /* Walk the entire namespace, testing each supported named data object */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX, acpi_db_test_one_object,
+                                 NULL, NULL, NULL);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_one_object
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test one namespace object. Supported types are Integer,
+ *              String, Buffer, buffer_field, and field_unit. All other object
+ *              types are simply ignored.
+ *
+ *              Note: Support for Packages is not implemented.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_one_object(acpi_handle obj_handle,
+                       u32 nesting_level, void *context, void **return_value)
+{
+       struct acpi_namespace_node *node;
+       union acpi_operand_object *obj_desc;
+       union acpi_operand_object *region_obj;
+       acpi_object_type local_type;
+       u32 bit_length = 0;
+       u32 byte_length = 0;
+       acpi_status status = AE_OK;
+
+       node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+       obj_desc = node->object;
+
+       /*
+        * For the supported types, get the actual bit length or
+        * byte length. Map the type to one of Integer/String/Buffer.
+        */
+       switch (node->type) {
+       case ACPI_TYPE_INTEGER:
+
+               /* Integer width is either 32 or 64 */
+
+               local_type = ACPI_TYPE_INTEGER;
+               bit_length = acpi_gbl_integer_bit_width;
+               break;
+
+       case ACPI_TYPE_STRING:
+
+               local_type = ACPI_TYPE_STRING;
+               byte_length = obj_desc->string.length;
+               break;
+
+       case ACPI_TYPE_BUFFER:
+
+               local_type = ACPI_TYPE_BUFFER;
+               byte_length = obj_desc->buffer.length;
+               bit_length = byte_length * 8;
+               break;
+
+       case ACPI_TYPE_FIELD_UNIT:
+       case ACPI_TYPE_BUFFER_FIELD:
+       case ACPI_TYPE_LOCAL_REGION_FIELD:
+       case ACPI_TYPE_LOCAL_INDEX_FIELD:
+       case ACPI_TYPE_LOCAL_BANK_FIELD:
+
+               local_type = ACPI_TYPE_INTEGER;
+               if (obj_desc) {
+                       /*
+                        * Returned object will be a Buffer if the field length
+                        * is larger than the size of an Integer (32 or 64 bits
+                        * depending on the DSDT version).
+                        */
+                       bit_length = obj_desc->common_field.bit_length;
+                       byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
+                       if (bit_length > acpi_gbl_integer_bit_width) {
+                               local_type = ACPI_TYPE_BUFFER;
+                       }
+               }
+               break;
+
+       default:
+
+               /* Ignore all other types */
+
+               return (AE_OK);
+       }
+
+       /* Emit the common prefix: Type:Name */
+
+       acpi_os_printf("%14s: %4.4s",
+                      acpi_ut_get_type_name(node->type), node->name.ascii);
+       if (!obj_desc) {
+               acpi_os_printf(" Ignoring, no attached object\n");
+               return (AE_OK);
+       }
+
+       /*
+        * Check for unsupported region types. Note: acpi_exec simulates
+        * access to system_memory, system_IO, PCI_Config, and EC.
+        */
+       switch (node->type) {
+       case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+               region_obj = obj_desc->field.region_obj;
+               switch (region_obj->region.space_id) {
+               case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+               case ACPI_ADR_SPACE_SYSTEM_IO:
+               case ACPI_ADR_SPACE_PCI_CONFIG:
+               case ACPI_ADR_SPACE_EC:
+
+                       break;
+
+               default:
+
+                       acpi_os_printf
+                           ("    %s space is not supported [%4.4s]\n",
+                            acpi_ut_get_region_name(region_obj->region.
+                                                    space_id),
+                            region_obj->region.node->name.ascii);
+                       return (AE_OK);
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       /* At this point, we have resolved the object to one of the major types */
+
+       switch (local_type) {
+       case ACPI_TYPE_INTEGER:
+
+               status = acpi_db_test_integer_type(node, bit_length);
+               break;
+
+       case ACPI_TYPE_STRING:
+
+               status = acpi_db_test_string_type(node, byte_length);
+               break;
+
+       case ACPI_TYPE_BUFFER:
+
+               status = acpi_db_test_buffer_type(node, bit_length);
+               break;
+
+       default:
+
+               acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
+                              local_type);
+               break;
+       }
+
+       switch (node->type) {
+       case ACPI_TYPE_LOCAL_REGION_FIELD:
+
+               region_obj = obj_desc->field.region_obj;
+               acpi_os_printf(" (%s)",
+                              acpi_ut_get_region_name(region_obj->region.
+                                                      space_id));
+               break;
+
+       default:
+               break;
+       }
+
+       acpi_os_printf("\n");
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_integer_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              bit_length          - Actual length of the object. Used for
+ *                                    support of arbitrary length field_unit
+ *                                    and buffer_field objects.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
+{
+       union acpi_object *temp1 = NULL;
+       union acpi_object *temp2 = NULL;
+       union acpi_object *temp3 = NULL;
+       union acpi_object write_value;
+       u64 value_to_write;
+       acpi_status status;
+
+       if (bit_length > 64) {
+               acpi_os_printf(" Invalid length for an Integer: %u",
+                              bit_length);
+               return (AE_OK);
+       }
+
+       /* Read the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X",
+                      bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
+                      ACPI_FORMAT_UINT64(temp1->integer.value));
+
+       value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
+       if (temp1->integer.value == value_to_write) {
+               value_to_write = 0;
+       }
+
+       /* Write a new value */
+
+       write_value.type = ACPI_TYPE_INTEGER;
+       write_value.integer.value = value_to_write;
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the new value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (temp2->integer.value != value_to_write) {
+               acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
+                              ACPI_FORMAT_UINT64(temp2->integer.value),
+                              ACPI_FORMAT_UINT64(value_to_write));
+       }
+
+       /* Write back the original value */
+
+       write_value.integer.value = temp1->integer.value;
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (temp3->integer.value != temp1->integer.value) {
+               acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
+                              ACPI_FORMAT_UINT64(temp3->integer.value),
+                              ACPI_FORMAT_UINT64(temp1->integer.value));
+       }
+
+exit:
+       if (temp1) {
+               acpi_os_free(temp1);
+       }
+       if (temp2) {
+               acpi_os_free(temp2);
+       }
+       if (temp3) {
+               acpi_os_free(temp3);
+       }
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_buffer_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              bit_length          - Actual length of the object.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
+{
+       union acpi_object *temp1 = NULL;
+       union acpi_object *temp2 = NULL;
+       union acpi_object *temp3 = NULL;
+       u8 *buffer;
+       union acpi_object write_value;
+       acpi_status status;
+       u32 byte_length;
+       u32 i;
+       u8 extra_bits;
+
+       byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
+       if (byte_length == 0) {
+               acpi_os_printf(" Ignoring zero length buffer");
+               return (AE_OK);
+       }
+
+       /* Allocate a local buffer */
+
+       buffer = ACPI_ALLOCATE_ZEROED(byte_length);
+       if (!buffer) {
+               return (AE_NO_MEMORY);
+       }
+
+       /* Read the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Emit a few bytes of the buffer */
+
+       acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length);
+       for (i = 0; ((i < 4) && (i < byte_length)); i++) {
+               acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
+       }
+       acpi_os_printf("... ");
+
+       /*
+        * Write a new value.
+        *
+        * Handle possible extra bits at the end of the buffer. Can
+        * happen for field_units larger than an integer, but the bit
+        * count is not an integral number of bytes. Zero out the
+        * unused bits.
+        */
+       memset(buffer, BUFFER_FILL_VALUE, byte_length);
+       extra_bits = bit_length % 8;
+       if (extra_bits) {
+               buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
+       }
+
+       write_value.type = ACPI_TYPE_BUFFER;
+       write_value.buffer.length = byte_length;
+       write_value.buffer.pointer = buffer;
+
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the new value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
+               acpi_os_printf(" MISMATCH 2: New buffer value");
+       }
+
+       /* Write back the original value */
+
+       write_value.buffer.length = byte_length;
+       write_value.buffer.pointer = temp1->buffer.pointer;
+
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
+               acpi_os_printf(" MISMATCH 3: While restoring original buffer");
+       }
+
+exit:
+       ACPI_FREE(buffer);
+       if (temp1) {
+               acpi_os_free(temp1);
+       }
+       if (temp2) {
+               acpi_os_free(temp2);
+       }
+       if (temp3) {
+               acpi_os_free(temp3);
+       }
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_test_string_type
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              byte_length         - Actual length of the object.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Test read/write for an String-valued object. Performs a
+ *              write/read/compare of an arbitrary new value, then performs
+ *              a write/read/compare of the original value.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
+{
+       union acpi_object *temp1 = NULL;
+       union acpi_object *temp2 = NULL;
+       union acpi_object *temp3 = NULL;
+       char *value_to_write = "Test String from AML Debugger";
+       union acpi_object write_value;
+       acpi_status status;
+
+       /* Read the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8),
+                      temp1->string.length, temp1->string.pointer);
+
+       /* Write a new value */
+
+       write_value.type = ACPI_TYPE_STRING;
+       write_value.string.length = strlen(value_to_write);
+       write_value.string.pointer = value_to_write;
+
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the new value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (strcmp(temp2->string.pointer, value_to_write)) {
+               acpi_os_printf(" MISMATCH 2: %s, expecting %s",
+                              temp2->string.pointer, value_to_write);
+       }
+
+       /* Write back the original value */
+
+       write_value.string.length = strlen(temp1->string.pointer);
+       write_value.string.pointer = temp1->string.pointer;
+
+       status = acpi_db_write_to_object(node, &write_value);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       /* Ensure that we can read back the original value */
+
+       status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
+               acpi_os_printf(" MISMATCH 3: %s, expecting %s",
+                              temp3->string.pointer, temp1->string.pointer);
+       }
+
+exit:
+       if (temp1) {
+               acpi_os_free(temp1);
+       }
+       if (temp2) {
+               acpi_os_free(temp2);
+       }
+       if (temp3) {
+               acpi_os_free(temp3);
+       }
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_read_from_object
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              expected_type       - Object type expected from the read
+ *              value               - Where the value read is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Performs a read from the specified object by invoking the
+ *              special debugger control method that reads the object. Thus,
+ *              the AML interpreter is doing all of the work, increasing the
+ *              validity of the test.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_read_from_object(struct acpi_namespace_node *node,
+                        acpi_object_type expected_type,
+                        union acpi_object **value)
+{
+       union acpi_object *ret_value;
+       struct acpi_object_list param_objects;
+       union acpi_object params[2];
+       struct acpi_buffer return_obj;
+       acpi_status status;
+
+       params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
+       params[0].reference.actual_type = node->type;
+       params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
+
+       param_objects.count = 1;
+       param_objects.pointer = params;
+
+       return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+       acpi_gbl_method_executing = TRUE;
+       status = acpi_evaluate_object(read_handle, NULL,
+                                     &param_objects, &return_obj);
+       acpi_gbl_method_executing = FALSE;
+
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not read from object, %s",
+                              acpi_format_exception(status));
+               return (status);
+       }
+
+       ret_value = (union acpi_object *)return_obj.pointer;
+
+       switch (ret_value->type) {
+       case ACPI_TYPE_INTEGER:
+       case ACPI_TYPE_BUFFER:
+       case ACPI_TYPE_STRING:
+               /*
+                * Did we receive the type we wanted? Most important for the
+                * Integer/Buffer case (when a field is larger than an Integer,
+                * it should return a Buffer).
+                */
+               if (ret_value->type != expected_type) {
+                       acpi_os_printf
+                           (" Type mismatch: Expected %s, Received %s",
+                            acpi_ut_get_type_name(expected_type),
+                            acpi_ut_get_type_name(ret_value->type));
+
+                       return (AE_TYPE);
+               }
+
+               *value = ret_value;
+               break;
+
+       default:
+
+               acpi_os_printf(" Unsupported return object type, %s",
+                              acpi_ut_get_type_name(ret_value->type));
+
+               acpi_os_free(return_obj.pointer);
+               return (AE_TYPE);
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_write_to_object
+ *
+ * PARAMETERS:  node                - Parent NS node for the object
+ *              value               - Value to be written
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Performs a write to the specified object by invoking the
+ *              special debugger control method that writes the object. Thus,
+ *              the AML interpreter is doing all of the work, increasing the
+ *              validity of the test.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_write_to_object(struct acpi_namespace_node *node,
+                       union acpi_object *value)
+{
+       struct acpi_object_list param_objects;
+       union acpi_object params[2];
+       acpi_status status;
+
+       params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
+       params[0].reference.actual_type = node->type;
+       params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
+
+       /* Copy the incoming user parameter */
+
+       memcpy(&params[1], value, sizeof(union acpi_object));
+
+       param_objects.count = 2;
+       param_objects.pointer = params;
+
+       acpi_gbl_method_executing = TRUE;
+       status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
+       acpi_gbl_method_executing = FALSE;
+
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not write to object, %s",
+                              acpi_format_exception(status));
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_evaluate_all_predefined_names
+ *
+ * PARAMETERS:  count_arg           - Max number of methods to execute
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Namespace batch execution. Execute predefined names in the
+ *              namespace, up to the max count, if specified.
+ *
+ ******************************************************************************/
+
+static void acpi_db_evaluate_all_predefined_names(char *count_arg)
+{
+       struct acpi_db_execute_walk info;
+
+       info.count = 0;
+       info.max_count = ACPI_UINT32_MAX;
+
+       if (count_arg) {
+               info.max_count = strtoul(count_arg, NULL, 0);
+       }
+
+       /* Search all nodes in namespace */
+
+       (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+                                 ACPI_UINT32_MAX,
+                                 acpi_db_evaluate_one_predefined_name, NULL,
+                                 (void *)&info, NULL);
+
+       acpi_os_printf("Evaluated %u predefined names in the namespace\n",
+                      info.count);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_evaluate_one_predefined_name
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Batch execution module. Currently only executes predefined
+ *              ACPI names.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
+                                    u32 nesting_level,
+                                    void *context, void **return_value)
+{
+       struct acpi_namespace_node *node =
+           (struct acpi_namespace_node *)obj_handle;
+       struct acpi_db_execute_walk *info =
+           (struct acpi_db_execute_walk *)context;
+       char *pathname;
+       const union acpi_predefined_info *predefined;
+       struct acpi_device_info *obj_info;
+       struct acpi_object_list param_objects;
+       union acpi_object params[ACPI_METHOD_NUM_ARGS];
+       union acpi_object *this_param;
+       struct acpi_buffer return_obj;
+       acpi_status status;
+       u16 arg_type_list;
+       u8 arg_count;
+       u8 arg_type;
+       u32 i;
+
+       /* The name must be a predefined ACPI name */
+
+       predefined = acpi_ut_match_predefined_method(node->name.ascii);
+       if (!predefined) {
+               return (AE_OK);
+       }
+
+       if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
+               return (AE_OK);
+       }
+
+       pathname = acpi_ns_get_external_pathname(node);
+       if (!pathname) {
+               return (AE_OK);
+       }
+
+       /* Get the object info for number of method parameters */
+
+       status = acpi_get_object_info(obj_handle, &obj_info);
+       if (ACPI_FAILURE(status)) {
+               ACPI_FREE(pathname);
+               return (status);
+       }
+
+       param_objects.count = 0;
+       param_objects.pointer = NULL;
+
+       if (obj_info->type == ACPI_TYPE_METHOD) {
+
+               /* Setup default parameters (with proper types) */
+
+               arg_type_list = predefined->info.argument_list;
+               arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
+
+               /*
+                * Setup the ACPI-required number of arguments, regardless of what
+                * the actual method defines. If there is a difference, then the
+                * method is wrong and a warning will be issued during execution.
+                */
+               this_param = params;
+               for (i = 0; i < arg_count; i++) {
+                       arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
+                       this_param->type = arg_type;
+
+                       switch (arg_type) {
+                       case ACPI_TYPE_INTEGER:
+
+                               this_param->integer.value = 1;
+                               break;
+
+                       case ACPI_TYPE_STRING:
+
+                               this_param->string.pointer =
+                                   "This is the default argument string";
+                               this_param->string.length =
+                                   strlen(this_param->string.pointer);
+                               break;
+
+                       case ACPI_TYPE_BUFFER:
+
+                               this_param->buffer.pointer = (u8 *)params;      /* just a garbage buffer */
+                               this_param->buffer.length = 48;
+                               break;
+
+                       case ACPI_TYPE_PACKAGE:
+
+                               this_param->package.elements = NULL;
+                               this_param->package.count = 0;
+                               break;
+
+                       default:
+
+                               acpi_os_printf
+                                   ("%s: Unsupported argument type: %u\n",
+                                    pathname, arg_type);
+                               break;
+                       }
+
+                       this_param++;
+               }
+
+               param_objects.count = arg_count;
+               param_objects.pointer = params;
+       }
+
+       ACPI_FREE(obj_info);
+       return_obj.pointer = NULL;
+       return_obj.length = ACPI_ALLOCATE_BUFFER;
+
+       /* Do the actual method execution */
+
+       acpi_gbl_method_executing = TRUE;
+
+       status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
+
+       acpi_os_printf("%-32s returned %s\n",
+                      pathname, acpi_format_exception(status));
+       acpi_gbl_method_executing = FALSE;
+       ACPI_FREE(pathname);
+
+       /* Ignore status from method execution */
+
+       status = AE_OK;
+
+       /* Update count, check if we have executed enough methods */
+
+       info->count++;
+       if (info->count >= info->max_count) {
+               status = AE_CTRL_TERMINATE;
+       }
+
+       return (status);
+}
diff --git a/drivers/acpi/acpica/dbutils.c b/drivers/acpi/acpica/dbutils.c
new file mode 100644 (file)
index 0000000..86790e0
--- /dev/null
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ *
+ * Module Name: dbutils - AML debugger utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "acnamesp.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbutils")
+
+/* Local prototypes */
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root);
+
+void acpi_db_dump_buffer(u32 address);
+#endif
+
+static char *gbl_hex_to_ascii = "0123456789ABCDEF";
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_match_argument
+ *
+ * PARAMETERS:  user_argument           - User command line
+ *              arguments               - Array of commands to match against
+ *
+ * RETURN:      Index into command array or ACPI_TYPE_NOT_FOUND if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+acpi_object_type
+acpi_db_match_argument(char *user_argument,
+                      struct acpi_db_argument_info *arguments)
+{
+       u32 i;
+
+       if (!user_argument || user_argument[0] == 0) {
+               return (ACPI_TYPE_NOT_FOUND);
+       }
+
+       for (i = 0; arguments[i].name; i++) {
+               if (strstr(arguments[i].name, user_argument) ==
+                   arguments[i].name) {
+                       return (i);
+               }
+       }
+
+       /* Argument not recognized */
+
+       return (ACPI_TYPE_NOT_FOUND);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_set_output_destination
+ *
+ * PARAMETERS:  output_flags        - Current flags word
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set the current destination for debugger output. Also sets
+ *              the debug output level accordingly.
+ *
+ ******************************************************************************/
+
+void acpi_db_set_output_destination(u32 output_flags)
+{
+
+       acpi_gbl_db_output_flags = (u8)output_flags;
+
+       if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) &&
+           acpi_gbl_db_output_to_file) {
+               acpi_dbg_level = acpi_gbl_db_debug_level;
+       } else {
+               acpi_dbg_level = acpi_gbl_db_console_debug_level;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_external_object
+ *
+ * PARAMETERS:  obj_desc        - External ACPI object to dump
+ *              level           - Nesting level.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump the contents of an ACPI external object
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_external_object(union acpi_object *obj_desc, u32 level)
+{
+       u32 i;
+
+       if (!obj_desc) {
+               acpi_os_printf("[Null Object]\n");
+               return;
+       }
+
+       for (i = 0; i < level; i++) {
+               acpi_os_printf(" ");
+       }
+
+       switch (obj_desc->type) {
+       case ACPI_TYPE_ANY:
+
+               acpi_os_printf("[Null Object] (Type=0)\n");
+               break;
+
+       case ACPI_TYPE_INTEGER:
+
+               acpi_os_printf("[Integer] = %8.8X%8.8X\n",
+                              ACPI_FORMAT_UINT64(obj_desc->integer.value));
+               break;
+
+       case ACPI_TYPE_STRING:
+
+               acpi_os_printf("[String] Length %.2X = ",
+                              obj_desc->string.length);
+               acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
+               acpi_os_printf("\n");
+               break;
+
+       case ACPI_TYPE_BUFFER:
+
+               acpi_os_printf("[Buffer] Length %.2X = ",
+                              obj_desc->buffer.length);
+               if (obj_desc->buffer.length) {
+                       if (obj_desc->buffer.length > 16) {
+                               acpi_os_printf("\n");
+                       }
+                       acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
+                                                 (u8,
+                                                  obj_desc->buffer.pointer),
+                                                 obj_desc->buffer.length,
+                                                 DB_BYTE_DISPLAY, _COMPONENT);
+               } else {
+                       acpi_os_printf("\n");
+               }
+               break;
+
+       case ACPI_TYPE_PACKAGE:
+
+               acpi_os_printf("[Package] Contains %u Elements:\n",
+                              obj_desc->package.count);
+
+               for (i = 0; i < obj_desc->package.count; i++) {
+                       acpi_db_dump_external_object(&obj_desc->package.
+                                                    elements[i], level + 1);
+               }
+               break;
+
+       case ACPI_TYPE_LOCAL_REFERENCE:
+
+               acpi_os_printf("[Object Reference] = ");
+               acpi_db_display_internal_object(obj_desc->reference.handle,
+                                               NULL);
+               break;
+
+       case ACPI_TYPE_PROCESSOR:
+
+               acpi_os_printf("[Processor]\n");
+               break;
+
+       case ACPI_TYPE_POWER:
+
+               acpi_os_printf("[Power Resource]\n");
+               break;
+
+       default:
+
+               acpi_os_printf("[Unknown Type] %X\n", obj_desc->type);
+               break;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_prep_namestring
+ *
+ * PARAMETERS:  name            - String to prepare
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Translate all forward slashes and dots to backslashes.
+ *
+ ******************************************************************************/
+
+void acpi_db_prep_namestring(char *name)
+{
+
+       if (!name) {
+               return;
+       }
+
+       acpi_ut_strupr(name);
+
+       /* Convert a leading forward slash to a backslash */
+
+       if (*name == '/') {
+               *name = '\\';
+       }
+
+       /* Ignore a leading backslash, this is the root prefix */
+
+       if (ACPI_IS_ROOT_PREFIX(*name)) {
+               name++;
+       }
+
+       /* Convert all slash path separators to dots */
+
+       while (*name) {
+               if ((*name == '/') || (*name == '\\')) {
+                       *name = '.';
+               }
+
+               name++;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_local_ns_lookup
+ *
+ * PARAMETERS:  name            - Name to lookup
+ *
+ * RETURN:      Pointer to a namespace node, null on failure
+ *
+ * DESCRIPTION: Lookup a name in the ACPI namespace
+ *
+ * Note: Currently begins search from the root. Could be enhanced to use
+ * the current prefix (scope) node as the search beginning point.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_db_local_ns_lookup(char *name)
+{
+       char *internal_path;
+       acpi_status status;
+       struct acpi_namespace_node *node = NULL;
+
+       acpi_db_prep_namestring(name);
+
+       /* Build an internal namestring */
+
+       status = acpi_ns_internalize_name(name, &internal_path);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Invalid namestring: %s\n", name);
+               return (NULL);
+       }
+
+       /*
+        * Lookup the name.
+        * (Uses root node as the search starting point)
+        */
+       status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
+                               ACPI_IMODE_EXECUTE,
+                               ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE,
+                               NULL, &node);
+       if (ACPI_FAILURE(status)) {
+               acpi_os_printf("Could not locate name: %s, %s\n",
+                              name, acpi_format_exception(status));
+       }
+
+       ACPI_FREE(internal_path);
+       return (node);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_uint32_to_hex_string
+ *
+ * PARAMETERS:  value           - The value to be converted to string
+ *              buffer          - Buffer for result (not less than 11 bytes)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
+ *
+ * NOTE: It is the caller's responsibility to ensure that the length of buffer
+ *       is sufficient.
+ *
+ ******************************************************************************/
+
+void acpi_db_uint32_to_hex_string(u32 value, char *buffer)
+{
+       int i;
+
+       if (value == 0) {
+               strcpy(buffer, "0");
+               return;
+       }
+
+       buffer[8] = '\0';
+
+       for (i = 7; i >= 0; i--) {
+               buffer[i] = gbl_hex_to_ascii[value & 0x0F];
+               value = value >> 4;
+       }
+}
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_second_pass_parse
+ *
+ * PARAMETERS:  root            - Root of the parse tree
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
+ *              second pass to parse the control methods
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_second_pass_parse(union acpi_parse_object *root)
+{
+       union acpi_parse_object *op = root;
+       union acpi_parse_object *method;
+       union acpi_parse_object *search_op;
+       union acpi_parse_object *start_op;
+       acpi_status status = AE_OK;
+       u32 base_aml_offset;
+       struct acpi_walk_state *walk_state;
+
+       ACPI_FUNCTION_ENTRY();
+
+       acpi_os_printf("Pass two parse ....\n");
+
+       while (op) {
+               if (op->common.aml_opcode == AML_METHOD_OP) {
+                       method = op;
+
+                       /* Create a new walk state for the parse */
+
+                       walk_state =
+                           acpi_ds_create_walk_state(0, NULL, NULL, NULL);
+                       if (!walk_state) {
+                               return (AE_NO_MEMORY);
+                       }
+
+                       /* Init the Walk State */
+
+                       walk_state->parser_state.aml =
+                           walk_state->parser_state.aml_start =
+                           method->named.data;
+                       walk_state->parser_state.aml_end =
+                           walk_state->parser_state.pkg_end =
+                           method->named.data + method->named.length;
+                       walk_state->parser_state.start_scope = op;
+
+                       walk_state->descending_callback =
+                           acpi_ds_load1_begin_op;
+                       walk_state->ascending_callback = acpi_ds_load1_end_op;
+
+                       /* Perform the AML parse */
+
+                       status = acpi_ps_parse_aml(walk_state);
+
+                       base_aml_offset =
+                           (method->common.value.arg)->common.aml_offset + 1;
+                       start_op = (method->common.value.arg)->common.next;
+                       search_op = start_op;
+
+                       while (search_op) {
+                               search_op->common.aml_offset += base_aml_offset;
+                               search_op =
+                                   acpi_ps_get_depth_next(start_op, search_op);
+                       }
+               }
+
+               if (op->common.aml_opcode == AML_REGION_OP) {
+
+                       /* TBD: [Investigate] this isn't quite the right thing to do! */
+                       /*
+                        *
+                        * Method = (ACPI_DEFERRED_OP *) Op;
+                        * Status = acpi_ps_parse_aml (Op, Method->Body, Method->body_length);
+                        */
+               }
+
+               if (ACPI_FAILURE(status)) {
+                       break;
+               }
+
+               op = acpi_ps_get_depth_next(root, op);
+       }
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_dump_buffer
+ *
+ * PARAMETERS:  address             - Pointer to the buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a portion of a buffer
+ *
+ ******************************************************************************/
+
+void acpi_db_dump_buffer(u32 address)
+{
+
+       acpi_os_printf("\nLocation %X:\n", address);
+
+       acpi_dbg_level |= ACPI_LV_TABLES;
+       acpi_ut_debug_dump_buffer(ACPI_TO_POINTER(address), 64, DB_BYTE_DISPLAY,
+                                 ACPI_UINT32_MAX);
+}
+#endif
diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c
new file mode 100644 (file)
index 0000000..342298a
--- /dev/null
@@ -0,0 +1,513 @@
+/*******************************************************************************
+ *
+ * Module Name: dbxface - AML Debugger external interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, 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 "amlcode.h"
+#include "acdebug.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbxface")
+
+/* Local prototypes */
+static acpi_status
+acpi_db_start_command(struct acpi_walk_state *walk_state,
+                     union acpi_parse_object *op);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void acpi_db_method_end(struct acpi_walk_state *walk_state);
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_start_command
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              op              - Current executing Op, from AML interpreter
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enter debugger command loop
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_start_command(struct acpi_walk_state *walk_state,
+                     union acpi_parse_object *op)
+{
+       acpi_status status;
+
+       /* TBD: [Investigate] are there namespace locking issues here? */
+
+       /* acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */
+
+       /* Go into the command loop and await next user command */
+
+       acpi_gbl_method_executing = TRUE;
+       status = AE_CTRL_TRUE;
+       while (status == AE_CTRL_TRUE) {
+               if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) {
+
+                       /* Handshake with the front-end that gets user command lines */
+
+                       acpi_os_release_mutex(acpi_gbl_db_command_complete);
+
+                       status =
+                           acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+                                                 ACPI_WAIT_FOREVER);
+                       if (ACPI_FAILURE(status)) {
+                               return (status);
+                       }
+               } else {
+                       /* Single threaded, we must get a command line ourselves */
+
+                       /* Force output to console until a command is entered */
+
+                       acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+
+                       /* Different prompt if method is executing */
+
+                       if (!acpi_gbl_method_executing) {
+                               acpi_os_printf("%1c ",
+                                              ACPI_DEBUGGER_COMMAND_PROMPT);
+                       } else {
+                               acpi_os_printf("%1c ",
+                                              ACPI_DEBUGGER_EXECUTE_PROMPT);
+                       }
+
+                       /* Get the user input line */
+
+                       status = acpi_os_get_line(acpi_gbl_db_line_buf,
+                                                 ACPI_DB_LINE_BUFFER_SIZE,
+                                                 NULL);
+                       if (ACPI_FAILURE(status)) {
+                               ACPI_EXCEPTION((AE_INFO, status,
+                                               "While parsing command line"));
+                               return (status);
+                       }
+               }
+
+               status =
+                   acpi_db_command_dispatch(acpi_gbl_db_line_buf, walk_state,
+                                            op);
+       }
+
+       /* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_single_step
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *              op              - Current executing op (from aml interpreter)
+ *              opcode_class    - Class of the current AML Opcode
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called just before execution of an AML opcode.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_db_single_step(struct acpi_walk_state * walk_state,
+                   union acpi_parse_object * op, u32 opcode_class)
+{
+       union acpi_parse_object *next;
+       acpi_status status = AE_OK;
+       u32 original_debug_level;
+       union acpi_parse_object *display_op;
+       union acpi_parse_object *parent_op;
+       u32 aml_offset;
+
+       ACPI_FUNCTION_ENTRY();
+
+#ifndef ACPI_APPLICATION
+       if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+               return (AE_OK);
+       }
+#endif
+
+       /* Check the abort flag */
+
+       if (acpi_gbl_abort_method) {
+               acpi_gbl_abort_method = FALSE;
+               return (AE_ABORT_METHOD);
+       }
+
+       aml_offset = (u32)ACPI_PTR_DIFF(op->common.aml,
+                                       walk_state->parser_state.aml_start);
+
+       /* Check for single-step breakpoint */
+
+       if (walk_state->method_breakpoint &&
+           (walk_state->method_breakpoint <= aml_offset)) {
+
+               /* Check if the breakpoint has been reached or passed */
+               /* Hit the breakpoint, resume single step, reset breakpoint */
+
+               acpi_os_printf("***Break*** at AML offset %X\n", aml_offset);
+               acpi_gbl_cm_single_step = TRUE;
+               acpi_gbl_step_to_next_call = FALSE;
+               walk_state->method_breakpoint = 0;
+       }
+
+       /* Check for user breakpoint (Must be on exact Aml offset) */
+
+       else if (walk_state->user_breakpoint &&
+                (walk_state->user_breakpoint == aml_offset)) {
+               acpi_os_printf("***UserBreakpoint*** at AML offset %X\n",
+                              aml_offset);
+               acpi_gbl_cm_single_step = TRUE;
+               acpi_gbl_step_to_next_call = FALSE;
+               walk_state->method_breakpoint = 0;
+       }
+
+       /*
+        * Check if this is an opcode that we are interested in --
+        * namely, opcodes that have arguments
+        */
+       if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
+               return (AE_OK);
+       }
+
+       switch (opcode_class) {
+       case AML_CLASS_UNKNOWN:
+       case AML_CLASS_ARGUMENT:        /* constants, literals, etc. do nothing */
+
+               return (AE_OK);
+
+       default:
+
+               /* All other opcodes -- continue */
+               break;
+       }
+
+       /*
+        * Under certain debug conditions, display this opcode and its operands
+        */
+       if ((acpi_gbl_db_output_to_file) ||
+           (acpi_gbl_cm_single_step) || (acpi_dbg_level & ACPI_LV_PARSE)) {
+               if ((acpi_gbl_db_output_to_file) ||
+                   (acpi_dbg_level & ACPI_LV_PARSE)) {
+                       acpi_os_printf
+                           ("\n[AmlDebug] Next AML Opcode to execute:\n");
+               }
+
+               /*
+                * Display this op (and only this op - zero out the NEXT field
+                * temporarily, and disable parser trace output for the duration of
+                * the display because we don't want the extraneous debug output)
+                */
+               original_debug_level = acpi_dbg_level;
+               acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
+               next = op->common.next;
+               op->common.next = NULL;
+
+               display_op = op;
+               parent_op = op->common.parent;
+               if (parent_op) {
+                       if ((walk_state->control_state) &&
+                           (walk_state->control_state->common.state ==
+                            ACPI_CONTROL_PREDICATE_EXECUTING)) {
+                               /*
+                                * We are executing the predicate of an IF or WHILE statement
+                                * Search upwards for the containing IF or WHILE so that the
+                                * entire predicate can be displayed.
+                                */
+                               while (parent_op) {
+                                       if ((parent_op->common.aml_opcode ==
+                                            AML_IF_OP)
+                                           || (parent_op->common.aml_opcode ==
+                                               AML_WHILE_OP)) {
+                                               display_op = parent_op;
+                                               break;
+                                       }
+                                       parent_op = parent_op->common.parent;
+                               }
+                       } else {
+                               while (parent_op) {
+                                       if ((parent_op->common.aml_opcode ==
+                                            AML_IF_OP)
+                                           || (parent_op->common.aml_opcode ==
+                                               AML_ELSE_OP)
+                                           || (parent_op->common.aml_opcode ==
+                                               AML_SCOPE_OP)
+                                           || (parent_op->common.aml_opcode ==
+                                               AML_METHOD_OP)
+                                           || (parent_op->common.aml_opcode ==
+                                               AML_WHILE_OP)) {
+                                               break;
+                                       }
+                                       display_op = parent_op;
+                                       parent_op = parent_op->common.parent;
+                               }
+                       }
+               }
+
+               /* Now we can display it */
+
+#ifdef ACPI_DISASSEMBLER
+               acpi_dm_disassemble(walk_state, display_op, ACPI_UINT32_MAX);
+#endif
+
+               if ((op->common.aml_opcode == AML_IF_OP) ||
+                   (op->common.aml_opcode == AML_WHILE_OP)) {
+                       if (walk_state->control_state->common.value) {
+                               acpi_os_printf
+                                   ("Predicate = [True], IF block was executed\n");
+                       } else {
+                               acpi_os_printf
+                                   ("Predicate = [False], Skipping IF block\n");
+                       }
+               } else if (op->common.aml_opcode == AML_ELSE_OP) {
+                       acpi_os_printf
+                           ("Predicate = [False], ELSE block was executed\n");
+               }
+
+               /* Restore everything */
+
+               op->common.next = next;
+               acpi_os_printf("\n");
+               if ((acpi_gbl_db_output_to_file) ||
+                   (acpi_dbg_level & ACPI_LV_PARSE)) {
+                       acpi_os_printf("\n");
+               }
+               acpi_dbg_level = original_debug_level;
+       }
+
+       /* If we are not single stepping, just continue executing the method */
+
+       if (!acpi_gbl_cm_single_step) {
+               return (AE_OK);
+       }
+
+       /*
+        * If we are executing a step-to-call command,
+        * Check if this is a method call.
+        */
+       if (acpi_gbl_step_to_next_call) {
+               if (op->common.aml_opcode != AML_INT_METHODCALL_OP) {
+
+                       /* Not a method call, just keep executing */
+
+                       return (AE_OK);
+               }
+
+               /* Found a method call, stop executing */
+
+               acpi_gbl_step_to_next_call = FALSE;
+       }
+
+       /*
+        * If the next opcode is a method call, we will "step over" it
+        * by default.
+        */
+       if (op->common.aml_opcode == AML_INT_METHODCALL_OP) {
+
+               /* Force no more single stepping while executing called method */
+
+               acpi_gbl_cm_single_step = FALSE;
+
+               /*
+                * Set the breakpoint on/before the call, it will stop execution
+                * as soon as we return
+                */
+               walk_state->method_breakpoint = 1;      /* Must be non-zero! */
+       }
+
+       status = acpi_db_start_command(walk_state, op);
+
+       /* User commands complete, continue execution of the interrupted method */
+
+       return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_debugger
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Init and start debugger
+ *
+ ******************************************************************************/
+
+acpi_status acpi_initialize_debugger(void)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_initialize_debugger);
+
+       /* Init globals */
+
+       acpi_gbl_db_buffer = NULL;
+       acpi_gbl_db_filename = NULL;
+       acpi_gbl_db_output_to_file = FALSE;
+
+       acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2;
+       acpi_gbl_db_console_debug_level = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
+       acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+
+       acpi_gbl_db_opt_no_ini_methods = FALSE;
+
+       acpi_gbl_db_buffer = acpi_os_allocate(ACPI_DEBUG_BUFFER_SIZE);
+       if (!acpi_gbl_db_buffer) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
+       }
+       memset(acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE);
+
+       /* Initial scope is the root */
+
+       acpi_gbl_db_scope_buf[0] = AML_ROOT_PREFIX;
+       acpi_gbl_db_scope_buf[1] = 0;
+       acpi_gbl_db_scope_node = acpi_gbl_root_node;
+
+       /* Initialize user commands loop */
+
+       acpi_gbl_db_terminate_loop = FALSE;
+
+       /*
+        * If configured for multi-thread support, the debug executor runs in
+        * a separate thread so that the front end can be in another address
+        * space, environment, or even another machine.
+        */
+       if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+
+               /* These were created with one unit, grab it */
+
+               status = acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
+                                              ACPI_WAIT_FOREVER);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not get debugger mutex\n");
+                       return_ACPI_STATUS(status);
+               }
+
+               status = acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
+                                              ACPI_WAIT_FOREVER);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("Could not get debugger mutex\n");
+                       return_ACPI_STATUS(status);
+               }
+
+               /* Create the debug execution thread to execute commands */
+
+               acpi_gbl_db_threads_terminated = FALSE;
+               status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
+                                        acpi_db_execute_thread, NULL);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_EXCEPTION((AE_INFO, status,
+                                       "Could not start debugger thread"));
+                       acpi_gbl_db_threads_terminated = TRUE;
+                       return_ACPI_STATUS(status);
+               }
+       } else {
+               acpi_gbl_db_thread_id = acpi_os_get_thread_id();
+       }
+
+       return_ACPI_STATUS(AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_terminate_debugger
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Stop debugger
+ *
+ ******************************************************************************/
+void acpi_terminate_debugger(void)
+{
+
+       /* Terminate the AML Debugger */
+
+       acpi_gbl_db_terminate_loop = TRUE;
+
+       if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+               acpi_os_release_mutex(acpi_gbl_db_command_ready);
+
+               /* Wait the AML Debugger threads */
+
+               while (!acpi_gbl_db_threads_terminated) {
+                       acpi_os_sleep(100);
+               }
+       }
+
+       if (acpi_gbl_db_buffer) {
+               acpi_os_free(acpi_gbl_db_buffer);
+               acpi_gbl_db_buffer = NULL;
+       }
+
+       /* Ensure that debug output is now disabled */
+
+       acpi_gbl_db_output_flags = ACPI_DB_DISABLE_OUTPUT;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_debugger_thread_id
+ *
+ * PARAMETERS:  thread_id       - Debugger thread ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set debugger thread ID
+ *
+ ******************************************************************************/
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
+{
+       acpi_gbl_db_thread_id = thread_id;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)
index 81f2d9e87fad518369acc5eaca9d99172f22fdf5..07d22bfbaa00d99f8f549d0deb94cd688122177e 100644 (file)
@@ -405,7 +405,7 @@ cleanup:
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
-#endif                         /*  ACPI_FUTURE_USAGE  */
+#endif
 
 #if (!ACPI_REDUCED_HARDWARE)
 /*******************************************************************************
index faad911d46b5eb71c4ae93a5300cf460e63c8738..10ce48e16ebf43a334fdc2f13479572d9bca4bd1 100644 (file)
@@ -71,7 +71,7 @@ acpi_status acpi_enable(void)
 
        /* ACPI tables must be present */
 
-       if (!acpi_tb_tables_loaded()) {
+       if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
                return_ACPI_STATUS(AE_NO_ACPI_TABLES);
        }
 
index 075d654c837f27e767ebed874e68140b97fc12ff..1e4c5b6dc0b0ed400056cf59097875bf8a99ccfd 100644 (file)
@@ -618,6 +618,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
                break;
 
        case ARGI_TARGETREF:
+       case ARGI_STORE_TARGET:
 
                switch (destination_type) {
                case ACPI_TYPE_INTEGER:
index 7b109128b0350f0579fdf0b96fe0c74f949887b0..a1afe1a1e7c2cada36b9a6763bd81f3efa205dfa 100644 (file)
@@ -209,7 +209,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                                         * (i.e., dereference the package index)
                                         * Delete the ref object, increment the returned object
                                         */
-                                       acpi_ut_remove_reference(stack_desc);
                                        acpi_ut_add_reference(obj_desc);
                                        *stack_ptr = obj_desc;
                                } else {
index d2964af9ad4df52e9846c02a7e129e7d0f8c0ea2..424442d50b5e474c4a40eed1cb531af2aeede393 100644 (file)
@@ -307,6 +307,8 @@ acpi_ex_resolve_operands(u16 opcode,
                case ARGI_TARGETREF:    /* Allows implicit conversion rules before store */
                case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
                case ARGI_SIMPLE_TARGET:        /* Name, Local, or arg - no implicit conversion  */
+               case ARGI_STORE_TARGET:
+
                        /*
                         * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
                         * A Namespace Node is OK as-is
index a7eee2400ce01a592bcbe736745a6d3f0e6190f4..c076e9100d66823d332e382ab05c7b694f56b82e 100644 (file)
@@ -137,7 +137,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
                /* Destination is not a Reference object */
 
                ACPI_ERROR((AE_INFO,
-                           "Target is not a Reference or Constant object - %s [%p]",
+                           "Target is not a Reference or Constant object - [%s] %p",
                            acpi_ut_get_object_type_name(dest_desc),
                            dest_desc));
 
@@ -189,7 +189,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
                 * displayed and otherwise has no effect -- see ACPI Specification
                 */
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "**** Write to Debug Object: Object %p %s ****:\n\n",
+                                 "**** Write to Debug Object: Object %p [%s] ****:\n\n",
                                  source_desc,
                                  acpi_ut_get_object_type_name(source_desc)));
 
@@ -341,7 +341,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
                        /* All other types are invalid */
 
                        ACPI_ERROR((AE_INFO,
-                                   "Source must be Integer/Buffer/String type, not %s",
+                                   "Source must be type [Integer/Buffer/String], found [%s]",
                                    acpi_ut_get_object_type_name(source_desc)));
                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                }
@@ -352,8 +352,9 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
                break;
 
        default:
-               ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
-               status = AE_AML_OPERAND_TYPE;
+               ACPI_ERROR((AE_INFO,
+                           "Target is not of type [Package/BufferField]"));
+               status = AE_AML_TARGET_TYPE;
                break;
        }
 
@@ -373,20 +374,20 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
  *
  * DESCRIPTION: Store the object to the named object.
  *
- *              The Assignment of an object to a named object is handled here
- *              The value passed in will replace the current value (if any)
- *              with the input value.
+ * The assignment of an object to a named object is handled here.
+ * The value passed in will replace the current value (if any)
+ * with the input value.
  *
- *              When storing into an object the data is converted to the
- *              target object type then stored in the object. This means
- *              that the target object type (for an initialized target) will
- *              not be changed by a store operation. A copy_object can change
- *              the target type, however.
+ * When storing into an object the data is converted to the
+ * target object type then stored in the object. This means
+ * that the target object type (for an initialized target) will
+ * not be changed by a store operation. A copy_object can change
+ * the target type, however.
  *
- *              The implicit_conversion flag is set to NO/FALSE only when
- *              storing to an arg_x -- as per the rules of the ACPI spec.
+ * The implicit_conversion flag is set to NO/FALSE only when
+ * storing to an arg_x -- as per the rules of the ACPI spec.
  *
- *              Assumes parameters are already validated.
+ * Assumes parameters are already validated.
  *
  ******************************************************************************/
 
@@ -408,11 +409,75 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
        target_type = acpi_ns_get_type(node);
        target_desc = acpi_ns_get_attached_object(node);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
                          source_desc,
                          acpi_ut_get_object_type_name(source_desc), node,
                          acpi_ut_get_type_name(target_type)));
 
+       /* Only limited target types possible for everything except copy_object */
+
+       if (walk_state->opcode != AML_COPY_OP) {
+               /*
+                * Only copy_object allows all object types to be overwritten. For
+                * target_ref(s), there are restrictions on the object types that
+                * are allowed.
+                *
+                * Allowable operations/typing for Store:
+                *
+                * 1) Simple Store
+                *      Integer     --> Integer (Named/Local/Arg)
+                *      String      --> String  (Named/Local/Arg)
+                *      Buffer      --> Buffer  (Named/Local/Arg)
+                *      Package     --> Package (Named/Local/Arg)
+                *
+                * 2) Store with implicit conversion
+                *      Integer     --> String or Buffer  (Named)
+                *      String      --> Integer or Buffer (Named)
+                *      Buffer      --> Integer or String (Named)
+                */
+               switch (target_type) {
+               case ACPI_TYPE_PACKAGE:
+                       /*
+                        * Here, can only store a package to an existing package.
+                        * Storing a package to a Local/Arg is OK, and handled
+                        * elsewhere.
+                        */
+                       if (walk_state->opcode == AML_STORE_OP) {
+                               if (source_desc->common.type !=
+                                   ACPI_TYPE_PACKAGE) {
+                                       ACPI_ERROR((AE_INFO,
+                                                   "Cannot assign type [%s] to [Package] "
+                                                   "(source must be type Pkg)",
+                                                   acpi_ut_get_object_type_name
+                                                   (source_desc)));
+
+                                       return_ACPI_STATUS(AE_AML_TARGET_TYPE);
+                               }
+                               break;
+                       }
+
+                       /* Fallthrough */
+
+               case ACPI_TYPE_DEVICE:
+               case ACPI_TYPE_EVENT:
+               case ACPI_TYPE_MUTEX:
+               case ACPI_TYPE_REGION:
+               case ACPI_TYPE_POWER:
+               case ACPI_TYPE_PROCESSOR:
+               case ACPI_TYPE_THERMAL:
+
+                       ACPI_ERROR((AE_INFO,
+                                   "Target must be [Buffer/Integer/String/Reference], found [%s] (%4.4s)",
+                                   acpi_ut_get_type_name(node->type),
+                                   node->name.ascii));
+
+                       return_ACPI_STATUS(AE_AML_TARGET_TYPE);
+
+               default:
+                       break;
+               }
+       }
+
        /*
         * Resolve the source object to an actual value
         * (If it is a reference object)
@@ -425,13 +490,13 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
        /* Do the actual store operation */
 
        switch (target_type) {
-       case ACPI_TYPE_INTEGER:
-       case ACPI_TYPE_STRING:
-       case ACPI_TYPE_BUFFER:
                /*
                 * The simple data types all support implicit source operand
                 * conversion before the store.
                 */
+       case ACPI_TYPE_INTEGER:
+       case ACPI_TYPE_STRING:
+       case ACPI_TYPE_BUFFER:
 
                if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
                        /*
@@ -467,7 +532,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
                                                       new_desc->common.type);
 
                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                         "Store %s into %s via Convert/Attach\n",
+                                         "Store type [%s] into [%s] via Convert/Attach\n",
                                          acpi_ut_get_object_type_name
                                          (source_desc),
                                          acpi_ut_get_object_type_name
@@ -491,15 +556,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
 
        default:
                /*
-                * No conversions for all other types. Directly store a copy of
-                * the source object. This is the ACPI spec-defined behavior for
-                * the copy_object operator.
+                * copy_object operator: No conversions for all other types.
+                * Instead, directly store a copy of the source object.
                 *
-                * NOTE: For the Store operator, this is a departure from the
-                * ACPI spec, which states "If conversion is impossible, abort
-                * the running control method". Instead, this code implements
-                * "If conversion is impossible, treat the Store operation as
-                * a CopyObject".
+                * This is the ACPI spec-defined behavior for the copy_object
+                * operator. (Note, for this default case, all normal
+                * Store/Target operations exited above with an error).
                 */
                status = acpi_ex_store_direct_to_node(source_desc, node,
                                                      walk_state);
index 3101607b4efeaa5721e1cd62752ff27d576e928c..d1841defa6690c053aa7e283fbf29af526a04846 100644 (file)
@@ -122,9 +122,10 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
                        /* Conversion successful but still not a valid type */
 
                        ACPI_ERROR((AE_INFO,
-                                   "Cannot assign type %s to %s (must be type Int/Str/Buf)",
+                                   "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
                                    acpi_ut_get_object_type_name(source_desc),
                                    acpi_ut_get_type_name(target_type)));
+
                        status = AE_AML_OPERAND_TYPE;
                }
                break;
@@ -275,7 +276,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
                /*
                 * All other types come here.
                 */
-               ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
+               ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
                              acpi_ut_get_object_type_name(dest_desc)));
 
                status = AE_NOT_IMPLEMENTED;
index 0f1daba640e7a5f70c5a6f0196398f65551219d8..37aa5c45ca4b1936dbf18a00a4c40537505c3e2f 100644 (file)
@@ -60,7 +60,6 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
-#ifdef ACPI_FUTURE_USAGE
 static acpi_status
 acpi_ns_dump_one_object_path(acpi_handle obj_handle,
                             u32 level, void *context, void **return_value);
@@ -68,7 +67,6 @@ acpi_ns_dump_one_object_path(acpi_handle obj_handle,
 static acpi_status
 acpi_ns_get_max_depth(acpi_handle obj_handle,
                      u32 level, void *context, void **return_value);
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
@@ -625,7 +623,6 @@ cleanup:
        return (AE_OK);
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_objects
@@ -680,9 +677,7 @@ acpi_ns_dump_objects(acpi_object_type type,
 
        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif                         /* ACPI_FUTURE_USAGE */
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_one_object_path, acpi_ns_get_max_depth
@@ -810,7 +805,6 @@ acpi_ns_dump_object_paths(acpi_object_type type,
 
        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
index 0eb54315b4bebbd131c5b4c9ae40909ea0ca61b7..0c20980bbcf3dd4a49be177b937dade77ebdb49a 100644 (file)
@@ -226,7 +226,7 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info,
 {
        union acpi_operand_object *return_object = *return_object_ptr;
        acpi_status status = AE_OK;
-       char type_buffer[48];   /* Room for 5 types */
+       char type_buffer[96];   /* Room for 10 types */
 
        /* A Namespace node should not get here, but make sure */
 
index 89984f30addca71dfe02080335daec6ea2c0067d..cf2f2faf4f92098cedf4b0583320743820b90f9e 100644 (file)
@@ -183,7 +183,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
        }
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_get_depth_next
@@ -317,4 +316,3 @@ union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
        return (child);
 }
 #endif
-#endif                         /*  ACPI_FUTURE_USAGE  */
index 183cc1efbc5182d990dacaa88b5bff1471d2ee8b..71d2877cd2cefa9c1a98bcae4e3dbb686a20ffea 100644 (file)
@@ -205,7 +205,6 @@ u8 acpi_ps_is_leading_char(u32 c)
 /*
  * Get op's name (4-byte name segment) or 0 if unnamed
  */
-#ifdef ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object * op)
 {
 
@@ -219,7 +218,6 @@ u32 acpi_ps_get_name(union acpi_parse_object * op)
 
        return (op->named.name);
 }
-#endif                         /*  ACPI_FUTURE_USAGE  */
 
 /*
  * Set op's name
index c428bb33204ee89cd01fcb84d0e7e8e8e080a4dc..2a09288e7c57c3d1a6df3a0f93dc9a3b49ed24ac 100644 (file)
@@ -51,7 +51,6 @@ ACPI_MODULE_NAME("rsdump")
 /*
  * All functions in this module are used by the AML Debugger only
  */
-#if defined(ACPI_DEBUGGER)
 /* Local prototypes */
 static void acpi_rs_out_string(char *title, char *value);
 
@@ -565,5 +564,3 @@ static void acpi_rs_dump_word_list(u16 length, u16 *data)
                acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
        }
 }
-
-#endif
index 52b024df00524bffae3bb1117cffa0d3dc31eb3b..9486992edbb82b5c29094352b6d0eea536f7046d 100644 (file)
@@ -564,7 +564,6 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
  *
  ******************************************************************************/
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
                            struct acpi_buffer *ret_buffer)
@@ -596,7 +595,6 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
        acpi_ut_remove_reference(obj_desc);
        return_ACPI_STATUS(status);
 }
-#endif                         /*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
  *
index de51f836ef68e23280897bda0aca300b5341db90..1e8cd572332640fe5a6faa9db3a64f3ff0b56b07 100644 (file)
@@ -220,7 +220,7 @@ acpi_get_current_resources(acpi_handle device_handle,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
-#ifdef ACPI_FUTURE_USAGE
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_possible_resources
@@ -262,7 +262,7 @@ acpi_get_possible_resources(acpi_handle device_handle,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
-#endif                         /*  ACPI_FUTURE_USAGE  */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_current_resources
index 455a0700db392b1663a16c392d8da3bb544b72b6..a6454f4a6fb343b52cada9dc5394094768c6ea14 100644 (file)
@@ -298,7 +298,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
  *
  * FUNCTION:    acpi_tb_parse_fadt
  *
- * PARAMETERS:  table_index         - Index for the FADT
+ * PARAMETERS:  None
  *
  * RETURN:      None
  *
@@ -307,7 +307,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
  *
  ******************************************************************************/
 
-void acpi_tb_parse_fadt(u32 table_index)
+void acpi_tb_parse_fadt(void)
 {
        u32 length;
        struct acpi_table_header *table;
@@ -319,11 +319,11 @@ void acpi_tb_parse_fadt(u32 table_index)
         * Get a local copy of the FADT and convert it to a common format
         * Map entire FADT, assumed to be smaller than one page.
         */
-       length = acpi_gbl_root_table_list.tables[table_index].length;
+       length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
 
        table =
-           acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
-                              address, length);
+           acpi_os_map_memory(acpi_gbl_root_table_list.
+                              tables[acpi_gbl_fadt_index].address, length);
        if (!table) {
                return;
        }
index 4337990127cc39930b50983d7e7eff05966fcfb6..d8ddef38c947f750a226cee1b69fa373c9e1bf8f 100644 (file)
@@ -97,29 +97,6 @@ acpi_status acpi_tb_initialize_facs(void)
 }
 #endif                         /* !ACPI_REDUCED_HARDWARE */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_tables_loaded
- *
- * PARAMETERS:  None
- *
- * RETURN:      TRUE if required ACPI tables are loaded
- *
- * DESCRIPTION: Determine if the minimum required ACPI tables are present
- *              (FADT, FACS, DSDT)
- *
- ******************************************************************************/
-
-u8 acpi_tb_tables_loaded(void)
-{
-
-       if (acpi_gbl_root_table_list.current_table_count >= 4) {
-               return (TRUE);
-       }
-
-       return (FALSE);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_check_dsdt_header
@@ -392,7 +369,8 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
                    ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
                                      tables[table_index].signature,
                                      ACPI_SIG_FADT)) {
-                       acpi_tb_parse_fadt(table_index);
+                       acpi_gbl_fadt_index = table_index;
+                       acpi_tb_parse_fadt();
                }
 
 next_table:
index 988e23b7795caaaa40f6a4320310f1d8c1026085..ecaaaffc078813a2429ce86470e3fbe7e0c5544c 100644 (file)
@@ -232,12 +232,27 @@ char *acpi_ut_get_type_name(acpi_object_type type)
 
 char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
 {
+       ACPI_FUNCTION_TRACE(ut_get_object_type_name);
 
        if (!obj_desc) {
-               return ("[NULL Object Descriptor]");
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+               return_PTR("[NULL Object Descriptor]");
        }
 
-       return (acpi_ut_get_type_name(obj_desc->common.type));
+       /* These descriptor types share a common area */
+
+       if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) &&
+           (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_NAMED)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "Invalid object descriptor type: 0x%2.2X [%s] (%p)\n",
+                                 ACPI_GET_DESCRIPTOR_TYPE(obj_desc),
+                                 acpi_ut_get_descriptor_name(obj_desc),
+                                 obj_desc));
+
+               return_PTR("Invalid object");
+       }
+
+       return_PTR(acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
@@ -407,8 +422,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
        "ACPI_MTX_Events",
        "ACPI_MTX_Caches",
        "ACPI_MTX_Memory",
-       "ACPI_MTX_CommandComplete",
-       "ACPI_MTX_CommandReady"
 };
 
 char *acpi_ut_get_mutex_name(u32 mutex_id)
index 75a94f52b4bee07df7ac5722b64276bad82e42f4..d435b7b7eb948416db9e7d397e482c8ebd8e0743 100644 (file)
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include "acapps.h"
+#include "errno.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "aslcompiler.h"
@@ -301,6 +302,11 @@ acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
        file = fopen(filename, "rb");
        if (!file) {
                perror("Could not open input file");
+
+               if (errno == ENOENT) {
+                       return (AE_NOT_EXIST);
+               }
+
                return (status);
        }
 
index 28ab3a1d5ec1632b07b77b037869d4e7c815a167..ccd0745f011e886619dd2b891e51d23df372e08a 100644 (file)
@@ -241,8 +241,6 @@ acpi_status acpi_ut_init_globals(void)
        acpi_gbl_disable_mem_tracking = FALSE;
 #endif
 
-       ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
-
        return_ACPI_STATUS(AE_OK);
 }
 
@@ -284,6 +282,19 @@ void acpi_ut_subsystem_shutdown(void)
 {
        ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
 
+       /* Just exit if subsystem is already shutdown */
+
+       if (acpi_gbl_shutdown) {
+               ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
+               return_VOID;
+       }
+
+       /* Subsystem appears active, go ahead and shut it down */
+
+       acpi_gbl_shutdown = TRUE;
+       acpi_gbl_startup_flags = 0;
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
 #ifndef ACPI_ASL_COMPILER
 
        /* Close the acpi_event Handling */
index 37b8b58fcd565e563879f331be4cf983ae4c9f5f..ce406e39b669cd336b95b7b39c73dfa1c317b361 100644 (file)
@@ -108,6 +108,21 @@ acpi_status acpi_ut_mutex_initialize(void)
        /* Create the reader/writer lock for namespace access */
 
        status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+#ifdef ACPI_DEBUGGER
+
+       /* Debugger Support */
+
+       status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
+#endif
+
        return_ACPI_STATUS(status);
 }
 
@@ -147,6 +162,12 @@ void acpi_ut_mutex_terminate(void)
        /* Delete the reader/writer lock */
 
        acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
+
+#ifdef ACPI_DEBUGGER
+       acpi_os_delete_mutex(acpi_gbl_db_command_ready);
+       acpi_os_delete_mutex(acpi_gbl_db_command_complete);
+#endif
+
        return_VOID;
 }
 
index 4f332815db00c1356f2a3dd357d32349a92169ec..f9c8f9ce1f0f3e315d00db27e5e5623b92f278fa 100644 (file)
@@ -67,23 +67,6 @@ acpi_status __init acpi_terminate(void)
 
        ACPI_FUNCTION_TRACE(acpi_terminate);
 
-       /* Just exit if subsystem is already shutdown */
-
-       if (acpi_gbl_shutdown) {
-               ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
-               return_ACPI_STATUS(AE_OK);
-       }
-
-       /* Subsystem appears active, go ahead and shut it down */
-
-       acpi_gbl_shutdown = TRUE;
-       acpi_gbl_startup_flags = 0;
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
-
-       /* Terminate the AML Debugger if present */
-
-       ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
-
        /* Shutdown and free all resources */
 
        acpi_ut_subsystem_shutdown();
@@ -270,7 +253,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
-#endif                         /*  ACPI_FUTURE_USAGE  */
+#endif
 
 /*****************************************************************************
  *
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
new file mode 100644 (file)
index 0000000..3c083d2
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) methods used by CPUfreq drivers.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * CPPC describes a few methods for controlling CPU performance using
+ * information from a per CPU table called CPC. This table is described in
+ * the ACPI v5.0+ specification. The table consists of a list of
+ * registers which may be memory mapped or hardware registers and also may
+ * include some static integer values.
+ *
+ * CPU performance is on an abstract continuous scale as against a discretized
+ * P-state scale which is tied to CPU frequency only. In brief, the basic
+ * operation involves:
+ *
+ * - OS makes a CPU performance request. (Can provide min and max bounds)
+ *
+ * - Platform (such as BMC) is free to optimize request within requested bounds
+ *   depending on power/thermal budgets etc.
+ *
+ * - Platform conveys its decision back to OS
+ *
+ * The communication between OS and platform occurs through another medium
+ * called (PCC) Platform Communication Channel. This is a generic mailbox like
+ * mechanism which includes doorbell semantics to indicate register updates.
+ * See drivers/mailbox/pcc.c for details on PCC.
+ *
+ * Finer details about the PCC and CPPC spec are available in the ACPI v5.1 and
+ * above specifications.
+ */
+
+#define pr_fmt(fmt)    "ACPI CPPC: " fmt
+
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+
+#include <acpi/cppc_acpi.h>
+/*
+ * Lock to provide mutually exclusive access to the PCC
+ * channel. e.g. When the remote updates the shared region
+ * with new data, the reader needs to be protected from
+ * other CPUs activity on the same channel.
+ */
+static DEFINE_SPINLOCK(pcc_lock);
+
+/*
+ * The cpc_desc structure contains the ACPI register details
+ * as described in the per CPU _CPC tables. The details
+ * include the type of register (e.g. PCC, System IO, FFH etc.)
+ * and destination addresses which lets us READ/WRITE CPU performance
+ * information using the appropriate I/O methods.
+ */
+static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
+
+/* This layer handles all the PCC specifics for CPPC. */
+static struct mbox_chan *pcc_channel;
+static void __iomem *pcc_comm_addr;
+static u64 comm_base_addr;
+static int pcc_subspace_idx = -1;
+static u16 pcc_cmd_delay;
+static bool pcc_channel_acquired;
+
+/*
+ * Arbitrary Retries in case the remote processor is slow to respond
+ * to PCC commands.
+ */
+#define NUM_RETRIES 500
+
+static int send_pcc_cmd(u16 cmd)
+{
+       int retries, result = -EIO;
+       struct acpi_pcct_hw_reduced *pcct_ss = pcc_channel->con_priv;
+       struct acpi_pcct_shared_memory *generic_comm_base =
+               (struct acpi_pcct_shared_memory *) pcc_comm_addr;
+       u32 cmd_latency = pcct_ss->latency;
+
+       /* Min time OS should wait before sending next command. */
+       udelay(pcc_cmd_delay);
+
+       /* Write to the shared comm region. */
+       writew(cmd, &generic_comm_base->command);
+
+       /* Flip CMD COMPLETE bit */
+       writew(0, &generic_comm_base->status);
+
+       /* Ring doorbell */
+       result = mbox_send_message(pcc_channel, &cmd);
+       if (result < 0) {
+               pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n",
+                               cmd, result);
+               return result;
+       }
+
+       /* Wait for a nominal time to let platform process command. */
+       udelay(cmd_latency);
+
+       /* Retry in case the remote processor was too slow to catch up. */
+       for (retries = NUM_RETRIES; retries > 0; retries--) {
+               if (readw_relaxed(&generic_comm_base->status) & PCC_CMD_COMPLETE) {
+                       result = 0;
+                       break;
+               }
+       }
+
+       mbox_client_txdone(pcc_channel, result);
+       return result;
+}
+
+static void cppc_chan_tx_done(struct mbox_client *cl, void *msg, int ret)
+{
+       if (ret)
+               pr_debug("TX did not complete: CMD sent:%x, ret:%d\n",
+                               *(u16 *)msg, ret);
+       else
+               pr_debug("TX completed. CMD sent:%x, ret:%d\n",
+                               *(u16 *)msg, ret);
+}
+
+struct mbox_client cppc_mbox_cl = {
+       .tx_done = cppc_chan_tx_done,
+       .knows_txdone = true,
+};
+
+static int acpi_get_psd(struct cpc_desc *cpc_ptr, acpi_handle handle)
+{
+       int result = -EFAULT;
+       acpi_status status = AE_OK;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
+       struct acpi_buffer state = {0, NULL};
+       union acpi_object  *psd = NULL;
+       struct acpi_psd_package *pdomain;
+
+       status = acpi_evaluate_object_typed(handle, "_PSD", NULL, &buffer,
+                       ACPI_TYPE_PACKAGE);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       psd = buffer.pointer;
+       if (!psd || psd->package.count != 1) {
+               pr_debug("Invalid _PSD data\n");
+               goto end;
+       }
+
+       pdomain = &(cpc_ptr->domain_info);
+
+       state.length = sizeof(struct acpi_psd_package);
+       state.pointer = pdomain;
+
+       status = acpi_extract_package(&(psd->package.elements[0]),
+               &format, &state);
+       if (ACPI_FAILURE(status)) {
+               pr_debug("Invalid _PSD data for CPU:%d\n", cpc_ptr->cpu_id);
+               goto end;
+       }
+
+       if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
+               pr_debug("Unknown _PSD:num_entries for CPU:%d\n", cpc_ptr->cpu_id);
+               goto end;
+       }
+
+       if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
+               pr_debug("Unknown _PSD:revision for CPU: %d\n", cpc_ptr->cpu_id);
+               goto end;
+       }
+
+       if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+           pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+           pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+               pr_debug("Invalid _PSD:coord_type for CPU:%d\n", cpc_ptr->cpu_id);
+               goto end;
+       }
+
+       result = 0;
+end:
+       kfree(buffer.pointer);
+       return result;
+}
+
+/**
+ * acpi_get_psd_map - Map the CPUs in a common freq domain.
+ * @all_cpu_data: Ptrs to CPU specific CPPC data including PSD info.
+ *
+ *     Return: 0 for success or negative value for err.
+ */
+int acpi_get_psd_map(struct cpudata **all_cpu_data)
+{
+       int count_target;
+       int retval = 0;
+       unsigned int i, j;
+       cpumask_var_t covered_cpus;
+       struct cpudata *pr, *match_pr;
+       struct acpi_psd_package *pdomain;
+       struct acpi_psd_package *match_pdomain;
+       struct cpc_desc *cpc_ptr, *match_cpc_ptr;
+
+       if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
+               return -ENOMEM;
+
+       /*
+        * Now that we have _PSD data from all CPUs, lets setup P-state
+        * domain info.
+        */
+       for_each_possible_cpu(i) {
+               pr = all_cpu_data[i];
+               if (!pr)
+                       continue;
+
+               if (cpumask_test_cpu(i, covered_cpus))
+                       continue;
+
+               cpc_ptr = per_cpu(cpc_desc_ptr, i);
+               if (!cpc_ptr)
+                       continue;
+
+               pdomain = &(cpc_ptr->domain_info);
+               cpumask_set_cpu(i, pr->shared_cpu_map);
+               cpumask_set_cpu(i, covered_cpus);
+               if (pdomain->num_processors <= 1)
+                       continue;
+
+               /* Validate the Domain info */
+               count_target = pdomain->num_processors;
+               if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
+                       pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+               else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
+                       pr->shared_type = CPUFREQ_SHARED_TYPE_HW;
+               else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+                       pr->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+               for_each_possible_cpu(j) {
+                       if (i == j)
+                               continue;
+
+                       match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
+                       if (!match_cpc_ptr)
+                               continue;
+
+                       match_pdomain = &(match_cpc_ptr->domain_info);
+                       if (match_pdomain->domain != pdomain->domain)
+                               continue;
+
+                       /* Here i and j are in the same domain */
+                       if (match_pdomain->num_processors != count_target) {
+                               retval = -EFAULT;
+                               goto err_ret;
+                       }
+
+                       if (pdomain->coord_type != match_pdomain->coord_type) {
+                               retval = -EFAULT;
+                               goto err_ret;
+                       }
+
+                       cpumask_set_cpu(j, covered_cpus);
+                       cpumask_set_cpu(j, pr->shared_cpu_map);
+               }
+
+               for_each_possible_cpu(j) {
+                       if (i == j)
+                               continue;
+
+                       match_pr = all_cpu_data[j];
+                       if (!match_pr)
+                               continue;
+
+                       match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
+                       if (!match_cpc_ptr)
+                               continue;
+
+                       match_pdomain = &(match_cpc_ptr->domain_info);
+                       if (match_pdomain->domain != pdomain->domain)
+                               continue;
+
+                       match_pr->shared_type = pr->shared_type;
+                       cpumask_copy(match_pr->shared_cpu_map,
+                                    pr->shared_cpu_map);
+               }
+       }
+
+err_ret:
+       for_each_possible_cpu(i) {
+               pr = all_cpu_data[i];
+               if (!pr)
+                       continue;
+
+               /* Assume no coordination on any error parsing domain info */
+               if (retval) {
+                       cpumask_clear(pr->shared_cpu_map);
+                       cpumask_set_cpu(i, pr->shared_cpu_map);
+                       pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+               }
+       }
+
+       free_cpumask_var(covered_cpus);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(acpi_get_psd_map);
+
+static int register_pcc_channel(int pcc_subspace_idx)
+{
+       struct acpi_pcct_subspace *cppc_ss;
+       unsigned int len;
+
+       if (pcc_subspace_idx >= 0) {
+               pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl,
+                               pcc_subspace_idx);
+
+               if (IS_ERR(pcc_channel)) {
+                       pr_err("Failed to find PCC communication channel\n");
+                       return -ENODEV;
+               }
+
+               /*
+                * The PCC mailbox controller driver should
+                * have parsed the PCCT (global table of all
+                * PCC channels) and stored pointers to the
+                * subspace communication region in con_priv.
+                */
+               cppc_ss = pcc_channel->con_priv;
+
+               if (!cppc_ss) {
+                       pr_err("No PCC subspace found for CPPC\n");
+                       return -ENODEV;
+               }
+
+               /*
+                * This is the shared communication region
+                * for the OS and Platform to communicate over.
+                */
+               comm_base_addr = cppc_ss->base_address;
+               len = cppc_ss->length;
+               pcc_cmd_delay = cppc_ss->min_turnaround_time;
+
+               pcc_comm_addr = acpi_os_ioremap(comm_base_addr, len);
+               if (!pcc_comm_addr) {
+                       pr_err("Failed to ioremap PCC comm region mem\n");
+                       return -ENOMEM;
+               }
+
+               /* Set flag so that we dont come here for each CPU. */
+               pcc_channel_acquired = true;
+       }
+
+       return 0;
+}
+
+/*
+ * An example CPC table looks like the following.
+ *
+ *     Name(_CPC, Package()
+ *                     {
+ *                     17,
+ *                     NumEntries
+ *                     1,
+ *                     // Revision
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x120, 2)},
+ *                     // Highest Performance
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x124, 2)},
+ *                     // Nominal Performance
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x128, 2)},
+ *                     // Lowest Nonlinear Performance
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x12C, 2)},
+ *                     // Lowest Performance
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x130, 2)},
+ *                     // Guaranteed Performance Register
+ *                     ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)},
+ *                     // Desired Performance Register
+ *                     ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},
+ *                     ..
+ *                     ..
+ *                     ..
+ *
+ *             }
+ * Each Register() encodes how to access that specific register.
+ * e.g. a sample PCC entry has the following encoding:
+ *
+ *     Register (
+ *             PCC,
+ *             AddressSpaceKeyword
+ *             8,
+ *             //RegisterBitWidth
+ *             8,
+ *             //RegisterBitOffset
+ *             0x30,
+ *             //RegisterAddress
+ *             9
+ *             //AccessSize (subspace ID)
+ *             0
+ *             )
+ *     }
+ */
+
+/**
+ * acpi_cppc_processor_probe - Search for per CPU _CPC objects.
+ * @pr: Ptr to acpi_processor containing this CPUs logical Id.
+ *
+ *     Return: 0 for success or negative value for err.
+ */
+int acpi_cppc_processor_probe(struct acpi_processor *pr)
+{
+       struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *out_obj, *cpc_obj;
+       struct cpc_desc *cpc_ptr;
+       struct cpc_reg *gas_t;
+       acpi_handle handle = pr->handle;
+       unsigned int num_ent, i, cpc_rev;
+       acpi_status status;
+       int ret = -EFAULT;
+
+       /* Parse the ACPI _CPC table for this cpu. */
+       status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
+                       ACPI_TYPE_PACKAGE);
+       if (ACPI_FAILURE(status)) {
+               ret = -ENODEV;
+               goto out_buf_free;
+       }
+
+       out_obj = (union acpi_object *) output.pointer;
+
+       cpc_ptr = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL);
+       if (!cpc_ptr) {
+               ret = -ENOMEM;
+               goto out_buf_free;
+       }
+
+       /* First entry is NumEntries. */
+       cpc_obj = &out_obj->package.elements[0];
+       if (cpc_obj->type == ACPI_TYPE_INTEGER) {
+               num_ent = cpc_obj->integer.value;
+       } else {
+               pr_debug("Unexpected entry type(%d) for NumEntries\n",
+                               cpc_obj->type);
+               goto out_free;
+       }
+
+       /* Only support CPPCv2. Bail otherwise. */
+       if (num_ent != CPPC_NUM_ENT) {
+               pr_debug("Firmware exports %d entries. Expected: %d\n",
+                               num_ent, CPPC_NUM_ENT);
+               goto out_free;
+       }
+
+       /* Second entry should be revision. */
+       cpc_obj = &out_obj->package.elements[1];
+       if (cpc_obj->type == ACPI_TYPE_INTEGER) {
+               cpc_rev = cpc_obj->integer.value;
+       } else {
+               pr_debug("Unexpected entry type(%d) for Revision\n",
+                               cpc_obj->type);
+               goto out_free;
+       }
+
+       if (cpc_rev != CPPC_REV) {
+               pr_debug("Firmware exports revision:%d. Expected:%d\n",
+                               cpc_rev, CPPC_REV);
+               goto out_free;
+       }
+
+       /* Iterate through remaining entries in _CPC */
+       for (i = 2; i < num_ent; i++) {
+               cpc_obj = &out_obj->package.elements[i];
+
+               if (cpc_obj->type == ACPI_TYPE_INTEGER) {
+                       cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER;
+                       cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = cpc_obj->integer.value;
+               } else if (cpc_obj->type == ACPI_TYPE_BUFFER) {
+                       gas_t = (struct cpc_reg *)
+                               cpc_obj->buffer.pointer;
+
+                       /*
+                        * The PCC Subspace index is encoded inside
+                        * the CPC table entries. The same PCC index
+                        * will be used for all the PCC entries,
+                        * so extract it only once.
+                        */
+                       if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+                               if (pcc_subspace_idx < 0)
+                                       pcc_subspace_idx = gas_t->access_width;
+                               else if (pcc_subspace_idx != gas_t->access_width) {
+                                       pr_debug("Mismatched PCC ids.\n");
+                                       goto out_free;
+                               }
+                       } else if (gas_t->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+                               /* Support only PCC and SYS MEM type regs */
+                               pr_debug("Unsupported register type: %d\n", gas_t->space_id);
+                               goto out_free;
+                       }
+
+                       cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER;
+                       memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t));
+               } else {
+                       pr_debug("Err in entry:%d in CPC table of CPU:%d \n", i, pr->id);
+                       goto out_free;
+               }
+       }
+       /* Store CPU Logical ID */
+       cpc_ptr->cpu_id = pr->id;
+
+       /* Plug it into this CPUs CPC descriptor. */
+       per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
+
+       /* Parse PSD data for this CPU */
+       ret = acpi_get_psd(cpc_ptr, handle);
+       if (ret)
+               goto out_free;
+
+       /* Register PCC channel once for all CPUs. */
+       if (!pcc_channel_acquired) {
+               ret = register_pcc_channel(pcc_subspace_idx);
+               if (ret)
+                       goto out_free;
+       }
+
+       /* Everything looks okay */
+       pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
+
+       kfree(output.pointer);
+       return 0;
+
+out_free:
+       kfree(cpc_ptr);
+
+out_buf_free:
+       kfree(output.pointer);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe);
+
+/**
+ * acpi_cppc_processor_exit - Cleanup CPC structs.
+ * @pr: Ptr to acpi_processor containing this CPUs logical Id.
+ *
+ * Return: Void
+ */
+void acpi_cppc_processor_exit(struct acpi_processor *pr)
+{
+       struct cpc_desc *cpc_ptr;
+       cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
+       kfree(cpc_ptr);
+}
+EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
+
+static u64 get_phys_addr(struct cpc_reg *reg)
+{
+       /* PCC communication addr space begins at byte offset 0x8. */
+       if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM)
+               return (u64)comm_base_addr + 0x8 + reg->address;
+       else
+               return reg->address;
+}
+
+static void cpc_read(struct cpc_reg *reg, u64 *val)
+{
+       u64 addr = get_phys_addr(reg);
+
+       acpi_os_read_memory((acpi_physical_address)addr,
+                       val, reg->bit_width);
+}
+
+static void cpc_write(struct cpc_reg *reg, u64 val)
+{
+       u64 addr = get_phys_addr(reg);
+
+       acpi_os_write_memory((acpi_physical_address)addr,
+                       val, reg->bit_width);
+}
+
+/**
+ * cppc_get_perf_caps - Get a CPUs performance capabilities.
+ * @cpunum: CPU from which to get capabilities info.
+ * @perf_caps: ptr to cppc_perf_caps. See cppc_acpi.h
+ *
+ * Return: 0 for success with perf_caps populated else -ERRNO.
+ */
+int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
+{
+       struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
+       struct cpc_register_resource *highest_reg, *lowest_reg, *ref_perf,
+                                                                *nom_perf;
+       u64 high, low, ref, nom;
+       int ret = 0;
+
+       if (!cpc_desc) {
+               pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
+               return -ENODEV;
+       }
+
+       highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF];
+       lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF];
+       ref_perf = &cpc_desc->cpc_regs[REFERENCE_PERF];
+       nom_perf = &cpc_desc->cpc_regs[NOMINAL_PERF];
+
+       spin_lock(&pcc_lock);
+
+       /* Are any of the regs PCC ?*/
+       if ((highest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+                       (lowest_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+                       (ref_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+                       (nom_perf->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) {
+               /* Ring doorbell once to update PCC subspace */
+               if (send_pcc_cmd(CMD_READ)) {
+                       ret = -EIO;
+                       goto out_err;
+               }
+       }
+
+       cpc_read(&highest_reg->cpc_entry.reg, &high);
+       perf_caps->highest_perf = high;
+
+       cpc_read(&lowest_reg->cpc_entry.reg, &low);
+       perf_caps->lowest_perf = low;
+
+       cpc_read(&ref_perf->cpc_entry.reg, &ref);
+       perf_caps->reference_perf = ref;
+
+       cpc_read(&nom_perf->cpc_entry.reg, &nom);
+       perf_caps->nominal_perf = nom;
+
+       if (!ref)
+               perf_caps->reference_perf = perf_caps->nominal_perf;
+
+       if (!high || !low || !nom)
+               ret = -EFAULT;
+
+out_err:
+       spin_unlock(&pcc_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
+
+/**
+ * cppc_get_perf_ctrs - Read a CPUs performance feedback counters.
+ * @cpunum: CPU from which to read counters.
+ * @perf_fb_ctrs: ptr to cppc_perf_fb_ctrs. See cppc_acpi.h
+ *
+ * Return: 0 for success with perf_fb_ctrs populated else -ERRNO.
+ */
+int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
+{
+       struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
+       struct cpc_register_resource *delivered_reg, *reference_reg;
+       u64 delivered, reference;
+       int ret = 0;
+
+       if (!cpc_desc) {
+               pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
+               return -ENODEV;
+       }
+
+       delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR];
+       reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR];
+
+       spin_lock(&pcc_lock);
+
+       /* Are any of the regs PCC ?*/
+       if ((delivered_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) ||
+                       (reference_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM)) {
+               /* Ring doorbell once to update PCC subspace */
+               if (send_pcc_cmd(CMD_READ)) {
+                       ret = -EIO;
+                       goto out_err;
+               }
+       }
+
+       cpc_read(&delivered_reg->cpc_entry.reg, &delivered);
+       cpc_read(&reference_reg->cpc_entry.reg, &reference);
+
+       if (!delivered || !reference) {
+               ret = -EFAULT;
+               goto out_err;
+       }
+
+       perf_fb_ctrs->delivered = delivered;
+       perf_fb_ctrs->reference = reference;
+
+       perf_fb_ctrs->delivered -= perf_fb_ctrs->prev_delivered;
+       perf_fb_ctrs->reference -= perf_fb_ctrs->prev_reference;
+
+       perf_fb_ctrs->prev_delivered = delivered;
+       perf_fb_ctrs->prev_reference = reference;
+
+out_err:
+       spin_unlock(&pcc_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
+
+/**
+ * cppc_set_perf - Set a CPUs performance controls.
+ * @cpu: CPU for which to set performance controls.
+ * @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h
+ *
+ * Return: 0 for success, -ERRNO otherwise.
+ */
+int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
+{
+       struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+       struct cpc_register_resource *desired_reg;
+       int ret = 0;
+
+       if (!cpc_desc) {
+               pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+               return -ENODEV;
+       }
+
+       desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF];
+
+       spin_lock(&pcc_lock);
+
+       /*
+        * Skip writing MIN/MAX until Linux knows how to come up with
+        * useful values.
+        */
+       cpc_write(&desired_reg->cpc_entry.reg, perf_ctrls->desired_perf);
+
+       /* Is this a PCC reg ?*/
+       if (desired_reg->cpc_entry.reg.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+               /* Ring doorbell so Remote can get our perf request. */
+               if (send_pcc_cmd(CMD_WRITE))
+                       ret = -EIO;
+       }
+
+       spin_unlock(&pcc_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(cppc_set_perf);
index 4806b7f856c46047bb0b4bd38bbc66717e33a6e0..08a02cdc737c193d608970b6eec0b45781137d76 100644 (file)
@@ -962,23 +962,6 @@ int acpi_subsys_prepare(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
-/**
- * acpi_subsys_complete - Finalize device's resume during system resume.
- * @dev: Device to handle.
- */
-void acpi_subsys_complete(struct device *dev)
-{
-       pm_generic_complete(dev);
-       /*
-        * If the device had been runtime-suspended before the system went into
-        * the sleep state it is going out of and it has never been resumed till
-        * now, resume it in case the firmware powered it up.
-        */
-       if (dev->power.direct_complete)
-               pm_request_resume(dev);
-}
-EXPORT_SYMBOL_GPL(acpi_subsys_complete);
-
 /**
  * acpi_subsys_suspend - Run the device driver's suspend callback.
  * @dev: Device to handle.
@@ -1047,7 +1030,7 @@ static struct dev_pm_domain acpi_general_pm_domain = {
                .runtime_resume = acpi_subsys_runtime_resume,
 #ifdef CONFIG_PM_SLEEP
                .prepare = acpi_subsys_prepare,
-               .complete = acpi_subsys_complete,
+               .complete = pm_complete_with_resume_check,
                .suspend = acpi_subsys_suspend,
                .suspend_late = acpi_subsys_suspend_late,
                .resume_early = acpi_subsys_resume_early,
index 4ab4582e586b750a287b8b6744ecb3e0f480593f..707cf6213bc2888b4cc1e09a0f851d232b9521c0 100644 (file)
 
 #include "internal.h"
 
+static ssize_t acpi_object_path(acpi_handle handle, char *buf)
+{
+       struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+       int result;
+
+       result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path);
+       if (result)
+               return result;
+
+       result = sprintf(buf, "%s\n", (char*)path.pointer);
+       kfree(path.pointer);
+       return result;
+}
+
+struct acpi_data_node_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct acpi_data_node *, char *);
+       ssize_t (*store)(struct acpi_data_node *, const char *, size_t count);
+};
+
+#define DATA_NODE_ATTR(_name)                  \
+       static struct acpi_data_node_attr data_node_##_name =   \
+               __ATTR(_name, 0444, data_node_show_##_name, NULL)
+
+static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
+{
+       return acpi_object_path(dn->handle, buf);
+}
+
+DATA_NODE_ATTR(path);
+
+static struct attribute *acpi_data_node_default_attrs[] = {
+       &data_node_path.attr,
+       NULL
+};
+
+#define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
+#define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
+
+static ssize_t acpi_data_node_attr_show(struct kobject *kobj,
+                                       struct attribute *attr, char *buf)
+{
+       struct acpi_data_node *dn = to_data_node(kobj);
+       struct acpi_data_node_attr *dn_attr = to_attr(attr);
+
+       return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO;
+}
+
+static const struct sysfs_ops acpi_data_node_sysfs_ops = {
+       .show   = acpi_data_node_attr_show,
+};
+
+static void acpi_data_node_release(struct kobject *kobj)
+{
+       struct acpi_data_node *dn = to_data_node(kobj);
+       complete(&dn->kobj_done);
+}
+
+static struct kobj_type acpi_data_node_ktype = {
+       .sysfs_ops = &acpi_data_node_sysfs_ops,
+       .default_attrs = acpi_data_node_default_attrs,
+       .release = acpi_data_node_release,
+};
+
+static void acpi_expose_nondev_subnodes(struct kobject *kobj,
+                                       struct acpi_device_data *data)
+{
+       struct list_head *list = &data->subnodes;
+       struct acpi_data_node *dn;
+
+       if (list_empty(list))
+               return;
+
+       list_for_each_entry(dn, list, sibling) {
+               int ret;
+
+               init_completion(&dn->kobj_done);
+               ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
+                                          kobj, dn->name);
+               if (ret)
+                       acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
+               else
+                       acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
+       }
+}
+
+static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
+{
+       struct list_head *list = &data->subnodes;
+       struct acpi_data_node *dn;
+
+       if (list_empty(list))
+               return;
+
+       list_for_each_entry_reverse(dn, list, sibling) {
+               acpi_hide_nondev_subnodes(&dn->data);
+               kobject_put(&dn->kobj);
+       }
+}
+
 /**
  * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
  * @acpi_dev: ACPI device object.
@@ -323,20 +423,12 @@ static ssize_t acpi_device_adr_show(struct device *dev,
 }
 static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
 
-static ssize_t
-acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
+static ssize_t acpi_device_path_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
        struct acpi_device *acpi_dev = to_acpi_device(dev);
-       struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
-       int result;
-
-       result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
-       if (result)
-               goto end;
 
-       result = sprintf(buf, "%s\n", (char*)path.pointer);
-       kfree(path.pointer);
-end:
-       return result;
+       return acpi_object_path(acpi_dev->handle, buf);
 }
 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
 
@@ -475,6 +567,8 @@ int acpi_device_setup_files(struct acpi_device *dev)
                                                    &dev_attr_real_power_state);
        }
 
+       acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data);
+
 end:
        return result;
 }
@@ -485,6 +579,8 @@ end:
  */
 void acpi_device_remove_files(struct acpi_device *dev)
 {
+       acpi_hide_nondev_subnodes(&dev->data);
+
        if (dev->flags.power_manageable) {
                device_remove_file(&dev->dev, &dev_attr_power_state);
                if (dev->power.flags.power_resources)
index 42c66b64c12cefd8c1491e7b91af138b86ddf5af..f61a7c83454063a5e77ebf35e13cb4bb1431891b 100644 (file)
@@ -441,17 +441,31 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
 
 static bool acpi_ec_guard_event(struct acpi_ec *ec)
 {
+       bool guarded = true;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ec->lock, flags);
+       /*
+        * If firmware SCI_EVT clearing timing is "event", we actually
+        * don't know when the SCI_EVT will be cleared by firmware after
+        * evaluating _Qxx, so we need to re-check SCI_EVT after waiting an
+        * acceptable period.
+        *
+        * The guarding period begins when EC_FLAGS_QUERY_PENDING is
+        * flagged, which means SCI_EVT check has just been performed.
+        * But if the current transaction is ACPI_EC_COMMAND_QUERY, the
+        * guarding should have already been performed (via
+        * EC_FLAGS_QUERY_GUARDING) and should not be applied so that the
+        * ACPI_EC_COMMAND_QUERY transaction can be transitioned into
+        * ACPI_EC_COMMAND_POLL state immediately.
+        */
        if (ec_event_clearing == ACPI_EC_EVT_TIMING_STATUS ||
            ec_event_clearing == ACPI_EC_EVT_TIMING_QUERY ||
            !test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags) ||
            (ec->curr && ec->curr->command == ACPI_EC_COMMAND_QUERY))
-               return false;
-
-       /*
-        * Postpone the query submission to allow the firmware to proceed,
-        * we shouldn't check SCI_EVT before the firmware reflagging it.
-        */
-       return true;
+               guarded = false;
+       spin_unlock_irqrestore(&ec->lock, flags);
+       return guarded;
 }
 
 static int ec_transaction_polled(struct acpi_ec *ec)
@@ -597,6 +611,7 @@ static int ec_guard(struct acpi_ec *ec)
        unsigned long guard = usecs_to_jiffies(ec_polling_guard);
        unsigned long timeout = ec->timestamp + guard;
 
+       /* Ensure guarding period before polling EC status */
        do {
                if (ec_busy_polling) {
                        /* Perform busy polling */
@@ -606,11 +621,13 @@ static int ec_guard(struct acpi_ec *ec)
                } else {
                        /*
                         * Perform wait polling
-                        *
-                        * For SCI_EVT clearing timing of "event",
-                        * performing guarding before re-checking the
-                        * SCI_EVT. Otherwise, such guarding is not needed
-                        * due to the old practices.
+                        * 1. Wait the transaction to be completed by the
+                        *    GPE handler after the transaction enters
+                        *    ACPI_EC_COMMAND_POLL state.
+                        * 2. A special guarding logic is also required
+                        *    for event clearing mode "event" before the
+                        *    transaction enters ACPI_EC_COMMAND_POLL
+                        *    state.
                         */
                        if (!ec_transaction_polled(ec) &&
                            !acpi_ec_guard_event(ec))
@@ -620,7 +637,6 @@ static int ec_guard(struct acpi_ec *ec)
                                               guard))
                                return 0;
                }
-               /* Guard the register accesses for the polling modes */
        } while (time_before(jiffies, timeout));
        return -ETIME;
 }
@@ -929,6 +945,23 @@ acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler)
        return handler;
 }
 
+static struct acpi_ec_query_handler *
+acpi_ec_get_query_handler_by_value(struct acpi_ec *ec, u8 value)
+{
+       struct acpi_ec_query_handler *handler;
+       bool found = false;
+
+       mutex_lock(&ec->mutex);
+       list_for_each_entry(handler, &ec->list, node) {
+               if (value == handler->query_bit) {
+                       found = true;
+                       break;
+               }
+       }
+       mutex_unlock(&ec->mutex);
+       return found ? acpi_ec_get_query_handler(handler) : NULL;
+}
+
 static void acpi_ec_query_handler_release(struct kref *kref)
 {
        struct acpi_ec_query_handler *handler =
@@ -964,14 +997,15 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
 }
 EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
 
-void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
+                                         bool remove_all, u8 query_bit)
 {
        struct acpi_ec_query_handler *handler, *tmp;
        LIST_HEAD(free_list);
 
        mutex_lock(&ec->mutex);
        list_for_each_entry_safe(handler, tmp, &ec->list, node) {
-               if (query_bit == handler->query_bit) {
+               if (remove_all || query_bit == handler->query_bit) {
                        list_del_init(&handler->node);
                        list_add(&handler->node, &free_list);
                }
@@ -980,6 +1014,11 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
        list_for_each_entry_safe(handler, tmp, &free_list, node)
                acpi_ec_put_query_handler(handler);
 }
+
+void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+{
+       acpi_ec_remove_query_handlers(ec, false, query_bit);
+}
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
 static struct acpi_ec_query *acpi_ec_create_query(u8 *pval)
@@ -1025,7 +1064,6 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
 {
        u8 value = 0;
        int result;
-       struct acpi_ec_query_handler *handler;
        struct acpi_ec_query *q;
 
        q = acpi_ec_create_query(&value);
@@ -1043,25 +1081,26 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
        if (result)
                goto err_exit;
 
-       mutex_lock(&ec->mutex);
-       result = -ENODATA;
-       list_for_each_entry(handler, &ec->list, node) {
-               if (value == handler->query_bit) {
-                       result = 0;
-                       q->handler = acpi_ec_get_query_handler(handler);
-                       ec_dbg_evt("Query(0x%02x) scheduled",
-                                  q->handler->query_bit);
-                       /*
-                        * It is reported that _Qxx are evaluated in a
-                        * parallel way on Windows:
-                        * https://bugzilla.kernel.org/show_bug.cgi?id=94411
-                        */
-                       if (!schedule_work(&q->work))
-                               result = -EBUSY;
-                       break;
-               }
+       q->handler = acpi_ec_get_query_handler_by_value(ec, value);
+       if (!q->handler) {
+               result = -ENODATA;
+               goto err_exit;
+       }
+
+       /*
+        * It is reported that _Qxx are evaluated in a parallel way on
+        * Windows:
+        * https://bugzilla.kernel.org/show_bug.cgi?id=94411
+        *
+        * Put this log entry before schedule_work() in order to make
+        * it appearing before any other log entries occurred during the
+        * work queue execution.
+        */
+       ec_dbg_evt("Query(0x%02x) scheduled", value);
+       if (!schedule_work(&q->work)) {
+               ec_dbg_evt("Query(0x%02x) overlapped", value);
+               result = -EBUSY;
        }
-       mutex_unlock(&ec->mutex);
 
 err_exit:
        if (result && q)
@@ -1354,19 +1393,13 @@ static int acpi_ec_add(struct acpi_device *device)
 static int acpi_ec_remove(struct acpi_device *device)
 {
        struct acpi_ec *ec;
-       struct acpi_ec_query_handler *handler, *tmp;
 
        if (!device)
                return -EINVAL;
 
        ec = acpi_driver_data(device);
        ec_remove_handlers(ec);
-       mutex_lock(&ec->mutex);
-       list_for_each_entry_safe(handler, tmp, &ec->list, node) {
-               list_del(&handler->node);
-               kfree(handler);
-       }
-       mutex_unlock(&ec->mutex);
+       acpi_ec_remove_query_handlers(ec, true, 0);
        release_region(ec->data_addr, 1);
        release_region(ec->command_addr, 1);
        device->driver_data = NULL;
index b9657af751d1051d9b44ed2a22e2c347dd9c9846..1470ae4f98c07ce6e358bd53bf17b0c0b209b1cb 100644 (file)
@@ -351,13 +351,12 @@ static int acpi_platform_notify_remove(struct device *dev)
        return 0;
 }
 
-int __init init_acpi_device_notify(void)
+void __init init_acpi_device_notify(void)
 {
        if (platform_notify || platform_notify_remove) {
                printk(KERN_ERR PREFIX "Can't use platform_notify\n");
-               return 0;
+               return;
        }
        platform_notify = acpi_platform_notify;
        platform_notify_remove = acpi_platform_notify_remove;
-       return 0;
 }
index 9e426210c2a8ea6a283bc04d9dc8bd1ac739370e..c31787bef2d323145f38b6a5b6884713a953df20 100644 (file)
@@ -21,7 +21,7 @@
 #define PREFIX "ACPI: "
 
 acpi_status acpi_os_initialize1(void);
-int init_acpi_device_notify(void);
+void init_acpi_device_notify(void);
 int acpi_scan_init(void);
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
@@ -179,13 +179,13 @@ static inline int acpi_sleep_init(void) { return -ENXIO; }
 #endif
 
 #ifdef CONFIG_ACPI_SLEEP
-int acpi_sleep_proc_init(void);
+void acpi_sleep_proc_init(void);
 int suspend_nvs_alloc(void);
 void suspend_nvs_free(void);
 int suspend_nvs_save(void);
 void suspend_nvs_restore(void);
 #else
-static inline int acpi_sleep_proc_init(void) { return 0; }
+static inline void acpi_sleep_proc_init(void) {}
 static inline int suspend_nvs_alloc(void) { return 0; }
 static inline void suspend_nvs_free(void) {}
 static inline int suspend_nvs_save(void) { return 0; }
index c1b8d03e262eeeedf21d24f58b528acefe827abb..bc18aa213bb1c9ce23d07cc60b54f505d7d14c81 100644 (file)
@@ -706,7 +706,7 @@ static ssize_t flags_show(struct device *dev,
                flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
                flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
                flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-               flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+               flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
                flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
 }
 static DEVICE_ATTR_RO(flags);
@@ -815,7 +815,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                        flags |= NDD_ALIASING;
 
                mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-               if (mem_flags & ACPI_NFIT_MEM_ARMED)
+               if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
                        flags |= NDD_UNARMED;
 
                rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
@@ -839,7 +839,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
                  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
                  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
-                 mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+                 mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
 
        }
 
index 7e740156b9c2996986e0283e2bdb5d84512929ee..329a1eba0c164e79cac859c28afeab456755ca89 100644 (file)
@@ -24,7 +24,7 @@
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
                | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
-               | ACPI_NFIT_MEM_ARMED)
+               | ACPI_NFIT_MEM_NOT_ARMED)
 
 enum nfit_uuids {
        NFIT_SPA_VOLATILE,
index 739a4a6b3b9b4c6eaf8669c0d10503c94717b0dd..3935745ac78bf83e2299172fef06f342a038b65a 100644 (file)
@@ -66,8 +66,6 @@ struct acpi_os_dpc {
 /* stuff for debugger support */
 int acpi_in_debugger;
 EXPORT_SYMBOL(acpi_in_debugger);
-
-extern char line_buf[80];
 #endif                         /*ENABLE_DEBUGGER */
 
 static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
@@ -81,6 +79,7 @@ static struct workqueue_struct *kacpid_wq;
 static struct workqueue_struct *kacpi_notify_wq;
 static struct workqueue_struct *kacpi_hotplug_wq;
 static bool acpi_os_initialized;
+unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
 
 /*
  * This list of permanent mappings is for memory that may be accessed from
@@ -856,17 +855,19 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
                acpi_irq_handler = NULL;
                return AE_NOT_ACQUIRED;
        }
+       acpi_sci_irq = irq;
 
        return AE_OK;
 }
 
-acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
+acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
 {
-       if (irq != acpi_gbl_FADT.sci_interrupt)
+       if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
                return AE_BAD_PARAMETER;
 
-       free_irq(irq, acpi_irq);
+       free_irq(acpi_sci_irq, acpi_irq);
        acpi_irq_handler = NULL;
+       acpi_sci_irq = INVALID_ACPI_IRQ;
 
        return AE_OK;
 }
@@ -1180,8 +1181,8 @@ void acpi_os_wait_events_complete(void)
         * Make sure the GPE handler or the fixed event handler is not used
         * on another CPU after removal.
         */
-       if (acpi_irq_handler)
-               synchronize_hardirq(acpi_gbl_FADT.sci_interrupt);
+       if (acpi_sci_irq_valid())
+               synchronize_hardirq(acpi_sci_irq);
        flush_workqueue(kacpid_wq);
        flush_workqueue(kacpi_notify_wq);
 }
@@ -1345,15 +1346,13 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
        return AE_OK;
 }
 
-#ifdef ACPI_FUTURE_USAGE
-u32 acpi_os_get_line(char *buffer)
+acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 {
-
 #ifdef ENABLE_DEBUGGER
        if (acpi_in_debugger) {
                u32 chars;
 
-               kdb_read(buffer, sizeof(line_buf));
+               kdb_read(buffer, buffer_length);
 
                /* remove the CR kdb includes */
                chars = strlen(buffer) - 1;
@@ -1361,9 +1360,8 @@ u32 acpi_os_get_line(char *buffer)
        }
 #endif
 
-       return 0;
+       return AE_OK;
 }
-#endif                         /*  ACPI_FUTURE_USAGE  */
 
 acpi_status acpi_os_signal(u32 function, void *info)
 {
index 393706a5261b0d82f58f877e49581a521eb1d672..850d7bf0c873fb64af77ada90e971a733527e2bd 100644 (file)
@@ -652,6 +652,210 @@ static void acpi_pci_root_remove(struct acpi_device *device)
        kfree(root);
 }
 
+/*
+ * Following code to support acpi_pci_root_create() is copied from
+ * arch/x86/pci/acpi.c and modified so it could be reused by x86, IA64
+ * and ARM64.
+ */
+static void acpi_pci_root_validate_resources(struct device *dev,
+                                            struct list_head *resources,
+                                            unsigned long type)
+{
+       LIST_HEAD(list);
+       struct resource *res1, *res2, *root = NULL;
+       struct resource_entry *tmp, *entry, *entry2;
+
+       BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
+       root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
+
+       list_splice_init(resources, &list);
+       resource_list_for_each_entry_safe(entry, tmp, &list) {
+               bool free = false;
+               resource_size_t end;
+
+               res1 = entry->res;
+               if (!(res1->flags & type))
+                       goto next;
+
+               /* Exclude non-addressable range or non-addressable portion */
+               end = min(res1->end, root->end);
+               if (end <= res1->start) {
+                       dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
+                                res1);
+                       free = true;
+                       goto next;
+               } else if (res1->end != end) {
+                       dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
+                                res1, (unsigned long long)end + 1,
+                                (unsigned long long)res1->end);
+                       res1->end = end;
+               }
+
+               resource_list_for_each_entry(entry2, resources) {
+                       res2 = entry2->res;
+                       if (!(res2->flags & type))
+                               continue;
+
+                       /*
+                        * I don't like throwing away windows because then
+                        * our resources no longer match the ACPI _CRS, but
+                        * the kernel resource tree doesn't allow overlaps.
+                        */
+                       if (resource_overlaps(res1, res2)) {
+                               res2->start = min(res1->start, res2->start);
+                               res2->end = max(res1->end, res2->end);
+                               dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
+                                        res2, res1);
+                               free = true;
+                               goto next;
+                       }
+               }
+
+next:
+               resource_list_del(entry);
+               if (free)
+                       resource_list_free_entry(entry);
+               else
+                       resource_list_add_tail(entry, resources);
+       }
+}
+
+int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
+{
+       int ret;
+       struct list_head *list = &info->resources;
+       struct acpi_device *device = info->bridge;
+       struct resource_entry *entry, *tmp;
+       unsigned long flags;
+
+       flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
+       ret = acpi_dev_get_resources(device, list,
+                                    acpi_dev_filter_resource_type_cb,
+                                    (void *)flags);
+       if (ret < 0)
+               dev_warn(&device->dev,
+                        "failed to parse _CRS method, error code %d\n", ret);
+       else if (ret == 0)
+               dev_dbg(&device->dev,
+                       "no IO and memory resources present in _CRS\n");
+       else {
+               resource_list_for_each_entry_safe(entry, tmp, list) {
+                       if (entry->res->flags & IORESOURCE_DISABLED)
+                               resource_list_destroy_entry(entry);
+                       else
+                               entry->res->name = info->name;
+               }
+               acpi_pci_root_validate_resources(&device->dev, list,
+                                                IORESOURCE_MEM);
+               acpi_pci_root_validate_resources(&device->dev, list,
+                                                IORESOURCE_IO);
+       }
+
+       return ret;
+}
+
+static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info)
+{
+       struct resource_entry *entry, *tmp;
+       struct resource *res, *conflict, *root = NULL;
+
+       resource_list_for_each_entry_safe(entry, tmp, &info->resources) {
+               res = entry->res;
+               if (res->flags & IORESOURCE_MEM)
+                       root = &iomem_resource;
+               else if (res->flags & IORESOURCE_IO)
+                       root = &ioport_resource;
+               else
+                       continue;
+
+               conflict = insert_resource_conflict(root, res);
+               if (conflict) {
+                       dev_info(&info->bridge->dev,
+                                "ignoring host bridge window %pR (conflicts with %s %pR)\n",
+                                res, conflict->name, conflict);
+                       resource_list_destroy_entry(entry);
+               }
+       }
+}
+
+static void __acpi_pci_root_release_info(struct acpi_pci_root_info *info)
+{
+       struct resource *res;
+       struct resource_entry *entry, *tmp;
+
+       if (!info)
+               return;
+
+       resource_list_for_each_entry_safe(entry, tmp, &info->resources) {
+               res = entry->res;
+               if (res->parent &&
+                   (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+                       release_resource(res);
+               resource_list_destroy_entry(entry);
+       }
+
+       info->ops->release_info(info);
+}
+
+static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
+{
+       struct resource *res;
+       struct resource_entry *entry;
+
+       resource_list_for_each_entry(entry, &bridge->windows) {
+               res = entry->res;
+               if (res->parent &&
+                   (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+                       release_resource(res);
+       }
+       __acpi_pci_root_release_info(bridge->release_data);
+}
+
+struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
+                                    struct acpi_pci_root_ops *ops,
+                                    struct acpi_pci_root_info *info,
+                                    void *sysdata)
+{
+       int ret, busnum = root->secondary.start;
+       struct acpi_device *device = root->device;
+       int node = acpi_get_node(device->handle);
+       struct pci_bus *bus;
+
+       info->root = root;
+       info->bridge = device;
+       info->ops = ops;
+       INIT_LIST_HEAD(&info->resources);
+       snprintf(info->name, sizeof(info->name), "PCI Bus %04x:%02x",
+                root->segment, busnum);
+
+       if (ops->init_info && ops->init_info(info))
+               goto out_release_info;
+       if (ops->prepare_resources)
+               ret = ops->prepare_resources(info);
+       else
+               ret = acpi_pci_probe_root_resources(info);
+       if (ret < 0)
+               goto out_release_info;
+
+       pci_acpi_root_add_resources(info);
+       pci_add_resource(&info->resources, &root->secondary);
+       bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
+                                 sysdata, &info->resources);
+       if (!bus)
+               goto out_release_info;
+
+       pci_scan_child_bus(bus);
+       pci_set_host_bridge_release(to_pci_host_bridge(bus->bridge),
+                                   acpi_pci_root_release_info, info);
+       if (node != NUMA_NO_NODE)
+               dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
+       return bus;
+
+out_release_info:
+       __acpi_pci_root_release_info(info);
+       return NULL;
+}
+
 void __init acpi_pci_root_init(void)
 {
        acpi_hest_init();
index 75c28eae88604903ac518fc0fe4ebe83f2e2669e..2a358154b770dda2a603600cb1348fc2514aabae 100644 (file)
@@ -144,11 +144,9 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
        .release = single_release,
 };
 
-int __init acpi_sleep_proc_init(void)
+void __init acpi_sleep_proc_init(void)
 {
        /* 'wakeup device' [R/W] */
        proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
                    acpi_root_dir, &acpi_system_wakeup_device_fops);
-
-       return 0;
 }
index 51e658f21e956fd66895d431971bb56449c74e56..f4e02ae93f585fbb8de42c09d4d0fb32d2751887 100644 (file)
@@ -242,6 +242,10 @@ static int __acpi_processor_start(struct acpi_device *device)
        if (pr->flags.need_hotplug_init)
                return 0;
 
+       result = acpi_cppc_processor_probe(pr);
+       if (result)
+               return -ENODEV;
+
        if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
                acpi_processor_power_init(pr);
 
@@ -287,6 +291,8 @@ static int acpi_processor_stop(struct device *dev)
 
        acpi_pss_perf_exit(pr, device);
 
+       acpi_cppc_processor_exit(pr);
+
        return 0;
 }
 
index 6d99450549c59dc1990598a0ad801049bc241b03..88f4306744c0aa23cb1b8b38ecf7f8df9c38b5f1 100644 (file)
 
 #include "internal.h"
 
+static int acpi_data_get_property_array(struct acpi_device_data *data,
+                                       const char *name,
+                                       acpi_object_type type,
+                                       const union acpi_object **obj);
+
 /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
 static const u8 prp_uuid[16] = {
        0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
        0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
 };
+/* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
+static const u8 ads_uuid[16] = {
+       0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b,
+       0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b
+};
+
+static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
+                                          const union acpi_object *desc,
+                                          struct acpi_device_data *data);
+static bool acpi_extract_properties(const union acpi_object *desc,
+                                   struct acpi_device_data *data);
+
+static bool acpi_nondev_subnode_ok(acpi_handle scope,
+                                  const union acpi_object *link,
+                                  struct list_head *list)
+{
+       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+       struct acpi_data_node *dn;
+       acpi_handle handle;
+       acpi_status status;
+
+       dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+       if (!dn)
+               return false;
+
+       dn->name = link->package.elements[0].string.pointer;
+       dn->fwnode.type = FWNODE_ACPI_DATA;
+       INIT_LIST_HEAD(&dn->data.subnodes);
+
+       status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
+                                &handle);
+       if (ACPI_FAILURE(status))
+               goto fail;
+
+       status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
+                                           ACPI_TYPE_PACKAGE);
+       if (ACPI_FAILURE(status))
+               goto fail;
+
+       if (acpi_extract_properties(buf.pointer, &dn->data))
+               dn->handle = handle;
+
+       /*
+        * The scope for the subnode object lookup is the one of the namespace
+        * node (device) containing the object that has returned the package.
+        * That is, it's the scope of that object's parent.
+        */
+       status = acpi_get_parent(handle, &scope);
+       if (ACPI_SUCCESS(status)
+           && acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data))
+               dn->handle = handle;
+
+       if (dn->handle) {
+               dn->data.pointer = buf.pointer;
+               list_add_tail(&dn->sibling, list);
+               return true;
+       }
+
+       acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
+
+ fail:
+       ACPI_FREE(buf.pointer);
+       kfree(dn);
+       return false;
+}
+
+static int acpi_add_nondev_subnodes(acpi_handle scope,
+                                   const union acpi_object *links,
+                                   struct list_head *list)
+{
+       bool ret = false;
+       int i;
+
+       for (i = 0; i < links->package.count; i++) {
+               const union acpi_object *link;
+
+               link = &links->package.elements[i];
+               /* Only two elements allowed, both must be strings. */
+               if (link->package.count == 2
+                   && link->package.elements[0].type == ACPI_TYPE_STRING
+                   && link->package.elements[1].type == ACPI_TYPE_STRING
+                   && acpi_nondev_subnode_ok(scope, link, list))
+                       ret = true;
+       }
+
+       return ret;
+}
+
+static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
+                                          const union acpi_object *desc,
+                                          struct acpi_device_data *data)
+{
+       int i;
+
+       /* Look for the ACPI data subnodes UUID. */
+       for (i = 0; i < desc->package.count; i += 2) {
+               const union acpi_object *uuid, *links;
+
+               uuid = &desc->package.elements[i];
+               links = &desc->package.elements[i + 1];
+
+               /*
+                * The first element must be a UUID and the second one must be
+                * a package.
+                */
+               if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
+                   || links->type != ACPI_TYPE_PACKAGE)
+                       break;
+
+               if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid)))
+                       continue;
+
+               return acpi_add_nondev_subnodes(scope, links, &data->subnodes);
+       }
+
+       return false;
+}
 
 static bool acpi_property_value_ok(const union acpi_object *value)
 {
@@ -81,8 +203,8 @@ static void acpi_init_of_compatible(struct acpi_device *adev)
        const union acpi_object *of_compatible;
        int ret;
 
-       ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
-                                         &of_compatible);
+       ret = acpi_data_get_property_array(&adev->data, "compatible",
+                                          ACPI_TYPE_STRING, &of_compatible);
        if (ret) {
                ret = acpi_dev_get_property(adev, "compatible",
                                            ACPI_TYPE_STRING, &of_compatible);
@@ -100,34 +222,13 @@ static void acpi_init_of_compatible(struct acpi_device *adev)
        adev->flags.of_compatible_ok = 1;
 }
 
-void acpi_init_properties(struct acpi_device *adev)
+static bool acpi_extract_properties(const union acpi_object *desc,
+                                   struct acpi_device_data *data)
 {
-       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
-       bool acpi_of = false;
-       struct acpi_hardware_id *hwid;
-       const union acpi_object *desc;
-       acpi_status status;
        int i;
 
-       /*
-        * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
-        * Device Tree compatible properties for this device.
-        */
-       list_for_each_entry(hwid, &adev->pnp.ids, list) {
-               if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
-                       acpi_of = true;
-                       break;
-               }
-       }
-
-       status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
-                                           ACPI_TYPE_PACKAGE);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       desc = buf.pointer;
        if (desc->package.count % 2)
-               goto fail;
+               return false;
 
        /* Look for the device properties UUID. */
        for (i = 0; i < desc->package.count; i += 2) {
@@ -154,18 +255,50 @@ void acpi_init_properties(struct acpi_device *adev)
                if (!acpi_properties_format_valid(properties))
                        break;
 
-               adev->data.pointer = buf.pointer;
-               adev->data.properties = properties;
+               data->properties = properties;
+               return true;
+       }
 
-               if (acpi_of)
-                       acpi_init_of_compatible(adev);
+       return false;
+}
 
+void acpi_init_properties(struct acpi_device *adev)
+{
+       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+       struct acpi_hardware_id *hwid;
+       acpi_status status;
+       bool acpi_of = false;
+
+       INIT_LIST_HEAD(&adev->data.subnodes);
+
+       /*
+        * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in
+        * Device Tree compatible properties for this device.
+        */
+       list_for_each_entry(hwid, &adev->pnp.ids, list) {
+               if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) {
+                       acpi_of = true;
+                       break;
+               }
+       }
+
+       status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
+                                           ACPI_TYPE_PACKAGE);
+       if (ACPI_FAILURE(status))
                goto out;
+
+       if (acpi_extract_properties(buf.pointer, &adev->data)) {
+               adev->data.pointer = buf.pointer;
+               if (acpi_of)
+                       acpi_init_of_compatible(adev);
        }
+       if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data))
+               adev->data.pointer = buf.pointer;
 
- fail:
-       dev_dbg(&adev->dev, "Returned _DSD data is not valid, skipping\n");
-       ACPI_FREE(buf.pointer);
+       if (!adev->data.pointer) {
+               acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
+               ACPI_FREE(buf.pointer);
+       }
 
  out:
        if (acpi_of && !adev->flags.of_compatible_ok)
@@ -173,8 +306,25 @@ void acpi_init_properties(struct acpi_device *adev)
                         ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n");
 }
 
+static void acpi_destroy_nondev_subnodes(struct list_head *list)
+{
+       struct acpi_data_node *dn, *next;
+
+       if (list_empty(list))
+               return;
+
+       list_for_each_entry_safe_reverse(dn, next, list, sibling) {
+               acpi_destroy_nondev_subnodes(&dn->data.subnodes);
+               wait_for_completion(&dn->kobj_done);
+               list_del(&dn->sibling);
+               ACPI_FREE((void *)dn->data.pointer);
+               kfree(dn);
+       }
+}
+
 void acpi_free_properties(struct acpi_device *adev)
 {
+       acpi_destroy_nondev_subnodes(&adev->data.subnodes);
        ACPI_FREE((void *)adev->data.pointer);
        adev->data.of_compatible = NULL;
        adev->data.pointer = NULL;
@@ -182,8 +332,8 @@ void acpi_free_properties(struct acpi_device *adev)
 }
 
 /**
- * acpi_dev_get_property - return an ACPI property with given name
- * @adev: ACPI device to get property
+ * acpi_data_get_property - return an ACPI property with given name
+ * @data: ACPI device deta object to get the property from
  * @name: Name of the property
  * @type: Expected property type
  * @obj: Location to store the property value (if not %NULL)
@@ -192,26 +342,27 @@ void acpi_free_properties(struct acpi_device *adev)
  * object at the location pointed to by @obj if found.
  *
  * Callers must not attempt to free the returned objects.  These objects will be
- * freed by the ACPI core automatically during the removal of @adev.
+ * freed by the ACPI core automatically during the removal of @data.
  *
  * Return: %0 if property with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
  *         %-ENODATA if the property doesn't exist,
  *         %-EPROTO if the property value type doesn't match @type.
  */
-int acpi_dev_get_property(struct acpi_device *adev, const char *name,
-                         acpi_object_type type, const union acpi_object **obj)
+static int acpi_data_get_property(struct acpi_device_data *data,
+                                 const char *name, acpi_object_type type,
+                                 const union acpi_object **obj)
 {
        const union acpi_object *properties;
        int i;
 
-       if (!adev || !name)
+       if (!data || !name)
                return -EINVAL;
 
-       if (!adev->data.pointer || !adev->data.properties)
+       if (!data->pointer || !data->properties)
                return -ENODATA;
 
-       properties = adev->data.properties;
+       properties = data->properties;
        for (i = 0; i < properties->package.count; i++) {
                const union acpi_object *propname, *propvalue;
                const union acpi_object *property;
@@ -232,11 +383,50 @@ int acpi_dev_get_property(struct acpi_device *adev, const char *name,
        }
        return -ENODATA;
 }
+
+/**
+ * acpi_dev_get_property - return an ACPI property with given name.
+ * @adev: ACPI device to get the property from.
+ * @name: Name of the property.
+ * @type: Expected property type.
+ * @obj: Location to store the property value (if not %NULL).
+ */
+int acpi_dev_get_property(struct acpi_device *adev, const char *name,
+                         acpi_object_type type, const union acpi_object **obj)
+{
+       return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL;
+}
 EXPORT_SYMBOL_GPL(acpi_dev_get_property);
 
+static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode)
+{
+       if (fwnode->type == FWNODE_ACPI) {
+               struct acpi_device *adev = to_acpi_device_node(fwnode);
+               return &adev->data;
+       } else if (fwnode->type == FWNODE_ACPI_DATA) {
+               struct acpi_data_node *dn = to_acpi_data_node(fwnode);
+               return &dn->data;
+       }
+       return NULL;
+}
+
+/**
+ * acpi_node_prop_get - return an ACPI property with given name.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @valptr: Location to store a pointer to the property value (if not %NULL).
+ */
+int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
+                      void **valptr)
+{
+       return acpi_data_get_property(acpi_device_data_of_node(fwnode),
+                                     propname, ACPI_TYPE_ANY,
+                                     (const union acpi_object **)valptr);
+}
+
 /**
- * acpi_dev_get_property_array - return an ACPI array property with given name
- * @adev: ACPI device to get property
+ * acpi_data_get_property_array - return an ACPI array property with given name
+ * @adev: ACPI data object to get the property from
  * @name: Name of the property
  * @type: Expected type of array elements
  * @obj: Location to store a pointer to the property value (if not NULL)
@@ -245,7 +435,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_property);
  * ACPI object at the location pointed to by @obj if found.
  *
  * Callers must not attempt to free the returned objects.  Those objects will be
- * freed by the ACPI core automatically during the removal of @adev.
+ * freed by the ACPI core automatically during the removal of @data.
  *
  * Return: %0 if array property (package) with @name has been found (success),
  *         %-EINVAL if the arguments are invalid,
@@ -253,14 +443,15 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_property);
  *         %-EPROTO if the property is not a package or the type of its elements
  *           doesn't match @type.
  */
-int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
-                               acpi_object_type type,
-                               const union acpi_object **obj)
+static int acpi_data_get_property_array(struct acpi_device_data *data,
+                                       const char *name,
+                                       acpi_object_type type,
+                                       const union acpi_object **obj)
 {
        const union acpi_object *prop;
        int ret, i;
 
-       ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
+       ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop);
        if (ret)
                return ret;
 
@@ -275,12 +466,11 @@ int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
 
 /**
- * acpi_dev_get_property_reference - returns handle to the referenced object
- * @adev: ACPI device to get property
- * @name: Name of the property
+ * acpi_data_get_property_reference - returns handle to the referenced object
+ * @data: ACPI device data object containing the property
+ * @propname: Name of the property
  * @index: Index of the reference to return
  * @args: Location to store the returned reference with optional arguments
  *
@@ -294,16 +484,16 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
  *
  * Return: %0 on success, negative error code on failure.
  */
-int acpi_dev_get_property_reference(struct acpi_device *adev,
-                                   const char *name, size_t index,
-                                   struct acpi_reference_args *args)
+static int acpi_data_get_property_reference(struct acpi_device_data *data,
+                                           const char *propname, size_t index,
+                                           struct acpi_reference_args *args)
 {
        const union acpi_object *element, *end;
        const union acpi_object *obj;
        struct acpi_device *device;
        int ret, idx = 0;
 
-       ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
+       ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
        if (ret)
                return ret;
 
@@ -378,17 +568,27 @@ int acpi_dev_get_property_reference(struct acpi_device *adev,
 
        return -EPROTO;
 }
-EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
 
-int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
-                     void **valptr)
+/**
+ * acpi_node_get_property_reference - get a handle to the referenced object.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @index: Index of the reference to return.
+ * @args: Location to store the returned reference with optional arguments.
+ */
+int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+                                    const char *name, size_t index,
+                                    struct acpi_reference_args *args)
 {
-       return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
-                                    (const union acpi_object **)valptr);
+       struct acpi_device_data *data = acpi_device_data_of_node(fwnode);
+
+       return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
 }
+EXPORT_SYMBOL_GPL(acpi_node_get_property_reference);
 
-int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
-                             enum dev_prop_type proptype, void *val)
+static int acpi_data_prop_read_single(struct acpi_device_data *data,
+                                     const char *propname,
+                                     enum dev_prop_type proptype, void *val)
 {
        const union acpi_object *obj;
        int ret;
@@ -397,7 +597,7 @@ int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
                return -EINVAL;
 
        if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
-               ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
+               ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
                if (ret)
                        return ret;
 
@@ -422,7 +622,7 @@ int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
                        break;
                }
        } else if (proptype == DEV_PROP_STRING) {
-               ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
+               ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
                if (ret)
                        return ret;
 
@@ -433,6 +633,12 @@ int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
        return ret;
 }
 
+int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
+                             enum dev_prop_type proptype, void *val)
+{
+       return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL;
+}
+
 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
                                       size_t nval)
 {
@@ -509,20 +715,22 @@ static int acpi_copy_property_array_string(const union acpi_object *items,
        return 0;
 }
 
-int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
-                      enum dev_prop_type proptype, void *val, size_t nval)
+static int acpi_data_prop_read(struct acpi_device_data *data,
+                              const char *propname,
+                              enum dev_prop_type proptype,
+                              void *val, size_t nval)
 {
        const union acpi_object *obj;
        const union acpi_object *items;
        int ret;
 
        if (val && nval == 1) {
-               ret = acpi_dev_prop_read_single(adev, propname, proptype, val);
+               ret = acpi_data_prop_read_single(data, propname, proptype, val);
                if (!ret)
                        return ret;
        }
 
-       ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
+       ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
        if (ret)
                return ret;
 
@@ -558,3 +766,84 @@ int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
        }
        return ret;
 }
+
+int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
+                      enum dev_prop_type proptype, void *val, size_t nval)
+{
+       return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL;
+}
+
+/**
+ * acpi_node_prop_read - retrieve the value of an ACPI property with given name.
+ * @fwnode: Firmware node to get the property from.
+ * @propname: Name of the property.
+ * @proptype: Expected property type.
+ * @val: Location to store the property value (if not %NULL).
+ * @nval: Size of the array pointed to by @val.
+ *
+ * If @val is %NULL, return the number of array elements comprising the value
+ * of the property.  Otherwise, read at most @nval values to the array at the
+ * location pointed to by @val.
+ */
+int acpi_node_prop_read(struct fwnode_handle *fwnode,  const char *propname,
+                       enum dev_prop_type proptype, void *val, size_t nval)
+{
+       return acpi_data_prop_read(acpi_device_data_of_node(fwnode),
+                                  propname, proptype, val, nval);
+}
+
+/**
+ * acpi_get_next_subnode - Return the next child node handle for a device.
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+                                           struct fwnode_handle *child)
+{
+       struct acpi_device *adev = ACPI_COMPANION(dev);
+       struct list_head *head, *next;
+
+       if (!adev)
+               return NULL;
+
+       if (!child || child->type == FWNODE_ACPI) {
+               head = &adev->children;
+               if (list_empty(head))
+                       goto nondev;
+
+               if (child) {
+                       adev = to_acpi_device_node(child);
+                       next = adev->node.next;
+                       if (next == head) {
+                               child = NULL;
+                               goto nondev;
+                       }
+                       adev = list_entry(next, struct acpi_device, node);
+               } else {
+                       adev = list_first_entry(head, struct acpi_device, node);
+               }
+               return acpi_fwnode_handle(adev);
+       }
+
+ nondev:
+       if (!child || child->type == FWNODE_ACPI_DATA) {
+               struct acpi_data_node *dn;
+
+               head = &adev->data.subnodes;
+               if (list_empty(head))
+                       return NULL;
+
+               if (child) {
+                       dn = to_acpi_data_node(child);
+                       next = dn->sibling.next;
+                       if (next == head)
+                               return NULL;
+
+                       dn = list_entry(next, struct acpi_data_node, sibling);
+               } else {
+                       dn = list_first_entry(head, struct acpi_data_node, sibling);
+               }
+               return &dn->fwnode;
+       }
+       return NULL;
+}
index 15d22db05054526a95c233ea7f9de1c5510c4b42..cdc5c2599bebcc1a95ca2f29a525a5e63fab3b0f 100644 (file)
@@ -119,7 +119,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
 EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
 
 static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
-                                     u8 io_decode)
+                                     u8 io_decode, u8 translation_type)
 {
        res->flags = IORESOURCE_IO;
 
@@ -131,6 +131,8 @@ static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
 
        if (io_decode == ACPI_DECODE_16)
                res->flags |= IORESOURCE_IO_16BIT_ADDR;
+       if (translation_type == ACPI_SPARSE_TRANSLATION)
+               res->flags |= IORESOURCE_IO_SPARSE;
 }
 
 static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
@@ -138,7 +140,7 @@ static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
 {
        res->start = start;
        res->end = start + len - 1;
-       acpi_dev_ioresource_flags(res, len, io_decode);
+       acpi_dev_ioresource_flags(res, len, io_decode, 0);
 }
 
 /**
@@ -231,7 +233,8 @@ static bool acpi_decode_space(struct resource_win *win,
                acpi_dev_memresource_flags(res, len, wp);
                break;
        case ACPI_IO_RANGE:
-               acpi_dev_ioresource_flags(res, len, iodec);
+               acpi_dev_ioresource_flags(res, len, iodec,
+                                         addr->info.io.translation_type);
                break;
        case ACPI_BUS_NUMBER_RANGE:
                res->flags = IORESOURCE_BUS;
index 01136b8790381ccff5afc259e47643c338914740..daf9fc8329e64c41817269d0b6c437e3ccb2d1e3 100644 (file)
@@ -695,26 +695,6 @@ int acpi_device_add(struct acpi_device *device,
        return result;
 }
 
-struct acpi_device *acpi_get_next_child(struct device *dev,
-                                       struct acpi_device *child)
-{
-       struct acpi_device *adev = ACPI_COMPANION(dev);
-       struct list_head *head, *next;
-
-       if (!adev)
-               return NULL;
-
-       head = &adev->children;
-       if (list_empty(head))
-               return NULL;
-
-       if (!child)
-               return list_first_entry(head, struct acpi_device, node);
-
-       next = child->node.next;
-       return next == head ? NULL : list_entry(next, struct acpi_device, node);
-}
-
 /* --------------------------------------------------------------------------
                                  Device Enumeration
    -------------------------------------------------------------------------- */
@@ -1184,7 +1164,7 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id)
        if (!id)
                return;
 
-       id->id = kstrdup(dev_id, GFP_KERNEL);
+       id->id = kstrdup_const(dev_id, GFP_KERNEL);
        if (!id->id) {
                kfree(id);
                return;
@@ -1322,7 +1302,7 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
        struct acpi_hardware_id *id, *tmp;
 
        list_for_each_entry_safe(id, tmp, &pnp->ids, list) {
-               kfree(id->id);
+               kfree_const(id->id);
                kfree(id);
        }
        kfree(pnp->unique_id);
@@ -1472,7 +1452,7 @@ bool acpi_device_is_present(struct acpi_device *adev)
 }
 
 static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
-                                      char *idstr,
+                                      const char *idstr,
                                       const struct acpi_device_id **matchid)
 {
        const struct acpi_device_id *devid;
@@ -1491,7 +1471,7 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
        return false;
 }
 
-static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr,
+static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
                                        const struct acpi_device_id **matchid)
 {
        struct acpi_scan_handler *handler;
@@ -1933,3 +1913,42 @@ int __init acpi_scan_init(void)
        mutex_unlock(&acpi_scan_lock);
        return result;
 }
+
+static struct acpi_probe_entry *ape;
+static int acpi_probe_count;
+static DEFINE_SPINLOCK(acpi_probe_lock);
+
+static int __init acpi_match_madt(struct acpi_subtable_header *header,
+                                 const unsigned long end)
+{
+       if (!ape->subtable_valid || ape->subtable_valid(header, ape))
+               if (!ape->probe_subtbl(header, end))
+                       acpi_probe_count++;
+
+       return 0;
+}
+
+int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
+{
+       int count = 0;
+
+       if (acpi_disabled)
+               return 0;
+
+       spin_lock(&acpi_probe_lock);
+       for (ape = ap_head; nr; ape++, nr--) {
+               if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) {
+                       acpi_probe_count = 0;
+                       acpi_table_parse_madt(ape->type, acpi_match_madt, 0);
+                       count += acpi_probe_count;
+               } else {
+                       int res;
+                       res = acpi_table_parse(ape->id, ape->probe_table);
+                       if (!res)
+                               count++;
+               }
+       }
+       spin_unlock(&acpi_probe_lock);
+
+       return count;
+}
index 2f0d4db40a9e8aa078787b177d138322fdd6c0b9..0d94621dc856080a0a3715040b7b5339c1edb248 100644 (file)
@@ -487,6 +487,8 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
                pr_err("ACPI does not support sleep state S%u\n", acpi_state);
                return -ENOSYS;
        }
+       if (acpi_state > ACPI_STATE_S1)
+               pm_set_suspend_via_firmware();
 
        acpi_pm_start(acpi_state);
        return 0;
@@ -522,6 +524,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
                if (error)
                        return error;
                pr_info(PREFIX "Low-level resume complete\n");
+               pm_set_resume_via_firmware();
                break;
        }
        trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);
@@ -632,14 +635,16 @@ static int acpi_freeze_prepare(void)
        acpi_enable_wakeup_devices(ACPI_STATE_S0);
        acpi_enable_all_wakeup_gpes();
        acpi_os_wait_events_complete();
-       enable_irq_wake(acpi_gbl_FADT.sci_interrupt);
+       if (acpi_sci_irq_valid())
+               enable_irq_wake(acpi_sci_irq);
        return 0;
 }
 
 static void acpi_freeze_restore(void)
 {
        acpi_disable_wakeup_devices(ACPI_STATE_S0);
-       disable_irq_wake(acpi_gbl_FADT.sci_interrupt);
+       if (acpi_sci_irq_valid())
+               disable_irq_wake(acpi_sci_irq);
        acpi_enable_all_runtime_gpes();
 }
 
index 40a42655227c2ccacd6cf0c0f47269224a8fe658..0243d375c6fd40134bd7404008ef6e43144867dc 100644 (file)
@@ -878,6 +878,9 @@ int __init acpi_sysfs_init(void)
                return result;
 
        hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
+       if (!hotplug_kobj)
+               return -ENOMEM;
+
        result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr);
        if (result)
                return result;
index 17a6fa01a3384e3d1ab52bbb585c50b7f4bde990..6c0f0794aa82bd007a14effaa21494043e3eb8e1 100644 (file)
@@ -210,20 +210,39 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
        }
 }
 
-int __init
-acpi_parse_entries(char *id, unsigned long table_size,
-               acpi_tbl_entry_handler handler,
+/**
+ * acpi_parse_entries_array - for each proc_num find a suitable subtable
+ *
+ * @id: table id (for debugging purposes)
+ * @table_size: single entry size
+ * @table_header: where does the table start?
+ * @proc: array of acpi_subtable_proc struct containing entry id
+ *        and associated handler with it
+ * @proc_num: how big proc is?
+ * @max_entries: how many entries can we process?
+ *
+ * For each proc_num find a subtable with proc->id and run proc->handler
+ * on it. Assumption is that there's only single handler for particular
+ * entry id.
+ *
+ * On success returns sum of all matching entries for all proc handlers.
+ * Otherwise, -ENODEV or -EINVAL is returned.
+ */
+static int __init
+acpi_parse_entries_array(char *id, unsigned long table_size,
                struct acpi_table_header *table_header,
-               int entry_id, unsigned int max_entries)
+               struct acpi_subtable_proc *proc, int proc_num,
+               unsigned int max_entries)
 {
        struct acpi_subtable_header *entry;
-       int count = 0;
        unsigned long table_end;
+       int count = 0;
+       int i;
 
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!id || !handler)
+       if (!id)
                return -EINVAL;
 
        if (!table_size)
@@ -243,20 +262,28 @@ acpi_parse_entries(char *id, unsigned long table_size,
 
        while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
               table_end) {
-               if (entry->type == entry_id
-                   && (!max_entries || count < max_entries)) {
-                       if (handler(entry, table_end))
+               if (max_entries && count >= max_entries)
+                       break;
+
+               for (i = 0; i < proc_num; i++) {
+                       if (entry->type != proc[i].id)
+                               continue;
+                       if (!proc[i].handler ||
+                            proc[i].handler(entry, table_end))
                                return -EINVAL;
 
-                       count++;
+                       proc->count++;
+                       break;
                }
+               if (i != proc_num)
+                       count++;
 
                /*
                 * If entry->length is 0, break from this loop to avoid
                 * infinite loop.
                 */
                if (entry->length == 0) {
-                       pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+                       pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id);
                        return -EINVAL;
                }
 
@@ -266,17 +293,32 @@ acpi_parse_entries(char *id, unsigned long table_size,
 
        if (max_entries && count > max_entries) {
                pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
-                       id, entry_id, count - max_entries, count);
+                       id, proc->id, count - max_entries, count);
        }
 
        return count;
 }
 
 int __init
-acpi_table_parse_entries(char *id,
+acpi_parse_entries(char *id,
+                       unsigned long table_size,
+                       acpi_tbl_entry_handler handler,
+                       struct acpi_table_header *table_header,
+                       int entry_id, unsigned int max_entries)
+{
+       struct acpi_subtable_proc proc = {
+               .id             = entry_id,
+               .handler        = handler,
+       };
+
+       return acpi_parse_entries_array(id, table_size, table_header,
+                       &proc, 1, max_entries);
+}
+
+int __init
+acpi_table_parse_entries_array(char *id,
                         unsigned long table_size,
-                        int entry_id,
-                        acpi_tbl_entry_handler handler,
+                        struct acpi_subtable_proc *proc, int proc_num,
                         unsigned int max_entries)
 {
        struct acpi_table_header *table_header = NULL;
@@ -287,7 +329,7 @@ acpi_table_parse_entries(char *id,
        if (acpi_disabled)
                return -ENODEV;
 
-       if (!id || !handler)
+       if (!id)
                return -EINVAL;
 
        if (!strncmp(id, ACPI_SIG_MADT, 4))
@@ -299,13 +341,29 @@ acpi_table_parse_entries(char *id,
                return -ENODEV;
        }
 
-       count = acpi_parse_entries(id, table_size, handler, table_header,
-                       entry_id, max_entries);
+       count = acpi_parse_entries_array(id, table_size, table_header,
+                       proc, proc_num, max_entries);
 
        early_acpi_os_unmap_memory((char *)table_header, tbl_size);
        return count;
 }
 
+int __init
+acpi_table_parse_entries(char *id,
+                       unsigned long table_size,
+                       int entry_id,
+                       acpi_tbl_entry_handler handler,
+                       unsigned int max_entries)
+{
+       struct acpi_subtable_proc proc = {
+               .id             = entry_id,
+               .handler        = handler,
+       };
+
+       return acpi_table_parse_entries_array(id, table_size, &proc, 1,
+                                               max_entries);
+}
+
 int __init
 acpi_table_parse_madt(enum acpi_madt_type id,
                      acpi_tbl_entry_handler handler, unsigned int max_entries)
index 2922f1f252d58aafd2d6c233404ae7ca21abb524..0d3a384b508a9c4782b7fe20ca1264dc3b11b0bf 100644 (file)
@@ -243,6 +243,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
        },
 
        /* Non win8 machines which need native backlight nevertheless */
+       {
+        /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
+        .callback = video_detect_force_native,
+        .ident = "Lenovo Ideapad S405",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
+               },
+       },
        {
         /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
         .callback = video_detect_force_native,
index 950fff9ce45397024ac5751b452cdd96a6da9907..a12ff9863d7e116ba9f15e21fe9c6fa4070b0f22 100644 (file)
@@ -187,7 +187,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  * global one. Requires architecture specific dev_get_cma_area() helper
  * function.
  */
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int align)
 {
        if (align > CONFIG_CMA_ALIGNMENT)
index 2a4154a09e4dca0dc9af3aa09f9a395a313f60e8..85e17bacc834156664c5980c4f7ea7ef68e5d6b6 100644 (file)
@@ -77,13 +77,16 @@ static bool default_stop_ok(struct device *dev)
                                      dev_update_qos_constraint);
 
        if (constraint_ns > 0) {
-               constraint_ns -= td->start_latency_ns;
+               constraint_ns -= td->save_state_latency_ns +
+                               td->stop_latency_ns +
+                               td->start_latency_ns +
+                               td->restore_state_latency_ns;
                if (constraint_ns == 0)
                        return false;
        }
        td->effective_constraint_ns = constraint_ns;
-       td->cached_stop_ok = constraint_ns > td->stop_latency_ns ||
-                               constraint_ns == 0;
+       td->cached_stop_ok = constraint_ns >= 0;
+
        /*
         * The children have been suspended already, so we don't need to take
         * their stop latencies into account here.
@@ -126,18 +129,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
 
        off_on_time_ns = genpd->power_off_latency_ns +
                                genpd->power_on_latency_ns;
-       /*
-        * It doesn't make sense to remove power from the domain if saving
-        * the state of all devices in it and the power off/power on operations
-        * take too much time.
-        *
-        * All devices in this domain have been stopped already at this point.
-        */
-       list_for_each_entry(pdd, &genpd->dev_list, list_node) {
-               if (pdd->dev->driver)
-                       off_on_time_ns +=
-                               to_gpd_data(pdd)->td.save_state_latency_ns;
-       }
 
        min_off_time_ns = -1;
        /*
@@ -193,7 +184,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
                 * constraint_ns cannot be negative here, because the device has
                 * been suspended.
                 */
-               constraint_ns -= td->restore_state_latency_ns;
                if (constraint_ns <= off_on_time_ns)
                        return false;
 
index 96a92db83cad863ac286ce2249b573bb7c1085a6..07c3c4a9522d4e6bec1f0f540bd38f8c1ce6ed00 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
+#include <linux/suspend.h>
 
 #ifdef CONFIG_PM
 /**
@@ -296,11 +297,27 @@ void pm_generic_complete(struct device *dev)
 
        if (drv && drv->pm && drv->pm->complete)
                drv->pm->complete(dev);
+}
 
+/**
+ * pm_complete_with_resume_check - Complete a device power transition.
+ * @dev: Device to handle.
+ *
+ * Complete a device power transition during a system-wide power transition and
+ * optionally schedule a runtime resume of the device if the system resume in
+ * progress has been initated by the platform firmware and the device had its
+ * power.direct_complete flag set.
+ */
+void pm_complete_with_resume_check(struct device *dev)
+{
+       pm_generic_complete(dev);
        /*
-        * Let runtime PM try to suspend devices that haven't been in use before
-        * going into the system-wide sleep state we're resuming from.
+        * If the device had been runtime-suspended before the system went into
+        * the sleep state it is going out of and it has never been resumed till
+        * now, resume it in case the firmware powered it up.
         */
-       pm_request_idle(dev);
+       if (dev->power.direct_complete && pm_resume_via_firmware())
+               pm_request_resume(dev);
 }
+EXPORT_SYMBOL_GPL(pm_complete_with_resume_check);
 #endif /* CONFIG_PM_SLEEP */
index 51f15bc15774250a203b46c44b5682b36f450f1d..a1e0b9ab847a345c6a09adab3ff9f2fd9af3ad3e 100644 (file)
@@ -25,6 +25,9 @@
  */
 bool events_check_enabled __read_mostly;
 
+/* First wakeup IRQ seen by the kernel in the last cycle. */
+unsigned int pm_wakeup_irq __read_mostly;
+
 /* If set and the system is suspending, terminate the suspend. */
 static bool pm_abort_suspend __read_mostly;
 
@@ -91,7 +94,7 @@ struct wakeup_source *wakeup_source_create(const char *name)
        if (!ws)
                return NULL;
 
-       wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL);
+       wakeup_source_prepare(ws, name ? kstrdup_const(name, GFP_KERNEL) : NULL);
        return ws;
 }
 EXPORT_SYMBOL_GPL(wakeup_source_create);
@@ -154,7 +157,7 @@ void wakeup_source_destroy(struct wakeup_source *ws)
 
        wakeup_source_drop(ws);
        wakeup_source_record(ws);
-       kfree(ws->name);
+       kfree_const(ws->name);
        kfree(ws);
 }
 EXPORT_SYMBOL_GPL(wakeup_source_destroy);
@@ -868,6 +871,15 @@ EXPORT_SYMBOL_GPL(pm_system_wakeup);
 void pm_wakeup_clear(void)
 {
        pm_abort_suspend = false;
+       pm_wakeup_irq = 0;
+}
+
+void pm_system_irq_wakeup(unsigned int irq_number)
+{
+       if (pm_wakeup_irq == 0) {
+               pm_wakeup_irq = irq_number;
+               pm_system_wakeup();
+       }
 }
 
 /**
index 2d75366c61e03c7188e2839ec1e8d727d3365966..de40623bbd8a748fd81f3208810046d05861a75c 100644 (file)
@@ -134,7 +134,7 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
        if (is_of_node(fwnode))
                return of_property_read_bool(to_of_node(fwnode), propname);
        else if (is_acpi_node(fwnode))
-               return !acpi_dev_prop_get(to_acpi_node(fwnode), propname, NULL);
+               return !acpi_node_prop_get(fwnode, propname, NULL);
 
        return !!pset_prop_get(to_pset(fwnode), propname);
 }
@@ -287,6 +287,28 @@ int device_property_read_string(struct device *dev, const char *propname,
 }
 EXPORT_SYMBOL_GPL(device_property_read_string);
 
+/**
+ * device_property_match_string - find a string in an array and return index
+ * @dev: Device to get the property of
+ * @propname: Name of the property holding the array
+ * @string: String to look for
+ *
+ * Find a given string in a string array and if it is found return the
+ * index back.
+ *
+ * Return: %0 if the property was found (success),
+ *        %-EINVAL if given arguments are not valid,
+ *        %-ENODATA if the property does not have a value,
+ *        %-EPROTO if the property is not an array of strings,
+ *        %-ENXIO if no suitable firmware interface is present.
+ */
+int device_property_match_string(struct device *dev, const char *propname,
+                                const char *string)
+{
+       return fwnode_property_match_string(dev_fwnode(dev), propname, string);
+}
+EXPORT_SYMBOL_GPL(device_property_match_string);
+
 #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
        (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
              : of_property_count_elems_of_size((node), (propname), sizeof(type))
@@ -298,8 +320,8 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
                _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \
                                               _type_, _val_, _nval_); \
        else if (is_acpi_node(_fwnode_)) \
-               _ret_ = acpi_dev_prop_read(to_acpi_node(_fwnode_), _propname_, \
-                                          _proptype_, _val_, _nval_); \
+               _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \
+                                           _val_, _nval_); \
        else if (is_pset(_fwnode_)) \
                _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \
                                             _proptype_, _val_, _nval_); \
@@ -440,8 +462,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
                                                      propname, val, nval) :
                        of_property_count_strings(to_of_node(fwnode), propname);
        else if (is_acpi_node(fwnode))
-               return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
-                                         DEV_PROP_STRING, val, nval);
+               return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+                                          val, nval);
        else if (is_pset(fwnode))
                return pset_prop_read_array(to_pset(fwnode), propname,
                                            DEV_PROP_STRING, val, nval);
@@ -470,14 +492,60 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
        if (is_of_node(fwnode))
                return of_property_read_string(to_of_node(fwnode), propname, val);
        else if (is_acpi_node(fwnode))
-               return acpi_dev_prop_read(to_acpi_node(fwnode), propname,
-                                         DEV_PROP_STRING, val, 1);
+               return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
+                                          val, 1);
 
        return pset_prop_read_array(to_pset(fwnode), propname,
                                    DEV_PROP_STRING, val, 1);
 }
 EXPORT_SYMBOL_GPL(fwnode_property_read_string);
 
+/**
+ * fwnode_property_match_string - find a string in an array and return index
+ * @fwnode: Firmware node to get the property of
+ * @propname: Name of the property holding the array
+ * @string: String to look for
+ *
+ * Find a given string in a string array and if it is found return the
+ * index back.
+ *
+ * Return: %0 if the property was found (success),
+ *        %-EINVAL if given arguments are not valid,
+ *        %-ENODATA if the property does not have a value,
+ *        %-EPROTO if the property is not an array of strings,
+ *        %-ENXIO if no suitable firmware interface is present.
+ */
+int fwnode_property_match_string(struct fwnode_handle *fwnode,
+       const char *propname, const char *string)
+{
+       const char **values;
+       int nval, ret, i;
+
+       nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
+       if (nval < 0)
+               return nval;
+
+       values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
+       if (!values)
+               return -ENOMEM;
+
+       ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
+       if (ret < 0)
+               goto out;
+
+       ret = -ENODATA;
+       for (i = 0; i < nval; i++) {
+               if (!strcmp(values[i], string)) {
+                       ret = i;
+                       break;
+               }
+       }
+out:
+       kfree(values);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(fwnode_property_match_string);
+
 /**
  * device_get_next_child_node - Return the next child node handle for a device
  * @dev: Device to find the next child node for.
@@ -493,11 +561,7 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
                if (node)
                        return &node->fwnode;
        } else if (IS_ENABLED(CONFIG_ACPI)) {
-               struct acpi_device *node;
-
-               node = acpi_get_next_child(dev, to_acpi_node(child));
-               if (node)
-                       return acpi_fwnode_handle(node);
+               return acpi_get_next_subnode(dev, child);
        }
        return NULL;
 }
index 293495a75d3d8ce1e0f61e3571ddcc0c1fa14312..1b87623381e2b1183b5c9d57c870b7c10924f65e 100644 (file)
@@ -60,6 +60,7 @@ struct nbd_device {
        bool disconnect; /* a disconnect has been requested by user */
 
        struct timer_list timeout_timer;
+       spinlock_t tasks_lock;
        struct task_struct *task_recv;
        struct task_struct *task_send;
 
@@ -140,21 +141,23 @@ static void sock_shutdown(struct nbd_device *nbd)
 static void nbd_xmit_timeout(unsigned long arg)
 {
        struct nbd_device *nbd = (struct nbd_device *)arg;
-       struct task_struct *task;
+       unsigned long flags;
 
        if (list_empty(&nbd->queue_head))
                return;
 
        nbd->disconnect = true;
 
-       task = READ_ONCE(nbd->task_recv);
-       if (task)
-               force_sig(SIGKILL, task);
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
+
+       if (nbd->task_recv)
+               force_sig(SIGKILL, nbd->task_recv);
 
-       task = READ_ONCE(nbd->task_send);
-       if (task)
+       if (nbd->task_send)
                force_sig(SIGKILL, nbd->task_send);
 
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
        dev_err(nbd_to_dev(nbd), "Connection timed out, killed receiver and sender, shutting down connection\n");
 }
 
@@ -403,17 +406,24 @@ static int nbd_thread_recv(struct nbd_device *nbd)
 {
        struct request *req;
        int ret;
+       unsigned long flags;
 
        BUG_ON(nbd->magic != NBD_MAGIC);
 
        sk_set_memalloc(nbd->sock->sk);
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_recv = current;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        ret = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
        if (ret) {
                dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
+
+               spin_lock_irqsave(&nbd->tasks_lock, flags);
                nbd->task_recv = NULL;
+               spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
                return ret;
        }
 
@@ -429,7 +439,9 @@ static int nbd_thread_recv(struct nbd_device *nbd)
 
        device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_recv = NULL;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        if (signal_pending(current)) {
                siginfo_t info;
@@ -534,8 +546,11 @@ static int nbd_thread_send(void *data)
 {
        struct nbd_device *nbd = data;
        struct request *req;
+       unsigned long flags;
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_send = current;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
 
        set_user_nice(current, MIN_NICE);
        while (!kthread_should_stop() || !list_empty(&nbd->waiting_queue)) {
@@ -572,7 +587,15 @@ static int nbd_thread_send(void *data)
                nbd_handle_req(nbd, req);
        }
 
+       spin_lock_irqsave(&nbd->tasks_lock, flags);
        nbd->task_send = NULL;
+       spin_unlock_irqrestore(&nbd->tasks_lock, flags);
+
+       /* Clear maybe pending signals */
+       if (signal_pending(current)) {
+               siginfo_t info;
+               dequeue_signal_lock(current, &current->blocked, &info);
+       }
 
        return 0;
 }
@@ -1052,6 +1075,7 @@ static int __init nbd_init(void)
                nbd_dev[i].magic = NBD_MAGIC;
                INIT_LIST_HEAD(&nbd_dev[i].waiting_queue);
                spin_lock_init(&nbd_dev[i].queue_lock);
+               spin_lock_init(&nbd_dev[i].tasks_lock);
                INIT_LIST_HEAD(&nbd_dev[i].queue_head);
                mutex_init(&nbd_dev[i].tx_lock);
                init_timer(&nbd_dev[i].timeout_timer);
index 6f04771f1019798cc2feabf73eff2ddbadc84b81..ccc0c1f93daa45fae2603dd8e36bd2dcc38a8217 100644 (file)
@@ -603,27 +603,31 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        struct nvme_iod *iod = ctx;
        struct request *req = iod_get_private(iod);
        struct nvme_cmd_info *cmd_rq = blk_mq_rq_to_pdu(req);
-
        u16 status = le16_to_cpup(&cqe->status) >> 1;
+       bool requeue = false;
+       int error = 0;
 
        if (unlikely(status)) {
                if (!(status & NVME_SC_DNR || blk_noretry_request(req))
                    && (jiffies - req->start_time) < req->timeout) {
                        unsigned long flags;
 
+                       requeue = true;
                        blk_mq_requeue_request(req);
                        spin_lock_irqsave(req->q->queue_lock, flags);
                        if (!blk_queue_stopped(req->q))
                                blk_mq_kick_requeue_list(req->q);
                        spin_unlock_irqrestore(req->q->queue_lock, flags);
-                       return;
+                       goto release_iod;
                }
 
                if (req->cmd_type == REQ_TYPE_DRV_PRIV) {
                        if (cmd_rq->ctx == CMD_CTX_CANCELLED)
-                               status = -EINTR;
+                               error = -EINTR;
+                       else
+                               error = status;
                } else {
-                       status = nvme_error_status(status);
+                       error = nvme_error_status(status);
                }
        }
 
@@ -635,8 +639,9 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        if (cmd_rq->aborted)
                dev_warn(nvmeq->dev->dev,
                        "completing aborted command with status:%04x\n",
-                       status);
+                       error);
 
+release_iod:
        if (iod->nents) {
                dma_unmap_sg(nvmeq->dev->dev, iod->sg, iod->nents,
                        rq_data_dir(req) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
@@ -649,7 +654,8 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
        }
        nvme_free_iod(nvmeq->dev, iod);
 
-       blk_mq_complete_request(req, status);
+       if (likely(!requeue))
+               blk_mq_complete_request(req, error);
 }
 
 /* length is in bytes.  gfp flags indicates whether we may sleep. */
@@ -1804,7 +1810,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
 
        length = (io.nblocks + 1) << ns->lba_shift;
        meta_len = (io.nblocks + 1) * ns->ms;
-       metadata = (void __user *)(unsigned long)io.metadata;
+       metadata = (void __user *)(uintptr_t)io.metadata;
        write = io.opcode & 1;
 
        if (ns->ext) {
@@ -1844,7 +1850,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
        c.rw.metadata = cpu_to_le64(meta_dma);
 
        status = __nvme_submit_sync_cmd(ns->queue, &c, NULL,
-                       (void __user *)io.addr, length, NULL, 0);
+                       (void __user *)(uintptr_t)io.addr, length, NULL, 0);
  unmap:
        if (meta) {
                if (status == NVME_SC_SUCCESS && !write) {
@@ -1886,7 +1892,7 @@ static int nvme_user_cmd(struct nvme_dev *dev, struct nvme_ns *ns,
                timeout = msecs_to_jiffies(cmd.timeout_ms);
 
        status = __nvme_submit_sync_cmd(ns ? ns->queue : dev->admin_q, &c,
-                       NULL, (void __user *)cmd.addr, cmd.data_len,
+                       NULL, (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
                        &cmd.result, timeout);
        if (status >= 0) {
                if (put_user(cmd.result, &ucmd->result))
index d93a0372b37b5c7b4cb214e7013e64897c3a9aba..6f26cf38c6f9c732bfa3293c1b129919a6e245f3 100644 (file)
@@ -96,6 +96,8 @@ static int atomic_dec_return_safe(atomic_t *v)
 #define RBD_MINORS_PER_MAJOR           256
 #define RBD_SINGLE_MAJOR_PART_SHIFT    4
 
+#define RBD_MAX_PARENT_CHAIN_LEN       16
+
 #define RBD_SNAP_DEV_NAME_PREFIX       "snap_"
 #define RBD_MAX_SNAP_NAME_LEN  \
                        (NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
@@ -426,7 +428,7 @@ static ssize_t rbd_add_single_major(struct bus_type *bus, const char *buf,
                                    size_t count);
 static ssize_t rbd_remove_single_major(struct bus_type *bus, const char *buf,
                                       size_t count);
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping);
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
 static void rbd_spec_put(struct rbd_spec *spec);
 
 static int rbd_dev_id_to_minor(int dev_id)
@@ -1863,9 +1865,11 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
                rbd_osd_read_callback(obj_request);
                break;
        case CEPH_OSD_OP_SETALLOCHINT:
-               rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE);
+               rbd_assert(osd_req->r_ops[1].op == CEPH_OSD_OP_WRITE ||
+                          osd_req->r_ops[1].op == CEPH_OSD_OP_WRITEFULL);
                /* fall through */
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
                rbd_osd_write_callback(obj_request);
                break;
        case CEPH_OSD_OP_STAT:
@@ -2401,7 +2405,10 @@ static void rbd_img_obj_request_fill(struct rbd_obj_request *obj_request,
                                opcode = CEPH_OSD_OP_ZERO;
                }
        } else if (op_type == OBJ_OP_WRITE) {
-               opcode = CEPH_OSD_OP_WRITE;
+               if (!offset && length == object_size)
+                       opcode = CEPH_OSD_OP_WRITEFULL;
+               else
+                       opcode = CEPH_OSD_OP_WRITE;
                osd_req_op_alloc_hint_init(osd_request, num_ops,
                                        object_size, object_size);
                num_ops++;
@@ -3760,6 +3767,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        /* set io sizes to object size */
        segment_size = rbd_obj_bytes(&rbd_dev->header);
        blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
+       q->limits.max_sectors = queue_max_hw_sectors(q);
        blk_queue_max_segments(q, segment_size / SECTOR_SIZE);
        blk_queue_max_segment_size(q, segment_size);
        blk_queue_io_min(q, segment_size);
@@ -5125,44 +5133,51 @@ out_err:
        return ret;
 }
 
-static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
+/*
+ * @depth is rbd_dev_image_probe() -> rbd_dev_probe_parent() ->
+ * rbd_dev_image_probe() recursion depth, which means it's also the
+ * length of the already discovered part of the parent chain.
+ */
+static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
 {
        struct rbd_device *parent = NULL;
-       struct rbd_spec *parent_spec;
-       struct rbd_client *rbdc;
        int ret;
 
        if (!rbd_dev->parent_spec)
                return 0;
-       /*
-        * We need to pass a reference to the client and the parent
-        * spec when creating the parent rbd_dev.  Images related by
-        * parent/child relationships always share both.
-        */
-       parent_spec = rbd_spec_get(rbd_dev->parent_spec);
-       rbdc = __rbd_get_client(rbd_dev->rbd_client);
 
-       ret = -ENOMEM;
-       parent = rbd_dev_create(rbdc, parent_spec, NULL);
-       if (!parent)
+       if (++depth > RBD_MAX_PARENT_CHAIN_LEN) {
+               pr_info("parent chain is too long (%d)\n", depth);
+               ret = -EINVAL;
                goto out_err;
+       }
 
-       ret = rbd_dev_image_probe(parent, false);
+       parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec,
+                               NULL);
+       if (!parent) {
+               ret = -ENOMEM;
+               goto out_err;
+       }
+
+       /*
+        * Images related by parent/child relationships always share
+        * rbd_client and spec/parent_spec, so bump their refcounts.
+        */
+       __rbd_get_client(rbd_dev->rbd_client);
+       rbd_spec_get(rbd_dev->parent_spec);
+
+       ret = rbd_dev_image_probe(parent, depth);
        if (ret < 0)
                goto out_err;
+
        rbd_dev->parent = parent;
        atomic_set(&rbd_dev->parent_ref, 1);
-
        return 0;
+
 out_err:
-       if (parent) {
-               rbd_dev_unparent(rbd_dev);
+       rbd_dev_unparent(rbd_dev);
+       if (parent)
                rbd_dev_destroy(parent);
-       } else {
-               rbd_put_client(rbdc);
-               rbd_spec_put(parent_spec);
-       }
-
        return ret;
 }
 
@@ -5280,7 +5295,7 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
  * parent), initiate a watch on its header object before using that
  * object to get detailed information about the rbd image.
  */
-static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
+static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
 {
        int ret;
 
@@ -5298,7 +5313,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
        if (ret)
                goto err_out_format;
 
-       if (mapping) {
+       if (!depth) {
                ret = rbd_dev_header_watch_sync(rbd_dev);
                if (ret) {
                        if (ret == -ENOENT)
@@ -5319,7 +5334,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
         * Otherwise this is a parent image, identified by pool, image
         * and snap ids - need to fill in names for those ids.
         */
-       if (mapping)
+       if (!depth)
                ret = rbd_spec_fill_snap_id(rbd_dev);
        else
                ret = rbd_spec_fill_names(rbd_dev);
@@ -5341,12 +5356,12 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
                 * Need to warn users if this image is the one being
                 * mapped and has a parent.
                 */
-               if (mapping && rbd_dev->parent_spec)
+               if (!depth && rbd_dev->parent_spec)
                        rbd_warn(rbd_dev,
                                 "WARNING: kernel layering is EXPERIMENTAL!");
        }
 
-       ret = rbd_dev_probe_parent(rbd_dev);
+       ret = rbd_dev_probe_parent(rbd_dev, depth);
        if (ret)
                goto err_out_probe;
 
@@ -5357,7 +5372,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
 err_out_probe:
        rbd_dev_unprobe(rbd_dev);
 err_out_watch:
-       if (mapping)
+       if (!depth)
                rbd_dev_header_unwatch_sync(rbd_dev);
 out_header_name:
        kfree(rbd_dev->header_name);
@@ -5420,7 +5435,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        spec = NULL;            /* rbd_dev now owns this */
        rbd_opts = NULL;        /* rbd_dev now owns this */
 
-       rc = rbd_dev_image_probe(rbd_dev, true);
+       rc = rbd_dev_image_probe(rbd_dev, 0);
        if (rc < 0)
                goto err_out_rbd_dev;
 
index 611170896b8c94ce1d7494d62116ba1fde574fce..a69c02dadec05684f2a49eefe98033e8ebbc0c3e 100644 (file)
@@ -1956,7 +1956,8 @@ static void blkback_changed(struct xenbus_device *dev,
                        break;
                /* Missed the backend's Closing state -- fallthrough */
        case XenbusStateClosing:
-               blkfront_closing(info);
+               if (info)
+                       blkfront_closing(info);
                break;
        }
 }
index 7d9879e166cf4c4346402cb353ef3cd002483740..7082c7268845639399d9ceab44471937011e1705 100644 (file)
@@ -1184,11 +1184,12 @@ static int arm_ccn_pmu_cpu_notifier(struct notifier_block *nb,
                if (!cpumask_test_and_clear_cpu(cpu, &dt->cpu))
                        break;
                target = cpumask_any_but(cpu_online_mask, cpu);
-               if (target < 0)
+               if (target >= nr_cpu_ids)
                        break;
                perf_pmu_migrate_context(&dt->pmu, cpu, target);
                cpumask_set_cpu(target, &dt->cpu);
-               WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
+               if (ccn->irq)
+                       WARN_ON(irq_set_affinity(ccn->irq, &dt->cpu) != 0);
        default:
                break;
        }
index 5837eb8a212fbdcd8446ff9da77f393cc05c128a..85da8b9832568b2e4daab35eea661d4d99a5ac26 100644 (file)
@@ -197,6 +197,7 @@ static void __init of_cpu_clk_setup(struct device_node *node)
        for_each_node_by_type(dn, "cpu") {
                struct clk_init_data init;
                struct clk *clk;
+               struct clk *parent_clk;
                char *clk_name = kzalloc(5, GFP_KERNEL);
                int cpu, err;
 
@@ -208,8 +209,9 @@ static void __init of_cpu_clk_setup(struct device_node *node)
                        goto bail_out;
 
                sprintf(clk_name, "cpu%d", cpu);
+               parent_clk = of_clk_get(node, 0);
 
-               cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
+               cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
                cpuclk[cpu].clk_name = clk_name;
                cpuclk[cpu].cpu = cpu;
                cpuclk[cpu].reg_base = clock_complex_base;
index a7726db13abbb0e883ec5681fec65a473bc9d29e..1a9c5dc1e5f9c54de7fc77834de21719ea4258fb 100644 (file)
@@ -2,6 +2,14 @@ menu "Clock Source drivers"
 
 config CLKSRC_OF
        bool
+       select CLKSRC_PROBE
+
+config CLKSRC_ACPI
+       bool
+       select CLKSRC_PROBE
+
+config CLKSRC_PROBE
+       bool
 
 config CLKSRC_I8253
        bool
@@ -123,6 +131,7 @@ config CLKSRC_STM32
 config ARM_ARCH_TIMER
        bool
        select CLKSRC_OF if OF
+       select CLKSRC_ACPI if ACPI
 
 config ARM_ARCH_TIMER_EVTSTREAM
        bool "Support for ARM architected timer event stream generation"
index 5c00863c3e33ad8a3061fdf88765cfb4c0770d97..51856d50bccc33ac49793e7eff9bffc25ef19e80 100644 (file)
@@ -1,4 +1,4 @@
-obj-$(CONFIG_CLKSRC_OF)        += clksrc-of.o
+obj-$(CONFIG_CLKSRC_PROBE)     += clksrc-probe.o
 obj-$(CONFIG_ATMEL_PIT)                += timer-atmel-pit.o
 obj-$(CONFIG_ATMEL_ST)         += timer-atmel-st.o
 obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
index d6e3e49399dd40558823c8db833f2bf8e258b662..c64d543d64bf69576d9d75ffc54839439c70ea9b 100644 (file)
@@ -864,13 +864,5 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
        arch_timer_init();
        return 0;
 }
-
-/* Initialize all the generic timers presented in GTDT */
-void __init acpi_generic_timer_init(void)
-{
-       if (acpi_disabled)
-               return;
-
-       acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
-}
+CLOCKSOURCE_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init);
 #endif
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c
deleted file mode 100644 (file)
index 0093a8e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/clocksource.h>
-
-extern struct of_device_id __clksrc_of_table[];
-
-static const struct of_device_id __clksrc_of_table_sentinel
-       __used __section(__clksrc_of_table_end);
-
-void __init clocksource_of_init(void)
-{
-       struct device_node *np;
-       const struct of_device_id *match;
-       of_init_fn_1 init_func;
-       unsigned clocksources = 0;
-
-       for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
-               if (!of_device_is_available(np))
-                       continue;
-
-               init_func = match->data;
-               init_func(np);
-               clocksources++;
-       }
-       if (!clocksources)
-               pr_crit("%s: no matching clocksources found\n", __func__);
-}
diff --git a/drivers/clocksource/clksrc-probe.c b/drivers/clocksource/clksrc-probe.c
new file mode 100644 (file)
index 0000000..7cb6c92
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/clocksource.h>
+
+extern struct of_device_id __clksrc_of_table[];
+
+static const struct of_device_id __clksrc_of_table_sentinel
+       __used __section(__clksrc_of_table_end);
+
+void __init clocksource_probe(void)
+{
+       struct device_node *np;
+       const struct of_device_id *match;
+       of_init_fn_1 init_func;
+       unsigned clocksources = 0;
+
+       for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
+               if (!of_device_is_available(np))
+                       continue;
+
+               init_func = match->data;
+               init_func(np);
+               clocksources++;
+       }
+
+       clocksources += acpi_probe_device_table(clksrc);
+
+       if (!clocksources)
+               pr_crit("%s: no matching clocksources found\n", __func__);
+}
index cd0391e46c6dbc6163819b533ce225f3afe898e8..642fd49793b0a9284a83eddb3275ff627ca46763 100644 (file)
@@ -227,3 +227,20 @@ config ARM_PXA2xx_CPUFREQ
          This add the CPUFreq driver support for Intel PXA2xx SOCs.
 
          If in doubt, say N.
+
+config ACPI_CPPC_CPUFREQ
+       tristate "CPUFreq driver based on the ACPI CPPC spec"
+       depends on ACPI
+       select ACPI_CPPC_LIB
+       default n
+       help
+         This adds a CPUFreq driver which uses CPPC methods
+         as described in the ACPIv5.1 spec. CPPC stands for
+         Collaborative Processor Performance Controls. It
+         is based on an abstract continuous scale of CPU
+         performance values which allows the remote power
+         processor to flexibly optimize for power and
+         performance. CPPC relies on power management firmware
+         support for its operation.
+
+         If in doubt, say N.
index 41340384f11f291c4fe93e96e73559926f4f59b1..47a7ebbcf998b1ff9e13eedc6647bba428c3e44f 100644 (file)
@@ -76,6 +76,8 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ)               += spear-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)      += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)     += tegra124-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o
+obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
+
 
 ##################################################################################
 # PowerPC platform drivers
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
new file mode 100644 (file)
index 0000000..93c219f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) driver for
+ * interfacing with the CPUfreq layer and governors. See
+ * cppc_acpi.c for CPPC specific methods.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#define pr_fmt(fmt)    "CPPC Cpufreq:" fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/vmalloc.h>
+
+#include <acpi/cppc_acpi.h>
+
+/*
+ * These structs contain information parsed from per CPU
+ * ACPI _CPC structures.
+ * e.g. For each CPU the highest, lowest supported
+ * performance capabilities, desired performance level
+ * requested etc.
+ */
+static struct cpudata **all_cpu_data;
+
+static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
+               unsigned int target_freq,
+               unsigned int relation)
+{
+       struct cpudata *cpu;
+       struct cpufreq_freqs freqs;
+       int ret = 0;
+
+       cpu = all_cpu_data[policy->cpu];
+
+       cpu->perf_ctrls.desired_perf = target_freq;
+       freqs.old = policy->cur;
+       freqs.new = target_freq;
+
+       cpufreq_freq_transition_begin(policy, &freqs);
+       ret = cppc_set_perf(cpu->cpu, &cpu->perf_ctrls);
+       cpufreq_freq_transition_end(policy, &freqs, ret != 0);
+
+       if (ret)
+               pr_debug("Failed to set target on CPU:%d. ret:%d\n",
+                               cpu->cpu, ret);
+
+       return ret;
+}
+
+static int cppc_verify_policy(struct cpufreq_policy *policy)
+{
+       cpufreq_verify_within_cpu_limits(policy);
+       return 0;
+}
+
+static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy)
+{
+       int cpu_num = policy->cpu;
+       struct cpudata *cpu = all_cpu_data[cpu_num];
+       int ret;
+
+       cpu->perf_ctrls.desired_perf = cpu->perf_caps.lowest_perf;
+
+       ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
+       if (ret)
+               pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
+                               cpu->perf_caps.lowest_perf, cpu_num, ret);
+}
+
+static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+       struct cpudata *cpu;
+       unsigned int cpu_num = policy->cpu;
+       int ret = 0;
+
+       cpu = all_cpu_data[policy->cpu];
+
+       cpu->cpu = cpu_num;
+       ret = cppc_get_perf_caps(policy->cpu, &cpu->perf_caps);
+
+       if (ret) {
+               pr_debug("Err reading CPU%d perf capabilities. ret:%d\n",
+                               cpu_num, ret);
+               return ret;
+       }
+
+       policy->min = cpu->perf_caps.lowest_perf;
+       policy->max = cpu->perf_caps.highest_perf;
+       policy->cpuinfo.min_freq = policy->min;
+       policy->cpuinfo.max_freq = policy->max;
+
+       if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+               cpumask_copy(policy->cpus, cpu->shared_cpu_map);
+       else {
+               /* Support only SW_ANY for now. */
+               pr_debug("Unsupported CPU co-ord type\n");
+               return -EFAULT;
+       }
+
+       cpumask_set_cpu(policy->cpu, policy->cpus);
+       cpu->cur_policy = policy;
+
+       /* Set policy->cur to max now. The governors will adjust later. */
+       policy->cur = cpu->perf_ctrls.desired_perf = cpu->perf_caps.highest_perf;
+
+       ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
+       if (ret)
+               pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n",
+                               cpu->perf_caps.highest_perf, cpu_num, ret);
+
+       return ret;
+}
+
+static struct cpufreq_driver cppc_cpufreq_driver = {
+       .flags = CPUFREQ_CONST_LOOPS,
+       .verify = cppc_verify_policy,
+       .target = cppc_cpufreq_set_target,
+       .init = cppc_cpufreq_cpu_init,
+       .stop_cpu = cppc_cpufreq_stop_cpu,
+       .name = "cppc_cpufreq",
+};
+
+static int __init cppc_cpufreq_init(void)
+{
+       int i, ret = 0;
+       struct cpudata *cpu;
+
+       if (acpi_disabled)
+               return -ENODEV;
+
+       all_cpu_data = kzalloc(sizeof(void *) * num_possible_cpus(), GFP_KERNEL);
+       if (!all_cpu_data)
+               return -ENOMEM;
+
+       for_each_possible_cpu(i) {
+               all_cpu_data[i] = kzalloc(sizeof(struct cpudata), GFP_KERNEL);
+               if (!all_cpu_data[i])
+                       goto out;
+
+               cpu = all_cpu_data[i];
+               if (!zalloc_cpumask_var(&cpu->shared_cpu_map, GFP_KERNEL))
+                       goto out;
+       }
+
+       ret = acpi_get_psd_map(all_cpu_data);
+       if (ret) {
+               pr_debug("Error parsing PSD data. Aborting cpufreq registration.\n");
+               goto out;
+       }
+
+       ret = cpufreq_register_driver(&cppc_cpufreq_driver);
+       if (ret)
+               goto out;
+
+       return ret;
+
+out:
+       for_each_possible_cpu(i)
+               if (all_cpu_data[i])
+                       kfree(all_cpu_data[i]);
+
+       kfree(all_cpu_data);
+       return -ENODEV;
+}
+
+late_initcall(cppc_cpufreq_init);
index 980151f34707b2560aab8b1dbe84457b07308949..01a856971f05b8af0b470508dbade67981292392 100644 (file)
@@ -99,44 +99,40 @@ static struct cpuidle_driver armada38x_idle_driver = {
 
 static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
 {
-       mvebu_v7_cpu_suspend = pdev->dev.platform_data;
+       const struct platform_device_id *id = pdev->id_entry;
 
-       if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-xp"))
-               return cpuidle_register(&armadaxp_idle_driver, NULL);
-       else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-370"))
-               return cpuidle_register(&armada370_idle_driver, NULL);
-       else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-38x"))
-               return cpuidle_register(&armada38x_idle_driver, NULL);
-       else
+       if (!id)
                return -EINVAL;
-}
 
-static struct platform_driver armadaxp_cpuidle_plat_driver = {
-       .driver = {
-               .name = "cpuidle-armada-xp",
-       },
-       .probe = mvebu_v7_cpuidle_probe,
-};
+       mvebu_v7_cpu_suspend = pdev->dev.platform_data;
 
-module_platform_driver(armadaxp_cpuidle_plat_driver);
+       return cpuidle_register((struct cpuidle_driver *)id->driver_data, NULL);
+}
 
-static struct platform_driver armada370_cpuidle_plat_driver = {
-       .driver = {
+static const struct platform_device_id mvebu_cpuidle_ids[] = {
+       {
+               .name = "cpuidle-armada-xp",
+               .driver_data = (unsigned long)&armadaxp_idle_driver,
+       }, {
                .name = "cpuidle-armada-370",
+               .driver_data = (unsigned long)&armada370_idle_driver,
+       }, {
+               .name = "cpuidle-armada-38x",
+               .driver_data = (unsigned long)&armada38x_idle_driver,
        },
-       .probe = mvebu_v7_cpuidle_probe,
+       {}
 };
 
-module_platform_driver(armada370_cpuidle_plat_driver);
-
-static struct platform_driver armada38x_cpuidle_plat_driver = {
+static struct platform_driver mvebu_cpuidle_driver = {
+       .probe = mvebu_v7_cpuidle_probe,
        .driver = {
-               .name = "cpuidle-armada-38x",
+               .name = "cpuidle-mbevu",
+               .suppress_bind_attrs = true,
        },
-       .probe = mvebu_v7_cpuidle_probe,
+       .id_table = mvebu_cpuidle_ids,
 };
 
-module_platform_driver(armada38x_cpuidle_plat_driver);
+builtin_platform_driver(mvebu_cpuidle_driver);
 
 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
 MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
index 5a635646e05cfe87a9f92083c5864827c669ccee..981a38fc4cb879b81208edd9ffa588253de53253 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/acpi.h>
 #include <linux/acpi_dma.h>
+#include <linux/property.h>
 
 static LIST_HEAD(acpi_dma_list);
 static DEFINE_MUTEX(acpi_dma_lock);
@@ -413,21 +414,29 @@ EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
  * translate the names "tx" and "rx" here based on the most common case where
  * the first FixedDMA descriptor is TX and second is RX.
  *
+ * If the device has "dma-names" property the FixedDMA descriptor indices
+ * are retrieved based on those. Otherwise the function falls back using
+ * hardcoded indices.
+ *
  * Return:
  * Pointer to appropriate dma channel on success or an error pointer.
  */
 struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev,
                const char *name)
 {
-       size_t index;
-
-       if (!strcmp(name, "tx"))
-               index = 0;
-       else if (!strcmp(name, "rx"))
-               index = 1;
-       else
-               return ERR_PTR(-ENODEV);
+       int index;
+
+       index = device_property_match_string(dev, "dma-names", name);
+       if (index < 0) {
+               if (!strcmp(name, "tx"))
+                       index = 0;
+               else if (!strcmp(name, "rx"))
+                       index = 1;
+               else
+                       return ERR_PTR(-ENODEV);
+       }
 
+       dev_dbg(dev, "found DMA channel \"%s\" at index %d\n", name, index);
        return acpi_dma_request_slave_chan_by_index(dev, index);
 }
 EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name);
index 143a9bdbaa53e1ba056a02549e521ccd6efc2220..69a83626f1aed1ef78bbd6c25a2ffe3208d69274 100644 (file)
@@ -389,6 +389,8 @@ struct acpi_gpio_lookup {
        struct acpi_gpio_info info;
        int index;
        int pin_index;
+       bool active_low;
+       struct acpi_device *adev;
        struct gpio_desc *desc;
        int n;
 };
@@ -425,6 +427,65 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
        return 1;
 }
 
+static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup,
+                                    struct acpi_gpio_info *info)
+{
+       struct list_head res_list;
+       int ret;
+
+       INIT_LIST_HEAD(&res_list);
+
+       ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio,
+                                    lookup);
+       if (ret < 0)
+               return ret;
+
+       acpi_dev_free_resource_list(&res_list);
+
+       if (!lookup->desc)
+               return -ENOENT;
+
+       if (info) {
+               *info = lookup->info;
+               if (lookup->active_low)
+                       info->active_low = lookup->active_low;
+       }
+       return 0;
+}
+
+static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
+                                    const char *propname, int index,
+                                    struct acpi_gpio_lookup *lookup)
+{
+       struct acpi_reference_args args;
+       int ret;
+
+       memset(&args, 0, sizeof(args));
+       ret = acpi_node_get_property_reference(fwnode, propname, index, &args);
+       if (ret) {
+               struct acpi_device *adev = to_acpi_device_node(fwnode);
+
+               if (!adev)
+                       return ret;
+
+               if (!acpi_get_driver_gpio_data(adev, propname, index, &args))
+                       return ret;
+       }
+       /*
+        * The property was found and resolved, so need to lookup the GPIO based
+        * on returned args.
+        */
+       lookup->adev = args.adev;
+       if (args.nargs >= 2) {
+               lookup->index = args.args[0];
+               lookup->pin_index = args.args[1];
+               /* 3rd argument, if present is used to specify active_low. */
+               if (args.nargs >= 3)
+                       lookup->active_low = !!args.args[2];
+       }
+       return 0;
+}
+
 /**
  * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
  * @adev: pointer to a ACPI device to get GPIO from
@@ -452,8 +513,6 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
                                          struct acpi_gpio_info *info)
 {
        struct acpi_gpio_lookup lookup;
-       struct list_head resource_list;
-       bool active_low = false;
        int ret;
 
        if (!adev)
@@ -463,58 +522,64 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
        lookup.index = index;
 
        if (propname) {
-               struct acpi_reference_args args;
-
                dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
 
-               memset(&args, 0, sizeof(args));
-               ret = acpi_dev_get_property_reference(adev, propname,
-                                                     index, &args);
-               if (ret) {
-                       bool found = acpi_get_driver_gpio_data(adev, propname,
-                                                              index, &args);
-                       if (!found)
-                               return ERR_PTR(ret);
-               }
+               ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev),
+                                               propname, index, &lookup);
+               if (ret)
+                       return ERR_PTR(ret);
 
-               /*
-                * The property was found and resolved so need to
-                * lookup the GPIO based on returned args instead.
-                */
-               adev = args.adev;
-               if (args.nargs >= 2) {
-                       lookup.index = args.args[0];
-                       lookup.pin_index = args.args[1];
-                       /*
-                        * 3rd argument, if present is used to
-                        * specify active_low.
-                        */
-                       if (args.nargs >= 3)
-                               active_low = !!args.args[2];
-               }
-
-               dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
-                       dev_name(&adev->dev), args.nargs,
-                       args.args[0], args.args[1], args.args[2]);
+               dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n",
+                       dev_name(&lookup.adev->dev), lookup.index,
+                       lookup.pin_index, lookup.active_low);
        } else {
                dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
+               lookup.adev = adev;
        }
 
-       INIT_LIST_HEAD(&resource_list);
-       ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
-                                    &lookup);
-       if (ret < 0)
-               return ERR_PTR(ret);
+       ret = acpi_gpio_resource_lookup(&lookup, info);
+       return ret ? ERR_PTR(ret) : lookup.desc;
+}
+
+/**
+ * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
+ * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
+ * @propname: Property name of the GPIO
+ * @index: index of GpioIo/GpioInt resource (starting from %0)
+ * @info: info pointer to fill in (optional)
+ *
+ * If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it.
+ * Otherwise (ie. it is a data-only non-device object), use the property-based
+ * GPIO lookup to get to the GPIO resource with the relevant information and use
+ * that to obtain the GPIO descriptor to return.
+ */
+struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+                                     const char *propname, int index,
+                                     struct acpi_gpio_info *info)
+{
+       struct acpi_gpio_lookup lookup;
+       struct acpi_device *adev;
+       int ret;
 
-       acpi_dev_free_resource_list(&resource_list);
+       adev = to_acpi_device_node(fwnode);
+       if (adev)
+               return acpi_get_gpiod_by_index(adev, propname, index, info);
 
-       if (lookup.desc && info) {
-               *info = lookup.info;
-               if (active_low)
-                       info->active_low = active_low;
-       }
+       if (!is_acpi_data_node(fwnode))
+               return ERR_PTR(-ENODEV);
+
+       if (!propname)
+               return ERR_PTR(-EINVAL);
+
+       memset(&lookup, 0, sizeof(lookup));
+       lookup.index = index;
+
+       ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);
+       if (ret)
+               return ERR_PTR(ret);
 
-       return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
+       ret = acpi_gpio_resource_lookup(&lookup, info);
+       return ret ? ERR_PTR(ret) : lookup.desc;
 }
 
 /**
index 5db3445552b176d2c11ca8b225ef88b4b80d22eb..c52a70f3d0a8c0e2c97aa2d4fe9400d5d2ddfa1c 100644 (file)
@@ -2093,8 +2093,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
        } else if (is_acpi_node(fwnode)) {
                struct acpi_gpio_info info;
 
-               desc = acpi_get_gpiod_by_index(to_acpi_node(fwnode), propname, 0,
-                                              &info);
+               desc = acpi_node_get_gpiod(fwnode, propname, 0, &info);
                if (!IS_ERR(desc))
                        active_low = info.active_low;
        }
index bf343004b0085c4bcc21243a63195cb875ca636a..e69c7157cdad16986735c69219703526f0793857 100644 (file)
@@ -42,6 +42,9 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
 struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
                                          const char *propname, int index,
                                          struct acpi_gpio_info *info);
+struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+                                     const char *propname, int index,
+                                     struct acpi_gpio_info *info);
 
 int acpi_gpio_count(struct device *dev, const char *con_id);
 #else
@@ -60,7 +63,12 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
 {
        return ERR_PTR(-ENOSYS);
 }
-
+static inline struct gpio_desc *
+acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
+                   int index, struct acpi_gpio_info *info)
+{
+       return ERR_PTR(-ENXIO);
+}
 static inline int acpi_gpio_count(struct device *dev, const char *con_id)
 {
        return -ENODEV;
index 77f1d7c6ea3af627324b147e63b21b6cbdd16302..9416e0f5c1db2bf8c5601ddee999b1ade5efabc0 100644 (file)
@@ -672,8 +672,12 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
                /* disp clock */
                adev->clock.default_dispclk =
                        le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
-               if (adev->clock.default_dispclk == 0)
-                       adev->clock.default_dispclk = 54000; /* 540 Mhz */
+               /* set a reasonable default for DP */
+               if (adev->clock.default_dispclk < 53900) {
+                       DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",
+                                adev->clock.default_dispclk / 100);
+                       adev->clock.default_dispclk = 60000;
+               }
                adev->clock.dp_extclk =
                        le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
                adev->clock.current_dispclk = adev->clock.default_dispclk;
index cb3c274edb0a6b23a9b830f1ca923cf07ccc45f2..fd16652aa277c75d8ed5ca28e9088c153699addd 100644 (file)
@@ -177,7 +177,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 
        /* get chunks */
        INIT_LIST_HEAD(&p->validated);
-       chunk_array_user = (uint64_t __user *)(cs->in.chunks);
+       chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks);
        if (copy_from_user(chunk_array, chunk_array_user,
                           sizeof(uint64_t)*cs->in.num_chunks)) {
                ret = -EFAULT;
@@ -197,7 +197,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                struct drm_amdgpu_cs_chunk user_chunk;
                uint32_t __user *cdata;
 
-               chunk_ptr = (void __user *)chunk_array[i];
+               chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
                if (copy_from_user(&user_chunk, chunk_ptr,
                                       sizeof(struct drm_amdgpu_cs_chunk))) {
                        ret = -EFAULT;
@@ -208,7 +208,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                p->chunks[i].length_dw = user_chunk.length_dw;
 
                size = p->chunks[i].length_dw;
-               cdata = (void __user *)user_chunk.chunk_data;
+               cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
                p->chunks[i].user_ptr = cdata;
 
                p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
index e3d70772b53104f1f6a48020088d8391d10985b3..dc29ed8145c256c61c6c47da3671664175f4f30d 100644 (file)
@@ -85,8 +85,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
        /* We borrow the event spin lock for protecting flip_status */
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
-       /* set the proper interrupt */
-       amdgpu_irq_get(adev, &adev->pageflip_irq, work->crtc_id);
        /* do the flip (mmio) */
        adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
        /* set the flip status */
index adb48353f2e1a10f169df7c2cd4fc6d6f8e2c23a..b190c2a83680260dba3cfccca1fa6fad6ee6feae 100644 (file)
@@ -242,11 +242,11 @@ static struct pci_device_id pciidlist[] = {
        {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
 #endif
        /* topaz */
-       {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
-       {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
+       {0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
+       {0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
        /* tonga */
        {0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
        {0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
index 8a122b1b77861028c123301726b8bb440537ad55..96290d9cddcab6ad8f0e9e8927a71ff97a093c80 100644 (file)
@@ -402,3 +402,19 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
                return true;
        return false;
 }
+
+void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev)
+{
+       struct amdgpu_fbdev *afbdev = adev->mode_info.rfbdev;
+       struct drm_fb_helper *fb_helper;
+       int ret;
+
+       if (!afbdev)
+               return;
+
+       fb_helper = &afbdev->helper;
+
+       ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+       if (ret)
+               DRM_DEBUG("failed to restore crtc mode\n");
+}
index 8c735f544b6608b0f814dfe2396650ddf9c8a34b..5d11e798230ce759af5d13d5c318aa77cfe755d2 100644 (file)
@@ -485,7 +485,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  * Outdated mess for old drm with Xorg being in charge (void function now).
  */
 /**
- * amdgpu_driver_firstopen_kms - drm callback for last close
+ * amdgpu_driver_lastclose_kms - drm callback for last close
  *
  * @dev: drm dev pointer
  *
@@ -493,6 +493,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  */
 void amdgpu_driver_lastclose_kms(struct drm_device *dev)
 {
+       struct amdgpu_device *adev = dev->dev_private;
+
+       amdgpu_fbdev_restore_mode(adev);
        vga_switcheroo_process_delayed_switch();
 }
 
index 64efe5b52e6500f840f0ad7edbdc6a9f64db6f66..7bd470d9ac30556825260575671c24a3229f28d6 100644 (file)
@@ -567,6 +567,7 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);
 void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
 int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
 bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
+void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);
 
 void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev);
 
index efed11509f4a2326cb5c22b68d20cac77c499705..ed2bbe5b10afe9272cabe2325b183e508c3a1e61 100644 (file)
@@ -294,10 +294,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
        struct amdgpu_device *adev = dev_get_drvdata(dev);
        umode_t effective_mode = attr->mode;
 
-       /* Skip limit attributes if DPM is not enabled */
+       /* Skip attributes if DPM is not enabled */
        if (!adev->pm.dpm_enabled &&
            (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
-            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr))
+            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
                return 0;
 
        /* Skip fan attributes if fan is not present */
index 1e14531353e05ec7aadd69ea9d6e019310a25682..53d551f2d8395ccc24dc799887160e0977419ef2 100644 (file)
@@ -455,8 +455,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
                return -ENOMEM;
 
        r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
-       if (r)
+       if (r) {
+               kfree(ib);
                return r;
+       }
        ib->length_dw = 0;
 
        /* walk over the address space and update the page directory */
index 82e8d073051759f7b0307b7675282a8dfea280e8..a1a35a5df8e71357eea132019d3500a35a89fce4 100644 (file)
@@ -6185,6 +6185,11 @@ static int ci_dpm_late_init(void *handle)
        if (!amdgpu_dpm)
                return 0;
 
+       /* init the sysfs and debugfs files late */
+       ret = amdgpu_pm_sysfs_init(adev);
+       if (ret)
+               return ret;
+
        ret = ci_set_temperature_range(adev);
        if (ret)
                return ret;
@@ -6232,9 +6237,6 @@ static int ci_dpm_sw_init(void *handle)
        adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_failed;
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index 4b6ce74753cded5179b17eaf698ddd16766760b1..484710cfdf8243d563afe908c2b9c9884879f971 100644 (file)
@@ -1567,6 +1567,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
        int ret, i;
        u16 tmp16;
 
+       if (pci_is_root_bus(adev->pdev->bus))
+               return;
+
        if (amdgpu_pcie_gen2 == 0)
                return;
 
index 44fa96ad47099b765ac81e5c439766a8f9849392..2e3373ed4c942d9fc753851d50adb9a3034ebff8 100644 (file)
@@ -596,6 +596,12 @@ static int cz_dpm_late_init(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        if (amdgpu_dpm) {
+               int ret;
+               /* init the sysfs and debugfs files late */
+               ret = amdgpu_pm_sysfs_init(adev);
+               if (ret)
+                       return ret;
+
                /* powerdown unused blocks for now */
                cz_dpm_powergate_uvd(adev, true);
                cz_dpm_powergate_vce(adev, true);
@@ -632,10 +638,6 @@ static int cz_dpm_sw_init(void *handle)
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
 
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_init_failed;
-
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index e4d101b1252a47eaf7a2c7e35c2d8d83f737d762..d4c82b6257273475d15c3274cda7a30404fca231 100644 (file)
@@ -255,6 +255,24 @@ static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v10_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v10_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v10_0_page_flip - pageflip callback.
  *
@@ -2663,9 +2681,10 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v10_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v10_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v10_0_crtc_load_lut(crtc);
                break;
@@ -3025,6 +3044,8 @@ static int dce_v10_0_hw_init(void *handle)
                dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v10_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3039,6 +3060,8 @@ static int dce_v10_0_hw_fini(void *handle)
                dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v10_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3050,6 +3073,8 @@ static int dce_v10_0_suspend(void *handle)
 
        dce_v10_0_hpd_fini(adev);
 
+       dce_v10_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3075,6 +3100,8 @@ static int dce_v10_0_resume(void *handle)
        /* initialize hpd */
        dce_v10_0_hpd_init(adev);
 
+       dce_v10_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3369,7 +3396,6 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index 6411e824467164831eef8af634051f95b8faba69..7e1cf5e4eebf468dfd7c6fc0d97aeccb805e0fbe 100644 (file)
@@ -233,6 +233,24 @@ static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v11_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v11_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v11_0_page_flip - pageflip callback.
  *
@@ -2640,9 +2658,10 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v11_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v11_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v11_0_crtc_load_lut(crtc);
                break;
@@ -2888,7 +2907,7 @@ static int dce_v11_0_early_init(void *handle)
 
        switch (adev->asic_type) {
        case CHIP_CARRIZO:
-               adev->mode_info.num_crtc = 4;
+               adev->mode_info.num_crtc = 3;
                adev->mode_info.num_hpd = 6;
                adev->mode_info.num_dig = 9;
                break;
@@ -3000,6 +3019,8 @@ static int dce_v11_0_hw_init(void *handle)
                dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v11_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3014,6 +3035,8 @@ static int dce_v11_0_hw_fini(void *handle)
                dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v11_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3025,6 +3048,8 @@ static int dce_v11_0_suspend(void *handle)
 
        dce_v11_0_hpd_fini(adev);
 
+       dce_v11_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -3051,6 +3076,8 @@ static int dce_v11_0_resume(void *handle)
        /* initialize hpd */
        dce_v11_0_hpd_init(adev);
 
+       dce_v11_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3345,7 +3372,6 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index c86911c2ea2a896f414473f798d782e9c08518cf..34b9c2a9d8d489c7958af39e0fdbd4e484a572c6 100644 (file)
@@ -204,6 +204,24 @@ static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)
                return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
 }
 
+static void dce_v8_0_pageflip_interrupt_init(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Enable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_get(adev, &adev->pageflip_irq, i);
+}
+
+static void dce_v8_0_pageflip_interrupt_fini(struct amdgpu_device *adev)
+{
+       unsigned i;
+
+       /* Disable pflip interrupts */
+       for (i = 0; i < adev->mode_info.num_crtc; i++)
+               amdgpu_irq_put(adev, &adev->pageflip_irq, i);
+}
+
 /**
  * dce_v8_0_page_flip - pageflip callback.
  *
@@ -2575,9 +2593,10 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
                dce_v8_0_vga_enable(crtc, true);
                amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);
                dce_v8_0_vga_enable(crtc, false);
-               /* Make sure VBLANK interrupt is still enabled */
+               /* Make sure VBLANK and PFLIP interrupts are still enabled */
                type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);
                amdgpu_irq_update(adev, &adev->crtc_irq, type);
+               amdgpu_irq_update(adev, &adev->pageflip_irq, type);
                drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);
                dce_v8_0_crtc_load_lut(crtc);
                break;
@@ -2933,6 +2952,8 @@ static int dce_v8_0_hw_init(void *handle)
                dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v8_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -2947,6 +2968,8 @@ static int dce_v8_0_hw_fini(void *handle)
                dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
        }
 
+       dce_v8_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -2958,6 +2981,8 @@ static int dce_v8_0_suspend(void *handle)
 
        dce_v8_0_hpd_fini(adev);
 
+       dce_v8_0_pageflip_interrupt_fini(adev);
+
        return 0;
 }
 
@@ -2981,6 +3006,8 @@ static int dce_v8_0_resume(void *handle)
        /* initialize hpd */
        dce_v8_0_hpd_init(adev);
 
+       dce_v8_0_pageflip_interrupt_init(adev);
+
        return 0;
 }
 
@@ -3376,7 +3403,6 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
 
        drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
-       amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);
        queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);
 
        return 0;
index 94ec04a9c4d5c975eeb329dc770d3dd055b74ae5..7e9154c7f1dbbb7f9d3eee6791c0e4fcc835ea8d 100644 (file)
@@ -2995,6 +2995,15 @@ static int kv_dpm_late_init(void *handle)
 {
        /* powerdown unused blocks for now */
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int ret;
+
+       if (!amdgpu_dpm)
+               return 0;
+
+       /* init the sysfs and debugfs files late */
+       ret = amdgpu_pm_sysfs_init(adev);
+       if (ret)
+               return ret;
 
        kv_dpm_powergate_acp(adev, true);
        kv_dpm_powergate_samu(adev, true);
@@ -3038,9 +3047,6 @@ static int kv_dpm_sw_init(void *handle)
        adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
        if (amdgpu_dpm == 1)
                amdgpu_pm_print_power_states(adev);
-       ret = amdgpu_pm_sysfs_init(adev);
-       if (ret)
-               goto dpm_failed;
        mutex_unlock(&adev->pm.mutex);
        DRM_INFO("amdgpu: dpm initialized\n");
 
index b55ceb14fdcd91e92f7a5924a232490a6419a80a..0bac8702e9348c2ee9c86ed52d6aaf490ef5032f 100644 (file)
@@ -1005,6 +1005,9 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
        u32 mask;
        int ret;
 
+       if (pci_is_root_bus(adev->pdev->bus))
+               return;
+
        if (amdgpu_pcie_gen2 == 0)
                return;
 
index bf27a07dbce36993e7ed668ff567f5565a6e0995..809959d56d7826364b540204a16190aaf270f9c4 100644 (file)
@@ -1194,17 +1194,18 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
 
                list_for_each_entry(port, &mstb->ports, next) {
                        if (port->port_num == port_num) {
-                               if (!port->mstb) {
+                               mstb = port->mstb;
+                               if (!mstb) {
                                        DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]);
-                                       return NULL;
+                                       goto out;
                                }
 
-                               mstb = port->mstb;
                                break;
                        }
                }
        }
        kref_get(&mstb->kref);
+out:
        mutex_unlock(&mgr->lock);
        return mstb;
 }
@@ -2801,12 +2802,13 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs
        if (msgs[num - 1].flags & I2C_M_RD)
                reading = true;
 
-       if (!reading) {
+       if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) {
                DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n");
                ret = -EIO;
                goto out;
        }
 
+       memset(&msg, 0, sizeof(msg));
        msg.req_type = DP_REMOTE_I2C_READ;
        msg.u.i2c_read.num_transactions = num - 1;
        msg.u.i2c_read.port_number = port->port_num;
index 0f6cd33b531f104f5094513a0992eb99361e65b3..684bd4a138439ef254f7123c66ffde989fede279 100644 (file)
@@ -235,18 +235,12 @@ static ssize_t dpms_show(struct device *device,
                           char *buf)
 {
        struct drm_connector *connector = to_drm_connector(device);
-       struct drm_device *dev = connector->dev;
-       uint64_t dpms_status;
-       int ret;
+       int dpms;
 
-       ret = drm_object_property_get_value(&connector->base,
-                                           dev->mode_config.dpms_property,
-                                           &dpms_status);
-       if (ret)
-               return 0;
+       dpms = READ_ONCE(connector->dpms);
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
-                       drm_get_dpms_name((int)dpms_status));
+                       drm_get_dpms_name(dpms));
 }
 
 static ssize_t enabled_show(struct device *device,
index f6ecbda2c60475297b36b1da6cff0766fb0fe833..674341708033b0aa2900ee0776db9a78424b2028 100644 (file)
@@ -143,7 +143,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
 }
 
 /**
- * i915_gem_shrink - Shrink buffer object caches completely
+ * i915_gem_shrink_all - Shrink buffer object caches completely
  * @dev_priv: i915 device
  *
  * This is a simple wraper around i915_gem_shrink() to aggressively shrink all
index 8fd431bcdfd3a33ffb6afda7a1584b44e33d8296..a96b9006a51e5a893eea071d1d638ef3c2cef6fb 100644 (file)
@@ -804,7 +804,10 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
  * Also note, that the object created here is not currently a "first class"
  * object, in that several ioctls are banned. These are the CPU access
  * ioctls: mmap(), pwrite and pread. In practice, you are expected to use
- * direct access via your pointer rather than use those ioctls.
+ * direct access via your pointer rather than use those ioctls. Another
+ * restriction is that we do not allow userptr surfaces to be pinned to the
+ * hardware and so we reject any attempt to create a framebuffer out of a
+ * userptr.
  *
  * If you think this is a good interface to use to pass GPU memory between
  * drivers, please use dma-buf instead. In fact, wherever possible use
index cf418be7d30a52d0e25ac42201b61b0e42f16dbe..b2270d576979bd2acf42b6bec10d48eed947ab57 100644 (file)
@@ -1724,6 +1724,15 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
                           I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE);
        }
 
+       /*
+        * Apparently we need to have VGA mode enabled prior to changing
+        * the P1/P2 dividers. Otherwise the DPLL will keep using the old
+        * dividers, even though the register value does change.
+        */
+       I915_WRITE(reg, 0);
+
+       I915_WRITE(reg, dpll);
+
        /* Wait for the clocks to stabilize. */
        POSTING_READ(reg);
        udelay(150);
@@ -14107,6 +14116,11 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
        struct drm_i915_gem_object *obj = intel_fb->obj;
 
+       if (obj->userptr.mm) {
+               DRM_DEBUG("attempting to use a userptr for a framebuffer, denied\n");
+               return -EINVAL;
+       }
+
        return drm_gem_handle_create(file, &obj->base, handle);
 }
 
@@ -14897,9 +14911,19 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
        /* restore vblank interrupts to correct state */
        drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
+               struct intel_plane *plane;
+
                drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
                update_scanline_offset(crtc);
                drm_crtc_vblank_on(&crtc->base);
+
+               /* Disable everything but the primary plane */
+               for_each_intel_plane_on_crtc(dev, crtc, plane) {
+                       if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+                               continue;
+
+                       plane->disable_plane(&plane->base, &crtc->base);
+               }
        }
 
        /* We need to sanitize the plane -> pipe mapping first because this will
@@ -15067,38 +15091,25 @@ void i915_redisable_vga(struct drm_device *dev)
        i915_redisable_vga_power_on(dev);
 }
 
-static bool primary_get_hw_state(struct intel_crtc *crtc)
+static bool primary_get_hw_state(struct intel_plane *plane)
 {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 
-       return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
+       return I915_READ(DSPCNTR(plane->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
-static void readout_plane_state(struct intel_crtc *crtc,
-                               struct intel_crtc_state *crtc_state)
+/* FIXME read out full plane state for all planes */
+static void readout_plane_state(struct intel_crtc *crtc)
 {
-       struct intel_plane *p;
-       struct intel_plane_state *plane_state;
-       bool active = crtc_state->base.active;
-
-       for_each_intel_plane(crtc->base.dev, p) {
-               if (crtc->pipe != p->pipe)
-                       continue;
-
-               plane_state = to_intel_plane_state(p->base.state);
+       struct drm_plane *primary = crtc->base.primary;
+       struct intel_plane_state *plane_state =
+               to_intel_plane_state(primary->state);
 
-               if (p->base.type == DRM_PLANE_TYPE_PRIMARY) {
-                       plane_state->visible = primary_get_hw_state(crtc);
-                       if (plane_state->visible)
-                               crtc->base.state->plane_mask |=
-                                       1 << drm_plane_index(&p->base);
-               } else {
-                       if (active)
-                               p->disable_plane(&p->base, &crtc->base);
+       plane_state->visible =
+               primary_get_hw_state(to_intel_plane(primary));
 
-                       plane_state->visible = false;
-               }
-       }
+       if (plane_state->visible)
+               crtc->base.state->plane_mask |= 1 << drm_plane_index(primary);
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15121,34 +15132,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                crtc->base.state->active = crtc->active;
                crtc->base.enabled = crtc->active;
 
-               memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
-               if (crtc->base.state->active) {
-                       intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
-                       intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
-                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
-
-                       /*
-                        * The initial mode needs to be set in order to keep
-                        * the atomic core happy. It wants a valid mode if the
-                        * crtc's enabled, so we do the above call.
-                        *
-                        * At this point some state updated by the connectors
-                        * in their ->detect() callback has not run yet, so
-                        * no recalculation can be done yet.
-                        *
-                        * Even if we could do a recalculation and modeset
-                        * right now it would cause a double modeset if
-                        * fbdev or userspace chooses a different initial mode.
-                        *
-                        * If that happens, someone indicated they wanted a
-                        * mode change, which means it's safe to do a full
-                        * recalculation.
-                        */
-                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
-               }
-
-               crtc->base.hwmode = crtc->config->base.adjusted_mode;
-               readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
+               readout_plane_state(crtc);
 
                DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
                              crtc->base.base.id,
@@ -15207,6 +15191,36 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                              connector->base.name,
                              connector->base.encoder ? "enabled" : "disabled");
        }
+
+       for_each_intel_crtc(dev, crtc) {
+               crtc->base.hwmode = crtc->config->base.adjusted_mode;
+
+               memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
+               if (crtc->base.state->active) {
+                       intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
+                       intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
+                       WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+
+                       /*
+                        * The initial mode needs to be set in order to keep
+                        * the atomic core happy. It wants a valid mode if the
+                        * crtc's enabled, so we do the above call.
+                        *
+                        * At this point some state updated by the connectors
+                        * in their ->detect() callback has not run yet, so
+                        * no recalculation can be done yet.
+                        *
+                        * Even if we could do a recalculation and modeset
+                        * right now it would cause a double modeset if
+                        * fbdev or userspace chooses a different initial mode.
+                        *
+                        * If that happens, someone indicated they wanted a
+                        * mode change, which means it's safe to do a full
+                        * recalculation.
+                        */
+                       crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+               }
+       }
 }
 
 /* Scan out the current hw modeset state,
index 7412caedcf7f98a2a5e494c41e2bad97f34d4e34..29dd4488dc49856b6518ba5fce760cbd4710a1e8 100644 (file)
@@ -1659,6 +1659,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
 
        if (invalidate_domains) {
index 6e6b8db996ef2450c615a71ef10b7ffcbbc62479..61b451fbd09e6ec9de8a42b20a1bb11b6438496f 100644 (file)
@@ -347,6 +347,7 @@ gen7_render_ring_flush(struct drm_i915_gem_request *req,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
        if (invalidate_domains) {
                flags |= PIPE_CONTROL_TLB_INVALIDATE;
@@ -418,6 +419,7 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req,
        if (flush_domains) {
                flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
                flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_FLUSH_ENABLE;
        }
        if (invalidate_domains) {
                flags |= PIPE_CONTROL_TLB_INVALIDATE;
index cc6c228e11c83566d1ac1a2c59fcefa959345463..e905c00acf1a37baef92d66a6f38b888372b9834 100644 (file)
@@ -469,9 +469,13 @@ nouveau_display_create(struct drm_device *dev)
        if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
                dev->mode_config.max_width = 4096;
                dev->mode_config.max_height = 4096;
-       } else {
+       } else
+       if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) {
                dev->mode_config.max_width = 8192;
                dev->mode_config.max_height = 8192;
+       } else {
+               dev->mode_config.max_width = 16384;
+               dev->mode_config.max_height = 16384;
        }
 
        dev->mode_config.preferred_depth = 24;
index 2791701685dc82bf4e2655ce3ea8ea6c3b278e49..59f27e774acb5e9c98c9854bd72195efdbec3a48 100644 (file)
@@ -178,8 +178,30 @@ nouveau_fbcon_sync(struct fb_info *info)
        return 0;
 }
 
+static int
+nouveau_fbcon_open(struct fb_info *info, int user)
+{
+       struct nouveau_fbdev *fbcon = info->par;
+       struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+       int ret = pm_runtime_get_sync(drm->dev->dev);
+       if (ret < 0 && ret != -EACCES)
+               return ret;
+       return 0;
+}
+
+static int
+nouveau_fbcon_release(struct fb_info *info, int user)
+{
+       struct nouveau_fbdev *fbcon = info->par;
+       struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
+       pm_runtime_put(drm->dev->dev);
+       return 0;
+}
+
 static struct fb_ops nouveau_fbcon_ops = {
        .owner = THIS_MODULE,
+       .fb_open = nouveau_fbcon_open,
+       .fb_release = nouveau_fbcon_release,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
        .fb_fillrect = nouveau_fbcon_fillrect,
@@ -195,6 +217,8 @@ static struct fb_ops nouveau_fbcon_ops = {
 
 static struct fb_ops nouveau_fbcon_sw_ops = {
        .owner = THIS_MODULE,
+       .fb_open = nouveau_fbcon_open,
+       .fb_release = nouveau_fbcon_release,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
        .fb_fillrect = drm_fb_helper_cfb_fillrect,
index 2c9981512d27b7702f6f196f64b54276acd8b86e..41be584147b936a921d0c6bdd4e5fe0b4251c70c 100644 (file)
@@ -227,11 +227,12 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
        struct nouveau_bo *nvbo = nouveau_gem_object(gem);
        struct nvkm_vma *vma;
 
-       if (nvbo->bo.mem.mem_type == TTM_PL_TT)
+       if (is_power_of_2(nvbo->valid_domains))
+               rep->domain = nvbo->valid_domains;
+       else if (nvbo->bo.mem.mem_type == TTM_PL_TT)
                rep->domain = NOUVEAU_GEM_DOMAIN_GART;
        else
                rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
-
        rep->offset = nvbo->bo.offset;
        if (cli->vm) {
                vma = nouveau_bo_vma_find(nvbo, cli->vm);
index 65af31441e9c29496647084d927c11f393974653..a7d69ce7abc1ad33b5fd283a5f4b5321feb89f18 100644 (file)
@@ -267,6 +267,12 @@ init_i2c(struct nvbios_init *init, int index)
                index = NVKM_I2C_BUS_PRI;
                if (init->outp && init->outp->i2c_upper_default)
                        index = NVKM_I2C_BUS_SEC;
+       } else
+       if (index == 0x80) {
+               index = NVKM_I2C_BUS_PRI;
+       } else
+       if (index == 0x81) {
+               index = NVKM_I2C_BUS_SEC;
        }
 
        bus = nvkm_i2c_bus_find(i2c, index);
index e0ec2a6b7b795c964e119eae2dfed644d24e4ae2..212800ecdce99e4eb1a3a23ebdab9c207cd860da 100644 (file)
@@ -8,7 +8,10 @@ struct nvbios_source {
        void *(*init)(struct nvkm_bios *, const char *);
        void  (*fini)(void *);
        u32   (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
+       u32   (*size)(void *);
        bool rw;
+       bool ignore_checksum;
+       bool no_pcir;
 };
 
 int nvbios_extend(struct nvkm_bios *, u32 length);
index 792f017525f689bb1d38b86c0bf2e746f9495c8d..b2557e87afdd6d0e95910b3b4b91e37ce9a3e269 100644 (file)
@@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto)
                u32 read = mthd->func->read(data, start, limit - start, bios);
                bios->size = start + read;
        }
-       return bios->size >= limit;
+       return bios->size >= upto;
 }
 
 static int
@@ -55,14 +55,22 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
        struct nvbios_image image;
        int score = 1;
 
-       if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
-               nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
-               return 0;
-       }
+       if (mthd->func->no_pcir) {
+               image.base = 0;
+               image.type = 0;
+               image.size = mthd->func->size(mthd->data);
+               image.last = 1;
+       } else {
+               if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
+                       nvkm_debug(subdev, "%08x: header fetch failed\n",
+                                  offset);
+                       return 0;
+               }
 
-       if (!nvbios_image(bios, idx, &image)) {
-               nvkm_debug(subdev, "image %d invalid\n", idx);
-               return 0;
+               if (!nvbios_image(bios, idx, &image)) {
+                       nvkm_debug(subdev, "image %d invalid\n", idx);
+                       return 0;
+               }
        }
        nvkm_debug(subdev, "%08x: type %02x, %d bytes\n",
                   image.base, image.type, image.size);
@@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
 
        switch (image.type) {
        case 0x00:
-               if (nvbios_checksum(&bios->data[image.base], image.size)) {
+               if (!mthd->func->ignore_checksum &&
+                   nvbios_checksum(&bios->data[image.base], image.size)) {
                        nvkm_debug(subdev, "%08x: checksum failed\n",
                                   image.base);
                        if (mthd->func->rw)
index bd60d7dd09f51a45b70f120597ca38adaf8c102b..4bf486b57101367708bba2b6fe4bdd1d985f1d19 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 #include "priv.h"
+
 #include <core/pci.h>
 
 #if defined(__powerpc__)
@@ -33,17 +34,26 @@ static u32
 of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
 {
        struct priv *priv = data;
-       if (offset + length <= priv->size) {
+       if (offset < priv->size) {
+               length = min_t(u32, length, priv->size - offset);
                memcpy_fromio(bios->data + offset, priv->data + offset, length);
                return length;
        }
        return 0;
 }
 
+static u32
+of_size(void *data)
+{
+       struct priv *priv = data;
+       return priv->size;
+}
+
 static void *
 of_init(struct nvkm_bios *bios, const char *name)
 {
-       struct pci_dev *pdev = bios->subdev.device->func->pci(bios->subdev.device)->pdev;
+       struct nvkm_device *device = bios->subdev.device;
+       struct pci_dev *pdev = device->func->pci(device)->pdev;
        struct device_node *dn;
        struct priv *priv;
        if (!(dn = pci_device_to_OF_node(pdev)))
@@ -62,7 +72,10 @@ nvbios_of = {
        .init = of_init,
        .fini = (void(*)(void *))kfree,
        .read = of_read,
+       .size = of_size,
        .rw = false,
+       .ignore_checksum = true,
+       .no_pcir = true,
 };
 #else
 const struct nvbios_source
index 814cb51cc87372bd4c18225b16b1401d10285b60..385a90f91ed6a14e394ba1e8b4743d9c38c06412 100644 (file)
@@ -35,6 +35,8 @@ static const struct nvkm_device_agp_quirk
 nvkm_device_agp_quirks[] = {
        /* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */
        { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
+       /* SiS 761 does not support AGP cards, use PCI mode */
+       { PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 },
        {},
 };
 
@@ -137,8 +139,10 @@ nvkm_agp_ctor(struct nvkm_pci *pci)
        while (quirk->hostbridge_vendor) {
                if (info.device->vendor == quirk->hostbridge_vendor &&
                    info.device->device == quirk->hostbridge_device &&
-                   pci->pdev->vendor == quirk->chip_vendor &&
-                   pci->pdev->device == quirk->chip_device) {
+                   (quirk->chip_vendor == (u16)PCI_ANY_ID ||
+                   pci->pdev->vendor == quirk->chip_vendor) &&
+                   (quirk->chip_device == (u16)PCI_ANY_ID ||
+                   pci->pdev->device == quirk->chip_device)) {
                        nvkm_info(subdev, "forcing default agp mode to %dX, "
                                          "use NvAGP=<mode> to override\n",
                                  quirk->mode);
index 4649bd2ed3401ae74049798ab591c8b2e2e58779..183aea1abebc4afe5ad28f4694bc92ccc788ee8d 100644 (file)
@@ -242,6 +242,10 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
        bo->is_primary = true;
 
        ret = qxl_bo_reserve(bo, false);
+       if (ret)
+               return ret;
+       ret = qxl_bo_pin(bo, bo->type, NULL);
+       qxl_bo_unreserve(bo);
        if (ret)
                return ret;
 
@@ -257,7 +261,11 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
        }
        drm_vblank_put(dev, qcrtc->index);
 
-       qxl_bo_unreserve(bo);
+       ret = qxl_bo_reserve(bo, false);
+       if (!ret) {
+               qxl_bo_unpin(bo);
+               qxl_bo_unreserve(bo);
+       }
 
        return 0;
 }
index 41c422fee31a02dbc932964bc4686921e533fdd3..c4a552637c9353d70cab76083b7d7786dc436d29 100644 (file)
@@ -144,14 +144,17 @@ static void qxl_dirty_update(struct qxl_fbdev *qfbdev,
 
        spin_lock_irqsave(&qfbdev->dirty.lock, flags);
 
-       if (qfbdev->dirty.y1 < y)
-               y = qfbdev->dirty.y1;
-       if (qfbdev->dirty.y2 > y2)
-               y2 = qfbdev->dirty.y2;
-       if (qfbdev->dirty.x1 < x)
-               x = qfbdev->dirty.x1;
-       if (qfbdev->dirty.x2 > x2)
-               x2 = qfbdev->dirty.x2;
+       if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) &&
+           (qfbdev->dirty.x2 - qfbdev->dirty.x1)) {
+               if (qfbdev->dirty.y1 < y)
+                       y = qfbdev->dirty.y1;
+               if (qfbdev->dirty.y2 > y2)
+                       y2 = qfbdev->dirty.y2;
+               if (qfbdev->dirty.x1 < x)
+                       x = qfbdev->dirty.x1;
+               if (qfbdev->dirty.x2 > x2)
+                       x2 = qfbdev->dirty.x2;
+       }
 
        qfbdev->dirty.x1 = x;
        qfbdev->dirty.x2 = x2;
index b66ec331c17cd51f1b81022ebd29d18944258b43..4efa8e261baf59546ca24eb39920bc4159358ab7 100644 (file)
@@ -307,7 +307,7 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
                if (idr_ret < 0)
                        return idr_ret;
-               bo = qxl_bo_ref(to_qxl_bo(entry->tv.bo));
+               bo = to_qxl_bo(entry->tv.bo);
 
                (*release)->release_offset = create_rel->release_offset + 64;
 
@@ -316,8 +316,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                info = qxl_release_map(qdev, *release);
                info->id = idr_ret;
                qxl_release_unmap(qdev, *release, info);
-
-               qxl_bo_unref(&bo);
                return 0;
        }
 
index d2e9e9efc159c053b954aed21840ebe7d91f2739..6743174acdbcd22b5d357d0275f1e564dc653d81 100644 (file)
@@ -1633,18 +1633,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
        radeon_fbdev_init(rdev);
        drm_kms_helper_poll_init(rdev->ddev);
 
-       if (rdev->pm.dpm_enabled) {
-               /* do dpm late init */
-               ret = radeon_pm_late_init(rdev);
-               if (ret) {
-                       rdev->pm.dpm_enabled = false;
-                       DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
-               }
-               /* set the dpm state for PX since there won't be
-                * a modeset to call this.
-                */
-               radeon_pm_compute_clocks(rdev);
-       }
+       /* do pm late init */
+       ret = radeon_pm_late_init(rdev);
 
        return 0;
 }
index 6cddae44fa6e4cafa59de1b3d7528b82959b6fd9..744f5c49c66463c56187dbc2130a77539a264130 100644 (file)
@@ -283,6 +283,7 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
        radeon_connector->mst_encoder = radeon_dp_create_fake_mst_encoder(master);
 
        drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
+       drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
        drm_mode_connector_set_path_property(connector, pathprop);
 
        return connector;
index 1aa657fe31cb26f88c2d413bb1a38974e091eee2..26da2f4d7b4f56fca3948af07bca9c061bb5ddaf 100644 (file)
@@ -397,3 +397,19 @@ void radeon_fb_remove_connector(struct radeon_device *rdev, struct drm_connector
 {
        drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
 }
+
+void radeon_fbdev_restore_mode(struct radeon_device *rdev)
+{
+       struct radeon_fbdev *rfbdev = rdev->mode_info.rfbdev;
+       struct drm_fb_helper *fb_helper;
+       int ret;
+
+       if (!rfbdev)
+               return;
+
+       fb_helper = &rfbdev->helper;
+
+       ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
+       if (ret)
+               DRM_DEBUG("failed to restore crtc mode\n");
+}
index 4a119c255ba9709692b234c51a928d826cc22ec2..0e932bf932c11f95a59a57bb3c9126e01a6baf3d 100644 (file)
@@ -598,7 +598,7 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  * Outdated mess for old drm with Xorg being in charge (void function now).
  */
 /**
- * radeon_driver_firstopen_kms - drm callback for last close
+ * radeon_driver_lastclose_kms - drm callback for last close
  *
  * @dev: drm dev pointer
  *
@@ -606,6 +606,9 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
  */
 void radeon_driver_lastclose_kms(struct drm_device *dev)
 {
+       struct radeon_device *rdev = dev->dev_private;
+
+       radeon_fbdev_restore_mode(rdev);
        vga_switcheroo_process_delayed_switch();
 }
 
index aecc3e3dec0ca093441e3871df414627b51e92ec..457b026a0972782fc6d777b1069b683c1fda037f 100644 (file)
@@ -980,6 +980,7 @@ int radeon_fbdev_init(struct radeon_device *rdev);
 void radeon_fbdev_fini(struct radeon_device *rdev);
 void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
 bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
+void radeon_fbdev_restore_mode(struct radeon_device *rdev);
 
 void radeon_fb_output_poll_changed(struct radeon_device *rdev);
 
index 05751f3f84449d40457b3f989f0d7ab874935bbf..6a0a176e26ec2ad82df440a94cbe7822d17e393f 100644 (file)
@@ -717,10 +717,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
        struct radeon_device *rdev = dev_get_drvdata(dev);
        umode_t effective_mode = attr->mode;
 
-       /* Skip limit attributes if DPM is not enabled */
+       /* Skip attributes if DPM is not enabled */
        if (rdev->pm.pm_method != PM_METHOD_DPM &&
            (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr ||
-            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr))
+            attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+            attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
                return 0;
 
        /* Skip fan attributes if fan is not present */
@@ -1326,14 +1330,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev)
        INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
 
        if (rdev->pm.num_power_states > 1) {
-               /* where's the best place to put these? */
-               ret = device_create_file(rdev->dev, &dev_attr_power_profile);
-               if (ret)
-                       DRM_ERROR("failed to create device file for power profile\n");
-               ret = device_create_file(rdev->dev, &dev_attr_power_method);
-               if (ret)
-                       DRM_ERROR("failed to create device file for power method\n");
-
                if (radeon_debugfs_pm_init(rdev)) {
                        DRM_ERROR("Failed to register debugfs file for PM!\n");
                }
@@ -1391,20 +1387,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
                goto dpm_failed;
        rdev->pm.dpm_enabled = true;
 
-       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
-       if (ret)
-               DRM_ERROR("failed to create device file for dpm state\n");
-       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
-       if (ret)
-               DRM_ERROR("failed to create device file for dpm state\n");
-       /* XXX: these are noops for dpm but are here for backwards compat */
-       ret = device_create_file(rdev->dev, &dev_attr_power_profile);
-       if (ret)
-               DRM_ERROR("failed to create device file for power profile\n");
-       ret = device_create_file(rdev->dev, &dev_attr_power_method);
-       if (ret)
-               DRM_ERROR("failed to create device file for power method\n");
-
        if (radeon_debugfs_pm_init(rdev)) {
                DRM_ERROR("Failed to register debugfs file for dpm!\n");
        }
@@ -1545,9 +1527,44 @@ int radeon_pm_late_init(struct radeon_device *rdev)
        int ret = 0;
 
        if (rdev->pm.pm_method == PM_METHOD_DPM) {
-               mutex_lock(&rdev->pm.mutex);
-               ret = radeon_dpm_late_enable(rdev);
-               mutex_unlock(&rdev->pm.mutex);
+               if (rdev->pm.dpm_enabled) {
+                       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for dpm state\n");
+                       ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for dpm state\n");
+                       /* XXX: these are noops for dpm but are here for backwards compat */
+                       ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power profile\n");
+                       ret = device_create_file(rdev->dev, &dev_attr_power_method);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power method\n");
+
+                       mutex_lock(&rdev->pm.mutex);
+                       ret = radeon_dpm_late_enable(rdev);
+                       mutex_unlock(&rdev->pm.mutex);
+                       if (ret) {
+                               rdev->pm.dpm_enabled = false;
+                               DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+                       } else {
+                               /* set the dpm state for PX since there won't be
+                                * a modeset to call this.
+                                */
+                               radeon_pm_compute_clocks(rdev);
+                       }
+               }
+       } else {
+               if (rdev->pm.num_power_states > 1) {
+                       /* where's the best place to put these? */
+                       ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power profile\n");
+                       ret = device_create_file(rdev->dev, &dev_attr_power_method);
+                       if (ret)
+                               DRM_ERROR("failed to create device file for power method\n");
+               }
        }
        return ret;
 }
index e9115d3f67b0ca0a34ff68ce564b316895c81939..e72bf46042e0a42f469cbfd8ff285b1ae9abb155 100644 (file)
@@ -2928,6 +2928,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = {
        { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
        { PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
        { PCI_VENDOR_ID_ATI, 0x6811, 0x1762, 0x2015, 0, 120000 },
+       { PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 },
        { 0, 0, 0, 0 },
 };
 
index db8b49101a8b620f742af39c24154933bf3d1ff7..512263919282328cb55505abf2542987c5f9f9cd 100644 (file)
@@ -34,8 +34,8 @@ virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct virtio_gpu_device *vgdev = node->minor->dev->dev_private;
 
-       seq_printf(m, "fence %ld %lld\n",
-                  atomic64_read(&vgdev->fence_drv.last_seq),
+       seq_printf(m, "fence %llu %lld\n",
+                  (u64)atomic64_read(&vgdev->fence_drv.last_seq),
                   vgdev->fence_drv.sync_seq);
        return 0;
 }
index 1da632631dac808e8273fe3aa77a5426950f9156..67097c9ce9c143e2d6ac3534c4379d0f024d4887 100644 (file)
@@ -61,7 +61,7 @@ static void virtio_timeline_value_str(struct fence *f, char *str, int size)
 {
        struct virtio_gpu_fence *fence = to_virtio_fence(f);
 
-       snprintf(str, size, "%lu", atomic64_read(&fence->drv->last_seq));
+       snprintf(str, size, "%llu", (u64)atomic64_read(&fence->drv->last_seq));
 }
 
 static const struct fence_ops virtio_fence_ops = {
index 64b50409fa0749558844cf561aac983e36197241..03f63c749c02333f412c82184f20def8ce1d8d74 100644 (file)
@@ -657,7 +657,8 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
        struct vmw_resource *res = &user_srf->srf.res;
 
        *p_base = NULL;
-       ttm_base_object_unref(&user_srf->backup_base);
+       if (user_srf->backup_base)
+               ttm_base_object_unref(&user_srf->backup_base);
        vmw_resource_unreference(&res);
 }
 
index 3dd2de31a2f8d380f71ff61c562a53d8638f9eb5..472b88285c755e5f18d25ba2c935dbdaca449546 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/i2c.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
@@ -51,6 +52,22 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 }
 
 #ifdef CONFIG_ACPI
+/*
+ * The HCNT/LCNT information coming from ACPI should be the most accurate
+ * for given platform. However, some systems get it wrong. On such systems
+ * we get better results by calculating those based on the input clock.
+ */
+static const struct dmi_system_id dw_i2c_no_acpi_params[] = {
+       {
+               .ident = "Dell Inspiron 7348",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
+               },
+       },
+       { }
+};
+
 static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
                               u16 *hcnt, u16 *lcnt, u32 *sda_hold)
 {
@@ -58,6 +75,9 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
        acpi_handle handle = ACPI_HANDLE(&pdev->dev);
        union acpi_object *obj;
 
+       if (dmi_check_system(dw_i2c_no_acpi_params))
+               return;
+
        if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
                return;
 
@@ -253,12 +273,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
 
-       r = i2c_add_numbered_adapter(adap);
-       if (r) {
-               dev_err(&pdev->dev, "failure adding adapter\n");
-               return r;
-       }
-
        if (dev->pm_runtime_disabled) {
                pm_runtime_forbid(&pdev->dev);
        } else {
@@ -268,6 +282,13 @@ static int dw_i2c_probe(struct platform_device *pdev)
                pm_runtime_enable(&pdev->dev);
        }
 
+       r = i2c_add_numbered_adapter(adap);
+       if (r) {
+               dev_err(&pdev->dev, "failure adding adapter\n");
+               pm_runtime_disable(&pdev->dev);
+               return r;
+       }
+
        return 0;
 }
 
index d8361dada584556baccc2c6bd861eb11028c6d51..d8b5a8fee1e6c85588dd569b80894306b1c76b1a 100644 (file)
@@ -690,15 +690,16 @@ static int rcar_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
+       pm_runtime_enable(dev);
+       platform_set_drvdata(pdev, priv);
+
        ret = i2c_add_numbered_adapter(adap);
        if (ret < 0) {
                dev_err(dev, "reg adap failed: %d\n", ret);
+               pm_runtime_disable(dev);
                return ret;
        }
 
-       pm_runtime_enable(dev);
-       platform_set_drvdata(pdev, priv);
-
        dev_info(dev, "probed\n");
 
        return 0;
index 50bfd8cef5f224aebb189a5b6635b62316f6117c..5df819610d5280cc1fee176344be4d226fc5ea56 100644 (file)
@@ -1243,17 +1243,19 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        i2c->adap.nr = i2c->pdata->bus_num;
        i2c->adap.dev.of_node = pdev->dev.of_node;
 
+       platform_set_drvdata(pdev, i2c);
+
+       pm_runtime_enable(&pdev->dev);
+
        ret = i2c_add_numbered_adapter(&i2c->adap);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+               pm_runtime_disable(&pdev->dev);
                s3c24xx_i2c_deregister_cpufreq(i2c);
                clk_unprepare(i2c->clk);
                return ret;
        }
 
-       platform_set_drvdata(pdev, i2c);
-
-       pm_runtime_enable(&pdev->dev);
        pm_runtime_enable(&i2c->adap.dev);
 
        dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
index 5f89f1e3c2f24fc562a519eb173d33de8c280f42..a59c3111f7fb98df957e19d1fa93faac16322e20 100644 (file)
@@ -694,12 +694,12 @@ static int i2c_device_probe(struct device *dev)
                goto err_clear_wakeup_irq;
 
        status = dev_pm_domain_attach(&client->dev, true);
-       if (status != -EPROBE_DEFER) {
-               status = driver->probe(client, i2c_match_id(driver->id_table,
-                                       client));
-               if (status)
-                       goto err_detach_pm_domain;
-       }
+       if (status == -EPROBE_DEFER)
+               goto err_clear_wakeup_irq;
+
+       status = driver->probe(client, i2c_match_id(driver->id_table, client));
+       if (status)
+               goto err_detach_pm_domain;
 
        return 0;
 
index ff30f880688019fa099d79d7fce3f53b28cfb828..fb93111104249bcc93d390e7492c96f4c211ac27 100644 (file)
 #define ST_ACCEL_4_BDU_MASK                    0x40
 #define ST_ACCEL_4_DRDY_IRQ_ADDR               0x21
 #define ST_ACCEL_4_DRDY_IRQ_INT1_MASK          0x04
-#define ST_ACCEL_4_IG1_EN_ADDR                 0x21
-#define ST_ACCEL_4_IG1_EN_MASK                 0x08
 #define ST_ACCEL_4_MULTIREAD_BIT               true
 
 /* CUSTOM VALUES FOR SENSOR 5 */
@@ -489,10 +487,6 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                .drdy_irq = {
                        .addr = ST_ACCEL_4_DRDY_IRQ_ADDR,
                        .mask_int1 = ST_ACCEL_4_DRDY_IRQ_INT1_MASK,
-                       .ig1 = {
-                               .en_addr = ST_ACCEL_4_IG1_EN_ADDR,
-                               .en_mask = ST_ACCEL_4_IG1_EN_MASK,
-                       },
                },
                .multi_read_bit = ST_ACCEL_4_MULTIREAD_BIT,
                .bootime = 2, /* guess */
index ebe415f1064000c95c88f5d20da48a7f52f71d84..0c74869a540ad390a0f995a702ee953cf53e0669 100644 (file)
 #include <linux/types.h>
 #include <linux/gfp.h>
 #include <linux/err.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/iio/iio.h>
 
+#define TWL4030_USB_SEL_MADC_MCPC      (1<<3)
+#define TWL4030_USB_CARKIT_ANA_CTRL    0xBB
+
 /**
  * struct twl4030_madc_data - a container for madc info
  * @dev:               Pointer to device structure for madc
  * @lock:              Mutex protecting this data structure
+ * @regulator:         Pointer to bias regulator for madc
  * @requests:          Array of request struct corresponding to SW1, SW2 and RT
  * @use_second_irq:    IRQ selection (main or co-processor)
  * @imr:               Interrupt mask register of MADC
@@ -60,6 +65,7 @@
 struct twl4030_madc_data {
        struct device *dev;
        struct mutex lock;      /* mutex protecting this data structure */
+       struct regulator *usb3v1;
        struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
        bool use_second_irq;
        u8 imr;
@@ -841,6 +847,32 @@ static int twl4030_madc_probe(struct platform_device *pdev)
        }
        twl4030_madc = madc;
 
+       /* Configure MADC[3:6] */
+       ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
+                       TWL4030_USB_CARKIT_ANA_CTRL);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
+                               TWL4030_USB_CARKIT_ANA_CTRL);
+               goto err_i2c;
+       }
+       regval |= TWL4030_USB_SEL_MADC_MCPC;
+       ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
+                                TWL4030_USB_CARKIT_ANA_CTRL);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
+                               TWL4030_USB_CARKIT_ANA_CTRL);
+               goto err_i2c;
+       }
+
+       /* Enable 3v1 bias regulator for MADC[3:6] */
+       madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
+       if (IS_ERR(madc->usb3v1))
+               return -ENODEV;
+
+       ret = regulator_enable(madc->usb3v1);
+       if (ret)
+               dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
+
        ret = iio_device_register(iio_dev);
        if (ret) {
                dev_err(&pdev->dev, "could not register iio device\n");
@@ -866,6 +898,8 @@ static int twl4030_madc_remove(struct platform_device *pdev)
        twl4030_madc_set_current_generator(madc, 0, 0);
        twl4030_madc_set_power(madc, 0);
 
+       regulator_disable(madc->usb3v1);
+
        return 0;
 }
 
index 8f66c67ff0df09380dc7c486dce44d92efac1f18..87471ef371986c11f59e6761e7566ebec78cc1cd 100644 (file)
@@ -508,12 +508,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
        memset(&gid_attr, 0, sizeof(gid_attr));
        gid_attr.ndev = ndev;
 
+       mutex_lock(&table->lock);
        ix = find_gid(table, NULL, NULL, true, GID_ATTR_FIND_MASK_DEFAULT);
 
        /* Coudn't find default GID location */
        WARN_ON(ix < 0);
 
-       mutex_lock(&table->lock);
        if (!__ib_cache_gid_get(ib_dev, port, ix,
                                &current_gid, &current_gid_attr) &&
            mode == IB_CACHE_GID_DEFAULT_MODE_SET &&
index ea4db9c1d44fba56ea5798649f3744c78b148e87..4f918b929eca955532cd5dc0541bc842272a0a3b 100644 (file)
@@ -835,6 +835,11 @@ retest:
        case IB_CM_SIDR_REQ_RCVD:
                spin_unlock_irq(&cm_id_priv->lock);
                cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
+               spin_lock_irq(&cm.lock);
+               if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
+                       rb_erase(&cm_id_priv->sidr_id_node,
+                                &cm.remote_sidr_table);
+               spin_unlock_irq(&cm.lock);
                break;
        case IB_CM_REQ_SENT:
        case IB_CM_MRA_REQ_RCVD:
@@ -3172,7 +3177,10 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
        spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 
        spin_lock_irqsave(&cm.lock, flags);
-       rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+       if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
+               rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+               RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
+       }
        spin_unlock_irqrestore(&cm.lock, flags);
        return 0;
 
index b1ab13f3e182bb520cc986512d11e9016ecf1362..36b12d560e17e5a862a2e37d1f56875b46425f4b 100644 (file)
@@ -1067,14 +1067,14 @@ static int cma_save_req_info(const struct ib_cm_event *ib_event,
                       sizeof(req->local_gid));
                req->has_gid    = true;
                req->service_id = req_param->primary_path->service_id;
-               req->pkey       = req_param->bth_pkey;
+               req->pkey       = be16_to_cpu(req_param->primary_path->pkey);
                break;
        case IB_CM_SIDR_REQ_RECEIVED:
                req->device     = sidr_param->listen_id->device;
                req->port       = sidr_param->port;
                req->has_gid    = false;
                req->service_id = sidr_param->service_id;
-               req->pkey       = sidr_param->bth_pkey;
+               req->pkey       = sidr_param->pkey;
                break;
        default:
                return -EINVAL;
@@ -1232,14 +1232,32 @@ static bool cma_match_private_data(struct rdma_id_private *id_priv,
        return true;
 }
 
+static bool cma_protocol_roce_dev_port(struct ib_device *device, int port_num)
+{
+       enum rdma_link_layer ll = rdma_port_get_link_layer(device, port_num);
+       enum rdma_transport_type transport =
+               rdma_node_get_transport(device->node_type);
+
+       return ll == IB_LINK_LAYER_ETHERNET && transport == RDMA_TRANSPORT_IB;
+}
+
+static bool cma_protocol_roce(const struct rdma_cm_id *id)
+{
+       struct ib_device *device = id->device;
+       const int port_num = id->port_num ?: rdma_start_port(device);
+
+       return cma_protocol_roce_dev_port(device, port_num);
+}
+
 static bool cma_match_net_dev(const struct rdma_id_private *id_priv,
                              const struct net_device *net_dev)
 {
        const struct rdma_addr *addr = &id_priv->id.route.addr;
 
        if (!net_dev)
-               /* This request is an AF_IB request */
-               return addr->src_addr.ss_family == AF_IB;
+               /* This request is an AF_IB request or a RoCE request */
+               return addr->src_addr.ss_family == AF_IB ||
+                      cma_protocol_roce(&id_priv->id);
 
        return !addr->dev_addr.bound_dev_if ||
               (net_eq(dev_net(net_dev), &init_net) &&
@@ -1294,6 +1312,10 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
                if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
                        /* Assuming the protocol is AF_IB */
                        *net_dev = NULL;
+               } else if (cma_protocol_roce_dev_port(req.device, req.port)) {
+                       /* TODO find the net dev matching the request parameters
+                        * through the RoCE GID table */
+                       *net_dev = NULL;
                } else {
                        return ERR_CAST(*net_dev);
                }
@@ -1302,7 +1324,7 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
        bind_list = cma_ps_find(rdma_ps_from_service_id(req.service_id),
                                cma_port_from_service_id(req.service_id));
        id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev);
-       if (IS_ERR(id_priv)) {
+       if (IS_ERR(id_priv) && *net_dev) {
                dev_put(*net_dev);
                *net_dev = NULL;
        }
@@ -1593,11 +1615,16 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
                if (ret)
                        goto err;
        } else {
-               /* An AF_IB connection */
-               WARN_ON_ONCE(ss_family != AF_IB);
-
-               cma_translate_ib((struct sockaddr_ib *)cma_src_addr(id_priv),
-                                &rt->addr.dev_addr);
+               if (!cma_protocol_roce(listen_id) &&
+                   cma_any_addr(cma_src_addr(id_priv))) {
+                       rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
+                       rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
+                       ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
+               } else if (!cma_any_addr(cma_src_addr(id_priv))) {
+                       ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
+                       if (ret)
+                               goto err;
+               }
        }
        rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
 
@@ -1635,13 +1662,12 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
                if (ret)
                        goto err;
        } else {
-               /* An AF_IB connection */
-               WARN_ON_ONCE(ss_family != AF_IB);
-
-               if (!cma_any_addr(cma_src_addr(id_priv)))
-                       cma_translate_ib((struct sockaddr_ib *)
-                                               cma_src_addr(id_priv),
-                                        &id->route.addr.dev_addr);
+               if (!cma_any_addr(cma_src_addr(id_priv))) {
+                       ret = cma_translate_addr(cma_src_addr(id_priv),
+                                                &id->route.addr.dev_addr);
+                       if (ret)
+                               goto err;
+               }
        }
 
        id_priv->state = RDMA_CM_CONNECT;
index 6b24cba1e474df33002186275fb2a7ca81c83717..178f98482e13e217c16d447978a855a900808bc0 100644 (file)
@@ -250,25 +250,44 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
                                 u8 port, struct net_device *ndev)
 {
        struct in_device *in_dev;
+       struct sin_list {
+               struct list_head        list;
+               struct sockaddr_in      ip;
+       };
+       struct sin_list *sin_iter;
+       struct sin_list *sin_temp;
 
+       LIST_HEAD(sin_list);
        if (ndev->reg_state >= NETREG_UNREGISTERING)
                return;
 
-       in_dev = in_dev_get(ndev);
-       if (!in_dev)
+       rcu_read_lock();
+       in_dev = __in_dev_get_rcu(ndev);
+       if (!in_dev) {
+               rcu_read_unlock();
                return;
+       }
 
        for_ifa(in_dev) {
-               struct sockaddr_in ip;
+               struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 
-               ip.sin_family = AF_INET;
-               ip.sin_addr.s_addr = ifa->ifa_address;
-               update_gid_ip(GID_ADD, ib_dev, port, ndev,
-                             (struct sockaddr *)&ip);
+               if (!entry) {
+                       pr_warn("roce_gid_mgmt: couldn't allocate entry for IPv4 update\n");
+                       continue;
+               }
+               entry->ip.sin_family = AF_INET;
+               entry->ip.sin_addr.s_addr = ifa->ifa_address;
+               list_add_tail(&entry->list, &sin_list);
        }
        endfor_ifa(in_dev);
+       rcu_read_unlock();
 
-       in_dev_put(in_dev);
+       list_for_each_entry_safe(sin_iter, sin_temp, &sin_list, list) {
+               update_gid_ip(GID_ADD, ib_dev, port, ndev,
+                             (struct sockaddr *)&sin_iter->ip);
+               list_del(&sin_iter->list);
+               kfree(sin_iter);
+       }
 }
 
 static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
index a53fc9b01c69957cb6d45433c4a34a0a69a5c367..30467d10df91b170e40657864354356153545e76 100644 (file)
@@ -1624,11 +1624,16 @@ static int ucma_open(struct inode *inode, struct file *filp)
        if (!file)
                return -ENOMEM;
 
+       file->close_wq = create_singlethread_workqueue("ucma_close_id");
+       if (!file->close_wq) {
+               kfree(file);
+               return -ENOMEM;
+       }
+
        INIT_LIST_HEAD(&file->event_list);
        INIT_LIST_HEAD(&file->ctx_list);
        init_waitqueue_head(&file->poll_wait);
        mutex_init(&file->mut);
-       file->close_wq = create_singlethread_workqueue("ucma_close_id");
 
        filp->private_data = file;
        file->filp = filp;
index 5be13d8991bce0e7c4edec27c8034e847d4cba29..f903502d3883256e8044dbbec9b2ef9baa2fbdc4 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 04a66229584e0089ef72e027f986d3d71a574b0d..7fe9502ce8d3df43a57b8e7325ecd0aa262949cd 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 3935672661423ff007f6cfc405197967e56c9792..596e0ed49a8e2a066097b5612da723535fdcccbc 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 9d737ed5e55d905e6452d2c5fb20f040cf765705..b54986de5f0cad3677461af613862351ca3fb3f2 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 5d13860161a4a64af533b3a5aee3c43e25e475d0..5e55b8bc6fe402af423118c1454b5bc67d21d8ba 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 4087d24a88f6d9a1e6080b3a2b91dff473cd0944..98453e91daa6f0a1d91c9eb50d468a2585bfcdbe 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index e3c9bd9d3ba366d7f5cd8ef30f5cd5f43b3fbe74..3c37dd59c04eaec750e5ddbf98383e8e4b64d669 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 93713a2230b36724c5bef33933de4c512ba89784..3a8add9ddf4611f89272ee21a0a17dc70fe5028f 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index e5a9297dd1bd3eac9f2dda97f2954e002a31ca4f..525bf272671e6973afb13472263dd8f730c4eac3 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 34c49b8105feb4b59ae320997622e4145d24a742..0c15bd885035ee5fe5110e1317cafe09e762fe07 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index db3588df3546b3ceaf8dce0ae8e175e6326265a3..85dc3f989ff72aa565c85efb4d07fdc7772d3c93 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index b0aafe8db0c35a9d2930e59207a0a01f530b1792..b1458be1d402d60b417904ec450e3d7a0b5b5020 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 27dc67c1689ff4245dff59931f91e5c3d22b58c4..3412ea06116e2cca6ba802571edd5e48186edc7f 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 0d09b493cd02b4f8fa12a217c8cfc19e39cc5693..3d98e16cfeaf67fa9300d941eb064b96fd40b274 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 7df43827cb29661a039d1794d24a20e6cbf1b094..f8e3211689a3453164c9044f3bef4601053c1dba 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 0bd04efa16f33f514c30b3b5c32cf62f8488c271..414eaa566bd94e5f05a796a5416ef8f76e7939f6 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 75777a66c6848a1d7e946782052382e8f031c0b9..183fcb6a952f4bdaf0714492e1e3cce4a3d15852 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index ddef6f77a78cf4c3fbf68a1b867a23b843fd3124..de318389a301a58058fb166acd85aef0189e89d5 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 7e5dc6d9f462d68ecc3a99a7ef997e74d4e2b626..9a7a2d9755c021928ea38be608abda733129a76d 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index cb2337f0532b5dcbe0d328eb74a196d976b7b6dc..645a5f6e6c88f0a4166bf0647d26d3b7bf082670 100644 (file)
@@ -7,7 +7,7 @@
  * licenses.  You may choose to be licensed under the terms of the GNU
  * General Public License (GPL) Version 2, available from the file
  * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
+ * BSD license below:
  *
  *     Redistribution and use in source and binary forms, with or
  *     without modification, are permitted provided that the following
index 70440996e8f2cbee289fb137d16dbd7ece78d345..45ca7c1613a7f76a86b8ac81c0d215746490ea04 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 3a4288e0fbace4621df7166e7e64ca7a97a9d283..42b4b4c4e452eae8b712fb0ef295f304a7ab7492 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2014, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index d4f752e258fd4812ec81c2f627ba4ff9e222e4cc..c0b0b876ab905a574dd23c3a87fa13d8d9ce4990 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 656b88c39edab15c27214e2e963ce31104fcb2e5..66de93fb8ea934c15051f7b33fa7808306f19f05 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 14d931a8829dc4616571af436e30fd2b03070825..a08423e478af2778f9529f558221658aa62c1f42 100644 (file)
@@ -1,9 +1,24 @@
 /*
  * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
index 4cd5428a2399a2cc73757c49382842094714d1bc..edc5b8565d6d9eb5ba6e22e1baefd21d53986b5f 100644 (file)
@@ -495,6 +495,7 @@ void ipoib_dev_cleanup(struct net_device *dev);
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
 void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb);
+void ipoib_mcast_free(struct ipoib_mcast *mc);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
index f74316e679d2fc2b7b27212d47fc806e95844f01..babba05d7a0eb707f472d7de3cb06843a0844eff 100644 (file)
@@ -1207,8 +1207,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
 
 out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
+       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
                ipoib_mcast_leave(dev, mcast);
+               ipoib_mcast_free(mcast);
+       }
 }
 
 static void ipoib_reap_neigh(struct work_struct *work)
index 136cbefe00f87aeb79b02d6508d42fdac5741069..d750a86042f3d8da0736c23a52f41737b329c37d 100644 (file)
@@ -106,7 +106,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
                queue_delayed_work(priv->wq, &priv->mcast_task, 0);
 }
 
-static void ipoib_mcast_free(struct ipoib_mcast *mcast)
+void ipoib_mcast_free(struct ipoib_mcast *mcast)
 {
        struct net_device *dev = mcast->dev;
        int tx_dropped = 0;
index 5f191071d44a033d45d1f433475cd3b7d0b4befd..e4eb048d1bf63f8bc2d7027800a81a58cdf4f855 100644 (file)
@@ -241,14 +241,10 @@ static int cyapa_gen6_read_sys_info(struct cyapa *cyapa)
        memcpy(&cyapa->product_id[13], &resp_data[62], 2);
        cyapa->product_id[15] = '\0';
 
+       /* Get the number of Rx electrodes. */
        rotat_align = resp_data[68];
-       if (rotat_align) {
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-       } else {
-               cyapa->electrodes_rx = cyapa->electrodes_x;
-               cyapa->electrodes_rx = cyapa->electrodes_y;
-       }
+       cyapa->electrodes_rx =
+               rotat_align ? cyapa->electrodes_y : cyapa->electrodes_x;
        cyapa->aligned_electrodes_rx = (cyapa->electrodes_rx + 3) & ~3u;
 
        if (!cyapa->electrodes_x || !cyapa->electrodes_y ||
index db91de539ee30bfc14612f0056f3979b884ff4aa..454195709a824b3e5a346b3aa9e087672dccdcae 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/i8042.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 
 #include <asm/io.h>
 
@@ -1170,7 +1171,8 @@ static int i8042_pm_suspend(struct device *dev)
 {
        int i;
 
-       i8042_controller_reset(true);
+       if (pm_suspend_via_firmware())
+               i8042_controller_reset(true);
 
        /* Set up serio interrupts for system wakeup. */
        for (i = 0; i < I8042_NUM_PORTS; i++) {
@@ -1183,8 +1185,17 @@ static int i8042_pm_suspend(struct device *dev)
        return 0;
 }
 
+static int i8042_pm_resume_noirq(struct device *dev)
+{
+       if (!pm_resume_via_firmware())
+               i8042_interrupt(0, NULL);
+
+       return 0;
+}
+
 static int i8042_pm_resume(struct device *dev)
 {
+       bool force_reset;
        int i;
 
        for (i = 0; i < I8042_NUM_PORTS; i++) {
@@ -1195,11 +1206,21 @@ static int i8042_pm_resume(struct device *dev)
        }
 
        /*
-        * On resume from S2R we always try to reset the controller
-        * to bring it in a sane state. (In case of S2D we expect
-        * BIOS to reset the controller for us.)
+        * If platform firmware was not going to be involved in suspend, we did
+        * not restore the controller state to whatever it had been at boot
+        * time, so we do not need to do anything.
         */
-       return i8042_controller_resume(true);
+       if (!pm_suspend_via_firmware())
+               return 0;
+
+       /*
+        * We only need to reset the controller if we are resuming after handing
+        * off control to the platform firmware, otherwise we can simply restore
+        * the mode.
+        */
+       force_reset = pm_resume_via_firmware();
+
+       return i8042_controller_resume(force_reset);
 }
 
 static int i8042_pm_thaw(struct device *dev)
@@ -1223,6 +1244,7 @@ static int i8042_pm_restore(struct device *dev)
 
 static const struct dev_pm_ops i8042_pm_ops = {
        .suspend        = i8042_pm_suspend,
+       .resume_noirq   = i8042_pm_resume_noirq,
        .resume         = i8042_pm_resume,
        .thaw           = i8042_pm_thaw,
        .poweroff       = i8042_pm_reset,
index 0f5f968592bd02afd9c5381a8839b3428c3bcbea..04edc8f7122fa77d9c043694ba8f47d0c83dab0c 100644 (file)
@@ -668,18 +668,22 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
 
 static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
 {
+       int value;
        struct spi_transfer *t =
                list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
 
        if (ts->model == 7845) {
-               return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
+               value = be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1]));
        } else {
                /*
                 * adjust:  on-wire is a must-ignore bit, a BE12 value, then
                 * padding; built from two 8 bit values written msb-first.
                 */
-               return be16_to_cpup((__be16 *)t->rx_buf) >> 3;
+               value = be16_to_cpup((__be16 *)t->rx_buf);
        }
+
+       /* enforce ADC output is 12 bits width */
+       return (value >> 3) & 0xfff;
 }
 
 static void ads7846_update_value(struct spi_message *m, int val)
index d9da766719c863327d4a8563804994c3edfd01c0..cbe6a890a93a0d1448f46e32edbfdc5231ba7098 100644 (file)
@@ -23,8 +23,7 @@ config IOMMU_IO_PGTABLE
 config IOMMU_IO_PGTABLE_LPAE
        bool "ARMv7/v8 Long Descriptor Format"
        select IOMMU_IO_PGTABLE
-       # SWIOTLB guarantees a dma_to_phys() implementation
-       depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
+       depends on HAS_DMA && (ARM || ARM64 || COMPILE_TEST)
        help
          Enable support for the ARM long descriptor pagetable format.
          This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
index f82060e778a23bb7a8901ef2356d42b5363d93a6..08d2775887f7add00e44858cc6bf4a5eece6e260 100644 (file)
@@ -2006,6 +2006,15 @@ static void do_detach(struct iommu_dev_data *dev_data)
 {
        struct amd_iommu *iommu;
 
+       /*
+        * First check if the device is still attached. It might already
+        * be detached from its domain because the generic
+        * iommu_detach_group code detached it and we try again here in
+        * our alias handling.
+        */
+       if (!dev_data->domain)
+               return;
+
        iommu = amd_iommu_rlookup_table[dev_data->devid];
 
        /* decrease reference counters */
index 5ef347a13cb5d54789c07869b0527d81cb24365e..1b066e7d144d6fdc0043cfbfa340ce2e7a209c50 100644 (file)
@@ -1256,6 +1256,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
        if (!iommu->dev)
                return -ENODEV;
 
+       /* Prevent binding other PCI device drivers to IOMMU devices */
+       iommu->dev->match_driver = false;
+
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
                              &iommu->cap);
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_RANGE_OFFSET,
index dafaf59dc3b82833fb78d55e8f194ff728999d35..286e890e7d64caa31867044f568e3a3cf6ce2ba9 100644 (file)
@@ -56,6 +56,7 @@
 #define IDR0_TTF_SHIFT                 2
 #define IDR0_TTF_MASK                  0x3
 #define IDR0_TTF_AARCH64               (2 << IDR0_TTF_SHIFT)
+#define IDR0_TTF_AARCH32_64            (3 << IDR0_TTF_SHIFT)
 #define IDR0_S1P                       (1 << 1)
 #define IDR0_S2P                       (1 << 0)
 
 #define CMDQ_TLBI_0_VMID_SHIFT         32
 #define CMDQ_TLBI_0_ASID_SHIFT         48
 #define CMDQ_TLBI_1_LEAF               (1UL << 0)
-#define CMDQ_TLBI_1_ADDR_MASK          ~0xfffUL
+#define CMDQ_TLBI_1_VA_MASK            ~0xfffUL
+#define CMDQ_TLBI_1_IPA_MASK           0xfffffffff000UL
 
 #define CMDQ_PRI_0_SSID_SHIFT          12
 #define CMDQ_PRI_0_SSID_MASK           0xfffffUL
@@ -770,11 +772,13 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
                break;
        case CMDQ_OP_TLBI_NH_VA:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
-               /* Fallthrough */
+               cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
+               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
+               break;
        case CMDQ_OP_TLBI_S2_IPA:
                cmd[0] |= (u64)ent->tlbi.vmid << CMDQ_TLBI_0_VMID_SHIFT;
                cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
-               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_ADDR_MASK;
+               cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_IPA_MASK;
                break;
        case CMDQ_OP_TLBI_NH_ASID:
                cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
@@ -2460,7 +2464,13 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
        }
 
        /* We only support the AArch64 table format at present */
-       if ((reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) < IDR0_TTF_AARCH64) {
+       switch (reg & IDR0_TTF_MASK << IDR0_TTF_SHIFT) {
+       case IDR0_TTF_AARCH32_64:
+               smmu->ias = 40;
+               /* Fallthrough */
+       case IDR0_TTF_AARCH64:
+               break;
+       default:
                dev_err(smmu->dev, "AArch64 table format not supported!\n");
                return -ENXIO;
        }
@@ -2541,8 +2551,7 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
                dev_warn(smmu->dev,
                         "failed to set DMA mask for table walker\n");
 
-       if (!smmu->ias)
-               smmu->ias = smmu->oas;
+       smmu->ias = max(smmu->ias, smmu->oas);
 
        dev_info(smmu->dev, "ias %lu-bit, oas %lu-bit (features 0x%08x)\n",
                 smmu->ias, smmu->oas, smmu->features);
index 041bc1810a86131deb77152dd6b5a7cd43338a5d..d65cf42399e8e5aa0f856a1ab6869c041adc0c48 100644 (file)
@@ -2115,15 +2115,19 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                                return -ENOMEM;
                        /* It is large page*/
                        if (largepage_lvl > 1) {
+                               unsigned long nr_superpages, end_pfn;
+
                                pteval |= DMA_PTE_LARGE_PAGE;
                                lvl_pages = lvl_to_nr_pages(largepage_lvl);
+
+                               nr_superpages = sg_res / lvl_pages;
+                               end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
+
                                /*
                                 * Ensure that old small page tables are
-                                * removed to make room for superpage,
-                                * if they exist.
+                                * removed to make room for superpage(s).
                                 */
-                               dma_pte_free_pagetable(domain, iov_pfn,
-                                                      iov_pfn + lvl_pages - 1);
+                               dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
                        } else {
                                pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
                        }
@@ -2301,6 +2305,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
 
        if (ret) {
                spin_unlock_irqrestore(&device_domain_lock, flags);
+               free_devinfo_mem(info);
                return NULL;
        }
 
index 73c07482f48763c5af3f0d43d73a2f04774bb74d..7df97777662d4d8a9284a8f2cae4cc0e8891210a 100644 (file)
@@ -202,9 +202,9 @@ typedef u64 arm_lpae_iopte;
 
 static bool selftest_running = false;
 
-static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages)
+static dma_addr_t __arm_lpae_dma_addr(void *pages)
 {
-       return phys_to_dma(dev, virt_to_phys(pages));
+       return (dma_addr_t)virt_to_phys(pages);
 }
 
 static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
@@ -223,10 +223,10 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
                        goto out_free;
                /*
                 * We depend on the IOMMU being able to work with any physical
-                * address directly, so if the DMA layer suggests it can't by
-                * giving us back some translation, that bodes very badly...
+                * address directly, so if the DMA layer suggests otherwise by
+                * translating or truncating them, that bodes very badly...
                 */
-               if (dma != __arm_lpae_dma_addr(dev, pages))
+               if (dma != virt_to_phys(pages))
                        goto out_unmap;
        }
 
@@ -243,10 +243,8 @@ out_free:
 static void __arm_lpae_free_pages(void *pages, size_t size,
                                  struct io_pgtable_cfg *cfg)
 {
-       struct device *dev = cfg->iommu_dev;
-
        if (!selftest_running)
-               dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
+               dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
                                 size, DMA_TO_DEVICE);
        free_pages_exact(pages, size);
 }
@@ -254,12 +252,11 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
 static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
                               struct io_pgtable_cfg *cfg)
 {
-       struct device *dev = cfg->iommu_dev;
-
        *ptep = pte;
 
        if (!selftest_running)
-               dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
+               dma_sync_single_for_device(cfg->iommu_dev,
+                                          __arm_lpae_dma_addr(ptep),
                                           sizeof(pte), DMA_TO_DEVICE);
 }
 
@@ -629,6 +626,11 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
        if (cfg->oas > ARM_LPAE_MAX_ADDR_BITS)
                return NULL;
 
+       if (!selftest_running && cfg->iommu_dev->dma_pfn_offset) {
+               dev_err(cfg->iommu_dev, "Cannot accommodate DMA offset for IOMMU page tables\n");
+               return NULL;
+       }
+
        data = kmalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return NULL;
index 982c09c2d79171d21355c75153b4de87f4a1bee2..d4add30d1d4650c507da403aca880f6157ef6681 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqchip/arm-gic.h>
-#include <linux/irqchip/arm-gic-acpi.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -1195,7 +1194,7 @@ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 #endif
 
 #ifdef CONFIG_ACPI
-static phys_addr_t dist_phy_base, cpu_phy_base __initdata;
+static phys_addr_t cpu_phy_base __initdata;
 
 static int __init
 gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
@@ -1223,60 +1222,56 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
        return 0;
 }
 
-static int __init
-gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-                               const unsigned long end)
+/* The things you have to do to just *count* something... */
+static int __init acpi_dummy_func(struct acpi_subtable_header *header,
+                                 const unsigned long end)
 {
-       struct acpi_madt_generic_distributor *dist;
+       return 0;
+}
 
-       dist = (struct acpi_madt_generic_distributor *)header;
+static bool __init acpi_gic_redist_is_present(void)
+{
+       return acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+                                    acpi_dummy_func, 0) > 0;
+}
 
-       if (BAD_MADT_ENTRY(dist, end))
-               return -EINVAL;
+static bool __init gic_validate_dist(struct acpi_subtable_header *header,
+                                    struct acpi_probe_entry *ape)
+{
+       struct acpi_madt_generic_distributor *dist;
+       dist = (struct acpi_madt_generic_distributor *)header;
 
-       dist_phy_base = dist->base_address;
-       return 0;
+       return (dist->version == ape->driver_data &&
+               (dist->version != ACPI_MADT_GIC_VERSION_NONE ||
+                !acpi_gic_redist_is_present()));
 }
 
-int __init
-gic_v2_acpi_init(struct acpi_table_header *table)
+#define ACPI_GICV2_DIST_MEM_SIZE       (SZ_4K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE       (SZ_8K)
+
+static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
+                                  const unsigned long end)
 {
+       struct acpi_madt_generic_distributor *dist;
        void __iomem *cpu_base, *dist_base;
        int count;
 
        /* Collect CPU base addresses */
-       count = acpi_parse_entries(ACPI_SIG_MADT,
-                                  sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_cpu, table,
-                                  ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
+       count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+                                     gic_acpi_parse_madt_cpu, 0);
        if (count <= 0) {
                pr_err("No valid GICC entries exist\n");
                return -EINVAL;
        }
 
-       /*
-        * Find distributor base address. We expect one distributor entry since
-        * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-        */
-       count = acpi_parse_entries(ACPI_SIG_MADT,
-                                  sizeof(struct acpi_table_madt),
-                                  gic_acpi_parse_madt_distributor, table,
-                                  ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-       if (count <= 0) {
-               pr_err("No valid GICD entries exist\n");
-               return -EINVAL;
-       } else if (count > 1) {
-               pr_err("More than one GICD entry detected\n");
-               return -EINVAL;
-       }
-
        cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
        if (!cpu_base) {
                pr_err("Unable to map GICC registers\n");
                return -ENOMEM;
        }
 
-       dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
+       dist = (struct acpi_madt_generic_distributor *)header;
+       dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
        if (!dist_base) {
                pr_err("Unable to map GICD registers\n");
                iounmap(cpu_base);
@@ -1302,4 +1297,10 @@ gic_v2_acpi_init(struct acpi_table_header *table)
        acpi_irq_model = ACPI_IRQ_MODEL_GIC;
        return 0;
 }
+IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+                    gic_validate_dist, ACPI_MADT_GIC_VERSION_V2,
+                    gic_v2_acpi_init);
+IRQCHIP_ACPI_DECLARE(gic_v2_maybe, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+                    gic_validate_dist, ACPI_MADT_GIC_VERSION_NONE,
+                    gic_v2_acpi_init);
 #endif
index afd1af3dfe5a231692cd0904c5b5a18e5c3f8245..2b35e68bea825c3a5d132d42a2a52b2740ec1353 100644 (file)
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/acpi_irq.h>
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/of_irq.h>
 #include <linux/irqchip.h>
@@ -27,6 +27,5 @@ extern struct of_device_id __irqchip_of_table[];
 void __init irqchip_init(void)
 {
        of_irq_init(__irqchip_of_table);
-
-       acpi_irq_init();
+       acpi_probe_device_table(irqchip);
 }
index 20cc36b01b77895625adbe82a14923148d688edb..0a17d1b91a811d712a350c399d94cdc50322f0d0 100644 (file)
@@ -634,10 +634,10 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
 
        disk_super = dm_block_data(sblock);
 
+       disk_super->flags = cpu_to_le32(cmd->flags);
        if (mutator)
                update_flags(disk_super, mutator);
 
-       disk_super->flags = cpu_to_le32(cmd->flags);
        disk_super->mapping_root = cpu_to_le64(cmd->root);
        disk_super->hint_root = cpu_to_le64(cmd->hint_root);
        disk_super->discard_root = cpu_to_le64(cmd->discard_root);
index aeacad9be51dcb1c10c78df1398abddb9e8bc4f1..117a05e40090a9b78829ed415446d906c8268701 100644 (file)
@@ -847,6 +847,7 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
 static int persistent_ctr(struct dm_exception_store *store, char *options)
 {
        struct pstore *ps;
+       int r;
 
        /* allocate the pstore */
        ps = kzalloc(sizeof(*ps), GFP_KERNEL);
@@ -868,9 +869,9 @@ static int persistent_ctr(struct dm_exception_store *store, char *options)
 
        ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0);
        if (!ps->metadata_wq) {
-               kfree(ps);
                DMERR("couldn't start header metadata update thread");
-               return -ENOMEM;
+               r = -ENOMEM;
+               goto err_workqueue;
        }
 
        if (options) {
@@ -879,13 +880,21 @@ static int persistent_ctr(struct dm_exception_store *store, char *options)
                        store->userspace_supports_overflow = true;
                else {
                        DMERR("Unsupported persistent store option: %s", options);
-                       return -EINVAL;
+                       r = -EINVAL;
+                       goto err_options;
                }
        }
 
        store->context = ps;
 
        return 0;
+
+err_options:
+       destroy_workqueue(ps->metadata_wq);
+err_workqueue:
+       kfree(ps);
+
+       return r;
 }
 
 static unsigned persistent_status(struct dm_exception_store *store,
index 6fcbfb0633665a7c7b91d036b771cd997560e3de..3897b90bd462d852e0aec27a792be14655efa150 100644 (file)
@@ -3201,7 +3201,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
                                                metadata_low_callback,
                                                pool);
        if (r)
-               goto out_free_pt;
+               goto out_flags_changed;
 
        pt->callbacks.congested_fn = pool_is_congested;
        dm_table_add_target_callbacks(ti->table, &pt->callbacks);
index 421a36c593e3e7dedef785a5f78c12914c13d8b3..2e4c4cb79e4d939f0ed2638986d2ccc3ddd8b972 100644 (file)
@@ -301,11 +301,16 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
 {
        int s;
        uint32_t max_entries = le32_to_cpu(left->header.max_entries);
-       unsigned target = (nr_left + nr_center + nr_right) / 3;
-       BUG_ON(target > max_entries);
+       unsigned total = nr_left + nr_center + nr_right;
+       unsigned target_right = total / 3;
+       unsigned remainder = (target_right * 3) != total;
+       unsigned target_left = target_right + remainder;
+
+       BUG_ON(target_left > max_entries);
+       BUG_ON(target_right > max_entries);
 
        if (nr_left < nr_right) {
-               s = nr_left - target;
+               s = nr_left - target_left;
 
                if (s < 0 && nr_center < -s) {
                        /* not enough in central node */
@@ -316,10 +321,10 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
                } else
                        shift(left, center, s);
 
-               shift(center, right, target - nr_right);
+               shift(center, right, target_right - nr_right);
 
        } else {
-               s = target - nr_right;
+               s = target_right - nr_right;
                if (s > 0 && nr_center < s) {
                        /* not enough in central node */
                        shift(center, right, nr_center);
@@ -329,7 +334,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
                } else
                        shift(center, right, s);
 
-               shift(left, center, nr_left - target);
+               shift(left, center, nr_left - target_left);
        }
 
        *key_ptr(parent, c->index) = center->keys[0];
index b6cec258cc2138497b3c8875fc4defdb7523701f..0e09aef43998ac250cc296122247875eed23ceb2 100644 (file)
@@ -523,7 +523,7 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 
        r = new_block(s->info, &right);
        if (r < 0) {
-               /* FIXME: put left */
+               unlock_block(s->info, left);
                return r;
        }
 
index b055319d532edd93ff85f5e68c57e4ae1ac9493a..c1e2d1834b782096ff3e35fefa3db8bb5c2bb786 100644 (file)
@@ -46,8 +46,8 @@ extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
                                        const struct horus3a_config *config,
                                        struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend *horus3a_attach(
-                                       const struct cxd2820r_config *config,
+static inline struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
+                                       const struct horus3a_config *config,
                                        struct i2c_adapter *i2c)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
index 69f30e21f6b31f96497c3d6acccc4a0000b7e822..1f329ef05accea6601a093e33078b5104ef2cfa2 100644 (file)
@@ -43,7 +43,7 @@ struct dvb_frontend *lnbh25_attach(
        struct lnbh25_config *cfg,
        struct i2c_adapter *i2c);
 #else
-static inline dvb_frontend *lnbh25_attach(
+static inline struct dvb_frontend *lnbh25_attach(
        struct dvb_frontend *fe,
        struct lnbh25_config *cfg,
        struct i2c_adapter *i2c)
index ff31e7a01ca9aba8f9746e61d5091d2d1f45c255..feeeb70d841ed92a485e4ec630b1133d51c75291 100644 (file)
 
 static struct dvb_frontend_ops m88ds3103_ops;
 
+/* write single register with mask */
+static int m88ds3103_update_bits(struct m88ds3103_dev *dev,
+                               u8 reg, u8 mask, u8 val)
+{
+       int ret;
+       u8 tmp;
+
+       /* no need for read if whole reg is written */
+       if (mask != 0xff) {
+               ret = regmap_bulk_read(dev->regmap, reg, &tmp, 1);
+               if (ret)
+                       return ret;
+
+               val &= mask;
+               tmp &= ~mask;
+               val |= tmp;
+       }
+
+       return regmap_bulk_write(dev->regmap, reg, &val, 1);
+}
+
 /* write reg val table using reg addr auto increment */
 static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev,
                const struct m88ds3103_reg_val *tab, int tab_len)
@@ -394,10 +415,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                        u8tmp2 = 0x00; /* 0b00 */
                        break;
                }
-               ret = regmap_update_bits(dev->regmap, 0x22, 0xc0, u8tmp1 << 6);
+               ret = m88ds3103_update_bits(dev, 0x22, 0xc0, u8tmp1 << 6);
                if (ret)
                        goto err;
-               ret = regmap_update_bits(dev->regmap, 0x24, 0xc0, u8tmp2 << 6);
+               ret = m88ds3103_update_bits(dev, 0x24, 0xc0, u8tmp2 << 6);
                if (ret)
                        goto err;
        }
@@ -455,13 +476,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
                        if (ret)
                                goto err;
                }
-               ret = regmap_update_bits(dev->regmap, 0x9d, 0x08, 0x08);
+               ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
                if (ret)
                        goto err;
                ret = regmap_write(dev->regmap, 0xf1, 0x01);
                if (ret)
                        goto err;
-               ret = regmap_update_bits(dev->regmap, 0x30, 0x80, 0x80);
+               ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
                if (ret)
                        goto err;
        }
@@ -498,7 +519,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
        switch (dev->cfg->ts_mode) {
        case M88DS3103_TS_SERIAL:
        case M88DS3103_TS_SERIAL_D7:
-               ret = regmap_update_bits(dev->regmap, 0x29, 0x20, u8tmp1);
+               ret = m88ds3103_update_bits(dev, 0x29, 0x20, u8tmp1);
                if (ret)
                        goto err;
                u8tmp1 = 0;
@@ -567,11 +588,11 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
        if (ret)
                goto err;
 
-       ret = regmap_update_bits(dev->regmap, 0x4d, 0x02, dev->cfg->spec_inv << 1);
+       ret = m88ds3103_update_bits(dev, 0x4d, 0x02, dev->cfg->spec_inv << 1);
        if (ret)
                goto err;
 
-       ret = regmap_update_bits(dev->regmap, 0x30, 0x10, dev->cfg->agc_inv << 4);
+       ret = m88ds3103_update_bits(dev, 0x30, 0x10, dev->cfg->agc_inv << 4);
        if (ret)
                goto err;
 
@@ -625,13 +646,13 @@ static int m88ds3103_init(struct dvb_frontend *fe)
        dev->warm = false;
 
        /* wake up device from sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x01);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x00);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x00);
        if (ret)
                goto err;
 
@@ -749,18 +770,18 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
                utmp = 0x29;
        else
                utmp = 0x27;
-       ret = regmap_update_bits(dev->regmap, utmp, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, utmp, 0x01, 0x00);
        if (ret)
                goto err;
 
        /* sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
        if (ret)
                goto err;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
        if (ret)
                goto err;
 
@@ -992,12 +1013,12 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
        }
 
        utmp = tone << 7 | dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
        utmp = 1 << 2;
-       ret = regmap_update_bits(dev->regmap, 0xa1, reg_a1_mask, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa1, reg_a1_mask, utmp);
        if (ret)
                goto err;
 
@@ -1047,7 +1068,7 @@ static int m88ds3103_set_voltage(struct dvb_frontend *fe,
        voltage_dis ^= dev->cfg->lnb_en_pol;
 
        utmp = voltage_dis << 1 | voltage_sel << 0;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0x03, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0x03, utmp);
        if (ret)
                goto err;
 
@@ -1080,7 +1101,7 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
        }
 
        utmp = dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
@@ -1115,12 +1136,12 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
        } else {
                dev_dbg(&client->dev, "diseqc tx timeout\n");
 
-               ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+               ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
                if (ret)
                        goto err;
        }
 
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
        if (ret)
                goto err;
 
@@ -1152,7 +1173,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
        }
 
        utmp = dev->cfg->envelope_mode << 5;
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xe0, utmp);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
        if (ret)
                goto err;
 
@@ -1194,12 +1215,12 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
        } else {
                dev_dbg(&client->dev, "diseqc tx timeout\n");
 
-               ret = regmap_update_bits(dev->regmap, 0xa1, 0xc0, 0x40);
+               ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
                if (ret)
                        goto err;
        }
 
-       ret = regmap_update_bits(dev->regmap, 0xa2, 0xc0, 0x80);
+       ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
        if (ret)
                goto err;
 
@@ -1435,13 +1456,13 @@ static int m88ds3103_probe(struct i2c_client *client,
                goto err_kfree;
 
        /* sleep */
-       ret = regmap_update_bits(dev->regmap, 0x08, 0x01, 0x00);
+       ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
        if (ret)
                goto err_kfree;
-       ret = regmap_update_bits(dev->regmap, 0x04, 0x01, 0x01);
+       ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
        if (ret)
                goto err_kfree;
-       ret = regmap_update_bits(dev->regmap, 0x23, 0x10, 0x10);
+       ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
        if (ret)
                goto err_kfree;
 
index 81788c5a44d838dc1f6e27e7c060db174af56913..821a8f481507a14ec3857c66cd7c4744a6ac3efd 100644 (file)
@@ -502,6 +502,10 @@ static int si2168_init(struct dvb_frontend *fe)
                /* firmware is in the new format */
                for (remaining = fw->size; remaining > 0; remaining -= 17) {
                        len = fw->data[fw->size - remaining];
+                       if (len > SI2168_ARGLEN) {
+                               ret = -EINVAL;
+                               break;
+                       }
                        memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
                        cmd.wlen = len;
                        cmd.rlen = 1;
index f55b3276f28de0122c3f4e4385cb3a1736d0b430..56773f3893d40e02d6b9cde1a72fcf0108ad350d 100644 (file)
@@ -80,11 +80,9 @@ irqreturn_t netup_spi_interrupt(struct netup_spi *spi)
        u16 reg;
        unsigned long flags;
 
-       if (!spi) {
-               dev_dbg(&spi->master->dev,
-                       "%s(): SPI not initialized\n", __func__);
+       if (!spi)
                return IRQ_NONE;
-       }
+
        spin_lock_irqsave(&spi->lock, flags);
        reg = readw(&spi->regs->control_stat);
        if (!(reg & NETUP_SPI_CTRL_IRQ)) {
@@ -234,11 +232,9 @@ void netup_spi_release(struct netup_unidvb_dev *ndev)
        unsigned long flags;
        struct netup_spi *spi = ndev->spi;
 
-       if (!spi) {
-               dev_dbg(&spi->master->dev,
-                       "%s(): SPI not initialized\n", __func__);
+       if (!spi)
                return;
-       }
+
        spin_lock_irqsave(&spi->lock, flags);
        reg = readw(&spi->regs->control_stat);
        writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat);
index 486aef50d99b23e4753cbd055221cd2dbb4f6097..f922f2e827bcbb2bfe8cd0606fac89d3ec8c5bd6 100644 (file)
@@ -1097,7 +1097,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
        Elf32_Ehdr *ehdr;
        Elf32_Phdr *phdr;
        u8 __iomem *dst;
-       int err, i;
+       int err = 0, i;
 
        if (!fw || !context)
                return -EINVAL;
@@ -1106,7 +1106,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
        phdr = (Elf32_Phdr *)(fw->data + ehdr->e_phoff);
 
        /* go through the available ELF segments */
-       for (i = 0; i < ehdr->e_phnum && !err; i++, phdr++) {
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
 
                /* Only consider LOAD segments */
                if (phdr->p_type != PT_LOAD)
@@ -1192,7 +1192,6 @@ err:
 
 static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
 {
-       int ret;
        int err;
 
        dev_info(fei->dev, "Loading firmware: %s\n", FIRMWARE_MEMDMA);
@@ -1207,7 +1206,7 @@ static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
        if (err) {
                dev_err(fei->dev, "request_firmware_nowait err: %d.\n", err);
                complete_all(&fei->fw_ack);
-               return ret;
+               return err;
        }
 
        return 0;
index 1c087cb76815a3ab488cb53db85cf98b5b0cac80..d0549fba711c474a1d58e416bbff09dad9a2f328 100644 (file)
@@ -257,7 +257,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev)
                goto clkerr;
 
        if (devm_request_irq(dev, priv->irq, hix5hd2_ir_rx_interrupt,
-                            IRQF_NO_SUSPEND, pdev->name, priv) < 0) {
+                            0, pdev->name, priv) < 0) {
                dev_err(dev, "IRQ %d register failed\n", priv->irq);
                ret = -EINVAL;
                goto regerr;
index 507382160e5e7524022c782240c36f98c1b54871..ce157edd45fa1adb3dd382037dd421f8b8590091 100644 (file)
@@ -166,6 +166,10 @@ static int si2157_init(struct dvb_frontend *fe)
 
        for (remaining = fw->size; remaining > 0; remaining -= 17) {
                len = fw->data[fw->size - remaining];
+               if (len > SI2157_ARGLEN) {
+                       dev_err(&client->dev, "Bad firmware length\n");
+                       goto err_release_firmware;
+               }
                memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
                cmd.wlen = len;
                cmd.rlen = 1;
index c3cac4c12fb3c6c18315ab83941a3454dc5ce9bd..197a4f2e54d2a1c08a3c662b3f983b57bf8190dd 100644 (file)
@@ -34,6 +34,14 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        unsigned int pipe;
        u8 requesttype;
 
+       mutex_lock(&d->usb_mutex);
+
+       if (req->size > sizeof(dev->buf)) {
+               dev_err(&d->intf->dev, "too large message %u\n", req->size);
+               ret = -EINVAL;
+               goto err_mutex_unlock;
+       }
+
        if (req->index & CMD_WR_FLAG) {
                /* write */
                memcpy(dev->buf, req->data, req->size);
@@ -50,14 +58,17 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
                        req->index, dev->buf, req->size);
        if (ret < 0)
-               goto err;
+               goto err_mutex_unlock;
 
        /* read request, copy returned data to return buf */
        if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
                memcpy(req->data, dev->buf, req->size);
 
+       mutex_unlock(&d->usb_mutex);
+
        return 0;
-err:
+err_mutex_unlock:
+       mutex_unlock(&d->usb_mutex);
        dev_dbg(&d->intf->dev, "failed=%d\n", ret);
        return ret;
 }
index 9f6115a2ee0166d509584d5b5c5fd0b62d5bff06..138062960a7367737521659acc607983c921a685 100644 (file)
@@ -71,7 +71,7 @@
 
 
 struct rtl28xxu_dev {
-       u8 buf[28];
+       u8 buf[128];
        u8 chip_id;
        u8 tuner;
        char *tuner_name;
index 82876a67f1449b62f02142f4a677aee8880c295a..9beece00869bf0e27a99fc641b8f926c0d3bad8f 100644 (file)
@@ -47,7 +47,7 @@ config V4L2_MEM2MEM_DEV
 # Used by LED subsystem flash drivers
 config V4L2_FLASH_LED_CLASS
        tristate "V4L2 flash API for LED flash class devices"
-       depends on VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
        depends on LEDS_CLASS_FLASH
        ---help---
          Say Y here to enable V4L2 flash API support for LED flash
index c6a644b22af44e53b5cee18fc596df48ff675835..6f3154613dc7174b04a7e91dff0af1d3aae9b31e 100644 (file)
@@ -58,12 +58,18 @@ config OMAP_GPMC
          memory drives like NOR, NAND, OneNAND, SRAM.
 
 config OMAP_GPMC_DEBUG
-       bool
+       bool "Enable GPMC debug output and skip reset of GPMC during init"
        depends on OMAP_GPMC
        help
          Enables verbose debugging mostly to decode the bootloader provided
-         timings. Enable this during development to configure devices
-         connected to the GPMC bus.
+         timings. To preserve the bootloader provided timings, the reset
+         of GPMC is skipped during init. Enable this during development to
+         configure devices connected to the GPMC bus.
+
+         NOTE: In addition to matching the register setup with the bootloader
+         you also need to match the GPMC FCLK frequency used by the
+         bootloader or else the GPMC timings won't be identical with the
+         bootloader timings.
 
 config MVEBU_DEVBUS
        bool "Marvell EBU Device Bus Controller"
index 32ac049f2bc4dbda4418587cc017cc074d5989c9..6515dfc2b805d6c5198756e17bacd23724689dac 100644 (file)
@@ -696,7 +696,6 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
        int div;
        u32 l;
 
-       gpmc_cs_show_timings(cs, "before gpmc_cs_set_timings");
        div = gpmc_calc_divider(t->sync_clk);
        if (div < 0)
                return div;
@@ -1988,6 +1987,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
        if (ret < 0)
                goto err;
 
+       gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
        ret = gpmc_cs_program_settings(cs, &gpmc_s);
        if (ret < 0)
                goto err;
index f28cb28a62f87073c214d47368355be6c29c6f25..2c7f8d7c0595e2d849183dfd0db91d2d945daa10 100644 (file)
@@ -42,6 +42,8 @@ int intel_lpss_resume(struct device *dev);
        .thaw = intel_lpss_resume,              \
        .poweroff = intel_lpss_suspend,         \
        .restore = intel_lpss_resume,
+#else
+#define INTEL_LPSS_SLEEP_PM_OPS
 #endif
 
 #define INTEL_LPSS_RUNTIME_PM_OPS              \
index c52162ea3d0ab1daf8bd375220669f3ba53db15e..586098f1b233a6d19da9e74e1d2dd2e396408635 100644 (file)
@@ -80,7 +80,7 @@ static int max77843_chg_init(struct max77693_dev *max77843)
        if (!max77843->i2c_chg) {
                dev_err(&max77843->i2c->dev,
                                "Cannot allocate I2C device for Charger\n");
-               return PTR_ERR(max77843->i2c_chg);
+               return -ENODEV;
        }
        i2c_set_clientdata(max77843->i2c_chg, max77843);
 
index 8af12c884b04eeb870d21ae2bb4bf15e0cfb76c4..103baf0e0c5bfd9aa23537adf12f6035bb427d86 100644 (file)
@@ -105,6 +105,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
 
 void cxl_free_afu_irqs(struct cxl_context *ctx)
 {
+       afu_irq_name_free(ctx);
        cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 }
 EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
index e762f85ee233a4b510390aa0ce4a5a79266b84c3..2faa1270d085b15f92e185f8f389f5790390fbef 100644 (file)
@@ -275,6 +275,9 @@ static void reclaim_ctx(struct rcu_head *rcu)
        if (ctx->kernelapi)
                kfree(ctx->mapping);
 
+       if (ctx->irq_bitmap)
+               kfree(ctx->irq_bitmap);
+
        kfree(ctx);
 }
 
index 1c30ef77073d607cd250ade57c08b110fffd092f..0cfb9c129f273cbdf0a408c6b5d3008bd308596d 100644 (file)
@@ -677,6 +677,7 @@ int cxl_register_serr_irq(struct cxl_afu *afu);
 void cxl_release_serr_irq(struct cxl_afu *afu);
 int afu_register_irqs(struct cxl_context *ctx, u32 count);
 void afu_release_irqs(struct cxl_context *ctx, void *cookie);
+void afu_irq_name_free(struct cxl_context *ctx);
 irqreturn_t cxl_slice_irq_err(int irq, void *data);
 
 int cxl_debugfs_init(void);
index a30bf285b5bdd75c3f2b357d89dbab251bb98c7c..7ccd2998be92b8b3f7cdca2a0acbf3f9586d0f34 100644 (file)
@@ -120,9 +120,16 @@ int afu_release(struct inode *inode, struct file *file)
                 __func__, ctx->pe);
        cxl_context_detach(ctx);
 
-       mutex_lock(&ctx->mapping_lock);
-       ctx->mapping = NULL;
-       mutex_unlock(&ctx->mapping_lock);
+
+       /*
+        * Delete the context's mapping pointer, unless it's created by the
+        * kernel API, in which case leave it so it can be freed by reclaim_ctx()
+        */
+       if (!ctx->kernelapi) {
+               mutex_lock(&ctx->mapping_lock);
+               ctx->mapping = NULL;
+               mutex_unlock(&ctx->mapping_lock);
+       }
 
        put_device(&ctx->afu->dev);
 
index 583b42afeda2355da2e606f4fbc33546445a8df6..09a406058c4650ddf71114c26201889620003b9e 100644 (file)
@@ -414,7 +414,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu)
        kfree(afu->psl_irq_name);
 }
 
-static void afu_irq_name_free(struct cxl_context *ctx)
+void afu_irq_name_free(struct cxl_context *ctx)
 {
        struct cxl_irq_name *irq_name, *tmp;
 
@@ -524,7 +524,5 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
        afu_irq_name_free(ctx);
        cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
 
-       kfree(ctx->irq_bitmap);
-       ctx->irq_bitmap = NULL;
        ctx->irq_count = 0;
 }
index b37f2e8004f5bcd58f970ea274ebd29ef4b1eae3..d2e75c88f4d2165762913c27c57e5d4487e431ad 100644 (file)
@@ -457,6 +457,7 @@ static int activate_afu_directed(struct cxl_afu *afu)
 
        dev_info(&afu->dev, "Activating AFU directed mode\n");
 
+       afu->num_procs = afu->max_procs_virtualised;
        if (afu->spa == NULL) {
                if (cxl_alloc_spa(afu))
                        return -ENOMEM;
@@ -468,7 +469,6 @@ static int activate_afu_directed(struct cxl_afu *afu)
        cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
 
        afu->current_mode = CXL_MODE_DIRECTED;
-       afu->num_procs = afu->max_procs_virtualised;
 
        if ((rc = cxl_chardev_m_afu_add(afu)))
                return rc;
index a5e977192b61f97bfbace09aa93f0b577be67bb7..85761d7eb333173040204a7a5593bf2c7cf06485 100644 (file)
@@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
        return 0;
 }
 
+/*
+ * Workaround a PCIe Host Bridge defect on some cards, that can cause
+ * malformed Transaction Layer Packet (TLP) errors to be erroneously
+ * reported. Mask this error in the Uncorrectable Error Mask Register.
+ *
+ * The upper nibble of the PSL revision is used to distinguish between
+ * different cards. The affected ones have it set to 0.
+ */
+static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
+{
+       int aer;
+       u32 data;
+
+       if (adapter->psl_rev & 0xf000)
+               return;
+       if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
+               return;
+       pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
+       if (data & PCI_ERR_UNC_MALF_TLP)
+               if (data & PCI_ERR_UNC_INTN)
+                       return;
+       data |= PCI_ERR_UNC_MALF_TLP;
+       data |= PCI_ERR_UNC_INTN;
+       pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
+}
+
 static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
 {
        if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
@@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
        if ((rc = cxl_vsec_looks_ok(adapter, dev)))
                return rc;
 
+       cxl_fixup_malformed_tlp(adapter, dev);
+
        if ((rc = setup_cxl_bars(dev)))
                return rc;
 
index b78cf5d403a33b74244a39245b9df6f9024c4d24..7fc9174d46191a13c77fa4e220bb476a32dfe05e 100644 (file)
@@ -2263,15 +2263,12 @@ static int mmc_test_profile_sglen_r_nonblock_perf(struct mmc_test_card *test)
 /*
  * eMMC hardware reset.
  */
-static int mmc_test_hw_reset(struct mmc_test_card *test)
+static int mmc_test_reset(struct mmc_test_card *test)
 {
        struct mmc_card *card = test->card;
        struct mmc_host *host = card->host;
        int err;
 
-       if (!mmc_card_mmc(card) || !mmc_can_reset(card))
-               return RESULT_UNSUP_CARD;
-
        err = mmc_hw_reset(host);
        if (!err)
                return RESULT_OK;
@@ -2605,8 +2602,8 @@ static const struct mmc_test_case mmc_test_cases[] = {
        },
 
        {
-               .name = "eMMC hardware reset",
-               .run = mmc_test_hw_reset,
+               .name = "Reset test",
+               .run = mmc_test_reset,
        },
 };
 
index e726903170a828cffd69a1cb2e7f80d59c0d5152..f6cd995dbe920392cce50062ff2e4f080634ee06 100644 (file)
@@ -1924,7 +1924,6 @@ EXPORT_SYMBOL(mmc_can_reset);
 static int mmc_reset(struct mmc_host *host)
 {
        struct mmc_card *card = host->card;
-       u32 status;
 
        if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
                return -EOPNOTSUPP;
@@ -1937,12 +1936,6 @@ static int mmc_reset(struct mmc_host *host)
 
        host->ops->hw_reset(host);
 
-       /* If the reset has happened, then a status command will fail */
-       if (!mmc_send_status(card, &status)) {
-               mmc_host_clk_release(host);
-               return -ENOSYS;
-       }
-
        /* Set initial state and call mmc_set_ios */
        mmc_set_initial_state(host);
        mmc_host_clk_release(host);
index e5fac368068a2320eb06d207934c4b969356237b..131026fbc2d77cbc3ccb5903daa10f8920f8ae17 100644 (file)
@@ -87,6 +87,7 @@ static const struct pci_device_id peak_pci_tbl[] = {
        {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+       {PEAK_PCI_VENDOR_ID, PEAK_PCIE_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,},
 #ifdef CONFIG_CAN_PEAK_PCIEC
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC34_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
index 2c063b60db4b02bc48246887fb5d98f6b3de0394..96f485ab612e679dc7065b1e214cb9d73c690d43 100644 (file)
@@ -327,9 +327,13 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
        pdata->debugfs_xpcs_reg = 0;
 
        buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
+       if (!buf)
+               return;
+
        pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
        if (!pdata->xgbe_debugfs) {
                netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
+               kfree(buf);
                return;
        }
 
index aeb7ce64452e14cd3cbe49325f63bae2d99e3ef2..be628bd9fb18b6f0116125e5a3f9ea16ad1d3561 100644 (file)
@@ -3351,6 +3351,13 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
                        udp_rss_requested = 0;
                else
                        return -EINVAL;
+
+               if (CHIP_IS_E1x(bp) && udp_rss_requested) {
+                       DP(BNX2X_MSG_ETHTOOL,
+                          "57710, 57711 boards don't support RSS according to UDP 4-tuple\n");
+                       return -EINVAL;
+               }
+
                if ((info->flow_type == UDP_V4_FLOW) &&
                    (bp->rss_conf_obj.udp_rss_v4 != udp_rss_requested)) {
                        bp->rss_conf_obj.udp_rss_v4 = udp_rss_requested;
index 3bc701e4c59eb56cc19e11c917dd34c24062754e..1805541b4240e72c79445ea6f50bbc2a74ba13c7 100644 (file)
@@ -1683,6 +1683,24 @@ static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
        bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
 }
 
+static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
+{
+       u32 int0_enable = 0;
+
+       /* Monitor cable plug/unplugged event for internal PHY, external PHY
+        * and MoCA PHY
+        */
+       if (priv->internal_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->ext_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
+               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+                       int0_enable |= UMAC_IRQ_LINK_EVENT;
+       }
+       bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
+}
+
 static int init_umac(struct bcmgenet_priv *priv)
 {
        struct device *kdev = &priv->pdev->dev;
@@ -1723,15 +1741,8 @@ static int init_umac(struct bcmgenet_priv *priv)
        /* Enable Tx default queue 16 interrupts */
        int0_enable |= UMAC_IRQ_TXDMA_DONE;
 
-       /* Monitor cable plug/unplugged event for internal PHY */
-       if (priv->internal_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->ext_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
-               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
-                       int0_enable |= UMAC_IRQ_LINK_EVENT;
-
+       /* Configure backpressure vectors for MoCA */
+       if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
                reg = bcmgenet_bp_mc_get(priv);
                reg |= BIT(priv->hw_params->bp_in_en_shift);
 
@@ -2645,6 +2656,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
 
        netif_tx_start_all_queues(dev);
 
+       /* Monitor link interrupts now */
+       bcmgenet_link_intr_enable(priv);
+
        phy_start(priv->phydev);
 }
 
index 821540913343db10f59ae3a03835a084ca82063d..d463563e1f7039ee5176ca36abfdc6bae3f2ed46 100644 (file)
@@ -592,6 +592,7 @@ struct be_adapter {
        int be_get_temp_freq;
        struct be_hwmon hwmon_info;
        u8 pf_number;
+       u8 pci_func_num;
        struct rss_info rss_info;
        /* Filters for packets that need to be sent to BMC */
        u32 bmc_filt_mask;
index eb323913cd39fb981a8c0cc02140c0c7205ee4f8..1795c935ff023fcf795008a49a9a4cd0fce63d9c 100644 (file)
@@ -851,8 +851,10 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
                return status;
 
        dest_wrb = be_cmd_copy(adapter, wrb);
-       if (!dest_wrb)
-               return -EBUSY;
+       if (!dest_wrb) {
+               status = -EBUSY;
+               goto unlock;
+       }
 
        if (use_mcc(adapter))
                status = be_mcc_notify_wait(adapter);
@@ -862,6 +864,7 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
        if (!status)
                memcpy(wrb, dest_wrb, sizeof(*wrb));
 
+unlock:
        be_cmd_unlock(adapter);
        return status;
 }
@@ -1984,6 +1987,8 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
                         be_if_cap_flags(adapter));
        }
        flags &= be_if_cap_flags(adapter);
+       if (!flags)
+               return -ENOTSUPP;
 
        return __be_cmd_rx_filter(adapter, flags, value);
 }
@@ -2887,6 +2892,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
        if (!status) {
                attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
                adapter->hba_port_num = attribs->hba_attribs.phy_port;
+               adapter->pci_func_num = attribs->pci_func_num;
                serial_num = attribs->hba_attribs.controller_serial_number;
                for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
                        adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
@@ -3709,7 +3715,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
                        status = -EINVAL;
                        goto err;
                }
-
                adapter->pf_number = desc->pf_num;
                be_copy_nic_desc(res, desc);
        }
@@ -3721,7 +3726,10 @@ err:
        return status;
 }
 
-/* Will use MBOX only if MCCQ has not been created */
+/* Will use MBOX only if MCCQ has not been created
+ * non-zero domain => a PF is querying this on behalf of a VF
+ * zero domain => a PF or a VF is querying this for itself
+ */
 int be_cmd_get_profile_config(struct be_adapter *adapter,
                              struct be_resources *res, u8 query, u8 domain)
 {
@@ -3748,10 +3756,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
                               OPCODE_COMMON_GET_PROFILE_CONFIG,
                               cmd.size, &wrb, &cmd);
 
-       req->hdr.domain = domain;
        if (!lancer_chip(adapter))
                req->hdr.version = 1;
        req->type = ACTIVE_PROFILE_TYPE;
+       /* When a function is querying profile information relating to
+        * itself hdr.pf_number must be set to it's pci_func_num + 1
+        */
+       req->hdr.domain = domain;
+       if (domain == 0)
+               req->hdr.pf_num = adapter->pci_func_num + 1;
 
        /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
         * descriptors with all bits set to "1" for the fields which can be
@@ -3921,12 +3934,16 @@ static void be_fill_vf_res_template(struct be_adapter *adapter,
                        vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
                                             BE_IF_FLAGS_DEFQ_RSS);
                }
-
-               nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        } else {
                num_vf_qs = 1;
        }
 
+       if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS) {
+               nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
+               vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS;
+       }
+
+       nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        nic_vft->rq_count = cpu_to_le16(num_vf_qs);
        nic_vft->txq_count = cpu_to_le16(num_vf_qs);
        nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
index 7d178bdb112eb7d14d5a62d74ea21ecaa30ba0e9..91155ea74f342e2663f18848c9fe5546635e7c05 100644 (file)
@@ -289,7 +289,9 @@ struct be_cmd_req_hdr {
        u32 timeout;            /* dword 1 */
        u32 request_length;     /* dword 2 */
        u8 version;             /* dword 3 */
-       u8 rsvd[3];             /* dword 3 */
+       u8 rsvd1;               /* dword 3 */
+       u8 pf_num;              /* dword 3 */
+       u8 rsvd2;               /* dword 3 */
 };
 
 #define RESP_HDR_INFO_OPCODE_SHIFT     0       /* bits 0 - 7 */
@@ -1652,7 +1654,11 @@ struct mgmt_hba_attribs {
 
 struct mgmt_controller_attrib {
        struct mgmt_hba_attribs hba_attribs;
-       u32 rsvd0[10];
+       u32 rsvd0[2];
+       u16 rsvd1;
+       u8 pci_func_num;
+       u8 rsvd2;
+       u32 rsvd3[7];
 } __packed;
 
 struct be_cmd_req_cntl_attribs {
index 7bf51a1a0a77e12a4812662767dd21767813dc1b..eb48a977f8daabe78d6d5b6a94f6607bf19287b8 100644 (file)
@@ -1123,11 +1123,12 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
                                           struct sk_buff *skb,
                                           struct be_wrb_params *wrb_params)
 {
-       /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
-        * less may cause a transmit stall on that port. So the work-around is
-        * to pad short packets (<= 32 bytes) to a 36-byte length.
+       /* Lancer, SH and BE3 in SRIOV mode have a bug wherein
+        * packets that are 32b or less may cause a transmit stall
+        * on that port. The workaround is to pad such packets
+        * (len <= 32 bytes) to a minimum length of 36b.
         */
-       if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
+       if (skb->len <= 32) {
                if (skb_put_padto(skb, 36))
                        return NULL;
        }
@@ -4205,10 +4206,6 @@ static int be_get_config(struct be_adapter *adapter)
        int status, level;
        u16 profile_id;
 
-       status = be_cmd_get_cntl_attributes(adapter);
-       if (status)
-               return status;
-
        status = be_cmd_query_fw_cfg(adapter);
        if (status)
                return status;
@@ -4407,6 +4404,11 @@ static int be_setup(struct be_adapter *adapter)
        if (!lancer_chip(adapter))
                be_cmd_req_native_mode(adapter);
 
+       /* Need to invoke this cmd first to get the PCI Function Number */
+       status = be_cmd_get_cntl_attributes(adapter);
+       if (status)
+               return status;
+
        if (!BE2_chip(adapter) && be_physfn(adapter))
                be_alloc_sriov_res(adapter);
 
@@ -4999,7 +5001,15 @@ static bool be_check_ufi_compatibility(struct be_adapter *adapter,
                return false;
        }
 
-       return (fhdr->asic_type_rev >= adapter->asic_rev);
+       /* In BE3 FW images the "asic_type_rev" field doesn't track the
+        * asic_rev of the chips it is compatible with.
+        * When asic_type_rev is 0 the image is compatible only with
+        * pre-BE3-R chips (asic_rev < 0x10)
+        */
+       if (BEx_chip(adapter) && fhdr->asic_type_rev == 0)
+               return adapter->asic_rev < 0x10;
+       else
+               return (fhdr->asic_type_rev >= adapter->asic_rev);
 }
 
 static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
index 3c40f6b9922436a32d255aa627e9d94db45f8477..55c36230e17634c3e063bdb20f4bb6a896bce4a6 100644 (file)
@@ -198,17 +198,28 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
 
 #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
 /*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MDIO registers (struct gfar)
  * This is mildly evil, but so is our hardware for doing this.
  * Also, we have to cast back to struct gfar because of
  * definition weirdness done in gianfar.h.
  */
-static uint32_t __iomem *get_gfar_tbipa(void __iomem *p)
+static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
 {
        struct gfar __iomem *enet_regs = p;
 
        return &enet_regs->tbipa;
 }
 
+/*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
+ */
+static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
+{
+       return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
+}
+
 /*
  * Return the TBIPAR address for an eTSEC2 node
  */
@@ -220,11 +231,12 @@ static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
 
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE)
 /*
- * Return the TBIPAR address for a QE MDIO node
+ * Return the TBIPAR address for a QE MDIO node, starting from the address
+ * of the mapped MII registers (struct fsl_pq_mii)
  */
 static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
 {
-       struct fsl_pq_mdio __iomem *mdio = p;
+       struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
 
        return &mdio->utbipar;
 }
@@ -300,14 +312,14 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "fsl,gianfar-tbi",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
                .compatible = "fsl,gianfar-mdio",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
@@ -315,7 +327,7 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "gianfar",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = offsetof(struct fsl_pq_mdio, mii),
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mdio,
                },
        },
        {
@@ -445,6 +457,16 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
 
                        tbipa = data->get_tbipa(priv->map);
 
+                       /*
+                        * Add consistency check to make sure TBI is contained
+                        * within the mapped range (not because we would get a
+                        * segfault, rather to catch bugs in computing TBI
+                        * address). Print error message but continue anyway.
+                        */
+                       if ((void *)tbipa > priv->map + resource_size(&res) - 4)
+                               dev_err(&pdev->dev, "invalid register map (should be at least 0x%04x to contain TBI address)\n",
+                                       ((void *)tbipa - priv->map) + 4);
+
                        iowrite32be(be32_to_cpup(prop), tbipa);
                }
        }
index 62488a67149d1f0ac38279517427853ebbcec6fc..c0e943aecd1394262757e790b04a6ce1eccda72a 100644 (file)
@@ -386,7 +386,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -404,6 +403,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -445,7 +445,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -463,6 +462,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index 2fdf978ae6a5d10a6751f3ec702ef3636fca543f..dd44fafd8798613be8c440c36c2366233d0958d0 100644 (file)
@@ -8389,6 +8389,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
        netdev->hw_enc_features |= NETIF_F_IP_CSUM       |
                                  NETIF_F_GSO_UDP_TUNNEL |
+                                 NETIF_F_GSO_GRE        |
                                  NETIF_F_TSO;
 
        netdev->features = NETIF_F_SG                  |
@@ -8396,6 +8397,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                           NETIF_F_SCTP_CSUM           |
                           NETIF_F_HIGHDMA             |
                           NETIF_F_GSO_UDP_TUNNEL      |
+                          NETIF_F_GSO_GRE             |
                           NETIF_F_HW_VLAN_CTAG_TX     |
                           NETIF_F_HW_VLAN_CTAG_RX     |
                           NETIF_F_HW_VLAN_CTAG_FILTER |
index 929d47152bf271b1ddba3d8dc284d1941131261a..a23ebfd5cd254014cd0632979aa441a2a6f6eadf 100644 (file)
@@ -373,7 +373,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -391,6 +390,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -432,7 +432,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -450,6 +449,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index 8e81e53c370e7d54e6367c012212cccc73ee26fd..c3448847936570582ace12e6baec0f51604f1072 100644 (file)
@@ -1364,6 +1364,10 @@ int mlx4_test_interrupts(struct mlx4_dev *dev)
         * and performing a NOP command
         */
        for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
+               /* Make sure request_irq was called */
+               if (!priv->eq_table.eq[i].have_irq)
+                       continue;
+
                /* Temporary use polling for command completions */
                mlx4_cmd_use_polling(dev);
 
index 006757f80988bcb71cfc352542305b61310ef40f..cc3a9897574c542ee368ab067c109128ce89b290 100644 (file)
@@ -2669,14 +2669,11 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
 
        if (msi_x) {
                int nreq = dev->caps.num_ports * num_online_cpus() + 1;
-               bool shared_ports = false;
 
                nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
                             nreq);
-               if (nreq > MAX_MSIX) {
+               if (nreq > MAX_MSIX)
                        nreq = MAX_MSIX;
-                       shared_ports = true;
-               }
 
                entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
                if (!entries)
@@ -2699,9 +2696,6 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                bitmap_zero(priv->eq_table.eq[MLX4_EQ_ASYNC].actv_ports.ports,
                            dev->caps.num_ports);
 
-               if (MLX4_IS_LEGACY_EQ_MODE(dev->caps))
-                       shared_ports = true;
-
                for (i = 0; i < dev->caps.num_comp_vectors + 1; i++) {
                        if (i == MLX4_EQ_ASYNC)
                                continue;
@@ -2709,7 +2703,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                        priv->eq_table.eq[i].irq =
                                entries[i + 1 - !!(i > MLX4_EQ_ASYNC)].vector;
 
-                       if (shared_ports) {
+                       if (MLX4_IS_LEGACY_EQ_MODE(dev->caps)) {
                                bitmap_fill(priv->eq_table.eq[i].actv_ports.ports,
                                            dev->caps.num_ports);
                                /* We don't set affinity hint when there
index e71563ce05d1bc34123fd4aa63348d569adf4c57..22d603f7827333e2dce6eab7be6ed6acd5a14cdb 100644 (file)
@@ -598,6 +598,8 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = false;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -607,6 +609,8 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = true;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -717,8 +721,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
        bool enable_broadcast  = !ea->broadcast_enabled &&  broadcast_enabled;
        bool disable_broadcast =  ea->broadcast_enabled && !broadcast_enabled;
 
-       if (enable_promisc)
+       if (enable_promisc) {
                mlx5e_add_eth_addr_rule(priv, &ea->promisc, MLX5E_PROMISC);
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
+       }
        if (enable_allmulti)
                mlx5e_add_eth_addr_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
        if (enable_broadcast)
@@ -730,8 +738,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->broadcast);
        if (disable_allmulti)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->allmulti);
-       if (disable_promisc)
+       if (disable_promisc) {
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->promisc);
+       }
 
        ea->promisc_enabled   = promisc_enabled;
        ea->allmulti_enabled  = allmulti_enabled;
index 821caaab9bfb04697fb0424cb8498bdc9eacabed..3b9480fa3403dee018931c16b678f5ec6c98e913 100644 (file)
@@ -311,7 +311,7 @@ static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
        int err;
 
        memset(in, 0, sizeof(in));
-       MLX5_SET(ptys_reg, in, local_port, local_port);
+       MLX5_SET(pvlc_reg, in, local_port, local_port);
 
        err = mlx5_core_access_reg(dev, in, sizeof(in), pvlc,
                                   pvlc_size, MLX5_REG_PVLC, 0, 0);
index dbcaf5df8967e828f85648de4edce281860f2a61..28c19cc1a17c5f44a7b15103ce168651502843d8 100644 (file)
@@ -374,26 +374,31 @@ static int __mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core,
        int err;
        int ret;
 
+       mlxsw_core->emad.trans_active = true;
+
        err = mlxsw_core_skb_transmit(mlxsw_core->driver_priv, skb, tx_info);
        if (err) {
                dev_err(mlxsw_core->bus_info->dev, "Failed to transmit EMAD (tid=%llx)\n",
                        mlxsw_core->emad.tid);
                dev_kfree_skb(skb);
-               return err;
+               goto trans_inactive_out;
        }
 
-       mlxsw_core->emad.trans_active = true;
        ret = wait_event_timeout(mlxsw_core->emad.wait,
                                 !(mlxsw_core->emad.trans_active),
                                 msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS));
        if (!ret) {
                dev_warn(mlxsw_core->bus_info->dev, "EMAD timed-out (tid=%llx)\n",
                         mlxsw_core->emad.tid);
-               mlxsw_core->emad.trans_active = false;
-               return -EIO;
+               err = -EIO;
+               goto trans_inactive_out;
        }
 
        return 0;
+
+trans_inactive_out:
+       mlxsw_core->emad.trans_active = false;
+       return err;
 }
 
 static int mlxsw_emad_process_status(struct mlxsw_core *mlxsw_core,
index ffd55d030ce28dbf902f6990a0dfb7f96b08a766..36fb1cec53c98e9c7dad0cb7b9b59051d7e0c352 100644 (file)
@@ -187,6 +187,7 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
 {
        u16 max_index, be_index;
        u16 offset;             /* byte offset inside the array */
+       u8 in_byte_index;
 
        BUG_ON(index && !item->element_size);
        if (item->offset % sizeof(u32) != 0 ||
@@ -199,7 +200,8 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
        max_index = (item->size.bytes << 3) / item->element_size - 1;
        be_index = max_index - index;
        offset = be_index * item->element_size >> 3;
-       *shift = index % (BITS_PER_BYTE / item->element_size) << 1;
+       in_byte_index  = index % (BITS_PER_BYTE / item->element_size);
+       *shift = in_byte_index * item->element_size;
 
        return item->offset + offset;
 }
index 462cea31ecbb7be6387512dc741286d7fb56658e..cef866c37648ca0c93d4f109eb9d4f3671fcd890 100644 (file)
@@ -1582,11 +1582,11 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 
        if (in_mbox)
                memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, in_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, in_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, upper_32_bits(in_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, lower_32_bits(in_mapaddr));
 
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, out_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, out_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, upper_32_bits(out_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, lower_32_bits(out_mapaddr));
 
        mlxsw_pci_write32(mlxsw_pci, CIR_IN_MODIFIER, in_mod);
        mlxsw_pci_write32(mlxsw_pci, CIR_TOKEN, 0);
index 3e52ee93438c00188d0efe6482cfbd9f686b8ee9..62cbbd1ada8da6a5d8343beb394b67dc5af6a81c 100644 (file)
@@ -1069,9 +1069,9 @@ static int mlxsw_sx_port_create(struct mlxsw_sx *mlxsw_sx, u8 local_port)
        return 0;
 
 err_register_netdev:
-err_port_admin_status_set:
 err_port_mac_learning_mode_set:
 err_port_stp_state_set:
+err_port_admin_status_set:
 err_port_mtu_set:
 err_port_speed_set:
 err_port_swid_set:
index 66fd868152e579a4ba3483fd4726f0e9d9662436..b159ef8303cc3e65d1e374367d19ca590d934901 100644 (file)
@@ -476,13 +476,12 @@ static void __lpc_get_mac(struct netdata_local *pldat, u8 *mac)
        mac[5] = tmp >> 8;
 }
 
-static void __lpc_eth_clock_enable(struct netdata_local *pldat,
-                                  bool enable)
+static void __lpc_eth_clock_enable(struct netdata_local *pldat, bool enable)
 {
        if (enable)
-               clk_enable(pldat->clk);
+               clk_prepare_enable(pldat->clk);
        else
-               clk_disable(pldat->clk);
+               clk_disable_unprepare(pldat->clk);
 }
 
 static void __lpc_params_setup(struct netdata_local *pldat)
@@ -1494,7 +1493,7 @@ err_out_free_irq:
 err_out_iounmap:
        iounmap(pldat->net_base);
 err_out_disable_clocks:
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
 err_out_free_dev:
        free_netdev(ndev);
@@ -1519,7 +1518,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
        iounmap(pldat->net_base);
        mdiobus_unregister(pldat->mii_bus);
        mdiobus_free(pldat->mii_bus);
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
        free_netdev(ndev);
 
@@ -1540,7 +1539,7 @@ static int lpc_eth_drv_suspend(struct platform_device *pdev,
                if (netif_running(ndev)) {
                        netif_device_detach(ndev);
                        __lpc_eth_shutdown(pldat);
-                       clk_disable(pldat->clk);
+                       clk_disable_unprepare(pldat->clk);
 
                        /*
                         * Reset again now clock is disable to be sure
index a83263743665411eacb0ca845e23f52db612866c..2b7550c43f7800fe36e54fafacabfcd921c408f4 100644 (file)
@@ -2134,10 +2134,11 @@ static int rhine_rx(struct net_device *dev, int limit)
                        }
 
                        skb_put(skb, pkt_len);
-                       skb->protocol = eth_type_trans(skb, dev);
 
                        rhine_rx_vlan_tag(skb, desc, data_size);
 
+                       skb->protocol = eth_type_trans(skb, dev);
+
                        netif_receive_skb(skb);
 
                        u64_stats_update_begin(&rp->rx_stats.syncp);
index 8f5c02eed47de09883b43b8b587717993064ef0b..cde29f8a37bfebe036273f3a76bbc24b0e034fff 100644 (file)
@@ -870,14 +870,14 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
        __be16 dst_port = htons(GENEVE_UDP_PORT);
        __u8 ttl = 0, tos = 0;
        bool metadata = false;
-       __be32 rem_addr;
-       __u32 vni;
+       __be32 rem_addr = 0;
+       __u32 vni = 0;
 
-       if (!data[IFLA_GENEVE_ID] || !data[IFLA_GENEVE_REMOTE])
-               return -EINVAL;
+       if (data[IFLA_GENEVE_ID])
+               vni = nla_get_u32(data[IFLA_GENEVE_ID]);
 
-       vni = nla_get_u32(data[IFLA_GENEVE_ID]);
-       rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
+       if (data[IFLA_GENEVE_REMOTE])
+               rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
 
        if (data[IFLA_GENEVE_TTL])
                ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
index c5ad98ace5d0abeff5d6ef8f3f028e537b241a8e..11e3975485c1eaa377b7ee82a3d3eef5a3b00ffe 100644 (file)
@@ -168,8 +168,6 @@ config MDIO_OCTEON
          busses. It is required by the Octeon and ThunderX ethernet device
          drivers.
 
-         If in doubt, say Y.
-
 config MDIO_SUN4I
        tristate "Allwinner sun4i MDIO interface support"
        depends on ARCH_SUNXI
index 3837ae344f63b9d69a5dd958d0e7b7dc202ff316..2ed75060da50abe74a7f303010aad8c937a31b73 100644 (file)
@@ -313,7 +313,6 @@ static void pppoe_flush_dev(struct net_device *dev)
                        if (po->pppoe_dev == dev &&
                            sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
                                pppox_unbind_sock(sk);
-                               sk->sk_state = PPPOX_ZOMBIE;
                                sk->sk_state_change(sk);
                                po->pppoe_dev = NULL;
                                dev_put(dev);
index fbb9325d1f6e539421f2ad592d718bcede68acea..e66805eeffb45f014a9c61d20e0bd6f3b473098b 100644 (file)
@@ -164,6 +164,7 @@ config USB_NET_AX8817X
            * Aten UC210T
            * ASIX AX88172
            * Billionton Systems, USB2AR
+           * Billionton Systems, GUSB2AM-1G-B
            * Buffalo LUA-U2-KTX
            * Corega FEther USB2-TX
            * D-Link DUB-E100
index 75d6f26729a30e34cdaaf8334a9cc0aaa2a01c82..079069a060a62fdb42cb9dff9acbcd55148277b8 100644 (file)
@@ -91,8 +91,10 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
                        }
                        rx->ax_skb = netdev_alloc_skb_ip_align(dev->net,
                                                               rx->size);
-                       if (!rx->ax_skb)
+                       if (!rx->ax_skb) {
+                               rx->size = 0;
                                return 0;
+                       }
                }
 
                if (rx->size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
index 1173a24feda38c3af236c84acaf8982f39c0e0b1..5cabefc2349438f26cddde0022d52acf6e967116 100644 (file)
@@ -958,6 +958,10 @@ static const struct usb_device_id  products [] = {
        // Billionton Systems, USB2AR
        USB_DEVICE (0x08dd, 0x90ff),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Billionton Systems, GUSB2AM-1G-B
+       USB_DEVICE(0x08dd, 0x0114),
+       .driver_info =  (unsigned long) &ax88178_info,
 }, {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
index bbac1d35ed4e37450a3282b4b7f9dc41dabcd4e8..afdc65fd5bc57c9101c9ffcb4aeac7cfe2431a63 100644 (file)
@@ -2745,11 +2745,10 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
        struct vxlan_config conf;
        int err;
 
-       if (!data[IFLA_VXLAN_ID])
-               return -EINVAL;
-
        memset(&conf, 0, sizeof(conf));
-       conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
+
+       if (data[IFLA_VXLAN_ID])
+               conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
 
        if (data[IFLA_VXLAN_GROUP]) {
                conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
index 23afcda2de967637d73c7039d0f2cdb5f3b777ff..678d72af4a9df73976b7513d9af17888bc1ef7d1 100644 (file)
@@ -337,7 +337,7 @@ enum ath10k_hw_rate_cck {
 #define TARGET_10X_MAX_FRAG_ENTRIES            0
 
 /* 10.2 parameters */
-#define TARGET_10_2_DMA_BURST_SIZE             1
+#define TARGET_10_2_DMA_BURST_SIZE             0
 
 /* Target specific defines for WMI-TLV firmware */
 #define TARGET_TLV_NUM_VDEVS                   4
@@ -391,7 +391,7 @@ enum ath10k_hw_rate_cck {
 
 #define TARGET_10_4_TX_DBG_LOG_SIZE            1024
 #define TARGET_10_4_NUM_WDS_ENTRIES            32
-#define TARGET_10_4_DMA_BURST_SIZE             1
+#define TARGET_10_4_DMA_BURST_SIZE             0
 #define TARGET_10_4_MAC_AGGR_DELIM             0
 #define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
 #define TARGET_10_4_VOW_CONFIG                 0
index 57f95f2dca5b072ac294b2c76122ec1b952a2a80..90eb75012e4f4818a03481d98cb9b137a89393fa 100644 (file)
@@ -880,6 +880,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->max_rate_tries = 10;
        hw->sta_data_size = sizeof(struct ath_node);
        hw->vif_data_size = sizeof(struct ath_vif);
+       hw->extra_tx_headroom = 4;
 
        hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
        hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
index 28490702124a0da53bb2834f1ca880a452d6523b..71d3e9adbf3c02b4d5ff50843a2b4b06cd96b6a5 100644 (file)
@@ -120,6 +120,7 @@ MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if over
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x15, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
index ab45819c1fbbf6d0080813c26090bb095082672d..e18629a16fb0260dff9b3486c572f4bfd2166fcd 100644 (file)
@@ -1020,7 +1020,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64(
+                       aes_sc[i].pn = cpu_to_le64(
                                        (u64)pn[5] |
                                        ((u64)pn[4] << 8) |
                                        ((u64)pn[3] << 16) |
index 6951aba620eb74a13f6fc2c2da36a043272d8a43..3fb327d5a911aeba53e4ac71ad6bb2ad419d06b0 100644 (file)
@@ -348,6 +348,6 @@ const struct iwl_cfg iwl7265d_n_cfg = {
 };
 
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
-MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
+MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
index 04264e417c1c644e2b362e9bf29760489cfcae4f..576187611e614adc3a92ca50c4e1f2ab3a7bb7e1 100644 (file)
@@ -274,18 +274,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                if (sta) {
-                       u8 *pn = seq.ccmp.pn;
+                       u64 pn64;
 
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
                        aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
 
-                       ieee80211_get_key_tx_seq(key, &seq);
-                       aes_tx_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                   ((u64)pn[4] << 8) |
-                                                   ((u64)pn[3] << 16) |
-                                                   ((u64)pn[2] << 24) |
-                                                   ((u64)pn[1] << 32) |
-                                                   ((u64)pn[0] << 40));
+                       pn64 = atomic64_read(&key->tx_pn);
+                       aes_tx_sc->pn = cpu_to_le64(pn64);
                } else {
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
                }
@@ -298,12 +293,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                ((u64)pn[4] << 8) |
-                                                ((u64)pn[3] << 16) |
-                                                ((u64)pn[2] << 24) |
-                                                ((u64)pn[1] << 32) |
-                                                ((u64)pn[0] << 40));
+                       aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
+                                                  ((u64)pn[4] << 8) |
+                                                  ((u64)pn[3] << 16) |
+                                                  ((u64)pn[2] << 24) |
+                                                  ((u64)pn[1] << 32) |
+                                                  ((u64)pn[0] << 40));
                }
                data->use_rsc_tsc = true;
                break;
@@ -1453,15 +1448,15 @@ static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw,
 
                switch (key->cipher) {
                case WLAN_CIPHER_SUITE_CCMP:
-                       iwl_mvm_aes_sc_to_seq(&sc->aes.tsc, &seq);
                        iwl_mvm_set_aes_rx_seq(sc->aes.unicast_rsc, key);
+                       atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
                        break;
                case WLAN_CIPHER_SUITE_TKIP:
                        iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
                        iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
+                       ieee80211_set_key_tx_seq(key, &seq);
                        break;
                }
-               ieee80211_set_key_tx_seq(key, &seq);
 
                /* that's it for this key */
                return;
index 4a0ce83315bdd212d1714956af8900ea271f62b6..5c7f7cc9ffcc2aa1d81cbf1ff5b2d33f46133727 100644 (file)
@@ -703,7 +703,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
         * abort after reading the nvm in case RF Kill is on, we will complete
         * the init seq later when RF kill will switch to off
         */
-       if (iwl_mvm_is_radio_killed(mvm)) {
+       if (iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm,
                                  "jump over all phy activities due to RF kill\n");
                iwl_remove_notification(&mvm->notif_wait, &calib_wait);
@@ -736,7 +736,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
        ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
                        MVM_UCODE_CALIB_TIMEOUT);
 
-       if (ret && iwl_mvm_is_radio_killed(mvm)) {
+       if (ret && iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
                ret = 1;
        }
index aa8c2b7f23c73862f0526f109ad647cc0c80a259..7c2944a72470b92acdca39a6f7c13b845b34842a 100644 (file)
@@ -2388,6 +2388,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
                iwl_mvm_remove_time_event(mvm, mvmvif,
                                          &mvmvif->time_event_data);
                RCU_INIT_POINTER(mvm->csa_vif, NULL);
+               mvmvif->csa_countdown = false;
        }
 
        if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
index b95a07ec9e362bf031f960dee35dc52c97221ed0..c754051a4ceacf138d4e6399c9cc679d8a9979c0 100644 (file)
@@ -860,6 +860,11 @@ static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
               test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
 }
 
+static inline bool iwl_mvm_is_radio_hw_killed(struct iwl_mvm *mvm)
+{
+       return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
+}
+
 /* Must be called with rcu_read_lock() held and it can only be
  * released when mvmsta is not needed anymore.
  */
index a37de3f410a01e0b594f41d43bfda4360273e324..f0cb092f980ec26b26e9ca3c6cadf813f39de853 100644 (file)
@@ -590,6 +590,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        ieee80211_unregister_hw(mvm->hw);
        iwl_mvm_leds_exit(mvm);
  out_free:
+       flush_delayed_work(&mvm->fw_dump_wk);
        iwl_phy_db_free(mvm->phy_db);
        kfree(mvm->scan_cmd);
        if (!cfg->no_power_up_nic_in_init || !mvm->nvm_file_name)
index b0825c402c732c0514637b3b21b26288a7275444..644b58bc5226c52b3cdee0a24b9a392c25e8ac02 100644 (file)
@@ -414,6 +414,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5F10, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5212, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
 
 /* 8000 Series */
        {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
index 5932306084fd305a6f45ccf03d8957b771eaaa13..bf9afbf46c1bbbc1220bad06e429d2622a1f9f58 100644 (file)
@@ -1114,6 +1114,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x0db0, 0x871c) },
        { USB_DEVICE(0x0db0, 0x899a) },
        /* Ovislink */
+       { USB_DEVICE(0x1b75, 0x3070) },
        { USB_DEVICE(0x1b75, 0x3071) },
        { USB_DEVICE(0x1b75, 0x3072) },
        { USB_DEVICE(0x1b75, 0xa200) },
index d4567d12e07ebd13f17f0097baeec41a25702d31..5da6703942d9dd08017d896070404fdbe29a96e4 100644 (file)
@@ -247,6 +247,8 @@ struct rtl_pci {
        /* MSI support */
        bool msi_support;
        bool using_msi;
+       /* interrupt clear before set */
+       bool int_clear;
 };
 
 struct mp_adapter {
index b7f18e2155eb18358cf4d4f9f3f82774f9b6f522..6e9418ed90c289bee5b7f2dfc478f847dfc7ca68 100644 (file)
@@ -2253,11 +2253,28 @@ void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
        }
 }
 
+static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 tmp = rtl_read_dword(rtlpriv, REG_HISR);
+
+       rtl_write_dword(rtlpriv, REG_HISR, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HISRE);
+       rtl_write_dword(rtlpriv, REG_HISRE, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HSISR);
+       rtl_write_dword(rtlpriv, REG_HSISR, tmp);
+}
+
 void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
+       if (!rtlpci->int_clear)
+               rtl8821ae_clear_interrupt(hw);/*clear it here first*/
+
        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
        rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
        rtlpci->irq_enabled = true;
index a4988121e1ab6a20bad5ad9b5934c166a41f36d6..8ee141a55bc5cc6b566e79dde58cdb05583e7fdf 100644 (file)
@@ -96,6 +96,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 
        rtl8821ae_bt_reg_init(hw);
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
        rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
        rtlpriv->dm.dm_initialgain_enable = 1;
@@ -167,6 +168,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
        rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
        if (rtlpriv->cfg->mod_params->disable_watchdog)
                pr_info("watchdog disabled\n");
        rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -308,6 +310,7 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
        .swctrl_lps = false,
        .fwctrl_lps = true,
        .msi_support = true,
+       .int_clear = true,
        .debug = DBG_EMERG,
        .disable_watchdog = 0,
 };
@@ -437,6 +440,7 @@ module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
 module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
                   bool, 0444);
+module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
@@ -444,6 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
+MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index b90ca618b123209a1724bc808c4fdfe8ea330a69..4544752a2ba83ca173f7cb4f14abc72538b73beb 100644 (file)
@@ -2249,6 +2249,9 @@ struct rtl_mod_params {
 
        /* default 0: 1 means disable */
        bool disable_watchdog;
+
+       /* default 0: 1 means do not disable interrupts */
+       bool int_clear;
 };
 
 struct rtl_hal_usbint_cfg {
index 929a6e7e5ecfe9249569c0059516e531fb0b79eb..56ebd8267386e6a91cabf506962e15f5d83531ec 100644 (file)
@@ -788,6 +788,12 @@ static void connect(struct backend_info *be)
        /* Use the number of queues requested by the frontend */
        be->vif->queues = vzalloc(requested_num_queues *
                                  sizeof(struct xenvif_queue));
+       if (!be->vif->queues) {
+               xenbus_dev_fatal(dev, -ENOMEM,
+                                "allocating queues");
+               return;
+       }
+
        be->vif->num_queues = requested_num_queues;
        be->vif->stalled_queues = requested_num_queues;
 
index d4497141d083a71d5d5206496fee58fbddc5cb13..4a7da3c3e0353c3c746e9b10be9a093c8d085920 100644 (file)
@@ -1243,6 +1243,10 @@ static void pci_msi_domain_update_chip_ops(struct msi_domain_info *info)
        BUG_ON(!chip);
        if (!chip->irq_write_msi_msg)
                chip->irq_write_msi_msg = pci_msi_domain_write_msg;
+       if (!chip->irq_mask)
+               chip->irq_mask = pci_msi_mask_irq;
+       if (!chip->irq_unmask)
+               chip->irq_unmask = pci_msi_unmask_irq;
 }
 
 /**
index 108a3118ace7fbd107a2916aa29066cc326c0b6c..306124bba61e2a1dbf3e116e33b8768db192bc25 100644 (file)
@@ -684,10 +684,16 @@ static int pci_pm_prepare(struct device *dev)
        return pci_dev_keep_suspended(to_pci_dev(dev));
 }
 
+static void pci_pm_complete(struct device *dev)
+{
+       pci_dev_complete_resume(to_pci_dev(dev));
+       pm_complete_with_resume_check(dev);
+}
 
 #else /* !CONFIG_PM_SLEEP */
 
 #define pci_pm_prepare NULL
+#define pci_pm_complete        NULL
 
 #endif /* !CONFIG_PM_SLEEP */
 
@@ -1218,6 +1224,7 @@ static int pci_pm_runtime_idle(struct device *dev)
 
 static const struct dev_pm_ops pci_dev_pm_ops = {
        .prepare = pci_pm_prepare,
+       .complete = pci_pm_complete,
        .suspend = pci_pm_suspend,
        .resume = pci_pm_resume,
        .freeze = pci_pm_freeze,
index 6a9a1116f1ebed7312f903570df56615352d57c1..78693fc5dbe9e680952687d4a0f04d08e7fb0ca6 100644 (file)
@@ -1710,15 +1710,7 @@ static void pci_pme_list_scan(struct work_struct *work)
        mutex_unlock(&pci_pme_list_mutex);
 }
 
-/**
- * pci_pme_active - enable or disable PCI device's PME# function
- * @dev: PCI device to handle.
- * @enable: 'true' to enable PME# generation; 'false' to disable it.
- *
- * The caller must verify that the device is capable of generating PME# before
- * calling this function with @enable equal to 'true'.
- */
-void pci_pme_active(struct pci_dev *dev, bool enable)
+static void __pci_pme_active(struct pci_dev *dev, bool enable)
 {
        u16 pmcsr;
 
@@ -1732,6 +1724,19 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
                pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
 
        pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
+}
+
+/**
+ * pci_pme_active - enable or disable PCI device's PME# function
+ * @dev: PCI device to handle.
+ * @enable: 'true' to enable PME# generation; 'false' to disable it.
+ *
+ * The caller must verify that the device is capable of generating PME# before
+ * calling this function with @enable equal to 'true'.
+ */
+void pci_pme_active(struct pci_dev *dev, bool enable)
+{
+       __pci_pme_active(dev, enable);
 
        /*
         * PCI (as opposed to PCIe) PME requires that the device have
@@ -2032,17 +2037,60 @@ EXPORT_SYMBOL_GPL(pci_dev_run_wake);
  * reconfigured due to wakeup settings difference between system and runtime
  * suspend and the current power state of it is suitable for the upcoming
  * (system) transition.
+ *
+ * If the device is not configured for system wakeup, disable PME for it before
+ * returning 'true' to prevent it from waking up the system unnecessarily.
  */
 bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
 {
        struct device *dev = &pci_dev->dev;
 
        if (!pm_runtime_suspended(dev)
-           || (device_can_wakeup(dev) && !device_may_wakeup(dev))
+           || pci_target_state(pci_dev) != pci_dev->current_state
            || platform_pci_need_resume(pci_dev))
                return false;
 
-       return pci_target_state(pci_dev) == pci_dev->current_state;
+       /*
+        * At this point the device is good to go unless it's been configured
+        * to generate PME at the runtime suspend time, but it is not supposed
+        * to wake up the system.  In that case, simply disable PME for it
+        * (it will have to be re-enabled on exit from system resume).
+        *
+        * If the device's power state is D3cold and the platform check above
+        * hasn't triggered, the device's configuration is suitable and we don't
+        * need to manipulate it at all.
+        */
+       spin_lock_irq(&dev->power.lock);
+
+       if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold &&
+           !device_may_wakeup(dev))
+               __pci_pme_active(pci_dev, false);
+
+       spin_unlock_irq(&dev->power.lock);
+       return true;
+}
+
+/**
+ * pci_dev_complete_resume - Finalize resume from system sleep for a device.
+ * @pci_dev: Device to handle.
+ *
+ * If the device is runtime suspended and wakeup-capable, enable PME for it as
+ * it might have been disabled during the prepare phase of system suspend if
+ * the device was not configured for system wakeup.
+ */
+void pci_dev_complete_resume(struct pci_dev *pci_dev)
+{
+       struct device *dev = &pci_dev->dev;
+
+       if (!pci_dev_run_wake(pci_dev))
+               return;
+
+       spin_lock_irq(&dev->power.lock);
+
+       if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold)
+               __pci_pme_active(pci_dev, true);
+
+       spin_unlock_irq(&dev->power.lock);
 }
 
 void pci_config_pm_runtime_get(struct pci_dev *pdev)
index 24ba9dc8910a2ccf7c8735d7c8601e147ad13cb1..037e787a3ad582c62121175a6b17339ed546d83b 100644 (file)
@@ -75,6 +75,7 @@ void pci_disable_enabled_device(struct pci_dev *dev);
 int pci_finish_runtime_suspend(struct pci_dev *dev);
 int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
 bool pci_dev_keep_suspended(struct pci_dev *dev);
+void pci_dev_complete_resume(struct pci_dev *pci_dev);
 void pci_config_pm_runtime_get(struct pci_dev *dev);
 void pci_config_pm_runtime_put(struct pci_dev *dev);
 void pci_pm_init(struct pci_dev *dev);
index 2365a32a595e42b8ddf43c2dc32603749cf990d7..be3755c973e96d4c6ee48f0459c751ba6d225665 100644 (file)
@@ -823,9 +823,15 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
                }
 
                /* Now look up the logical CPU number */
-               for_each_possible_cpu(cpu)
-                       if (dn == of_cpu_device_node_get(cpu))
+               for_each_possible_cpu(cpu) {
+                       struct device_node *cpu_dn;
+
+                       cpu_dn = of_cpu_device_node_get(cpu);
+                       of_node_put(cpu_dn);
+
+                       if (dn == cpu_dn)
                                break;
+               }
 
                if (cpu >= nr_cpu_ids) {
                        pr_warn("Failed to find logical CPU for %s\n",
index faf635654312a75168ad7237ecf1995d317e396d..293ed4381cc0e08c1bb195bbb9f535fba66075ed 100644 (file)
@@ -26,7 +26,8 @@
 #include "pinctrl-imx.h"
 
 enum imx25_pads {
-       MX25_PAD_RESERVE0 = 1,
+       MX25_PAD_RESERVE0 = 0,
+       MX25_PAD_RESERVE1 = 1,
        MX25_PAD_A10 = 2,
        MX25_PAD_A13 = 3,
        MX25_PAD_A14 = 4,
@@ -169,6 +170,7 @@ enum imx25_pads {
 /* Pad names for the pinmux subsystem */
 static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = {
        IMX_PINCTRL_PIN(MX25_PAD_RESERVE0),
+       IMX_PINCTRL_PIN(MX25_PAD_RESERVE1),
        IMX_PINCTRL_PIN(MX25_PAD_A10),
        IMX_PINCTRL_PIN(MX25_PAD_A13),
        IMX_PINCTRL_PIN(MX25_PAD_A14),
index 63676617bc5997218729a56c15c8597f8c2499b9..f9a3f8f446f76afe28177d5f9dcb8b8376b0310b 100644 (file)
@@ -653,7 +653,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
                  SUNXI_FUNCTION(0x0, "gpio_in"),
                  SUNXI_FUNCTION(0x1, "gpio_out"),
                  SUNXI_FUNCTION(0x2, "spi1"),          /* CS1 */
-                 SUNXI_FUNCTION(0x3, "uart3"),         /* PWM1 */
+                 SUNXI_FUNCTION(0x3, "pwm"),           /* PWM1 */
                  SUNXI_FUNCTION(0x5, "uart2"),         /* CTS */
                  SUNXI_FUNCTION_IRQ(0x6, 13)),         /* EINT13 */
 };
index 7e9dae54fcb22e1df91d8a9fc6e01556de2e14f1..2df8bbecebfc4c5742e5652386186ce67a7aba7e 100644 (file)
 #define DRIVER_NAME "ph1-sld8-pinctrl"
 
 static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
-       UNIPHIER_PINCTRL_PIN(0, "PCA00", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(0, "PCA00", 0,
                             15, UNIPHIER_PIN_DRV_4_8,
                             15, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(1, "PCA01", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(1, "PCA01", 0,
                             16, UNIPHIER_PIN_DRV_4_8,
                             16, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(2, "PCA02", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(2, "PCA02", 0,
                             17, UNIPHIER_PIN_DRV_4_8,
                             17, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(3, "PCA03", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(3, "PCA03", 0,
                             18, UNIPHIER_PIN_DRV_4_8,
                             18, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(4, "PCA04", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(4, "PCA04", 0,
                             19, UNIPHIER_PIN_DRV_4_8,
                             19, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(5, "PCA05", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(5, "PCA05", 0,
                             20, UNIPHIER_PIN_DRV_4_8,
                             20, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(6, "PCA06", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(6, "PCA06", 0,
                             21, UNIPHIER_PIN_DRV_4_8,
                             21, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(7, "PCA07", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(7, "PCA07", 0,
                             22, UNIPHIER_PIN_DRV_4_8,
                             22, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(8, "PCA08", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(8, "PCA08", 0,
                             23, UNIPHIER_PIN_DRV_4_8,
                             23, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(9, "PCA09", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(9, "PCA09", 0,
                             24, UNIPHIER_PIN_DRV_4_8,
                             24, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(10, "PCA10", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(10, "PCA10", 0,
                             25, UNIPHIER_PIN_DRV_4_8,
                             25, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(11, "PCA11", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(11, "PCA11", 0,
                             26, UNIPHIER_PIN_DRV_4_8,
                             26, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(12, "PCA12", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(12, "PCA12", 0,
                             27, UNIPHIER_PIN_DRV_4_8,
                             27, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(13, "PCA13", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(13, "PCA13", 0,
                             28, UNIPHIER_PIN_DRV_4_8,
                             28, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(14, "PCA14", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(14, "PCA14", 0,
                             29, UNIPHIER_PIN_DRV_4_8,
                             29, UNIPHIER_PIN_PULL_DOWN),
        UNIPHIER_PINCTRL_PIN(15, "XNFRE_GB", UNIPHIER_PIN_IECTRL_NONE,
@@ -118,199 +118,199 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(31, "NFD7_GB", UNIPHIER_PIN_IECTRL_NONE,
                             36, UNIPHIER_PIN_DRV_8_12_16_20,
                             128, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(32, "SDCLK", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(32, "SDCLK", 8,
                             40, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(33, "SDCMD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(33, "SDCMD", 8,
                             44, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(34, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(34, "SDDAT0", 8,
                             48, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(35, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(35, "SDDAT1", 8,
                             52, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(36, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(36, "SDDAT2", 8,
                             56, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(37, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(37, "SDDAT3", 8,
                             60, UNIPHIER_PIN_DRV_8_12_16_20,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(38, "SDCD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(38, "SDCD", 8,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             129, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(39, "SDWP", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(39, "SDWP", 8,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             130, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(40, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(40, "SDVOLC", 9,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             131, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(41, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(41, "USB0VBUS", 0,
                             37, UNIPHIER_PIN_DRV_4_8,
                             37, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(42, "USB0OD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(42, "USB0OD", 0,
                             38, UNIPHIER_PIN_DRV_4_8,
                             38, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(43, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(43, "USB1VBUS", 0,
                             39, UNIPHIER_PIN_DRV_4_8,
                             39, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(44, "USB1OD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(44, "USB1OD", 0,
                             40, UNIPHIER_PIN_DRV_4_8,
                             40, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(45, "PCRESET", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(45, "PCRESET", 0,
                             41, UNIPHIER_PIN_DRV_4_8,
                             41, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(46, "PCREG", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(46, "PCREG", 0,
                             42, UNIPHIER_PIN_DRV_4_8,
                             42, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(47, "PCCE2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(47, "PCCE2", 0,
                             43, UNIPHIER_PIN_DRV_4_8,
                             43, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(48, "PCVS1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(48, "PCVS1", 0,
                             44, UNIPHIER_PIN_DRV_4_8,
                             44, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(49, "PCCD2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(49, "PCCD2", 0,
                             45, UNIPHIER_PIN_DRV_4_8,
                             45, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(50, "PCCD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(50, "PCCD1", 0,
                             46, UNIPHIER_PIN_DRV_4_8,
                             46, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(51, "PCREADY", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(51, "PCREADY", 0,
                             47, UNIPHIER_PIN_DRV_4_8,
                             47, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(52, "PCDOE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(52, "PCDOE", 0,
                             48, UNIPHIER_PIN_DRV_4_8,
                             48, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(53, "PCCE1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(53, "PCCE1", 0,
                             49, UNIPHIER_PIN_DRV_4_8,
                             49, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(54, "PCWE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(54, "PCWE", 0,
                             50, UNIPHIER_PIN_DRV_4_8,
                             50, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(55, "PCOE", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(55, "PCOE", 0,
                             51, UNIPHIER_PIN_DRV_4_8,
                             51, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(56, "PCWAIT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(56, "PCWAIT", 0,
                             52, UNIPHIER_PIN_DRV_4_8,
                             52, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(57, "PCIOWR", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(57, "PCIOWR", 0,
                             53, UNIPHIER_PIN_DRV_4_8,
                             53, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(58, "PCIORD", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(58, "PCIORD", 0,
                             54, UNIPHIER_PIN_DRV_4_8,
                             54, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(59, "HS0DIN0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(59, "HS0DIN0", 0,
                             55, UNIPHIER_PIN_DRV_4_8,
                             55, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(60, "HS0DIN1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(60, "HS0DIN1", 0,
                             56, UNIPHIER_PIN_DRV_4_8,
                             56, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(61, "HS0DIN2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(61, "HS0DIN2", 0,
                             57, UNIPHIER_PIN_DRV_4_8,
                             57, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(62, "HS0DIN3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(62, "HS0DIN3", 0,
                             58, UNIPHIER_PIN_DRV_4_8,
                             58, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(63, "HS0DIN4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(63, "HS0DIN4", 0,
                             59, UNIPHIER_PIN_DRV_4_8,
                             59, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(64, "HS0DIN5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(64, "HS0DIN5", 0,
                             60, UNIPHIER_PIN_DRV_4_8,
                             60, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(65, "HS0DIN6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(65, "HS0DIN6", 0,
                             61, UNIPHIER_PIN_DRV_4_8,
                             61, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(66, "HS0DIN7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(66, "HS0DIN7", 0,
                             62, UNIPHIER_PIN_DRV_4_8,
                             62, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(67, "HS0BCLKIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(67, "HS0BCLKIN", 0,
                             63, UNIPHIER_PIN_DRV_4_8,
                             63, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(68, "HS0VALIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(68, "HS0VALIN", 0,
                             64, UNIPHIER_PIN_DRV_4_8,
                             64, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(69, "HS0SYNCIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(69, "HS0SYNCIN", 0,
                             65, UNIPHIER_PIN_DRV_4_8,
                             65, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(70, "HSDOUT0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(70, "HSDOUT0", 0,
                             66, UNIPHIER_PIN_DRV_4_8,
                             66, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(71, "HSDOUT1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(71, "HSDOUT1", 0,
                             67, UNIPHIER_PIN_DRV_4_8,
                             67, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(72, "HSDOUT2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(72, "HSDOUT2", 0,
                             68, UNIPHIER_PIN_DRV_4_8,
                             68, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(73, "HSDOUT3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(73, "HSDOUT3", 0,
                             69, UNIPHIER_PIN_DRV_4_8,
                             69, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(74, "HSDOUT4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(74, "HSDOUT4", 0,
                             70, UNIPHIER_PIN_DRV_4_8,
                             70, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(75, "HSDOUT5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(75, "HSDOUT5", 0,
                             71, UNIPHIER_PIN_DRV_4_8,
                             71, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(76, "HSDOUT6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(76, "HSDOUT6", 0,
                             72, UNIPHIER_PIN_DRV_4_8,
                             72, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(77, "HSDOUT7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(77, "HSDOUT7", 0,
                             73, UNIPHIER_PIN_DRV_4_8,
                             73, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(78, "HSBCLKOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(78, "HSBCLKOUT", 0,
                             74, UNIPHIER_PIN_DRV_4_8,
                             74, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(79, "HSVALOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(79, "HSVALOUT", 0,
                             75, UNIPHIER_PIN_DRV_4_8,
                             75, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(80, "HSSYNCOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(80, "HSSYNCOUT", 0,
                             76, UNIPHIER_PIN_DRV_4_8,
                             76, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(81, "HS1DIN0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(81, "HS1DIN0", 0,
                             77, UNIPHIER_PIN_DRV_4_8,
                             77, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(82, "HS1DIN1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(82, "HS1DIN1", 0,
                             78, UNIPHIER_PIN_DRV_4_8,
                             78, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(83, "HS1DIN2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(83, "HS1DIN2", 0,
                             79, UNIPHIER_PIN_DRV_4_8,
                             79, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(84, "HS1DIN3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(84, "HS1DIN3", 0,
                             80, UNIPHIER_PIN_DRV_4_8,
                             80, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(85, "HS1DIN4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(85, "HS1DIN4", 0,
                             81, UNIPHIER_PIN_DRV_4_8,
                             81, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(86, "HS1DIN5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(86, "HS1DIN5", 0,
                             82, UNIPHIER_PIN_DRV_4_8,
                             82, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(87, "HS1DIN6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(87, "HS1DIN6", 0,
                             83, UNIPHIER_PIN_DRV_4_8,
                             83, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(88, "HS1DIN7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(88, "HS1DIN7", 0,
                             84, UNIPHIER_PIN_DRV_4_8,
                             84, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(89, "HS1BCLKIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(89, "HS1BCLKIN", 0,
                             85, UNIPHIER_PIN_DRV_4_8,
                             85, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(90, "HS1VALIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(90, "HS1VALIN", 0,
                             86, UNIPHIER_PIN_DRV_4_8,
                             86, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(91, "HS1SYNCIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(91, "HS1SYNCIN", 0,
                             87, UNIPHIER_PIN_DRV_4_8,
                             87, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(92, "AGCI", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(92, "AGCI", 3,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             132, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(93, "AGCR", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(93, "AGCR", 4,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             133, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(94, "AGCBS", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(94, "AGCBS", 5,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             134, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(95, "IECOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(95, "IECOUT", 0,
                             88, UNIPHIER_PIN_DRV_4_8,
                             88, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(96, "ASMCK", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(96, "ASMCK", 0,
                             89, UNIPHIER_PIN_DRV_4_8,
                             89, UNIPHIER_PIN_PULL_DOWN),
        UNIPHIER_PINCTRL_PIN(97, "ABCKO", UNIPHIER_PIN_IECTRL_NONE,
@@ -325,31 +325,31 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(100, "ASDOUT1", UNIPHIER_PIN_IECTRL_NONE,
                             93, UNIPHIER_PIN_DRV_4_8,
                             93, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(101, "ARCOUT", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(101, "ARCOUT", 0,
                             94, UNIPHIER_PIN_DRV_4_8,
                             94, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(102, "SDA0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(102, "SDA0", 10,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(103, "SCL0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(103, "SCL0", 10,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(104, "SDA1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(104, "SDA1", 11,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(105, "SCL1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(105, "SCL1", 11,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", 12,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", 12,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", 13,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", 13,
                             -1, UNIPHIER_PIN_DRV_FIXED_4,
                             -1, UNIPHIER_PIN_PULL_NONE),
        UNIPHIER_PINCTRL_PIN(110, "SBO0", UNIPHIER_PIN_IECTRL_NONE,
@@ -358,76 +358,76 @@ static const struct pinctrl_pin_desc ph1_sld8_pins[] = {
        UNIPHIER_PINCTRL_PIN(111, "SBI0", UNIPHIER_PIN_IECTRL_NONE,
                             96, UNIPHIER_PIN_DRV_4_8,
                             96, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(112, "SBO1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(112, "SBO1", 0,
                             97, UNIPHIER_PIN_DRV_4_8,
                             97, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(113, "SBI1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(113, "SBI1", 0,
                             98, UNIPHIER_PIN_DRV_4_8,
                             98, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(114, "TXD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(114, "TXD1", 0,
                             99, UNIPHIER_PIN_DRV_4_8,
                             99, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(115, "RXD1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(115, "RXD1", 0,
                             100, UNIPHIER_PIN_DRV_4_8,
                             100, UNIPHIER_PIN_PULL_UP),
-       UNIPHIER_PINCTRL_PIN(116, "HIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(116, "HIN", 1,
                             -1, UNIPHIER_PIN_DRV_FIXED_5,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(117, "VIN", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(117, "VIN", 2,
                             -1, UNIPHIER_PIN_DRV_FIXED_5,
                             -1, UNIPHIER_PIN_PULL_NONE),
-       UNIPHIER_PINCTRL_PIN(118, "TCON0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(118, "TCON0", 0,
                             101, UNIPHIER_PIN_DRV_4_8,
                             101, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(119, "TCON1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(119, "TCON1", 0,
                             102, UNIPHIER_PIN_DRV_4_8,
                             102, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(120, "TCON2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(120, "TCON2", 0,
                             103, UNIPHIER_PIN_DRV_4_8,
                             103, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(121, "TCON3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(121, "TCON3", 0,
                             104, UNIPHIER_PIN_DRV_4_8,
                             104, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(122, "TCON4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(122, "TCON4", 0,
                             105, UNIPHIER_PIN_DRV_4_8,
                             105, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(123, "TCON5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(123, "TCON5", 0,
                             106, UNIPHIER_PIN_DRV_4_8,
                             106, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(124, "TCON6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(124, "TCON6", 0,
                             107, UNIPHIER_PIN_DRV_4_8,
                             107, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(125, "TCON7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(125, "TCON7", 0,
                             108, UNIPHIER_PIN_DRV_4_8,
                             108, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(126, "TCON8", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(126, "TCON8", 0,
                             109, UNIPHIER_PIN_DRV_4_8,
                             109, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(127, "PWMA", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(127, "PWMA", 0,
                             110, UNIPHIER_PIN_DRV_4_8,
                             110, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(128, "XIRQ0", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(128, "XIRQ0", 0,
                             111, UNIPHIER_PIN_DRV_4_8,
                             111, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(129, "XIRQ1", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(129, "XIRQ1", 0,
                             112, UNIPHIER_PIN_DRV_4_8,
                             112, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(130, "XIRQ2", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(130, "XIRQ2", 0,
                             113, UNIPHIER_PIN_DRV_4_8,
                             113, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(131, "XIRQ3", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(131, "XIRQ3", 0,
                             114, UNIPHIER_PIN_DRV_4_8,
                             114, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(132, "XIRQ4", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(132, "XIRQ4", 0,
                             115, UNIPHIER_PIN_DRV_4_8,
                             115, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(133, "XIRQ5", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(133, "XIRQ5", 0,
                             116, UNIPHIER_PIN_DRV_4_8,
                             116, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(134, "XIRQ6", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(134, "XIRQ6", 0,
                             117, UNIPHIER_PIN_DRV_4_8,
                             117, UNIPHIER_PIN_PULL_DOWN),
-       UNIPHIER_PINCTRL_PIN(135, "XIRQ7", UNIPHIER_PIN_IECTRL_NONE,
+       UNIPHIER_PINCTRL_PIN(135, "XIRQ7", 0,
                             118, UNIPHIER_PIN_DRV_4_8,
                             118, UNIPHIER_PIN_PULL_DOWN),
 };
index 5153d1d69aee8e0472c21ec63ff393f6fb9b7682..9113876487edd43037038357726208dd828e9a2a 100644 (file)
@@ -207,7 +207,7 @@ struct pnp_protocol pnpacpi_protocol = {
 };
 EXPORT_SYMBOL(pnpacpi_protocol);
 
-static char *__init pnpacpi_get_id(struct acpi_device *device)
+static const char *__init pnpacpi_get_id(struct acpi_device *device)
 {
        struct acpi_hardware_id *id;
 
@@ -222,7 +222,7 @@ static char *__init pnpacpi_get_id(struct acpi_device *device)
 static int __init pnpacpi_add_device(struct acpi_device *device)
 {
        struct pnp_dev *dev;
-       char *pnpid;
+       const char *pnpid;
        struct acpi_hardware_id *id;
        int error;
 
index 23685e74917e2a5c3f3ab6dc6542f48d5ecbb2a9..bd2c69f85949ba6ce40b80c588a2e6a4036964a2 100644 (file)
@@ -116,7 +116,7 @@ static int sca3000_read_first_n_hw_rb(struct iio_buffer *r,
        if (ret)
                goto error_ret;
 
-       for (i = 0; i < num_read; i++)
+       for (i = 0; i < num_read / sizeof(u16); i++)
                *(((u16 *)rx) + i) = be16_to_cpup((__be16 *)rx + i);
 
        if (copy_to_user(buf, rx, num_read))
index 3f7715c9968b83b25d6d1a4f6099c29b051db5fd..47fc00a3f63bc9e5106f0c77354c7cf8e309f36e 100644 (file)
@@ -915,11 +915,12 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
        case IIO_CHAN_INFO_OFFSET:
                if (chan->type == IIO_TEMP) {
                        /* The calculated value from the ADC is in Kelvin, we
-                        * want Celsius for hwmon so the offset is
-                        * -272.15 * scale
+                        * want Celsius for hwmon so the offset is -273.15
+                        * The offset is applied before scaling so it is
+                        * actually -213.15 * 4 / 1.012 = -1079.644268
                         */
-                       *val = -1075;
-                       *val2 = 691699;
+                       *val = -1079;
+                       *val2 = 644268;
 
                        return IIO_VAL_INT_PLUS_MICRO;
                }
index 769b61193d87ef29c7868465c50e9b8ab87ee045..a9bc6e23fc2582f39c5a753638979fba15451e61 100644 (file)
@@ -224,7 +224,7 @@ static int ll_dir_filler(void *_hash, struct page *page0)
 
                prefetchw(&page->flags);
                ret = add_to_page_cache_lru(page, inode->i_mapping, offset,
-                                           GFP_KERNEL);
+                                           GFP_NOFS);
                if (ret == 0) {
                        unlock_page(page);
                } else {
index 0bae8cc6c23a0be622b2addf1479830e838cb243..ca920b0ecf8f8688763426ba2d6b253a3620a1b6 100644 (file)
@@ -932,7 +932,7 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 
        if (data->soc == SOC_ARCH_EXYNOS5260)
                emul_con = EXYNOS5260_EMUL_CON;
-       if (data->soc == SOC_ARCH_EXYNOS5433)
+       else if (data->soc == SOC_ARCH_EXYNOS5433)
                emul_con = EXYNOS5433_TMU_EMUL_CON;
        else if (data->soc == SOC_ARCH_EXYNOS7)
                emul_con = EXYNOS7_TMU_REG_EMUL_CON;
index 21d01a491405a2c52cd1ec02f3198fa4c6b8f10c..e508939daea3f3128a2ada1e696a5f751d212077 100644 (file)
@@ -80,10 +80,6 @@ int serial8250_tx_dma(struct uart_8250_port *p)
                return 0;
 
        dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-       if (dma->tx_size < p->port.fifosize) {
-               ret = -EINVAL;
-               goto err;
-       }
 
        desc = dmaengine_prep_slave_single(dma->txchan,
                                           dma->tx_addr + xmit->tail,
index c79d33676672daca6047ebead9d8afb70a49007d..c47d3e48058659230e8d48ed342f9c163b08732d 100644 (file)
@@ -147,6 +147,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
                pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
                xhci->quirks |= XHCI_SPURIOUS_REBOOT;
+               xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
        }
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
                (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
index 43291f93afeb59a90a3b39cbb045a26b3bd1ad5b..97ffe39972735109f1ca1f86e003fe2550e4f936 100644 (file)
@@ -2191,6 +2191,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                }
        /* Fast path - was this the last TRB in the TD for this URB? */
        } else if (event_trb == td->last_trb) {
+               if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX)
+                       return finish_td(xhci, td, event_trb, event, ep,
+                                        status, false);
+
                if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
                        td->urb->actual_length =
                                td->urb->transfer_buffer_length -
@@ -2242,6 +2246,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                        td->urb->actual_length +=
                                TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
                                EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+               if (trb_comp_code == COMP_SHORT_TX) {
+                       xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n");
+                       td->urb_length_set = true;
+                       return 0;
+               }
        }
 
        return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2274,6 +2284,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
        u32 trb_comp_code;
        int ret = 0;
        int td_num = 0;
+       bool handling_skipped_tds = false;
 
        slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
        xdev = xhci->devs[slot_id];
@@ -2410,6 +2421,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                ep->skip = true;
                xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
                goto cleanup;
+       case COMP_PING_ERR:
+               ep->skip = true;
+               xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n");
+               goto cleanup;
        default:
                if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
                        status = 0;
@@ -2546,13 +2561,18 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                                                 ep, &status);
 
 cleanup:
+
+
+               handling_skipped_tds = ep->skip &&
+                       trb_comp_code != COMP_MISSED_INT &&
+                       trb_comp_code != COMP_PING_ERR;
+
                /*
-                * Do not update event ring dequeue pointer if ep->skip is set.
-                * Will roll back to continue process missed tds.
+                * Do not update event ring dequeue pointer if we're in a loop
+                * processing missed tds.
                 */
-               if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
+               if (!handling_skipped_tds)
                        inc_deq(xhci, xhci->event_ring);
-               }
 
                if (ret) {
                        urb = td->urb;
@@ -2587,7 +2607,7 @@ cleanup:
         * Process them as short transfer until reach the td pointed by
         * the event.
         */
-       } while (ep->skip && trb_comp_code != COMP_MISSED_INT);
+       } while (handling_skipped_tds);
 
        return 0;
 }
index 1aaf89300621abc811f57f549c25b9a540a21d99..92f394927f241bef338a293170e4a09b9f45c647 100644 (file)
@@ -1093,6 +1093,7 @@ static void fbcon_init(struct vc_data *vc, int init)
                con_copy_unimap(vc, svc);
 
        ops = info->fbcon_par;
+       ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
        p->con_rotate = initial_rotation;
        set_blitting_type(vc, info);
 
index ecbc63d3143e78d53a9ab0e3dd2091686e51d620..9a2ec79e8cfb6c4ad26a5578e39f62f8fa80226b 100644 (file)
@@ -1828,7 +1828,6 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
        int found = 0;
        struct extent_buffer *eb;
        struct btrfs_inode_extref *extref;
-       struct extent_buffer *leaf;
        u32 item_size;
        u32 cur_offset;
        unsigned long ptr;
@@ -1856,9 +1855,8 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
                btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
                btrfs_release_path(path);
 
-               leaf = path->nodes[0];
-               item_size = btrfs_item_size_nr(leaf, slot);
-               ptr = btrfs_item_ptr_offset(leaf, slot);
+               item_size = btrfs_item_size_nr(eb, slot);
+               ptr = btrfs_item_ptr_offset(eb, slot);
                cur_offset = 0;
 
                while (cur_offset < item_size) {
@@ -1872,7 +1870,7 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
                        if (ret)
                                break;
 
-                       cur_offset += btrfs_inode_extref_name_len(leaf, extref);
+                       cur_offset += btrfs_inode_extref_name_len(eb, extref);
                        cur_offset += sizeof(*extref);
                }
                btrfs_tree_read_unlock_blocking(eb);
index b823fac91c9289bc67d3bb5191f4ce96e38294ac..8c6f247ba81d4e84c6a7d3d00d0348c974c1b049 100644 (file)
@@ -2584,7 +2584,7 @@ static long btrfs_fallocate(struct file *file, int mode,
                                        alloc_start);
                if (ret)
                        goto out;
-       } else {
+       } else if (offset + len > inode->i_size) {
                /*
                 * If we are fallocating from the end of the file onward we
                 * need to zero out the end of the page if i_size lands in the
index 0adf5422fce9d4b9fc62c2bbf319429b38aaec7c..8d20f3b1cab0abfa7b5f2bc4b8646c094a9353a5 100644 (file)
@@ -4639,6 +4639,11 @@ locked:
                bctl->flags |= BTRFS_BALANCE_TYPE_MASK;
        }
 
+       if (bctl->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
+               ret = -EINVAL;
+               goto out_bctl;
+       }
+
 do_balance:
        /*
         * Ownership of bctl and mutually_exclusive_operation_running
@@ -4650,12 +4655,15 @@ do_balance:
        need_unlock = false;
 
        ret = btrfs_balance(bctl, bargs);
+       bctl = NULL;
 
        if (arg) {
                if (copy_to_user(arg, bargs, sizeof(*bargs)))
                        ret = -EFAULT;
        }
 
+out_bctl:
+       kfree(bctl);
 out_bargs:
        kfree(bargs);
 out_unlock:
index 2ca784a14e84bc2a00d0c3d1ec1a15290128edfc..595279a8b99fd461e24cb24df3805fa8401f3dd6 100644 (file)
@@ -376,6 +376,14 @@ struct map_lookup {
 #define BTRFS_BALANCE_ARGS_VRANGE      (1ULL << 4)
 #define BTRFS_BALANCE_ARGS_LIMIT       (1ULL << 5)
 
+#define BTRFS_BALANCE_ARGS_MASK                        \
+       (BTRFS_BALANCE_ARGS_PROFILES |          \
+        BTRFS_BALANCE_ARGS_USAGE |             \
+        BTRFS_BALANCE_ARGS_DEVID |             \
+        BTRFS_BALANCE_ARGS_DRANGE |            \
+        BTRFS_BALANCE_ARGS_VRANGE |            \
+        BTRFS_BALANCE_ARGS_LIMIT)
+
 /*
  * Profile changing flags.  When SOFT is set we won't relocate chunk if
  * it already has the target profile (even though it may be
index e2a6af1508af2aef789d0caab21fedfa91d49c60..62203c387db45a23b05c1cadcc0946843ea5332f 100644 (file)
@@ -3380,6 +3380,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
        struct page *page, *tpage;
        unsigned int expected_index;
        int rc;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(mapping);
 
        INIT_LIST_HEAD(tmplist);
 
@@ -3392,7 +3393,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
         */
        __set_page_locked(page);
        rc = add_to_page_cache_locked(page, mapping,
-                                     page->index, GFP_KERNEL);
+                                     page->index, gfp);
 
        /* give up if we can't stick it in the cache */
        if (rc) {
@@ -3418,8 +3419,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
                        break;
 
                __set_page_locked(page);
-               if (add_to_page_cache_locked(page, mapping, page->index,
-                                                               GFP_KERNEL)) {
+               if (add_to_page_cache_locked(page, mapping, page->index, gfp)) {
                        __clear_page_locked(page);
                        break;
                }
index bcfb14bfc1e49eb36d507c53ccd1c3f4f23135f9..a86d3cc2b38941b0e39f23be84e4986d8852ae42 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -285,6 +285,7 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh,
 static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
                        struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+       struct address_space *mapping = inode->i_mapping;
        sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9);
        unsigned long vaddr = (unsigned long)vmf->virtual_address;
        void __pmem *addr;
@@ -292,6 +293,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
        pgoff_t size;
        int error;
 
+       i_mmap_lock_read(mapping);
+
        /*
         * Check truncate didn't happen while we were allocating a block.
         * If it did, this block may or may not be still allocated to the
@@ -321,6 +324,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
        error = vm_insert_mixed(vma, vaddr, pfn);
 
  out:
+       i_mmap_unlock_read(mapping);
+
        return error;
 }
 
@@ -382,17 +387,15 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                         * from a read fault and we've raced with a truncate
                         */
                        error = -EIO;
-                       goto unlock;
+                       goto unlock_page;
                }
-       } else {
-               i_mmap_lock_write(mapping);
        }
 
        error = get_block(inode, block, &bh, 0);
        if (!error && (bh.b_size < PAGE_SIZE))
                error = -EIO;           /* fs corruption? */
        if (error)
-               goto unlock;
+               goto unlock_page;
 
        if (!buffer_mapped(&bh) && !buffer_unwritten(&bh) && !vmf->cow_page) {
                if (vmf->flags & FAULT_FLAG_WRITE) {
@@ -403,9 +406,8 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                        if (!error && (bh.b_size < PAGE_SIZE))
                                error = -EIO;
                        if (error)
-                               goto unlock;
+                               goto unlock_page;
                } else {
-                       i_mmap_unlock_write(mapping);
                        return dax_load_hole(mapping, page, vmf);
                }
        }
@@ -417,15 +419,17 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                else
                        clear_user_highpage(new_page, vaddr);
                if (error)
-                       goto unlock;
+                       goto unlock_page;
                vmf->page = page;
                if (!page) {
+                       i_mmap_lock_read(mapping);
                        /* Check we didn't race with truncate */
                        size = (i_size_read(inode) + PAGE_SIZE - 1) >>
                                                                PAGE_SHIFT;
                        if (vmf->pgoff >= size) {
+                               i_mmap_unlock_read(mapping);
                                error = -EIO;
-                               goto unlock;
+                               goto out;
                        }
                }
                return VM_FAULT_LOCKED;
@@ -461,8 +465,6 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                        WARN_ON_ONCE(!(vmf->flags & FAULT_FLAG_WRITE));
        }
 
-       if (!page)
-               i_mmap_unlock_write(mapping);
  out:
        if (error == -ENOMEM)
                return VM_FAULT_OOM | major;
@@ -471,14 +473,11 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
                return VM_FAULT_SIGBUS | major;
        return VM_FAULT_NOPAGE | major;
 
- unlock:
+ unlock_page:
        if (page) {
                unlock_page(page);
                page_cache_release(page);
-       } else {
-               i_mmap_unlock_write(mapping);
        }
-
        goto out;
 }
 EXPORT_SYMBOL(__dax_fault);
@@ -556,10 +555,10 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        block = (sector_t)pgoff << (PAGE_SHIFT - blkbits);
 
        bh.b_size = PMD_SIZE;
-       i_mmap_lock_write(mapping);
        length = get_block(inode, block, &bh, write);
        if (length)
                return VM_FAULT_SIGBUS;
+       i_mmap_lock_read(mapping);
 
        /*
         * If the filesystem isn't willing to tell us the length of a hole,
@@ -569,36 +568,14 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
        if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
                goto fallback;
 
-       sector = bh.b_blocknr << (blkbits - 9);
-
-       if (buffer_unwritten(&bh) || buffer_new(&bh)) {
-               int i;
-
-               length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn,
-                                               bh.b_size);
-               if (length < 0) {
-                       result = VM_FAULT_SIGBUS;
-                       goto out;
-               }
-               if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
-                       goto fallback;
-
-               for (i = 0; i < PTRS_PER_PMD; i++)
-                       clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
-               wmb_pmem();
-               count_vm_event(PGMAJFAULT);
-               mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
-               result |= VM_FAULT_MAJOR;
-       }
-
        /*
         * If we allocated new storage, make sure no process has any
         * zero pages covering this hole
         */
        if (buffer_new(&bh)) {
-               i_mmap_unlock_write(mapping);
+               i_mmap_unlock_read(mapping);
                unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
-               i_mmap_lock_write(mapping);
+               i_mmap_lock_read(mapping);
        }
 
        /*
@@ -635,6 +612,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                result = VM_FAULT_NOPAGE;
                spin_unlock(ptl);
        } else {
+               sector = bh.b_blocknr << (blkbits - 9);
                length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn,
                                                bh.b_size);
                if (length < 0) {
@@ -644,15 +622,25 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
                if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
                        goto fallback;
 
+               if (buffer_unwritten(&bh) || buffer_new(&bh)) {
+                       int i;
+                       for (i = 0; i < PTRS_PER_PMD; i++)
+                               clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
+                       wmb_pmem();
+                       count_vm_event(PGMAJFAULT);
+                       mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
+                       result |= VM_FAULT_MAJOR;
+               }
+
                result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
        }
 
  out:
+       i_mmap_unlock_read(mapping);
+
        if (buffer_unwritten(&bh))
                complete_unwritten(&bh, !(result & VM_FAULT_ERROR));
 
-       i_mmap_unlock_write(mapping);
-
        return result;
 
  fallback:
index 47728da7702cdf69d2977af996dea42170a8b07d..b46e9fc641960aeba81b48d61b6e933d724b5205 100644 (file)
@@ -63,7 +63,7 @@ config EXT4_FS
          If unsure, say N.
 
 config EXT4_USE_FOR_EXT2
-       bool "Use ext4 for ext2/ext3 file systems"
+       bool "Use ext4 for ext2 file systems"
        depends on EXT4_FS
        depends on EXT2_FS=n
        default y
index e26803fb210d3bf1134f500b85f43802b2ce7e58..560af043770462df6170acd4d523f9d0385884a3 100644 (file)
@@ -165,8 +165,8 @@ int ext4_mpage_readpages(struct address_space *mapping,
                if (pages) {
                        page = list_entry(pages->prev, struct page, lru);
                        list_del(&page->lru);
-                       if (add_to_page_cache_lru(page, mapping,
-                                                 page->index, GFP_KERNEL))
+                       if (add_to_page_cache_lru(page, mapping, page->index,
+                                       GFP_KERNEL & mapping_gfp_mask(mapping)))
                                goto next_page;
                }
 
index 091a36444972fa0b746118b0cc58ca2a3dcaa97f..29e4599f6fc1c20b73acb2c580ce8383e169c5f2 100644 (file)
@@ -778,19 +778,24 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi,
                                  struct wb_writeback_work *base_work,
                                  bool skip_if_busy)
 {
-       int next_memcg_id = 0;
-       struct bdi_writeback *wb;
-       struct wb_iter iter;
+       struct bdi_writeback *last_wb = NULL;
+       struct bdi_writeback *wb = list_entry_rcu(&bdi->wb_list,
+                                               struct bdi_writeback, bdi_node);
 
        might_sleep();
 restart:
        rcu_read_lock();
-       bdi_for_each_wb(wb, bdi, &iter, next_memcg_id) {
+       list_for_each_entry_continue_rcu(wb, &bdi->wb_list, bdi_node) {
                DEFINE_WB_COMPLETION_ONSTACK(fallback_work_done);
                struct wb_writeback_work fallback_work;
                struct wb_writeback_work *work;
                long nr_pages;
 
+               if (last_wb) {
+                       wb_put(last_wb);
+                       last_wb = NULL;
+               }
+
                /* SYNC_ALL writes out I_DIRTY_TIME too */
                if (!wb_has_dirty_io(wb) &&
                    (base_work->sync_mode == WB_SYNC_NONE ||
@@ -819,12 +824,22 @@ restart:
 
                wb_queue_work(wb, work);
 
-               next_memcg_id = wb->memcg_css->id + 1;
+               /*
+                * Pin @wb so that it stays on @bdi->wb_list.  This allows
+                * continuing iteration from @wb after dropping and
+                * regrabbing rcu read lock.
+                */
+               wb_get(wb);
+               last_wb = wb;
+
                rcu_read_unlock();
                wb_wait_for_completion(bdi, &fallback_work_done);
                goto restart;
        }
        rcu_read_unlock();
+
+       if (last_wb)
+               wb_put(last_wb);
 }
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
@@ -1857,12 +1872,11 @@ void wakeup_flusher_threads(long nr_pages, enum wb_reason reason)
        rcu_read_lock();
        list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
                struct bdi_writeback *wb;
-               struct wb_iter iter;
 
                if (!bdi_has_dirty_io(bdi))
                        continue;
 
-               bdi_for_each_wb(wb, bdi, &iter, 0)
+               list_for_each_entry_rcu(wb, &bdi->wb_list, bdi_node)
                        wb_start_writeback(wb, wb_split_bdi_pages(wb, nr_pages),
                                           false, reason);
        }
@@ -1894,11 +1908,10 @@ static void wakeup_dirtytime_writeback(struct work_struct *w)
        rcu_read_lock();
        list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
                struct bdi_writeback *wb;
-               struct wb_iter iter;
 
-               bdi_for_each_wb(wb, bdi, &iter, 0)
-                       if (!list_empty(&bdi->wb.b_dirty_time))
-                               wb_wakeup(&bdi->wb);
+               list_for_each_entry_rcu(wb, &bdi->wb_list, bdi_node)
+                       if (!list_empty(&wb->b_dirty_time))
+                               wb_wakeup(wb);
        }
        rcu_read_unlock();
        schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ);
index 778a4ddef77a21844b08af82058d3b188371dc01..a7c34274f2076bc36e9cb9797f682988e617417f 100644 (file)
@@ -139,7 +139,8 @@ map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block)
 static struct bio *
 do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
                sector_t *last_block_in_bio, struct buffer_head *map_bh,
-               unsigned long *first_logical_block, get_block_t get_block)
+               unsigned long *first_logical_block, get_block_t get_block,
+               gfp_t gfp)
 {
        struct inode *inode = page->mapping->host;
        const unsigned blkbits = inode->i_blkbits;
@@ -277,8 +278,7 @@ alloc_new:
                                goto out;
                }
                bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
-                               min_t(int, nr_pages, BIO_MAX_PAGES),
-                               GFP_KERNEL);
+                               min_t(int, nr_pages, BIO_MAX_PAGES), gfp);
                if (bio == NULL)
                        goto confused;
        }
@@ -361,6 +361,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
        sector_t last_block_in_bio = 0;
        struct buffer_head map_bh;
        unsigned long first_logical_block = 0;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(mapping);
 
        map_bh.b_state = 0;
        map_bh.b_size = 0;
@@ -370,12 +371,13 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
                prefetchw(&page->flags);
                list_del(&page->lru);
                if (!add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+                                       page->index,
+                                       gfp)) {
                        bio = do_mpage_readpage(bio, page,
                                        nr_pages - page_idx,
                                        &last_block_in_bio, &map_bh,
                                        &first_logical_block,
-                                       get_block);
+                                       get_block, gfp);
                }
                page_cache_release(page);
        }
@@ -395,11 +397,12 @@ int mpage_readpage(struct page *page, get_block_t get_block)
        sector_t last_block_in_bio = 0;
        struct buffer_head map_bh;
        unsigned long first_logical_block = 0;
+       gfp_t gfp = GFP_KERNEL & mapping_gfp_mask(page->mapping);
 
        map_bh.b_state = 0;
        map_bh.b_size = 0;
        bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
-                       &map_bh, &first_logical_block, get_block);
+                       &map_bh, &first_logical_block, get_block, gfp);
        if (bio)
                mpage_bio_submit(READ, bio);
        return 0;
index cdefaa331a0719e88df91ef7c04c32706ae199a1..c29d9421bd5e1f8c890178c6ec961899b319ceef 100644 (file)
@@ -56,14 +56,6 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp,
        u32 device_generation = 0;
        int error;
 
-       /*
-        * We do not attempt to support I/O smaller than the fs block size,
-        * or not aligned to it.
-        */
-       if (args->lg_minlength < block_size) {
-               dprintk("pnfsd: I/O too small\n");
-               goto out_layoutunavailable;
-       }
        if (seg->offset & (block_size - 1)) {
                dprintk("pnfsd: I/O misaligned\n");
                goto out_layoutunavailable;
index ee5aa4daaea0dbf6c1840649ac505f60313aa8dd..ce38b4ccc9ab6c52c796a148b496bab0d8d46510 100644 (file)
@@ -1658,12 +1658,13 @@ send_response:
                if (ret < 0) {
                        mlog(ML_ERROR, "failed to dispatch assert master work\n");
                        response = DLM_MASTER_RESP_ERROR;
+                       spin_unlock(&res->spinlock);
                        dlm_lockres_put(res);
                } else {
                        dispatched = 1;
                        __dlm_lockres_grab_inflight_worker(dlm, res);
+                       spin_unlock(&res->spinlock);
                }
-               spin_unlock(&res->spinlock);
        } else {
                if (res)
                        dlm_lockres_put(res);
index 3d90ad7ff91fe4748386218807f7131bd61d7d69..58eaa5c0d387051301a089f0d234d4b69bf18d51 100644 (file)
@@ -1723,8 +1723,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
                        } else {
                                dispatched = 1;
                                __dlm_lockres_grab_inflight_worker(dlm, res);
+                               spin_unlock(&res->spinlock);
                        }
-                       spin_unlock(&res->spinlock);
                } else {
                        /* put.. incase we are not the master */
                        spin_unlock(&res->spinlock);
index ba1323a94924962299d27cbe67d76ff4e0056bb9..a586467f6ff6c73a4f31234fd96fce0a7b0dc34b 100644 (file)
@@ -70,6 +70,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
        unsigned order;
        void *data;
        int ret;
+       gfp_t gfp = mapping_gfp_mask(inode->i_mapping);
 
        /* make various checks */
        order = get_order(newsize);
@@ -84,7 +85,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
 
        /* allocate enough contiguous pages to be able to satisfy the
         * request */
-       pages = alloc_pages(mapping_gfp_mask(inode->i_mapping), order);
+       pages = alloc_pages(gfp, order);
        if (!pages)
                return -ENOMEM;
 
@@ -108,7 +109,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
                struct page *page = pages + loop;
 
                ret = add_to_page_cache_lru(page, inode->i_mapping, loop,
-                                       GFP_KERNEL);
+                                       gfp);
                if (ret < 0)
                        goto add_error;
 
index 9f20eb4acaa6054ef2362ee5eeef4576beb6c88a..204f5819d464b6ec3c169d78b2ec9a30989be90e 100644 (file)
@@ -193,8 +193,9 @@ struct acpi_exception_info {
 #define AE_AML_ILLEGAL_ADDRESS          EXCEP_AML (0x0020)
 #define AE_AML_INFINITE_LOOP            EXCEP_AML (0x0021)
 #define AE_AML_UNINITIALIZED_NODE       EXCEP_AML (0x0022)
+#define AE_AML_TARGET_TYPE              EXCEP_AML (0x0023)
 
-#define AE_CODE_AML_MAX                 0x0022
+#define AE_CODE_AML_MAX                 0x0023
 
 /*
  * Internal exceptions used for control
@@ -358,7 +359,9 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = {
        EXCEP_TXT("AE_AML_INFINITE_LOOP",
                  "An apparent infinite AML While loop, method was aborted"),
        EXCEP_TXT("AE_AML_UNINITIALIZED_NODE",
-                 "A namespace node is uninitialized or unresolved")
+                 "A namespace node is uninitialized or unresolved"),
+       EXCEP_TXT("AE_AML_TARGET_TYPE",
+                 "A target operand of an incorrect type was encountered")
 };
 
 static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = {
index 5ba8fb64f664ecea523f21034ad3c8f7d3a47e13..d11eff8a4efe95f92d8e75a18498017709ca096f 100644 (file)
@@ -129,7 +129,7 @@ static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile(
 struct acpi_scan_handler {
        const struct acpi_device_id *ids;
        struct list_head list_node;
-       bool (*match)(char *idstr, const struct acpi_device_id **matchid);
+       bool (*match)(const char *idstr, const struct acpi_device_id **matchid);
        int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
        void (*detach)(struct acpi_device *dev);
        void (*bind)(struct device *phys_dev);
@@ -227,7 +227,7 @@ typedef char acpi_device_class[20];
 
 struct acpi_hardware_id {
        struct list_head list;
-       char *id;
+       const char *id;
 };
 
 struct acpi_pnp_type {
@@ -343,6 +343,7 @@ struct acpi_device_data {
        const union acpi_object *pointer;
        const union acpi_object *properties;
        const union acpi_object *of_compatible;
+       struct list_head subnodes;
 };
 
 struct acpi_gpio_mapping;
@@ -378,6 +379,17 @@ struct acpi_device {
        void (*remove)(struct acpi_device *);
 };
 
+/* Non-device subnode */
+struct acpi_data_node {
+       const char *name;
+       acpi_handle handle;
+       struct fwnode_handle fwnode;
+       struct acpi_device_data data;
+       struct list_head sibling;
+       struct kobject kobj;
+       struct completion kobj_done;
+};
+
 static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 {
        bool ret = false;
@@ -412,16 +424,33 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 }
 
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
+{
+       return fwnode && (fwnode->type == FWNODE_ACPI
+               || fwnode->type == FWNODE_ACPI_DATA);
+}
+
+static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
 {
        return fwnode && fwnode->type == FWNODE_ACPI;
 }
 
-static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode)
+static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
 {
-       return is_acpi_node(fwnode) ?
+       return is_acpi_device_node(fwnode) ?
                container_of(fwnode, struct acpi_device, fwnode) : NULL;
 }
 
+static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
+{
+       return fwnode && fwnode->type == FWNODE_ACPI_DATA;
+}
+
+static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
+{
+       return is_acpi_data_node(fwnode) ?
+               container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
+}
+
 static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
 {
        return &adev->fwnode;
index a54ad1cc990c6b53d9e9b7a2f7283f2101f923ff..fbc2baf2b9dc98ac6f7195decd71b27aeac4076d 100644 (file)
@@ -55,7 +55,8 @@ typedef enum {
        OSL_GLOBAL_LOCK_HANDLER,
        OSL_NOTIFY_HANDLER,
        OSL_GPE_HANDLER,
-       OSL_DEBUGGER_THREAD,
+       OSL_DEBUGGER_MAIN_THREAD,
+       OSL_DEBUGGER_EXEC_THREAD,
        OSL_EC_POLL_HANDLER,
        OSL_EC_BURST_HANDLER
 } acpi_execute_type;
index c33eeabde1602ecb967df2b1c131a58cda32dc1e..3aaaa8630735c187d19943467f3242c1e0c9388a 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20150818
+#define ACPI_CA_VERSION                 0x20150930
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
@@ -393,15 +393,11 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_terminate(void))
  */
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void))
-#endif
 
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                            acpi_get_system_info(struct acpi_buffer
                                                 *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_get_statistics(struct acpi_statistics *stats))
 ACPI_EXTERNAL_RETURN_PTR(const char
@@ -625,11 +621,9 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                                                               space_id,
                                                               acpi_adr_space_handler
                                                               handler))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_install_exception_handler
                             (acpi_exception_handler handler))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_install_interface_handler
                             (acpi_interface_handler handler))
@@ -750,12 +744,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_get_current_resources(acpi_handle device,
                                                        struct acpi_buffer
                                                        *ret_buffer))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_get_possible_resources(acpi_handle device,
                                                         struct acpi_buffer
                                                         *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                             acpi_get_event_resources(acpi_handle device_handle,
                                                      struct acpi_buffer
@@ -844,7 +836,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 /*
  * ACPI Timer interfaces
  */
-#ifdef ACPI_FUTURE_USAGE
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_get_timer_resolution(u32 *resolution))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks))
@@ -853,7 +844,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
                                acpi_get_timer_duration(u32 start_ticks,
                                                        u32 end_ticks,
                                                        u32 *time_elapsed))
-#endif                         /* ACPI_FUTURE_USAGE */
 
 /*
  * Error/Warning output
@@ -939,4 +929,6 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
                                               void **data,
                                               void (*callback)(void *)))
 
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
+
 #endif                         /* __ACXFACE_H__ */
index fcd570999f354247c9dbba73163797ff38cbd1a6..1bb979e3e3f53b3bce69f348436e6c3a44a38d91 100644 (file)
@@ -1012,7 +1012,7 @@ struct acpi_nfit_memory_map {
 #define ACPI_NFIT_MEM_SAVE_FAILED       (1)    /* 00: Last SAVE to Memory Device failed */
 #define ACPI_NFIT_MEM_RESTORE_FAILED    (1<<1) /* 01: Last RESTORE from Memory Device failed */
 #define ACPI_NFIT_MEM_FLUSH_FAILED      (1<<2) /* 02: Platform flush failed */
-#define ACPI_NFIT_MEM_ARMED             (1<<3) /* 03: Memory Device observed to be not armed */
+#define ACPI_NFIT_MEM_NOT_ARMED         (1<<3) /* 03: Memory Device is not armed */
 #define ACPI_NFIT_MEM_HEALTH_OBSERVED   (1<<4) /* 04: Memory Device observed SMART/health events */
 #define ACPI_NFIT_MEM_HEALTH_ENABLED    (1<<5) /* 05: SMART/health events enabled */
 
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
new file mode 100644 (file)
index 0000000..717a298
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * CPPC (Collaborative Processor Performance Control) methods used
+ * by CPUfreq drivers.
+ *
+ * (C) Copyright 2014, 2015 Linaro Ltd.
+ * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _CPPC_ACPI_H
+#define _CPPC_ACPI_H
+
+#include <linux/acpi.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+#include <linux/types.h>
+
+#include <acpi/processor.h>
+
+/* Only support CPPCv2 for now. */
+#define CPPC_NUM_ENT   21
+#define CPPC_REV       2
+
+#define PCC_CMD_COMPLETE 1
+#define MAX_CPC_REG_ENT 19
+
+/* CPPC specific PCC commands. */
+#define        CMD_READ 0
+#define        CMD_WRITE 1
+
+/* Each register has the folowing format. */
+struct cpc_reg {
+       u8 descriptor;
+       u16 length;
+       u8 space_id;
+       u8 bit_width;
+       u8 bit_offset;
+       u8 access_width;
+       u64 __iomem address;
+} __packed;
+
+/*
+ * Each entry in the CPC table is either
+ * of type ACPI_TYPE_BUFFER or
+ * ACPI_TYPE_INTEGER.
+ */
+struct cpc_register_resource {
+       acpi_object_type type;
+       union {
+               struct cpc_reg reg;
+               u64 int_value;
+       } cpc_entry;
+};
+
+/* Container to hold the CPC details for each CPU */
+struct cpc_desc {
+       int num_entries;
+       int version;
+       int cpu_id;
+       struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
+       struct acpi_psd_package domain_info;
+};
+
+/* These are indexes into the per-cpu cpc_regs[]. Order is important. */
+enum cppc_regs {
+       HIGHEST_PERF,
+       NOMINAL_PERF,
+       LOW_NON_LINEAR_PERF,
+       LOWEST_PERF,
+       GUARANTEED_PERF,
+       DESIRED_PERF,
+       MIN_PERF,
+       MAX_PERF,
+       PERF_REDUC_TOLERANCE,
+       TIME_WINDOW,
+       CTR_WRAP_TIME,
+       REFERENCE_CTR,
+       DELIVERED_CTR,
+       PERF_LIMITED,
+       ENABLE,
+       AUTO_SEL_ENABLE,
+       AUTO_ACT_WINDOW,
+       ENERGY_PERF,
+       REFERENCE_PERF,
+};
+
+/*
+ * Categorization of registers as described
+ * in the ACPI v.5.1 spec.
+ * XXX: Only filling up ones which are used by governors
+ * today.
+ */
+struct cppc_perf_caps {
+       u32 highest_perf;
+       u32 nominal_perf;
+       u32 reference_perf;
+       u32 lowest_perf;
+};
+
+struct cppc_perf_ctrls {
+       u32 max_perf;
+       u32 min_perf;
+       u32 desired_perf;
+};
+
+struct cppc_perf_fb_ctrs {
+       u64 reference;
+       u64 prev_reference;
+       u64 delivered;
+       u64 prev_delivered;
+};
+
+/* Per CPU container for runtime CPPC management. */
+struct cpudata {
+       int cpu;
+       struct cppc_perf_caps perf_caps;
+       struct cppc_perf_ctrls perf_ctrls;
+       struct cppc_perf_fb_ctrs perf_fb_ctrs;
+       struct cpufreq_policy *cur_policy;
+       unsigned int shared_type;
+       cpumask_var_t shared_cpu_map;
+};
+
+extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
+extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
+extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
+extern int acpi_get_psd_map(struct cpudata **);
+
+/* Methods to interact with the PCC mailbox controller. */
+extern struct mbox_chan *
+       pcc_mbox_request_channel(struct mbox_client *, unsigned int);
+extern int mbox_send_message(struct mbox_chan *chan, void *mssg);
+
+#endif /* _CPPC_ACPI_H*/
index ec00e2bb029e6258daa3b0e8db8aa1061fabbc2c..056f245ad0380171b0de8adad7b89324ecbb29b0 100644 (file)
 
 #ifdef ACPI_LIBRARY
 #define ACPI_USE_LOCAL_CACHE
-#define ACPI_FUTURE_USAGE
+#define ACPI_FULL_DEBUG
 #endif
 
 /* Common for all ACPICA applications */
  * multi-threaded if ACPI_APPLICATION is not set.
  */
 #ifndef DEBUGGER_THREADING
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+#if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP)
+#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
 
 #else
-#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
 #endif
 #endif                         /* !DEBUGGER_THREADING */
 
index 74ba46c8157a6f13098d27bd2338b8c8bf7db93f..323e5daece54999684144620cc644e4b64e1c707 100644 (file)
 
 #define ACPI_USE_SYSTEM_INTTYPES
 
-/* Compile for reduced hardware mode only with this kernel config */
+/* Kernel specific ACPICA configuration */
 
 #ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY
 #define ACPI_REDUCED_HARDWARE 1
 #endif
 
+#ifdef CONFIG_ACPI_DEBUGGER
+#define ACPI_DEBUGGER
+#endif
+
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
  * OSL interfaces used by utilities
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_name
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_index
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_address
index acedc3f026de7bd6e3a8a8fce834000e97efdcdc..fd6d70fe1219c35b12b65902759185e6bcbaa9cd 100644 (file)
@@ -124,6 +124,11 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
                lock ? AE_OK : AE_NO_MEMORY; \
        })
 
+static inline u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+       return TRUE;
+}
+
 /*
  * OSL interfaces added by Linux
  */
index ff5f135f16b139e5fb04096a8a28d8103d72d2c5..07fb100bcc688ddc1835b958ac430182ee699128 100644 (file)
@@ -311,6 +311,20 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id);
 int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
 int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+extern int acpi_cppc_processor_probe(struct acpi_processor *pr);
+extern void acpi_cppc_processor_exit(struct acpi_processor *pr);
+#else
+static inline int acpi_cppc_processor_probe(struct acpi_processor *pr)
+{
+       return 0;
+}
+static inline void acpi_cppc_processor_exit(struct acpi_processor *pr)
+{
+       return;
+}
+#endif /* CONFIG_ACPI_CPPC_LIB */
+
 /* in processor_pdc.c */
 void acpi_processor_set_pdc(acpi_handle handle);
 
index 1781e54ea6d30791796c450df64240dff720fbbf..c4bd0e2c173c011e37f6eef7acfb9bc3920fcca6 100644 (file)
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
 #define EARLYCON_OF_TABLES()   OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
+#ifdef CONFIG_ACPI
+#define ACPI_PROBE_TABLE(name)                                         \
+       . = ALIGN(8);                                                   \
+       VMLINUX_SYMBOL(__##name##_acpi_probe_table) = .;                \
+       *(__##name##_acpi_probe_table)                                  \
+       VMLINUX_SYMBOL(__##name##_acpi_probe_table_end) = .;
+#else
+#define ACPI_PROBE_TABLE(name)
+#endif
+
 #define KERNEL_DTB()                                                   \
        STRUCT_ALIGN();                                                 \
        VMLINUX_SYMBOL(__dtb_start) = .;                                \
        CPUIDLE_METHOD_OF_TABLES()                                      \
        KERNEL_DTB()                                                    \
        IRQCHIP_OF_MATCH_TABLE()                                        \
+       ACPI_PROBE_TABLE(irqchip)                                       \
+       ACPI_PROBE_TABLE(clksrc)                                        \
        EARLYCON_TABLE()                                                \
        EARLYCON_OF_TABLES()
 
index 0f408b002d989ee8bca9489d6c1add673b315a51..5340099741aec8c48575b1c1056f23903e150ed6 100644 (file)
@@ -253,6 +253,7 @@ struct drm_dp_remote_dpcd_write {
        u8 *bytes;
 };
 
+#define DP_REMOTE_I2C_READ_MAX_TRANSACTIONS 4
 struct drm_dp_remote_i2c_read {
        u8 num_transactions;
        u8 port_number;
@@ -262,7 +263,7 @@ struct drm_dp_remote_i2c_read {
                u8 *bytes;
                u8 no_stop_bit;
                u8 i2c_transaction_delay;
-       } transactions[4];
+       } transactions[DP_REMOTE_I2C_READ_MAX_TRANSACTIONS];
        u8 read_i2c_device_id;
        u8 num_bytes_read;
 };
index 43856d19cf4d8abc8942849202485fe76244135d..82f56bb0214c5be2321b679402a743c4f70b97e3 100644 (file)
@@ -49,7 +49,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
        return adev ? adev->handle : NULL;
 }
 
-#define ACPI_COMPANION(dev)            to_acpi_node((dev)->fwnode)
+#define ACPI_COMPANION(dev)            to_acpi_device_node((dev)->fwnode)
 #define ACPI_COMPANION_SET(dev, adev)  set_primary_fwnode(dev, (adev) ? \
        acpi_fwnode_handle(adev) : NULL)
 #define ACPI_HANDLE(dev)               acpi_device_handle(ACPI_COMPANION(dev))
@@ -69,7 +69,7 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev)
 
 static inline bool has_acpi_companion(struct device *dev)
 {
-       return is_acpi_node(dev->fwnode);
+       return is_acpi_device_node(dev->fwnode);
 }
 
 static inline void acpi_preset_companion(struct device *dev,
@@ -131,6 +131,12 @@ static inline void acpi_initrd_override(void *data, size_t size)
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
                ((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
 
+struct acpi_subtable_proc {
+       int id;
+       acpi_tbl_entry_handler handler;
+       int count;
+};
+
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
@@ -146,9 +152,16 @@ int __init acpi_parse_entries(char *id, unsigned long table_size,
                              struct acpi_table_header *table_header,
                              int entry_id, unsigned int max_entries);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-                                   int entry_id,
-                                   acpi_tbl_entry_handler handler,
-                                   unsigned int max_entries);
+                             int entry_id,
+                             acpi_tbl_entry_handler handler,
+                             unsigned int max_entries);
+int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+                             int entry_id,
+                             acpi_tbl_entry_handler handler,
+                             unsigned int max_entries);
+int __init acpi_table_parse_entries_array(char *id, unsigned long table_size,
+                             struct acpi_subtable_proc *proc, int proc_num,
+                             unsigned int max_entries);
 int acpi_table_parse_madt(enum acpi_madt_type id,
                          acpi_tbl_entry_handler handler,
                          unsigned int max_entries);
@@ -193,6 +206,12 @@ int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base);
 void acpi_irq_stats_init(void);
 extern u32 acpi_irq_handled;
 extern u32 acpi_irq_not_handled;
+extern unsigned int acpi_sci_irq;
+#define INVALID_ACPI_IRQ       ((unsigned)-1)
+static inline bool acpi_sci_irq_valid(void)
+{
+       return acpi_sci_irq != INVALID_ACPI_IRQ;
+}
 
 extern int sbf_port;
 extern unsigned long acpi_realmode_flags;
@@ -462,7 +481,22 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode)
        return false;
 }
 
-static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode)
+static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
+{
+       return false;
+}
+
+static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
+{
+       return NULL;
+}
+
+static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
+{
+       return false;
+}
+
+static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
 {
        return NULL;
 }
@@ -744,22 +778,76 @@ struct acpi_reference_args {
 #ifdef CONFIG_ACPI
 int acpi_dev_get_property(struct acpi_device *adev, const char *name,
                          acpi_object_type type, const union acpi_object **obj);
-int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
-                               acpi_object_type type,
-                               const union acpi_object **obj);
-int acpi_dev_get_property_reference(struct acpi_device *adev,
-                                   const char *name, size_t index,
-                                   struct acpi_reference_args *args);
-
-int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
-                     void **valptr);
+int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+                                    const char *name, size_t index,
+                                    struct acpi_reference_args *args);
+
+int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
+                      void **valptr);
 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname,
                              enum dev_prop_type proptype, void *val);
+int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname,
+                       enum dev_prop_type proptype, void *val, size_t nval);
 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
                       enum dev_prop_type proptype, void *val, size_t nval);
 
-struct acpi_device *acpi_get_next_child(struct device *dev,
-                                       struct acpi_device *child);
+struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+                                           struct fwnode_handle *subnode);
+
+struct acpi_probe_entry;
+typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
+                                                struct acpi_probe_entry *);
+
+#define ACPI_TABLE_ID_LEN      5
+
+/**
+ * struct acpi_probe_entry - boot-time probing entry
+ * @id:                        ACPI table name
+ * @type:              Optional subtable type to match
+ *                     (if @id contains subtables)
+ * @subtable_valid:    Optional callback to check the validity of
+ *                     the subtable
+ * @probe_table:       Callback to the driver being probed when table
+ *                     match is successful
+ * @probe_subtbl:      Callback to the driver being probed when table and
+ *                     subtable match (and optional callback is successful)
+ * @driver_data:       Sideband data provided back to the driver
+ */
+struct acpi_probe_entry {
+       __u8 id[ACPI_TABLE_ID_LEN];
+       __u8 type;
+       acpi_probe_entry_validate_subtbl subtable_valid;
+       union {
+               acpi_tbl_table_handler probe_table;
+               acpi_tbl_entry_handler probe_subtbl;
+       };
+       kernel_ulong_t driver_data;
+};
+
+#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn)     \
+       static const struct acpi_probe_entry __acpi_probe_##name        \
+               __used __section(__##table##_acpi_probe_table)          \
+                = {                                                    \
+                       .id = table_id,                                 \
+                       .type = subtable,                               \
+                       .subtable_valid = valid,                        \
+                       .probe_table = (acpi_tbl_table_handler)fn,      \
+                       .driver_data = data,                            \
+                  }
+
+#define ACPI_PROBE_TABLE(name)         __##name##_acpi_probe_table
+#define ACPI_PROBE_TABLE_END(name)     __##name##_acpi_probe_table_end
+
+int __acpi_probe_device_table(struct acpi_probe_entry *start, int nr);
+
+#define acpi_probe_device_table(t)                                     \
+       ({                                                              \
+               extern struct acpi_probe_entry ACPI_PROBE_TABLE(t),     \
+                                              ACPI_PROBE_TABLE_END(t); \
+               __acpi_probe_device_table(&ACPI_PROBE_TABLE(t),         \
+                                         (&ACPI_PROBE_TABLE_END(t) -   \
+                                          &ACPI_PROBE_TABLE(t)));      \
+       })
 #else
 static inline int acpi_dev_get_property(struct acpi_device *adev,
                                        const char *name, acpi_object_type type,
@@ -767,16 +855,17 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
 {
        return -ENXIO;
 }
-static inline int acpi_dev_get_property_array(struct acpi_device *adev,
-                                             const char *name,
-                                             acpi_object_type type,
-                                             const union acpi_object **obj)
+
+static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+                               const char *name, const char *cells_name,
+                               size_t index, struct acpi_reference_args *args)
 {
        return -ENXIO;
 }
-static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
-                               const char *name, const char *cells_name,
-                               size_t index, struct acpi_reference_args *args)
+
+static inline int acpi_node_prop_get(struct fwnode_handle *fwnode,
+                                    const char *propname,
+                                    void **valptr)
 {
        return -ENXIO;
 }
@@ -796,6 +885,14 @@ static inline int acpi_dev_prop_read_single(struct acpi_device *adev,
        return -ENXIO;
 }
 
+static inline int acpi_node_prop_read(struct fwnode_handle *fwnode,
+                                     const char *propname,
+                                     enum dev_prop_type proptype,
+                                     void *val, size_t nval)
+{
+       return -ENXIO;
+}
+
 static inline int acpi_dev_prop_read(struct acpi_device *adev,
                                     const char *propname,
                                     enum dev_prop_type proptype,
@@ -804,12 +901,22 @@ static inline int acpi_dev_prop_read(struct acpi_device *adev,
        return -ENXIO;
 }
 
-static inline struct acpi_device *acpi_get_next_child(struct device *dev,
-                                                     struct acpi_device *child)
+static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+                                               struct fwnode_handle *subnode)
 {
        return NULL;
 }
 
+#define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, validate, data, fn) \
+       static const void * __acpi_table_##name[]                       \
+               __attribute__((unused))                                 \
+                = { (void *) table_id,                                 \
+                    (void *) subtable,                                 \
+                    (void *) valid,                                    \
+                    (void *) fn,                                       \
+                    (void *) data }
+
+#define acpi_probe_device_table(t)     ({ int __r = 0; __r;})
 #endif
 
 #endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/acpi_irq.h b/include/linux/acpi_irq.h
deleted file mode 100644 (file)
index f10c872..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _LINUX_ACPI_IRQ_H
-#define _LINUX_ACPI_IRQ_H
-
-#include <linux/irq.h>
-
-#ifndef acpi_irq_init
-static inline void acpi_irq_init(void) { }
-#endif
-
-#endif /* _LINUX_ACPI_IRQ_H */
index a23209b43842106c6a74de8a51d6b4b752613157..1b4d69f68c33cc73ad99a1136b2408c71e763fb8 100644 (file)
@@ -116,6 +116,8 @@ struct bdi_writeback {
        struct list_head work_list;
        struct delayed_work dwork;      /* work item used for writeback */
 
+       struct list_head bdi_node;      /* anchored at bdi->wb_list */
+
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct percpu_ref refcnt;       /* used only for !root wb's */
        struct fprop_local_percpu memcg_completions;
@@ -150,6 +152,7 @@ struct backing_dev_info {
        atomic_long_t tot_write_bandwidth;
 
        struct bdi_writeback wb;  /* the root writeback info for this bdi */
+       struct list_head wb_list; /* list of all wbs */
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
        struct rb_root cgwb_congested_tree; /* their congested states */
index d5eb4ad1c534a8074b64ee75d4b597563e36e89a..c85f74946a8bab65ff3f16cddea6a4446b0a4799 100644 (file)
 #include <linux/slab.h>
 
 int __must_check bdi_init(struct backing_dev_info *bdi);
-void bdi_destroy(struct backing_dev_info *bdi);
+void bdi_exit(struct backing_dev_info *bdi);
 
 __printf(3, 4)
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
                const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
+void bdi_unregister(struct backing_dev_info *bdi);
+
 int __must_check bdi_setup_and_register(struct backing_dev_info *, char *);
+void bdi_destroy(struct backing_dev_info *bdi);
+
 void wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
                        bool range_cyclic, enum wb_reason reason);
 void wb_start_background_writeback(struct bdi_writeback *wb);
@@ -408,61 +412,6 @@ static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
        rcu_read_unlock();
 }
 
-struct wb_iter {
-       int                     start_memcg_id;
-       struct radix_tree_iter  tree_iter;
-       void                    **slot;
-};
-
-static inline struct bdi_writeback *__wb_iter_next(struct wb_iter *iter,
-                                                  struct backing_dev_info *bdi)
-{
-       struct radix_tree_iter *titer = &iter->tree_iter;
-
-       WARN_ON_ONCE(!rcu_read_lock_held());
-
-       if (iter->start_memcg_id >= 0) {
-               iter->slot = radix_tree_iter_init(titer, iter->start_memcg_id);
-               iter->start_memcg_id = -1;
-       } else {
-               iter->slot = radix_tree_next_slot(iter->slot, titer, 0);
-       }
-
-       if (!iter->slot)
-               iter->slot = radix_tree_next_chunk(&bdi->cgwb_tree, titer, 0);
-       if (iter->slot)
-               return *iter->slot;
-       return NULL;
-}
-
-static inline struct bdi_writeback *__wb_iter_init(struct wb_iter *iter,
-                                                  struct backing_dev_info *bdi,
-                                                  int start_memcg_id)
-{
-       iter->start_memcg_id = start_memcg_id;
-
-       if (start_memcg_id)
-               return __wb_iter_next(iter, bdi);
-       else
-               return &bdi->wb;
-}
-
-/**
- * bdi_for_each_wb - walk all wb's of a bdi in ascending memcg ID order
- * @wb_cur: cursor struct bdi_writeback pointer
- * @bdi: bdi to walk wb's of
- * @iter: pointer to struct wb_iter to be used as iteration buffer
- * @start_memcg_id: memcg ID to start iteration from
- *
- * Iterate @wb_cur through the wb's (bdi_writeback's) of @bdi in ascending
- * memcg ID order starting from @start_memcg_id.  @iter is struct wb_iter
- * to be used as temp storage during iteration.  rcu_read_lock() must be
- * held throughout iteration.
- */
-#define bdi_for_each_wb(wb_cur, bdi, iter, start_memcg_id)             \
-       for ((wb_cur) = __wb_iter_init(iter, bdi, start_memcg_id);      \
-            (wb_cur); (wb_cur) = __wb_iter_next(iter, bdi))
-
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
 static inline bool inode_cgwb_enabled(struct inode *inode)
@@ -522,14 +471,6 @@ static inline void wb_blkcg_offline(struct blkcg *blkcg)
 {
 }
 
-struct wb_iter {
-       int             next_id;
-};
-
-#define bdi_for_each_wb(wb_cur, bdi, iter, start_blkcg_id)             \
-       for ((iter)->next_id = (start_blkcg_id);                        \
-            ({ (wb_cur) = !(iter)->next_id++ ? &(bdi)->wb : NULL; }); )
-
 static inline int inode_congested(struct inode *inode, int cong_bits)
 {
        return wb_congested(&inode_to_bdi(inode)->wb, cong_bits);
index 278dd279a7a8035e8be073a9664ea88f7357984a..7784b597e9592b0ea0a32d661a0068cf9a8e2137 100644 (file)
@@ -246,16 +246,13 @@ extern int clocksource_i8253_init(void);
 #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \
        OF_DECLARE_1(clksrc, name, compat, fn)
 
-#ifdef CONFIG_CLKSRC_OF
-extern void clocksource_of_init(void);
+#ifdef CONFIG_CLKSRC_PROBE
+extern void clocksource_probe(void);
 #else
-static inline void clocksource_of_init(void) {}
+static inline void clocksource_probe(void) {}
 #endif
 
-#ifdef CONFIG_ACPI
-void acpi_generic_timer_init(void);
-#else
-static inline void acpi_generic_timer_init(void) { }
-#endif
+#define CLOCKSOURCE_ACPI_DECLARE(name, table_id, fn)           \
+       ACPI_DECLARE_PROBE_ENTRY(clksrc, name, table_id, 0, NULL, 0, fn)
 
 #endif /* _LINUX_CLOCKSOURCE_H */
index f7ef093ec49a2bbdd637aae6ab0f1bf0fa4e1e32..29f9e774ab76ef5c1deb019a142af3027a43ebce 100644 (file)
@@ -26,6 +26,6 @@ extern int __init cma_declare_contiguous(phys_addr_t base,
 extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
                                        unsigned int order_per_bit,
                                        struct cma **res_cma);
-extern struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align);
+extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align);
 extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
 #endif
index dfaa7b3e9ae900676b61dc7c3f693c78de97e8cd..8efb40e61d6e48021d68f93635eea8d3ab3e8c0b 100644 (file)
 #define KASAN_ABI_VERSION 3
 #endif
 
+#if GCC_VERSION >= 40902
+/*
+ * Tell the compiler that address safety instrumentation (KASAN)
+ * should not be applied to that function.
+ * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
+ */
+#define __no_sanitize_address __attribute__((no_sanitize_address))
+#endif
+
 #endif /* gcc version >= 40000 specific checks */
 
 #if !defined(__noclone)
 #define __noclone      /* not needed */
 #endif
 
+#if !defined(__no_sanitize_address)
+#define __no_sanitize_address
+#endif
+
 /*
  * A trick to suppress uninitialized variable warning without generating any
  * code
index c836eb2dc44d5b3a4d5e98dfbbd274c4448daa90..3d7810341b579795398e36cb15597feb344bb912 100644 (file)
@@ -198,19 +198,45 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 
 #include <uapi/linux/types.h>
 
-static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
+#define __READ_ONCE_SIZE                                               \
+({                                                                     \
+       switch (size) {                                                 \
+       case 1: *(__u8 *)res = *(volatile __u8 *)p; break;              \
+       case 2: *(__u16 *)res = *(volatile __u16 *)p; break;            \
+       case 4: *(__u32 *)res = *(volatile __u32 *)p; break;            \
+       case 8: *(__u64 *)res = *(volatile __u64 *)p; break;            \
+       default:                                                        \
+               barrier();                                              \
+               __builtin_memcpy((void *)res, (const void *)p, size);   \
+               barrier();                                              \
+       }                                                               \
+})
+
+static __always_inline
+void __read_once_size(const volatile void *p, void *res, int size)
 {
-       switch (size) {
-       case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
-       case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
-       case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
-       case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
-       default:
-               barrier();
-               __builtin_memcpy((void *)res, (const void *)p, size);
-               barrier();
-       }
+       __READ_ONCE_SIZE;
+}
+
+#ifdef CONFIG_KASAN
+/*
+ * This function is not 'inline' because __no_sanitize_address confilcts
+ * with inlining. Attempt to inline it may cause a build failure.
+ *     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
+ * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
+ */
+static __no_sanitize_address __maybe_unused
+void __read_once_size_nocheck(const volatile void *p, void *res, int size)
+{
+       __READ_ONCE_SIZE;
+}
+#else
+static __always_inline
+void __read_once_size_nocheck(const volatile void *p, void *res, int size)
+{
+       __READ_ONCE_SIZE;
 }
+#endif
 
 static __always_inline void __write_once_size(volatile void *p, void *res, int size)
 {
@@ -248,8 +274,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * required ordering.
  */
 
-#define READ_ONCE(x) \
-       ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
+#define __READ_ONCE(x, check)                                          \
+({                                                                     \
+       union { typeof(x) __val; char __c[1]; } __u;                    \
+       if (check)                                                      \
+               __read_once_size(&(x), __u.__c, sizeof(x));             \
+       else                                                            \
+               __read_once_size_nocheck(&(x), __u.__c, sizeof(x));     \
+       __u.__val;                                                      \
+})
+#define READ_ONCE(x) __READ_ONCE(x, 1)
+
+/*
+ * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
+ * to hide memory access from KASAN.
+ */
+#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
 
 #define WRITE_ONCE(x, val) \
 ({                                                     \
index 569bbd039896f330923d53b4a6231ba1c73e70cc..fec734df1524799e1e7137e943098c907d0fce8c 100644 (file)
@@ -111,7 +111,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
        return ret;
 }
 
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int order);
 bool dma_release_from_contiguous(struct device *dev, struct page *pages,
                                 int count);
@@ -144,7 +144,7 @@ int dma_declare_contiguous(struct device *dev, phys_addr_t size,
 }
 
 static inline
-struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
                                       unsigned int order)
 {
        return NULL;
index 0408545bce42403ecd50ecbeed8bffb78b336274..b08d6ba5c1e6c9a5e7e31d7ed966bffa20e517a1 100644 (file)
@@ -16,6 +16,7 @@ enum fwnode_type {
        FWNODE_INVALID = 0,
        FWNODE_OF,
        FWNODE_ACPI,
+       FWNODE_ACPI_DATA,
        FWNODE_PDATA,
 };
 
index 388e3ae94f7a3b1c3c86d7ba45d6f9227ee31f0d..24bea087e7af8083b3c81596a289d70530c64285 100644 (file)
@@ -94,6 +94,7 @@ struct resource {
 /* PnP I/O specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_IO_16BIT_ADDR       (1<<0)
 #define IORESOURCE_IO_FIXED            (1<<1)
+#define IORESOURCE_IO_SPARSE           (1<<2)
 
 /* PCI ROM control bits (IORESOURCE_BITS) */
 #define IORESOURCE_ROM_ENABLE          (1<<0)  /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
index 638887376e582c83531ea663269ddfc1ef625a42..89c34b20067122f732073df0b3234dfab2a7fa48 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef _LINUX_IRQCHIP_H
 #define _LINUX_IRQCHIP_H
 
+#include <linux/acpi.h>
 #include <linux/of.h>
 
 /*
  */
 #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
 
+/*
+ * This macro must be used by the different irqchip drivers to declare
+ * the association between their version and their initialization function.
+ *
+ * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
+ * same file.
+ * @subtable: Subtable to be identified in MADT
+ * @validate: Function to be called on that subtable to check its validity.
+ *            Can be NULL.
+ * @data: data to be checked by the validate function.
+ * @fn: initialization function
+ */
+#define IRQCHIP_ACPI_DECLARE(name, subtable, validate, data, fn)       \
+       ACPI_DECLARE_PROBE_ENTRY(irqchip, name, ACPI_SIG_MADT,          \
+                                subtable, validate, data, fn)
+
 #ifdef CONFIG_IRQCHIP
 void irqchip_init(void);
 #else
diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
deleted file mode 100644 (file)
index de3419e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014, Linaro Ltd.
- *     Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ARM_GIC_ACPI_H_
-#define ARM_GIC_ACPI_H_
-
-#ifdef CONFIG_ACPI
-
-/*
- * Hard code here, we can not get memory size from MADT (but FDT does),
- * Actually no need to do that, because this size can be inferred
- * from GIC spec.
- */
-#define ACPI_GICV2_DIST_MEM_SIZE       (SZ_4K)
-#define ACPI_GIC_CPU_IF_MEM_SIZE       (SZ_8K)
-
-struct acpi_table_header;
-
-int gic_v2_acpi_init(struct acpi_table_header *table);
-void acpi_gic_init(void);
-#else
-static inline void acpi_gic_init(void) { }
-#endif
-
-#endif /* ARM_GIC_ACPI_H_ */
index 6452ff4c463fd8715edc9a5043bc812521a18d6a..3e3318ddfc0e3e09a0e15825f78eb6052d628d78 100644 (file)
@@ -676,8 +676,9 @@ enum {
 
 struct list_head *mem_cgroup_cgwb_list(struct mem_cgroup *memcg);
 struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb);
-void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pavail,
-                        unsigned long *pdirty, unsigned long *pwriteback);
+void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pfilepages,
+                        unsigned long *pheadroom, unsigned long *pdirty,
+                        unsigned long *pwriteback);
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
@@ -687,7 +688,8 @@ static inline struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb)
 }
 
 static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb,
-                                      unsigned long *pavail,
+                                      unsigned long *pfilepages,
+                                      unsigned long *pheadroom,
                                       unsigned long *pdirty,
                                       unsigned long *pwriteback)
 {
index a965efa52152ee27b38a7827588610802e4f6079..89ab0572dbc63cfe4375cdae9528809b3b0bdd62 100644 (file)
@@ -52,6 +52,30 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
        return ACPI_HANDLE(dev);
 }
 
+struct acpi_pci_root;
+struct acpi_pci_root_ops;
+
+struct acpi_pci_root_info {
+       struct acpi_pci_root            *root;
+       struct acpi_device              *bridge;
+       struct acpi_pci_root_ops        *ops;
+       struct list_head                resources;
+       char                            name[16];
+};
+
+struct acpi_pci_root_ops {
+       struct pci_ops *pci_ops;
+       int (*init_info)(struct acpi_pci_root_info *info);
+       void (*release_info)(struct acpi_pci_root_info *info);
+       int (*prepare_resources)(struct acpi_pci_root_info *info);
+};
+
+extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info);
+extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
+                                           struct acpi_pci_root_ops *ops,
+                                           struct acpi_pci_root_info *info,
+                                           void *sd);
+
 void acpi_pci_add_bus(struct pci_bus *bus);
 void acpi_pci_remove_bus(struct pci_bus *bus);
 
index 35d599e7250d2d8c29defd0373ff25fed0b03467..528be6787796b52a405fbc0af8bf707c31d55192 100644 (file)
@@ -732,6 +732,7 @@ extern int pm_generic_poweroff_noirq(struct device *dev);
 extern int pm_generic_poweroff_late(struct device *dev);
 extern int pm_generic_poweroff(struct device *dev);
 extern void pm_generic_complete(struct device *dev);
+extern void pm_complete_with_resume_check(struct device *dev);
 
 #else /* !CONFIG_PM_SLEEP */
 
index a59c6ee566c2cf908ca7c6ec5512768e90d4a3b0..463de52fe8915486d2e2159bde7edf12834f8dcc 100644 (file)
@@ -40,6 +40,8 @@ int device_property_read_string_array(struct device *dev, const char *propname,
                                      const char **val, size_t nval);
 int device_property_read_string(struct device *dev, const char *propname,
                                const char **val);
+int device_property_match_string(struct device *dev,
+                                const char *propname, const char *string);
 
 bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
 int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
@@ -59,6 +61,8 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
                                      size_t nval);
 int fwnode_property_read_string(struct fwnode_handle *fwnode,
                                const char *propname, const char **val);
+int fwnode_property_match_string(struct fwnode_handle *fwnode,
+                                const char *propname, const char *string);
 
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
                                                 struct fwnode_handle *child);
index 5efe743ce1e88fc544cd4d98b2100861f1774105..8b6ec7ef0854e0f51fd94e38dbf7b831c9015f6c 100644 (file)
@@ -202,6 +202,36 @@ struct platform_freeze_ops {
 extern void suspend_set_ops(const struct platform_suspend_ops *ops);
 extern int suspend_valid_only_mem(suspend_state_t state);
 
+extern unsigned int pm_suspend_global_flags;
+
+#define PM_SUSPEND_FLAG_FW_SUSPEND     (1 << 0)
+#define PM_SUSPEND_FLAG_FW_RESUME      (1 << 1)
+
+static inline void pm_suspend_clear_flags(void)
+{
+       pm_suspend_global_flags = 0;
+}
+
+static inline void pm_set_suspend_via_firmware(void)
+{
+       pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_SUSPEND;
+}
+
+static inline void pm_set_resume_via_firmware(void)
+{
+       pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_RESUME;
+}
+
+static inline bool pm_suspend_via_firmware(void)
+{
+       return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_SUSPEND);
+}
+
+static inline bool pm_resume_via_firmware(void)
+{
+       return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_RESUME);
+}
+
 /* Suspend-to-idle state machnine. */
 enum freeze_state {
        FREEZE_STATE_NONE,      /* Not suspended/suspending. */
@@ -241,6 +271,12 @@ extern int pm_suspend(suspend_state_t state);
 #else /* !CONFIG_SUSPEND */
 #define suspend_valid_only_mem NULL
 
+static inline void pm_suspend_clear_flags(void) {}
+static inline void pm_set_suspend_via_firmware(void) {}
+static inline void pm_set_resume_via_firmware(void) {}
+static inline bool pm_suspend_via_firmware(void) { return false; }
+static inline bool pm_resume_via_firmware(void) { return false; }
+
 static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
 static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
 static inline bool idle_should_freeze(void) { return false; }
@@ -387,10 +423,12 @@ extern int unregister_pm_notifier(struct notifier_block *nb);
 
 /* drivers/base/power/wakeup.c */
 extern bool events_check_enabled;
+extern unsigned int pm_wakeup_irq;
 
 extern bool pm_wakeup_pending(void);
 extern void pm_system_wakeup(void);
 extern void pm_wakeup_clear(void);
+extern void pm_system_irq_wakeup(unsigned int irq_number);
 extern bool pm_get_wakeup_count(unsigned int *count, bool block);
 extern bool pm_save_wakeup_count(unsigned int count);
 extern void pm_wakep_autosleep_enabled(bool set);
@@ -440,6 +478,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
 static inline bool pm_wakeup_pending(void) { return false; }
 static inline void pm_system_wakeup(void) {}
 static inline void pm_wakeup_clear(void) {}
+static inline void pm_system_irq_wakeup(unsigned int irq_number) {}
 
 static inline void lock_system_sleep(void) {}
 static inline void unlock_system_sleep(void) {}
index cb1b9bbda332116b6e2173b011ff9fd58f83f431..b36d837c701ec9fe94280a91df3cf1e359ad50af 100644 (file)
@@ -64,7 +64,7 @@ struct unix_sock {
        struct socket_wq        peer_wq;
 };
 
-static inline struct unix_sock *unix_sk(struct sock *sk)
+static inline struct unix_sock *unix_sk(const struct sock *sk)
 {
        return (struct unix_sock *)sk;
 }
index 186f3a1e1b1f6ddd898d0f5871cb46222ae6b80d..fc19376986259de8faf9c2be4c5c3376780e54ff 100644 (file)
@@ -113,12 +113,12 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
 void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo,
                          bool rearm);
 
-static void inline inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, false);
 }
 
-static void inline inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, true);
 }
index 7aa78440559a47db8e5ccc8ea69a34f87b90c125..e23717013a4e6cb1ef84e6b8ba6654b011ee8670 100644 (file)
@@ -828,6 +828,14 @@ static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *s
        if (sk_rcvqueues_full(sk, limit))
                return -ENOBUFS;
 
+       /*
+        * If the skb was allocated from pfmemalloc reserves, only
+        * allow SOCK_MEMALLOC sockets to use it as this socket is
+        * helping free memory
+        */
+       if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC))
+               return -ENOMEM;
+
        __sk_add_backlog(sk, skb);
        sk->sk_backlog.len += skb->truesize;
        return 0;
index 884e728b09d9a57e8a56ac8ea224b3f873cb81c3..26ede14597daba32f8bf2cfcc84a821d094cc3d3 100644 (file)
@@ -86,7 +86,7 @@
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array),\
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx,\
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
        SNDRV_CTL_ELEM_ACCESS_READWRITE, \
        .tlv.p  = (tlv_array), \
-       .info = snd_soc_info_volsw, \
+       .info = snd_soc_info_volsw_sx, \
        .get = snd_soc_get_volsw_sx, \
        .put = snd_soc_put_volsw_sx, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -574,6 +574,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
 int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_info *uinfo);
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_info *uinfo);
 #define snd_soc_info_bool_ext          snd_ctl_boolean_mono_info
 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol);
index 898be3a8db9aecfc8c9e942e03053b582be3af2a..6d8f8fba33414a40cefc344811ec3acfecd72f01 100644 (file)
 #define WM8904_MIC_REGS  2
 #define WM8904_GPIO_REGS 4
 #define WM8904_DRC_REGS  4
-#define WM8904_EQ_REGS   25
+#define WM8904_EQ_REGS   24
 
 /**
  * DRC configurations are specified with a label and a set of register
index 9df61f1edb0f8048472bee5136f81097e47ac569..3094618d382f4d661dd14f9ceb4f4180a8f2c39d 100644 (file)
  *     SA_RESTORER     0x04000000
  */
 
+#if !defined MINSIGSTKSZ || !defined SIGSTKSZ
 #define MINSIGSTKSZ    2048
 #define SIGSTKSZ       8192
+#endif
 
 #ifndef __ASSEMBLY__
 typedef struct {
index 32e07d8cbaf47cf80841adf0e872d85c26c8c708..036f73bc54cd692763dc04954151d45a28f5e98d 100644 (file)
@@ -323,10 +323,10 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_MPLS,      /* array of struct ovs_key_mpls.
                                 * The implementation may restrict
                                 * the accepted length of the array. */
-       OVS_KEY_ATTR_CT_STATE,  /* u8 bitmask of OVS_CS_F_* */
+       OVS_KEY_ATTR_CT_STATE,  /* u32 bitmask of OVS_CS_F_* */
        OVS_KEY_ATTR_CT_ZONE,   /* u16 connection tracking zone. */
        OVS_KEY_ATTR_CT_MARK,   /* u32 connection tracking mark */
-       OVS_KEY_ATTR_CT_LABEL /* 16-octet connection tracking label */
+       OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
 
 #ifdef __KERNEL__
        OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ip_tunnel_info */
@@ -439,9 +439,9 @@ struct ovs_key_nd {
        __u8    nd_tll[ETH_ALEN];
 };
 
-#define OVS_CT_LABEL_LEN       16
-struct ovs_key_ct_label {
-       __u8    ct_label[OVS_CT_LABEL_LEN];
+#define OVS_CT_LABELS_LEN      16
+struct ovs_key_ct_labels {
+       __u8    ct_labels[OVS_CT_LABELS_LEN];
 };
 
 /* OVS_KEY_ATTR_CT_STATE flags */
@@ -449,9 +449,9 @@ struct ovs_key_ct_label {
 #define OVS_CS_F_ESTABLISHED       0x02 /* Part of an existing connection. */
 #define OVS_CS_F_RELATED           0x04 /* Related to an established
                                         * connection. */
-#define OVS_CS_F_INVALID           0x20 /* Could not track connection. */
-#define OVS_CS_F_REPLY_DIR         0x40 /* Flow is in the reply direction. */
-#define OVS_CS_F_TRACKED           0x80 /* Conntrack has occurred. */
+#define OVS_CS_F_REPLY_DIR         0x08 /* Flow is in the reply direction. */
+#define OVS_CS_F_INVALID           0x10 /* Could not track connection. */
+#define OVS_CS_F_TRACKED           0x20 /* Conntrack has occurred. */
 
 /**
  * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
@@ -618,22 +618,24 @@ struct ovs_action_hash {
 
 /**
  * enum ovs_ct_attr - Attributes for %OVS_ACTION_ATTR_CT action.
- * @OVS_CT_ATTR_FLAGS: u32 connection tracking flags.
+ * @OVS_CT_ATTR_COMMIT: If present, commits the connection to the conntrack
+ * table. This allows future packets for the same connection to be identified
+ * as 'established' or 'related'.
  * @OVS_CT_ATTR_ZONE: u16 connection tracking zone.
  * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the
  * mask, the corresponding bit in the value is copied to the connection
  * tracking mark field in the connection.
- * @OVS_CT_ATTR_LABEL: %OVS_CT_LABEL_LEN value followed by %OVS_CT_LABEL_LEN
+ * @OVS_CT_ATTR_LABEL: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN
  * mask. For each bit set in the mask, the corresponding bit in the value is
  * copied to the connection tracking label field in the connection.
  * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG.
  */
 enum ovs_ct_attr {
        OVS_CT_ATTR_UNSPEC,
-       OVS_CT_ATTR_FLAGS,      /* u8 bitmask of OVS_CT_F_*. */
+       OVS_CT_ATTR_COMMIT,     /* No argument, commits connection. */
        OVS_CT_ATTR_ZONE,       /* u16 zone id. */
        OVS_CT_ATTR_MARK,       /* mark to associate with this connection. */
-       OVS_CT_ATTR_LABEL,      /* label to associate with this connection. */
+       OVS_CT_ATTR_LABELS,     /* labels to associate with this connection. */
        OVS_CT_ATTR_HELPER,     /* netlink helper to assist detection of
                                   related connections. */
        __OVS_CT_ATTR_MAX
@@ -641,14 +643,6 @@ enum ovs_ct_attr {
 
 #define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)
 
-/*
- * OVS_CT_ATTR_FLAGS flags - bitmask of %OVS_CT_F_*
- * @OVS_CT_F_COMMIT: Commits the flow to the conntrack table. This allows
- * future packets for the same connection to be identified as 'established'
- * or 'related'.
- */
-#define OVS_CT_F_COMMIT                0x01
-
 /**
  * enum ovs_action_attr - Action types.
  *
@@ -705,7 +699,7 @@ enum ovs_action_attr {
                                       * data immediately followed by a mask.
                                       * The data must be zero for the unmasked
                                       * bits. */
-       OVS_ACTION_ATTR_CT,           /* One nested OVS_CT_ATTR_* . */
+       OVS_ACTION_ATTR_CT,           /* Nested OVS_CT_ATTR_* . */
 
        __OVS_ACTION_ATTR_MAX,        /* Nothing past this will be accepted
                                       * from userspace. */
index 702024769c74bc39f1e9f8400b23ec5bbd7a8ffb..9d8f5d10c1e553122be08d3407434ea24d19c136 100644 (file)
@@ -160,7 +160,7 @@ struct rtattr {
 
 /* Macros to handle rtattributes */
 
-#define RTA_ALIGNTO    4
+#define RTA_ALIGNTO    4U
 #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
 #define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
                         (rta)->rta_len >= sizeof(struct rtattr) && \
index 7e6512b9dc1ff2682394cdd0fea9a8c6d01cf6e9..be9149f62eb86e63ac06194d4eeaa4065823ea62 100644 (file)
@@ -228,11 +228,7 @@ static void msi_domain_update_chip_ops(struct msi_domain_info *info)
 {
        struct irq_chip *chip = info->chip;
 
-       BUG_ON(!chip);
-       if (!chip->irq_mask)
-               chip->irq_mask = pci_msi_mask_irq;
-       if (!chip->irq_unmask)
-               chip->irq_unmask = pci_msi_unmask_irq;
+       BUG_ON(!chip || !chip->irq_mask || !chip->irq_unmask);
        if (!chip->irq_set_affinity)
                chip->irq_set_affinity = msi_domain_set_affinity;
 }
index 21c62617a35a6dae316b22221b3b4896317faedd..e80c4400118ae7a8e3f09476964260490fccf01a 100644 (file)
@@ -21,7 +21,7 @@ bool irq_pm_check_wakeup(struct irq_desc *desc)
                desc->istate |= IRQS_SUSPENDED | IRQS_PENDING;
                desc->depth++;
                irq_disable(desc);
-               pm_system_wakeup();
+               pm_system_irq_wakeup(irq_desc_get_irq(desc));
                return true;
        }
        return false;
index da98d0593de24206d68222d787d059a5a2b025a1..0277d1216f80ae1adeed84a686ed34c9b2931fc2 100644 (file)
@@ -327,9 +327,13 @@ static void call_usermodehelper_exec_work(struct work_struct *work)
                call_usermodehelper_exec_sync(sub_info);
        } else {
                pid_t pid;
-
+               /*
+                * Use CLONE_PARENT to reparent it to kthreadd; we do not
+                * want to pollute current->children, and we need a parent
+                * that always ignores SIGCHLD to ensure auto-reaping.
+                */
                pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
-                                   SIGCHLD);
+                                   CLONE_PARENT | SIGCHLD);
                if (pid < 0) {
                        sub_info->retval = pid;
                        umh_complete(sub_info);
index 690f78f210f2cf4ec9436c9f37a3bbf5eb876397..b7342a24f559211934fb90db21a4a06d5479b21a 100644 (file)
@@ -733,7 +733,7 @@ int hibernate(void)
  * contents of memory is restored from the saved image.
  *
  * If this is successful, control reappears in the restored target kernel in
- * hibernation_snaphot() which returns to hibernate().  Otherwise, the routine
+ * hibernation_snapshot() which returns to hibernate().  Otherwise, the routine
  * attempts to recover gracefully and make the kernel return to the normal mode
  * of operation.
  */
index 63d395b5df9305b0033e6e294e209bf101e0937b..b2dd4d999900a26edd9cd26fb952b84b98ee411f 100644 (file)
@@ -272,6 +272,22 @@ static inline void pm_print_times_init(void)
 {
        pm_print_times_enabled = !!initcall_debug;
 }
+
+static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
+                                       struct kobj_attribute *attr,
+                                       char *buf)
+{
+       return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
+}
+
+static ssize_t pm_wakeup_irq_store(struct kobject *kobj,
+                                       struct kobj_attribute *attr,
+                                       const char *buf, size_t n)
+{
+       return -EINVAL;
+}
+power_attr(pm_wakeup_irq);
+
 #else /* !CONFIG_PM_SLEEP_DEBUG */
 static inline void pm_print_times_init(void) {}
 #endif /* CONFIG_PM_SLEEP_DEBUG */
@@ -604,6 +620,7 @@ static struct attribute * g[] = {
 #endif
 #ifdef CONFIG_PM_SLEEP_DEBUG
        &pm_print_times_attr.attr,
+       &pm_wakeup_irq_attr.attr,
 #endif
 #endif
 #ifdef CONFIG_FREEZER
index 7e4cda4a8dd9d5386bc657ef0c3a37851417a637..f9fe133c13e24de8e91f4ea81abebe6c58a3fd23 100644 (file)
@@ -35,6 +35,9 @@
 const char *pm_labels[] = { "mem", "standby", "freeze", NULL };
 const char *pm_states[PM_SUSPEND_MAX];
 
+unsigned int pm_suspend_global_flags;
+EXPORT_SYMBOL_GPL(pm_suspend_global_flags);
+
 static const struct platform_suspend_ops *suspend_ops;
 static const struct platform_freeze_ops *freeze_ops;
 static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
@@ -493,6 +496,7 @@ static int enter_state(suspend_state_t state)
 #endif
 
        pr_debug("PM: Preparing system for sleep (%s)\n", pm_states[state]);
+       pm_suspend_clear_flags();
        error = suspend_prepare(state);
        if (error)
                goto Unlock;
index 10a8faa1b0d4a5f737bd9008eb8f9a7e817b6ec9..bcd214e4b4d630eb3304f6000a220dc881bafc24 100644 (file)
@@ -2366,8 +2366,15 @@ void wake_up_new_task(struct task_struct *p)
        trace_sched_wakeup_new(p);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
-       if (p->sched_class->task_woken)
+       if (p->sched_class->task_woken) {
+               /*
+                * Nothing relies on rq->lock after this, so its fine to
+                * drop it.
+                */
+               lockdep_unpin_lock(&rq->lock);
                p->sched_class->task_woken(rq, p);
+               lockdep_pin_lock(&rq->lock);
+       }
 #endif
        task_rq_unlock(rq, p, &flags);
 }
@@ -7238,9 +7245,6 @@ void __init sched_init_smp(void)
        alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL);
        alloc_cpumask_var(&fallback_doms, GFP_KERNEL);
 
-       /* nohz_full won't take effect without isolating the cpus. */
-       tick_nohz_full_add_cpus_to(cpu_isolated_map);
-
        sched_init_numa();
 
        /*
index fc8f01083527a570af73a8f8b4c6e586e7e332f9..8b0a15e285f9121ccd5540fa11eef49c94f017c1 100644 (file)
@@ -668,8 +668,15 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
         * Queueing this task back might have overloaded rq, check if we need
         * to kick someone away.
         */
-       if (has_pushable_dl_tasks(rq))
+       if (has_pushable_dl_tasks(rq)) {
+               /*
+                * Nothing relies on rq->lock after this, so its safe to drop
+                * rq->lock.
+                */
+               lockdep_unpin_lock(&rq->lock);
                push_dl_task(rq);
+               lockdep_pin_lock(&rq->lock);
+       }
 #endif
 
 unlock:
@@ -1066,8 +1073,9 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags)
                int target = find_later_rq(p);
 
                if (target != -1 &&
-                               dl_time_before(p->dl.deadline,
-                                       cpu_rq(target)->dl.earliest_dl.curr))
+                               (dl_time_before(p->dl.deadline,
+                                       cpu_rq(target)->dl.earliest_dl.curr) ||
+                               (cpu_rq(target)->dl.dl_nr_running == 0)))
                        cpu = target;
        }
        rcu_read_unlock();
@@ -1417,7 +1425,8 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq)
 
                later_rq = cpu_rq(cpu);
 
-               if (!dl_time_before(task->dl.deadline,
+               if (later_rq->dl.dl_nr_running &&
+                   !dl_time_before(task->dl.deadline,
                                        later_rq->dl.earliest_dl.curr)) {
                        /*
                         * Target rq has tasks of equal or earlier deadline,
index 6e2e3483b1ecff588e76103e0b7b7d673f16d2a5..9a5e60fe721a5e7e8036508f61950eeb0c8dea31 100644 (file)
@@ -2363,7 +2363,7 @@ static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
         */
        tg_weight = atomic_long_read(&tg->load_avg);
        tg_weight -= cfs_rq->tg_load_avg_contrib;
-       tg_weight += cfs_rq_load_avg(cfs_rq);
+       tg_weight += cfs_rq->load.weight;
 
        return tg_weight;
 }
@@ -2373,7 +2373,7 @@ static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
        long tg_weight, load, shares;
 
        tg_weight = calc_tg_weight(tg, cfs_rq);
-       load = cfs_rq_load_avg(cfs_rq);
+       load = cfs_rq->load.weight;
 
        shares = (tg->shares * load);
        if (tg_weight)
@@ -2664,13 +2664,14 @@ static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
 /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
 static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
 {
-       int decayed;
        struct sched_avg *sa = &cfs_rq->avg;
+       int decayed, removed = 0;
 
        if (atomic_long_read(&cfs_rq->removed_load_avg)) {
                long r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
                sa->load_avg = max_t(long, sa->load_avg - r, 0);
                sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
+               removed = 1;
        }
 
        if (atomic_long_read(&cfs_rq->removed_util_avg)) {
@@ -2688,7 +2689,7 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
        cfs_rq->load_last_update_time_copy = sa->last_update_time;
 #endif
 
-       return decayed;
+       return decayed || removed;
 }
 
 /* Update task and its cfs_rq load average */
index 8f177c73ae199ba41878fea8de9a5b0a7196620a..4a2ef5a02fd3f91d7c4228378c23d5606bb73812 100644 (file)
@@ -57,9 +57,11 @@ static inline int cpu_idle_poll(void)
        rcu_idle_enter();
        trace_cpu_idle_rcuidle(0, smp_processor_id());
        local_irq_enable();
+       stop_critical_timings();
        while (!tif_need_resched() &&
                (cpu_idle_force_poll || tick_check_broadcast_expired()))
                cpu_relax();
+       start_critical_timings();
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
        rcu_idle_exit();
        return 1;
index 3739ac6aa47355e7234cf0ee2fc60ebc3adce979..44d2cc0436f4968a32fb61772e19ca701fccbfb0 100644 (file)
@@ -1251,7 +1251,7 @@ void __init timekeeping_init(void)
        set_normalized_timespec64(&tmp, -boot.tv_sec, -boot.tv_nsec);
        tk_set_wall_to_mono(tk, tmp);
 
-       timekeeping_update(tk, TK_MIRROR);
+       timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
 
        write_seqcount_end(&tk_core.seq);
        raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
index b746399ab59c01e422da63468aa370b1b642a860..8abf1ba18085742af78176dbc514095a47643c9c 100644 (file)
@@ -85,9 +85,19 @@ check_stack(unsigned long ip, unsigned long *stack)
        if (!object_is_on_stack(stack))
                return;
 
+       /* Can't do this from NMI context (can cause deadlocks) */
+       if (in_nmi())
+               return;
+
        local_irq_save(flags);
        arch_spin_lock(&max_stack_lock);
 
+       /*
+        * RCU may not be watching, make it see us.
+        * The stack trace code uses rcu_sched.
+        */
+       rcu_irq_enter();
+
        /* In case another CPU set the tracer_frame on us */
        if (unlikely(!frame_size))
                this_size -= tracer_frame;
@@ -169,6 +179,7 @@ check_stack(unsigned long ip, unsigned long *stack)
        }
 
  out:
+       rcu_irq_exit();
        arch_spin_unlock(&max_stack_lock);
        local_irq_restore(flags);
 }
index ca71582fcfab29ec708746eab636c325b9caef15..bcb14cafe007148b15edb5cfed5adc041a6d966c 100644 (file)
@@ -1458,13 +1458,13 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
        timer_stats_timer_set_start_info(&dwork->timer);
 
        dwork->wq = wq;
+       /* timer isn't guaranteed to run in this cpu, record earlier */
+       if (cpu == WORK_CPU_UNBOUND)
+               cpu = raw_smp_processor_id();
        dwork->cpu = cpu;
        timer->expires = jiffies + delay;
 
-       if (unlikely(cpu != WORK_CPU_UNBOUND))
-               add_timer_on(timer, cpu);
-       else
-               add_timer(timer);
+       add_timer_on(timer, cpu);
 }
 
 /**
index 2e491ac15622a559c88ba12a4067eeb5ca704115..f0df318104e7272ef97641421c938069a047a85e 100644 (file)
@@ -220,6 +220,7 @@ config ZLIB_INFLATE
 
 config ZLIB_DEFLATE
        tristate
+       select BITREVERSE
 
 config LZO_COMPRESS
        tristate
index ab76b99adc857fb38c2e4677b6ab34d6a01fa786..1d1521c26302a2510e873d49a8b6bb525f399d66 100644 (file)
@@ -197,6 +197,7 @@ config ENABLE_MUST_CHECK
 config FRAME_WARN
        int "Warn for stack frames larger than (needs gcc 4.4)"
        range 0 8192
+       default 0 if KASAN
        default 1024 if !64BIT
        default 2048 if 64BIT
        help
index f1cdeb024d172a488e1ed44f70ce1e090ee5e541..6a823a53e357bc83e84476d93cc2c155f0adfee5 100644 (file)
@@ -44,7 +44,7 @@ static void fail_dump(struct fault_attr *attr)
                printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
                       "name %pd, interval %lu, probability %lu, "
                       "space %d, times %d\n", attr->dname,
-                      attr->probability, attr->interval,
+                      attr->interval, attr->probability,
                       atomic_read(&attr->space),
                       atomic_read(&attr->times));
                if (attr->verbose > 1)
index 2df8ddcb0ca0a7f7a055456de4b46a8c55bbfdf1..619984fc07ec32792349c7fe8aec7c8b56e3d2a3 100644 (file)
@@ -480,6 +480,10 @@ static void cgwb_release_workfn(struct work_struct *work)
                                                release_work);
        struct backing_dev_info *bdi = wb->bdi;
 
+       spin_lock_irq(&cgwb_lock);
+       list_del_rcu(&wb->bdi_node);
+       spin_unlock_irq(&cgwb_lock);
+
        wb_shutdown(wb);
 
        css_put(wb->memcg_css);
@@ -575,6 +579,7 @@ static int cgwb_create(struct backing_dev_info *bdi,
                ret = radix_tree_insert(&bdi->cgwb_tree, memcg_css->id, wb);
                if (!ret) {
                        atomic_inc(&bdi->usage_cnt);
+                       list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
                        list_add(&wb->memcg_node, memcg_cgwb_list);
                        list_add(&wb->blkcg_node, blkcg_cgwb_list);
                        css_get(memcg_css);
@@ -676,7 +681,7 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi)
 static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
 {
        struct radix_tree_iter iter;
-       struct bdi_writeback_congested *congested, *congested_n;
+       struct rb_node *rbn;
        void **slot;
 
        WARN_ON(test_bit(WB_registered, &bdi->wb.state));
@@ -686,9 +691,11 @@ static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
        radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0)
                cgwb_kill(*slot);
 
-       rbtree_postorder_for_each_entry_safe(congested, congested_n,
-                                       &bdi->cgwb_congested_tree, rb_node) {
-               rb_erase(&congested->rb_node, &bdi->cgwb_congested_tree);
+       while ((rbn = rb_first(&bdi->cgwb_congested_tree))) {
+               struct bdi_writeback_congested *congested =
+                       rb_entry(rbn, struct bdi_writeback_congested, rb_node);
+
+               rb_erase(rbn, &bdi->cgwb_congested_tree);
                congested->bdi = NULL;  /* mark @congested unlinked */
        }
 
@@ -764,15 +771,22 @@ static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { }
 
 int bdi_init(struct backing_dev_info *bdi)
 {
+       int ret;
+
        bdi->dev = NULL;
 
        bdi->min_ratio = 0;
        bdi->max_ratio = 100;
        bdi->max_prop_frac = FPROP_FRAC_BASE;
        INIT_LIST_HEAD(&bdi->bdi_list);
+       INIT_LIST_HEAD(&bdi->wb_list);
        init_waitqueue_head(&bdi->wb_waitq);
 
-       return cgwb_bdi_init(bdi);
+       ret = cgwb_bdi_init(bdi);
+
+       list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
+
+       return ret;
 }
 EXPORT_SYMBOL(bdi_init);
 
@@ -823,7 +837,7 @@ static void bdi_remove_from_list(struct backing_dev_info *bdi)
        synchronize_rcu_expedited();
 }
 
-void bdi_destroy(struct backing_dev_info *bdi)
+void bdi_unregister(struct backing_dev_info *bdi)
 {
        /* make sure nobody finds us on the bdi_list anymore */
        bdi_remove_from_list(bdi);
@@ -835,9 +849,19 @@ void bdi_destroy(struct backing_dev_info *bdi)
                device_unregister(bdi->dev);
                bdi->dev = NULL;
        }
+}
 
+void bdi_exit(struct backing_dev_info *bdi)
+{
+       WARN_ON_ONCE(bdi->dev);
        wb_exit(&bdi->wb);
 }
+
+void bdi_destroy(struct backing_dev_info *bdi)
+{
+       bdi_unregister(bdi);
+       bdi_exit(bdi);
+}
 EXPORT_SYMBOL(bdi_destroy);
 
 /*
index e7d1db5330254da4a8d265b8784d1eb645693447..4eb56badf37e60e63a5a1badd093d1934a21ad35 100644 (file)
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -361,7 +361,7 @@ err:
  * This function allocates part of contiguous memory on specific
  * contiguous memory area.
  */
-struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align)
+struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
 {
        unsigned long mask, offset, pfn, start = 0;
        unsigned long bitmap_maxno, bitmap_no, bitmap_count;
@@ -371,7 +371,7 @@ struct page *cma_alloc(struct cma *cma, unsigned int count, unsigned int align)
        if (!cma || !cma->count)
                return NULL;
 
-       pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
+       pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma,
                 count, align);
 
        if (!count)
index 1cc5467cf36ce7852f7a0474d5fd3237b3dfff10..327910c2400c6ce36f440383147fdc768cf14692 100644 (file)
@@ -2488,6 +2488,11 @@ again:
                        break;
                }
 
+               if (fatal_signal_pending(current)) {
+                       status = -EINTR;
+                       break;
+               }
+
                status = a_ops->write_begin(file, mapping, pos, bytes, flags,
                                                &page, &fsdata);
                if (unlikely(status < 0))
@@ -2525,10 +2530,6 @@ again:
                written += copied;
 
                balance_dirty_pages_ratelimited(mapping);
-               if (fatal_signal_pending(current)) {
-                       status = -EINTR;
-                       break;
-               }
        } while (iov_iter_count(i));
 
        return written ? written : status;
index 4b06b8db9df23c8f33406586507bbaecf7f5444c..bbac913f96bc1662ac3d7ef37c82080d9c17562f 100644 (file)
@@ -2206,7 +2206,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
        for (_pte = pte; _pte < pte+HPAGE_PMD_NR;
             _pte++, address += PAGE_SIZE) {
                pte_t pteval = *_pte;
-               if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
+               if (pte_none(pteval) || (pte_present(pteval) &&
+                               is_zero_pfn(pte_pfn(pteval)))) {
                        if (!userfaultfd_armed(vma) &&
                            ++none_or_zero <= khugepaged_max_ptes_none)
                                continue;
index 1fedbde68f595c2b83d5aa84962a667c1ada120a..c57c4423c68837d14816c5ff230435e1567e7c20 100644 (file)
@@ -3387,6 +3387,7 @@ static int __mem_cgroup_usage_register_event(struct mem_cgroup *memcg,
        ret = page_counter_memparse(args, "-1", &threshold);
        if (ret)
                return ret;
+       threshold <<= PAGE_SHIFT;
 
        mutex_lock(&memcg->thresholds_lock);
 
@@ -3740,44 +3741,43 @@ struct wb_domain *mem_cgroup_wb_domain(struct bdi_writeback *wb)
 /**
  * mem_cgroup_wb_stats - retrieve writeback related stats from its memcg
  * @wb: bdi_writeback in question
- * @pavail: out parameter for number of available pages
+ * @pfilepages: out parameter for number of file pages
+ * @pheadroom: out parameter for number of allocatable pages according to memcg
  * @pdirty: out parameter for number of dirty pages
  * @pwriteback: out parameter for number of pages under writeback
  *
- * Determine the numbers of available, dirty, and writeback pages in @wb's
- * memcg.  Dirty and writeback are self-explanatory.  Available is a bit
- * more involved.
+ * Determine the numbers of file, headroom, dirty, and writeback pages in
+ * @wb's memcg.  File, dirty and writeback are self-explanatory.  Headroom
+ * is a bit more involved.
  *
- * A memcg's headroom is "min(max, high) - used".  The available memory is
- * calculated as the lowest headroom of itself and the ancestors plus the
- * number of pages already being used for file pages.  Note that this
- * doesn't consider the actual amount of available memory in the system.
- * The caller should further cap *@pavail accordingly.
+ * A memcg's headroom is "min(max, high) - used".  In the hierarchy, the
+ * headroom is calculated as the lowest headroom of itself and the
+ * ancestors.  Note that this doesn't consider the actual amount of
+ * available memory in the system.  The caller should further cap
+ * *@pheadroom accordingly.
  */
-void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pavail,
-                        unsigned long *pdirty, unsigned long *pwriteback)
+void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pfilepages,
+                        unsigned long *pheadroom, unsigned long *pdirty,
+                        unsigned long *pwriteback)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(wb->memcg_css);
        struct mem_cgroup *parent;
-       unsigned long head_room = PAGE_COUNTER_MAX;
-       unsigned long file_pages;
 
        *pdirty = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_DIRTY);
 
        /* this should eventually include NR_UNSTABLE_NFS */
        *pwriteback = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_WRITEBACK);
+       *pfilepages = mem_cgroup_nr_lru_pages(memcg, (1 << LRU_INACTIVE_FILE) |
+                                                    (1 << LRU_ACTIVE_FILE));
+       *pheadroom = PAGE_COUNTER_MAX;
 
-       file_pages = mem_cgroup_nr_lru_pages(memcg, (1 << LRU_INACTIVE_FILE) |
-                                                   (1 << LRU_ACTIVE_FILE));
        while ((parent = parent_mem_cgroup(memcg))) {
                unsigned long ceiling = min(memcg->memory.limit, memcg->high);
                unsigned long used = page_counter_read(&memcg->memory);
 
-               head_room = min(head_room, ceiling - min(ceiling, used));
+               *pheadroom = min(*pheadroom, ceiling - min(ceiling, used));
                memcg = parent;
        }
-
-       *pavail = file_pages + head_room;
 }
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
index 9cb27470fee991cb874676bb0cbc0f694b5e1d36..deb679c31f2ab897cafebf72643aec4f66233308 100644 (file)
@@ -2426,6 +2426,8 @@ void unmap_mapping_range(struct address_space *mapping,
        if (details.last_index < details.first_index)
                details.last_index = ULONG_MAX;
 
+
+       /* DAX uses i_mmap_lock to serialise file truncate vs page fault */
        i_mmap_lock_write(mapping);
        if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
                unmap_mapping_range_tree(&mapping->i_mmap, &details);
index 0a931cdd4f6baaa96cdfab2e0dd668c0abef8809..2c90357c34ea4c4d81521b7bf14d669d6565cc07 100644 (file)
@@ -145,9 +145,6 @@ struct dirty_throttle_control {
        unsigned long           pos_ratio;
 };
 
-#define DTC_INIT_COMMON(__wb)  .wb = (__wb),                           \
-                               .wb_completions = &(__wb)->completions
-
 /*
  * Length of period for aging writeout fractions of bdis. This is an
  * arbitrarily chosen number. The longer the period, the slower fractions will
@@ -157,12 +154,16 @@ struct dirty_throttle_control {
 
 #ifdef CONFIG_CGROUP_WRITEBACK
 
-#define GDTC_INIT(__wb)                .dom = &global_wb_domain,               \
-                               DTC_INIT_COMMON(__wb)
+#define GDTC_INIT(__wb)                .wb = (__wb),                           \
+                               .dom = &global_wb_domain,               \
+                               .wb_completions = &(__wb)->completions
+
 #define GDTC_INIT_NO_WB                .dom = &global_wb_domain
-#define MDTC_INIT(__wb, __gdtc)        .dom = mem_cgroup_wb_domain(__wb),      \
-                               .gdtc = __gdtc,                         \
-                               DTC_INIT_COMMON(__wb)
+
+#define MDTC_INIT(__wb, __gdtc)        .wb = (__wb),                           \
+                               .dom = mem_cgroup_wb_domain(__wb),      \
+                               .wb_completions = &(__wb)->memcg_completions, \
+                               .gdtc = __gdtc
 
 static bool mdtc_valid(struct dirty_throttle_control *dtc)
 {
@@ -213,7 +214,8 @@ static void wb_min_max_ratio(struct bdi_writeback *wb,
 
 #else  /* CONFIG_CGROUP_WRITEBACK */
 
-#define GDTC_INIT(__wb)                DTC_INIT_COMMON(__wb)
+#define GDTC_INIT(__wb)                .wb = (__wb),                           \
+                               .wb_completions = &(__wb)->completions
 #define GDTC_INIT_NO_WB
 #define MDTC_INIT(__wb, __gdtc)
 
@@ -682,13 +684,19 @@ static unsigned long hard_dirty_limit(struct wb_domain *dom,
        return max(thresh, dom->dirty_limit);
 }
 
-/* memory available to a memcg domain is capped by system-wide clean memory */
-static void mdtc_cap_avail(struct dirty_throttle_control *mdtc)
+/*
+ * Memory which can be further allocated to a memcg domain is capped by
+ * system-wide clean memory excluding the amount being used in the domain.
+ */
+static void mdtc_calc_avail(struct dirty_throttle_control *mdtc,
+                           unsigned long filepages, unsigned long headroom)
 {
        struct dirty_throttle_control *gdtc = mdtc_gdtc(mdtc);
-       unsigned long clean = gdtc->avail - min(gdtc->avail, gdtc->dirty);
+       unsigned long clean = filepages - min(filepages, mdtc->dirty);
+       unsigned long global_clean = gdtc->avail - min(gdtc->avail, gdtc->dirty);
+       unsigned long other_clean = global_clean - min(global_clean, clean);
 
-       mdtc->avail = min(mdtc->avail, clean);
+       mdtc->avail = filepages + min(headroom, other_clean);
 }
 
 /**
@@ -1562,16 +1570,16 @@ static void balance_dirty_pages(struct address_space *mapping,
                }
 
                if (mdtc) {
-                       unsigned long writeback;
+                       unsigned long filepages, headroom, writeback;
 
                        /*
                         * If @wb belongs to !root memcg, repeat the same
                         * basic calculations for the memcg domain.
                         */
-                       mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty,
-                                           &writeback);
-                       mdtc_cap_avail(mdtc);
+                       mem_cgroup_wb_stats(wb, &filepages, &headroom,
+                                           &mdtc->dirty, &writeback);
                        mdtc->dirty += writeback;
+                       mdtc_calc_avail(mdtc, filepages, headroom);
 
                        domain_dirty_limits(mdtc);
 
@@ -1893,10 +1901,11 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb)
                return true;
 
        if (mdtc) {
-               unsigned long writeback;
+               unsigned long filepages, headroom, writeback;
 
-               mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty, &writeback);
-               mdtc_cap_avail(mdtc);
+               mem_cgroup_wb_stats(wb, &filepages, &headroom, &mdtc->dirty,
+                                   &writeback);
+               mdtc_calc_avail(mdtc, filepages, headroom);
                domain_dirty_limits(mdtc);      /* ditto, ignore writeback */
 
                if (mdtc->dirty > mdtc->bg_thresh)
@@ -1956,7 +1965,6 @@ void laptop_mode_timer_fn(unsigned long data)
        int nr_pages = global_page_state(NR_FILE_DIRTY) +
                global_page_state(NR_UNSTABLE_NFS);
        struct bdi_writeback *wb;
-       struct wb_iter iter;
 
        /*
         * We want to write everything out, not just down to the dirty
@@ -1965,10 +1973,12 @@ void laptop_mode_timer_fn(unsigned long data)
        if (!bdi_has_dirty_io(&q->backing_dev_info))
                return;
 
-       bdi_for_each_wb(wb, &q->backing_dev_info, &iter, 0)
+       rcu_read_lock();
+       list_for_each_entry_rcu(wb, &q->backing_dev_info.wb_list, bdi_node)
                if (wb_has_dirty_io(wb))
                        wb_start_writeback(wb, nr_pages, true,
                                           WB_REASON_LAPTOP_TIMER);
+       rcu_read_unlock();
 }
 
 /*
index 60cd846a9a4401f73a6a51539507ecc22fb308d4..24682f6f4cfd1d84d7245faea0da78e7fd17e716 100644 (file)
@@ -89,8 +89,8 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
        while (!list_empty(pages)) {
                page = list_to_page(pages);
                list_del(&page->lru);
-               if (add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+               if (add_to_page_cache_lru(page, mapping, page->index,
+                               GFP_KERNEL & mapping_gfp_mask(mapping))) {
                        read_cache_pages_invalidate_page(mapping, page);
                        continue;
                }
@@ -127,8 +127,8 @@ static int read_pages(struct address_space *mapping, struct file *filp,
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                struct page *page = list_to_page(pages);
                list_del(&page->lru);
-               if (!add_to_page_cache_lru(page, mapping,
-                                       page->index, GFP_KERNEL)) {
+               if (!add_to_page_cache_lru(page, mapping, page->index,
+                               GFP_KERNEL & mapping_gfp_mask(mapping))) {
                        mapping->a_ops->readpage(filp, page);
                }
                page_cache_release(page);
index 4f5cd974e11a0adbb8a601cc92b9866ab6d67d55..fbf14485a0498bf181e81f43bc69a0522e67afd5 100644 (file)
@@ -1363,15 +1363,16 @@ static cpumask_var_t cpu_stat_off;
 
 static void vmstat_update(struct work_struct *w)
 {
-       if (refresh_cpu_vm_stats())
+       if (refresh_cpu_vm_stats()) {
                /*
                 * Counters were updated so we expect more updates
                 * to occur in the future. Keep on running the
                 * update worker thread.
                 */
-               schedule_delayed_work(this_cpu_ptr(&vmstat_work),
+               schedule_delayed_work_on(smp_processor_id(),
+                       this_cpu_ptr(&vmstat_work),
                        round_jiffies_relative(sysctl_stat_interval));
-       else {
+       else {
                /*
                 * We did not update any counters so the app may be in
                 * a mode where it does not cause counter updates.
index b4548c739a6475446d643bd5b01ab8627ef1f08e..2dda439c8cb83b7fa72b238dcf93023088762001 100644 (file)
@@ -91,10 +91,50 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
         * autoconnect action, remove them completely. If they are, just unmark
         * them as waiting for connection, by clearing explicit_connect field.
         */
-       if (params->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+       params->explicit_connect = false;
+
+       list_del_init(&params->action);
+
+       switch (params->auto_connect) {
+       case HCI_AUTO_CONN_EXPLICIT:
                hci_conn_params_del(conn->hdev, bdaddr, bdaddr_type);
-       else
-               params->explicit_connect = false;
+               /* return instead of break to avoid duplicate scan update */
+               return;
+       case HCI_AUTO_CONN_DIRECT:
+       case HCI_AUTO_CONN_ALWAYS:
+               list_add(&params->action, &conn->hdev->pend_le_conns);
+               break;
+       case HCI_AUTO_CONN_REPORT:
+               list_add(&params->action, &conn->hdev->pend_le_reports);
+               break;
+       default:
+               break;
+       }
+
+       hci_update_background_scan(conn->hdev);
+}
+
+static void hci_conn_cleanup(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
+               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
+
+       hci_chan_list_flush(conn);
+
+       hci_conn_hash_del(hdev, conn);
+
+       if (hdev->notify)
+               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+
+       hci_conn_del_sysfs(conn);
+
+       debugfs_remove_recursive(conn->debugfs);
+
+       hci_dev_put(hdev);
+
+       hci_conn_put(conn);
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -102,8 +142,13 @@ static void hci_connect_le_scan_remove(struct hci_conn *conn)
 {
        hci_connect_le_scan_cleanup(conn);
 
-       hci_conn_hash_del(conn->hdev, conn);
-       hci_update_background_scan(conn->hdev);
+       /* We can't call hci_conn_del here since that would deadlock
+        * with trying to call cancel_delayed_work_sync(&conn->disc_work).
+        * Instead, call just hci_conn_cleanup() which contains the bare
+        * minimum cleanup operations needed for a connection in this
+        * state.
+        */
+       hci_conn_cleanup(conn);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
@@ -581,27 +626,17 @@ int hci_conn_del(struct hci_conn *conn)
                }
        }
 
-       hci_chan_list_flush(conn);
-
        if (conn->amp_mgr)
                amp_mgr_put(conn->amp_mgr);
 
-       hci_conn_hash_del(hdev, conn);
-       if (hdev->notify)
-               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
-
        skb_queue_purge(&conn->data_q);
 
-       hci_conn_del_sysfs(conn);
-
-       debugfs_remove_recursive(conn->debugfs);
-
-       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
-               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
-
-       hci_dev_put(hdev);
-
-       hci_conn_put(conn);
+       /* Remove the connection from the list and cleanup its remaining
+        * state. This is a separate function since for some cases like
+        * BT_CONNECT_SCAN we *only* want the cleanup part without the
+        * rest of hci_conn_del.
+        */
+       hci_conn_cleanup(conn);
 
        return 0;
 }
@@ -973,15 +1008,23 @@ static int hci_explicit_conn_params_set(struct hci_request *req,
        if (is_connected(hdev, addr, addr_type))
                return -EISCONN;
 
-       params = hci_conn_params_add(hdev, addr, addr_type);
-       if (!params)
-               return -EIO;
+       params = hci_conn_params_lookup(hdev, addr, addr_type);
+       if (!params) {
+               params = hci_conn_params_add(hdev, addr, addr_type);
+               if (!params)
+                       return -ENOMEM;
 
-       /* If we created new params, or existing params were marked as disabled,
-        * mark them to be used just once to connect.
-        */
-       if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               /* If we created new params, mark them to be deleted in
+                * hci_connect_le_scan_cleanup. It's different case than
+                * existing disabled params, those will stay after cleanup.
+                */
                params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+       }
+
+       /* We're trying to connect, so make sure params are at pend_le_conns */
+       if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+           params->auto_connect == HCI_AUTO_CONN_REPORT ||
+           params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                list_del_init(&params->action);
                list_add(&params->action, &hdev->pend_le_conns);
        }
index adcbc74c243268e8330bf760c39fa792a1c2a3a8..e837539452fb0e2880d8335da7769752a3b08110 100644 (file)
@@ -2861,13 +2861,6 @@ struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
                        return param;
        }
 
-       list_for_each_entry(param, &hdev->pend_le_reports, action) {
-               if (bacmp(&param->addr, addr) == 0 &&
-                   param->addr_type == addr_type &&
-                   param->explicit_connect)
-                       return param;
-       }
-
        return NULL;
 }
 
index 186041866315a4e107de086df52142f39d6c6ee3..bc31099d3b5bd113a8496b2ccad9e3e40364187f 100644 (file)
@@ -55,7 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
        wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
        hci_dev_lock(hdev);
-       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       /* Set discovery state to stopped if we're not doing LE active
+        * scanning.
+        */
+       if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+           hdev->le_scan_type != LE_SCAN_ACTIVE)
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
        hci_dev_unlock(hdev);
 
        hci_conn_check_pending(hdev);
@@ -4648,8 +4653,8 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
        /* If we're not connectable only connect devices that we have in
         * our pend_le_conns list.
         */
-       params = hci_explicit_connect_lookup(hdev, addr, addr_type);
-
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
+                                          addr_type);
        if (!params)
                return NULL;
 
index ccaf5a436d8f7a70799729a04ffc17583d11913f..c4fe2fee753fcfaa4233a4bb6675bbbdd29fc9d5 100644 (file)
@@ -3545,6 +3545,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                                       auth_type);
        } else {
                u8 addr_type;
+               struct hci_conn_params *p;
 
                /* Convert from L2CAP channel address type to HCI address type
                 */
@@ -3562,7 +3563,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                 * If connection parameters already exist, then they
                 * will be kept and this function does nothing.
                 */
-               hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+               p = hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+
+               if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+                       p->auto_connect = HCI_AUTO_CONN_DISABLED;
 
                conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
                                           addr_type, sec_level,
@@ -6117,14 +6121,21 @@ static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr,
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_REPORT:
-               list_add(&params->action, &hdev->pend_le_reports);
+               if (params->explicit_connect)
+                       list_add(&params->action, &hdev->pend_le_conns);
+               else
+                       list_add(&params->action, &hdev->pend_le_reports);
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_DIRECT:
        case HCI_AUTO_CONN_ALWAYS:
                if (!is_connected(hdev, addr, addr_type)) {
                        list_add(&params->action, &hdev->pend_le_conns);
-                       __hci_update_background_scan(req);
+                       /* If we are in scan phase of connecting, we were
+                        * already added to pend_le_conns and scanning.
+                        */
+                       if (params->auto_connect != HCI_AUTO_CONN_EXPLICIT)
+                               __hci_update_background_scan(req);
                }
                break;
        }
@@ -6379,7 +6390,8 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        goto unlock;
                }
 
-               if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+                   params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                        err = cmd->cmd_complete(cmd,
                                                MGMT_STATUS_INVALID_PARAMS);
                        mgmt_pending_remove(cmd);
@@ -6415,6 +6427,10 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
                                continue;
                        device_removed(sk, hdev, &p->addr, p->addr_type);
+                       if (p->explicit_connect) {
+                               p->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+                               continue;
+                       }
                        list_del(&p->action);
                        list_del(&p->list);
                        kfree(p);
index 80b94e37c94aae115155454b9f4386a1b91021de..f79ccac6699fb7b171b680261db9000f7fe4c70c 100644 (file)
@@ -285,6 +285,7 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
        switch (op->op) {
        case CEPH_OSD_OP_READ:
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
                ceph_osd_data_release(&op->extent.osd_data);
                break;
        case CEPH_OSD_OP_CALL:
@@ -485,13 +486,14 @@ void osd_req_op_extent_init(struct ceph_osd_request *osd_req,
        size_t payload_len = 0;
 
        BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE &&
-              opcode != CEPH_OSD_OP_ZERO && opcode != CEPH_OSD_OP_TRUNCATE);
+              opcode != CEPH_OSD_OP_WRITEFULL && opcode != CEPH_OSD_OP_ZERO &&
+              opcode != CEPH_OSD_OP_TRUNCATE);
 
        op->extent.offset = offset;
        op->extent.length = length;
        op->extent.truncate_size = truncate_size;
        op->extent.truncate_seq = truncate_seq;
-       if (opcode == CEPH_OSD_OP_WRITE)
+       if (opcode == CEPH_OSD_OP_WRITE || opcode == CEPH_OSD_OP_WRITEFULL)
                payload_len += length;
 
        op->payload_len = payload_len;
@@ -670,9 +672,11 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                break;
        case CEPH_OSD_OP_READ:
        case CEPH_OSD_OP_WRITE:
+       case CEPH_OSD_OP_WRITEFULL:
        case CEPH_OSD_OP_ZERO:
        case CEPH_OSD_OP_TRUNCATE:
-               if (src->op == CEPH_OSD_OP_WRITE)
+               if (src->op == CEPH_OSD_OP_WRITE ||
+                   src->op == CEPH_OSD_OP_WRITEFULL)
                        request_data_len = src->extent.length;
                dst->extent.offset = cpu_to_le64(src->extent.offset);
                dst->extent.length = cpu_to_le64(src->extent.length);
@@ -681,7 +685,8 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
                dst->extent.truncate_seq =
                        cpu_to_le32(src->extent.truncate_seq);
                osd_data = &src->extent.osd_data;
-               if (src->op == CEPH_OSD_OP_WRITE)
+               if (src->op == CEPH_OSD_OP_WRITE ||
+                   src->op == CEPH_OSD_OP_WRITEFULL)
                        ceph_osdc_msg_data_add(req->r_request, osd_data);
                else
                        ceph_osdc_msg_data_add(req->r_reply, osd_data);
index b495ab1797fae303d12a3251f09b141052c1ff55..29edf74846fc9cfef49f3fc35b4ba41de6c254af 100644 (file)
@@ -1284,7 +1284,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
 
        gstrings.len = ret;
 
-       data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
+       data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
        if (!data)
                return -ENOMEM;
 
index 05a04ea871728d2c18f68571321e9435df1f3b18..bb18c368000129ebea752a0a78785524848eaab8 100644 (file)
@@ -1415,6 +1415,7 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5)
                return dev_forward_skb(dev, skb2);
 
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        return dev_queue_xmit(skb2);
 }
 
@@ -1854,9 +1855,13 @@ int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
                goto out;
 
        /* We're copying the filter that has been originally attached,
-        * so no conversion/decode needed anymore.
+        * so no conversion/decode needed anymore. eBPF programs that
+        * have no original program cannot be dumped through this.
         */
+       ret = -EACCES;
        fprog = filter->prog->orig_prog;
+       if (!fprog)
+               goto out;
 
        ret = fprog->len;
        if (!len)
index c59fa5d9c22c449b4bfa9f058575d44324cfd7f9..adb5325f49348412efb50f0eeee5a5f0fa1e50ed 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
 #include <linux/sysfs.h>
+#include <linux/phy_fixed.h>
 #include "dsa_priv.h"
 
 char dsa_driver_version[] = "0.1";
@@ -305,7 +306,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
        if (ret < 0)
                goto out;
 
-       ds->slave_mii_bus = mdiobus_alloc();
+       ds->slave_mii_bus = devm_mdiobus_alloc(parent);
        if (ds->slave_mii_bus == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -314,7 +315,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        ret = mdiobus_register(ds->slave_mii_bus);
        if (ret < 0)
-               goto out_free;
+               goto out;
 
 
        /*
@@ -367,10 +368,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        return ret;
 
-out_free:
-       mdiobus_free(ds->slave_mii_bus);
 out:
-       kfree(ds);
        return ret;
 }
 
@@ -400,7 +398,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
        /*
         * Allocate and initialise switch state.
         */
-       ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
+       ds = devm_kzalloc(parent, sizeof(*ds) + drv->priv_size, GFP_KERNEL);
        if (ds == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -420,10 +418,47 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 
 static void dsa_switch_destroy(struct dsa_switch *ds)
 {
+       struct device_node *port_dn;
+       struct phy_device *phydev;
+       struct dsa_chip_data *cd = ds->pd;
+       int port;
+
 #ifdef CONFIG_NET_DSA_HWMON
        if (ds->hwmon_dev)
                hwmon_device_unregister(ds->hwmon_dev);
 #endif
+
+       /* Disable configuration of the CPU and DSA ports */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
+                       continue;
+
+               port_dn = cd->port_dn[port];
+               if (of_phy_is_fixed_link(port_dn)) {
+                       phydev = of_phy_find_device(port_dn);
+                       if (phydev) {
+                               int addr = phydev->addr;
+
+                               phy_device_free(phydev);
+                               of_node_put(port_dn);
+                               fixed_phy_del(addr);
+                       }
+               }
+       }
+
+       /* Destroy network devices for physical switch ports. */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(ds->phys_port_mask & (1 << port)))
+                       continue;
+
+               if (!ds->ports[port])
+                       continue;
+
+               unregister_netdev(ds->ports[port]);
+               free_netdev(ds->ports[port]);
+       }
+
+       mdiobus_unregister(ds->slave_mii_bus);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -802,10 +837,11 @@ static inline void dsa_of_remove(struct device *dev)
 }
 #endif
 
-static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
-                         struct device *parent, struct dsa_platform_data *pd)
+static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
+                        struct device *parent, struct dsa_platform_data *pd)
 {
        int i;
+       unsigned configured = 0;
 
        dst->pd = pd;
        dst->master_netdev = dev;
@@ -825,8 +861,16 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->ds[i] = ds;
                if (ds->drv->poll_link != NULL)
                        dst->link_poll_needed = 1;
+
+               ++configured;
        }
 
+       /*
+        * If no switch was found, exit cleanly
+        */
+       if (!configured)
+               return -EPROBE_DEFER;
+
        /*
         * If we use a tagging format that doesn't have an ethertype
         * field, make sure that all packets from this point on get
@@ -843,6 +887,8 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->link_poll_timer.expires = round_jiffies(jiffies + HZ);
                add_timer(&dst->link_poll_timer);
        }
+
+       return 0;
 }
 
 static int dsa_probe(struct platform_device *pdev)
@@ -883,7 +929,7 @@ static int dsa_probe(struct platform_device *pdev)
                goto out;
        }
 
-       dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+       dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
        if (dst == NULL) {
                dev_put(dev);
                ret = -ENOMEM;
@@ -892,7 +938,9 @@ static int dsa_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dst);
 
-       dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       if (ret)
+               goto out;
 
        return 0;
 
@@ -914,7 +962,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
        for (i = 0; i < dst->pd->nr_chips; i++) {
                struct dsa_switch *ds = dst->ds[i];
 
-               if (ds != NULL)
+               if (ds)
                        dsa_switch_destroy(ds);
        }
 }
index f03db8b7abee68806468c104470da4054a8bf755..0c9c3482e41997a671c23be7dc0387edb1403916 100644 (file)
@@ -312,7 +312,7 @@ static void arp_send_dst(int type, int ptype, __be32 dest_ip,
        if (!skb)
                return;
 
-       skb_dst_set(skb, dst);
+       skb_dst_set(skb, dst_clone(dst));
        arp_xmit(skb);
 }
 
@@ -384,7 +384,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
        }
 
        if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
-               dst = dst_clone(skb_dst(skb));
+               dst = skb_dst(skb);
        arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
                     dst_hw, dev->dev_addr, NULL, dst);
 }
@@ -811,7 +811,7 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
                                } else {
                                        pneigh_enqueue(&arp_tbl,
                                                       in_dev->arp_parms, skb);
-                                       return 0;
+                                       goto out_free_dst;
                                }
                                goto out;
                        }
@@ -865,6 +865,8 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
 
 out:
        consume_skb(skb);
+out_free_dst:
+       dst_release(reply_dst);
        return 0;
 }
 
index 7bb9c39e0a4d1a6a30b7aece9d3b0c17e447c20a..61b45a17fc738e17146a5e1f1cf97774f338179e 100644 (file)
@@ -577,21 +577,22 @@ EXPORT_SYMBOL(inet_rtx_syn_ack);
 static bool reqsk_queue_unlink(struct request_sock_queue *queue,
                               struct request_sock *req)
 {
-       struct listen_sock *lopt = queue->listen_opt;
        struct request_sock **prev;
+       struct listen_sock *lopt;
        bool found = false;
 
        spin_lock(&queue->syn_wait_lock);
-
-       for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
-            prev = &(*prev)->dl_next) {
-               if (*prev == req) {
-                       *prev = req->dl_next;
-                       found = true;
-                       break;
+       lopt = queue->listen_opt;
+       if (lopt) {
+               for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
+                    prev = &(*prev)->dl_next) {
+                       if (*prev == req) {
+                               *prev = req->dl_next;
+                               found = true;
+                               break;
+                       }
                }
        }
-
        spin_unlock(&queue->syn_wait_lock);
        if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
                reqsk_put(req);
index 900113376d4e0e528dc5a5d349687ae908ca08d6..36b85bd05ac8a320b1b910c7d3454da1139ecd3c 100644 (file)
@@ -3119,6 +3119,8 @@ static void addrconf_gre_config(struct net_device *dev)
        }
 
        addrconf_addr_gen(idev, true);
+       if (dev->flags & IFF_POINTOPOINT)
+               addrconf_add_mroute(dev);
 }
 #endif
 
index 92b1aa38f121507b662e2c964423952bf995b81e..61d403ee1031caa5536d9298abd4604606dff6f5 100644 (file)
@@ -376,6 +376,9 @@ int ip6_forward(struct sk_buff *skb)
        if (skb->pkt_type != PACKET_HOST)
                goto drop;
 
+       if (unlikely(skb->sk))
+               goto drop;
+
        if (skb_warn_if_lro(skb))
                goto drop;
 
index cb32ce250db0c0fd8cdc19a066f3956a893f2fba..968f31c01f89e8ccc6a4a13c056f8be3dcc0b7c6 100644 (file)
@@ -142,6 +142,9 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
        struct net_device *loopback_dev = net->loopback_dev;
        int cpu;
 
+       if (dev == loopback_dev)
+               return;
+
        for_each_possible_cpu(cpu) {
                struct uncached_list *ul = per_cpu_ptr(&rt6_uncached_list, cpu);
                struct rt6_info *rt;
@@ -151,14 +154,12 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
                        struct inet6_dev *rt_idev = rt->rt6i_idev;
                        struct net_device *rt_dev = rt->dst.dev;
 
-                       if (rt_idev && (rt_idev->dev == dev || !dev) &&
-                           rt_idev->dev != loopback_dev) {
+                       if (rt_idev->dev == dev) {
                                rt->rt6i_idev = in6_dev_get(loopback_dev);
                                in6_dev_put(rt_idev);
                        }
 
-                       if (rt_dev && (rt_dev == dev || !dev) &&
-                           rt_dev != loopback_dev) {
+                       if (rt_dev == dev) {
                                rt->dst.dev = loopback_dev;
                                dev_hold(rt->dst.dev);
                                dev_put(rt_dev);
@@ -247,12 +248,6 @@ static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
 {
 }
 
-static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
-                                        unsigned long old)
-{
-       return NULL;
-}
-
 static struct dst_ops ip6_dst_blackhole_ops = {
        .family                 =       AF_INET6,
        .destroy                =       ip6_dst_destroy,
@@ -261,7 +256,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .default_advmss         =       ip6_default_advmss,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .redirect               =       ip6_rt_blackhole_redirect,
-       .cow_metrics            =       ip6_rt_blackhole_cow_metrics,
+       .cow_metrics            =       dst_cow_metrics_generic,
        .neigh_lookup           =       ip6_neigh_lookup,
 };
 
@@ -318,6 +313,15 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
 
 #endif
 
+static void rt6_info_init(struct rt6_info *rt)
+{
+       struct dst_entry *dst = &rt->dst;
+
+       memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
+       INIT_LIST_HEAD(&rt->rt6i_siblings);
+       INIT_LIST_HEAD(&rt->rt6i_uncached);
+}
+
 /* allocate dst with ip6_dst_ops */
 static struct rt6_info *__ip6_dst_alloc(struct net *net,
                                        struct net_device *dev,
@@ -326,13 +330,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net,
        struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
                                        0, DST_OBSOLETE_FORCE_CHK, flags);
 
-       if (rt) {
-               struct dst_entry *dst = &rt->dst;
+       if (rt)
+               rt6_info_init(rt);
 
-               memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
-               INIT_LIST_HEAD(&rt->rt6i_siblings);
-               INIT_LIST_HEAD(&rt->rt6i_uncached);
-       }
        return rt;
 }
 
@@ -1213,24 +1213,20 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
 
        rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
        if (rt) {
-               new = &rt->dst;
-
-               memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
+               rt6_info_init(rt);
 
+               new = &rt->dst;
                new->__use = 1;
                new->input = dst_discard;
                new->output = dst_discard_sk;
 
-               if (dst_metrics_read_only(&ort->dst))
-                       new->_metrics = ort->dst._metrics;
-               else
-                       dst_copy_metrics(new, &ort->dst);
+               dst_copy_metrics(new, &ort->dst);
                rt->rt6i_idev = ort->rt6i_idev;
                if (rt->rt6i_idev)
                        in6_dev_hold(rt->rt6i_idev);
 
                rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags;
+               rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
                rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -2622,7 +2618,8 @@ void rt6_ifdown(struct net *net, struct net_device *dev)
 
        fib6_clean_all(net, fib6_ifdown, &adn);
        icmp6_clean_all(fib6_ifdown, &adn);
-       rt6_uncached_list_flush_dev(net, dev);
+       if (dev)
+               rt6_uncached_list_flush_dev(net, dev);
 }
 
 struct rt6_mtu_change_arg {
index 30caa289c5dbf589270768ce90d15f2990341231..5cedfda4b241045e92fe89971836e549b88f5074 100644 (file)
@@ -37,6 +37,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
+       fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
        memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
        if (saddr)
                memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
index ced6bf3be8d6cf5d3d9fc80b6c46f48c4e567aef..1560c8482bcb9fd587d1e278a499f99fd9958803 100644 (file)
@@ -149,7 +149,7 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 
        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
                if (test_bit(i, local->hw.flags))
-                       pos += scnprintf(pos, end - pos, "%s",
+                       pos += scnprintf(pos, end - pos, "%s\n",
                                         hw_flag_names[i]);
        }
 
index 8ba5832435095f10e94f782e07d92a4f742cad3a..3ed7ddfbf8e840d4c910b0e9452c06843031c91d 100644 (file)
@@ -101,6 +101,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
         * when it wakes up for the next time.
         */
        set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
+       ieee80211_clear_fast_xmit(sta);
 
        /*
         * This code races in the following way:
index 84e0e8c7fb236952dfc1cfcb23204623e80d7867..7892eb8ed4c8b1fa416ebcb297fab9f1cce91743 100644 (file)
@@ -1218,8 +1218,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
        if (!tx->sta)
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+               ieee80211_check_fast_xmit(tx->sta);
+       }
 
        info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
 
@@ -2451,7 +2453,8 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
 
        if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
            test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-           test_sta_flag(sta, WLAN_STA_PS_DELIVER))
+           test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
+           test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
                goto out;
 
        if (sdata->noack_map)
index 8f060d7f9a0e107a410d3ffe71722f49059f7bc8..0a49a8c7c56432989de924e01563f692cf10e545 100644 (file)
@@ -2785,6 +2785,7 @@ static int netlink_dump(struct sock *sk)
        struct sk_buff *skb = NULL;
        struct nlmsghdr *nlh;
        int len, err = -ENOBUFS;
+       int alloc_min_size;
        int alloc_size;
 
        mutex_lock(nlk->cb_mutex);
@@ -2793,9 +2794,6 @@ static int netlink_dump(struct sock *sk)
                goto errout_skb;
        }
 
-       cb = &nlk->cb;
-       alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
-
        if (!netlink_rx_is_mmaped(sk) &&
            atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
                goto errout_skb;
@@ -2805,23 +2803,35 @@ static int netlink_dump(struct sock *sk)
         * to reduce number of system calls on dump operations, if user
         * ever provided a big enough buffer.
         */
-       if (alloc_size < nlk->max_recvmsg_len) {
-               skb = netlink_alloc_skb(sk,
-                                       nlk->max_recvmsg_len,
-                                       nlk->portid,
+       cb = &nlk->cb;
+       alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
+
+       if (alloc_min_size < nlk->max_recvmsg_len) {
+               alloc_size = nlk->max_recvmsg_len;
+               skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL |
                                        __GFP_NOWARN |
                                        __GFP_NORETRY);
-               /* available room should be exact amount to avoid MSG_TRUNC */
-               if (skb)
-                       skb_reserve(skb, skb_tailroom(skb) -
-                                        nlk->max_recvmsg_len);
        }
-       if (!skb)
+       if (!skb) {
+               alloc_size = alloc_min_size;
                skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL);
+       }
        if (!skb)
                goto errout_skb;
+
+       /* Trim skb to allocated size. User is expected to provide buffer as
+        * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
+        * netlink_recvmsg())). dump will pack as many smaller messages as
+        * could fit within the allocated skb. skb is typically allocated
+        * with larger space than required (could be as much as near 2x the
+        * requested size with align to next power of 2 approach). Allowing
+        * dump to use the excess space makes it difficult for a user to have a
+        * reasonable static buffer based on the expected largest dump of a
+        * single netdev. The outcome is MSG_TRUNC error.
+        */
+       skb_reserve(skb, skb_tailroom(skb) - alloc_size);
        netlink_skb_set_owner_r(skb, sk);
 
        len = cb->dump(skb, cb);
index 315f5330b6e5400eaf28ce7d0290038b7113a6fd..c6a39bf2c3b954481a7217fa2b0f95778a2376b8 100644 (file)
@@ -684,7 +684,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
 {
        if (skb_network_offset(skb) > MAX_L2_LEN) {
                OVS_NLERR(1, "L2 header too long to fragment");
-               return;
+               goto err;
        }
 
        if (ethertype == htons(ETH_P_IP)) {
@@ -708,8 +708,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                struct rt6_info ovs_rt;
 
                if (!v6ops) {
-                       kfree_skb(skb);
-                       return;
+                       goto err;
                }
 
                prepare_frag(vport, skb);
@@ -728,8 +727,12 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.",
                          ovs_vport_name(vport), ntohs(ethertype), mru,
                          vport->dev->mtu);
-               kfree_skb(skb);
+               goto err;
        }
+
+       return;
+err:
+       kfree_skb(skb);
 }
 
 static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
@@ -968,7 +971,7 @@ static int execute_masked_set_action(struct sk_buff *skb,
        case OVS_KEY_ATTR_CT_STATE:
        case OVS_KEY_ATTR_CT_ZONE:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
                err = -EINVAL;
                break;
        }
@@ -1099,6 +1102,12 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case OVS_ACTION_ATTR_CT:
+                       if (!is_flow_key_valid(key)) {
+                               err = ovs_flow_key_update(skb, key);
+                               if (err)
+                                       return err;
+                       }
+
                        err = ovs_ct_execute(ovs_dp_get_net(dp), skb, key,
                                             nla_data(a));
 
index 002a755fa07ea8c6c71c762716a5be8700c0a36c..80bf702715bb3e8875ded486dbff63d86d7797f8 100644 (file)
@@ -37,9 +37,9 @@ struct md_mark {
 };
 
 /* Metadata label for masked write to conntrack label. */
-struct md_label {
-       struct ovs_key_ct_label value;
-       struct ovs_key_ct_label mask;
+struct md_labels {
+       struct ovs_key_ct_labels value;
+       struct ovs_key_ct_labels mask;
 };
 
 /* Conntrack action context for execution. */
@@ -47,10 +47,10 @@ struct ovs_conntrack_info {
        struct nf_conntrack_helper *helper;
        struct nf_conntrack_zone zone;
        struct nf_conn *ct;
-       u32 flags;
+       u8 commit : 1;
        u16 family;
        struct md_mark mark;
-       struct md_label label;
+       struct md_labels labels;
 };
 
 static u16 key_to_nfproto(const struct sw_flow_key *key)
@@ -109,21 +109,21 @@ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
 #endif
 }
 
-static void ovs_ct_get_label(const struct nf_conn *ct,
-                            struct ovs_key_ct_label *label)
+static void ovs_ct_get_labels(const struct nf_conn *ct,
+                             struct ovs_key_ct_labels *labels)
 {
        struct nf_conn_labels *cl = ct ? nf_ct_labels_find(ct) : NULL;
 
        if (cl) {
                size_t len = cl->words * sizeof(long);
 
-               if (len > OVS_CT_LABEL_LEN)
-                       len = OVS_CT_LABEL_LEN;
-               else if (len < OVS_CT_LABEL_LEN)
-                       memset(label, 0, OVS_CT_LABEL_LEN);
-               memcpy(label, cl->bits, len);
+               if (len > OVS_CT_LABELS_LEN)
+                       len = OVS_CT_LABELS_LEN;
+               else if (len < OVS_CT_LABELS_LEN)
+                       memset(labels, 0, OVS_CT_LABELS_LEN);
+               memcpy(labels, cl->bits, len);
        } else {
-               memset(label, 0, OVS_CT_LABEL_LEN);
+               memset(labels, 0, OVS_CT_LABELS_LEN);
        }
 }
 
@@ -134,7 +134,7 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
        key->ct.state = state;
        key->ct.zone = zone->id;
        key->ct.mark = ovs_ct_get_mark(ct);
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
 }
 
 /* Update 'key' based on skb->nfct. If 'post_ct' is true, then OVS has
@@ -167,7 +167,7 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
 
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
 {
-       if (nla_put_u8(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
+       if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
@@ -179,8 +179,8 @@ int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_KEY_ATTR_CT_LABEL, sizeof(key->ct.label),
-                   &key->ct.label))
+           nla_put(skb, OVS_KEY_ATTR_CT_LABELS, sizeof(key->ct.labels),
+                   &key->ct.labels))
                return -EMSGSIZE;
 
        return 0;
@@ -213,9 +213,9 @@ static int ovs_ct_set_mark(struct sk_buff *skb, struct sw_flow_key *key,
 #endif
 }
 
-static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
-                           const struct ovs_key_ct_label *label,
-                           const struct ovs_key_ct_label *mask)
+static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
+                            const struct ovs_key_ct_labels *labels,
+                            const struct ovs_key_ct_labels *mask)
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn_labels *cl;
@@ -235,15 +235,15 @@ static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
                nf_ct_labels_ext_add(ct);
                cl = nf_ct_labels_find(ct);
        }
-       if (!cl || cl->words * sizeof(long) < OVS_CT_LABEL_LEN)
+       if (!cl || cl->words * sizeof(long) < OVS_CT_LABELS_LEN)
                return -ENOSPC;
 
-       err = nf_connlabels_replace(ct, (u32 *)label, (u32 *)mask,
-                                   OVS_CT_LABEL_LEN / sizeof(u32));
+       err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
+                                   OVS_CT_LABELS_LEN / sizeof(u32));
        if (err)
                return err;
 
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
        return 0;
 }
 
@@ -465,12 +465,12 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
        return 0;
 }
 
-static bool label_nonzero(const struct ovs_key_ct_label *label)
+static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
 {
        size_t i;
 
-       for (i = 0; i < sizeof(*label); i++)
-               if (label->ct_label[i])
+       for (i = 0; i < sizeof(*labels); i++)
+               if (labels->ct_labels[i])
                        return true;
 
        return false;
@@ -493,7 +493,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                        return err;
        }
 
-       if (info->flags & OVS_CT_F_COMMIT)
+       if (info->commit)
                err = ovs_ct_commit(net, key, info, skb);
        else
                err = ovs_ct_lookup(net, key, info, skb);
@@ -506,9 +506,9 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                if (err)
                        goto err;
        }
-       if (label_nonzero(&info->label.mask))
-               err = ovs_ct_set_label(skb, key, &info->label.value,
-                                      &info->label.mask);
+       if (labels_nonzero(&info->labels.mask))
+               err = ovs_ct_set_labels(skb, key, &info->labels.value,
+                                       &info->labels.mask);
 err:
        skb_push(skb, nh_ofs);
        return err;
@@ -539,14 +539,13 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
 }
 
 static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = {
-       [OVS_CT_ATTR_FLAGS]     = { .minlen = sizeof(u32),
-                                   .maxlen = sizeof(u32) },
+       [OVS_CT_ATTR_COMMIT]    = { .minlen = 0, .maxlen = 0 },
        [OVS_CT_ATTR_ZONE]      = { .minlen = sizeof(u16),
                                    .maxlen = sizeof(u16) },
        [OVS_CT_ATTR_MARK]      = { .minlen = sizeof(struct md_mark),
                                    .maxlen = sizeof(struct md_mark) },
-       [OVS_CT_ATTR_LABEL]     = { .minlen = sizeof(struct md_label),
-                                   .maxlen = sizeof(struct md_label) },
+       [OVS_CT_ATTR_LABELS]    = { .minlen = sizeof(struct md_labels),
+                                   .maxlen = sizeof(struct md_labels) },
        [OVS_CT_ATTR_HELPER]    = { .minlen = 1,
                                    .maxlen = NF_CT_HELPER_NAME_LEN }
 };
@@ -576,8 +575,8 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                }
 
                switch (type) {
-               case OVS_CT_ATTR_FLAGS:
-                       info->flags = nla_get_u32(a);
+               case OVS_CT_ATTR_COMMIT:
+                       info->commit = true;
                        break;
 #ifdef CONFIG_NF_CONNTRACK_ZONES
                case OVS_CT_ATTR_ZONE:
@@ -593,10 +592,10 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                }
 #endif
 #ifdef CONFIG_NF_CONNTRACK_LABELS
-               case OVS_CT_ATTR_LABEL: {
-                       struct md_label *label = nla_data(a);
+               case OVS_CT_ATTR_LABELS: {
+                       struct md_labels *labels = nla_data(a);
 
-                       info->label = *label;
+                       info->labels = *labels;
                        break;
                }
 #endif
@@ -633,7 +632,7 @@ bool ovs_ct_verify(struct net *net, enum ovs_key_attr attr)
            attr == OVS_KEY_ATTR_CT_MARK)
                return true;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           attr == OVS_KEY_ATTR_CT_LABEL) {
+           attr == OVS_KEY_ATTR_CT_LABELS) {
                struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
                return ovs_net->xt_label;
@@ -701,7 +700,7 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
        if (!start)
                return -EMSGSIZE;
 
-       if (nla_put_u32(skb, OVS_CT_ATTR_FLAGS, ct_info->flags))
+       if (ct_info->commit && nla_put_flag(skb, OVS_CT_ATTR_COMMIT))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
            nla_put_u16(skb, OVS_CT_ATTR_ZONE, ct_info->zone.id))
@@ -711,8 +710,8 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
                    &ct_info->mark))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_CT_ATTR_LABEL, sizeof(ct_info->label),
-                   &ct_info->label))
+           nla_put(skb, OVS_CT_ATTR_LABELS, sizeof(ct_info->labels),
+                   &ct_info->labels))
                return -EMSGSIZE;
        if (ct_info->helper) {
                if (nla_put_string(skb, OVS_CT_ATTR_HELPER,
@@ -737,7 +736,7 @@ void ovs_ct_free_action(const struct nlattr *a)
 
 void ovs_ct_init(struct net *net)
 {
-       unsigned int n_bits = sizeof(struct ovs_key_ct_label) * BITS_PER_BYTE;
+       unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
        struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
        if (nf_connlabels_get(net, n_bits)) {
index 43f5dd7a55774414aeb7aad8c0560db3e0596035..da8714942c95f73803aa48a157484e898651bc8f 100644 (file)
@@ -34,6 +34,13 @@ int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *,
 void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb);
 void ovs_ct_free_action(const struct nlattr *a);
+
+static inline bool ovs_ct_state_supported(u32 state)
+{
+       return !(state & ~(OVS_CS_F_NEW | OVS_CS_F_ESTABLISHED |
+                        OVS_CS_F_RELATED | OVS_CS_F_REPLY_DIR |
+                        OVS_CS_F_INVALID | OVS_CS_F_TRACKED));
+}
 #else
 #include <linux/errno.h>
 
@@ -46,6 +53,11 @@ static inline bool ovs_ct_verify(struct net *net, int attr)
        return false;
 }
 
+static inline bool ovs_ct_state_supported(u32 state)
+{
+       return false;
+}
+
 static inline int ovs_ct_copy_action(struct net *net, const struct nlattr *nla,
                                     const struct sw_flow_key *key,
                                     struct sw_flow_actions **acts, bool log)
@@ -72,7 +84,7 @@ static inline void ovs_ct_fill_key(const struct sk_buff *skb,
        key->ct.state = 0;
        key->ct.zone = 0;
        key->ct.mark = 0;
-       memset(&key->ct.label, 0, sizeof(key->ct.label));
+       memset(&key->ct.labels, 0, sizeof(key->ct.labels));
 }
 
 static inline int ovs_ct_put_key(const struct sw_flow_key *key,
index fe527d2dd4b7ae9d6b31a7d9d92586d1cd276c26..8cfa15a08668804a2a74c0047662694f23acbb80 100644 (file)
@@ -116,7 +116,7 @@ struct sw_flow_key {
                u16 zone;
                u32 mark;
                u8 state;
-               struct ovs_key_ct_label label;
+               struct ovs_key_ct_labels labels;
        } ct;
 
 } __aligned(BITS_PER_LONG/8); /* Ensure that we can do comparisons as longs. */
index 5c030a4d73382f6123345f4a6b608ea1b1684ae0..171a691f1c3218ed1a63ac9151c95475ef7fcade 100644 (file)
@@ -291,10 +291,10 @@ size_t ovs_key_attr_size(void)
                + nla_total_size(4)   /* OVS_KEY_ATTR_SKB_MARK */
                + nla_total_size(4)   /* OVS_KEY_ATTR_DP_HASH */
                + nla_total_size(4)   /* OVS_KEY_ATTR_RECIRC_ID */
-               + nla_total_size(1)   /* OVS_KEY_ATTR_CT_STATE */
+               + nla_total_size(4)   /* OVS_KEY_ATTR_CT_STATE */
                + nla_total_size(2)   /* OVS_KEY_ATTR_CT_ZONE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_CT_MARK */
-               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABEL */
+               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABELS */
                + nla_total_size(12)  /* OVS_KEY_ATTR_ETHERNET */
                + nla_total_size(2)   /* OVS_KEY_ATTR_ETHERTYPE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_VLAN */
@@ -349,10 +349,10 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_TUNNEL]    = { .len = OVS_ATTR_NESTED,
                                     .next = ovs_tunnel_key_lens, },
        [OVS_KEY_ATTR_MPLS]      = { .len = sizeof(struct ovs_key_mpls) },
-       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u8) },
+       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u32) },
        [OVS_KEY_ATTR_CT_ZONE]   = { .len = sizeof(u16) },
        [OVS_KEY_ATTR_CT_MARK]   = { .len = sizeof(u32) },
-       [OVS_KEY_ATTR_CT_LABEL]  = { .len = sizeof(struct ovs_key_ct_label) },
+       [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) },
 };
 
 static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -814,7 +814,13 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 
        if (*attrs & (1 << OVS_KEY_ATTR_CT_STATE) &&
            ovs_ct_verify(net, OVS_KEY_ATTR_CT_STATE)) {
-               u8 ct_state = nla_get_u8(a[OVS_KEY_ATTR_CT_STATE]);
+               u32 ct_state = nla_get_u32(a[OVS_KEY_ATTR_CT_STATE]);
+
+               if (!is_mask && !ovs_ct_state_supported(ct_state)) {
+                       OVS_NLERR(log, "ct_state flags %08x unsupported",
+                                 ct_state);
+                       return -EINVAL;
+               }
 
                SW_FLOW_KEY_PUT(match, ct.state, ct_state, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
@@ -833,14 +839,14 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
                SW_FLOW_KEY_PUT(match, ct.mark, mark, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_MARK);
        }
-       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABEL) &&
-           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABEL)) {
-               const struct ovs_key_ct_label *cl;
+       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABELS) &&
+           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABELS)) {
+               const struct ovs_key_ct_labels *cl;
 
-               cl = nla_data(a[OVS_KEY_ATTR_CT_LABEL]);
-               SW_FLOW_KEY_MEMCPY(match, ct.label, cl->ct_label,
+               cl = nla_data(a[OVS_KEY_ATTR_CT_LABELS]);
+               SW_FLOW_KEY_MEMCPY(match, ct.labels, cl->ct_labels,
                                   sizeof(*cl), is_mask);
-               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABEL);
+               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABELS);
        }
        return 0;
 }
@@ -1973,7 +1979,7 @@ static int validate_set(const struct nlattr *a,
        case OVS_KEY_ATTR_PRIORITY:
        case OVS_KEY_ATTR_SKB_MARK:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
        case OVS_KEY_ATTR_ETHERNET:
                break;
 
index f2ea83ba47631d4f650aa3dcf2f9c66cf4fd1c6f..c7f74aab34b9ef7d2befcd571d44290b76fbfbc1 100644 (file)
@@ -93,7 +93,8 @@ struct sw_flow *ovs_flow_alloc(void)
 
        /* Initialize the default stat node. */
        stats = kmem_cache_alloc_node(flow_stats_cache,
-                                     GFP_KERNEL | __GFP_ZERO, 0);
+                                     GFP_KERNEL | __GFP_ZERO,
+                                     node_online(0) ? 0 : NUMA_NO_NODE);
        if (!stats)
                goto err;
 
index dc81dc619aa2344a5c7912def9d6852fcd37ebda..12a36ac21edaaeddf50442408a1ea27aca975fa0 100644 (file)
@@ -280,35 +280,19 @@ void ovs_vport_del(struct vport *vport)
  */
 void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
 {
-       struct net_device *dev = vport->dev;
-       int i;
-
-       memset(stats, 0, sizeof(*stats));
-       stats->rx_errors  = dev->stats.rx_errors;
-       stats->tx_errors  = dev->stats.tx_errors;
-       stats->tx_dropped = dev->stats.tx_dropped;
-       stats->rx_dropped = dev->stats.rx_dropped;
-
-       stats->rx_dropped += atomic_long_read(&dev->rx_dropped);
-       stats->tx_dropped += atomic_long_read(&dev->tx_dropped);
-
-       for_each_possible_cpu(i) {
-               const struct pcpu_sw_netstats *percpu_stats;
-               struct pcpu_sw_netstats local_stats;
-               unsigned int start;
-
-               percpu_stats = per_cpu_ptr(dev->tstats, i);
-
-               do {
-                       start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
-                       local_stats = *percpu_stats;
-               } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
-
-               stats->rx_bytes         += local_stats.rx_bytes;
-               stats->rx_packets       += local_stats.rx_packets;
-               stats->tx_bytes         += local_stats.tx_bytes;
-               stats->tx_packets       += local_stats.tx_packets;
-       }
+       const struct rtnl_link_stats64 *dev_stats;
+       struct rtnl_link_stats64 temp;
+
+       dev_stats = dev_get_stats(vport->dev, &temp);
+       stats->rx_errors  = dev_stats->rx_errors;
+       stats->tx_errors  = dev_stats->tx_errors;
+       stats->tx_dropped = dev_stats->tx_dropped;
+       stats->rx_dropped = dev_stats->rx_dropped;
+
+       stats->rx_bytes   = dev_stats->rx_bytes;
+       stats->rx_packets = dev_stats->rx_packets;
+       stats->tx_bytes   = dev_stats->tx_bytes;
+       stats->tx_packets = dev_stats->tx_packets;
 }
 
 /**
@@ -460,6 +444,15 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
 
        OVS_CB(skb)->input_vport = vport;
        OVS_CB(skb)->mru = 0;
+       if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
+               u32 mark;
+
+               mark = skb->mark;
+               skb_scrub_packet(skb, true);
+               skb->mark = mark;
+               tun_info = NULL;
+       }
+
        /* Extract flow from 'skb' into 'key'. */
        error = ovs_flow_key_extract(tun_info, skb, &key);
        if (unlikely(error)) {
index 2d1be4a760fdc4361f23d0aa93a861298eaafe45..32fcdecdb9e2074bad6f3e3002738e9c289317c3 100644 (file)
 
 #define MIRRED_TAB_MASK     7
 static LIST_HEAD(mirred_list);
+static DEFINE_SPINLOCK(mirred_list_lock);
 
 static void tcf_mirred_release(struct tc_action *a, int bind)
 {
        struct tcf_mirred *m = to_mirred(a);
        struct net_device *dev = rcu_dereference_protected(m->tcfm_dev, 1);
 
+       /* We could be called either in a RCU callback or with RTNL lock held. */
+       spin_lock_bh(&mirred_list_lock);
        list_del(&m->tcfm_list);
+       spin_unlock_bh(&mirred_list_lock);
        if (dev)
                dev_put(dev);
 }
@@ -103,10 +107,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        } else {
                if (bind)
                        return 0;
-               if (!ovr) {
-                       tcf_hash_release(a, bind);
+
+               tcf_hash_release(a, bind);
+               if (!ovr)
                        return -EEXIST;
-               }
        }
        m = to_mirred(a);
 
@@ -123,7 +127,9 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        }
 
        if (ret == ACT_P_CREATED) {
+               spin_lock_bh(&mirred_list_lock);
                list_add(&m->tcfm_list, &mirred_list);
+               spin_unlock_bh(&mirred_list_lock);
                tcf_hash_insert(a);
        }
 
@@ -173,6 +179,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 
        skb2->skb_iif = skb->dev->ifindex;
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        err = dev_queue_xmit(skb2);
 
        if (err) {
@@ -221,7 +228,8 @@ static int mirred_device_event(struct notifier_block *unused,
        struct tcf_mirred *m;
 
        ASSERT_RTNL();
-       if (event == NETDEV_UNREGISTER)
+       if (event == NETDEV_UNREGISTER) {
+               spin_lock_bh(&mirred_list_lock);
                list_for_each_entry(m, &mirred_list, tcfm_list) {
                        if (rcu_access_pointer(m->tcfm_dev) == dev) {
                                dev_put(dev);
@@ -231,6 +239,8 @@ static int mirred_device_event(struct notifier_block *unused,
                                RCU_INIT_POINTER(m->tcfm_dev, NULL);
                        }
                }
+               spin_unlock_bh(&mirred_list_lock);
+       }
 
        return NOTIFY_DONE;
 }
index 9d15cb6b8cb1f5e8424e96f6245e9dd206d92405..86b04e31e60b76027214b85ee0c4c0e0de1b04c4 100644 (file)
@@ -368,6 +368,15 @@ static unsigned int hhf_drop(struct Qdisc *sch)
        return bucket - q->buckets;
 }
 
+static unsigned int hhf_qdisc_drop(struct Qdisc *sch)
+{
+       unsigned int prev_backlog;
+
+       prev_backlog = sch->qstats.backlog;
+       hhf_drop(sch);
+       return prev_backlog - sch->qstats.backlog;
+}
+
 static int hhf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct hhf_sched_data *q = qdisc_priv(sch);
@@ -696,7 +705,7 @@ static struct Qdisc_ops hhf_qdisc_ops __read_mostly = {
        .enqueue        =       hhf_enqueue,
        .dequeue        =       hhf_dequeue,
        .peek           =       qdisc_peek_dequeued,
-       .drop           =       hhf_drop,
+       .drop           =       hhf_qdisc_drop,
        .init           =       hhf_init,
        .reset          =       hhf_reset,
        .destroy        =       hhf_destroy,
index 5f6ca47092b039a1c927420a51b851a83047b5fc..f0c3ff67ca987427136baebf67034ad3bf58a27f 100644 (file)
@@ -533,7 +533,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
        rqstp->rq_arg.page_base = head->arg.page_base;
 
        /* rq_respages starts after the last arg page */
-       rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
+       rqstp->rq_respages = &rqstp->rq_pages[page_no];
        rqstp->rq_next_page = rqstp->rq_respages + 1;
 
        /* Rebuild rq_arg head and tail. */
index 8a477e27bad75f4b9a6c8feeceb745ffe9407c71..5502d4dade74aa8646f89305b011d215294352e0 100644 (file)
@@ -543,11 +543,8 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        }
 
        if (memreg == RPCRDMA_FRMR) {
-               /* Requires both frmr reg and local dma lkey */
-               if (((devattr->device_cap_flags &
-                    (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) !=
-                   (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) ||
-                     (devattr->max_fast_reg_page_list_len == 0)) {
+               if (!(devattr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) ||
+                   (devattr->max_fast_reg_page_list_len == 0)) {
                        dprintk("RPC:       %s: FRMR registration "
                                "not supported by HCA\n", __func__);
                        memreg = RPCRDMA_MTHCAFMR;
@@ -557,6 +554,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
                if (!ia->ri_device->alloc_fmr) {
                        dprintk("RPC:       %s: MTHCAFMR registration "
                                "not supported by HCA\n", __func__);
+                       rc = -EINVAL;
                        goto out3;
                }
        }
index fda38f830a10869713177220f8d2066c6076da0c..77f5d17e261230a6db4f261445311eafb37c7b06 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
 #include <net/ip_fib.h>
 #include <net/switchdev.h>
 
@@ -634,6 +635,8 @@ static int switchdev_port_br_afspec(struct net_device *dev,
                if (nla_len(attr) != sizeof(struct bridge_vlan_info))
                        return -EINVAL;
                vinfo = nla_data(attr);
+               if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
+                       return -EINVAL;
                vlan->flags = vinfo->flags;
                if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
                        if (vlan->vid_begin)
index a82c5848d4bc22129bd1e6ba7f677795febdc9e9..5351a3f97e8ecf17e545459344a8b315f522045a 100644 (file)
@@ -357,7 +357,7 @@ static inline u32 msg_importance(struct tipc_msg *m)
        if (likely((usr <= TIPC_CRITICAL_IMPORTANCE) && !msg_errcode(m)))
                return usr;
        if ((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER))
-               return msg_bits(m, 5, 13, 0x7);
+               return msg_bits(m, 9, 0, 0x7);
        return TIPC_SYSTEM_IMPORTANCE;
 }
 
@@ -366,7 +366,7 @@ static inline void msg_set_importance(struct tipc_msg *m, u32 i)
        int usr = msg_user(m);
 
        if (likely((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER)))
-               msg_set_bits(m, 5, 13, 0x7, i);
+               msg_set_bits(m, 9, 0, 0x7, i);
        else if (i < TIPC_SYSTEM_IMPORTANCE)
                msg_set_user(m, i);
        else
index 703875fd6cde204ddeaf630b9a6bd11daec6dbfa..2c32a83037a3614ef09fb4b29c8f3337dcdf0f45 100644 (file)
@@ -1116,7 +1116,7 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        }
 
        /* Ignore duplicate packets */
-       if (less(oseqno, rcv_nxt))
+       if ((usr != LINK_PROTOCOL) && less(oseqno, rcv_nxt))
                return true;
 
        /* Initiate or update failover mode if applicable */
@@ -1146,8 +1146,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        if (!pl || !tipc_link_is_up(pl))
                return true;
 
-       /* Initiate or update synch mode if applicable */
-       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG)) {
+       /* Initiate synch mode if applicable */
+       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
                syncpt = iseqno + exp_pkts - 1;
                if (!tipc_link_is_up(l)) {
                        tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT);
index ef31b40ad55000a5fd029d7479b546483cc782b3..94f658235fb49a0c644a84867302cc00a75243d5 100644 (file)
@@ -2064,6 +2064,11 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
                goto out;
        }
 
+       if (flags & MSG_PEEK)
+               skip = sk_peek_offset(sk, flags);
+       else
+               skip = 0;
+
        do {
                int chunk;
                struct sk_buff *skb, *last;
@@ -2112,7 +2117,6 @@ unlock:
                        break;
                }
 
-               skip = sk_peek_offset(sk, flags);
                while (skip >= unix_skb_len(skb)) {
                        skip -= unix_skb_len(skb);
                        last = skb;
@@ -2179,14 +2183,12 @@ unlock:
                        if (UNIXCB(skb).fp)
                                scm.fp = scm_fp_dup(UNIXCB(skb).fp);
 
-                       if (skip) {
-                               sk_peek_offset_fwd(sk, chunk);
-                               skip -= chunk;
-                       }
+                       sk_peek_offset_fwd(sk, chunk);
 
                        if (UNIXCB(skb).fp)
                                break;
 
+                       skip = 0;
                        last = skb;
                        last_len = skb->len;
                        unix_state_lock(sk);
index 0cd46e129920e8ad114eb335ae92ce85230d068d..b967e4f9fed2e6cc78b9538c79517a473fc375b8 100755 (executable)
@@ -115,7 +115,7 @@ esac
 BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
 
 # Setup the directory structure
-rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir"
+rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
 mkdir -m 755 -p "$tmpdir/DEBIAN"
 mkdir -p "$tmpdir/lib" "$tmpdir/boot"
 mkdir -p "$fwdir/lib/firmware/$version/"
@@ -408,7 +408,7 @@ binary-arch:
        \$(MAKE) KDEB_SOURCENAME=${sourcename} KDEB_PKGVERSION=${packageversion} bindeb-pkg
 
 clean:
-       rm -rf debian/*tmp
+       rm -rf debian/*tmp debian/files
        mv debian/ debian.backup # debian/ might be cleaned away
        \$(MAKE) clean
        mv debian.backup debian
index 39eac1fd5706c6370df8b18fe5ac42e85e1b2ed3..addf060399e09547307d9c023f36d8dbf869a931 100644 (file)
@@ -134,8 +134,10 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
                kdebug("- %u", key->serial);
                key_check(key);
 
-               /* Throw away the key data */
-               if (key->type->destroy)
+               /* Throw away the key data if the key is instantiated */
+               if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
+                   !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
+                   key->type->destroy)
                        key->type->destroy(key);
 
                security_key_free(key);
index 486ef6fa393b2cc9d8ceb8cb11f187f97730bd90..0d625312427831b63ed18784719cd0b424f03a41 100644 (file)
@@ -440,6 +440,9 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
 
        kenter("");
 
+       if (ctx->index_key.type == &key_type_keyring)
+               return ERR_PTR(-EPERM);
+       
        user = key_user_lookup(current_fsuid());
        if (!user)
                return ERR_PTR(-ENOMEM);
index 4449d1a990893db4078a102b9da0f92835d5add3..2433f7c81472848be51b9af420ec198b523871b1 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <sound/hdaudio_ext.h>
 
 MODULE_DESCRIPTION("HDA extended core");
index 37f43a1b34ef1f5f48682230055c0f01d9a07449..a249d5486889dca683af566e0818d95ee49b12ae 100644 (file)
@@ -3367,10 +3367,8 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
        int dev, err;
 
        err = snd_hda_codec_parse_pcms(codec);
-       if (err < 0) {
-               snd_hda_codec_reset(codec);
+       if (err < 0)
                return err;
-       }
 
        /* attach a new PCM streams */
        list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
index ca03c40609fcf09d8838ed05f4920de3f03a6cf7..2f0ec7c45fc70d6232339761e5773349d24213a9 100644 (file)
@@ -819,6 +819,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
        SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
+       SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
index 3c2f0f8d6266e358a667aa376fea3d094829845a..f823eb502367dccad4b93e71ac7e06d30c0bccdf 100644 (file)
@@ -50,24 +50,24 @@ struct rt298_priv {
 };
 
 static struct reg_default rt298_index_def[] = {
-       { 0x01, 0xaaaa },
-       { 0x02, 0x8aaa },
+       { 0x01, 0xa5a8 },
+       { 0x02, 0x8e95 },
        { 0x03, 0x0002 },
-       { 0x04, 0xaf01 },
-       { 0x08, 0x000d },
-       { 0x09, 0xd810 },
-       { 0x0a, 0x0120 },
+       { 0x04, 0xaf67 },
+       { 0x08, 0x200f },
+       { 0x09, 0xd010 },
+       { 0x0a, 0x0100 },
        { 0x0b, 0x0000 },
        { 0x0d, 0x2800 },
-       { 0x0f, 0x0000 },
-       { 0x19, 0x0a17 },
+       { 0x0f, 0x0022 },
+       { 0x19, 0x0217 },
        { 0x20, 0x0020 },
        { 0x33, 0x0208 },
        { 0x46, 0x0300 },
-       { 0x49, 0x0004 },
-       { 0x4f, 0x50e9 },
-       { 0x50, 0x2000 },
-       { 0x63, 0x2902 },
+       { 0x49, 0x4004 },
+       { 0x4f, 0x50c9 },
+       { 0x50, 0x3000 },
+       { 0x63, 0x1b02 },
        { 0x67, 0x1111 },
        { 0x68, 0x1016 },
        { 0x69, 0x273f },
@@ -1214,7 +1214,7 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
        mdelay(10);
 
        if (!rt298->pdata.gpio2_en)
-               regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x4000);
+               regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x40);
        else
                regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0);
 
index 2fbc6ef8cbdb394fd4ffa2b612f50d111fcdc4e5..39ebd7bf4f5306382c86fb49f3417dc3c908dcad 100644 (file)
@@ -3808,6 +3808,8 @@ static int wm8962_runtime_resume(struct device *dev)
 
        wm8962_reset(wm8962);
 
+       regcache_mark_dirty(wm8962->regmap);
+
        /* SYSCLK defaults to on; make sure it is off so we can safely
         * write to registers if the device is declocked.
         */
index 100d92b5b77ef92da6a7e64efd58ffde1437f769..05977ae1ff2a3250c3fe2043b8124f9370dd1542 100644 (file)
@@ -206,6 +206,34 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
 }
 EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
 
+/**
+ * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
+ * @kcontrol: mixer control
+ * @uinfo: control element information
+ *
+ * Callback to provide information about a single mixer control, or a double
+ * mixer control that spans 2 registers of the SX TLV type. SX TLV controls
+ * have a range that represents both positive and negative values either side
+ * of zero but without a sign bit.
+ *
+ * Returns 0 for success.
+ */
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+                         struct snd_ctl_elem_info *uinfo)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+
+       snd_soc_info_volsw(kcontrol, uinfo);
+       /* Max represents the number of levels in an SX control not the
+        * maximum value, so add the minimum value back on
+        */
+       uinfo->value.integer.max += mc->min;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx);
+
 /**
  * snd_soc_get_volsw - single mixer get callback
  * @kcontrol: mixer control
index a37f9702b2a90433978f4a6715919c4a9f8e11e6..a1c62de42a3bc479e04818df981885eb2e458a47 100644 (file)
@@ -150,7 +150,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
                strcat(filename, instance_str);
        }
 
-       strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+       strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 
        if (gbl_verbose_mode) {
                acpi_log_error
index d1b6475095967fb029af77ed69956c28b7828226..6cae06117b55297e031a210129e7f5a3f9d4c053 100644 (file)
 
 #define FIXUP_SECTION ".ex_fixup"
 
+static inline unsigned long __fls(unsigned long x);
+
 #include "word-at-a-time.h"
 
 #include "utils.h"
 
+static inline unsigned long __fls(unsigned long x)
+{
+       int lz;
+
+       asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
+       return sizeof(unsigned long) - 1 - lz;
+}
 
 static int page_size;
 static char *mem_region;
index 48c6e1ac6827f14be7eaede56bfd1ae3d185d217..b9d3a32cbc048ddb7c1c885fb3af523f97944fbc 100644 (file)
@@ -137,6 +137,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+       bool phys_active;
+       int ret;
 
        /*
         * We're about to run this vcpu again, so there is no need to
@@ -151,6 +153,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
         */
        if (kvm_timer_should_fire(vcpu))
                kvm_timer_inject_irq(vcpu);
+
+       /*
+        * We keep track of whether the edge-triggered interrupt has been
+        * signalled to the vgic/guest, and if so, we mask the interrupt and
+        * the physical distributor to prevent the timer from raising a
+        * physical interrupt whenever we run a guest, preventing forward
+        * VCPU progress.
+        */
+       if (kvm_vgic_get_phys_irq_active(timer->map))
+               phys_active = true;
+       else
+               phys_active = false;
+
+       ret = irq_set_irqchip_state(timer->map->irq,
+                                   IRQCHIP_STATE_ACTIVE,
+                                   phys_active);
+       WARN_ON(ret);
 }
 
 /**
index 6bd1c9bf7ae71504d042f455bce8ad9ca6abf6fc..66c66165e712d743ed3da1a501c03a087f442378 100644 (file)
@@ -531,6 +531,34 @@ bool vgic_handle_set_pending_reg(struct kvm *kvm,
        return false;
 }
 
+/*
+ * If a mapped interrupt's state has been modified by the guest such that it
+ * is no longer active or pending, without it have gone through the sync path,
+ * then the map->active field must be cleared so the interrupt can be taken
+ * again.
+ */
+static void vgic_handle_clear_mapped_irq(struct kvm_vcpu *vcpu)
+{
+       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+       struct list_head *root;
+       struct irq_phys_map_entry *entry;
+       struct irq_phys_map *map;
+
+       rcu_read_lock();
+
+       /* Check for PPIs */
+       root = &vgic_cpu->irq_phys_map_list;
+       list_for_each_entry_rcu(entry, root, entry) {
+               map = &entry->map;
+
+               if (!vgic_dist_irq_is_pending(vcpu, map->virt_irq) &&
+                   !vgic_irq_is_active(vcpu, map->virt_irq))
+                       map->active = false;
+       }
+
+       rcu_read_unlock();
+}
+
 bool vgic_handle_clear_pending_reg(struct kvm *kvm,
                                   struct kvm_exit_mmio *mmio,
                                   phys_addr_t offset, int vcpu_id)
@@ -561,6 +589,7 @@ bool vgic_handle_clear_pending_reg(struct kvm *kvm,
                                          vcpu_id, offset);
                vgic_reg_access(mmio, reg, offset, mode);
 
+               vgic_handle_clear_mapped_irq(kvm_get_vcpu(kvm, vcpu_id));
                vgic_update_state(kvm);
                return true;
        }
@@ -598,6 +627,7 @@ bool vgic_handle_clear_active_reg(struct kvm *kvm,
                        ACCESS_READ_VALUE | ACCESS_WRITE_CLEARBIT);
 
        if (mmio->is_write) {
+               vgic_handle_clear_mapped_irq(kvm_get_vcpu(kvm, vcpu_id));
                vgic_update_state(kvm);
                return true;
        }
@@ -982,6 +1012,12 @@ static int compute_pending_for_cpu(struct kvm_vcpu *vcpu)
        pend_percpu = vcpu->arch.vgic_cpu.pending_percpu;
        pend_shared = vcpu->arch.vgic_cpu.pending_shared;
 
+       if (!dist->enabled) {
+               bitmap_zero(pend_percpu, VGIC_NR_PRIVATE_IRQS);
+               bitmap_zero(pend_shared, nr_shared);
+               return 0;
+       }
+
        pending = vgic_bitmap_get_cpu_map(&dist->irq_pending, vcpu_id);
        enabled = vgic_bitmap_get_cpu_map(&dist->irq_enabled, vcpu_id);
        bitmap_and(pend_percpu, pending, enabled, VGIC_NR_PRIVATE_IRQS);
@@ -1009,11 +1045,6 @@ void vgic_update_state(struct kvm *kvm)
        struct kvm_vcpu *vcpu;
        int c;
 
-       if (!dist->enabled) {
-               set_bit(0, dist->irq_pending_on_cpu);
-               return;
-       }
-
        kvm_for_each_vcpu(c, vcpu, kvm) {
                if (compute_pending_for_cpu(vcpu))
                        set_bit(c, dist->irq_pending_on_cpu);
@@ -1092,6 +1123,15 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
 
+       /*
+        * We must transfer the pending state back to the distributor before
+        * retiring the LR, otherwise we may loose edge-triggered interrupts.
+        */
+       if (vlr.state & LR_STATE_PENDING) {
+               vgic_dist_irq_set_pending(vcpu, irq);
+               vlr.hwirq = 0;
+       }
+
        vlr.state = 0;
        vgic_set_lr(vcpu, lr_nr, vlr);
        clear_bit(lr_nr, vgic_cpu->lr_used);
@@ -1132,7 +1172,8 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
                kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
                vgic_irq_clear_active(vcpu, irq);
                vgic_update_state(vcpu->kvm);
-       } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
+       } else {
+               WARN_ON(!vgic_dist_irq_is_pending(vcpu, irq));
                vlr.state |= LR_STATE_PENDING;
                kvm_debug("Set pending: 0x%x\n", vlr.state);
        }
@@ -1240,7 +1281,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
        unsigned long *pa_percpu, *pa_shared;
-       int i, vcpu_id, lr, ret;
+       int i, vcpu_id;
        int overflow = 0;
        int nr_shared = vgic_nr_shared_irqs(dist);
 
@@ -1295,31 +1336,6 @@ epilog:
                 */
                clear_bit(vcpu_id, dist->irq_pending_on_cpu);
        }
-
-       for (lr = 0; lr < vgic->nr_lr; lr++) {
-               struct vgic_lr vlr;
-
-               if (!test_bit(lr, vgic_cpu->lr_used))
-                       continue;
-
-               vlr = vgic_get_lr(vcpu, lr);
-
-               /*
-                * If we have a mapping, and the virtual interrupt is
-                * presented to the guest (as pending or active), then we must
-                * set the state to active in the physical world. See
-                * Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
-                */
-               if (vlr.state & LR_HW) {
-                       struct irq_phys_map *map;
-                       map = vgic_irq_map_search(vcpu, vlr.irq);
-
-                       ret = irq_set_irqchip_state(map->irq,
-                                                   IRQCHIP_STATE_ACTIVE,
-                                                   true);
-                       WARN_ON(ret);
-               }
-       }
 }
 
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
@@ -1421,7 +1437,7 @@ static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
                return 0;
 
        map = vgic_irq_map_search(vcpu, vlr.irq);
-       BUG_ON(!map || !map->active);
+       BUG_ON(!map);
 
        ret = irq_get_irqchip_state(map->irq,
                                    IRQCHIP_STATE_ACTIVE,
@@ -1429,13 +1445,8 @@ static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 
        WARN_ON(ret);
 
-       if (map->active) {
-               ret = irq_set_irqchip_state(map->irq,
-                                           IRQCHIP_STATE_ACTIVE,
-                                           false);
-               WARN_ON(ret);
+       if (map->active)
                return 0;
-       }
 
        return 1;
 }
@@ -1607,8 +1618,12 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
        } else {
                if (level_triggered) {
                        vgic_dist_irq_clear_level(vcpu, irq_num);
-                       if (!vgic_dist_irq_soft_pend(vcpu, irq_num))
+                       if (!vgic_dist_irq_soft_pend(vcpu, irq_num)) {
                                vgic_dist_irq_clear_pending(vcpu, irq_num);
+                               vgic_cpu_irq_clear(vcpu, irq_num);
+                               if (!compute_pending_for_cpu(vcpu))
+                                       clear_bit(cpuid, dist->irq_pending_on_cpu);
+                       }
                }
 
                ret = false;